summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2011-12-06 09:59:52 +0000
committerDave Airlie <airlied@redhat.com>2011-12-06 09:59:57 +0000
commitcee5ec43460351f0ce4617d3ffb34b74ad613a00 (patch)
tree1c3fddcf3e7fbf086e857884113a748d9b9d17e7
parent04b3924db60f974d2b4af0b2e19a0ae7ca202dc7 (diff)
parent1b22edfd6efd02b6cb9cfe3389ed54731abb3a45 (diff)
drm: Merge branch 'drm-gma500-alancox' into drm-core-next
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
-rw-r--r--drivers/gpu/drm/gma500/accel_2d.c12
-rw-r--r--drivers/gpu/drm/gma500/cdv_device.c3
-rw-r--r--drivers/gpu/drm/gma500/framebuffer.c154
-rw-r--r--drivers/gpu/drm/gma500/framebuffer.h1
-rw-r--r--drivers/gpu/drm/gma500/gem.c11
-rw-r--r--drivers/gpu/drm/gma500/gtt.c81
-rw-r--r--drivers/gpu/drm/gma500/gtt.h3
-rw-r--r--drivers/gpu/drm/gma500/intel_bios.c2
-rw-r--r--drivers/gpu/drm/gma500/intel_opregion.c1
-rw-r--r--drivers/gpu/drm/gma500/mid_bios.c8
-rw-r--r--drivers/gpu/drm/gma500/oaktrail_crtc.c16
-rw-r--r--drivers/gpu/drm/gma500/oaktrail_device.c27
-rw-r--r--drivers/gpu/drm/gma500/oaktrail_lvds.c37
-rw-r--r--drivers/gpu/drm/gma500/power.c2
-rw-r--r--drivers/gpu/drm/gma500/psb_device.c34
-rw-r--r--drivers/gpu/drm/gma500/psb_drm.h207
-rw-r--r--drivers/gpu/drm/gma500/psb_drv.c538
-rw-r--r--drivers/gpu/drm/gma500/psb_drv.h12
-rw-r--r--drivers/gpu/drm/gma500/psb_intel_lvds.c61
-rw-r--r--drivers/gpu/drm/gma500/psb_irq.c71
-rw-r--r--drivers/gpu/drm/gma500/psb_lid.c2
-rw-r--r--include/drm/gma_drm.h91
22 files changed, 437 insertions, 937 deletions
diff --git a/drivers/gpu/drm/gma500/accel_2d.c b/drivers/gpu/drm/gma500/accel_2d.c
index 305e6f91a7db..f0ce82aed654 100644
--- a/drivers/gpu/drm/gma500/accel_2d.c
+++ b/drivers/gpu/drm/gma500/accel_2d.c
@@ -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;
@@ -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;
}
@@ -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.
*/
@@ -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;
}
diff --git a/drivers/gpu/drm/gma500/cdv_device.c b/drivers/gpu/drm/gma500/cdv_device.c
index 87614e0d396a..7e8028abcc99 100644
--- a/drivers/gpu/drm/gma500/cdv_device.c
+++ b/drivers/gpu/drm/gma500/cdv_device.c
@@ -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"
@@ -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;
diff --git a/drivers/gpu/drm/gma500/framebuffer.c b/drivers/gpu/drm/gma500/framebuffer.c
index 171c4419b7f6..9ec167600d04 100644
--- a/drivers/gpu/drm/gma500/framebuffer.c
+++ b/drivers/gpu/drm/gma500/framebuffer.c
@@ -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,
@@ -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)
{
@@ -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,
@@ -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)
{
@@ -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;
}
/**
@@ -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;
@@ -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);
@@ -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) {
@@ -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) {
@@ -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);
@@ -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);
@@ -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));
diff --git a/drivers/gpu/drm/gma500/framebuffer.h b/drivers/gpu/drm/gma500/framebuffer.h
index d1b2289447f0..989558a9e6ee 100644
--- a/drivers/gpu/drm/gma500/framebuffer.h
+++ b/drivers/gpu/drm/gma500/framebuffer.h
@@ -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 {
diff --git a/drivers/gpu/drm/gma500/gem.c b/drivers/gpu/drm/gma500/gem.c
index 65fdd6b8ab16..9fbb86868e2e 100644
--- a/drivers/gpu/drm/gma500/gem.c
+++ b/drivers/gpu/drm/gma500/gem.c
@@ -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)
@@ -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;
}
@@ -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)
{
@@ -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);
}
diff --git a/drivers/gpu/drm/gma500/gtt.c b/drivers/gpu/drm/gma500/gtt.c
index 461ead251bbd..e770bd190a5c 100644
--- a/drivers/gpu/drm/gma500/gtt.c
+++ b/drivers/gpu/drm/gma500/gtt.c
@@ -72,9 +72,8 @@ u32 *psb_gtt_entry(struct drm_device *dev, struct gtt_range *r)
* @r: our GTT range
*
* Take our preallocated GTT range and insert the GEM object into
- * the GTT.
- *
- * FIXME: gtt lock ?
+ * the GTT. This is protected via the gtt mutex which the caller
+ * must hold.
*/
static int psb_gtt_insert(struct drm_device *dev, struct gtt_range *r)
{
@@ -96,12 +95,17 @@ static int psb_gtt_insert(struct drm_device *dev, struct gtt_range *r)
set_pages_array_uc(pages, r->npage);
/* Write our page entries into the GTT itself */
- for (i = 0; i < r->npage; i++) {
- pte = psb_gtt_mask_pte(page_to_pfn(*pages++), 0/*type*/);
+ for (i = r->roll; i < r->npage; i++) {
+ pte = psb_gtt_mask_pte(page_to_pfn(r->pages[i]), 0);
+ iowrite32(pte, gtt_slot++);
+ }
+ for (i = 0; i < r->roll; i++) {
+ pte = psb_gtt_mask_pte(page_to_pfn(r->pages[i]), 0);
iowrite32(pte, gtt_slot++);
}
/* Make sure all the entries are set before we return */
ioread32(gtt_slot - 1);
+
return 0;
}
@@ -111,9 +115,9 @@ static int psb_gtt_insert(struct drm_device *dev, struct gtt_range *r)
* @r: our GTT range
*
* Remove a preallocated GTT range from the GTT. Overwrite all the
- * page table entries with the dummy page
+ * page table entries with the dummy page. This is protected via the gtt
+ * mutex which the caller must hold.
*/
-
static void psb_gtt_remove(struct drm_device *dev, struct gtt_range *r)
{
struct drm_psb_private *dev_priv = dev->dev_private;
@@ -132,11 +136,52 @@ static void psb_gtt_remove(struct drm_device *dev, struct gtt_range *r)
}
/**
+ * psb_gtt_roll - set scrolling position
+ * @dev: our DRM device
+ * @r: the gtt mapping we are using
+ * @roll: roll offset
+ *
+ * Roll an existing pinned mapping by moving the pages through the GTT.
+ * This allows us to implement hardware scrolling on the consoles without
+ * a 2D engine
+ */
+void psb_gtt_roll(struct drm_device *dev, struct gtt_range *r, int roll)
+{
+ u32 *gtt_slot, pte;
+ int i;
+
+ if (roll >= r->npage) {
+ WARN_ON(1);
+ return;
+ }
+
+ r->roll = roll;
+
+ /* Not currently in the GTT - no worry we will write the mapping at
+ the right position when it gets pinned */
+ if (!r->stolen && !r->in_gart)
+ return;
+
+ gtt_slot = psb_gtt_entry(dev, r);
+
+ for (i = r->roll; i < r->npage; i++) {
+ pte = psb_gtt_mask_pte(page_to_pfn(r->pages[i]), 0);
+ iowrite32(pte, gtt_slot++);
+ }
+ for (i = 0; i < r->roll; i++) {
+ pte = psb_gtt_mask_pte(page_to_pfn(r->pages[i]), 0);
+ iowrite32(pte, gtt_slot++);
+ }
+ ioread32(gtt_slot - 1);
+}
+
+/**
* psb_gtt_attach_pages - attach and pin GEM pages
* @gt: the gtt range
*
* Pin and build an in kernel list of the pages that back our GEM object.
- * While we hold this the pages cannot be swapped out
+ * While we hold this the pages cannot be swapped out. This is protected
+ * via the gtt mutex which the caller must hold.
*/
static int psb_gtt_attach_pages(struct gtt_range *gt)
{
@@ -158,7 +203,7 @@ static int psb_gtt_attach_pages(struct gtt_range *gt)
gt->npage = pages;
for (i = 0; i < pages; i++) {
- /* FIXME: review flags later */
+ /* FIXME: needs updating as per mail from Hugh Dickins */
p = read_cache_page_gfp(mapping, i,
__GFP_COLD | GFP_KERNEL);
if (IS_ERR(p))
@@ -181,7 +226,8 @@ err:
*
* Undo the effect of psb_gtt_attach_pages. At this point the pages
* must have been removed from the GTT as they could now be paged out
- * and move bus address.
+ * and move bus address. This is protected via the gtt mutex which the
+ * caller must hold.
*/
static void psb_gtt_detach_pages(struct gtt_range *gt)
{
@@ -300,6 +346,7 @@ struct gtt_range *psb_gtt_alloc_range(struct drm_device *dev, int len,
gt->resource.name = name;
gt->stolen = backed;
gt->in_gart = backed;
+ gt->roll = 0;
/* Ensure this is set for non GEM objects */
gt->gem.dev = dev;
ret = allocate_resource(dev_priv->gtt_mem, &gt->resource,
@@ -390,15 +437,18 @@ int psb_gtt_init(struct drm_device *dev, int resume)
pg->gtt_phys_start = dev_priv->pge_ctl & PAGE_MASK;
/*
- * FIXME: video mmu has hw bug to access 0x0D0000000,
- * then make gatt start at 0x0e000,0000
+ * The video mmu has a hw bug when accessing 0x0D0000000.
+ * Make gatt start at 0x0e000,0000. This doesn't actually
+ * matter for us but may do if the video acceleration ever
+ * gets opened up.
*/
pg->mmu_gatt_start = 0xE0000000;
pg->gtt_start = pci_resource_start(dev->pdev, PSB_GTT_RESOURCE);
gtt_pages = pci_resource_len(dev->pdev, PSB_GTT_RESOURCE)
>> PAGE_SHIFT;
- /* CDV workaround */
+ /* Some CDV firmware doesn't report this currently. In which case the
+ system has 64 gtt pages */
if (pg->gtt_start == 0 || gtt_pages == 0) {
dev_err(dev->dev, "GTT PCI BAR not initialized.\n");
gtt_pages = 64;
@@ -412,13 +462,16 @@ int psb_gtt_init(struct drm_device *dev, int resume)
if (pg->gatt_pages == 0 || pg->gatt_start == 0) {
static struct resource fudge; /* Preferably peppermint */
-
/* This can occur on CDV SDV systems. Fudge it in this case.
We really don't care what imaginary space is being allocated
at this point */
dev_err(dev->dev, "GATT PCI BAR not initialized.\n");
pg->gatt_start = 0x40000000;
pg->gatt_pages = (128 * 1024 * 1024) >> PAGE_SHIFT;
+ /* This is a little confusing but in fact the GTT is providing
+ a view from the GPU into memory and not vice versa. As such
+ this is really allocating space that is not the same as the
+ CPU address space on CDV */
fudge.start = 0x40000000;
fudge.end = 0x40000000 + 128 * 1024 * 1024 - 1;
fudge.name = "fudge";
diff --git a/drivers/gpu/drm/gma500/gtt.h b/drivers/gpu/drm/gma500/gtt.h
index e0e1cb6f9bd6..aa1742387f5a 100644
--- a/drivers/gpu/drm/gma500/gtt.h
+++ b/drivers/gpu/drm/gma500/gtt.h
@@ -49,6 +49,7 @@ struct gtt_range {
bool mmapping; /* Is mmappable */
struct page **pages; /* Backing pages if present */
int npage; /* Number of backing pages */
+ int roll; /* Roll applied to the GTT entries */
};
extern struct gtt_range *psb_gtt_alloc_range(struct drm_device *dev, int len,
@@ -57,5 +58,7 @@ extern void psb_gtt_kref_put(struct gtt_range *gt);
extern void psb_gtt_free_range(struct drm_device *dev, struct gtt_range *gt);
extern int psb_gtt_pin(struct gtt_range *gt);
extern void psb_gtt_unpin(struct gtt_range *gt);
+extern void psb_gtt_roll(struct drm_device *dev,
+ struct gtt_range *gt, int roll);
#endif
diff --git a/drivers/gpu/drm/gma500/intel_bios.c b/drivers/gpu/drm/gma500/intel_bios.c
index 096757f9bc89..d4d0c5b8bf91 100644
--- a/drivers/gpu/drm/gma500/intel_bios.c
+++ b/drivers/gpu/drm/gma500/intel_bios.c
@@ -20,7 +20,7 @@
*/
#include <drm/drmP.h>
#include <drm/drm.h>
-#include "psb_drm.h"
+#include "gma_drm.h"
#include "psb_drv.h"
#include "psb_intel_drv.h"
#include "psb_intel_reg.h"
diff --git a/drivers/gpu/drm/gma500/intel_opregion.c b/drivers/gpu/drm/gma500/intel_opregion.c
index d2e60376982f..d946bc1b17bf 100644
--- a/drivers/gpu/drm/gma500/intel_opregion.c
+++ b/drivers/gpu/drm/gma500/intel_opregion.c
@@ -20,6 +20,7 @@
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
+ * FIXME: resolve with the i915 version
*/
#include "psb_drv.h"
diff --git a/drivers/gpu/drm/gma500/mid_bios.c b/drivers/gpu/drm/gma500/mid_bios.c
index 7115d1a7408f..128e6bb37568 100644
--- a/drivers/gpu/drm/gma500/mid_bios.c
+++ b/drivers/gpu/drm/gma500/mid_bios.c
@@ -25,7 +25,7 @@
#include <drm/drmP.h>
#include <drm/drm.h>
-#include "psb_drm.h"
+#include "gma_drm.h"
#include "psb_drv.h"
#include "mid_bios.h"
@@ -142,6 +142,12 @@ static void mid_get_vbt_data(struct drm_psb_private *dev_priv)
memcpy(vbt, vbt_virtual, sizeof(*vbt));
iounmap(vbt_virtual); /* Free virtual address space */
+ /* No matching signature don't process the data */
+ if (memcmp(vbt->signature, "$GCT", 4)) {
+ vbt->size = 0;
+ return;
+ }
+
dev_dbg(dev->dev, "GCT revision is %x\n", vbt->revision);
switch (vbt->revision) {
diff --git a/drivers/gpu/drm/gma500/oaktrail_crtc.c b/drivers/gpu/drm/gma500/oaktrail_crtc.c
index 7f9c791fbe78..8e15b5af1213 100644
--- a/drivers/gpu/drm/gma500/oaktrail_crtc.c
+++ b/drivers/gpu/drm/gma500/oaktrail_crtc.c
@@ -521,12 +521,11 @@ int oaktrail_pipe_set_base(struct drm_crtc *crtc,
int x, int y, struct drm_framebuffer *old_fb)
{
struct drm_device *dev = crtc->dev;
- /* struct drm_i915_master_private *master_priv; */
struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc);
struct psb_framebuffer *psbfb = to_psb_fb(crtc->fb);
int pipe = psb_intel_crtc->pipe;
unsigned long start, offset;
- /* FIXME: check if we need this surely MRST is pipe 0 only */
+
int dspbase = (pipe == 0 ? DSPALINOFF : DSPBBASE);
int dspsurf = (pipe == 0 ? DSPASURF : DSPBSURF);
int dspstride = (pipe == 0) ? DSPASTRIDE : DSPBSTRIDE;
@@ -572,15 +571,10 @@ int oaktrail_pipe_set_base(struct drm_crtc *crtc,
}
REG_WRITE(dspcntr_reg, dspcntr);
- if (0 /* FIXMEAC - check what PSB needs */) {
- REG_WRITE(dspbase, offset);
- REG_READ(dspbase);
- REG_WRITE(dspsurf, start);
- REG_READ(dspsurf);
- } else {
- REG_WRITE(dspbase, start + offset);
- REG_READ(dspbase);
- }
+ REG_WRITE(dspbase, offset);
+ REG_READ(dspbase);
+ REG_WRITE(dspsurf, start);
+ REG_READ(dspsurf);
pipe_set_base_exit:
gma_power_end(dev);
diff --git a/drivers/gpu/drm/gma500/oaktrail_device.c b/drivers/gpu/drm/gma500/oaktrail_device.c
index 41c418fa9aee..63aea2f010d9 100644
--- a/drivers/gpu/drm/gma500/oaktrail_device.c
+++ b/drivers/gpu/drm/gma500/oaktrail_device.c
@@ -22,13 +22,14 @@
#include <linux/dmi.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"
#include <asm/mrst.h>
#include <asm/intel_scu_ipc.h>
#include "mid_bios.h"
+#include "intel_bios.h"
static int oaktrail_output_init(struct drm_device *dev)
{
@@ -456,9 +457,31 @@ static int oaktrail_power_up(struct drm_device *dev)
}
+static int oaktrail_chip_setup(struct drm_device *dev)
+{
+ struct drm_psb_private *dev_priv = dev->dev_private;
+ struct oaktrail_vbt *vbt = &dev_priv->vbt_data;
+ int ret;
+
+ ret = mid_chip_setup(dev);
+ if (ret < 0)
+ return ret;
+ if (vbt->size == 0) {
+ /* Now pull the BIOS data */
+ gma_intel_opregion_init(dev);
+ psb_intel_init_bios(dev);
+ }
+ return 0;
+}
+
static void oaktrail_teardown(struct drm_device *dev)
{
+ struct drm_psb_private *dev_priv = dev->dev_private;
+ struct oaktrail_vbt *vbt = &dev_priv->vbt_data;
+
oaktrail_hdmi_teardown(dev);
+ if (vbt->size == 0)
+ psb_intel_destroy_bios(dev);
}
const struct psb_ops oaktrail_chip_ops = {
@@ -468,7 +491,7 @@ const struct psb_ops oaktrail_chip_ops = {
.crtcs = 2,
.sgx_offset = MRST_SGX_OFFSET,
- .chip_setup = mid_chip_setup,
+ .chip_setup = oaktrail_chip_setup,
.chip_teardown = oaktrail_teardown,
.crtc_helper = &oaktrail_helper_funcs,
.crtc_funcs = &psb_intel_crtc_funcs,
diff --git a/drivers/gpu/drm/gma500/oaktrail_lvds.c b/drivers/gpu/drm/gma500/oaktrail_lvds.c
index a552226a08ff..69659cad6778 100644
--- a/drivers/gpu/drm/gma500/oaktrail_lvds.c
+++ b/drivers/gpu/drm/gma500/oaktrail_lvds.c
@@ -228,17 +228,20 @@ static struct drm_display_mode lvds_configuration_modes[] = {
/* Returns the panel fixed mode from configuration. */
-static struct drm_display_mode *
-oaktrail_lvds_get_configuration_mode(struct drm_device *dev)
+static void oaktrail_lvds_get_configuration_mode(struct drm_device *dev,
+ struct psb_intel_mode_device *mode_dev)
{
struct drm_display_mode *mode = NULL;
struct drm_psb_private *dev_priv = dev->dev_private;
struct oaktrail_timing_info *ti = &dev_priv->gct_data.DTD;
+ mode_dev->panel_fixed_mode = NULL;
+
+ /* Use the firmware provided data on Moorestown */
if (dev_priv->vbt_data.size != 0x00) { /*if non-zero, then use vbt*/
mode = kzalloc(sizeof(*mode), GFP_KERNEL);
if (!mode)
- return NULL;
+ return;
mode->hdisplay = (ti->hactive_hi << 8) | ti->hactive_lo;
mode->vdisplay = (ti->vactive_hi << 8) | ti->vactive_lo;
@@ -270,13 +273,27 @@ oaktrail_lvds_get_configuration_mode(struct drm_device *dev)
printk(KERN_INFO "vtotal is %d\n", mode->vtotal);
printk(KERN_INFO "clock is %d\n", mode->clock);
#endif
- } else
- mode = drm_mode_duplicate(dev, &lvds_configuration_modes[2]);
-
- drm_mode_set_name(mode);
- drm_mode_set_crtcinfo(mode, 0);
+ mode_dev->panel_fixed_mode = mode;
+ }
- return mode;
+ /* Use the BIOS VBT mode if available */
+ if (mode_dev->panel_fixed_mode == NULL && mode_dev->vbt_mode)
+ mode_dev->panel_fixed_mode = drm_mode_duplicate(dev,
+ mode_dev->vbt_mode);
+
+ /* Then try the LVDS VBT mode */
+ if (mode_dev->panel_fixed_mode == NULL)
+ if (dev_priv->lfp_lvds_vbt_mode)
+ mode_dev->panel_fixed_mode =
+ drm_mode_duplicate(dev,
+ dev_priv->lfp_lvds_vbt_mode);
+ /* Then guess */
+ if (mode_dev->panel_fixed_mode == NULL)
+ mode_dev->panel_fixed_mode
+ = drm_mode_duplicate(dev, &lvds_configuration_modes[2]);
+
+ drm_mode_set_name(mode_dev->panel_fixed_mode);
+ drm_mode_set_crtcinfo(mode_dev->panel_fixed_mode, 0);
}
/**
@@ -375,7 +392,7 @@ void oaktrail_lvds_init(struct drm_device *dev,
* If we didn't get EDID, try geting panel timing
* from configuration data
*/
- mode_dev->panel_fixed_mode = oaktrail_lvds_get_configuration_mode(dev);
+ oaktrail_lvds_get_configuration_mode(dev, mode_dev);
if (mode_dev->panel_fixed_mode) {
mode_dev->panel_fixed_mode->type |= DRM_MODE_TYPE_PREFERRED;
diff --git a/drivers/gpu/drm/gma500/power.c b/drivers/gpu/drm/gma500/power.c
index 972bea7c1af2..94025693bae1 100644
--- a/drivers/gpu/drm/gma500/power.c
+++ b/drivers/gpu/drm/gma500/power.c
@@ -302,7 +302,7 @@ int psb_runtime_suspend(struct device *dev)
int psb_runtime_resume(struct device *dev)
{
- return 0;
+ return gma_power_resume(dev);;
}
int psb_runtime_idle(struct device *dev)
diff --git a/drivers/gpu/drm/gma500/psb_device.c b/drivers/gpu/drm/gma500/psb_device.c
index 46591323595a..35eddef45bed 100644
--- a/drivers/gpu/drm/gma500/psb_device.c
+++ b/drivers/gpu/drm/gma500/psb_device.c
@@ -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"
@@ -213,7 +213,6 @@ static int psb_restore_display_registers(struct drm_device *dev)
struct drm_psb_private *dev_priv = dev->dev_private;
struct drm_crtc *crtc;
struct drm_connector *connector;
- int pp_stat;
/* Display arbitration + watermarks */
PSB_WVDC32(dev_priv->saveDSPARB, DSPARB);
@@ -237,37 +236,6 @@ static int psb_restore_display_registers(struct drm_device *dev)
connector->funcs->restore(connector);
mutex_unlock(&dev->mode_config.mutex);
-
- if (dev_priv->iLVDS_enable) {
- /*shutdown the panel*/
- PSB_WVDC32(0, PP_CONTROL);
- do {
- pp_stat = PSB_RVDC32(PP_STATUS);
- } while (pp_stat & 0x80000000);
-
- /* Turn off the plane */
- PSB_WVDC32(0x58000000, DSPACNTR);
- PSB_WVDC32(0, DSPASURF);/*trigger the plane disable*/
- /* Wait ~4 ticks */
- msleep(4);
- /* Turn off pipe */
- PSB_WVDC32(0x0, PIPEACONF);
- /* Wait ~8 ticks */
- msleep(8);
-
- /* Turn off PLLs */
- PSB_WVDC32(0, MRST_DPLL_A);
- } else {
- PSB_WVDC32(DPI_SHUT_DOWN, DPI_CONTROL_REG);
- PSB_WVDC32(0x0, PIPEACONF);
- PSB_WVDC32(0x2faf0000, BLC_PWM_CTL);
- while (REG_READ(0x70008) & 0x40000000)
- cpu_relax();
- while ((PSB_RVDC32(GEN_FIFO_STAT_REG) & DPI_FIFO_EMPTY)
- != DPI_FIFO_EMPTY)
- cpu_relax();
- PSB_WVDC32(0, DEVICE_READY_REG);
- }
return 0;
}
diff --git a/drivers/gpu/drm/gma500/psb_drm.h b/drivers/gpu/drm/gma500/psb_drm.h
deleted file mode 100644
index dca7b20568f9..000000000000
--- a/drivers/gpu/drm/gma500/psb_drm.h
+++ /dev/null
@@ -1,207 +0,0 @@
-/**************************************************************************
- * Copyright (c) 2007-2011, Intel Corporation.
- * All Rights Reserved.
- * Copyright (c) 2008, Tungsten Graphics Inc. Cedar Park, TX., USA.
- * All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
- *
- **************************************************************************/
-
-#ifndef _PSB_DRM_H_
-#define _PSB_DRM_H_
-
-#define PSB_NUM_PIPE 3
-
-#define PSB_GPU_ACCESS_READ (1ULL << 32)
-#define PSB_GPU_ACCESS_WRITE (1ULL << 33)
-#define PSB_GPU_ACCESS_MASK (PSB_GPU_ACCESS_READ | PSB_GPU_ACCESS_WRITE)
-
-#define PSB_BO_FLAG_COMMAND (1ULL << 52)
-
-/*
- * Feedback components:
- */
-
-struct drm_psb_sizes_arg {
- u32 ta_mem_size;
- u32 mmu_size;
- u32 pds_size;
- u32 rastgeom_size;
- u32 tt_size;
- u32 vram_size;
-};
-
-struct drm_psb_dpst_lut_arg {
- uint8_t lut[256];
- int output_id;
-};
-
-#define PSB_DC_CRTC_SAVE 0x01
-#define PSB_DC_CRTC_RESTORE 0x02
-#define PSB_DC_OUTPUT_SAVE 0x04
-#define PSB_DC_OUTPUT_RESTORE 0x08
-#define PSB_DC_CRTC_MASK 0x03
-#define PSB_DC_OUTPUT_MASK 0x0C
-
-struct drm_psb_dc_state_arg {
- u32 flags;
- u32 obj_id;
-};
-
-struct drm_psb_mode_operation_arg {
- u32 obj_id;
- u16 operation;
- struct drm_mode_modeinfo mode;
- void *data;
-};
-
-struct drm_psb_stolen_memory_arg {
- u32 base;
- u32 size;
-};
-
-/*Display Register Bits*/
-#define REGRWBITS_PFIT_CONTROLS (1 << 0)
-#define REGRWBITS_PFIT_AUTOSCALE_RATIOS (1 << 1)
-#define REGRWBITS_PFIT_PROGRAMMED_SCALE_RATIOS (1 << 2)
-#define REGRWBITS_PIPEASRC (1 << 3)
-#define REGRWBITS_PIPEBSRC (1 << 4)
-#define REGRWBITS_VTOTAL_A (1 << 5)
-#define REGRWBITS_VTOTAL_B (1 << 6)
-#define REGRWBITS_DSPACNTR (1 << 8)
-#define REGRWBITS_DSPBCNTR (1 << 9)
-#define REGRWBITS_DSPCCNTR (1 << 10)
-
-/*Overlay Register Bits*/
-#define OV_REGRWBITS_OVADD (1 << 0)
-#define OV_REGRWBITS_OGAM_ALL (1 << 1)
-
-#define OVC_REGRWBITS_OVADD (1 << 2)
-#define OVC_REGRWBITS_OGAM_ALL (1 << 3)
-
-struct drm_psb_register_rw_arg {
- u32 b_force_hw_on;
-
- u32 display_read_mask;
- u32 display_write_mask;
-
- struct {
- u32 pfit_controls;
- u32 pfit_autoscale_ratios;
- u32 pfit_programmed_scale_ratios;
- u32 pipeasrc;
- u32 pipebsrc;
- u32 vtotal_a;
- u32 vtotal_b;
- } display;
-
- u32 overlay_read_mask;
- u32 overlay_write_mask;
-
- struct {
- u32 OVADD;
- u32 OGAMC0;
- u32 OGAMC1;
- u32 OGAMC2;
- u32 OGAMC3;
- u32 OGAMC4;
- u32 OGAMC5;
- u32 IEP_ENABLED;
- u32 IEP_BLE_MINMAX;
- u32 IEP_BSSCC_CONTROL;
- u32 b_wait_vblank;
- } overlay;
-
- u32 sprite_enable_mask;
- u32 sprite_disable_mask;
-
- struct {
- u32 dspa_control;
- u32 dspa_key_value;
- u32 dspa_key_mask;
- u32 dspc_control;
- u32 dspc_stride;
- u32 dspc_position;
- u32 dspc_linear_offset;
- u32 dspc_size;
- u32 dspc_surface;
- } sprite;
-
- u32 subpicture_enable_mask;
- u32 subpicture_disable_mask;
-};
-
-/* Controlling the kernel modesetting buffers */
-
-#define DRM_PSB_SIZES 0x07
-#define DRM_PSB_FUSE_REG 0x08
-#define DRM_PSB_DC_STATE 0x0A
-#define DRM_PSB_ADB 0x0B
-#define DRM_PSB_MODE_OPERATION 0x0C
-#define DRM_PSB_STOLEN_MEMORY 0x0D
-#define DRM_PSB_REGISTER_RW 0x0E
-
-/*
- * NOTE: Add new commands here, but increment
- * the values below and increment their
- * corresponding defines where they're
- * defined elsewhere.
- */
-
-#define DRM_PSB_GEM_CREATE 0x10
-#define DRM_PSB_2D_OP 0x11 /* Will be merged later */
-#define DRM_PSB_GEM_MMAP 0x12
-#define DRM_PSB_DPST 0x1B
-#define DRM_PSB_GAMMA 0x1C
-#define DRM_PSB_DPST_BL 0x1D
-#define DRM_PSB_GET_PIPE_FROM_CRTC_ID 0x1F
-
-#define PSB_MODE_OPERATION_MODE_VALID 0x01
-#define PSB_MODE_OPERATION_SET_DC_BASE 0x02
-
-struct drm_psb_get_pipe_from_crtc_id_arg {
- /** ID of CRTC being requested **/
- u32 crtc_id;
-
- /** pipe of requested CRTC **/
- u32 pipe;
-};
-
-/* FIXME: move this into a medfield header once we are sure it isn't needed for an
- ioctl */
-struct psb_drm_dpu_rect {
- int x, y;
- int width, height;
-};
-
-struct drm_psb_gem_create {
- __u64 size;
- __u32 handle;
- __u32 flags;
-#define PSB_GEM_CREATE_STOLEN 1 /* Stolen memory can be used */
-};
-
-struct drm_psb_gem_mmap {
- __u32 handle;
- __u32 pad;
- /**
- * Fake offset to use for subsequent mmap call
- *
- * This is a fixed-size type for 32/64 compatibility.
- */
- __u64 offset;
-};
-
-#endif
diff --git a/drivers/gpu/drm/gma500/psb_drv.c b/drivers/gpu/drm/gma500/psb_drv.c
index 97b5b11fb10d..add3156cd8bf 100644
--- a/drivers/gpu/drm/gma500/psb_drv.c
+++ b/drivers/gpu/drm/gma500/psb_drv.c
@@ -21,7 +21,7 @@
#include <drm/drmP.h>
#include <drm/drm.h>
-#include "psb_drm.h"
+#include "gma_drm.h"
#include "psb_drv.h"
#include "framebuffer.h"
#include "psb_reg.h"
@@ -80,58 +80,36 @@ MODULE_DEVICE_TABLE(pci, pciidlist);
* Standard IOCTLs.
*/
-#define DRM_IOCTL_PSB_SIZES \
- DRM_IOR(DRM_PSB_SIZES + DRM_COMMAND_BASE, \
- struct drm_psb_sizes_arg)
-#define DRM_IOCTL_PSB_FUSE_REG \
- DRM_IOWR(DRM_PSB_FUSE_REG + DRM_COMMAND_BASE, uint32_t)
-#define DRM_IOCTL_PSB_DC_STATE \
- DRM_IOW(DRM_PSB_DC_STATE + DRM_COMMAND_BASE, \
- struct drm_psb_dc_state_arg)
#define DRM_IOCTL_PSB_ADB \
- DRM_IOWR(DRM_PSB_ADB + DRM_COMMAND_BASE, uint32_t)
+ DRM_IOWR(DRM_GMA_ADB + DRM_COMMAND_BASE, uint32_t)
#define DRM_IOCTL_PSB_MODE_OPERATION \
- DRM_IOWR(DRM_PSB_MODE_OPERATION + DRM_COMMAND_BASE, \
+ DRM_IOWR(DRM_GMA_MODE_OPERATION + DRM_COMMAND_BASE, \
struct drm_psb_mode_operation_arg)
#define DRM_IOCTL_PSB_STOLEN_MEMORY \
- DRM_IOWR(DRM_PSB_STOLEN_MEMORY + DRM_COMMAND_BASE, \
+ DRM_IOWR(DRM_GMA_STOLEN_MEMORY + DRM_COMMAND_BASE, \
struct drm_psb_stolen_memory_arg)
-#define DRM_IOCTL_PSB_REGISTER_RW \
- DRM_IOWR(DRM_PSB_REGISTER_RW + DRM_COMMAND_BASE, \
- struct drm_psb_register_rw_arg)
-#define DRM_IOCTL_PSB_DPST \
- DRM_IOWR(DRM_PSB_DPST + DRM_COMMAND_BASE, \
- uint32_t)
#define DRM_IOCTL_PSB_GAMMA \
- DRM_IOWR(DRM_PSB_GAMMA + DRM_COMMAND_BASE, \
+ DRM_IOWR(DRM_GMA_GAMMA + DRM_COMMAND_BASE, \
struct drm_psb_dpst_lut_arg)
#define DRM_IOCTL_PSB_DPST_BL \
- DRM_IOWR(DRM_PSB_DPST_BL + DRM_COMMAND_BASE, \
+ DRM_IOWR(DRM_GMA_DPST_BL + DRM_COMMAND_BASE, \
uint32_t)
#define DRM_IOCTL_PSB_GET_PIPE_FROM_CRTC_ID \
- DRM_IOWR(DRM_PSB_GET_PIPE_FROM_CRTC_ID + DRM_COMMAND_BASE, \
+ DRM_IOWR(DRM_GMA_GET_PIPE_FROM_CRTC_ID + DRM_COMMAND_BASE, \
struct drm_psb_get_pipe_from_crtc_id_arg)
#define DRM_IOCTL_PSB_GEM_CREATE \
- DRM_IOWR(DRM_PSB_GEM_CREATE + DRM_COMMAND_BASE, \
+ DRM_IOWR(DRM_GMA_GEM_CREATE + DRM_COMMAND_BASE, \
struct drm_psb_gem_create)
#define DRM_IOCTL_PSB_GEM_MMAP \
- DRM_IOWR(DRM_PSB_GEM_MMAP + DRM_COMMAND_BASE, \
+ DRM_IOWR(DRM_GMA_GEM_MMAP + DRM_COMMAND_BASE, \
struct drm_psb_gem_mmap)
-static int psb_sizes_ioctl(struct drm_device *dev, void *data,
- struct drm_file *file_priv);
-static int psb_dc_state_ioctl(struct drm_device *dev, void * data,
- struct drm_file *file_priv);
static int psb_adb_ioctl(struct drm_device *dev, void *data,
struct drm_file *file_priv);
static int psb_mode_operation_ioctl(struct drm_device *dev, void *data,
struct drm_file *file_priv);
static int psb_stolen_memory_ioctl(struct drm_device *dev, void *data,
struct drm_file *file_priv);
-static int psb_register_rw_ioctl(struct drm_device *dev, void *data,
- struct drm_file *file_priv);
-static int psb_dpst_ioctl(struct drm_device *dev, void *data,
- struct drm_file *file_priv);
static int psb_gamma_ioctl(struct drm_device *dev, void *data,
struct drm_file *file_priv);
static int psb_dpst_bl_ioctl(struct drm_device *dev, void *data,
@@ -141,16 +119,11 @@ static int psb_dpst_bl_ioctl(struct drm_device *dev, void *data,
[DRM_IOCTL_NR(ioctl) - DRM_COMMAND_BASE] = {ioctl, flags, func}
static struct drm_ioctl_desc psb_ioctls[] = {
- PSB_IOCTL_DEF(DRM_IOCTL_PSB_SIZES, psb_sizes_ioctl, DRM_AUTH),
- PSB_IOCTL_DEF(DRM_IOCTL_PSB_DC_STATE, psb_dc_state_ioctl, DRM_AUTH),
PSB_IOCTL_DEF(DRM_IOCTL_PSB_ADB, psb_adb_ioctl, DRM_AUTH),
PSB_IOCTL_DEF(DRM_IOCTL_PSB_MODE_OPERATION, psb_mode_operation_ioctl,
DRM_AUTH),
PSB_IOCTL_DEF(DRM_IOCTL_PSB_STOLEN_MEMORY, psb_stolen_memory_ioctl,
DRM_AUTH),
- PSB_IOCTL_DEF(DRM_IOCTL_PSB_REGISTER_RW, psb_register_rw_ioctl,
- DRM_AUTH),
- PSB_IOCTL_DEF(DRM_IOCTL_PSB_DPST, psb_dpst_ioctl, DRM_AUTH),
PSB_IOCTL_DEF(DRM_IOCTL_PSB_GAMMA, psb_gamma_ioctl, DRM_AUTH),
PSB_IOCTL_DEF(DRM_IOCTL_PSB_DPST_BL, psb_dpst_bl_ioctl, DRM_AUTH),
PSB_IOCTL_DEF(DRM_IOCTL_PSB_GET_PIPE_FROM_CRTC_ID,
@@ -168,7 +141,6 @@ static void psb_lastclose(struct drm_device *dev)
static void psb_do_takedown(struct drm_device *dev)
{
- /* FIXME: do we need to clean up the gtt here ? */
}
static int psb_do_init(struct drm_device *dev)
@@ -214,7 +186,7 @@ static int psb_do_init(struct drm_device *dev)
spin_lock_init(&dev_priv->irqmask_lock);
- mutex_init(&dev_priv->mutex_2d);
+ spin_lock_init(&dev_priv->lock_2d);
PSB_WSGX32(0x00000000, PSB_CR_BIF_BANK0);
PSB_WSGX32(0x00000000, PSB_CR_BIF_BANK1);
@@ -314,6 +286,11 @@ static int psb_driver_load(struct drm_device *dev, unsigned long chipset)
dev_priv->dev = dev;
dev->dev_private = (void *) dev_priv;
+ if (!IS_PSB(dev)) {
+ if (pci_enable_msi(dev->pdev))
+ dev_warn(dev->dev, "Enabling MSI failed!\n");
+ }
+
dev_priv->num_pipe = dev_priv->ops->pipes;
resource_start = pci_resource_start(dev->pdev, PSB_MMIO_RESOURCE);
@@ -395,7 +372,7 @@ static int psb_driver_load(struct drm_device *dev, unsigned long chipset)
PSB_WVDC32(0x00000000, PSB_INT_ENABLE_R);
PSB_WVDC32(0xFFFFFFFF, PSB_INT_MASK_R);
spin_unlock_irqrestore(&dev_priv->irqmask_lock, irqflags);
- if (drm_core_check_feature(dev, DRIVER_MODESET))
+ if (IS_PSB(dev) && drm_core_check_feature(dev, DRIVER_MODESET))
drm_irq_install(dev);
dev->vblank_disable_allowed = 1;
@@ -442,75 +419,6 @@ int psb_driver_device_is_agp(struct drm_device *dev)
return 0;
}
-
-static int psb_sizes_ioctl(struct drm_device *dev, void *data,
- struct drm_file *file_priv)
-{
- struct drm_psb_private *dev_priv = psb_priv(dev);
- struct drm_psb_sizes_arg *arg =
- (struct drm_psb_sizes_arg *) data;
-
- *arg = dev_priv->sizes;
- return 0;
-}
-
-static int psb_dc_state_ioctl(struct drm_device *dev, void * data,
- struct drm_file *file_priv)
-{
- uint32_t flags;
- uint32_t obj_id;
- struct drm_mode_object *obj;
- struct drm_connector *connector;
- struct drm_crtc *crtc;
- struct drm_psb_dc_state_arg *arg = data;
-
-
- /* Double check MRST case */
- if (IS_MRST(dev) || IS_MFLD(dev))
- return -EOPNOTSUPP;
-
- flags = arg->flags;
- obj_id = arg->obj_id;
-
- if (flags & PSB_DC_CRTC_MASK) {
- obj = drm_mode_object_find(dev, obj_id,
- DRM_MODE_OBJECT_CRTC);
- if (!obj) {
- dev_dbg(dev->dev, "Invalid CRTC object.\n");
- return -EINVAL;
- }
-
- crtc = obj_to_crtc(obj);
-
- mutex_lock(&dev->mode_config.mutex);
- if (drm_helper_crtc_in_use(crtc)) {
- if (flags & PSB_DC_CRTC_SAVE)
- crtc->funcs->save(crtc);
- else
- crtc->funcs->restore(crtc);
- }
- mutex_unlock(&dev->mode_config.mutex);
-
- return 0;
- } else if (flags & PSB_DC_OUTPUT_MASK) {
- obj = drm_mode_object_find(dev, obj_id,
- DRM_MODE_OBJECT_CONNECTOR);
- if (!obj) {
- dev_dbg(dev->dev, "Invalid connector id.\n");
- return -EINVAL;
- }
-
- connector = obj_to_connector(obj);
- if (flags & PSB_DC_OUTPUT_SAVE)
- connector->funcs->save(connector);
- else
- connector->funcs->restore(connector);
-
- return 0;
- }
- return -EINVAL;
-}
-
static inline void get_brightness(struct backlight_device *bd)
{
#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE
@@ -543,36 +451,6 @@ static int psb_adb_ioctl(struct drm_device *dev, void *data,
return 0;
}
-/* return the current mode to the dpst module */
-static int psb_dpst_ioctl(struct drm_device *dev, void *data,
- struct drm_file *file_priv)
-{
- struct drm_psb_private *dev_priv = psb_priv(dev);
- uint32_t *arg = data;
- uint32_t x;
- uint32_t y;
- uint32_t reg;
-
- if (!gma_power_begin(dev, 0))
- return -EIO;
-
- reg = PSB_RVDC32(PIPEASRC);
-
- gma_power_end(dev);
-
- /* horizontal is the left 16 bits */
- x = reg >> 16;
- /* vertical is the right 16 bits */
- y = reg & 0x0000ffff;
-
- /* the values are the image size minus one */
- x++;
- y++;
-
- *arg = (x << 16) | y;
-
- return 0;
-}
static int psb_gamma_ioctl(struct drm_device *dev, void *data,
struct drm_file *file_priv)
{
@@ -613,37 +491,15 @@ static int psb_mode_operation_ioctl(struct drm_device *dev, void *data,
struct drm_psb_mode_operation_arg *arg;
struct drm_mode_object *obj;
struct drm_connector *connector;
- struct drm_framebuffer *drm_fb;
- struct psb_framebuffer *psb_fb;
struct drm_connector_helper_funcs *connector_funcs;
int ret = 0;
int resp = MODE_OK;
- struct drm_psb_private *dev_priv = psb_priv(dev);
arg = (struct drm_psb_mode_operation_arg *)data;
obj_id = arg->obj_id;
op = arg->operation;
switch (op) {
- case PSB_MODE_OPERATION_SET_DC_BASE:
- obj = drm_mode_object_find(dev, obj_id, DRM_MODE_OBJECT_FB);
- if (!obj) {
- dev_dbg(dev->dev, "Invalid FB id %d\n", obj_id);
- return -EINVAL;
- }
-
- drm_fb = obj_to_fb(obj);
- psb_fb = to_psb_fb(drm_fb);
-
- if (gma_power_begin(dev, 0)) {
- REG_WRITE(DSPASURF, psb_fb->gtt->offset);
- REG_READ(DSPASURF);
- gma_power_end(dev);
- } else {
- dev_priv->saveDSPASURF = psb_fb->gtt->offset;
- }
-
- return 0;
case PSB_MODE_OPERATION_MODE_VALID:
umode = &arg->mode;
@@ -689,7 +545,7 @@ static int psb_mode_operation_ioctl(struct drm_device *dev, void *data,
if (connector_funcs->mode_valid) {
resp = connector_funcs->mode_valid(connector, mode);
- arg->data = (void *)resp;
+ arg->data = resp;
}
/*do some clean up work*/
@@ -719,363 +575,6 @@ static int psb_stolen_memory_ioctl(struct drm_device *dev, void *data,
return 0;
}
-/* FIXME: needs Medfield changes */
-static int psb_register_rw_ioctl(struct drm_device *dev, void *data,
- struct drm_file *file_priv)
-{
- struct drm_psb_private *dev_priv = psb_priv(dev);
- struct drm_psb_register_rw_arg *arg = data;
- bool usage = arg->b_force_hw_on ? true : false;
-
- if (arg->display_write_mask != 0) {
- if (gma_power_begin(dev, usage)) {
- if (arg->display_write_mask & REGRWBITS_PFIT_CONTROLS)
- PSB_WVDC32(arg->display.pfit_controls,
- PFIT_CONTROL);
- if (arg->display_write_mask &
- REGRWBITS_PFIT_AUTOSCALE_RATIOS)
- PSB_WVDC32(arg->display.pfit_autoscale_ratios,
- PFIT_AUTO_RATIOS);
- if (arg->display_write_mask &
- REGRWBITS_PFIT_PROGRAMMED_SCALE_RATIOS)
- PSB_WVDC32(
- arg->display.pfit_programmed_scale_ratios,
- PFIT_PGM_RATIOS);
- if (arg->display_write_mask & REGRWBITS_PIPEASRC)
- PSB_WVDC32(arg->display.pipeasrc,
- PIPEASRC);
- if (arg->display_write_mask & REGRWBITS_PIPEBSRC)
- PSB_WVDC32(arg->display.pipebsrc,
- PIPEBSRC);
- if (arg->display_write_mask & REGRWBITS_VTOTAL_A)
- PSB_WVDC32(arg->display.vtotal_a,
- VTOTAL_A);
- if (arg->display_write_mask & REGRWBITS_VTOTAL_B)
- PSB_WVDC32(arg->display.vtotal_b,
- VTOTAL_B);
- gma_power_end(dev);
- } else {
- if (arg->display_write_mask & REGRWBITS_PFIT_CONTROLS)
- dev_priv->savePFIT_CONTROL =
- arg->display.pfit_controls;
- if (arg->display_write_mask &
- REGRWBITS_PFIT_AUTOSCALE_RATIOS)
- dev_priv->savePFIT_AUTO_RATIOS =
- arg->display.pfit_autoscale_ratios;
- if (arg->display_write_mask &
- REGRWBITS_PFIT_PROGRAMMED_SCALE_RATIOS)
- dev_priv->savePFIT_PGM_RATIOS =
- arg->display.pfit_programmed_scale_ratios;
- if (arg->display_write_mask & REGRWBITS_PIPEASRC)
- dev_priv->savePIPEASRC = arg->display.pipeasrc;
- if (arg->display_write_mask & REGRWBITS_PIPEBSRC)
- dev_priv->savePIPEBSRC = arg->display.pipebsrc;
- if (arg->display_write_mask & REGRWBITS_VTOTAL_A)
- dev_priv->saveVTOTAL_A = arg->display.vtotal_a;
- if (arg->display_write_mask & REGRWBITS_VTOTAL_B)
- dev_priv->saveVTOTAL_B = arg->display.vtotal_b;
- }
- }
-
- if (arg->display_read_mask != 0) {
- if (gma_power_begin(dev, usage)) {
- if (arg->display_read_mask &
- REGRWBITS_PFIT_CONTROLS)
- arg->display.pfit_controls =
- PSB_RVDC32(PFIT_CONTROL);
- if (arg->display_read_mask &
- REGRWBITS_PFIT_AUTOSCALE_RATIOS)
- arg->display.pfit_autoscale_ratios =
- PSB_RVDC32(PFIT_AUTO_RATIOS);
- if (arg->display_read_mask &
- REGRWBITS_PFIT_PROGRAMMED_SCALE_RATIOS)
- arg->display.pfit_programmed_scale_ratios =
- PSB_RVDC32(PFIT_PGM_RATIOS);
- if (arg->display_read_mask & REGRWBITS_PIPEASRC)
- arg->display.pipeasrc = PSB_RVDC32(PIPEASRC);
- if (arg->display_read_mask & REGRWBITS_PIPEBSRC)
- arg->display.pipebsrc = PSB_RVDC32(PIPEBSRC);
- if (arg->display_read_mask & REGRWBITS_VTOTAL_A)
- arg->display.vtotal_a = PSB_RVDC32(VTOTAL_A);
- if (arg->display_read_mask & REGRWBITS_VTOTAL_B)
- arg->display.vtotal_b = PSB_RVDC32(VTOTAL_B);
- gma_power_end(dev);
- } else {
- if (arg->display_read_mask &
- REGRWBITS_PFIT_CONTROLS)
- arg->display.pfit_controls =
- dev_priv->savePFIT_CONTROL;
- if (arg->display_read_mask &
- REGRWBITS_PFIT_AUTOSCALE_RATIOS)
- arg->display.pfit_autoscale_ratios =
- dev_priv->savePFIT_AUTO_RATIOS;
- if (arg->display_read_mask &
- REGRWBITS_PFIT_PROGRAMMED_SCALE_RATIOS)
- arg->display.pfit_programmed_scale_ratios =
- dev_priv->savePFIT_PGM_RATIOS;
- if (arg->display_read_mask & REGRWBITS_PIPEASRC)
- arg->display.pipeasrc = dev_priv->savePIPEASRC;
- if (arg->display_read_mask & REGRWBITS_PIPEBSRC)
- arg->display.pipebsrc = dev_priv->savePIPEBSRC;
- if (arg->display_read_mask & REGRWBITS_VTOTAL_A)
- arg->display.vtotal_a = dev_priv->saveVTOTAL_A;
- if (arg->display_read_mask & REGRWBITS_VTOTAL_B)
- arg->display.vtotal_b = dev_priv->saveVTOTAL_B;
- }
- }
-
- if (arg->overlay_write_mask != 0) {
- if (gma_power_begin(dev, usage)) {
- if (arg->overlay_write_mask & OV_REGRWBITS_OGAM_ALL) {
- PSB_WVDC32(arg->overlay.OGAMC5, OV_OGAMC5);
- PSB_WVDC32(arg->overlay.OGAMC4, OV_OGAMC4);
- PSB_WVDC32(arg->overlay.OGAMC3, OV_OGAMC3);
- PSB_WVDC32(arg->overlay.OGAMC2, OV_OGAMC2);
- PSB_WVDC32(arg->overlay.OGAMC1, OV_OGAMC1);
- PSB_WVDC32(arg->overlay.OGAMC0, OV_OGAMC0);
- }
- if (arg->overlay_write_mask & OVC_REGRWBITS_OGAM_ALL) {
- PSB_WVDC32(arg->overlay.OGAMC5, OVC_OGAMC5);
- PSB_WVDC32(arg->overlay.OGAMC4, OVC_OGAMC4);
- PSB_WVDC32(arg->overlay.OGAMC3, OVC_OGAMC3);
- PSB_WVDC32(arg->overlay.OGAMC2, OVC_OGAMC2);
- PSB_WVDC32(arg->overlay.OGAMC1, OVC_OGAMC1);
- PSB_WVDC32(arg->overlay.OGAMC0, OVC_OGAMC0);
- }
-
- if (arg->overlay_write_mask & OV_REGRWBITS_OVADD) {
- PSB_WVDC32(arg->overlay.OVADD, OV_OVADD);
-
- if (arg->overlay.b_wait_vblank) {
- /* Wait for 20ms.*/
- unsigned long vblank_timeout = jiffies
- + HZ/50;
- uint32_t temp;
- while (time_before_eq(jiffies,
- vblank_timeout)) {
- temp = PSB_RVDC32(OV_DOVASTA);
- if ((temp & (0x1 << 31)) != 0)
- break;
- cpu_relax();
- }
- }
- }
- if (arg->overlay_write_mask & OVC_REGRWBITS_OVADD) {
- PSB_WVDC32(arg->overlay.OVADD, OVC_OVADD);
- if (arg->overlay.b_wait_vblank) {
- /* Wait for 20ms.*/
- unsigned long vblank_timeout =
- jiffies + HZ/50;
- uint32_t temp;
- while (time_before_eq(jiffies,
- vblank_timeout)) {
- temp = PSB_RVDC32(OVC_DOVCSTA);
- if ((temp & (0x1 << 31)) != 0)
- break;
- cpu_relax();
- }
- }
- }
- gma_power_end(dev);
- } else {
- if (arg->overlay_write_mask & OV_REGRWBITS_OGAM_ALL) {
- dev_priv->saveOV_OGAMC5 = arg->overlay.OGAMC5;
- dev_priv->saveOV_OGAMC4 = arg->overlay.OGAMC4;
- dev_priv->saveOV_OGAMC3 = arg->overlay.OGAMC3;
- dev_priv->saveOV_OGAMC2 = arg->overlay.OGAMC2;
- dev_priv->saveOV_OGAMC1 = arg->overlay.OGAMC1;
- dev_priv->saveOV_OGAMC0 = arg->overlay.OGAMC0;
- }
- if (arg->overlay_write_mask & OVC_REGRWBITS_OGAM_ALL) {
- dev_priv->saveOVC_OGAMC5 = arg->overlay.OGAMC5;
- dev_priv->saveOVC_OGAMC4 = arg->overlay.OGAMC4;
- dev_priv->saveOVC_OGAMC3 = arg->overlay.OGAMC3;
- dev_priv->saveOVC_OGAMC2 = arg->overlay.OGAMC2;
- dev_priv->saveOVC_OGAMC1 = arg->overlay.OGAMC1;
- dev_priv->saveOVC_OGAMC0 = arg->overlay.OGAMC0;
- }
- if (arg->overlay_write_mask & OV_REGRWBITS_OVADD)
- dev_priv->saveOV_OVADD = arg->overlay.OVADD;
- if (arg->overlay_write_mask & OVC_REGRWBITS_OVADD)
- dev_priv->saveOVC_OVADD = arg->overlay.OVADD;
- }
- }
-
- if (arg->overlay_read_mask != 0) {
- if (gma_power_begin(dev, usage)) {
- if (arg->overlay_read_mask & OV_REGRWBITS_OGAM_ALL) {
- arg->overlay.OGAMC5 = PSB_RVDC32(OV_OGAMC5);
- arg->overlay.OGAMC4 = PSB_RVDC32(OV_OGAMC4);
- arg->overlay.OGAMC3 = PSB_RVDC32(OV_OGAMC3);
- arg->overlay.OGAMC2 = PSB_RVDC32(OV_OGAMC2);
- arg->overlay.OGAMC1 = PSB_RVDC32(OV_OGAMC1);
- arg->overlay.OGAMC0 = PSB_RVDC32(OV_OGAMC0);
- }
- if (arg->overlay_read_mask & OVC_REGRWBITS_OGAM_ALL) {
- arg->overlay.OGAMC5 = PSB_RVDC32(OVC_OGAMC5);
- arg->overlay.OGAMC4 = PSB_RVDC32(OVC_OGAMC4);
- arg->overlay.OGAMC3 = PSB_RVDC32(OVC_OGAMC3);
- arg->overlay.OGAMC2 = PSB_RVDC32(OVC_OGAMC2);
- arg->overlay.OGAMC1 = PSB_RVDC32(OVC_OGAMC1);
- arg->overlay.OGAMC0 = PSB_RVDC32(OVC_OGAMC0);
- }
- if (arg->overlay_read_mask & OV_REGRWBITS_OVADD)
- arg->overlay.OVADD = PSB_RVDC32(OV_OVADD);
- if (arg->overlay_read_mask & OVC_REGRWBITS_OVADD)
- arg->overlay.OVADD = PSB_RVDC32(OVC_OVADD);
- gma_power_end(dev);
- } else {
- if (arg->overlay_read_mask & OV_REGRWBITS_OGAM_ALL) {
- arg->overlay.OGAMC5 = dev_priv->saveOV_OGAMC5;
- arg->overlay.OGAMC4 = dev_priv->saveOV_OGAMC4;
- arg->overlay.OGAMC3 = dev_priv->saveOV_OGAMC3;
- arg->overlay.OGAMC2 = dev_priv->saveOV_OGAMC2;
- arg->overlay.OGAMC1 = dev_priv->saveOV_OGAMC1;
- arg->overlay.OGAMC0 = dev_priv->saveOV_OGAMC0;
- }
- if (arg->overlay_read_mask & OVC_REGRWBITS_OGAM_ALL) {
- arg->overlay.OGAMC5 = dev_priv->saveOVC_OGAMC5;
- arg->overlay.OGAMC4 = dev_priv->saveOVC_OGAMC4;
- arg->overlay.OGAMC3 = dev_priv->saveOVC_OGAMC3;
- arg->overlay.OGAMC2 = dev_priv->saveOVC_OGAMC2;
- arg->overlay.OGAMC1 = dev_priv->saveOVC_OGAMC1;
- arg->overlay.OGAMC0 = dev_priv->saveOVC_OGAMC0;
- }
- if (arg->overlay_read_mask & OV_REGRWBITS_OVADD)
- arg->overlay.OVADD = dev_priv->saveOV_OVADD;
- if (arg->overlay_read_mask & OVC_REGRWBITS_OVADD)
- arg->overlay.OVADD = dev_priv->saveOVC_OVADD;
- }
- }
-
- if (arg->sprite_enable_mask != 0) {
- if (gma_power_begin(dev, usage)) {
- PSB_WVDC32(0x1F3E, DSPARB);
- PSB_WVDC32(arg->sprite.dspa_control
- | PSB_RVDC32(DSPACNTR), DSPACNTR);
- PSB_WVDC32(arg->sprite.dspa_key_value, DSPAKEYVAL);
- PSB_WVDC32(arg->sprite.dspa_key_mask, DSPAKEYMASK);
- PSB_WVDC32(PSB_RVDC32(DSPASURF), DSPASURF);
- PSB_RVDC32(DSPASURF);
- PSB_WVDC32(arg->sprite.dspc_control, DSPCCNTR);
- PSB_WVDC32(arg->sprite.dspc_stride, DSPCSTRIDE);
- PSB_WVDC32(arg->sprite.dspc_position, DSPCPOS);
- PSB_WVDC32(arg->sprite.dspc_linear_offset, DSPCLINOFF);
- PSB_WVDC32(arg->sprite.dspc_size, DSPCSIZE);
- PSB_WVDC32(arg->sprite.dspc_surface, DSPCSURF);
- PSB_RVDC32(DSPCSURF);
- gma_power_end(dev);
- }
- }
-
- if (arg->sprite_disable_mask != 0) {
- if (gma_power_begin(dev, usage)) {
- PSB_WVDC32(0x3F3E, DSPARB);
- PSB_WVDC32(0x0, DSPCCNTR);
- PSB_WVDC32(arg->sprite.dspc_surface, DSPCSURF);
- PSB_RVDC32(DSPCSURF);
- gma_power_end(dev);
- }
- }
-
- if (arg->subpicture_enable_mask != 0) {
- if (gma_power_begin(dev, usage)) {
- uint32_t temp;
- if (arg->subpicture_enable_mask & REGRWBITS_DSPACNTR) {
- temp = PSB_RVDC32(DSPACNTR);
- temp &= ~DISPPLANE_PIXFORMAT_MASK;
- temp &= ~DISPPLANE_BOTTOM;
- temp |= DISPPLANE_32BPP;
- PSB_WVDC32(temp, DSPACNTR);
-
- temp = PSB_RVDC32(DSPABASE);
- PSB_WVDC32(temp, DSPABASE);
- PSB_RVDC32(DSPABASE);
- temp = PSB_RVDC32(DSPASURF);
- PSB_WVDC32(temp, DSPASURF);
- PSB_RVDC32(DSPASURF);
- }
- if (arg->subpicture_enable_mask & REGRWBITS_DSPBCNTR) {
- temp = PSB_RVDC32(DSPBCNTR);
- temp &= ~DISPPLANE_PIXFORMAT_MASK;
- temp &= ~DISPPLANE_BOTTOM;
- temp |= DISPPLANE_32BPP;
- PSB_WVDC32(temp, DSPBCNTR);
-
- temp = PSB_RVDC32(DSPBBASE);
- PSB_WVDC32(temp, DSPBBASE);
- PSB_RVDC32(DSPBBASE);
- temp = PSB_RVDC32(DSPBSURF);
- PSB_WVDC32(temp, DSPBSURF);
- PSB_RVDC32(DSPBSURF);
- }
- if (arg->subpicture_enable_mask & REGRWBITS_DSPCCNTR) {
- temp = PSB_RVDC32(DSPCCNTR);
- temp &= ~DISPPLANE_PIXFORMAT_MASK;
- temp &= ~DISPPLANE_BOTTOM;
- temp |= DISPPLANE_32BPP;
- PSB_WVDC32(temp, DSPCCNTR);
-
- temp = PSB_RVDC32(DSPCBASE);
- PSB_WVDC32(temp, DSPCBASE);
- PSB_RVDC32(DSPCBASE);
- temp = PSB_RVDC32(DSPCSURF);
- PSB_WVDC32(temp, DSPCSURF);
- PSB_RVDC32(DSPCSURF);
- }
- gma_power_end(dev);
- }
- }
-
- if (arg->subpicture_disable_mask != 0) {
- if (gma_power_begin(dev, usage)) {
- uint32_t temp;
- if (arg->subpicture_disable_mask & REGRWBITS_DSPACNTR) {
- temp = PSB_RVDC32(DSPACNTR);
- temp &= ~DISPPLANE_PIXFORMAT_MASK;
- temp |= DISPPLANE_32BPP_NO_ALPHA;
- PSB_WVDC32(temp, DSPACNTR);
-
- temp = PSB_RVDC32(DSPABASE);
- PSB_WVDC32(temp, DSPABASE);
- PSB_RVDC32(DSPABASE);
- temp = PSB_RVDC32(DSPASURF);
- PSB_WVDC32(temp, DSPASURF);
- PSB_RVDC32(DSPASURF);
- }
- if (arg->subpicture_disable_mask & REGRWBITS_DSPBCNTR) {
- temp = PSB_RVDC32(DSPBCNTR);
- temp &= ~DISPPLANE_PIXFORMAT_MASK;
- temp |= DISPPLANE_32BPP_NO_ALPHA;
- PSB_WVDC32(temp, DSPBCNTR);
-
- temp = PSB_RVDC32(DSPBBASE);
- PSB_WVDC32(temp, DSPBBASE);
- PSB_RVDC32(DSPBBASE);
- temp = PSB_RVDC32(DSPBSURF);
- PSB_WVDC32(temp, DSPBSURF);
- PSB_RVDC32(DSPBSURF);
- }
- if (arg->subpicture_disable_mask & REGRWBITS_DSPCCNTR) {
- temp = PSB_RVDC32(DSPCCNTR);
- temp &= ~DISPPLANE_PIXFORMAT_MASK;
- temp |= DISPPLANE_32BPP_NO_ALPHA;
- PSB_WVDC32(temp, DSPCCNTR);
-
- temp = PSB_RVDC32(DSPCBASE);
- PSB_WVDC32(temp, DSPCBASE);
- PSB_RVDC32(DSPCBASE);
- temp = PSB_RVDC32(DSPCSURF);
- PSB_WVDC32(temp, DSPCSURF);
- PSB_RVDC32(DSPCSURF);
- }
- gma_power_end(dev);
- }
- }
-
- return 0;
-}
-
static int psb_driver_open(struct drm_device *dev, struct drm_file *priv)
{
return 0;
@@ -1188,9 +687,6 @@ static struct pci_driver psb_pci_driver = {
static int psb_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
{
- /* MLD Added this from Inaky's patch */
- if (pci_enable_msi(pdev))
- dev_warn(&pdev->dev, "Enable MSI failed!\n");
return drm_get_pci_dev(pdev, ent, &driver);
}
diff --git a/drivers/gpu/drm/gma500/psb_drv.h b/drivers/gpu/drm/gma500/psb_drv.h
index a5ae9b185efb..5ec8edf65163 100644
--- a/drivers/gpu/drm/gma500/psb_drv.h
+++ b/drivers/gpu/drm/gma500/psb_drv.h
@@ -25,7 +25,7 @@
#include <drm/drmP.h>
#include "drm_global.h"
#include "gem_glue.h"
-#include "psb_drm.h"
+#include "gma_drm.h"
#include "psb_reg.h"
#include "psb_intel_drv.h"
#include "gtt.h"
@@ -42,6 +42,7 @@ enum {
CHIP_MFLD_0130 = 3, /* Medfield */
};
+#define IS_PSB(dev) (((dev)->pci_device & 0xfffe) == 0x8108)
#define IS_MRST(dev) (((dev)->pci_device & 0xfffc) == 0x4100)
#define IS_MFLD(dev) (((dev)->pci_device & 0xfff8) == 0x0130)
@@ -133,6 +134,9 @@ enum {
#define _PSB_IRQ_MSVDX_FLAG (1<<19)
#define _LNC_IRQ_TOPAZ_FLAG (1<<20)
+#define _PSB_PIPE_EVENT_FLAG (_PSB_VSYNC_PIPEA_FLAG | \
+ _PSB_VSYNC_PIPEB_FLAG)
+
/* This flag includes all the display IRQ bits excepts the vblank irqs. */
#define _MDFLD_DISP_ALL_IRQ_FLAG (_MDFLD_PIPEC_EVENT_FLAG | \
_MDFLD_PIPEB_EVENT_FLAG | \
@@ -258,6 +262,8 @@ struct psb_intel_opregion {
struct psb_ops;
+#define PSB_NUM_PIPE 3
+
struct drm_psb_private {
struct drm_device *dev;
const struct psb_ops *ops;
@@ -324,8 +330,6 @@ struct drm_psb_private {
* Sizes info
*/
- struct drm_psb_sizes_arg sizes;
-
u32 fuse_reg_value;
u32 video_device_fuse;
@@ -602,7 +606,7 @@ struct drm_psb_private {
void *fbdev;
/* 2D acceleration */
- struct mutex mutex_2d;
+ spinlock_t lock_2d;
};
diff --git a/drivers/gpu/drm/gma500/psb_intel_lvds.c b/drivers/gpu/drm/gma500/psb_intel_lvds.c
index c6436da60732..21022e1a977a 100644
--- a/drivers/gpu/drm/gma500/psb_intel_lvds.c
+++ b/drivers/gpu/drm/gma500/psb_intel_lvds.c
@@ -68,20 +68,23 @@ struct psb_intel_lvds_priv {
static u32 psb_intel_lvds_get_max_backlight(struct drm_device *dev)
{
struct drm_psb_private *dev_priv = dev->dev_private;
- u32 retVal;
+ u32 ret;
if (gma_power_begin(dev, false)) {
- retVal = ((REG_READ(BLC_PWM_CTL) &
- BACKLIGHT_MODULATION_FREQ_MASK) >>
- BACKLIGHT_MODULATION_FREQ_SHIFT) * 2;
-
+ ret = REG_READ(BLC_PWM_CTL);
gma_power_end(dev);
- } else
- retVal = ((dev_priv->saveBLC_PWM_CTL &
- BACKLIGHT_MODULATION_FREQ_MASK) >>
- BACKLIGHT_MODULATION_FREQ_SHIFT) * 2;
-
- return retVal;
+ } else /* Powered off, use the saved value */
+ ret = dev_priv->saveBLC_PWM_CTL;
+
+ /* Top 15bits hold the frequency mask */
+ ret = (ret & BACKLIGHT_MODULATION_FREQ_MASK) >>
+ BACKLIGHT_MODULATION_FREQ_SHIFT;
+
+ ret *= 2; /* Return a 16bit range as needed for setting */
+ if (ret == 0)
+ dev_err(dev->dev, "BL bug: Reg %08x save %08X\n",
+ REG_READ(BLC_PWM_CTL), dev_priv->saveBLC_PWM_CTL);
+ return ret;
}
/*
@@ -142,7 +145,7 @@ static int psb_lvds_pwm_set_brightness(struct drm_device *dev, int level)
max_pwm_blc = psb_intel_lvds_get_max_backlight(dev);
/*BLC_PWM_CTL Should be initiated while backlight device init*/
- BUG_ON((max_pwm_blc & PSB_BLC_MAX_PWM_REG_FREQ) == 0);
+ BUG_ON(max_pwm_blc == 0);
blc_pwm_duty_cycle = level * max_pwm_blc / BRIGHTNESS_MAX_LEVEL;
@@ -154,6 +157,10 @@ static int psb_lvds_pwm_set_brightness(struct drm_device *dev, int level)
(max_pwm_blc << PSB_BACKLIGHT_PWM_CTL_SHIFT) |
(blc_pwm_duty_cycle));
+ dev_info(dev->dev, "Backlight lvds set brightness %08x\n",
+ (max_pwm_blc << PSB_BACKLIGHT_PWM_CTL_SHIFT) |
+ (blc_pwm_duty_cycle));
+
return 0;
}
@@ -162,14 +169,12 @@ static int psb_lvds_pwm_set_brightness(struct drm_device *dev, int level)
*/
void psb_intel_lvds_set_brightness(struct drm_device *dev, int level)
{
- /*u32 blc_pwm_ctl;*/
- struct drm_psb_private *dev_priv =
- (struct drm_psb_private *)dev->dev_private;
+ struct drm_psb_private *dev_priv = dev->dev_private;
dev_dbg(dev->dev, "backlight level is %d\n", level);
if (!dev_priv->lvds_bl) {
- dev_err(dev->dev, "NO LVDS Backlight Info\n");
+ dev_err(dev->dev, "NO LVDS backlight info\n");
return;
}
@@ -190,11 +195,13 @@ static void psb_intel_lvds_set_backlight(struct drm_device *dev, int level)
u32 blc_pwm_ctl;
if (gma_power_begin(dev, false)) {
- blc_pwm_ctl =
- REG_READ(BLC_PWM_CTL) & ~BACKLIGHT_DUTY_CYCLE_MASK;
+ blc_pwm_ctl = REG_READ(BLC_PWM_CTL);
+ blc_pwm_ctl &= ~BACKLIGHT_DUTY_CYCLE_MASK;
REG_WRITE(BLC_PWM_CTL,
(blc_pwm_ctl |
(level << BACKLIGHT_DUTY_CYCLE_SHIFT)));
+ dev_priv->saveBLC_PWM_CTL = (blc_pwm_ctl |
+ (level << BACKLIGHT_DUTY_CYCLE_SHIFT));
gma_power_end(dev);
} else {
blc_pwm_ctl = dev_priv->saveBLC_PWM_CTL &
@@ -212,9 +219,11 @@ static void psb_intel_lvds_set_power(struct drm_device *dev,
{
u32 pp_status;
- if (!gma_power_begin(dev, true))
+ if (!gma_power_begin(dev, true)) {
+ dev_err(dev->dev, "set power, chip off!\n");
return;
-
+ }
+
if (on) {
REG_WRITE(PP_CONTROL, REG_READ(PP_CONTROL) |
POWER_TARGET_ON);
@@ -296,9 +305,6 @@ static void psb_intel_lvds_restore(struct drm_connector *connector)
{
struct drm_device *dev = connector->dev;
u32 pp_status;
-
- /*struct drm_psb_private *dev_priv =
- (struct drm_psb_private *)dev->dev_private;*/
struct psb_intel_output *psb_intel_output =
to_psb_intel_output(connector);
struct psb_intel_lvds_priv *lvds_priv =
@@ -382,7 +388,6 @@ bool psb_intel_lvds_mode_fixup(struct drm_encoder *encoder,
if (psb_intel_output->type == INTEL_OUTPUT_MIPI2)
panel_fixed_mode = mode_dev->panel_fixed_mode2;
- /* FIXME: review for Medfield */
/* PSB requires the LVDS is on pipe B, MRST has only one pipe anyway */
if (!IS_MRST(dev) && psb_intel_crtc->pipe == 0) {
printk(KERN_ERR "Can't support LVDS on pipe A\n");
@@ -622,7 +627,8 @@ int psb_intel_lvds_set_property(struct drm_connector *connector,
goto set_prop_error;
else {
#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE
- struct drm_psb_private *devp = encoder->dev->dev_private;
+ struct drm_psb_private *devp =
+ encoder->dev->dev_private;
struct backlight_device *bd = devp->backlight_device;
if (bd) {
bd->props.brightness = value;
@@ -695,8 +701,7 @@ void psb_intel_lvds_init(struct drm_device *dev,
struct drm_encoder *encoder;
struct drm_display_mode *scan; /* *modes, *bios_mode; */
struct drm_crtc *crtc;
- struct drm_psb_private *dev_priv =
- (struct drm_psb_private *)dev->dev_private;
+ struct drm_psb_private *dev_priv = dev->dev_private;
u32 lvds;
int pipe;
@@ -712,8 +717,8 @@ void psb_intel_lvds_init(struct drm_device *dev,
}
psb_intel_output->dev_priv = lvds_priv;
-
psb_intel_output->mode_dev = mode_dev;
+
connector = &psb_intel_output->base;
encoder = &psb_intel_output->enc;
drm_connector_init(dev, &psb_intel_output->base,
diff --git a/drivers/gpu/drm/gma500/psb_irq.c b/drivers/gpu/drm/gma500/psb_irq.c
index 2d9545816b54..7be802baceb5 100644
--- a/drivers/gpu/drm/gma500/psb_irq.c
+++ b/drivers/gpu/drm/gma500/psb_irq.c
@@ -138,21 +138,10 @@ void mid_disable_pipe_event(struct drm_psb_private *dev_priv, int pipe)
}
/**
- * Display controller interrupt handler for vsync/vblank.
- *
- */
-static void mid_vblank_handler(struct drm_device *dev, uint32_t pipe)
-{
- drm_handle_vblank(dev, pipe);
-}
-
-
-/**
* Display controller interrupt handler for pipe event.
*
*/
-#define WAIT_STATUS_CLEAR_LOOP_COUNT 0xffff
-static void mid_pipe_event_handler(struct drm_device *dev, uint32_t pipe)
+static void mid_pipe_event_handler(struct drm_device *dev, int pipe)
{
struct drm_psb_private *dev_priv =
(struct drm_psb_private *) dev->dev_private;
@@ -161,6 +150,7 @@ static void mid_pipe_event_handler(struct drm_device *dev, uint32_t pipe)
uint32_t pipe_stat_reg = psb_pipestat(pipe);
uint32_t pipe_enable = dev_priv->pipestat[pipe];
uint32_t pipe_status = dev_priv->pipestat[pipe] >> 16;
+ uint32_t pipe_clear;
uint32_t i = 0;
spin_lock(&dev_priv->irqmask_lock);
@@ -171,27 +161,23 @@ static void mid_pipe_event_handler(struct drm_device *dev, uint32_t pipe)
spin_unlock(&dev_priv->irqmask_lock);
- /* clear the 2nd level interrupt status bits */
- /**
- * FIXME: shouldn't use while loop here. However, the interrupt
- * status 'sticky' bits cannot be cleared by setting '1' to that
- * bit once...
- */
- for (i = 0; i < WAIT_STATUS_CLEAR_LOOP_COUNT; i++) {
+ /* Clear the 2nd level interrupt status bits
+ * Sometimes the bits are very sticky so we repeat until they unstick */
+ for (i = 0; i < 0xffff; i++) {
PSB_WVDC32(PSB_RVDC32(pipe_stat_reg), pipe_stat_reg);
- (void) PSB_RVDC32(pipe_stat_reg);
+ pipe_clear = PSB_RVDC32(pipe_stat_reg) & pipe_status;
- if ((PSB_RVDC32(pipe_stat_reg) & pipe_status) == 0)
+ if (pipe_clear == 0)
break;
}
- if (i == WAIT_STATUS_CLEAR_LOOP_COUNT)
+ if (pipe_clear)
dev_err(dev->dev,
- "%s, can't clear the status bits in pipe_stat_reg, its value = 0x%x.\n",
- __func__, PSB_RVDC32(pipe_stat_reg));
+ "%s, can't clear status bits for pipe %d, its value = 0x%x.\n",
+ __func__, pipe, PSB_RVDC32(pipe_stat_reg));
if (pipe_stat_val & PIPE_VBLANK_STATUS)
- mid_vblank_handler(dev, pipe);
+ drm_handle_vblank(dev, pipe);
if (pipe_stat_val & PIPE_TE_STATUS)
drm_handle_vblank(dev, pipe);
@@ -202,8 +188,11 @@ static void mid_pipe_event_handler(struct drm_device *dev, uint32_t pipe)
*/
static void psb_vdc_interrupt(struct drm_device *dev, uint32_t vdc_stat)
{
- if (vdc_stat & _PSB_PIPEA_EVENT_FLAG)
+ if (vdc_stat & _PSB_VSYNC_PIPEA_FLAG)
mid_pipe_event_handler(dev, 0);
+
+ if (vdc_stat & _PSB_VSYNC_PIPEB_FLAG)
+ mid_pipe_event_handler(dev, 1);
}
irqreturn_t psb_irq_handler(DRM_IRQ_ARGS)
@@ -219,8 +208,13 @@ irqreturn_t psb_irq_handler(DRM_IRQ_ARGS)
vdc_stat = PSB_RVDC32(PSB_INT_IDENTITY_R);
+ if (vdc_stat & _PSB_PIPE_EVENT_FLAG)
+ dsp_int = 1;
+
+ /* FIXME: Handle Medfield
if (vdc_stat & _MDFLD_DISP_ALL_IRQ_FLAG)
dsp_int = 1;
+ */
if (vdc_stat & _PSB_IRQ_SGX_FLAG)
sgx_int = 1;
@@ -266,13 +260,18 @@ void psb_irq_preinstall(struct drm_device *dev)
if (gma_power_is_on(dev))
PSB_WVDC32(0xFFFFFFFF, PSB_HWSTAM);
if (dev->vblank_enabled[0])
- dev_priv->vdc_irq_mask |= _PSB_PIPEA_EVENT_FLAG;
+ dev_priv->vdc_irq_mask |= _PSB_VSYNC_PIPEA_FLAG;
+ if (dev->vblank_enabled[1])
+ dev_priv->vdc_irq_mask |= _PSB_VSYNC_PIPEB_FLAG;
+
+ /* FIXME: Handle Medfield irq mask
if (dev->vblank_enabled[1])
dev_priv->vdc_irq_mask |= _MDFLD_PIPEB_EVENT_FLAG;
if (dev->vblank_enabled[2])
dev_priv->vdc_irq_mask |= _MDFLD_PIPEC_EVENT_FLAG;
+ */
- /*This register is safe even if display island is off*/
+ /* This register is safe even if display island is off */
PSB_WVDC32(~dev_priv->vdc_irq_mask, PSB_INT_MASK_R);
spin_unlock_irqrestore(&dev_priv->irqmask_lock, irqflags);
}
@@ -464,7 +463,13 @@ int psb_enable_vblank(struct drm_device *dev, int pipe)
spin_lock_irqsave(&dev_priv->irqmask_lock, irqflags);
- mid_enable_pipe_event(dev_priv, pipe);
+ if (pipe == 0)
+ dev_priv->vdc_irq_mask |= _PSB_VSYNC_PIPEA_FLAG;
+ else if (pipe == 1)
+ dev_priv->vdc_irq_mask |= _PSB_VSYNC_PIPEB_FLAG;
+
+ PSB_WVDC32(~dev_priv->vdc_irq_mask, PSB_INT_MASK_R);
+ PSB_WVDC32(dev_priv->vdc_irq_mask, PSB_INT_ENABLE_R);
psb_enable_pipestat(dev_priv, pipe, PIPE_VBLANK_INTERRUPT_ENABLE);
spin_unlock_irqrestore(&dev_priv->irqmask_lock, irqflags);
@@ -482,7 +487,13 @@ void psb_disable_vblank(struct drm_device *dev, int pipe)
spin_lock_irqsave(&dev_priv->irqmask_lock, irqflags);
- mid_disable_pipe_event(dev_priv, pipe);
+ if (pipe == 0)
+ dev_priv->vdc_irq_mask &= ~_PSB_VSYNC_PIPEA_FLAG;
+ else if (pipe == 1)
+ dev_priv->vdc_irq_mask &= ~_PSB_VSYNC_PIPEB_FLAG;
+
+ PSB_WVDC32(~dev_priv->vdc_irq_mask, PSB_INT_MASK_R);
+ PSB_WVDC32(dev_priv->vdc_irq_mask, PSB_INT_ENABLE_R);
psb_disable_pipestat(dev_priv, pipe, PIPE_VBLANK_INTERRUPT_ENABLE);
spin_unlock_irqrestore(&dev_priv->irqmask_lock, irqflags);
diff --git a/drivers/gpu/drm/gma500/psb_lid.c b/drivers/gpu/drm/gma500/psb_lid.c
index af328516561e..b867aabe6bf3 100644
--- a/drivers/gpu/drm/gma500/psb_lid.c
+++ b/drivers/gpu/drm/gma500/psb_lid.c
@@ -52,8 +52,6 @@ static void psb_lid_timer_func(unsigned long data)
pp_status = REG_READ(PP_STATUS);
} while ((pp_status & PP_ON) == 0);
}
- /* printk(KERN_INFO"%s: lid: closed\n", __FUNCTION__); */
-
dev_priv->lid_last_state = readl(lid_state);
lid_timer_schedule:
diff --git a/include/drm/gma_drm.h b/include/drm/gma_drm.h
new file mode 100644
index 000000000000..113686785717
--- /dev/null
+++ b/include/drm/gma_drm.h
@@ -0,0 +1,91 @@
+/**************************************************************************
+ * Copyright (c) 2007-2011, Intel Corporation.
+ * All Rights Reserved.
+ * Copyright (c) 2008, Tungsten Graphics Inc. Cedar Park, TX., USA.
+ * All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ **************************************************************************/
+
+#ifndef _PSB_DRM_H_
+#define _PSB_DRM_H_
+
+/*
+ * Manage the LUT for an output
+ */
+struct drm_psb_dpst_lut_arg {
+ uint8_t lut[256];
+ int output_id;
+};
+
+/*
+ * Validate modes
+ */
+struct drm_psb_mode_operation_arg {
+ u32 obj_id;
+ u16 operation;
+ struct drm_mode_modeinfo mode;
+ u64 data;
+};
+
+/*
+ * Query the stolen memory for smarter management of
+ * memory by the server
+ */
+struct drm_psb_stolen_memory_arg {
+ u32 base;
+ u32 size;
+};
+
+struct drm_psb_get_pipe_from_crtc_id_arg {
+ /** ID of CRTC being requested **/
+ u32 crtc_id;
+ /** pipe of requested CRTC **/
+ u32 pipe;
+};
+
+struct drm_psb_gem_create {
+ __u64 size;
+ __u32 handle;
+ __u32 flags;
+#define GMA_GEM_CREATE_STOLEN 1 /* Stolen memory can be used */
+};
+
+struct drm_psb_gem_mmap {
+ __u32 handle;
+ __u32 pad;
+ /**
+ * Fake offset to use for subsequent mmap call
+ *
+ * This is a fixed-size type for 32/64 compatibility.
+ */
+ __u64 offset;
+};
+
+/* Controlling the kernel modesetting buffers */
+
+#define DRM_GMA_GEM_CREATE 0x00 /* Create a GEM object */
+#define DRM_GMA_GEM_MMAP 0x01 /* Map GEM memory */
+#define DRM_GMA_STOLEN_MEMORY 0x02 /* Report stolen memory */
+#define DRM_GMA_2D_OP 0x03 /* Will be merged later */
+#define DRM_GMA_GAMMA 0x04 /* Set gamma table */
+#define DRM_GMA_ADB 0x05 /* Get backlight */
+#define DRM_GMA_DPST_BL 0x06 /* Set backlight */
+#define DRM_GMA_GET_PIPE_FROM_CRTC_ID 0x1 /* CRTC to physical pipe# */
+#define DRM_GMA_MODE_OPERATION 0x07 /* Mode validation/DC set */
+#define PSB_MODE_OPERATION_MODE_VALID 0x01
+
+
+#endif