Commit cee5ec43 authored by Dave Airlie's avatar Dave Airlie

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
parents 04b3924d 1b22edfd
...@@ -111,14 +111,15 @@ static int psbfb_2d_submit(struct drm_psb_private *dev_priv, uint32_t *cmdbuf, ...@@ -111,14 +111,15 @@ static int psbfb_2d_submit(struct drm_psb_private *dev_priv, uint32_t *cmdbuf,
int ret = 0; int ret = 0;
int i; int i;
unsigned submit_size; unsigned submit_size;
unsigned long flags;
mutex_lock(&dev_priv->mutex_2d); spin_lock_irqsave(&dev_priv->lock_2d, flags);
while (size > 0) { while (size > 0) {
submit_size = (size < 0x60) ? size : 0x60; submit_size = (size < 0x60) ? size : 0x60;
size -= submit_size; size -= submit_size;
ret = psb_2d_wait_available(dev_priv, submit_size); ret = psb_2d_wait_available(dev_priv, submit_size);
if (ret) if (ret)
break; break;
submit_size <<= 2; submit_size <<= 2;
...@@ -127,7 +128,7 @@ static int psbfb_2d_submit(struct drm_psb_private *dev_priv, uint32_t *cmdbuf, ...@@ -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); (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; return ret;
} }
...@@ -327,8 +328,9 @@ int psbfb_sync(struct fb_info *info) ...@@ -327,8 +328,9 @@ int psbfb_sync(struct fb_info *info)
struct drm_psb_private *dev_priv = dev->dev_private; struct drm_psb_private *dev_priv = dev->dev_private;
unsigned long _end = jiffies + DRM_HZ; unsigned long _end = jiffies + DRM_HZ;
int busy = 0; 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. * First idle the 2D engine.
*/ */
...@@ -357,6 +359,6 @@ int psbfb_sync(struct fb_info *info) ...@@ -357,6 +359,6 @@ int psbfb_sync(struct fb_info *info)
_PSB_C2B_STATUS_BUSY) != 0); _PSB_C2B_STATUS_BUSY) != 0);
out: out:
mutex_unlock(&dev_priv->mutex_2d); spin_unlock_irqrestore(&dev_priv->lock_2d, flags);
return (busy) ? -EBUSY : 0; return (busy) ? -EBUSY : 0;
} }
...@@ -20,7 +20,7 @@ ...@@ -20,7 +20,7 @@
#include <linux/backlight.h> #include <linux/backlight.h>
#include <drm/drmP.h> #include <drm/drmP.h>
#include <drm/drm.h> #include <drm/drm.h>
#include "psb_drm.h" #include "gma_drm.h"
#include "psb_drv.h" #include "psb_drv.h"
#include "psb_reg.h" #include "psb_reg.h"
#include "psb_intel_reg.h" #include "psb_intel_reg.h"
...@@ -30,7 +30,6 @@ ...@@ -30,7 +30,6 @@
#define VGA_SR_INDEX 0x3c4 #define VGA_SR_INDEX 0x3c4
#define VGA_SR_DATA 0x3c5 #define VGA_SR_DATA 0x3c5
/* FIXME: should check if we are the active VGA device ?? */
static void cdv_disable_vga(struct drm_device *dev) static void cdv_disable_vga(struct drm_device *dev)
{ {
u8 sr1; u8 sr1;
......
...@@ -38,6 +38,7 @@ ...@@ -38,6 +38,7 @@
#include "psb_intel_reg.h" #include "psb_intel_reg.h"
#include "psb_intel_drv.h" #include "psb_intel_drv.h"
#include "framebuffer.h" #include "framebuffer.h"
#include "gtt.h"
static void psb_user_framebuffer_destroy(struct drm_framebuffer *fb); static void psb_user_framebuffer_destroy(struct drm_framebuffer *fb);
static int psb_user_framebuffer_create_handle(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, ...@@ -90,6 +91,25 @@ static int psbfb_setcolreg(unsigned regno, unsigned red, unsigned green,
return 0; 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) void psbfb_suspend(struct drm_device *dev)
{ {
...@@ -216,6 +236,21 @@ static struct fb_ops psbfb_ops = { ...@@ -216,6 +236,21 @@ static struct fb_ops psbfb_ops = {
.fb_ioctl = psbfb_ioctl, .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 = { static struct fb_ops psbfb_unaccel_ops = {
.owner = THIS_MODULE, .owner = THIS_MODULE,
.fb_check_var = drm_fb_helper_check_var, .fb_check_var = drm_fb_helper_check_var,
...@@ -306,16 +341,14 @@ static struct drm_framebuffer *psb_framebuffer_create ...@@ -306,16 +341,14 @@ static struct drm_framebuffer *psb_framebuffer_create
* psbfb_alloc - allocate frame buffer memory * psbfb_alloc - allocate frame buffer memory
* @dev: the DRM device * @dev: the DRM device
* @aligned_size: space needed * @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 * 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 * 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 * we fail as we don't have the virtual mapping space to really vmap it
* and back it with a GEM object. * and the kernel console code can't handle non linear framebuffers.
* *
* In this case the GEM object has no handle. * Re-address this as and if the framebuffer layer grows this ability.
*
* FIXME: console speed up - allocate twice the space if room and use
* hardware scrolling for acceleration.
*/ */
static struct gtt_range *psbfb_alloc(struct drm_device *dev, int aligned_size) 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) ...@@ -328,17 +361,7 @@ static struct gtt_range *psbfb_alloc(struct drm_device *dev, int aligned_size)
return backing; return backing;
psb_gtt_free_range(dev, backing); psb_gtt_free_range(dev, backing);
} }
/* Next try using GEM host memory */ return NULL;
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;
} }
/** /**
...@@ -362,6 +385,8 @@ static int psbfb_create(struct psb_fbdev *fbdev, ...@@ -362,6 +385,8 @@ static int psbfb_create(struct psb_fbdev *fbdev,
int ret; int ret;
struct gtt_range *backing; struct gtt_range *backing;
u32 bpp, depth; u32 bpp, depth;
int gtt_roll = 0;
int pitch_lines = 0;
mode_cmd.width = sizes->surface_width; mode_cmd.width = sizes->surface_width;
mode_cmd.height = sizes->surface_height; mode_cmd.height = sizes->surface_height;
...@@ -371,17 +396,51 @@ static int psbfb_create(struct psb_fbdev *fbdev, ...@@ -371,17 +396,51 @@ static int psbfb_create(struct psb_fbdev *fbdev,
if (bpp == 24) if (bpp == 24)
bpp = 32; bpp = 32;
/* HW requires pitch to be 64 byte aligned */ do {
mode_cmd.pitches[0] = ALIGN(mode_cmd.width * ((bpp + 7) / 8), 64); /*
depth = sizes->surface_depth; * 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 = mode_cmd.pitches[0] * mode_cmd.height;
size = ALIGN(size, PAGE_SIZE); size = ALIGN(size, PAGE_SIZE);
/* Allocate the framebuffer in the GTT with stolen page backing */ /* Allocate the fb in the GTT with stolen page backing */
backing = psbfb_alloc(dev, size); backing = psbfb_alloc(dev, size);
if (backing == NULL)
return -ENOMEM; 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); mutex_lock(&dev->struct_mutex);
...@@ -407,11 +466,13 @@ static int psbfb_create(struct psb_fbdev *fbdev, ...@@ -407,11 +466,13 @@ static int psbfb_create(struct psb_fbdev *fbdev,
strcpy(info->fix.id, "psbfb"); strcpy(info->fix.id, "psbfb");
info->flags = FBINFO_DEFAULT; info->flags = FBINFO_DEFAULT;
/* No 2D engine */ if (dev_priv->ops->accel_2d && pitch_lines > 8) /* 2D engine */
if (!dev_priv->ops->accel_2d)
info->fbops = &psbfb_unaccel_ops;
else
info->fbops = &psbfb_ops; 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); ret = fb_alloc_cmap(&info->cmap, 256, 0);
if (ret) { if (ret) {
...@@ -421,23 +482,12 @@ static int psbfb_create(struct psb_fbdev *fbdev, ...@@ -421,23 +482,12 @@ static int psbfb_create(struct psb_fbdev *fbdev,
info->fix.smem_start = dev->mode_config.fb_base; info->fix.smem_start = dev->mode_config.fb_base;
info->fix.smem_len = size; info->fix.smem_len = size;
info->fix.ywrapstep = gtt_roll;
info->fix.ypanstep = 0;
if (backing->stolen) { /* Accessed stolen memory directly */
/* Accessed stolen memory directly */ info->screen_base = (char *)dev_priv->vram_addr +
info->screen_base = (char *)dev_priv->vram_addr +
backing->offset; 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; info->screen_size = size;
if (dev_priv->gtt.stolen_size) { if (dev_priv->gtt.stolen_size) {
...@@ -471,11 +521,8 @@ static int psbfb_create(struct psb_fbdev *fbdev, ...@@ -471,11 +521,8 @@ static int psbfb_create(struct psb_fbdev *fbdev,
out_unref: out_unref:
if (backing->stolen) if (backing->stolen)
psb_gtt_free_range(dev, backing); psb_gtt_free_range(dev, backing);
else { else
if (psbfb->vm_map)
vm_unmap_ram(info->screen_base, backing->npage);
drm_gem_object_unreference(&backing->gem); drm_gem_object_unreference(&backing->gem);
}
out_err1: out_err1:
mutex_unlock(&dev->struct_mutex); mutex_unlock(&dev->struct_mutex);
psb_gtt_free_range(dev, backing); psb_gtt_free_range(dev, backing);
...@@ -549,13 +596,6 @@ int psb_fbdev_destroy(struct drm_device *dev, struct psb_fbdev *fbdev) ...@@ -549,13 +596,6 @@ int psb_fbdev_destroy(struct drm_device *dev, struct psb_fbdev *fbdev)
if (fbdev->psb_fb_helper.fbdev) { if (fbdev->psb_fb_helper.fbdev) {
info = 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); unregister_framebuffer(info);
if (info->cmap.len) if (info->cmap.len)
fb_dealloc_cmap(&info->cmap); fb_dealloc_cmap(&info->cmap);
...@@ -765,7 +805,7 @@ void psb_modeset_init(struct drm_device *dev) ...@@ -765,7 +805,7 @@ void psb_modeset_init(struct drm_device *dev)
dev->mode_config.funcs = (void *) &psb_mode_funcs; dev->mode_config.funcs = (void *) &psb_mode_funcs;
/* set memory base */ /* 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 *) pci_read_config_dword(dev->pdev, PSB_BSM, (u32 *)
&(dev->mode_config.fb_base)); &(dev->mode_config.fb_base));
......
...@@ -32,7 +32,6 @@ struct psb_framebuffer { ...@@ -32,7 +32,6 @@ struct psb_framebuffer {
struct address_space *addr_space; struct address_space *addr_space;
struct fb_info *fbdev; struct fb_info *fbdev;
struct gtt_range *gtt; struct gtt_range *gtt;
bool vm_map; /* True if we must undo a vm_map_ram */
}; };
struct psb_fbdev { struct psb_fbdev {
......
...@@ -25,7 +25,7 @@ ...@@ -25,7 +25,7 @@
#include <drm/drmP.h> #include <drm/drmP.h>
#include <drm/drm.h> #include <drm/drm.h>
#include "psb_drm.h" #include "gma_drm.h"
#include "psb_drv.h" #include "psb_drv.h"
int psb_gem_init_object(struct drm_gem_object *obj) int psb_gem_init_object(struct drm_gem_object *obj)
...@@ -120,8 +120,7 @@ static int psb_gem_create(struct drm_file *file, ...@@ -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 */ /* Initialize the extra goodies GEM needs to do all the hard work */
if (drm_gem_object_init(dev, &r->gem, size) != 0) { if (drm_gem_object_init(dev, &r->gem, size) != 0) {
psb_gtt_free_range(dev, r); psb_gtt_free_range(dev, r);
/* GEM doesn't give an error code and we don't have an /* GEM doesn't give an error code so use -ENOMEM */
EGEMSUCKS so make something up for now - FIXME */
dev_err(dev->dev, "GEM init failed for %lld\n", size); dev_err(dev->dev, "GEM init failed for %lld\n", size);
return -ENOMEM; return -ENOMEM;
} }
...@@ -191,8 +190,6 @@ int psb_gem_dumb_destroy(struct drm_file *file, struct drm_device *dev, ...@@ -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 * 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 * vma->vm_private_data points to the GEM object that is backing this
* mapping. * mapping.
*
* FIXME
*/ */
int psb_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf) 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, ...@@ -274,13 +271,13 @@ int psb_gem_create_ioctl(struct drm_device *dev, void *data,
{ {
struct drm_psb_gem_create *args = data; struct drm_psb_gem_create *args = data;
int ret; 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, ret = psb_gem_create_stolen(file, dev, args->size,
&args->handle); &args->handle);
if (ret == 0) if (ret == 0)
return 0; return 0;
/* Fall throguh */ /* Fall throguh */
args->flags &= ~PSB_GEM_CREATE_STOLEN; args->flags &= ~GMA_GEM_CREATE_STOLEN;
} }
return psb_gem_create(file, dev, args->size, &args->handle); return psb_gem_create(file, dev, args->size, &args->handle);
} }
......
...@@ -72,9 +72,8 @@ u32 *psb_gtt_entry(struct drm_device *dev, struct gtt_range *r) ...@@ -72,9 +72,8 @@ u32 *psb_gtt_entry(struct drm_device *dev, struct gtt_range *r)
* @r: our GTT range * @r: our GTT range
* *
* Take our preallocated GTT range and insert the GEM object into * Take our preallocated GTT range and insert the GEM object into
* the GTT. * the GTT. This is protected via the gtt mutex which the caller
* * must hold.
* FIXME: gtt lock ?
*/ */
static int psb_gtt_insert(struct drm_device *dev, struct gtt_range *r) 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) ...@@ -96,12 +95,17 @@ static int psb_gtt_insert(struct drm_device *dev, struct gtt_range *r)
set_pages_array_uc(pages, r->npage); set_pages_array_uc(pages, r->npage);
/* Write our page entries into the GTT itself */ /* Write our page entries into the GTT itself */
for (i = 0; i < r->npage; i++) { for (i = r->roll; i < r->npage; i++) {
pte = psb_gtt_mask_pte(page_to_pfn(*pages++), 0/*type*/); 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++); iowrite32(pte, gtt_slot++);
} }
/* Make sure all the entries are set before we return */ /* Make sure all the entries are set before we return */
ioread32(gtt_slot - 1); ioread32(gtt_slot - 1);
return 0; return 0;
} }
...@@ -111,9 +115,9 @@ static int psb_gtt_insert(struct drm_device *dev, struct gtt_range *r) ...@@ -111,9 +115,9 @@ static int psb_gtt_insert(struct drm_device *dev, struct gtt_range *r)
* @r: our GTT range * @r: our GTT range
* *
* Remove a preallocated GTT range from the GTT. Overwrite all the * 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) static void psb_gtt_remove(struct drm_device *dev, struct gtt_range *r)
{ {
struct drm_psb_private *dev_priv = dev->dev_private; struct drm_psb_private *dev_priv = dev->dev_private;
...@@ -131,12 +135,53 @@ static void psb_gtt_remove(struct drm_device *dev, struct gtt_range *r) ...@@ -131,12 +135,53 @@ static void psb_gtt_remove(struct drm_device *dev, struct gtt_range *r)
set_pages_array_wb(r->pages, r->npage); set_pages_array_wb(r->pages, r->npage);
} }
/**
* 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 * psb_gtt_attach_pages - attach and pin GEM pages
* @gt: the gtt range * @gt: the gtt range
* *
* Pin and build an in kernel list of the pages that back our GEM object. * 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) static int psb_gtt_attach_pages(struct gtt_range *gt)
{ {
...@@ -158,7 +203,7 @@ 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; gt->npage = pages;
for (i = 0; i < pages; i++) { 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, p = read_cache_page_gfp(mapping, i,
__GFP_COLD | GFP_KERNEL); __GFP_COLD | GFP_KERNEL);
if (IS_ERR(p)) if (IS_ERR(p))
...@@ -181,7 +226,8 @@ static int psb_gtt_attach_pages(struct gtt_range *gt) ...@@ -181,7 +226,8 @@ static int psb_gtt_attach_pages(struct gtt_range *gt)
* *
* Undo the effect of psb_gtt_attach_pages. At this point the pages * 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 * 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) 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, ...@@ -300,6 +346,7 @@ struct gtt_range *psb_gtt_alloc_range(struct drm_device *dev, int len,
gt->resource.name = name; gt->resource.name = name;
gt->stolen = backed; gt->stolen = backed;
gt->in_gart = backed; gt->in_gart = backed;
gt->roll = 0;
/* Ensure this is set for non GEM objects */ /* Ensure this is set for non GEM objects */
gt->gem.dev = dev; gt->gem.dev = dev;
ret = allocate_resource(dev_priv->gtt_mem, &gt->resource, ret = allocate_resource(dev_priv->gtt_mem, &gt->resource,
...@@ -390,15 +437,18 @@ int psb_gtt_init(struct drm_device *dev, int resume) ...@@ -390,15 +437,18 @@ int psb_gtt_init(struct drm_device *dev, int resume)
pg->gtt_phys_start = dev_priv->pge_ctl & PAGE_MASK; pg->gtt_phys_start = dev_priv->pge_ctl & PAGE_MASK;
/* /*
* FIXME: video mmu has hw bug to access 0x0D0000000, * The video mmu has a hw bug when accessing 0x0D0000000.
* then make gatt start at 0x0e000,0000 * 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->mmu_gatt_start = 0xE0000000;
pg->gtt_start = pci_resource_start(dev->pdev, PSB_GTT_RESOURCE); pg->gtt_start = pci_resource_start(dev->pdev, PSB_GTT_RESOURCE);
gtt_pages = pci_resource_len(dev->pdev, PSB_GTT_RESOURCE) gtt_pages = pci_resource_len(dev->pdev, PSB_GTT_RESOURCE)
>> PAGE_SHIFT; >> 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) { if (pg->gtt_start == 0 || gtt_pages == 0) {
dev_err(dev->dev, "GTT PCI BAR not initialized.\n"); dev_err(dev->dev, "GTT PCI BAR not initialized.\n");
gtt_pages = 64; gtt_pages = 64;
...@@ -412,13 +462,16 @@ int psb_gtt_init(struct drm_device *dev, int resume) ...@@ -412,13 +462,16 @@ int psb_gtt_init(struct drm_device *dev, int resume)
if (pg->gatt_pages == 0 || pg->gatt_start == 0) { if (pg->gatt_pages == 0 || pg->gatt_start == 0) {
static struct resource fudge; /* Preferably peppermint */ static struct resource fudge; /* Preferably peppermint */
/* This can occur on CDV SDV systems. Fudge it in this case. /* This can occur on CDV SDV systems. Fudge it in this case.
We really don't care what imaginary space is being allocated We really don't care what imaginary space is being allocated
at this point */ at this point */
dev_err(dev->dev, "GATT PCI BAR not initialized.\n"); dev_err(dev->dev, "GATT PCI BAR not initialized.\n");
pg->gatt_start = 0x40000000; pg->gatt_start = 0x40000000;
pg->gatt_pages = (128 * 1024 * 1024) >> PAGE_SHIFT; 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.start = 0x40000000;
fudge.end = 0x40000000 + 128 * 1024 * 1024 - 1; fudge.end = 0x40000000 + 128 * 1024 * 1024 - 1;
fudge.name = "fudge"; fudge.name = "fudge";
......
...@@ -49,6 +49,7 @@ struct gtt_range { ...@@ -49,6 +49,7 @@ struct gtt_range {
bool mmapping; /* Is mmappable */ bool mmapping; /* Is mmappable */
struct page **pages; /* Backing pages if present */ struct page **pages; /* Backing pages if present */
int npage; /* Number of backing pages */ 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, 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); ...@@ -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 void psb_gtt_free_range(struct drm_device *dev, struct gtt_range *gt);
extern int psb_gtt_pin(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_unpin(struct gtt_range *gt);
extern void psb_gtt_roll(struct drm_device *dev,
struct gtt_range *gt, int roll);
#endif #endif
...@@ -20,7 +20,7 @@ ...@@ -20,7 +20,7 @@
*/ */
#include <drm/drmP.h> #include <drm/drmP.h>
#include <drm/drm.h> #include <drm/drm.h>
#include "psb_drm.h" #include "gma_drm.h"
#include "psb_drv.h" #include "psb_drv.h"
#include "psb_intel_drv.h" #include "psb_intel_drv.h"
#include "psb_intel_reg.h" #include "psb_intel_reg.h"
......
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE. * DEALINGS IN THE SOFTWARE.
* *
* FIXME: resolve with the i915 version
*/ */
#include "psb_drv.h" #include "psb_drv.h"
......
...@@ -25,7 +25,7 @@ ...@@ -25,7 +25,7 @@
#include <drm/drmP.h> #include <drm/drmP.h>
#include <drm/drm.h> #include <drm/drm.h>
#include "psb_drm.h" #include "gma_drm.h"
#include "psb_drv.h" #include "psb_drv.h"
#include "mid_bios.h" #include "mid_bios.h"
...@@ -142,6 +142,12 @@ static void mid_get_vbt_data(struct drm_psb_private *dev_priv) ...@@ -142,6 +142,12 @@ static void mid_get_vbt_data(struct drm_psb_private *dev_priv)
memcpy(vbt, vbt_virtual, sizeof(*vbt)); memcpy(vbt, vbt_virtual, sizeof(*vbt));
iounmap(vbt_virtual); /* Free virtual address space */ 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); dev_dbg(dev->dev, "GCT revision is %x\n", vbt->revision);
switch (vbt->revision) { switch (vbt->revision) {
......
...@@ -521,12 +521,11 @@ int oaktrail_pipe_set_base(struct drm_crtc *crtc, ...@@ -521,12 +521,11 @@ int oaktrail_pipe_set_base(struct drm_crtc *crtc,
int x, int y, struct drm_framebuffer *old_fb) int x, int y, struct drm_framebuffer *old_fb)
{ {
struct drm_device *dev = crtc->dev; 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_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc);
struct psb_framebuffer *psbfb = to_psb_fb(crtc->fb); struct psb_framebuffer *psbfb = to_psb_fb(crtc->fb);
int pipe = psb_intel_crtc->pipe; int pipe = psb_intel_crtc->pipe;
unsigned long start, offset; unsigned long start, offset;
/* FIXME: check if we need this surely MRST is pipe 0 only */
int dspbase = (pipe == 0 ? DSPALINOFF : DSPBBASE); int dspbase = (pipe == 0 ? DSPALINOFF : DSPBBASE);
int dspsurf = (pipe == 0 ? DSPASURF : DSPBSURF); int dspsurf = (pipe == 0 ? DSPASURF : DSPBSURF);
int dspstride = (pipe == 0) ? DSPASTRIDE : DSPBSTRIDE; int dspstride = (pipe == 0) ? DSPASTRIDE : DSPBSTRIDE;
...@@ -572,15 +571,10 @@ int oaktrail_pipe_set_base(struct drm_crtc *crtc, ...@@ -572,15 +571,10 @@ int oaktrail_pipe_set_base(struct drm_crtc *crtc,
} }
REG_WRITE(dspcntr_reg, dspcntr); REG_WRITE(dspcntr_reg, dspcntr);
if (0 /* FIXMEAC - check what PSB needs */) { REG_WRITE(dspbase, offset);
REG_WRITE(dspbase, offset); REG_READ(dspbase);
REG_READ(dspbase); REG_WRITE(dspsurf, start);
REG_WRITE(dspsurf, start); REG_READ(dspsurf);
REG_READ(dspsurf);
} else {
REG_WRITE(dspbase, start + offset);
REG_READ(dspbase);
}
pipe_set_base_exit: pipe_set_base_exit:
gma_power_end(dev); gma_power_end(dev);
......
...@@ -22,13 +22,14 @@ ...@@ -22,13 +22,14 @@
#include <linux/dmi.h> #include <linux/dmi.h>
#include <drm/drmP.h> #include <drm/drmP.h>
#include <drm/drm.h> #include <drm/drm.h>
#include "psb_drm.h" #include "gma_drm.h"
#include "psb_drv.h" #include "psb_drv.h"
#include "psb_reg.h" #include "psb_reg.h"
#include "psb_intel_reg.h" #include "psb_intel_reg.h"
#include <asm/mrst.h> #include <asm/mrst.h>
#include <asm/intel_scu_ipc.h> #include <asm/intel_scu_ipc.h>
#include "mid_bios.h" #include "mid_bios.h"
#include "intel_bios.h"
static int oaktrail_output_init(struct drm_device *dev) static int oaktrail_output_init(struct drm_device *dev)
{ {
...@@ -456,9 +457,31 @@ static int oaktrail_power_up(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) 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); oaktrail_hdmi_teardown(dev);
if (vbt->size == 0)
psb_intel_destroy_bios(dev);
} }
const struct psb_ops oaktrail_chip_ops = { const struct psb_ops oaktrail_chip_ops = {
...@@ -468,7 +491,7 @@ const struct psb_ops oaktrail_chip_ops = { ...@@ -468,7 +491,7 @@ const struct psb_ops oaktrail_chip_ops = {
.crtcs = 2, .crtcs = 2,
.sgx_offset = MRST_SGX_OFFSET, .sgx_offset = MRST_SGX_OFFSET,
.chip_setup = mid_chip_setup, .chip_setup = oaktrail_chip_setup,
.chip_teardown = oaktrail_teardown, .chip_teardown = oaktrail_teardown,
.crtc_helper = &oaktrail_helper_funcs, .crtc_helper = &oaktrail_helper_funcs,
.crtc_funcs = &psb_intel_crtc_funcs, .crtc_funcs = &psb_intel_crtc_funcs,
......
...@@ -228,17 +228,20 @@ static struct drm_display_mode lvds_configuration_modes[] = { ...@@ -228,17 +228,20 @@ static struct drm_display_mode lvds_configuration_modes[] = {
/* Returns the panel fixed mode from configuration. */ /* Returns the panel fixed mode from configuration. */
static struct drm_display_mode * static void oaktrail_lvds_get_configuration_mode(struct drm_device *dev,
oaktrail_lvds_get_configuration_mode(struct drm_device *dev) struct psb_intel_mode_device *mode_dev)
{ {
struct drm_display_mode *mode = NULL; struct drm_display_mode *mode = NULL;
struct drm_psb_private *dev_priv = dev->dev_private; struct drm_psb_private *dev_priv = dev->dev_private;
struct oaktrail_timing_info *ti = &dev_priv->gct_data.DTD; 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*/ if (dev_priv->vbt_data.size != 0x00) { /*if non-zero, then use vbt*/
mode = kzalloc(sizeof(*mode), GFP_KERNEL); mode = kzalloc(sizeof(*mode), GFP_KERNEL);
if (!mode) if (!mode)
return NULL; return;
mode->hdisplay = (ti->hactive_hi << 8) | ti->hactive_lo; mode->hdisplay = (ti->hactive_hi << 8) | ti->hactive_lo;
mode->vdisplay = (ti->vactive_hi << 8) | ti->vactive_lo; mode->vdisplay = (ti->vactive_hi << 8) | ti->vactive_lo;
...@@ -270,13 +273,27 @@ oaktrail_lvds_get_configuration_mode(struct drm_device *dev) ...@@ -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 "vtotal is %d\n", mode->vtotal);
printk(KERN_INFO "clock is %d\n", mode->clock); printk(KERN_INFO "clock is %d\n", mode->clock);
#endif #endif
} else mode_dev->panel_fixed_mode = mode;
mode = drm_mode_duplicate(dev, &lvds_configuration_modes[2]); }
drm_mode_set_name(mode);
drm_mode_set_crtcinfo(mode, 0);
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, ...@@ -375,7 +392,7 @@ void oaktrail_lvds_init(struct drm_device *dev,
* If we didn't get EDID, try geting panel timing * If we didn't get EDID, try geting panel timing
* from configuration data * 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) { if (mode_dev->panel_fixed_mode) {
mode_dev->panel_fixed_mode->type |= DRM_MODE_TYPE_PREFERRED; mode_dev->panel_fixed_mode->type |= DRM_MODE_TYPE_PREFERRED;
......
...@@ -302,7 +302,7 @@ int psb_runtime_suspend(struct device *dev) ...@@ -302,7 +302,7 @@ int psb_runtime_suspend(struct device *dev)
int psb_runtime_resume(struct device *dev) int psb_runtime_resume(struct device *dev)
{ {
return 0; return gma_power_resume(dev);;
} }
int psb_runtime_idle(struct device *dev) int psb_runtime_idle(struct device *dev)
......
...@@ -20,7 +20,7 @@ ...@@ -20,7 +20,7 @@
#include <linux/backlight.h> #include <linux/backlight.h>
#include <drm/drmP.h> #include <drm/drmP.h>
#include <drm/drm.h> #include <drm/drm.h>
#include "psb_drm.h" #include "gma_drm.h"
#include "psb_drv.h" #include "psb_drv.h"
#include "psb_reg.h" #include "psb_reg.h"
#include "psb_intel_reg.h" #include "psb_intel_reg.h"
...@@ -213,7 +213,6 @@ static int psb_restore_display_registers(struct drm_device *dev) ...@@ -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_psb_private *dev_priv = dev->dev_private;
struct drm_crtc *crtc; struct drm_crtc *crtc;
struct drm_connector *connector; struct drm_connector *connector;
int pp_stat;
/* Display arbitration + watermarks */ /* Display arbitration + watermarks */
PSB_WVDC32(dev_priv->saveDSPARB, DSPARB); PSB_WVDC32(dev_priv->saveDSPARB, DSPARB);
...@@ -237,37 +236,6 @@ static int psb_restore_display_registers(struct drm_device *dev) ...@@ -237,37 +236,6 @@ static int psb_restore_display_registers(struct drm_device *dev)
connector->funcs->restore(connector); connector->funcs->restore(connector);
mutex_unlock(&dev->mode_config.mutex); 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; return 0;
} }
......
...@@ -21,7 +21,7 @@ ...@@ -21,7 +21,7 @@
#include <drm/drmP.h> #include <drm/drmP.h>
#include <drm/drm.h> #include <drm/drm.h>
#include "psb_drm.h" #include "gma_drm.h"
#include "psb_drv.h" #include "psb_drv.h"
#include "framebuffer.h" #include "framebuffer.h"
#include "psb_reg.h" #include "psb_reg.h"
...@@ -80,58 +80,36 @@ MODULE_DEVICE_TABLE(pci, pciidlist); ...@@ -80,58 +80,36 @@ MODULE_DEVICE_TABLE(pci, pciidlist);
* Standard IOCTLs. * 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 \ #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 \ #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) struct drm_psb_mode_operation_arg)
#define DRM_IOCTL_PSB_STOLEN_MEMORY \ #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) 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 \ #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) struct drm_psb_dpst_lut_arg)
#define DRM_IOCTL_PSB_DPST_BL \ #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) uint32_t)
#define DRM_IOCTL_PSB_GET_PIPE_FROM_CRTC_ID \ #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) struct drm_psb_get_pipe_from_crtc_id_arg)
#define DRM_IOCTL_PSB_GEM_CREATE \ #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) struct drm_psb_gem_create)
#define DRM_IOCTL_PSB_GEM_MMAP \ #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) 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, static int psb_adb_ioctl(struct drm_device *dev, void *data,
struct drm_file *file_priv); struct drm_file *file_priv);
static int psb_mode_operation_ioctl(struct drm_device *dev, void *data, static int psb_mode_operation_ioctl(struct drm_device *dev, void *data,
struct drm_file *file_priv); struct drm_file *file_priv);
static int psb_stolen_memory_ioctl(struct drm_device *dev, void *data, static int psb_stolen_memory_ioctl(struct drm_device *dev, void *data,
struct drm_file *file_priv); 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, static int psb_gamma_ioctl(struct drm_device *dev, void *data,
struct drm_file *file_priv); struct drm_file *file_priv);
static int psb_dpst_bl_ioctl(struct drm_device *dev, void *data, 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, ...@@ -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} [DRM_IOCTL_NR(ioctl) - DRM_COMMAND_BASE] = {ioctl, flags, func}
static struct drm_ioctl_desc psb_ioctls[] = { 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_ADB, psb_adb_ioctl, DRM_AUTH),
PSB_IOCTL_DEF(DRM_IOCTL_PSB_MODE_OPERATION, psb_mode_operation_ioctl, PSB_IOCTL_DEF(DRM_IOCTL_PSB_MODE_OPERATION, psb_mode_operation_ioctl,
DRM_AUTH), DRM_AUTH),
PSB_IOCTL_DEF(DRM_IOCTL_PSB_STOLEN_MEMORY, psb_stolen_memory_ioctl, PSB_IOCTL_DEF(DRM_IOCTL_PSB_STOLEN_MEMORY, psb_stolen_memory_ioctl,
DRM_AUTH), 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_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_DPST_BL, psb_dpst_bl_ioctl, DRM_AUTH),
PSB_IOCTL_DEF(DRM_IOCTL_PSB_GET_PIPE_FROM_CRTC_ID, PSB_IOCTL_DEF(DRM_IOCTL_PSB_GET_PIPE_FROM_CRTC_ID,
...@@ -168,7 +141,6 @@ static void psb_lastclose(struct drm_device *dev) ...@@ -168,7 +141,6 @@ static void psb_lastclose(struct drm_device *dev)
static void psb_do_takedown(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) static int psb_do_init(struct drm_device *dev)
...@@ -214,7 +186,7 @@ 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); 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_BANK0);
PSB_WSGX32(0x00000000, PSB_CR_BIF_BANK1); PSB_WSGX32(0x00000000, PSB_CR_BIF_BANK1);
...@@ -314,6 +286,11 @@ static int psb_driver_load(struct drm_device *dev, unsigned long chipset) ...@@ -314,6 +286,11 @@ static int psb_driver_load(struct drm_device *dev, unsigned long chipset)
dev_priv->dev = dev; dev_priv->dev = dev;
dev->dev_private = (void *) dev_priv; 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; dev_priv->num_pipe = dev_priv->ops->pipes;
resource_start = pci_resource_start(dev->pdev, PSB_MMIO_RESOURCE); 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) ...@@ -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(0x00000000, PSB_INT_ENABLE_R);
PSB_WVDC32(0xFFFFFFFF, PSB_INT_MASK_R); PSB_WVDC32(0xFFFFFFFF, PSB_INT_MASK_R);
spin_unlock_irqrestore(&dev_priv->irqmask_lock, irqflags); 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); drm_irq_install(dev);
dev->vblank_disable_allowed = 1; dev->vblank_disable_allowed = 1;
...@@ -442,75 +419,6 @@ int psb_driver_device_is_agp(struct drm_device *dev) ...@@ -442,75 +419,6 @@ int psb_driver_device_is_agp(struct drm_device *dev)
return 0; 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) static inline void get_brightness(struct backlight_device *bd)
{ {
#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE #ifdef CONFIG_BACKLIGHT_CLASS_DEVICE
...@@ -543,36 +451,6 @@ static int psb_adb_ioctl(struct drm_device *dev, void *data, ...@@ -543,36 +451,6 @@ static int psb_adb_ioctl(struct drm_device *dev, void *data,
return 0; 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, static int psb_gamma_ioctl(struct drm_device *dev, void *data,
struct drm_file *file_priv) struct drm_file *file_priv)
{ {
...@@ -613,37 +491,15 @@ static int psb_mode_operation_ioctl(struct drm_device *dev, void *data, ...@@ -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_psb_mode_operation_arg *arg;
struct drm_mode_object *obj; struct drm_mode_object *obj;
struct drm_connector *connector; struct drm_connector *connector;
struct drm_framebuffer *drm_fb;
struct psb_framebuffer *psb_fb;
struct drm_connector_helper_funcs *connector_funcs; struct drm_connector_helper_funcs *connector_funcs;
int ret = 0; int ret = 0;
int resp = MODE_OK; int resp = MODE_OK;
struct drm_psb_private *dev_priv = psb_priv(dev);
arg = (struct drm_psb_mode_operation_arg *)data; arg = (struct drm_psb_mode_operation_arg *)data;
obj_id = arg->obj_id; obj_id = arg->obj_id;
op = arg->operation; op = arg->operation;
switch (op) { 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: case PSB_MODE_OPERATION_MODE_VALID:
umode = &arg->mode; umode = &arg->mode;
...@@ -689,7 +545,7 @@ static int psb_mode_operation_ioctl(struct drm_device *dev, void *data, ...@@ -689,7 +545,7 @@ static int psb_mode_operation_ioctl(struct drm_device *dev, void *data,
if (connector_funcs->mode_valid) { if (connector_funcs->mode_valid) {
resp = connector_funcs->mode_valid(connector, mode); resp = connector_funcs->mode_valid(connector, mode);
arg->data = (void *)resp; arg->data = resp;
} }
/*do some clean up work*/ /*do some clean up work*/
...@@ -719,363 +575,6 @@ static int psb_stolen_memory_ioctl(struct drm_device *dev, void *data, ...@@ -719,363 +575,6 @@ static int psb_stolen_memory_ioctl(struct drm_device *dev, void *data,
return 0; 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) static int psb_driver_open(struct drm_device *dev, struct drm_file *priv)
{ {
return 0; return 0;
...@@ -1188,9 +687,6 @@ static struct pci_driver psb_pci_driver = { ...@@ -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) 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); return drm_get_pci_dev(pdev, ent, &driver);
} }
......
...@@ -25,7 +25,7 @@ ...@@ -25,7 +25,7 @@
#include <drm/drmP.h> #include <drm/drmP.h>
#include "drm_global.h" #include "drm_global.h"
#include "gem_glue.h" #include "gem_glue.h"
#include "psb_drm.h" #include "gma_drm.h"
#include "psb_reg.h" #include "psb_reg.h"
#include "psb_intel_drv.h" #include "psb_intel_drv.h"
#include "gtt.h" #include "gtt.h"
...@@ -42,6 +42,7 @@ enum { ...@@ -42,6 +42,7 @@ enum {
CHIP_MFLD_0130 = 3, /* Medfield */ 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_MRST(dev) (((dev)->pci_device & 0xfffc) == 0x4100)
#define IS_MFLD(dev) (((dev)->pci_device & 0xfff8) == 0x0130) #define IS_MFLD(dev) (((dev)->pci_device & 0xfff8) == 0x0130)
...@@ -133,6 +134,9 @@ enum { ...@@ -133,6 +134,9 @@ enum {
#define _PSB_IRQ_MSVDX_FLAG (1<<19) #define _PSB_IRQ_MSVDX_FLAG (1<<19)
#define _LNC_IRQ_TOPAZ_FLAG (1<<20) #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. */ /* This flag includes all the display IRQ bits excepts the vblank irqs. */
#define _MDFLD_DISP_ALL_IRQ_FLAG (_MDFLD_PIPEC_EVENT_FLAG | \ #define _MDFLD_DISP_ALL_IRQ_FLAG (_MDFLD_PIPEC_EVENT_FLAG | \
_MDFLD_PIPEB_EVENT_FLAG | \ _MDFLD_PIPEB_EVENT_FLAG | \
...@@ -258,6 +262,8 @@ struct psb_intel_opregion { ...@@ -258,6 +262,8 @@ struct psb_intel_opregion {
struct psb_ops; struct psb_ops;
#define PSB_NUM_PIPE 3
struct drm_psb_private { struct drm_psb_private {
struct drm_device *dev; struct drm_device *dev;
const struct psb_ops *ops; const struct psb_ops *ops;
...@@ -324,8 +330,6 @@ struct drm_psb_private { ...@@ -324,8 +330,6 @@ struct drm_psb_private {
* Sizes info * Sizes info
*/ */
struct drm_psb_sizes_arg sizes;
u32 fuse_reg_value; u32 fuse_reg_value;
u32 video_device_fuse; u32 video_device_fuse;
...@@ -602,7 +606,7 @@ struct drm_psb_private { ...@@ -602,7 +606,7 @@ struct drm_psb_private {
void *fbdev; void *fbdev;
/* 2D acceleration */ /* 2D acceleration */
struct mutex mutex_2d; spinlock_t lock_2d;
}; };
......
...@@ -68,20 +68,23 @@ struct psb_intel_lvds_priv { ...@@ -68,20 +68,23 @@ struct psb_intel_lvds_priv {
static u32 psb_intel_lvds_get_max_backlight(struct drm_device *dev) static u32 psb_intel_lvds_get_max_backlight(struct drm_device *dev)
{ {
struct drm_psb_private *dev_priv = dev->dev_private; struct drm_psb_private *dev_priv = dev->dev_private;
u32 retVal; u32 ret;
if (gma_power_begin(dev, false)) { if (gma_power_begin(dev, false)) {
retVal = ((REG_READ(BLC_PWM_CTL) & ret = REG_READ(BLC_PWM_CTL);
BACKLIGHT_MODULATION_FREQ_MASK) >>
BACKLIGHT_MODULATION_FREQ_SHIFT) * 2;
gma_power_end(dev); gma_power_end(dev);
} else } else /* Powered off, use the saved value */
retVal = ((dev_priv->saveBLC_PWM_CTL & ret = dev_priv->saveBLC_PWM_CTL;
BACKLIGHT_MODULATION_FREQ_MASK) >>
BACKLIGHT_MODULATION_FREQ_SHIFT) * 2; /* Top 15bits hold the frequency mask */
ret = (ret & BACKLIGHT_MODULATION_FREQ_MASK) >>
return retVal; 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) ...@@ -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); max_pwm_blc = psb_intel_lvds_get_max_backlight(dev);
/*BLC_PWM_CTL Should be initiated while backlight device init*/ /*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; 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) ...@@ -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) | (max_pwm_blc << PSB_BACKLIGHT_PWM_CTL_SHIFT) |
(blc_pwm_duty_cycle)); (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; return 0;
} }
...@@ -162,14 +169,12 @@ static int psb_lvds_pwm_set_brightness(struct drm_device *dev, int level) ...@@ -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) void psb_intel_lvds_set_brightness(struct drm_device *dev, int level)
{ {
/*u32 blc_pwm_ctl;*/ struct drm_psb_private *dev_priv = dev->dev_private;
struct drm_psb_private *dev_priv =
(struct drm_psb_private *)dev->dev_private;
dev_dbg(dev->dev, "backlight level is %d\n", level); dev_dbg(dev->dev, "backlight level is %d\n", level);
if (!dev_priv->lvds_bl) { if (!dev_priv->lvds_bl) {
dev_err(dev->dev, "NO LVDS Backlight Info\n"); dev_err(dev->dev, "NO LVDS backlight info\n");
return; return;
} }
...@@ -190,11 +195,13 @@ static void psb_intel_lvds_set_backlight(struct drm_device *dev, int level) ...@@ -190,11 +195,13 @@ static void psb_intel_lvds_set_backlight(struct drm_device *dev, int level)
u32 blc_pwm_ctl; u32 blc_pwm_ctl;
if (gma_power_begin(dev, false)) { if (gma_power_begin(dev, false)) {
blc_pwm_ctl = blc_pwm_ctl = REG_READ(BLC_PWM_CTL);
REG_READ(BLC_PWM_CTL) & ~BACKLIGHT_DUTY_CYCLE_MASK; blc_pwm_ctl &= ~BACKLIGHT_DUTY_CYCLE_MASK;
REG_WRITE(BLC_PWM_CTL, REG_WRITE(BLC_PWM_CTL,
(blc_pwm_ctl | (blc_pwm_ctl |
(level << BACKLIGHT_DUTY_CYCLE_SHIFT))); (level << BACKLIGHT_DUTY_CYCLE_SHIFT)));
dev_priv->saveBLC_PWM_CTL = (blc_pwm_ctl |
(level << BACKLIGHT_DUTY_CYCLE_SHIFT));
gma_power_end(dev); gma_power_end(dev);
} else { } else {
blc_pwm_ctl = dev_priv->saveBLC_PWM_CTL & blc_pwm_ctl = dev_priv->saveBLC_PWM_CTL &
...@@ -212,9 +219,11 @@ static void psb_intel_lvds_set_power(struct drm_device *dev, ...@@ -212,9 +219,11 @@ static void psb_intel_lvds_set_power(struct drm_device *dev,
{ {
u32 pp_status; 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; return;
}
if (on) { if (on) {
REG_WRITE(PP_CONTROL, REG_READ(PP_CONTROL) | REG_WRITE(PP_CONTROL, REG_READ(PP_CONTROL) |
POWER_TARGET_ON); POWER_TARGET_ON);
...@@ -296,9 +305,6 @@ static void psb_intel_lvds_restore(struct drm_connector *connector) ...@@ -296,9 +305,6 @@ static void psb_intel_lvds_restore(struct drm_connector *connector)
{ {
struct drm_device *dev = connector->dev; struct drm_device *dev = connector->dev;
u32 pp_status; u32 pp_status;
/*struct drm_psb_private *dev_priv =
(struct drm_psb_private *)dev->dev_private;*/
struct psb_intel_output *psb_intel_output = struct psb_intel_output *psb_intel_output =
to_psb_intel_output(connector); to_psb_intel_output(connector);
struct psb_intel_lvds_priv *lvds_priv = struct psb_intel_lvds_priv *lvds_priv =
...@@ -382,7 +388,6 @@ bool psb_intel_lvds_mode_fixup(struct drm_encoder *encoder, ...@@ -382,7 +388,6 @@ bool psb_intel_lvds_mode_fixup(struct drm_encoder *encoder,
if (psb_intel_output->type == INTEL_OUTPUT_MIPI2) if (psb_intel_output->type == INTEL_OUTPUT_MIPI2)
panel_fixed_mode = mode_dev->panel_fixed_mode2; 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 */ /* PSB requires the LVDS is on pipe B, MRST has only one pipe anyway */
if (!IS_MRST(dev) && psb_intel_crtc->pipe == 0) { if (!IS_MRST(dev) && psb_intel_crtc->pipe == 0) {
printk(KERN_ERR "Can't support LVDS on pipe A\n"); 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, ...@@ -622,7 +627,8 @@ int psb_intel_lvds_set_property(struct drm_connector *connector,
goto set_prop_error; goto set_prop_error;
else { else {
#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE #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; struct backlight_device *bd = devp->backlight_device;
if (bd) { if (bd) {
bd->props.brightness = value; bd->props.brightness = value;
...@@ -695,8 +701,7 @@ void psb_intel_lvds_init(struct drm_device *dev, ...@@ -695,8 +701,7 @@ void psb_intel_lvds_init(struct drm_device *dev,
struct drm_encoder *encoder; struct drm_encoder *encoder;
struct drm_display_mode *scan; /* *modes, *bios_mode; */ struct drm_display_mode *scan; /* *modes, *bios_mode; */
struct drm_crtc *crtc; struct drm_crtc *crtc;
struct drm_psb_private *dev_priv = struct drm_psb_private *dev_priv = dev->dev_private;
(struct drm_psb_private *)dev->dev_private;
u32 lvds; u32 lvds;
int pipe; int pipe;
...@@ -712,8 +717,8 @@ void psb_intel_lvds_init(struct drm_device *dev, ...@@ -712,8 +717,8 @@ void psb_intel_lvds_init(struct drm_device *dev,
} }
psb_intel_output->dev_priv = lvds_priv; psb_intel_output->dev_priv = lvds_priv;
psb_intel_output->mode_dev = mode_dev; psb_intel_output->mode_dev = mode_dev;
connector = &psb_intel_output->base; connector = &psb_intel_output->base;
encoder = &psb_intel_output->enc; encoder = &psb_intel_output->enc;
drm_connector_init(dev, &psb_intel_output->base, drm_connector_init(dev, &psb_intel_output->base,
......
...@@ -137,22 +137,11 @@ void mid_disable_pipe_event(struct drm_psb_private *dev_priv, int pipe) ...@@ -137,22 +137,11 @@ 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. * Display controller interrupt handler for pipe event.
* *
*/ */
#define WAIT_STATUS_CLEAR_LOOP_COUNT 0xffff static void mid_pipe_event_handler(struct drm_device *dev, int pipe)
static void mid_pipe_event_handler(struct drm_device *dev, uint32_t pipe)
{ {
struct drm_psb_private *dev_priv = struct drm_psb_private *dev_priv =
(struct drm_psb_private *) dev->dev_private; (struct drm_psb_private *) dev->dev_private;
...@@ -161,6 +150,7 @@ static void mid_pipe_event_handler(struct drm_device *dev, uint32_t pipe) ...@@ -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_stat_reg = psb_pipestat(pipe);
uint32_t pipe_enable = dev_priv->pipestat[pipe]; uint32_t pipe_enable = dev_priv->pipestat[pipe];
uint32_t pipe_status = dev_priv->pipestat[pipe] >> 16; uint32_t pipe_status = dev_priv->pipestat[pipe] >> 16;
uint32_t pipe_clear;
uint32_t i = 0; uint32_t i = 0;
spin_lock(&dev_priv->irqmask_lock); spin_lock(&dev_priv->irqmask_lock);
...@@ -171,27 +161,23 @@ static void mid_pipe_event_handler(struct drm_device *dev, uint32_t pipe) ...@@ -171,27 +161,23 @@ static void mid_pipe_event_handler(struct drm_device *dev, uint32_t pipe)
spin_unlock(&dev_priv->irqmask_lock); spin_unlock(&dev_priv->irqmask_lock);
/* clear the 2nd level interrupt status bits */ /* Clear the 2nd level interrupt status bits
/** * Sometimes the bits are very sticky so we repeat until they unstick */
* FIXME: shouldn't use while loop here. However, the interrupt for (i = 0; i < 0xffff; i++) {
* status 'sticky' bits cannot be cleared by setting '1' to that
* bit once...
*/
for (i = 0; i < WAIT_STATUS_CLEAR_LOOP_COUNT; i++) {
PSB_WVDC32(PSB_RVDC32(pipe_stat_reg), pipe_stat_reg); 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; break;
} }
if (i == WAIT_STATUS_CLEAR_LOOP_COUNT) if (pipe_clear)
dev_err(dev->dev, dev_err(dev->dev,
"%s, can't clear the status bits in pipe_stat_reg, its value = 0x%x.\n", "%s, can't clear status bits for pipe %d, its value = 0x%x.\n",
__func__, PSB_RVDC32(pipe_stat_reg)); __func__, pipe, PSB_RVDC32(pipe_stat_reg));
if (pipe_stat_val & PIPE_VBLANK_STATUS) if (pipe_stat_val & PIPE_VBLANK_STATUS)
mid_vblank_handler(dev, pipe); drm_handle_vblank(dev, pipe);
if (pipe_stat_val & PIPE_TE_STATUS) if (pipe_stat_val & PIPE_TE_STATUS)
drm_handle_vblank(dev, pipe); drm_handle_vblank(dev, pipe);
...@@ -202,8 +188,11 @@ static void mid_pipe_event_handler(struct drm_device *dev, uint32_t 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) 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); 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) irqreturn_t psb_irq_handler(DRM_IRQ_ARGS)
...@@ -219,8 +208,13 @@ 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); 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) if (vdc_stat & _MDFLD_DISP_ALL_IRQ_FLAG)
dsp_int = 1; dsp_int = 1;
*/
if (vdc_stat & _PSB_IRQ_SGX_FLAG) if (vdc_stat & _PSB_IRQ_SGX_FLAG)
sgx_int = 1; sgx_int = 1;
...@@ -266,13 +260,18 @@ void psb_irq_preinstall(struct drm_device *dev) ...@@ -266,13 +260,18 @@ void psb_irq_preinstall(struct drm_device *dev)
if (gma_power_is_on(dev)) if (gma_power_is_on(dev))
PSB_WVDC32(0xFFFFFFFF, PSB_HWSTAM); PSB_WVDC32(0xFFFFFFFF, PSB_HWSTAM);
if (dev->vblank_enabled[0]) 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]) if (dev->vblank_enabled[1])
dev_priv->vdc_irq_mask |= _MDFLD_PIPEB_EVENT_FLAG; dev_priv->vdc_irq_mask |= _MDFLD_PIPEB_EVENT_FLAG;
if (dev->vblank_enabled[2]) if (dev->vblank_enabled[2])
dev_priv->vdc_irq_mask |= _MDFLD_PIPEC_EVENT_FLAG; 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); PSB_WVDC32(~dev_priv->vdc_irq_mask, PSB_INT_MASK_R);
spin_unlock_irqrestore(&dev_priv->irqmask_lock, irqflags); spin_unlock_irqrestore(&dev_priv->irqmask_lock, irqflags);
} }
...@@ -464,7 +463,13 @@ int psb_enable_vblank(struct drm_device *dev, int pipe) ...@@ -464,7 +463,13 @@ int psb_enable_vblank(struct drm_device *dev, int pipe)
spin_lock_irqsave(&dev_priv->irqmask_lock, irqflags); 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); psb_enable_pipestat(dev_priv, pipe, PIPE_VBLANK_INTERRUPT_ENABLE);
spin_unlock_irqrestore(&dev_priv->irqmask_lock, irqflags); spin_unlock_irqrestore(&dev_priv->irqmask_lock, irqflags);
...@@ -482,7 +487,13 @@ void psb_disable_vblank(struct drm_device *dev, int pipe) ...@@ -482,7 +487,13 @@ void psb_disable_vblank(struct drm_device *dev, int pipe)
spin_lock_irqsave(&dev_priv->irqmask_lock, irqflags); 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); psb_disable_pipestat(dev_priv, pipe, PIPE_VBLANK_INTERRUPT_ENABLE);
spin_unlock_irqrestore(&dev_priv->irqmask_lock, irqflags); spin_unlock_irqrestore(&dev_priv->irqmask_lock, irqflags);
......
...@@ -52,8 +52,6 @@ static void psb_lid_timer_func(unsigned long data) ...@@ -52,8 +52,6 @@ static void psb_lid_timer_func(unsigned long data)
pp_status = REG_READ(PP_STATUS); pp_status = REG_READ(PP_STATUS);
} while ((pp_status & PP_ON) == 0); } while ((pp_status & PP_ON) == 0);
} }
/* printk(KERN_INFO"%s: lid: closed\n", __FUNCTION__); */
dev_priv->lid_last_state = readl(lid_state); dev_priv->lid_last_state = readl(lid_state);
lid_timer_schedule: lid_timer_schedule:
......
...@@ -22,175 +22,45 @@ ...@@ -22,175 +22,45 @@
#ifndef _PSB_DRM_H_ #ifndef _PSB_DRM_H_
#define _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: * Manage the LUT for an output
*/ */
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 { struct drm_psb_dpst_lut_arg {
uint8_t lut[256]; uint8_t lut[256];
int output_id; int output_id;
}; };
#define PSB_DC_CRTC_SAVE 0x01 /*
#define PSB_DC_CRTC_RESTORE 0x02 * Validate modes
#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 { struct drm_psb_mode_operation_arg {
u32 obj_id; u32 obj_id;
u16 operation; u16 operation;
struct drm_mode_modeinfo mode; struct drm_mode_modeinfo mode;
void *data; u64 data;
}; };
/*
* Query the stolen memory for smarter management of
* memory by the server
*/
struct drm_psb_stolen_memory_arg { struct drm_psb_stolen_memory_arg {
u32 base; u32 base;
u32 size; 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 { struct drm_psb_get_pipe_from_crtc_id_arg {
/** ID of CRTC being requested **/ /** ID of CRTC being requested **/
u32 crtc_id; u32 crtc_id;
/** pipe of requested CRTC **/ /** pipe of requested CRTC **/
u32 pipe; 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 { struct drm_psb_gem_create {
__u64 size; __u64 size;
__u32 handle; __u32 handle;
__u32 flags; __u32 flags;
#define PSB_GEM_CREATE_STOLEN 1 /* Stolen memory can be used */ #define GMA_GEM_CREATE_STOLEN 1 /* Stolen memory can be used */
}; };
struct drm_psb_gem_mmap { struct drm_psb_gem_mmap {
...@@ -204,4 +74,18 @@ struct drm_psb_gem_mmap { ...@@ -204,4 +74,18 @@ struct drm_psb_gem_mmap {
__u64 offset; __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 #endif
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment