Skip to content

Commit

Permalink
drm: Merge branch 'drm-gma500-alancox' into drm-core-next
Browse files Browse the repository at this point in the history
This merges a topic branch containing patches from Alan for the GMA500 driver.

* drm-gma500-alancox:
  gma500: Oaktrail BIOS handling
  gma500: Fix oaktrail probing part 1
  gma500: Be smarter about layout
  gma500: gtt based hardware scrolling console
  gma500: frame buffer locking
  gma500: Fix backlight crash
  gma500: kill bogus code
  gma500: Convert spaces to tabs in accel_2d.c.
  gma500: do a pass over the FIXME tags
  gma500: Add VBLANK support for Poulsbo hardware
  gma500: Don't enable MSI on Poulsbo
  gma500: Only register interrupt handler for poulsbo hardware
  gma500: kill virtual mapping support
  gma500: Move the API
  gma500: kill off NUM_PIPE define
  gma500: Rename the ioctls to avoid clashing with the legacy drivers
  drm/gma500: begin pruning dead bits of API
  • Loading branch information
Dave Airlie committed Dec 6, 2011
2 parents 04b3924 + 1b22edf commit cee5ec4
Show file tree
Hide file tree
Showing 22 changed files with 437 additions and 937 deletions.
12 changes: 7 additions & 5 deletions drivers/gpu/drm/gma500/accel_2d.c
Original file line number Diff line number Diff line change
Expand Up @@ -111,14 +111,15 @@ static int psbfb_2d_submit(struct drm_psb_private *dev_priv, uint32_t *cmdbuf,
int ret = 0;
int i;
unsigned submit_size;
unsigned long flags;

mutex_lock(&dev_priv->mutex_2d);
spin_lock_irqsave(&dev_priv->lock_2d, flags);
while (size > 0) {
submit_size = (size < 0x60) ? size : 0x60;
size -= submit_size;
ret = psb_2d_wait_available(dev_priv, submit_size);
if (ret)
break;
break;

submit_size <<= 2;

Expand All @@ -127,7 +128,7 @@ static int psbfb_2d_submit(struct drm_psb_private *dev_priv, uint32_t *cmdbuf,

(void)PSB_RSGX32(PSB_SGX_2D_SLAVE_PORT + i - 4);
}
mutex_unlock(&dev_priv->mutex_2d);
spin_unlock_irqrestore(&dev_priv->lock_2d, flags);
return ret;
}

Expand Down Expand Up @@ -327,8 +328,9 @@ int psbfb_sync(struct fb_info *info)
struct drm_psb_private *dev_priv = dev->dev_private;
unsigned long _end = jiffies + DRM_HZ;
int busy = 0;
unsigned long flags;

mutex_lock(&dev_priv->mutex_2d);
spin_lock_irqsave(&dev_priv->lock_2d, flags);
/*
* First idle the 2D engine.
*/
Expand Down Expand Up @@ -357,6 +359,6 @@ int psbfb_sync(struct fb_info *info)
_PSB_C2B_STATUS_BUSY) != 0);

out:
mutex_unlock(&dev_priv->mutex_2d);
spin_unlock_irqrestore(&dev_priv->lock_2d, flags);
return (busy) ? -EBUSY : 0;
}
3 changes: 1 addition & 2 deletions drivers/gpu/drm/gma500/cdv_device.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
#include <linux/backlight.h>
#include <drm/drmP.h>
#include <drm/drm.h>
#include "psb_drm.h"
#include "gma_drm.h"
#include "psb_drv.h"
#include "psb_reg.h"
#include "psb_intel_reg.h"
Expand All @@ -30,7 +30,6 @@
#define VGA_SR_INDEX 0x3c4
#define VGA_SR_DATA 0x3c5

/* FIXME: should check if we are the active VGA device ?? */
static void cdv_disable_vga(struct drm_device *dev)
{
u8 sr1;
Expand Down
154 changes: 97 additions & 57 deletions drivers/gpu/drm/gma500/framebuffer.c
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
#include "psb_intel_reg.h"
#include "psb_intel_drv.h"
#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,
Expand Down Expand Up @@ -90,6 +91,25 @@ static int psbfb_setcolreg(unsigned regno, unsigned red, unsigned green,
return 0;
}

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;

/*
* 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) {
/* 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);
}
return 0;
}

void psbfb_suspend(struct drm_device *dev)
{
Expand Down Expand Up @@ -216,6 +236,21 @@ static struct fb_ops psbfb_ops = {
.fb_ioctl = psbfb_ioctl,
};

static struct fb_ops psbfb_roll_ops = {
.owner = THIS_MODULE,
.fb_check_var = drm_fb_helper_check_var,
.fb_set_par = drm_fb_helper_set_par,
.fb_blank = drm_fb_helper_blank,
.fb_setcolreg = psbfb_setcolreg,
.fb_fillrect = cfb_fillrect,
.fb_copyarea = cfb_copyarea,
.fb_imageblit = cfb_imageblit,
.fb_pan_display = psbfb_pan,
.fb_mmap = psbfb_mmap,
.fb_sync = psbfb_sync,
.fb_ioctl = psbfb_ioctl,
};

static struct fb_ops psbfb_unaccel_ops = {
.owner = THIS_MODULE,
.fb_check_var = drm_fb_helper_check_var,
Expand Down Expand Up @@ -306,16 +341,14 @@ static struct drm_framebuffer *psb_framebuffer_create
* psbfb_alloc - allocate frame buffer memory
* @dev: the DRM device
* @aligned_size: space needed
* @force: fall back to GEM buffers if need be
*
* Allocate the frame buffer. In the usual case we get a GTT range that
* is stolen memory backed and life is simple. If there isn't sufficient
* stolen memory or the system has no stolen memory we allocate a range
* and back it with a GEM object.
* we fail as we don't have the virtual mapping space to really vmap it
* and the kernel console code can't handle non linear framebuffers.
*
* In this case the GEM object has no handle.
*
* FIXME: console speed up - allocate twice the space if room and use
* hardware scrolling for acceleration.
* Re-address this as and if the framebuffer layer grows this ability.
*/
static struct gtt_range *psbfb_alloc(struct drm_device *dev, int aligned_size)
{
Expand All @@ -328,17 +361,7 @@ static struct gtt_range *psbfb_alloc(struct drm_device *dev, int aligned_size)
return backing;
psb_gtt_free_range(dev, backing);
}
/* Next try using GEM host memory */
backing = psb_gtt_alloc_range(dev, aligned_size, "fb(gem)", 0);
if (backing == NULL)
return NULL;

/* Now back it with an object */
if (drm_gem_object_init(dev, &backing->gem, aligned_size) != 0) {
psb_gtt_free_range(dev, backing);
return NULL;
}
return backing;
return NULL;
}

/**
Expand All @@ -362,6 +385,8 @@ static int psbfb_create(struct psb_fbdev *fbdev,
int ret;
struct gtt_range *backing;
u32 bpp, depth;
int gtt_roll = 0;
int pitch_lines = 0;

mode_cmd.width = sizes->surface_width;
mode_cmd.height = sizes->surface_height;
Expand All @@ -371,17 +396,51 @@ static int psbfb_create(struct psb_fbdev *fbdev,
if (bpp == 24)
bpp = 32;

/* HW requires pitch to be 64 byte aligned */
mode_cmd.pitches[0] = ALIGN(mode_cmd.width * ((bpp + 7) / 8), 64);
depth = sizes->surface_depth;
do {
/*
* Acceleration via the GTT requires pitch to be
* power of two aligned. Preferably page but less
* is ok with some fonts
*/
mode_cmd.pitches[0] = ALIGN(mode_cmd.width * ((bpp + 7) / 8), 4096 >> pitch_lines);
depth = sizes->surface_depth;

size = mode_cmd.pitches[0] * mode_cmd.height;
size = ALIGN(size, PAGE_SIZE);
size = mode_cmd.pitches[0] * mode_cmd.height;
size = ALIGN(size, PAGE_SIZE);

/* Allocate the framebuffer in the GTT with stolen page backing */
backing = psbfb_alloc(dev, size);
if (backing == NULL)
return -ENOMEM;
/* Allocate the fb in the GTT with stolen page backing */
backing = psbfb_alloc(dev, size);

if (pitch_lines)
pitch_lines *= 2;
else
pitch_lines = 1;
gtt_roll++;
} while (backing == NULL && pitch_lines <= 16);

/* The final pitch we accepted if we succeeded */
pitch_lines /= 2;

if (backing == NULL) {
/*
* We couldn't get the space we wanted, fall back to the
* display engine requirement instead. The HW requires
* the pitch to be 64 byte aligned
*/

gtt_roll = 0; /* Don't use GTT accelerated scrolling */
pitch_lines = 64;

mode_cmd.pitches[0] = ALIGN(mode_cmd.width * ((bpp + 7) / 8), 64);

size = mode_cmd.pitches[0] * mode_cmd.height;
size = ALIGN(size, PAGE_SIZE);

/* Allocate the framebuffer in the GTT with stolen page backing */
backing = psbfb_alloc(dev, size);
if (backing == NULL)
return -ENOMEM;
}

mutex_lock(&dev->struct_mutex);

Expand All @@ -407,11 +466,13 @@ static int psbfb_create(struct psb_fbdev *fbdev,
strcpy(info->fix.id, "psbfb");

info->flags = FBINFO_DEFAULT;
/* No 2D engine */
if (!dev_priv->ops->accel_2d)
info->fbops = &psbfb_unaccel_ops;
else
if (dev_priv->ops->accel_2d && pitch_lines > 8) /* 2D engine */
info->fbops = &psbfb_ops;
else if (gtt_roll) { /* GTT rolling seems best */
info->fbops = &psbfb_roll_ops;
info->flags |= FBINFO_HWACCEL_YPAN;
} else /* Software */
info->fbops = &psbfb_unaccel_ops;

ret = fb_alloc_cmap(&info->cmap, 256, 0);
if (ret) {
Expand All @@ -421,23 +482,12 @@ static int psbfb_create(struct psb_fbdev *fbdev,

info->fix.smem_start = dev->mode_config.fb_base;
info->fix.smem_len = size;
info->fix.ywrapstep = gtt_roll;
info->fix.ypanstep = 0;

if (backing->stolen) {
/* Accessed stolen memory directly */
info->screen_base = (char *)dev_priv->vram_addr +
/* Accessed stolen memory directly */
info->screen_base = (char *)dev_priv->vram_addr +
backing->offset;
} else {
/* Pin the pages into the GTT and create a mapping to them */
psb_gtt_pin(backing);
info->screen_base = vm_map_ram(backing->pages, backing->npage,
-1, PAGE_KERNEL);
if (info->screen_base == NULL) {
psb_gtt_unpin(backing);
ret = -ENOMEM;
goto out_unref;
}
psbfb->vm_map = 1;
}
info->screen_size = size;

if (dev_priv->gtt.stolen_size) {
Expand Down Expand Up @@ -471,11 +521,8 @@ static int psbfb_create(struct psb_fbdev *fbdev,
out_unref:
if (backing->stolen)
psb_gtt_free_range(dev, backing);
else {
if (psbfb->vm_map)
vm_unmap_ram(info->screen_base, backing->npage);
else
drm_gem_object_unreference(&backing->gem);
}
out_err1:
mutex_unlock(&dev->struct_mutex);
psb_gtt_free_range(dev, backing);
Expand Down Expand Up @@ -549,13 +596,6 @@ int psb_fbdev_destroy(struct drm_device *dev, struct psb_fbdev *fbdev)

if (fbdev->psb_fb_helper.fbdev) {
info = fbdev->psb_fb_helper.fbdev;

/* If this is our base framebuffer then kill any virtual map
for the framebuffer layer and unpin it */
if (psbfb->vm_map) {
vm_unmap_ram(info->screen_base, psbfb->gtt->npage);
psb_gtt_unpin(psbfb->gtt);
}
unregister_framebuffer(info);
if (info->cmap.len)
fb_dealloc_cmap(&info->cmap);
Expand Down Expand Up @@ -765,7 +805,7 @@ void psb_modeset_init(struct drm_device *dev)
dev->mode_config.funcs = (void *) &psb_mode_funcs;

/* set memory base */
/* MRST and PSB should use BAR 2*/
/* Oaktrail and Poulsbo should use BAR 2*/
pci_read_config_dword(dev->pdev, PSB_BSM, (u32 *)
&(dev->mode_config.fb_base));

Expand Down
1 change: 0 additions & 1 deletion drivers/gpu/drm/gma500/framebuffer.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@ struct psb_framebuffer {
struct address_space *addr_space;
struct fb_info *fbdev;
struct gtt_range *gtt;
bool vm_map; /* True if we must undo a vm_map_ram */
};

struct psb_fbdev {
Expand Down
11 changes: 4 additions & 7 deletions drivers/gpu/drm/gma500/gem.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@

#include <drm/drmP.h>
#include <drm/drm.h>
#include "psb_drm.h"
#include "gma_drm.h"
#include "psb_drv.h"

int psb_gem_init_object(struct drm_gem_object *obj)
Expand Down Expand Up @@ -120,8 +120,7 @@ static int psb_gem_create(struct drm_file *file,
/* Initialize the extra goodies GEM needs to do all the hard work */
if (drm_gem_object_init(dev, &r->gem, size) != 0) {
psb_gtt_free_range(dev, r);
/* GEM doesn't give an error code and we don't have an
EGEMSUCKS so make something up for now - FIXME */
/* GEM doesn't give an error code so use -ENOMEM */
dev_err(dev->dev, "GEM init failed for %lld\n", size);
return -ENOMEM;
}
Expand Down Expand Up @@ -191,8 +190,6 @@ int psb_gem_dumb_destroy(struct drm_file *file, struct drm_device *dev,
* The VMA was set up by GEM. In doing so it also ensured that the
* vma->vm_private_data points to the GEM object that is backing this
* mapping.
*
* FIXME
*/
int psb_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
{
Expand Down Expand Up @@ -274,13 +271,13 @@ int psb_gem_create_ioctl(struct drm_device *dev, void *data,
{
struct drm_psb_gem_create *args = data;
int ret;
if (args->flags & PSB_GEM_CREATE_STOLEN) {
if (args->flags & GMA_GEM_CREATE_STOLEN) {
ret = psb_gem_create_stolen(file, dev, args->size,
&args->handle);
if (ret == 0)
return 0;
/* Fall throguh */
args->flags &= ~PSB_GEM_CREATE_STOLEN;
args->flags &= ~GMA_GEM_CREATE_STOLEN;
}
return psb_gem_create(file, dev, args->size, &args->handle);
}
Expand Down
Loading

0 comments on commit cee5ec4

Please sign in to comment.