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 <daniels@collabora.com> Reviewed-by: Thierry Reding <treding@nvidia.com> Cc: Patrik Jakobsson <patrik.r.jakobsson@gmail.com> Link: https://patchwork.freedesktop.org/patch/msgid/20180330141138.28987-20-daniels@collabora.com
This commit is contained in:
Родитель
ecb8a94785
Коммит
bc61c97502
|
@ -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) {
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
#include <drm/drm.h>
|
||||
#include <drm/drm_crtc.h>
|
||||
#include <drm/drm_fb_helper.h>
|
||||
#include <drm/drm_gem_framebuffer_helper.h>
|
||||
|
||||
#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,
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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]);
|
||||
|
|
Загрузка…
Ссылка в новой задаче