mirror of https://gitee.com/openkylin/linux.git
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
This commit is contained in:
commit
cee5ec4346
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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));
|
||||
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 @@ static int psb_gtt_attach_pages(struct gtt_range *gt)
|
|||
*
|
||||
* 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, >->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";
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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]);
|
||||
mode_dev->panel_fixed_mode = mode;
|
||||
}
|
||||
|
||||
drm_mode_set_name(mode);
|
||||
drm_mode_set_crtcinfo(mode, 0);
|
||||
/* 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);
|
||||
|
||||
return 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;
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -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;
|
||||
} else /* Powered off, use the saved value */
|
||||
ret = dev_priv->saveBLC_PWM_CTL;
|
||||
|
||||
return retVal;
|
||||
/* 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,
|
||||
|
|
|
@ -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.
|
||||
*
|
||||
*/
|
||||
#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);
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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
|
Loading…
Reference in New Issue