From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752760AbcDTPhx (ORCPT ); Wed, 20 Apr 2016 11:37:53 -0400 Received: from asav22.altibox.net ([109.247.116.9]:39429 "EHLO asav22.altibox.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752297AbcDTPfz (ORCPT ); Wed, 20 Apr 2016 11:35:55 -0400 From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= To: dri-devel@lists.freedesktop.org, linux-fbdev@vger.kernel.org Cc: daniel@ffwll.ch, laurent.pinchart@ideasonboard.com, tomi.valkeinen@ti.com, linux-kernel@vger.kernel.org, =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= Subject: [PATCH 7/8] drm/qxl: Use drm_fb_helper deferred_io support Date: Wed, 20 Apr 2016 17:25:28 +0200 Message-Id: <1461165929-11344-8-git-send-email-noralf@tronnes.org> X-Mailer: git-send-email 2.2.2 In-Reply-To: <1461165929-11344-1-git-send-email-noralf@tronnes.org> References: <1461165929-11344-1-git-send-email-noralf@tronnes.org> MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-CMAE-Score: 0 X-CMAE-Analysis: v=2.1 cv=H7l7u7si c=1 sm=1 tr=0 a=gFHx44SYZz5JQKQKbGEAEQ==:117 a=gFHx44SYZz5JQKQKbGEAEQ==:17 a=L9H7d07YOLsA:10 a=9cW_t1CCXrUA:10 a=s5jvgZ67dGcA:10 a=IkcTkHD0fZMA:10 a=SJz97ENfAAAA:8 a=URfIDc8HuQupk61Sm4gA:9 a=FN-48g-n5od3gyGd:21 a=caF6IMtwedoeOYbX:21 a=QEXdDO2ut3YA:10 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Use the fbdev deferred io support in drm_fb_helper. The (struct fb_ops *)->fb_{fillrect,copyarea,imageblit} functions will now be deferred in the same way that mmap damage is, instead of being flushed directly. This patch has only been compile tested. Signed-off-by: Noralf Trønnes --- drivers/gpu/drm/qxl/qxl_display.c | 9 +- drivers/gpu/drm/qxl/qxl_drv.h | 7 +- drivers/gpu/drm/qxl/qxl_fb.c | 220 ++++++++++---------------------------- drivers/gpu/drm/qxl/qxl_kms.c | 4 - 4 files changed, 62 insertions(+), 178 deletions(-) diff --git a/drivers/gpu/drm/qxl/qxl_display.c b/drivers/gpu/drm/qxl/qxl_display.c index 030409a..9a03524 100644 --- a/drivers/gpu/drm/qxl/qxl_display.c +++ b/drivers/gpu/drm/qxl/qxl_display.c @@ -465,7 +465,7 @@ static const struct drm_crtc_funcs qxl_crtc_funcs = { .page_flip = qxl_crtc_page_flip, }; -static void qxl_user_framebuffer_destroy(struct drm_framebuffer *fb) +void qxl_user_framebuffer_destroy(struct drm_framebuffer *fb) { struct qxl_framebuffer *qxl_fb = to_qxl_framebuffer(fb); @@ -527,12 +527,13 @@ int qxl_framebuffer_init(struct drm_device *dev, struct qxl_framebuffer *qfb, const struct drm_mode_fb_cmd2 *mode_cmd, - struct drm_gem_object *obj) + struct drm_gem_object *obj, + const struct drm_framebuffer_funcs *funcs) { int ret; qfb->obj = obj; - ret = drm_framebuffer_init(dev, &qfb->base, &qxl_fb_funcs); + ret = drm_framebuffer_init(dev, &qfb->base, funcs); if (ret) { qfb->obj = NULL; return ret; @@ -999,7 +1000,7 @@ qxl_user_framebuffer_create(struct drm_device *dev, if (qxl_fb == NULL) return NULL; - ret = qxl_framebuffer_init(dev, qxl_fb, mode_cmd, obj); + ret = qxl_framebuffer_init(dev, qxl_fb, mode_cmd, obj, &qxl_fb_funcs); if (ret) { kfree(qxl_fb); drm_gem_object_unreference_unlocked(obj); diff --git a/drivers/gpu/drm/qxl/qxl_drv.h b/drivers/gpu/drm/qxl/qxl_drv.h index 3f3897e..3ad6604 100644 --- a/drivers/gpu/drm/qxl/qxl_drv.h +++ b/drivers/gpu/drm/qxl/qxl_drv.h @@ -324,8 +324,6 @@ struct qxl_device { struct workqueue_struct *gc_queue; struct work_struct gc_work; - struct work_struct fb_work; - struct drm_property *hotplug_mode_update_property; int monitors_config_width; int monitors_config_height; @@ -389,11 +387,13 @@ int qxl_get_handle_for_primary_fb(struct qxl_device *qdev, void qxl_fbdev_set_suspend(struct qxl_device *qdev, int state); /* qxl_display.c */ +void qxl_user_framebuffer_destroy(struct drm_framebuffer *fb); int qxl_framebuffer_init(struct drm_device *dev, struct qxl_framebuffer *rfb, const struct drm_mode_fb_cmd2 *mode_cmd, - struct drm_gem_object *obj); + struct drm_gem_object *obj, + const struct drm_framebuffer_funcs *funcs); void qxl_display_read_client_monitors_config(struct qxl_device *qdev); void qxl_send_monitors_config(struct qxl_device *qdev); int qxl_create_monitors_object(struct qxl_device *qdev); @@ -553,7 +553,6 @@ int qxl_irq_init(struct qxl_device *qdev); irqreturn_t qxl_irq_handler(int irq, void *arg); /* qxl_fb.c */ -int qxl_fb_init(struct qxl_device *qdev); bool qxl_fbdev_qobj_is_fb(struct qxl_device *qdev, struct qxl_bo *qobj); int qxl_debugfs_add_files(struct qxl_device *qdev, diff --git a/drivers/gpu/drm/qxl/qxl_fb.c b/drivers/gpu/drm/qxl/qxl_fb.c index 06f032d..090dcee 100644 --- a/drivers/gpu/drm/qxl/qxl_fb.c +++ b/drivers/gpu/drm/qxl/qxl_fb.c @@ -30,6 +30,7 @@ #include "drm/drm.h" #include "drm/drm_crtc.h" #include "drm/drm_crtc_helper.h" +#include "drm/drm_rect.h" #include "qxl_drv.h" #include "qxl_object.h" @@ -46,15 +47,6 @@ struct qxl_fbdev { struct list_head delayed_ops; void *shadow; int size; - - /* dirty memory logging */ - struct { - spinlock_t lock; - unsigned x1; - unsigned y1; - unsigned x2; - unsigned y2; - } dirty; }; static void qxl_fb_image_init(struct qxl_fb_image *qxl_fb_image, @@ -82,169 +74,18 @@ static void qxl_fb_image_init(struct qxl_fb_image *qxl_fb_image, } } -static void qxl_fb_dirty_flush(struct fb_info *info) -{ - struct qxl_fbdev *qfbdev = info->par; - struct qxl_device *qdev = qfbdev->qdev; - struct qxl_fb_image qxl_fb_image; - struct fb_image *image = &qxl_fb_image.fb_image; - unsigned long flags; - u32 x1, x2, y1, y2; - - /* TODO: hard coding 32 bpp */ - int stride = qfbdev->qfb.base.pitches[0]; - - spin_lock_irqsave(&qfbdev->dirty.lock, flags); - - x1 = qfbdev->dirty.x1; - x2 = qfbdev->dirty.x2; - y1 = qfbdev->dirty.y1; - y2 = qfbdev->dirty.y2; - qfbdev->dirty.x1 = 0; - qfbdev->dirty.x2 = 0; - qfbdev->dirty.y1 = 0; - qfbdev->dirty.y2 = 0; - - spin_unlock_irqrestore(&qfbdev->dirty.lock, flags); - - /* - * we are using a shadow draw buffer, at qdev->surface0_shadow - */ - qxl_io_log(qdev, "dirty x[%d, %d], y[%d, %d]", x1, x2, y1, y2); - image->dx = x1; - image->dy = y1; - image->width = x2 - x1 + 1; - image->height = y2 - y1 + 1; - image->fg_color = 0xffffffff; /* unused, just to avoid uninitialized - warnings */ - image->bg_color = 0; - image->depth = 32; /* TODO: take from somewhere? */ - image->cmap.start = 0; - image->cmap.len = 0; - image->cmap.red = NULL; - image->cmap.green = NULL; - image->cmap.blue = NULL; - image->cmap.transp = NULL; - image->data = qfbdev->shadow + (x1 * 4) + (stride * y1); - - qxl_fb_image_init(&qxl_fb_image, qdev, info, NULL); - qxl_draw_opaque_fb(&qxl_fb_image, stride); -} - -static void qxl_dirty_update(struct qxl_fbdev *qfbdev, - int x, int y, int width, int height) -{ - struct qxl_device *qdev = qfbdev->qdev; - unsigned long flags; - int x2, y2; - - x2 = x + width - 1; - y2 = y + height - 1; - - spin_lock_irqsave(&qfbdev->dirty.lock, flags); - - if ((qfbdev->dirty.y2 - qfbdev->dirty.y1) && - (qfbdev->dirty.x2 - qfbdev->dirty.x1)) { - if (qfbdev->dirty.y1 < y) - y = qfbdev->dirty.y1; - if (qfbdev->dirty.y2 > y2) - y2 = qfbdev->dirty.y2; - if (qfbdev->dirty.x1 < x) - x = qfbdev->dirty.x1; - if (qfbdev->dirty.x2 > x2) - x2 = qfbdev->dirty.x2; - } - - qfbdev->dirty.x1 = x; - qfbdev->dirty.x2 = x2; - qfbdev->dirty.y1 = y; - qfbdev->dirty.y2 = y2; - - spin_unlock_irqrestore(&qfbdev->dirty.lock, flags); - - schedule_work(&qdev->fb_work); -} - -static void qxl_deferred_io(struct fb_info *info, - struct list_head *pagelist) -{ - struct qxl_fbdev *qfbdev = info->par; - unsigned long start, end, min, max; - struct page *page; - int y1, y2; - - min = ULONG_MAX; - max = 0; - list_for_each_entry(page, pagelist, lru) { - start = page->index << PAGE_SHIFT; - end = start + PAGE_SIZE - 1; - min = min(min, start); - max = max(max, end); - } - - if (min < max) { - y1 = min / info->fix.line_length; - y2 = (max / info->fix.line_length) + 1; - qxl_dirty_update(qfbdev, 0, y1, info->var.xres, y2 - y1); - } -}; - static struct fb_deferred_io qxl_defio = { .delay = QXL_DIRTY_DELAY, - .deferred_io = qxl_deferred_io, + .deferred_io = drm_fb_helper_deferred_io, }; -static void qxl_fb_fillrect(struct fb_info *info, - const struct fb_fillrect *rect) -{ - struct qxl_fbdev *qfbdev = info->par; - - sys_fillrect(info, rect); - qxl_dirty_update(qfbdev, rect->dx, rect->dy, rect->width, - rect->height); -} - -static void qxl_fb_copyarea(struct fb_info *info, - const struct fb_copyarea *area) -{ - struct qxl_fbdev *qfbdev = info->par; - - sys_copyarea(info, area); - qxl_dirty_update(qfbdev, area->dx, area->dy, area->width, - area->height); -} - -static void qxl_fb_imageblit(struct fb_info *info, - const struct fb_image *image) -{ - struct qxl_fbdev *qfbdev = info->par; - - sys_imageblit(info, image); - qxl_dirty_update(qfbdev, image->dx, image->dy, image->width, - image->height); -} - -static void qxl_fb_work(struct work_struct *work) -{ - struct qxl_device *qdev = container_of(work, struct qxl_device, fb_work); - struct qxl_fbdev *qfbdev = qdev->mode_info.qfbdev; - - qxl_fb_dirty_flush(qfbdev->helper.fbdev); -} - -int qxl_fb_init(struct qxl_device *qdev) -{ - INIT_WORK(&qdev->fb_work, qxl_fb_work); - return 0; -} - static struct fb_ops qxlfb_ops = { .owner = THIS_MODULE, .fb_check_var = drm_fb_helper_check_var, .fb_set_par = drm_fb_helper_set_par, /* TODO: copy vmwgfx */ - .fb_fillrect = qxl_fb_fillrect, - .fb_copyarea = qxl_fb_copyarea, - .fb_imageblit = qxl_fb_imageblit, + .fb_fillrect = drm_fb_helper_sys_fillrect, + .fb_copyarea = drm_fb_helper_sys_copyarea, + .fb_imageblit = drm_fb_helper_sys_imageblit, .fb_pan_display = drm_fb_helper_pan_display, .fb_blank = drm_fb_helper_blank, .fb_setcmap = drm_fb_helper_setcmap, @@ -338,6 +179,53 @@ out_unref: return ret; } +static int qxlfb_framebuffer_dirty(struct drm_framebuffer *fb, + struct drm_file *file_priv, + unsigned flags, unsigned color, + struct drm_clip_rect *clips, + unsigned num_clips) +{ + struct qxl_device *qdev = fb->dev->dev_private; + struct fb_info *info = qdev->fbdev_info; + struct qxl_fbdev *qfbdev = info->par; + struct qxl_fb_image qxl_fb_image; + struct fb_image *image = &qxl_fb_image.fb_image; + + /* TODO: hard coding 32 bpp */ + int stride = qfbdev->qfb.base.pitches[0]; + + /* + * we are using a shadow draw buffer, at qdev->surface0_shadow + */ + qxl_io_log(qdev, "dirty x[%d, %d], y[%d, %d]", clips->x1, clips->x2, + clips->y1, clips->y2); + image->dx = clips->x1; + image->dy = clips->y1; + image->width = drm_clip_rect_width(clips); + image->height = drm_clip_rect_height(clips); + image->fg_color = 0xffffffff; /* unused, just to avoid uninitialized + warnings */ + image->bg_color = 0; + image->depth = 32; /* TODO: take from somewhere? */ + image->cmap.start = 0; + image->cmap.len = 0; + image->cmap.red = NULL; + image->cmap.green = NULL; + image->cmap.blue = NULL; + image->cmap.transp = NULL; + image->data = qfbdev->shadow + (clips->x1 * 4) + (stride * clips->y1); + + qxl_fb_image_init(&qxl_fb_image, qdev, info, NULL); + qxl_draw_opaque_fb(&qxl_fb_image, stride); + + return 0; +} + +static const struct drm_framebuffer_funcs qxlfb_fb_funcs = { + .destroy = qxl_user_framebuffer_destroy, + .dirty = qxlfb_framebuffer_dirty, +}; + static int qxlfb_create(struct qxl_fbdev *qfbdev, struct drm_fb_helper_surface_size *sizes) { @@ -383,7 +271,8 @@ static int qxlfb_create(struct qxl_fbdev *qfbdev, info->par = qfbdev; - qxl_framebuffer_init(qdev->ddev, &qfbdev->qfb, &mode_cmd, gobj); + qxl_framebuffer_init(qdev->ddev, &qfbdev->qfb, &mode_cmd, gobj, + &qxlfb_fb_funcs); fb = &qfbdev->qfb.base; @@ -504,7 +393,6 @@ int qxl_fbdev_init(struct qxl_device *qdev) qfbdev->qdev = qdev; qdev->mode_info.qfbdev = qfbdev; spin_lock_init(&qfbdev->delayed_ops_lock); - spin_lock_init(&qfbdev->dirty.lock); INIT_LIST_HEAD(&qfbdev->delayed_ops); drm_fb_helper_prepare(qdev->ddev, &qfbdev->helper, diff --git a/drivers/gpu/drm/qxl/qxl_kms.c b/drivers/gpu/drm/qxl/qxl_kms.c index b2977a1..2319800 100644 --- a/drivers/gpu/drm/qxl/qxl_kms.c +++ b/drivers/gpu/drm/qxl/qxl_kms.c @@ -261,10 +261,6 @@ static int qxl_device_init(struct qxl_device *qdev, qdev->gc_queue = create_singlethread_workqueue("qxl_gc"); INIT_WORK(&qdev->gc_work, qxl_gc_work); - r = qxl_fb_init(qdev); - if (r) - return r; - return 0; } -- 2.2.2 From mboxrd@z Thu Jan 1 00:00:00 1970 From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= Date: Wed, 20 Apr 2016 15:25:28 +0000 Subject: [PATCH 7/8] drm/qxl: Use drm_fb_helper deferred_io support Message-Id: <1461165929-11344-8-git-send-email-noralf@tronnes.org> List-Id: References: <1461165929-11344-1-git-send-email-noralf@tronnes.org> In-Reply-To: <1461165929-11344-1-git-send-email-noralf@tronnes.org> MIME-Version: 1.0 Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: quoted-printable To: dri-devel@lists.freedesktop.org, linux-fbdev@vger.kernel.org Cc: tomi.valkeinen@ti.com, laurent.pinchart@ideasonboard.com, linux-kernel@vger.kernel.org Use the fbdev deferred io support in drm_fb_helper. The (struct fb_ops *)->fb_{fillrect,copyarea,imageblit} functions will now be deferred in the same way that mmap damage is, instead of being flushed directly. This patch has only been compile tested. Signed-off-by: Noralf Tr=C3=B8nnes --- drivers/gpu/drm/qxl/qxl_display.c | 9 +- drivers/gpu/drm/qxl/qxl_drv.h | 7 +- drivers/gpu/drm/qxl/qxl_fb.c | 220 ++++++++++------------------------= ---- drivers/gpu/drm/qxl/qxl_kms.c | 4 - 4 files changed, 62 insertions(+), 178 deletions(-) diff --git a/drivers/gpu/drm/qxl/qxl_display.c b/drivers/gpu/drm/qxl/qxl_di= splay.c index 030409a..9a03524 100644 --- a/drivers/gpu/drm/qxl/qxl_display.c +++ b/drivers/gpu/drm/qxl/qxl_display.c @@ -465,7 +465,7 @@ static const struct drm_crtc_funcs qxl_crtc_funcs =3D { .page_flip =3D qxl_crtc_page_flip, }; =20 -static void qxl_user_framebuffer_destroy(struct drm_framebuffer *fb) +void qxl_user_framebuffer_destroy(struct drm_framebuffer *fb) { struct qxl_framebuffer *qxl_fb =3D to_qxl_framebuffer(fb); =20 @@ -527,12 +527,13 @@ int qxl_framebuffer_init(struct drm_device *dev, struct qxl_framebuffer *qfb, const struct drm_mode_fb_cmd2 *mode_cmd, - struct drm_gem_object *obj) + struct drm_gem_object *obj, + const struct drm_framebuffer_funcs *funcs) { int ret; =20 qfb->obj =3D obj; - ret =3D drm_framebuffer_init(dev, &qfb->base, &qxl_fb_funcs); + ret =3D drm_framebuffer_init(dev, &qfb->base, funcs); if (ret) { qfb->obj =3D NULL; return ret; @@ -999,7 +1000,7 @@ qxl_user_framebuffer_create(struct drm_device *dev, if (qxl_fb =3D NULL) return NULL; =20 - ret =3D qxl_framebuffer_init(dev, qxl_fb, mode_cmd, obj); + ret =3D qxl_framebuffer_init(dev, qxl_fb, mode_cmd, obj, &qxl_fb_funcs); if (ret) { kfree(qxl_fb); drm_gem_object_unreference_unlocked(obj); diff --git a/drivers/gpu/drm/qxl/qxl_drv.h b/drivers/gpu/drm/qxl/qxl_drv.h index 3f3897e..3ad6604 100644 --- a/drivers/gpu/drm/qxl/qxl_drv.h +++ b/drivers/gpu/drm/qxl/qxl_drv.h @@ -324,8 +324,6 @@ struct qxl_device { struct workqueue_struct *gc_queue; struct work_struct gc_work; =20 - struct work_struct fb_work; - struct drm_property *hotplug_mode_update_property; int monitors_config_width; int monitors_config_height; @@ -389,11 +387,13 @@ int qxl_get_handle_for_primary_fb(struct qxl_device *= qdev, void qxl_fbdev_set_suspend(struct qxl_device *qdev, int state); =20 /* qxl_display.c */ +void qxl_user_framebuffer_destroy(struct drm_framebuffer *fb); int qxl_framebuffer_init(struct drm_device *dev, struct qxl_framebuffer *rfb, const struct drm_mode_fb_cmd2 *mode_cmd, - struct drm_gem_object *obj); + struct drm_gem_object *obj, + const struct drm_framebuffer_funcs *funcs); void qxl_display_read_client_monitors_config(struct qxl_device *qdev); void qxl_send_monitors_config(struct qxl_device *qdev); int qxl_create_monitors_object(struct qxl_device *qdev); @@ -553,7 +553,6 @@ int qxl_irq_init(struct qxl_device *qdev); irqreturn_t qxl_irq_handler(int irq, void *arg); =20 /* qxl_fb.c */ -int qxl_fb_init(struct qxl_device *qdev); bool qxl_fbdev_qobj_is_fb(struct qxl_device *qdev, struct qxl_bo *qobj); =20 int qxl_debugfs_add_files(struct qxl_device *qdev, diff --git a/drivers/gpu/drm/qxl/qxl_fb.c b/drivers/gpu/drm/qxl/qxl_fb.c index 06f032d..090dcee 100644 --- a/drivers/gpu/drm/qxl/qxl_fb.c +++ b/drivers/gpu/drm/qxl/qxl_fb.c @@ -30,6 +30,7 @@ #include "drm/drm.h" #include "drm/drm_crtc.h" #include "drm/drm_crtc_helper.h" +#include "drm/drm_rect.h" #include "qxl_drv.h" =20 #include "qxl_object.h" @@ -46,15 +47,6 @@ struct qxl_fbdev { struct list_head delayed_ops; void *shadow; int size; - - /* dirty memory logging */ - struct { - spinlock_t lock; - unsigned x1; - unsigned y1; - unsigned x2; - unsigned y2; - } dirty; }; =20 static void qxl_fb_image_init(struct qxl_fb_image *qxl_fb_image, @@ -82,169 +74,18 @@ static void qxl_fb_image_init(struct qxl_fb_image *qxl= _fb_image, } } =20 -static void qxl_fb_dirty_flush(struct fb_info *info) -{ - struct qxl_fbdev *qfbdev =3D info->par; - struct qxl_device *qdev =3D qfbdev->qdev; - struct qxl_fb_image qxl_fb_image; - struct fb_image *image =3D &qxl_fb_image.fb_image; - unsigned long flags; - u32 x1, x2, y1, y2; - - /* TODO: hard coding 32 bpp */ - int stride =3D qfbdev->qfb.base.pitches[0]; - - spin_lock_irqsave(&qfbdev->dirty.lock, flags); - - x1 =3D qfbdev->dirty.x1; - x2 =3D qfbdev->dirty.x2; - y1 =3D qfbdev->dirty.y1; - y2 =3D qfbdev->dirty.y2; - qfbdev->dirty.x1 =3D 0; - qfbdev->dirty.x2 =3D 0; - qfbdev->dirty.y1 =3D 0; - qfbdev->dirty.y2 =3D 0; - - spin_unlock_irqrestore(&qfbdev->dirty.lock, flags); - - /* - * we are using a shadow draw buffer, at qdev->surface0_shadow - */ - qxl_io_log(qdev, "dirty x[%d, %d], y[%d, %d]", x1, x2, y1, y2); - image->dx =3D x1; - image->dy =3D y1; - image->width =3D x2 - x1 + 1; - image->height =3D y2 - y1 + 1; - image->fg_color =3D 0xffffffff; /* unused, just to avoid uninitialized - warnings */ - image->bg_color =3D 0; - image->depth =3D 32; /* TODO: take from somewhere? */ - image->cmap.start =3D 0; - image->cmap.len =3D 0; - image->cmap.red =3D NULL; - image->cmap.green =3D NULL; - image->cmap.blue =3D NULL; - image->cmap.transp =3D NULL; - image->data =3D qfbdev->shadow + (x1 * 4) + (stride * y1); - - qxl_fb_image_init(&qxl_fb_image, qdev, info, NULL); - qxl_draw_opaque_fb(&qxl_fb_image, stride); -} - -static void qxl_dirty_update(struct qxl_fbdev *qfbdev, - int x, int y, int width, int height) -{ - struct qxl_device *qdev =3D qfbdev->qdev; - unsigned long flags; - int x2, y2; - - x2 =3D x + width - 1; - y2 =3D y + height - 1; - - spin_lock_irqsave(&qfbdev->dirty.lock, flags); - - if ((qfbdev->dirty.y2 - qfbdev->dirty.y1) && - (qfbdev->dirty.x2 - qfbdev->dirty.x1)) { - if (qfbdev->dirty.y1 < y) - y =3D qfbdev->dirty.y1; - if (qfbdev->dirty.y2 > y2) - y2 =3D qfbdev->dirty.y2; - if (qfbdev->dirty.x1 < x) - x =3D qfbdev->dirty.x1; - if (qfbdev->dirty.x2 > x2) - x2 =3D qfbdev->dirty.x2; - } - - qfbdev->dirty.x1 =3D x; - qfbdev->dirty.x2 =3D x2; - qfbdev->dirty.y1 =3D y; - qfbdev->dirty.y2 =3D y2; - - spin_unlock_irqrestore(&qfbdev->dirty.lock, flags); - - schedule_work(&qdev->fb_work); -} - -static void qxl_deferred_io(struct fb_info *info, - struct list_head *pagelist) -{ - struct qxl_fbdev *qfbdev =3D info->par; - unsigned long start, end, min, max; - struct page *page; - int y1, y2; - - min =3D ULONG_MAX; - max =3D 0; - list_for_each_entry(page, pagelist, lru) { - start =3D page->index << PAGE_SHIFT; - end =3D start + PAGE_SIZE - 1; - min =3D min(min, start); - max =3D max(max, end); - } - - if (min < max) { - y1 =3D min / info->fix.line_length; - y2 =3D (max / info->fix.line_length) + 1; - qxl_dirty_update(qfbdev, 0, y1, info->var.xres, y2 - y1); - } -}; - static struct fb_deferred_io qxl_defio =3D { .delay =3D QXL_DIRTY_DELAY, - .deferred_io =3D qxl_deferred_io, + .deferred_io =3D drm_fb_helper_deferred_io, }; =20 -static void qxl_fb_fillrect(struct fb_info *info, - const struct fb_fillrect *rect) -{ - struct qxl_fbdev *qfbdev =3D info->par; - - sys_fillrect(info, rect); - qxl_dirty_update(qfbdev, rect->dx, rect->dy, rect->width, - rect->height); -} - -static void qxl_fb_copyarea(struct fb_info *info, - const struct fb_copyarea *area) -{ - struct qxl_fbdev *qfbdev =3D info->par; - - sys_copyarea(info, area); - qxl_dirty_update(qfbdev, area->dx, area->dy, area->width, - area->height); -} - -static void qxl_fb_imageblit(struct fb_info *info, - const struct fb_image *image) -{ - struct qxl_fbdev *qfbdev =3D info->par; - - sys_imageblit(info, image); - qxl_dirty_update(qfbdev, image->dx, image->dy, image->width, - image->height); -} - -static void qxl_fb_work(struct work_struct *work) -{ - struct qxl_device *qdev =3D container_of(work, struct qxl_device, fb_work= ); - struct qxl_fbdev *qfbdev =3D qdev->mode_info.qfbdev; - - qxl_fb_dirty_flush(qfbdev->helper.fbdev); -} - -int qxl_fb_init(struct qxl_device *qdev) -{ - INIT_WORK(&qdev->fb_work, qxl_fb_work); - return 0; -} - static struct fb_ops qxlfb_ops =3D { .owner =3D THIS_MODULE, .fb_check_var =3D drm_fb_helper_check_var, .fb_set_par =3D drm_fb_helper_set_par, /* TODO: copy vmwgfx */ - .fb_fillrect =3D qxl_fb_fillrect, - .fb_copyarea =3D qxl_fb_copyarea, - .fb_imageblit =3D qxl_fb_imageblit, + .fb_fillrect =3D drm_fb_helper_sys_fillrect, + .fb_copyarea =3D drm_fb_helper_sys_copyarea, + .fb_imageblit =3D drm_fb_helper_sys_imageblit, .fb_pan_display =3D drm_fb_helper_pan_display, .fb_blank =3D drm_fb_helper_blank, .fb_setcmap =3D drm_fb_helper_setcmap, @@ -338,6 +179,53 @@ out_unref: return ret; } =20 +static int qxlfb_framebuffer_dirty(struct drm_framebuffer *fb, + struct drm_file *file_priv, + unsigned flags, unsigned color, + struct drm_clip_rect *clips, + unsigned num_clips) +{ + struct qxl_device *qdev =3D fb->dev->dev_private; + struct fb_info *info =3D qdev->fbdev_info; + struct qxl_fbdev *qfbdev =3D info->par; + struct qxl_fb_image qxl_fb_image; + struct fb_image *image =3D &qxl_fb_image.fb_image; + + /* TODO: hard coding 32 bpp */ + int stride =3D qfbdev->qfb.base.pitches[0]; + + /* + * we are using a shadow draw buffer, at qdev->surface0_shadow + */ + qxl_io_log(qdev, "dirty x[%d, %d], y[%d, %d]", clips->x1, clips->x2, + clips->y1, clips->y2); + image->dx =3D clips->x1; + image->dy =3D clips->y1; + image->width =3D drm_clip_rect_width(clips); + image->height =3D drm_clip_rect_height(clips); + image->fg_color =3D 0xffffffff; /* unused, just to avoid uninitialized + warnings */ + image->bg_color =3D 0; + image->depth =3D 32; /* TODO: take from somewhere? */ + image->cmap.start =3D 0; + image->cmap.len =3D 0; + image->cmap.red =3D NULL; + image->cmap.green =3D NULL; + image->cmap.blue =3D NULL; + image->cmap.transp =3D NULL; + image->data =3D qfbdev->shadow + (clips->x1 * 4) + (stride * clips->y1); + + qxl_fb_image_init(&qxl_fb_image, qdev, info, NULL); + qxl_draw_opaque_fb(&qxl_fb_image, stride); + + return 0; +} + +static const struct drm_framebuffer_funcs qxlfb_fb_funcs =3D { + .destroy =3D qxl_user_framebuffer_destroy, + .dirty =3D qxlfb_framebuffer_dirty, +}; + static int qxlfb_create(struct qxl_fbdev *qfbdev, struct drm_fb_helper_surface_size *sizes) { @@ -383,7 +271,8 @@ static int qxlfb_create(struct qxl_fbdev *qfbdev, =20 info->par =3D qfbdev; =20 - qxl_framebuffer_init(qdev->ddev, &qfbdev->qfb, &mode_cmd, gobj); + qxl_framebuffer_init(qdev->ddev, &qfbdev->qfb, &mode_cmd, gobj, + &qxlfb_fb_funcs); =20 fb =3D &qfbdev->qfb.base; =20 @@ -504,7 +393,6 @@ int qxl_fbdev_init(struct qxl_device *qdev) qfbdev->qdev =3D qdev; qdev->mode_info.qfbdev =3D qfbdev; spin_lock_init(&qfbdev->delayed_ops_lock); - spin_lock_init(&qfbdev->dirty.lock); INIT_LIST_HEAD(&qfbdev->delayed_ops); =20 drm_fb_helper_prepare(qdev->ddev, &qfbdev->helper, diff --git a/drivers/gpu/drm/qxl/qxl_kms.c b/drivers/gpu/drm/qxl/qxl_kms.c index b2977a1..2319800 100644 --- a/drivers/gpu/drm/qxl/qxl_kms.c +++ b/drivers/gpu/drm/qxl/qxl_kms.c @@ -261,10 +261,6 @@ static int qxl_device_init(struct qxl_device *qdev, qdev->gc_queue =3D create_singlethread_workqueue("qxl_gc"); INIT_WORK(&qdev->gc_work, qxl_gc_work); =20 - r =3D qxl_fb_init(qdev); - if (r) - return r; - return 0; } =20 --=20 2.2.2 From mboxrd@z Thu Jan 1 00:00:00 1970 From: =?UTF-8?q?Noralf=20Tr=C3=B8nnes?= Subject: [PATCH 7/8] drm/qxl: Use drm_fb_helper deferred_io support Date: Wed, 20 Apr 2016 17:25:28 +0200 Message-ID: <1461165929-11344-8-git-send-email-noralf@tronnes.org> References: <1461165929-11344-1-git-send-email-noralf@tronnes.org> Mime-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: base64 Return-path: Received: from asav22.altibox.net (asav22.altibox.net [109.247.116.9]) by gabe.freedesktop.org (Postfix) with ESMTPS id B368F6EA38 for ; Wed, 20 Apr 2016 15:26:27 +0000 (UTC) In-Reply-To: <1461165929-11344-1-git-send-email-noralf@tronnes.org> List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" To: dri-devel@lists.freedesktop.org, linux-fbdev@vger.kernel.org Cc: tomi.valkeinen@ti.com, laurent.pinchart@ideasonboard.com, linux-kernel@vger.kernel.org List-Id: dri-devel@lists.freedesktop.org VXNlIHRoZSBmYmRldiBkZWZlcnJlZCBpbyBzdXBwb3J0IGluIGRybV9mYl9oZWxwZXIuClRoZSAo c3RydWN0IGZiX29wcyAqKS0+ZmJfe2ZpbGxyZWN0LGNvcHlhcmVhLGltYWdlYmxpdH0gZnVuY3Rp b25zIHdpbGwKbm93IGJlIGRlZmVycmVkIGluIHRoZSBzYW1lIHdheSB0aGF0IG1tYXAgZGFtYWdl IGlzLCBpbnN0ZWFkIG9mIGJlaW5nCmZsdXNoZWQgZGlyZWN0bHkuClRoaXMgcGF0Y2ggaGFzIG9u bHkgYmVlbiBjb21waWxlIHRlc3RlZC4KClNpZ25lZC1vZmYtYnk6IE5vcmFsZiBUcsO4bm5lcyA8 bm9yYWxmQHRyb25uZXMub3JnPgotLS0KIGRyaXZlcnMvZ3B1L2RybS9xeGwvcXhsX2Rpc3BsYXku YyB8ICAgOSArLQogZHJpdmVycy9ncHUvZHJtL3F4bC9xeGxfZHJ2LmggICAgIHwgICA3ICstCiBk cml2ZXJzL2dwdS9kcm0vcXhsL3F4bF9mYi5jICAgICAgfCAyMjAgKysrKysrKysrKy0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tLS0tLS0KIGRyaXZlcnMvZ3B1L2RybS9xeGwvcXhsX2ttcy5jICAgICB8 ICAgNCAtCiA0IGZpbGVzIGNoYW5nZWQsIDYyIGluc2VydGlvbnMoKyksIDE3OCBkZWxldGlvbnMo LSkKCmRpZmYgLS1naXQgYS9kcml2ZXJzL2dwdS9kcm0vcXhsL3F4bF9kaXNwbGF5LmMgYi9kcml2 ZXJzL2dwdS9kcm0vcXhsL3F4bF9kaXNwbGF5LmMKaW5kZXggMDMwNDA5YS4uOWEwMzUyNCAxMDA2 NDQKLS0tIGEvZHJpdmVycy9ncHUvZHJtL3F4bC9xeGxfZGlzcGxheS5jCisrKyBiL2RyaXZlcnMv Z3B1L2RybS9xeGwvcXhsX2Rpc3BsYXkuYwpAQCAtNDY1LDcgKzQ2NSw3IEBAIHN0YXRpYyBjb25z dCBzdHJ1Y3QgZHJtX2NydGNfZnVuY3MgcXhsX2NydGNfZnVuY3MgPSB7CiAJLnBhZ2VfZmxpcCA9 IHF4bF9jcnRjX3BhZ2VfZmxpcCwKIH07CiAKLXN0YXRpYyB2b2lkIHF4bF91c2VyX2ZyYW1lYnVm ZmVyX2Rlc3Ryb3koc3RydWN0IGRybV9mcmFtZWJ1ZmZlciAqZmIpCit2b2lkIHF4bF91c2VyX2Zy YW1lYnVmZmVyX2Rlc3Ryb3koc3RydWN0IGRybV9mcmFtZWJ1ZmZlciAqZmIpCiB7CiAJc3RydWN0 IHF4bF9mcmFtZWJ1ZmZlciAqcXhsX2ZiID0gdG9fcXhsX2ZyYW1lYnVmZmVyKGZiKTsKIApAQCAt NTI3LDEyICs1MjcsMTMgQEAgaW50CiBxeGxfZnJhbWVidWZmZXJfaW5pdChzdHJ1Y3QgZHJtX2Rl dmljZSAqZGV2LAogCQkgICAgIHN0cnVjdCBxeGxfZnJhbWVidWZmZXIgKnFmYiwKIAkJICAgICBj b25zdCBzdHJ1Y3QgZHJtX21vZGVfZmJfY21kMiAqbW9kZV9jbWQsCi0JCSAgICAgc3RydWN0IGRy bV9nZW1fb2JqZWN0ICpvYmopCisJCSAgICAgc3RydWN0IGRybV9nZW1fb2JqZWN0ICpvYmosCisJ CSAgICAgY29uc3Qgc3RydWN0IGRybV9mcmFtZWJ1ZmZlcl9mdW5jcyAqZnVuY3MpCiB7CiAJaW50 IHJldDsKIAogCXFmYi0+b2JqID0gb2JqOwotCXJldCA9IGRybV9mcmFtZWJ1ZmZlcl9pbml0KGRl diwgJnFmYi0+YmFzZSwgJnF4bF9mYl9mdW5jcyk7CisJcmV0ID0gZHJtX2ZyYW1lYnVmZmVyX2lu aXQoZGV2LCAmcWZiLT5iYXNlLCBmdW5jcyk7CiAJaWYgKHJldCkgewogCQlxZmItPm9iaiA9IE5V TEw7CiAJCXJldHVybiByZXQ7CkBAIC05OTksNyArMTAwMCw3IEBAIHF4bF91c2VyX2ZyYW1lYnVm ZmVyX2NyZWF0ZShzdHJ1Y3QgZHJtX2RldmljZSAqZGV2LAogCWlmIChxeGxfZmIgPT0gTlVMTCkK IAkJcmV0dXJuIE5VTEw7CiAKLQlyZXQgPSBxeGxfZnJhbWVidWZmZXJfaW5pdChkZXYsIHF4bF9m YiwgbW9kZV9jbWQsIG9iaik7CisJcmV0ID0gcXhsX2ZyYW1lYnVmZmVyX2luaXQoZGV2LCBxeGxf ZmIsIG1vZGVfY21kLCBvYmosICZxeGxfZmJfZnVuY3MpOwogCWlmIChyZXQpIHsKIAkJa2ZyZWUo cXhsX2ZiKTsKIAkJZHJtX2dlbV9vYmplY3RfdW5yZWZlcmVuY2VfdW5sb2NrZWQob2JqKTsKZGlm ZiAtLWdpdCBhL2RyaXZlcnMvZ3B1L2RybS9xeGwvcXhsX2Rydi5oIGIvZHJpdmVycy9ncHUvZHJt L3F4bC9xeGxfZHJ2LmgKaW5kZXggM2YzODk3ZS4uM2FkNjYwNCAxMDA2NDQKLS0tIGEvZHJpdmVy cy9ncHUvZHJtL3F4bC9xeGxfZHJ2LmgKKysrIGIvZHJpdmVycy9ncHUvZHJtL3F4bC9xeGxfZHJ2 LmgKQEAgLTMyNCw4ICszMjQsNiBAQCBzdHJ1Y3QgcXhsX2RldmljZSB7CiAJc3RydWN0IHdvcmtx dWV1ZV9zdHJ1Y3QgKmdjX3F1ZXVlOwogCXN0cnVjdCB3b3JrX3N0cnVjdCBnY193b3JrOwogCi0J c3RydWN0IHdvcmtfc3RydWN0IGZiX3dvcms7Ci0KIAlzdHJ1Y3QgZHJtX3Byb3BlcnR5ICpob3Rw bHVnX21vZGVfdXBkYXRlX3Byb3BlcnR5OwogCWludCBtb25pdG9yc19jb25maWdfd2lkdGg7CiAJ aW50IG1vbml0b3JzX2NvbmZpZ19oZWlnaHQ7CkBAIC0zODksMTEgKzM4NywxMyBAQCBpbnQgcXhs X2dldF9oYW5kbGVfZm9yX3ByaW1hcnlfZmIoc3RydWN0IHF4bF9kZXZpY2UgKnFkZXYsCiB2b2lk IHF4bF9mYmRldl9zZXRfc3VzcGVuZChzdHJ1Y3QgcXhsX2RldmljZSAqcWRldiwgaW50IHN0YXRl KTsKIAogLyogcXhsX2Rpc3BsYXkuYyAqLwordm9pZCBxeGxfdXNlcl9mcmFtZWJ1ZmZlcl9kZXN0 cm95KHN0cnVjdCBkcm1fZnJhbWVidWZmZXIgKmZiKTsKIGludAogcXhsX2ZyYW1lYnVmZmVyX2lu aXQoc3RydWN0IGRybV9kZXZpY2UgKmRldiwKIAkJICAgICBzdHJ1Y3QgcXhsX2ZyYW1lYnVmZmVy ICpyZmIsCiAJCSAgICAgY29uc3Qgc3RydWN0IGRybV9tb2RlX2ZiX2NtZDIgKm1vZGVfY21kLAot CQkgICAgIHN0cnVjdCBkcm1fZ2VtX29iamVjdCAqb2JqKTsKKwkJICAgICBzdHJ1Y3QgZHJtX2dl bV9vYmplY3QgKm9iaiwKKwkJICAgICBjb25zdCBzdHJ1Y3QgZHJtX2ZyYW1lYnVmZmVyX2Z1bmNz ICpmdW5jcyk7CiB2b2lkIHF4bF9kaXNwbGF5X3JlYWRfY2xpZW50X21vbml0b3JzX2NvbmZpZyhz dHJ1Y3QgcXhsX2RldmljZSAqcWRldik7CiB2b2lkIHF4bF9zZW5kX21vbml0b3JzX2NvbmZpZyhz dHJ1Y3QgcXhsX2RldmljZSAqcWRldik7CiBpbnQgcXhsX2NyZWF0ZV9tb25pdG9yc19vYmplY3Qo c3RydWN0IHF4bF9kZXZpY2UgKnFkZXYpOwpAQCAtNTUzLDcgKzU1Myw2IEBAIGludCBxeGxfaXJx X2luaXQoc3RydWN0IHF4bF9kZXZpY2UgKnFkZXYpOwogaXJxcmV0dXJuX3QgcXhsX2lycV9oYW5k bGVyKGludCBpcnEsIHZvaWQgKmFyZyk7CiAKIC8qIHF4bF9mYi5jICovCi1pbnQgcXhsX2ZiX2lu aXQoc3RydWN0IHF4bF9kZXZpY2UgKnFkZXYpOwogYm9vbCBxeGxfZmJkZXZfcW9ial9pc19mYihz dHJ1Y3QgcXhsX2RldmljZSAqcWRldiwgc3RydWN0IHF4bF9ibyAqcW9iaik7CiAKIGludCBxeGxf ZGVidWdmc19hZGRfZmlsZXMoc3RydWN0IHF4bF9kZXZpY2UgKnFkZXYsCmRpZmYgLS1naXQgYS9k cml2ZXJzL2dwdS9kcm0vcXhsL3F4bF9mYi5jIGIvZHJpdmVycy9ncHUvZHJtL3F4bC9xeGxfZmIu YwppbmRleCAwNmYwMzJkLi4wOTBkY2VlIDEwMDY0NAotLS0gYS9kcml2ZXJzL2dwdS9kcm0vcXhs L3F4bF9mYi5jCisrKyBiL2RyaXZlcnMvZ3B1L2RybS9xeGwvcXhsX2ZiLmMKQEAgLTMwLDYgKzMw LDcgQEAKICNpbmNsdWRlICJkcm0vZHJtLmgiCiAjaW5jbHVkZSAiZHJtL2RybV9jcnRjLmgiCiAj aW5jbHVkZSAiZHJtL2RybV9jcnRjX2hlbHBlci5oIgorI2luY2x1ZGUgImRybS9kcm1fcmVjdC5o IgogI2luY2x1ZGUgInF4bF9kcnYuaCIKIAogI2luY2x1ZGUgInF4bF9vYmplY3QuaCIKQEAgLTQ2 LDE1ICs0Nyw2IEBAIHN0cnVjdCBxeGxfZmJkZXYgewogCXN0cnVjdCBsaXN0X2hlYWQgZGVsYXll ZF9vcHM7CiAJdm9pZCAqc2hhZG93OwogCWludCBzaXplOwotCi0JLyogZGlydHkgbWVtb3J5IGxv Z2dpbmcgKi8KLQlzdHJ1Y3QgewotCQlzcGlubG9ja190IGxvY2s7Ci0JCXVuc2lnbmVkIHgxOwot CQl1bnNpZ25lZCB5MTsKLQkJdW5zaWduZWQgeDI7Ci0JCXVuc2lnbmVkIHkyOwotCX0gZGlydHk7 CiB9OwogCiBzdGF0aWMgdm9pZCBxeGxfZmJfaW1hZ2VfaW5pdChzdHJ1Y3QgcXhsX2ZiX2ltYWdl ICpxeGxfZmJfaW1hZ2UsCkBAIC04MiwxNjkgKzc0LDE4IEBAIHN0YXRpYyB2b2lkIHF4bF9mYl9p bWFnZV9pbml0KHN0cnVjdCBxeGxfZmJfaW1hZ2UgKnF4bF9mYl9pbWFnZSwKIAl9CiB9CiAKLXN0 YXRpYyB2b2lkIHF4bF9mYl9kaXJ0eV9mbHVzaChzdHJ1Y3QgZmJfaW5mbyAqaW5mbykKLXsKLQlz dHJ1Y3QgcXhsX2ZiZGV2ICpxZmJkZXYgPSBpbmZvLT5wYXI7Ci0Jc3RydWN0IHF4bF9kZXZpY2Ug KnFkZXYgPSBxZmJkZXYtPnFkZXY7Ci0Jc3RydWN0IHF4bF9mYl9pbWFnZSBxeGxfZmJfaW1hZ2U7 Ci0Jc3RydWN0IGZiX2ltYWdlICppbWFnZSA9ICZxeGxfZmJfaW1hZ2UuZmJfaW1hZ2U7Ci0JdW5z aWduZWQgbG9uZyBmbGFnczsKLQl1MzIgeDEsIHgyLCB5MSwgeTI7Ci0KLQkvKiBUT0RPOiBoYXJk IGNvZGluZyAzMiBicHAgKi8KLQlpbnQgc3RyaWRlID0gcWZiZGV2LT5xZmIuYmFzZS5waXRjaGVz WzBdOwotCi0Jc3Bpbl9sb2NrX2lycXNhdmUoJnFmYmRldi0+ZGlydHkubG9jaywgZmxhZ3MpOwot Ci0JeDEgPSBxZmJkZXYtPmRpcnR5LngxOwotCXgyID0gcWZiZGV2LT5kaXJ0eS54MjsKLQl5MSA9 IHFmYmRldi0+ZGlydHkueTE7Ci0JeTIgPSBxZmJkZXYtPmRpcnR5LnkyOwotCXFmYmRldi0+ZGly dHkueDEgPSAwOwotCXFmYmRldi0+ZGlydHkueDIgPSAwOwotCXFmYmRldi0+ZGlydHkueTEgPSAw OwotCXFmYmRldi0+ZGlydHkueTIgPSAwOwotCi0Jc3Bpbl91bmxvY2tfaXJxcmVzdG9yZSgmcWZi ZGV2LT5kaXJ0eS5sb2NrLCBmbGFncyk7Ci0KLQkvKgotCSAqIHdlIGFyZSB1c2luZyBhIHNoYWRv dyBkcmF3IGJ1ZmZlciwgYXQgcWRldi0+c3VyZmFjZTBfc2hhZG93Ci0JICovCi0JcXhsX2lvX2xv ZyhxZGV2LCAiZGlydHkgeFslZCwgJWRdLCB5WyVkLCAlZF0iLCB4MSwgeDIsIHkxLCB5Mik7Ci0J aW1hZ2UtPmR4ID0geDE7Ci0JaW1hZ2UtPmR5ID0geTE7Ci0JaW1hZ2UtPndpZHRoID0geDIgLSB4 MSArIDE7Ci0JaW1hZ2UtPmhlaWdodCA9IHkyIC0geTEgKyAxOwotCWltYWdlLT5mZ19jb2xvciA9 IDB4ZmZmZmZmZmY7IC8qIHVudXNlZCwganVzdCB0byBhdm9pZCB1bmluaXRpYWxpemVkCi0JCQkJ CSB3YXJuaW5ncyAqLwotCWltYWdlLT5iZ19jb2xvciA9IDA7Ci0JaW1hZ2UtPmRlcHRoID0gMzI7 CSAgICAgLyogVE9ETzogdGFrZSBmcm9tIHNvbWV3aGVyZT8gKi8KLQlpbWFnZS0+Y21hcC5zdGFy dCA9IDA7Ci0JaW1hZ2UtPmNtYXAubGVuID0gMDsKLQlpbWFnZS0+Y21hcC5yZWQgPSBOVUxMOwot CWltYWdlLT5jbWFwLmdyZWVuID0gTlVMTDsKLQlpbWFnZS0+Y21hcC5ibHVlID0gTlVMTDsKLQlp bWFnZS0+Y21hcC50cmFuc3AgPSBOVUxMOwotCWltYWdlLT5kYXRhID0gcWZiZGV2LT5zaGFkb3cg KyAoeDEgKiA0KSArIChzdHJpZGUgKiB5MSk7Ci0KLQlxeGxfZmJfaW1hZ2VfaW5pdCgmcXhsX2Zi X2ltYWdlLCBxZGV2LCBpbmZvLCBOVUxMKTsKLQlxeGxfZHJhd19vcGFxdWVfZmIoJnF4bF9mYl9p bWFnZSwgc3RyaWRlKTsKLX0KLQotc3RhdGljIHZvaWQgcXhsX2RpcnR5X3VwZGF0ZShzdHJ1Y3Qg cXhsX2ZiZGV2ICpxZmJkZXYsCi0JCQkgICAgIGludCB4LCBpbnQgeSwgaW50IHdpZHRoLCBpbnQg aGVpZ2h0KQotewotCXN0cnVjdCBxeGxfZGV2aWNlICpxZGV2ID0gcWZiZGV2LT5xZGV2OwotCXVu c2lnbmVkIGxvbmcgZmxhZ3M7Ci0JaW50IHgyLCB5MjsKLQotCXgyID0geCArIHdpZHRoIC0gMTsK LQl5MiA9IHkgKyBoZWlnaHQgLSAxOwotCi0Jc3Bpbl9sb2NrX2lycXNhdmUoJnFmYmRldi0+ZGly dHkubG9jaywgZmxhZ3MpOwotCi0JaWYgKChxZmJkZXYtPmRpcnR5LnkyIC0gcWZiZGV2LT5kaXJ0 eS55MSkgJiYKLQkgICAgKHFmYmRldi0+ZGlydHkueDIgLSBxZmJkZXYtPmRpcnR5LngxKSkgewot CQlpZiAocWZiZGV2LT5kaXJ0eS55MSA8IHkpCi0JCQl5ID0gcWZiZGV2LT5kaXJ0eS55MTsKLQkJ aWYgKHFmYmRldi0+ZGlydHkueTIgPiB5MikKLQkJCXkyID0gcWZiZGV2LT5kaXJ0eS55MjsKLQkJ aWYgKHFmYmRldi0+ZGlydHkueDEgPCB4KQotCQkJeCA9IHFmYmRldi0+ZGlydHkueDE7Ci0JCWlm IChxZmJkZXYtPmRpcnR5LngyID4geDIpCi0JCQl4MiA9IHFmYmRldi0+ZGlydHkueDI7Ci0JfQot Ci0JcWZiZGV2LT5kaXJ0eS54MSA9IHg7Ci0JcWZiZGV2LT5kaXJ0eS54MiA9IHgyOwotCXFmYmRl di0+ZGlydHkueTEgPSB5OwotCXFmYmRldi0+ZGlydHkueTIgPSB5MjsKLQotCXNwaW5fdW5sb2Nr X2lycXJlc3RvcmUoJnFmYmRldi0+ZGlydHkubG9jaywgZmxhZ3MpOwotCi0Jc2NoZWR1bGVfd29y aygmcWRldi0+ZmJfd29yayk7Ci19Ci0KLXN0YXRpYyB2b2lkIHF4bF9kZWZlcnJlZF9pbyhzdHJ1 Y3QgZmJfaW5mbyAqaW5mbywKLQkJCSAgICBzdHJ1Y3QgbGlzdF9oZWFkICpwYWdlbGlzdCkKLXsK LQlzdHJ1Y3QgcXhsX2ZiZGV2ICpxZmJkZXYgPSBpbmZvLT5wYXI7Ci0JdW5zaWduZWQgbG9uZyBz dGFydCwgZW5kLCBtaW4sIG1heDsKLQlzdHJ1Y3QgcGFnZSAqcGFnZTsKLQlpbnQgeTEsIHkyOwot Ci0JbWluID0gVUxPTkdfTUFYOwotCW1heCA9IDA7Ci0JbGlzdF9mb3JfZWFjaF9lbnRyeShwYWdl LCBwYWdlbGlzdCwgbHJ1KSB7Ci0JCXN0YXJ0ID0gcGFnZS0+aW5kZXggPDwgUEFHRV9TSElGVDsK LQkJZW5kID0gc3RhcnQgKyBQQUdFX1NJWkUgLSAxOwotCQltaW4gPSBtaW4obWluLCBzdGFydCk7 Ci0JCW1heCA9IG1heChtYXgsIGVuZCk7Ci0JfQotCi0JaWYgKG1pbiA8IG1heCkgewotCQl5MSA9 IG1pbiAvIGluZm8tPmZpeC5saW5lX2xlbmd0aDsKLQkJeTIgPSAobWF4IC8gaW5mby0+Zml4Lmxp bmVfbGVuZ3RoKSArIDE7Ci0JCXF4bF9kaXJ0eV91cGRhdGUocWZiZGV2LCAwLCB5MSwgaW5mby0+ dmFyLnhyZXMsIHkyIC0geTEpOwotCX0KLX07Ci0KIHN0YXRpYyBzdHJ1Y3QgZmJfZGVmZXJyZWRf aW8gcXhsX2RlZmlvID0gewogCS5kZWxheQkJPSBRWExfRElSVFlfREVMQVksCi0JLmRlZmVycmVk X2lvCT0gcXhsX2RlZmVycmVkX2lvLAorCS5kZWZlcnJlZF9pbwk9IGRybV9mYl9oZWxwZXJfZGVm ZXJyZWRfaW8sCiB9OwogCi1zdGF0aWMgdm9pZCBxeGxfZmJfZmlsbHJlY3Qoc3RydWN0IGZiX2lu Zm8gKmluZm8sCi0JCQkgICAgY29uc3Qgc3RydWN0IGZiX2ZpbGxyZWN0ICpyZWN0KQotewotCXN0 cnVjdCBxeGxfZmJkZXYgKnFmYmRldiA9IGluZm8tPnBhcjsKLQotCXN5c19maWxscmVjdChpbmZv LCByZWN0KTsKLQlxeGxfZGlydHlfdXBkYXRlKHFmYmRldiwgcmVjdC0+ZHgsIHJlY3QtPmR5LCBy ZWN0LT53aWR0aCwKLQkJCSByZWN0LT5oZWlnaHQpOwotfQotCi1zdGF0aWMgdm9pZCBxeGxfZmJf Y29weWFyZWEoc3RydWN0IGZiX2luZm8gKmluZm8sCi0JCQkgICAgY29uc3Qgc3RydWN0IGZiX2Nv cHlhcmVhICphcmVhKQotewotCXN0cnVjdCBxeGxfZmJkZXYgKnFmYmRldiA9IGluZm8tPnBhcjsK LQotCXN5c19jb3B5YXJlYShpbmZvLCBhcmVhKTsKLQlxeGxfZGlydHlfdXBkYXRlKHFmYmRldiwg YXJlYS0+ZHgsIGFyZWEtPmR5LCBhcmVhLT53aWR0aCwKLQkJCSBhcmVhLT5oZWlnaHQpOwotfQot Ci1zdGF0aWMgdm9pZCBxeGxfZmJfaW1hZ2VibGl0KHN0cnVjdCBmYl9pbmZvICppbmZvLAotCQkJ ICAgICBjb25zdCBzdHJ1Y3QgZmJfaW1hZ2UgKmltYWdlKQotewotCXN0cnVjdCBxeGxfZmJkZXYg KnFmYmRldiA9IGluZm8tPnBhcjsKLQotCXN5c19pbWFnZWJsaXQoaW5mbywgaW1hZ2UpOwotCXF4 bF9kaXJ0eV91cGRhdGUocWZiZGV2LCBpbWFnZS0+ZHgsIGltYWdlLT5keSwgaW1hZ2UtPndpZHRo LAotCQkJIGltYWdlLT5oZWlnaHQpOwotfQotCi1zdGF0aWMgdm9pZCBxeGxfZmJfd29yayhzdHJ1 Y3Qgd29ya19zdHJ1Y3QgKndvcmspCi17Ci0Jc3RydWN0IHF4bF9kZXZpY2UgKnFkZXYgPSBjb250 YWluZXJfb2Yod29yaywgc3RydWN0IHF4bF9kZXZpY2UsIGZiX3dvcmspOwotCXN0cnVjdCBxeGxf ZmJkZXYgKnFmYmRldiA9IHFkZXYtPm1vZGVfaW5mby5xZmJkZXY7Ci0KLQlxeGxfZmJfZGlydHlf Zmx1c2gocWZiZGV2LT5oZWxwZXIuZmJkZXYpOwotfQotCi1pbnQgcXhsX2ZiX2luaXQoc3RydWN0 IHF4bF9kZXZpY2UgKnFkZXYpCi17Ci0JSU5JVF9XT1JLKCZxZGV2LT5mYl93b3JrLCBxeGxfZmJf d29yayk7Ci0JcmV0dXJuIDA7Ci19Ci0KIHN0YXRpYyBzdHJ1Y3QgZmJfb3BzIHF4bGZiX29wcyA9 IHsKIAkub3duZXIgPSBUSElTX01PRFVMRSwKIAkuZmJfY2hlY2tfdmFyID0gZHJtX2ZiX2hlbHBl cl9jaGVja192YXIsCiAJLmZiX3NldF9wYXIgPSBkcm1fZmJfaGVscGVyX3NldF9wYXIsIC8qIFRP RE86IGNvcHkgdm13Z2Z4ICovCi0JLmZiX2ZpbGxyZWN0ID0gcXhsX2ZiX2ZpbGxyZWN0LAotCS5m Yl9jb3B5YXJlYSA9IHF4bF9mYl9jb3B5YXJlYSwKLQkuZmJfaW1hZ2VibGl0ID0gcXhsX2ZiX2lt YWdlYmxpdCwKKwkuZmJfZmlsbHJlY3QgPSBkcm1fZmJfaGVscGVyX3N5c19maWxscmVjdCwKKwku ZmJfY29weWFyZWEgPSBkcm1fZmJfaGVscGVyX3N5c19jb3B5YXJlYSwKKwkuZmJfaW1hZ2VibGl0 ID0gZHJtX2ZiX2hlbHBlcl9zeXNfaW1hZ2VibGl0LAogCS5mYl9wYW5fZGlzcGxheSA9IGRybV9m Yl9oZWxwZXJfcGFuX2Rpc3BsYXksCiAJLmZiX2JsYW5rID0gZHJtX2ZiX2hlbHBlcl9ibGFuaywK IAkuZmJfc2V0Y21hcCA9IGRybV9mYl9oZWxwZXJfc2V0Y21hcCwKQEAgLTMzOCw2ICsxNzksNTMg QEAgb3V0X3VucmVmOgogCXJldHVybiByZXQ7CiB9CiAKK3N0YXRpYyBpbnQgcXhsZmJfZnJhbWVi dWZmZXJfZGlydHkoc3RydWN0IGRybV9mcmFtZWJ1ZmZlciAqZmIsCisJCQkJICAgc3RydWN0IGRy bV9maWxlICpmaWxlX3ByaXYsCisJCQkJICAgdW5zaWduZWQgZmxhZ3MsIHVuc2lnbmVkIGNvbG9y LAorCQkJCSAgIHN0cnVjdCBkcm1fY2xpcF9yZWN0ICpjbGlwcywKKwkJCQkgICB1bnNpZ25lZCBu dW1fY2xpcHMpCit7CisJc3RydWN0IHF4bF9kZXZpY2UgKnFkZXYgPSBmYi0+ZGV2LT5kZXZfcHJp dmF0ZTsKKwlzdHJ1Y3QgZmJfaW5mbyAqaW5mbyA9IHFkZXYtPmZiZGV2X2luZm87CisJc3RydWN0 IHF4bF9mYmRldiAqcWZiZGV2ID0gaW5mby0+cGFyOworCXN0cnVjdCBxeGxfZmJfaW1hZ2UgcXhs X2ZiX2ltYWdlOworCXN0cnVjdCBmYl9pbWFnZSAqaW1hZ2UgPSAmcXhsX2ZiX2ltYWdlLmZiX2lt YWdlOworCisJLyogVE9ETzogaGFyZCBjb2RpbmcgMzIgYnBwICovCisJaW50IHN0cmlkZSA9IHFm YmRldi0+cWZiLmJhc2UucGl0Y2hlc1swXTsKKworCS8qCisJICogd2UgYXJlIHVzaW5nIGEgc2hh ZG93IGRyYXcgYnVmZmVyLCBhdCBxZGV2LT5zdXJmYWNlMF9zaGFkb3cKKwkgKi8KKwlxeGxfaW9f bG9nKHFkZXYsICJkaXJ0eSB4WyVkLCAlZF0sIHlbJWQsICVkXSIsIGNsaXBzLT54MSwgY2xpcHMt PngyLAorCQkgICBjbGlwcy0+eTEsIGNsaXBzLT55Mik7CisJaW1hZ2UtPmR4ID0gY2xpcHMtPngx OworCWltYWdlLT5keSA9IGNsaXBzLT55MTsKKwlpbWFnZS0+d2lkdGggPSBkcm1fY2xpcF9yZWN0 X3dpZHRoKGNsaXBzKTsKKwlpbWFnZS0+aGVpZ2h0ID0gZHJtX2NsaXBfcmVjdF9oZWlnaHQoY2xp cHMpOworCWltYWdlLT5mZ19jb2xvciA9IDB4ZmZmZmZmZmY7IC8qIHVudXNlZCwganVzdCB0byBh dm9pZCB1bmluaXRpYWxpemVkCisJCQkJCSB3YXJuaW5ncyAqLworCWltYWdlLT5iZ19jb2xvciA9 IDA7CisJaW1hZ2UtPmRlcHRoID0gMzI7CSAgICAgLyogVE9ETzogdGFrZSBmcm9tIHNvbWV3aGVy ZT8gKi8KKwlpbWFnZS0+Y21hcC5zdGFydCA9IDA7CisJaW1hZ2UtPmNtYXAubGVuID0gMDsKKwlp bWFnZS0+Y21hcC5yZWQgPSBOVUxMOworCWltYWdlLT5jbWFwLmdyZWVuID0gTlVMTDsKKwlpbWFn ZS0+Y21hcC5ibHVlID0gTlVMTDsKKwlpbWFnZS0+Y21hcC50cmFuc3AgPSBOVUxMOworCWltYWdl LT5kYXRhID0gcWZiZGV2LT5zaGFkb3cgKyAoY2xpcHMtPngxICogNCkgKyAoc3RyaWRlICogY2xp cHMtPnkxKTsKKworCXF4bF9mYl9pbWFnZV9pbml0KCZxeGxfZmJfaW1hZ2UsIHFkZXYsIGluZm8s IE5VTEwpOworCXF4bF9kcmF3X29wYXF1ZV9mYigmcXhsX2ZiX2ltYWdlLCBzdHJpZGUpOworCisJ cmV0dXJuIDA7Cit9CisKK3N0YXRpYyBjb25zdCBzdHJ1Y3QgZHJtX2ZyYW1lYnVmZmVyX2Z1bmNz IHF4bGZiX2ZiX2Z1bmNzID0geworCS5kZXN0cm95ID0gcXhsX3VzZXJfZnJhbWVidWZmZXJfZGVz dHJveSwKKwkuZGlydHkgPSBxeGxmYl9mcmFtZWJ1ZmZlcl9kaXJ0eSwKK307CisKIHN0YXRpYyBp bnQgcXhsZmJfY3JlYXRlKHN0cnVjdCBxeGxfZmJkZXYgKnFmYmRldiwKIAkJCXN0cnVjdCBkcm1f ZmJfaGVscGVyX3N1cmZhY2Vfc2l6ZSAqc2l6ZXMpCiB7CkBAIC0zODMsNyArMjcxLDggQEAgc3Rh dGljIGludCBxeGxmYl9jcmVhdGUoc3RydWN0IHF4bF9mYmRldiAqcWZiZGV2LAogCiAJaW5mby0+ cGFyID0gcWZiZGV2OwogCi0JcXhsX2ZyYW1lYnVmZmVyX2luaXQocWRldi0+ZGRldiwgJnFmYmRl di0+cWZiLCAmbW9kZV9jbWQsIGdvYmopOworCXF4bF9mcmFtZWJ1ZmZlcl9pbml0KHFkZXYtPmRk ZXYsICZxZmJkZXYtPnFmYiwgJm1vZGVfY21kLCBnb2JqLAorCQkJICAgICAmcXhsZmJfZmJfZnVu Y3MpOwogCiAJZmIgPSAmcWZiZGV2LT5xZmIuYmFzZTsKIApAQCAtNTA0LDcgKzM5Myw2IEBAIGlu dCBxeGxfZmJkZXZfaW5pdChzdHJ1Y3QgcXhsX2RldmljZSAqcWRldikKIAlxZmJkZXYtPnFkZXYg PSBxZGV2OwogCXFkZXYtPm1vZGVfaW5mby5xZmJkZXYgPSBxZmJkZXY7CiAJc3Bpbl9sb2NrX2lu aXQoJnFmYmRldi0+ZGVsYXllZF9vcHNfbG9jayk7Ci0Jc3Bpbl9sb2NrX2luaXQoJnFmYmRldi0+ ZGlydHkubG9jayk7CiAJSU5JVF9MSVNUX0hFQUQoJnFmYmRldi0+ZGVsYXllZF9vcHMpOwogCiAJ ZHJtX2ZiX2hlbHBlcl9wcmVwYXJlKHFkZXYtPmRkZXYsICZxZmJkZXYtPmhlbHBlciwKZGlmZiAt LWdpdCBhL2RyaXZlcnMvZ3B1L2RybS9xeGwvcXhsX2ttcy5jIGIvZHJpdmVycy9ncHUvZHJtL3F4 bC9xeGxfa21zLmMKaW5kZXggYjI5NzdhMS4uMjMxOTgwMCAxMDA2NDQKLS0tIGEvZHJpdmVycy9n cHUvZHJtL3F4bC9xeGxfa21zLmMKKysrIGIvZHJpdmVycy9ncHUvZHJtL3F4bC9xeGxfa21zLmMK QEAgLTI2MSwxMCArMjYxLDYgQEAgc3RhdGljIGludCBxeGxfZGV2aWNlX2luaXQoc3RydWN0IHF4 bF9kZXZpY2UgKnFkZXYsCiAJcWRldi0+Z2NfcXVldWUgPSBjcmVhdGVfc2luZ2xldGhyZWFkX3dv cmtxdWV1ZSgicXhsX2djIik7CiAJSU5JVF9XT1JLKCZxZGV2LT5nY193b3JrLCBxeGxfZ2Nfd29y ayk7CiAKLQlyID0gcXhsX2ZiX2luaXQocWRldik7Ci0JaWYgKHIpCi0JCXJldHVybiByOwotCiAJ cmV0dXJuIDA7CiB9CiAKLS0gCjIuMi4yCgpfX19fX19fX19fX19fX19fX19fX19fX19fX19fX19f X19fX19fX19fX19fX19fXwpkcmktZGV2ZWwgbWFpbGluZyBsaXN0CmRyaS1kZXZlbEBsaXN0cy5m cmVlZGVza3RvcC5vcmcKaHR0cHM6Ly9saXN0cy5mcmVlZGVza3RvcC5vcmcvbWFpbG1hbi9saXN0 aW5mby9kcmktZGV2ZWwK