From bc61c97502e26af1be54022883d14ee0c03379fc Mon Sep 17 00:00:00 2001 From: Daniel Stone Date: Fri, 30 Mar 2018 15:11:34 +0100 Subject: drm/gma500: Move GEM BO to drm_framebuffer Since drm_framebuffer can now store GEM objects directly, place them there rather than in our own subclass. As this makes the framebuffer create_handle and destroy functions the same as the GEM framebuffer helper, we can reuse those. Signed-off-by: Daniel Stone Reviewed-by: Thierry Reding Cc: Patrik Jakobsson Link: https://patchwork.freedesktop.org/patch/msgid/20180330141138.28987-20-daniels@collabora.com --- drivers/gpu/drm/gma500/accel_2d.c | 2 +- drivers/gpu/drm/gma500/framebuffer.c | 62 ++++++---------------------------- drivers/gpu/drm/gma500/framebuffer.h | 1 - drivers/gpu/drm/gma500/gma_display.c | 10 +++--- drivers/gpu/drm/gma500/gtt.h | 2 ++ drivers/gpu/drm/gma500/oaktrail_crtc.c | 3 +- 6 files changed, 20 insertions(+), 60 deletions(-) (limited to 'drivers/gpu/drm/gma500') diff --git a/drivers/gpu/drm/gma500/accel_2d.c b/drivers/gpu/drm/gma500/accel_2d.c index c51d9259c7a7..204c8e452eb7 100644 --- a/drivers/gpu/drm/gma500/accel_2d.c +++ b/drivers/gpu/drm/gma500/accel_2d.c @@ -251,7 +251,7 @@ static void psbfb_copyarea_accel(struct fb_info *info, if (!fb) return; - offset = psbfb->gtt->offset; + offset = to_gtt_range(fb->obj[0])->offset; stride = fb->pitches[0]; switch (fb->format->depth) { diff --git a/drivers/gpu/drm/gma500/framebuffer.c b/drivers/gpu/drm/gma500/framebuffer.c index cb0a2ae916e0..8fa4ef192c1e 100644 --- a/drivers/gpu/drm/gma500/framebuffer.c +++ b/drivers/gpu/drm/gma500/framebuffer.c @@ -33,6 +33,7 @@ #include #include #include +#include #include "psb_drv.h" #include "psb_intel_reg.h" @@ -40,14 +41,9 @@ #include "framebuffer.h" #include "gtt.h" -static void psb_user_framebuffer_destroy(struct drm_framebuffer *fb); -static int psb_user_framebuffer_create_handle(struct drm_framebuffer *fb, - struct drm_file *file_priv, - unsigned int *handle); - static const struct drm_framebuffer_funcs psb_fb_funcs = { - .destroy = psb_user_framebuffer_destroy, - .create_handle = psb_user_framebuffer_create_handle, + .destroy = drm_gem_fb_destroy, + .create_handle = drm_gem_fb_create_handle, }; #define CMAP_TOHW(_val, _width) ((((_val) << (_width)) + 0x7FFF - (_val)) >> 16) @@ -96,17 +92,18 @@ static int psbfb_pan(struct fb_var_screeninfo *var, struct fb_info *info) struct psb_fbdev *fbdev = info->par; struct psb_framebuffer *psbfb = &fbdev->pfb; struct drm_device *dev = psbfb->base.dev; + struct gtt_range *gtt = to_gtt_range(psbfb->base.obj[0]); /* * We have to poke our nose in here. The core fb code assumes * panning is part of the hardware that can be invoked before * the actual fb is mapped. In our case that isn't quite true. */ - if (psbfb->gtt->npage) { + if (gtt->npage) { /* GTT roll shifts in 4K pages, we need to shift the right number of pages */ int pages = info->fix.line_length >> 12; - psb_gtt_roll(dev, psbfb->gtt, var->yoffset * pages); + psb_gtt_roll(dev, gtt, var->yoffset * pages); } return 0; } @@ -117,13 +114,14 @@ static int psbfb_vm_fault(struct vm_fault *vmf) struct psb_framebuffer *psbfb = vma->vm_private_data; struct drm_device *dev = psbfb->base.dev; struct drm_psb_private *dev_priv = dev->dev_private; + struct gtt_range *gtt = to_gtt_range(psbfb->base.obj[0]); int page_num; int i; unsigned long address; int ret; unsigned long pfn; unsigned long phys_addr = (unsigned long)dev_priv->stolen_base + - psbfb->gtt->offset; + gtt->offset; page_num = vma_pages(vma); address = vmf->address - (vmf->pgoff << PAGE_SHIFT); @@ -246,7 +244,7 @@ static int psb_framebuffer_init(struct drm_device *dev, return -EINVAL; drm_helper_mode_fill_fb_struct(dev, &fb->base, mode_cmd); - fb->gtt = gt; + fb->base.obj[0] = >->gem; ret = drm_framebuffer_init(dev, &fb->base, &psb_fb_funcs); if (ret) { dev_err(dev->dev, "framebuffer init failed: %d\n", ret); @@ -518,8 +516,8 @@ static int psb_fbdev_destroy(struct drm_device *dev, struct psb_fbdev *fbdev) drm_framebuffer_unregister_private(&psbfb->base); drm_framebuffer_cleanup(&psbfb->base); - if (psbfb->gtt) - drm_gem_object_unreference_unlocked(&psbfb->gtt->gem); + if (psbfb->base.obj[0]) + drm_gem_object_unreference_unlocked(psbfb->base.obj[0]); return 0; } @@ -576,44 +574,6 @@ static void psb_fbdev_fini(struct drm_device *dev) dev_priv->fbdev = NULL; } -/** - * psb_user_framebuffer_create_handle - add hamdle to a framebuffer - * @fb: framebuffer - * @file_priv: our DRM file - * @handle: returned handle - * - * Our framebuffer object is a GTT range which also contains a GEM - * object. We need to turn it into a handle for userspace. GEM will do - * the work for us - */ -static int psb_user_framebuffer_create_handle(struct drm_framebuffer *fb, - struct drm_file *file_priv, - unsigned int *handle) -{ - struct psb_framebuffer *psbfb = to_psb_fb(fb); - struct gtt_range *r = psbfb->gtt; - return drm_gem_handle_create(file_priv, &r->gem, handle); -} - -/** - * psb_user_framebuffer_destroy - destruct user created fb - * @fb: framebuffer - * - * User framebuffers are backed by GEM objects so all we have to do is - * clean up a bit and drop the reference, GEM will handle the fallout - */ -static void psb_user_framebuffer_destroy(struct drm_framebuffer *fb) -{ - struct psb_framebuffer *psbfb = to_psb_fb(fb); - struct gtt_range *r = psbfb->gtt; - - /* Let DRM do its clean up */ - drm_framebuffer_cleanup(fb); - /* We are no longer using the resource in GEM */ - drm_gem_object_unreference_unlocked(&r->gem); - kfree(fb); -} - static const struct drm_mode_config_funcs psb_mode_funcs = { .fb_create = psb_user_framebuffer_create, .output_poll_changed = drm_fb_helper_output_poll_changed, diff --git a/drivers/gpu/drm/gma500/framebuffer.h b/drivers/gpu/drm/gma500/framebuffer.h index 395f20b07aab..23dc3c5f8f0d 100644 --- a/drivers/gpu/drm/gma500/framebuffer.h +++ b/drivers/gpu/drm/gma500/framebuffer.h @@ -31,7 +31,6 @@ struct psb_framebuffer { struct drm_framebuffer base; struct address_space *addr_space; struct fb_info *fbdev; - struct gtt_range *gtt; }; struct psb_fbdev { diff --git a/drivers/gpu/drm/gma500/gma_display.c b/drivers/gpu/drm/gma500/gma_display.c index f3c48a2be71b..c8f071c47daf 100644 --- a/drivers/gpu/drm/gma500/gma_display.c +++ b/drivers/gpu/drm/gma500/gma_display.c @@ -60,7 +60,7 @@ int gma_pipe_set_base(struct drm_crtc *crtc, int x, int y, struct drm_psb_private *dev_priv = dev->dev_private; struct gma_crtc *gma_crtc = to_gma_crtc(crtc); struct drm_framebuffer *fb = crtc->primary->fb; - struct psb_framebuffer *psbfb = to_psb_fb(fb); + struct gtt_range *gtt = to_gtt_range(fb->obj[0]); int pipe = gma_crtc->pipe; const struct psb_offset *map = &dev_priv->regmap[pipe]; unsigned long start, offset; @@ -78,10 +78,10 @@ int gma_pipe_set_base(struct drm_crtc *crtc, int x, int y, /* We are displaying this buffer, make sure it is actually loaded into the GTT */ - ret = psb_gtt_pin(psbfb->gtt); + ret = psb_gtt_pin(gtt); if (ret < 0) goto gma_pipe_set_base_exit; - start = psbfb->gtt->offset; + start = gtt->offset; offset = y * fb->pitches[0] + x * fb->format->cpp[0]; REG_WRITE(map->stride, fb->pitches[0]); @@ -129,7 +129,7 @@ int gma_pipe_set_base(struct drm_crtc *crtc, int x, int y, gma_pipe_cleaner: /* If there was a previous display we can now unpin it */ if (old_fb) - psb_gtt_unpin(to_psb_fb(old_fb)->gtt); + psb_gtt_unpin(to_gtt_range(old_fb->obj[0])); gma_pipe_set_base_exit: gma_power_end(dev); @@ -491,7 +491,7 @@ void gma_crtc_disable(struct drm_crtc *crtc) crtc_funcs->dpms(crtc, DRM_MODE_DPMS_OFF); if (crtc->primary->fb) { - gt = to_psb_fb(crtc->primary->fb)->gtt; + gt = to_gtt_range(crtc->primary->fb->obj[0]); psb_gtt_unpin(gt); } } diff --git a/drivers/gpu/drm/gma500/gtt.h b/drivers/gpu/drm/gma500/gtt.h index cdbb350c9d5d..cb0c3a2a1fd4 100644 --- a/drivers/gpu/drm/gma500/gtt.h +++ b/drivers/gpu/drm/gma500/gtt.h @@ -53,6 +53,8 @@ struct gtt_range { int roll; /* Roll applied to the GTT entries */ }; +#define to_gtt_range(x) container_of(x, struct gtt_range, gem) + extern struct gtt_range *psb_gtt_alloc_range(struct drm_device *dev, int len, const char *name, int backed, u32 align); diff --git a/drivers/gpu/drm/gma500/oaktrail_crtc.c b/drivers/gpu/drm/gma500/oaktrail_crtc.c index 0fff269d3fe6..1b7fd6a9d8a5 100644 --- a/drivers/gpu/drm/gma500/oaktrail_crtc.c +++ b/drivers/gpu/drm/gma500/oaktrail_crtc.c @@ -600,7 +600,6 @@ static int oaktrail_pipe_set_base(struct drm_crtc *crtc, struct drm_psb_private *dev_priv = dev->dev_private; struct gma_crtc *gma_crtc = to_gma_crtc(crtc); struct drm_framebuffer *fb = crtc->primary->fb; - struct psb_framebuffer *psbfb = to_psb_fb(fb); int pipe = gma_crtc->pipe; const struct psb_offset *map = &dev_priv->regmap[pipe]; unsigned long start, offset; @@ -617,7 +616,7 @@ static int oaktrail_pipe_set_base(struct drm_crtc *crtc, if (!gma_power_begin(dev, true)) return 0; - start = psbfb->gtt->offset; + start = to_gtt_range(fb->obj[0])->offset; offset = y * fb->pitches[0] + x * fb->format->cpp[0]; REG_WRITE(map->stride, fb->pitches[0]); -- cgit v1.2.3 From c7cbed560ce24a87eccf219bc4c78a19961a6074 Mon Sep 17 00:00:00 2001 From: Daniel Stone Date: Mon, 21 May 2018 15:24:49 +0100 Subject: drm/gma500: Fix Medfield for drm_framebuffer move Commit bc61c97502e2 ("drm/gma500: Move GEM BO to drm_framebuffer") moved the gtt_range structure, from being in psb_framebuffer and embedding the GEM object, to being placed in the drm_framebuffer with the gtt_range being derived from the GEM object. The conversion missed out the Medfield subdriver, which was not being built in the default drm-misc config. Do the trivial fixup here. Signed-off-by: Daniel Stone Reported-by: kbuild test robot Reviewed-by: Thierry Reding Fixes: bc61c97502e2 ("drm/gma500: Move GEM BO to drm_framebuffer") Cc: Patrik Jakobsson Link: https://patchwork.freedesktop.org/patch/msgid/20180521142449.20800-1-daniels@collabora.com --- drivers/gpu/drm/gma500/mdfld_intel_display.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/gpu/drm/gma500') diff --git a/drivers/gpu/drm/gma500/mdfld_intel_display.c b/drivers/gpu/drm/gma500/mdfld_intel_display.c index 5c066448be5b..881d613cc2e5 100644 --- a/drivers/gpu/drm/gma500/mdfld_intel_display.c +++ b/drivers/gpu/drm/gma500/mdfld_intel_display.c @@ -196,7 +196,7 @@ static int mdfld__intel_pipe_set_base(struct drm_crtc *crtc, int x, int y, if (!gma_power_begin(dev, true)) return 0; - start = psbfb->gtt->offset; + start = to_gtt_range(fb->obj[0])->offset; offset = y * fb->pitches[0] + x * fb->format->cpp[0]; REG_WRITE(map->stride, fb->pitches[0]); -- cgit v1.2.3 From 520ea9347505f5eb90a6162385cf821e80b6c233 Mon Sep 17 00:00:00 2001 From: Laura Abbott Date: Mon, 9 Apr 2018 14:06:47 -0700 Subject: drm/gma500: Remove VLA There's an ongoing effort to remove VLAs[1] from the kernel to eventually turn on -Wvla. Switch to a reasonable upper bound for the VLAs in the gma500 driver. [1] https://lkml.org/lkml/2018/3/7/621 Signed-off-by: Laura Abbott Reviewed-by: Kees Cook Signed-off-by: Daniel Vetter Link: https://patchwork.freedesktop.org/patch/msgid/20180409210647.3718-1-labbott@redhat.com --- drivers/gpu/drm/gma500/psb_intel_sdvo.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) (limited to 'drivers/gpu/drm/gma500') diff --git a/drivers/gpu/drm/gma500/psb_intel_sdvo.c b/drivers/gpu/drm/gma500/psb_intel_sdvo.c index f2ee6aa10afa..1d40746ab625 100644 --- a/drivers/gpu/drm/gma500/psb_intel_sdvo.c +++ b/drivers/gpu/drm/gma500/psb_intel_sdvo.c @@ -429,13 +429,20 @@ static const char *cmd_status_names[] = { "Scaling not supported" }; +#define MAX_ARG_LEN 32 + static bool psb_intel_sdvo_write_cmd(struct psb_intel_sdvo *psb_intel_sdvo, u8 cmd, const void *args, int args_len) { - u8 buf[args_len*2 + 2], status; - struct i2c_msg msgs[args_len + 3]; + u8 buf[MAX_ARG_LEN*2 + 2], status; + struct i2c_msg msgs[MAX_ARG_LEN + 3]; int i, ret; + if (args_len > MAX_ARG_LEN) { + DRM_ERROR("Need to increase arg length\n"); + return false; + } + psb_intel_sdvo_debug_write(psb_intel_sdvo, cmd, args, args_len); for (i = 0; i < args_len; i++) { -- cgit v1.2.3