[PATCH 01/15] gma500: fix warnings

14 views
Skip to first unread message

Alan Cox

unread,
Jun 8, 2011, 6:11:10 AM6/8/11
to gr...@kroah.com, linux-...@vger.kernel.org, dri-...@lists.freedesktop.org
From: Alan Cox <al...@linux.intel.com>

Signed-off-by: Alan Cox <al...@linux.intel.com>
---

drivers/staging/gma500/psb_gtt.c | 3 +--
1 files changed, 1 insertions(+), 2 deletions(-)

diff --git a/drivers/staging/gma500/psb_gtt.c b/drivers/staging/gma500/psb_gtt.c
index 74c5a65..1d0e242 100644
--- a/drivers/staging/gma500/psb_gtt.c
+++ b/drivers/staging/gma500/psb_gtt.c
@@ -78,7 +78,6 @@ u32 *psb_gtt_entry(struct drm_device *dev, struct gtt_range *r)
*/
static int psb_gtt_insert(struct drm_device *dev, struct gtt_range *r)
{
- struct drm_psb_private *dev_priv = dev->dev_private;
u32 *gtt_slot, pte;
int numpages = (r->resource.end + 1 - r->resource.start) >> PAGE_SHIFT;
struct page **pages;
@@ -490,7 +489,7 @@ int psb_gtt_init(struct drm_device *dev, int resume)
goto out_err;
}

- DRM_DEBUG("%s: vram kernel virtual address %p\n", dev_priv->vram_addr);
+ DRM_DEBUG("gma500: vram kernel virtual address %p\n", dev_priv->vram_addr);

tt_pages = (pg->gatt_pages < PSB_TT_PRIV0_PLIMIT) ?
(pg->gatt_pages) : PSB_TT_PRIV0_PLIMIT;

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majo...@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/

Alan Cox

unread,
Jun 8, 2011, 6:10:54 AM6/8/11
to gr...@kroah.com, linux-...@vger.kernel.org, dri-...@lists.freedesktop.org
This patch series versus linux-next 2011/06/08 fixes various bugs including a
nasty pinning bug found by Andre Bartke.

With these patches applied the driver passes the various GEM tests and you can
use the KMS tools and test sets to set modes and display stuff from GEM
buffers including those mapped from main memory via the GTT.

You can't yet take a GEM handle of the system frame buffer. That requires
a trivial patch to drm_gem and a similar trivial patch to this driver.

The two main remaining tasks now are to provide a 2D command interface for the
X server including support for blitting between GEM objects (so we need relocs)
and to clean the code up.

Vblank support is also possible but doesn't seem terribly useful.
---

Alan Cox (12):
gma500: Kill spare kref
gma500: nuke the PSB debug stuff
gma500: nuke the last bits of TTM code
gma500: 2D acceleration tidying
gma500: polish for completion of this phase
gma500: trim some of the debug
gma500: Do sane FB cleanup
gma500: revamp frame buffer creation and handling
gma500: Set the correct bits according to the pipe
gma500: Ensure the frame buffer has a linear virtual mapping
gma500: Make GTT pages uncached
gma500: fix warnings

Andre Bartke (1):
gma500: Fix uninitialized variable and style issues

Michael Chang (1):
staging/gma500: get control from firmware framebuffer if conflicts

Patrik Jakobsson (1):
gma500: Skip bogus LVDS VBT mode and check for LVDS before adding backlight


drivers/staging/gma500/mrst_crtc.c | 27 +-
drivers/staging/gma500/mrst_lvds.c | 14 -
drivers/staging/gma500/psb_2d.c | 39 +--
drivers/staging/gma500/psb_bl.c | 12 -
drivers/staging/gma500/psb_drm.h | 90 --------
drivers/staging/gma500/psb_drv.c | 58 ++---
drivers/staging/gma500/psb_drv.h | 181 ++++------------
drivers/staging/gma500/psb_fb.c | 309 +++++++++++++++------------
drivers/staging/gma500/psb_fb.h | 6 -
drivers/staging/gma500/psb_gem.c | 39 +--
drivers/staging/gma500/psb_gtt.c | 187 ++++++----------
drivers/staging/gma500/psb_gtt.h | 11 +
drivers/staging/gma500/psb_intel_bios.c | 26 +-
drivers/staging/gma500/psb_intel_display.c | 130 +++--------
drivers/staging/gma500/psb_intel_drv.h | 19 --
drivers/staging/gma500/psb_intel_lvds.c | 53 +----
drivers/staging/gma500/psb_intel_opregion.c | 7 -
drivers/staging/gma500/psb_intel_sdvo.c | 34 +--
drivers/staging/gma500/psb_irq.c | 33 +--
drivers/staging/gma500/psb_irq.h | 8 -
drivers/staging/gma500/psb_powermgmt.c | 4
drivers/staging/gma500/psb_powermgmt.h | 2
drivers/staging/gma500/psb_reg.h | 2
23 files changed, 461 insertions(+), 830 deletions(-)

--
Signature

Alan Cox

unread,
Jun 8, 2011, 6:11:28 AM6/8/11
to gr...@kroah.com, linux-...@vger.kernel.org, dri-...@lists.freedesktop.org
From: Patrik Jakobsson <patrik.r....@gmail.com>

On the Fit-PC2 the VBT reports an invalid fixed panel mode for LVDS, this gets
in the way for SDVO. This patch makes VBT parsing skip the invalid mode. When
there is no LVDS output the backlight support crashes so the patch also checks
for this before enabling it.

Signed-off-by: Patrik Jakobsson <patrik.r....@gmail.com>


Signed-off-by: Alan Cox <al...@linux.intel.com>
---

drivers/staging/gma500/psb_drv.c | 15 ++++++++++++++-
drivers/staging/gma500/psb_intel_bios.c | 13 +++++++++----
2 files changed, 23 insertions(+), 5 deletions(-)

diff --git a/drivers/staging/gma500/psb_drv.c b/drivers/staging/gma500/psb_drv.c
index 1c45c11..aa87b1b 100644
--- a/drivers/staging/gma500/psb_drv.c
+++ b/drivers/staging/gma500/psb_drv.c
@@ -542,6 +542,8 @@ static int psb_driver_load(struct drm_device *dev, unsigned long chipset)
unsigned long irqflags;
int ret = -ENOMEM;
uint32_t tt_pages;
+ struct drm_connector *connector;
+ struct psb_intel_output *psb_intel_output;

dev_priv = kzalloc(sizeof(*dev_priv), GFP_KERNEL);
if (dev_priv == NULL)
@@ -663,7 +665,18 @@ static int psb_driver_load(struct drm_device *dev, unsigned long chipset)
drm_kms_helper_poll_init(dev);
}

- ret = psb_backlight_init(dev);
+ /* Only add backlight support if we have LVDS output */
+ list_for_each_entry(connector, &dev->mode_config.connector_list,
+ head) {
+ psb_intel_output = to_psb_intel_output(connector);
+
+ switch (psb_intel_output->type) {
+ case INTEL_OUTPUT_LVDS:
+ ret = psb_backlight_init(dev);
+ break;
+ }
+ }
+
if (ret)
return ret;
#if 0
diff --git a/drivers/staging/gma500/psb_intel_bios.c b/drivers/staging/gma500/psb_intel_bios.c
index 48ac8ba..417965d 100644
--- a/drivers/staging/gma500/psb_intel_bios.c
+++ b/drivers/staging/gma500/psb_intel_bios.c
@@ -154,10 +154,15 @@ static void parse_lfp_panel_data(struct drm_psb_private *dev_priv,

fill_detail_timing_data(panel_fixed_mode, dvo_timing);

- dev_priv->lfp_lvds_vbt_mode = panel_fixed_mode;
-
- DRM_DEBUG("Found panel mode in BIOS VBT tables:\n");
- drm_mode_debug_printmodeline(panel_fixed_mode);
+ if (panel_fixed_mode->htotal > 0 && panel_fixed_mode->vtotal > 0) {
+ dev_priv->lfp_lvds_vbt_mode = panel_fixed_mode;
+ DRM_DEBUG("Found panel mode in BIOS VBT tables:\n");
+ drm_mode_debug_printmodeline(panel_fixed_mode);
+ } else {
+ DRM_DEBUG("Ignoring bogus LVDS VBT mode.\n");
+ dev_priv->lvds_vbt = 0;
+ kfree(panel_fixed_mode);
+ }

return;

Alan Cox

unread,
Jun 8, 2011, 6:11:51 AM6/8/11
to gr...@kroah.com, linux-...@vger.kernel.org, dri-...@lists.freedesktop.org
From: Alan Cox <al...@linux.intel.com>

Clean up the GTT code a bit, make the pages uncached and go via the proper
interfaces. This avoids any aliasing problems.

On the CPU side we need to access the pages via their true addresses not via
the GTT. This is fine for GEM created fb objects for X. For the kernel fb
when not in stolen RAM we are going to need to use vm_map_ram() and hope we
have enough virtual address space to steal.

Signed-off-by: Alan Cox <al...@linux.intel.com>
---

drivers/staging/gma500/psb_fb.c | 9 ++++++++-
drivers/staging/gma500/psb_gem.c | 26 +++++++-------------------
drivers/staging/gma500/psb_gtt.c | 27 ++++++++++++++-------------
3 files changed, 29 insertions(+), 33 deletions(-)

diff --git a/drivers/staging/gma500/psb_fb.c b/drivers/staging/gma500/psb_fb.c
index 99c03a2..f578ca8 100644
--- a/drivers/staging/gma500/psb_fb.c
+++ b/drivers/staging/gma500/psb_fb.c
@@ -346,6 +346,11 @@ err:
* and back it with a GEM object.
*
* 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.
+ * FIXME: we need to vm_map_ram a linear mapping if the object has to
+ * be GEM host mapped, otherwise the cfb layer's brain will fall out.
*/
static struct gtt_range *psbfb_alloc(struct drm_device *dev, int aligned_size)
{
@@ -436,7 +441,7 @@ static int psbfb_create(struct psb_fbdev *fbdev,

/* Accessed via stolen memory directly, This only works for stolem
memory however. Need to address this once we start using gtt
- pages we allocate */
+ pages we allocate. FIXME: vm_map_ram for that case */
info->screen_base = (char *)dev_priv->vram_addr + backing->offset;
info->screen_size = size;
memset(info->screen_base, 0, size);
@@ -666,6 +671,8 @@ static void psb_user_framebuffer_destroy(struct drm_framebuffer *fb)
struct psb_framebuffer *psbfb = to_psb_fb(fb);
struct gtt_range *r = psbfb->gtt;

+ pr_err("user framebuffer destroy %p, fbdev %p\n",
+ psbfb, psbfb->fbdev);
if (psbfb->fbdev)
psbfb_remove(dev, fb);

diff --git a/drivers/staging/gma500/psb_gem.c b/drivers/staging/gma500/psb_gem.c
index 76ff7ba..98d8ab3 100644
--- a/drivers/staging/gma500/psb_gem.c
+++ b/drivers/staging/gma500/psb_gem.c
@@ -40,7 +40,6 @@ int psb_gem_init_object(struct drm_gem_object *obj)
void psb_gem_free_object(struct drm_gem_object *obj)
{
struct gtt_range *gtt = container_of(obj, struct gtt_range, gem);
- psb_gtt_free_range(obj->dev, gtt);
if (obj->map_list.map) {
/* Do things GEM should do for us */
struct drm_gem_mm *mm = obj->dev->mm_private;
@@ -51,6 +50,8 @@ void psb_gem_free_object(struct drm_gem_object *obj)
list->map = NULL;
}
drm_gem_object_release(obj);
+ /* This must occur last as it frees up the memory of the GEM object */
+ psb_gtt_free_range(obj->dev, gtt);
}

int psb_gem_get_aperture(struct drm_device *dev, void *data,
@@ -245,19 +246,13 @@ int psb_gem_dumb_destroy(struct drm_file *file, struct drm_device *dev,
* but we need to do the actual page work.
*
* This code eventually needs to handle faulting objects in and out
- * of the GART and repacking it when we run out of space. We can put
+ * of the GTT and repacking it when we run out of space. We can put
* that off for now and for our simple uses
*
* 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.
*
- * To avoid aliasing and cache funnies we want to map the object
- * through the GART. For the moment this is slightly hackish. It would
- * be nicer if GEM provided mmap opened/closed hooks for us giving
- * the object so that we could track things nicely. That needs changes
- * to the core GEM code so must be tackled post staging
- *
* FIXME
*/
int psb_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
@@ -289,20 +284,13 @@ int psb_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
r->mmapping = 1;
}

- /* FIXME: Locking. We may also need to repack the GART sometimes */
-
- /* Page relative to the VMA start */
+ /* Page relative to the VMA start - we must calculate this ourselves
+ because vmf->pgoff is the fake GEM offset */
page_offset = ((unsigned long) vmf->virtual_address - vma->vm_start)
>> PAGE_SHIFT;

- /* Bus address of the page is gart + object offset + page offset */
- /* Assumes gtt allocations are page aligned */
- pfn = (r->resource.start >> PAGE_SHIFT) + page_offset;
-
- pr_debug("Object GTT base at %p\n", (void *)(r->resource.start));
- pr_debug("Inserting %p pfn %lx, pa %lx\n", vmf->virtual_address,
- pfn, pfn << PAGE_SHIFT);
-
+ /* CPU view of the page, don't go via the GART for CPU writes */
+ pfn = page_to_phys(r->pages[page_offset]) >> PAGE_SHIFT;
ret = vm_insert_pfn(vma, (unsigned long)vmf->virtual_address, pfn);

fail:
diff --git a/drivers/staging/gma500/psb_gtt.c b/drivers/staging/gma500/psb_gtt.c
index 1d0e242..d76037f 100644
--- a/drivers/staging/gma500/psb_gtt.c
+++ b/drivers/staging/gma500/psb_gtt.c
@@ -28,11 +28,11 @@
*/

/**
- * psb_gtt_mask_pte - generate GART pte entry
+ * psb_gtt_mask_pte - generate GTT pte entry
* @pfn: page number to encode
- * @type: type of memory in the GART
+ * @type: type of memory in the GTT
*
- * Set the GART entry for the appropriate memory type.
+ * Set the GTT entry for the appropriate memory type.
*/
static inline uint32_t psb_gtt_mask_pte(uint32_t pfn, int type)
{
@@ -49,11 +49,11 @@ static inline uint32_t psb_gtt_mask_pte(uint32_t pfn, int type)
}

/**
- * psb_gtt_entry - find the GART entries for a gtt_range
+ * psb_gtt_entry - find the GTT entries for a gtt_range
* @dev: our DRM device
* @r: our GTT range
*
- * Given a gtt_range object return the GART offset of the page table
+ * Given a gtt_range object return the GTT offset of the page table
* entries for this gtt_range
*/


u32 *psb_gtt_entry(struct drm_device *dev, struct gtt_range *r)

@@ -67,12 +67,12 @@ u32 *psb_gtt_entry(struct drm_device *dev, struct gtt_range *r)
}

/**
- * psb_gtt_insert - put an object into the GART
+ * psb_gtt_insert - put an object into the GTT
* @dev: our DRM device
* @r: our GTT range
*
* Take our preallocated GTT range and insert the GEM object into
- * the GART.
+ * the GTT.
*
* FIXME: gtt lock ?
*/
@@ -93,10 +93,10 @@ static int psb_gtt_insert(struct drm_device *dev, struct gtt_range *r)
gtt_slot = psb_gtt_entry(dev, r);
pages = r->pages;

- /* Make sure we have no alias present */
- wbinvd();
+ /* Make sure changes are visible to the GPU */
+ set_pages_array_uc(pages, numpages);

- /* Write our page entries into the GART itself */
+ /* Write our page entries into the GTT itself */
for (i = 0; i < numpages; i++) {
pte = psb_gtt_mask_pte(page_to_pfn(*pages++), 0/*type*/);
iowrite32(pte, gtt_slot++);
@@ -108,11 +108,11 @@ static int psb_gtt_insert(struct drm_device *dev, struct gtt_range *r)
}

/**
- * psb_gtt_remove - remove an object from the GART
+ * psb_gtt_remove - remove an object from the GTT
* @dev: our DRM device
* @r: our GTT range
*
- * Remove a preallocated GTT range from the GART. Overwrite all the
+ * Remove a preallocated GTT range from the GTT. Overwrite all the
* page table entries with the dummy page
*/

@@ -131,6 +131,7 @@ static void psb_gtt_remove(struct drm_device *dev, struct gtt_range *r)
for (i = 0; i < numpages; i++)
iowrite32(pte, gtt_slot++);
ioread32(gtt_slot - 1);
+ set_pages_array_wb(r->pages, numpages);
}

/**
@@ -182,7 +183,7 @@ err:
* @gt: the gtt range
*
* Undo the effect of psb_gtt_attach_pages. At this point the pages
- * must have been removed from the GART 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.
*
* FIXME: Do we need to cache flush when we update the GTT

Alan Cox

unread,
Jun 8, 2011, 6:12:11 AM6/8/11
to gr...@kroah.com, linux-...@vger.kernel.org, dri-...@lists.freedesktop.org
From: Alan Cox <al...@linux.intel.com>

We need this for the framebuffer in order to ensure that the kernel
framebuffer layer can handle it when using KMS. Except for the base
framebuffer this isn't a concern.

Add an npage field to the gtt as too many copies of the page calculation
are getting spread around the code.

Signed-off-by: Alan Cox <al...@linux.intel.com>
---

drivers/staging/gma500/psb_fb.c | 47 ++++++++++++++++++++++++--------------
drivers/staging/gma500/psb_fb.h | 1 +
drivers/staging/gma500/psb_gtt.c | 18 ++++++---------
drivers/staging/gma500/psb_gtt.h | 5 ++--
4 files changed, 42 insertions(+), 29 deletions(-)

diff --git a/drivers/staging/gma500/psb_fb.c b/drivers/staging/gma500/psb_fb.c
index f578ca8..4e6294c 100644
--- a/drivers/staging/gma500/psb_fb.c
+++ b/drivers/staging/gma500/psb_fb.c
@@ -254,17 +254,13 @@ static int psbfb_mmap(struct fb_info *info, struct vm_area_struct *vma)
vma->vm_pgoff, fb_screen_base,
dev_priv->vram_addr);

- /* FIXME: ultimately this needs to become 'if entirely stolen memory' */
- if (1 || fb_screen_base == dev_priv->vram_addr) {
- vma->vm_ops = &psbfb_vm_ops;
- vma->vm_private_data = (void *)psbfb;
- vma->vm_flags |= VM_RESERVED | VM_IO |
- VM_MIXEDMAP | VM_DONTEXPAND;
- } else {
- /* GTT memory backed by kernel/user pages, needs a different
- approach ? - GEM ? */
- }
-
+ /* If this is a GEM object then info->screen_base is the virtual
+ kernel remapping of the object. FIXME: Review if this is
+ suitable for our mmap work */
+ vma->vm_ops = &psbfb_vm_ops;
+ vma->vm_private_data = (void *)psbfb;
+ vma->vm_flags |= VM_RESERVED | VM_IO |
+ VM_MIXEDMAP | VM_DONTEXPAND;
return 0;
}

@@ -349,8 +345,6 @@ err:
*


* FIXME: console speed up - allocate twice the space if room and use

* hardware scrolling for acceleration.

- * FIXME: we need to vm_map_ram a linear mapping if the object has to
- * be GEM host mapped, otherwise the cfb layer's brain will fall out.


*/
static struct gtt_range *psbfb_alloc(struct drm_device *dev, int aligned_size)
{

@@ -439,10 +433,22 @@ static int psbfb_create(struct psb_fbdev *fbdev,
info->fix.smem_start = dev->mode_config.fb_base;
info->fix.smem_len = size;

- /* Accessed via stolen memory directly, This only works for stolem
- memory however. Need to address this once we start using gtt
- pages we allocate. FIXME: vm_map_ram for that case */
- info->screen_base = (char *)dev_priv->vram_addr + backing->offset;
+ if (backing->stolen) {
+ /* 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_err0;
+ }
+ psbfb->vm_map = 1;
+ }


info->screen_size = size;
memset(info->screen_base, 0, size);

@@ -560,6 +566,13 @@ 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);
+ }
/* FIXME: this is a bit more inside knowledge than I'd like
but I don't see how to make a fake GEM object of the
stolen space nicely */
diff --git a/drivers/staging/gma500/psb_fb.h b/drivers/staging/gma500/psb_fb.h
index c8ec0d6..2153c74 100644
--- a/drivers/staging/gma500/psb_fb.h
+++ b/drivers/staging/gma500/psb_fb.h
@@ -33,6 +33,7 @@ struct psb_framebuffer {
struct address_space *addr_space;
struct fb_info *fbdev;
struct gtt_range *gtt;
+ bool vm_map; /* True if we must undo a vm_map_ram */
};

struct psb_fbdev {
diff --git a/drivers/staging/gma500/psb_gtt.c b/drivers/staging/gma500/psb_gtt.c
index d76037f..6a24246 100644
--- a/drivers/staging/gma500/psb_gtt.c
+++ b/drivers/staging/gma500/psb_gtt.c
@@ -79,7 +79,6 @@ u32 *psb_gtt_entry(struct drm_device *dev, struct gtt_range *r)


static int psb_gtt_insert(struct drm_device *dev, struct gtt_range *r)

{
u32 *gtt_slot, pte;
- int numpages = (r->resource.end + 1 - r->resource.start) >> PAGE_SHIFT;
struct page **pages;
int i;

@@ -94,10 +93,10 @@ static int psb_gtt_insert(struct drm_device *dev, struct gtt_range *r)
pages = r->pages;



/* Make sure changes are visible to the GPU */

- set_pages_array_uc(pages, numpages);
+ set_pages_array_uc(pages, r->npage);



/* Write our page entries into the GTT itself */

- for (i = 0; i < numpages; i++) {
+ for (i = 0; i < r->npage; i++) {


pte = psb_gtt_mask_pte(page_to_pfn(*pages++), 0/*type*/);
iowrite32(pte, gtt_slot++);
}

@@ -120,7 +119,6 @@ static void psb_gtt_remove(struct drm_device *dev, struct gtt_range *r)
{


struct drm_psb_private *dev_priv = dev->dev_private;
u32 *gtt_slot, pte;

- int numpages = (r->resource.end + 1 - r->resource.start) >> PAGE_SHIFT;
int i;

WARN_ON(r->stolen);
@@ -128,10 +126,10 @@ static void psb_gtt_remove(struct drm_device *dev, struct gtt_range *r)
gtt_slot = psb_gtt_entry(dev, r);
pte = psb_gtt_mask_pte(page_to_pfn(dev_priv->scratch_page), 0);;

- for (i = 0; i < numpages; i++)
+ for (i = 0; i < r->npage; i++)


iowrite32(pte, gtt_slot++);
ioread32(gtt_slot - 1);

- set_pages_array_wb(r->pages, numpages);
+ set_pages_array_wb(r->pages, r->npage);
}

/**
@@ -149,7 +147,7 @@ static int psb_gtt_attach_pages(struct gtt_range *gt)
struct address_space *mapping;
int i;
struct page *p;
- int pages = (gt->resource.end + 1 - gt->resource.start) >> PAGE_SHIFT;
+ int pages = gt->gem.size / PAGE_SIZE;

WARN_ON(gt->pages);

@@ -160,6 +158,8 @@ static int psb_gtt_attach_pages(struct gtt_range *gt)
gt->pages = kmalloc(pages * sizeof(struct page *), GFP_KERNEL);
if (gt->pages == NULL)
return -ENOMEM;
+ gt->npage = pages;
+
for (i = 0; i < pages; i++) {
/* FIXME: review flags later */
p = read_cache_page_gfp(mapping, i,
@@ -191,9 +191,7 @@ err:
static void psb_gtt_detach_pages(struct gtt_range *gt)
{
int i;
- int pages = (gt->resource.end + 1 - gt->resource.start) >> PAGE_SHIFT;
-
- for (i = 0; i < pages; i++) {
+ for (i = 0; i < gt->npage; i++) {
/* FIXME: do we need to force dirty */
set_page_dirty(gt->pages[i]);
/* Undo the reference we took when populating the table */
diff --git a/drivers/staging/gma500/psb_gtt.h b/drivers/staging/gma500/psb_gtt.h
index 535ae00..37287eb 100644
--- a/drivers/staging/gma500/psb_gtt.h
+++ b/drivers/staging/gma500/psb_gtt.h
@@ -46,9 +46,10 @@ struct gtt_range {
struct kref kref;
struct drm_gem_object gem; /* GEM high level stuff */
int in_gart; /* Currently in the GART (ref ct) */
- bool stolen; /* Backed from stolen RAM */
- bool mmapping; /* Is mmappable */
+ bool stolen; /* Backed from stolen RAM */
+ bool mmapping; /* Is mmappable */
struct page **pages; /* Backing pages if present */
+ int npage; /* Number of backing pages */
};

extern struct gtt_range *psb_gtt_alloc_range(struct drm_device *dev, int len,

Alan Cox

unread,
Jun 8, 2011, 6:12:29 AM6/8/11
to gr...@kroah.com, linux-...@vger.kernel.org, dri-...@lists.freedesktop.org
From: Alan Cox <al...@linux.intel.com>

Squash a hardcoded assumption we shouldn't really make

Signed-off-by: Alan Cox <al...@linux.intel.com>
---

drivers/staging/gma500/psb_intel_display.c | 11 ++++++-----
1 files changed, 6 insertions(+), 5 deletions(-)

diff --git a/drivers/staging/gma500/psb_intel_display.c b/drivers/staging/gma500/psb_intel_display.c
index 4f47d09..a99271d 100644
--- a/drivers/staging/gma500/psb_intel_display.c
+++ b/drivers/staging/gma500/psb_intel_display.c
@@ -723,17 +723,18 @@ static int psb_intel_crtc_mode_set(struct drm_crtc *crtc,
if (is_lvds) {
u32 lvds = REG_READ(LVDS);

- lvds |=
- LVDS_PORT_EN | LVDS_A0A2_CLKA_POWER_UP |
- LVDS_PIPEB_SELECT;
+ lvds &= ~LVDS_PIPEB_SELECT;
+ if (pipe == 1)
+ lvds |= LVDS_PIPEB_SELECT;
+
+ lvds |= LVDS_PORT_EN | LVDS_A0A2_CLKA_POWER_UP;
/* Set the B0-B3 data pairs corresponding to
* whether we're going to
* set the DPLLs for dual-channel mode or not.
*/
+ lvds &= ~(LVDS_B0B3_POWER_UP | LVDS_CLKB_POWER_UP);
if (clock.p2 == 7)
lvds |= LVDS_B0B3_POWER_UP | LVDS_CLKB_POWER_UP;
- else
- lvds &= ~(LVDS_B0B3_POWER_UP | LVDS_CLKB_POWER_UP);

/* It would be nice to set 24 vs 18-bit mode (LVDS_A3_POWER_UP)
* appropriately here, but we need to look more

Alan Cox

unread,
Jun 8, 2011, 6:12:51 AM6/8/11
to gr...@kroah.com, linux-...@vger.kernel.org, dri-...@lists.freedesktop.org
From: Michael Chang <mch...@novell.com>

Many Linux distributions would enable vesafb in order to display
early stage boot splash. In this case, we will get garbled X
Window screen if running X fbdev on psbfb.

This is because fb0 is occupied by vesafb while psbfb is on fb1.
They tried to drive the same pieces of hardware at the same
time. With unmodified X start-up, it would try to use default
fb0 framebuffer device and unfortunately it is now broken
becaues fb1 supersedes it.

We should let psbfb takeover framebuffer control from vesafb
to get around this problem.

See also commit : 4410f3910947dcea8672280b3adecd53cec4e85e

Signed-off-by: Michael Chang <mch...@novell.com>


Signed-off-by: Alan Cox <al...@linux.intel.com>
---

drivers/staging/gma500/psb_fb.c | 10 ++++++++++
1 files changed, 10 insertions(+), 0 deletions(-)

diff --git a/drivers/staging/gma500/psb_fb.c b/drivers/staging/gma500/psb_fb.c
index 4e6294c..4b05cdc 100644
--- a/drivers/staging/gma500/psb_fb.c
+++ b/drivers/staging/gma500/psb_fb.c
@@ -452,6 +452,16 @@ static int psbfb_create(struct psb_fbdev *fbdev,


info->screen_size = size;
memset(info->screen_base, 0, size);

+ if (dev_priv->pg->stolen_size) {
+ info->apertures = alloc_apertures(1);
+ if (!info->apertures) {


+ ret = -ENOMEM;
+ goto out_err0;
+ }

+ info->apertures->ranges[0].base = dev->mode_config.fb_base;
+ info->apertures->ranges[0].size = dev_priv->pg->stolen_size;
+ }
+
drm_fb_helper_fill_fix(info, fb->pitch, fb->depth);
drm_fb_helper_fill_var(info, &fbdev->psb_fb_helper,
sizes->fb_width, sizes->fb_height);

Alan Cox

unread,
Jun 8, 2011, 6:13:05 AM6/8/11
to gr...@kroah.com, linux-...@vger.kernel.org, dri-...@lists.freedesktop.org
From: Andre Bartke <andre....@googlemail.com>

The return variable of psb_gtt_pin() may be used
uninitialized. Also fixed some coding style issues.

Signed-off-by: Andre Bartke <andre....@gmail.com>
[Reapplied by hand due to other changes]


Signed-off-by: Alan Cox <al...@linux.intel.com>
---

drivers/staging/gma500/psb_gtt.c | 36 ++++++++++++++++++------------------
1 files changed, 18 insertions(+), 18 deletions(-)

diff --git a/drivers/staging/gma500/psb_gtt.c b/drivers/staging/gma500/psb_gtt.c
index 6a24246..5a296e1 100644
--- a/drivers/staging/gma500/psb_gtt.c
+++ b/drivers/staging/gma500/psb_gtt.c
@@ -58,7 +58,7 @@ static inline uint32_t psb_gtt_mask_pte(uint32_t pfn, int type)
*/


u32 *psb_gtt_entry(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;
unsigned long offset;

offset = r->resource.start - dev_priv->gtt_mem->start;
@@ -124,7 +124,7 @@ static void psb_gtt_remove(struct drm_device *dev, struct gtt_range *r)
WARN_ON(r->stolen);

gtt_slot = psb_gtt_entry(dev, r);
- pte = psb_gtt_mask_pte(page_to_pfn(dev_priv->scratch_page), 0);;
+ pte = psb_gtt_mask_pte(page_to_pfn(dev_priv->scratch_page), 0);



for (i = 0; i < r->npage; i++)
iowrite32(pte, gtt_slot++);

@@ -213,7 +213,7 @@ static void psb_gtt_detach_pages(struct gtt_range *gt)
*/
int psb_gtt_pin(struct gtt_range *gt)
{
- int ret;
+ int ret = 0;
struct drm_device *dev = gt->gem.dev;


struct drm_psb_private *dev_priv = dev->dev_private;

@@ -289,33 +289,33 @@ struct gtt_range *psb_gtt_alloc_range(struct drm_device *dev, int len,
struct resource *r = dev_priv->gtt_mem;
int ret;
unsigned long start, end;
-
+
if (backed) {
- /* The start of the GTT is the stolen pages */
- start = r->start;
- end = r->start + dev_priv->pg->stolen_size - 1;
+ /* The start of the GTT is the stolen pages */
+ start = r->start;
+ end = r->start + dev_priv->pg->stolen_size - 1;
} else {
- /* The rest we will use for GEM backed objects */
- start = r->start + dev_priv->pg->stolen_size;
- end = r->end;
+ /* The rest we will use for GEM backed objects */
+ start = r->start + dev_priv->pg->stolen_size;
+ end = r->end;
}

gt = kzalloc(sizeof(struct gtt_range), GFP_KERNEL);
if (gt == NULL)
return NULL;
- gt->resource.name = name;
- gt->stolen = backed;
- gt->in_gart = backed;
- /* Ensure this is set for non GEM objects */
- gt->gem.dev = dev;
+ gt->resource.name = name;
+ gt->stolen = backed;
+ gt->in_gart = backed;
+ /* Ensure this is set for non GEM objects */
+ gt->gem.dev = dev;
kref_init(&gt->kref);

ret = allocate_resource(dev_priv->gtt_mem, &gt->resource,
len, start, end, PAGE_SIZE, NULL, NULL);
if (ret == 0) {
- gt->offset = gt->resource.start - r->start;
+ gt->offset = gt->resource.start - r->start;
return gt;
- }
+ }
kfree(gt);
return NULL;
}
@@ -419,7 +419,7 @@ int psb_gtt_init(struct drm_device *dev, int resume)

dev_priv->pg = pg = psb_gtt_alloc(dev);
if (pg == NULL)
- return -ENOMEM;
+ return -ENOMEM;

pci_read_config_word(dev->pdev, PSB_GMCH_CTRL, &dev_priv->gmch_ctrl);
pci_write_config_word(dev->pdev, PSB_GMCH_CTRL,

Alan Cox

unread,
Jun 8, 2011, 6:13:23 AM6/8/11
to gr...@kroah.com, linux-...@vger.kernel.org, dri-...@lists.freedesktop.org
From: Alan Cox <al...@linux.intel.com>

Restructure this to work the same way as the i915 frame buffer does. That
cleans up various chunks of code.

We can now set a mode in modetest but mode restore is a bit iffy

Signed-off-by: Alan Cox <al...@linux.intel.com>
---

drivers/staging/gma500/psb_2d.c | 13 +--
drivers/staging/gma500/psb_fb.c | 195 +++++++++++++++++++++-----------------
drivers/staging/gma500/psb_fb.h | 2
drivers/staging/gma500/psb_gem.c | 18 +++-
drivers/staging/gma500/psb_gtt.c | 2
5 files changed, 133 insertions(+), 97 deletions(-)

diff --git a/drivers/staging/gma500/psb_2d.c b/drivers/staging/gma500/psb_2d.c
index 0bd834c..060eeaf 100644
--- a/drivers/staging/gma500/psb_2d.c
+++ b/drivers/staging/gma500/psb_2d.c
@@ -148,7 +148,7 @@ static void psbfb_fillrect_accel(struct fb_info *info,
const struct fb_fillrect *r)
{
struct psb_fbdev *fbdev = info->par;
- struct psb_framebuffer *psbfb = fbdev->pfb;
+ struct psb_framebuffer *psbfb = &fbdev->pfb;
struct drm_device *dev = psbfb->base.dev;
struct drm_framebuffer *fb = fbdev->psb_fb_helper.fb;


struct drm_psb_private *dev_priv = dev->dev_private;

@@ -291,7 +291,7 @@ static void psbfb_copyarea_accel(struct fb_info *info,
const struct fb_copyarea *a)
{
struct psb_fbdev *fbdev = info->par;
- struct psb_framebuffer *psbfb = fbdev->pfb;
+ struct psb_framebuffer *psbfb = &fbdev->pfb;
struct drm_device *dev = psbfb->base.dev;
struct drm_framebuffer *fb = fbdev->psb_fb_helper.fb;


struct drm_psb_private *dev_priv = dev->dev_private;

@@ -360,19 +360,12 @@ void psbfb_imageblit(struct fb_info *info, const struct fb_image *image)
int psbfb_sync(struct fb_info *info)
{
struct psb_fbdev *fbdev = info->par;
- struct psb_framebuffer *psbfb = fbdev->pfb;
+ struct psb_framebuffer *psbfb = &fbdev->pfb;
struct drm_device *dev = psbfb->base.dev;


struct drm_psb_private *dev_priv = dev->dev_private;

unsigned long _end = jiffies + DRM_HZ;
int busy = 0;

-#if 0
- /* Just a way to quickly test if cmd issue explodes */
- u32 test[2] = {
- PSB_2D_FENCE_BH,
- };
- psbfb_2d_submit(dev_priv, test, 1);
-#endif
/*
* First idle the 2D engine.
*/
diff --git a/drivers/staging/gma500/psb_fb.c b/drivers/staging/gma500/psb_fb.c
index 4b05cdc..5977add 100644
--- a/drivers/staging/gma500/psb_fb.c
+++ b/drivers/staging/gma500/psb_fb.c
@@ -235,7 +235,7 @@ static struct vm_operations_struct psbfb_vm_ops = {


static int psbfb_mmap(struct fb_info *info, struct vm_area_struct *vma)

{
struct psb_fbdev *fbdev = info->par;
- struct psb_framebuffer *psbfb = fbdev->pfb;
+ struct psb_framebuffer *psbfb = &fbdev->pfb;
char *fb_screen_base = NULL;
struct drm_device *dev = psbfb->base.dev;


struct drm_psb_private *dev_priv = dev->dev_private;

@@ -267,7 +267,7 @@ static int psbfb_mmap(struct fb_info *info, struct vm_area_struct *vma)
static int psbfb_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg)
{
struct psb_fbdev *fbdev = info->par;
- struct psb_framebuffer *psbfb = fbdev->pfb;
+ struct psb_framebuffer *psbfb = &fbdev->pfb;
struct drm_device *dev = psbfb->base.dev;


struct drm_psb_private *dev_priv = dev->dev_private;

u32 __user *p = (u32 __user *)arg;
@@ -304,8 +304,58 @@ static struct fb_ops psbfb_ops = {
.fb_ioctl = psbfb_ioctl,
};

+/**
+ * psb_framebuffer_init - initialize a framebuffer
+ * @dev: our DRM device
+ * @fb: framebuffer to set up
+ * @mode_cmd: mode description
+ * @gt: backing object
+ *
+ * Configure and fill in the boilerplate for our frame buffer. Return
+ * 0 on success or an error code if we fail.
+ */
+static int psb_framebuffer_init(struct drm_device *dev,
+ struct psb_framebuffer *fb,
+ struct drm_mode_fb_cmd *mode_cmd,
+ struct gtt_range *gt)
+{
+ int ret;
+
+ if (mode_cmd->pitch & 63)
+ return -EINVAL;
+ switch (mode_cmd->bpp) {
+ case 8:
+ case 16:
+ case 24:
+ case 32:
+ break;
+ default:
+ return -EINVAL;
+ }
+ ret = drm_framebuffer_init(dev, &fb->base, &psb_fb_funcs);
+ if (ret) {
+ dev_err(dev->dev, "framebuffer init failed: %d\n", ret);
+ return ret;
+ }
+ drm_helper_mode_fill_fb_struct(&fb->base, mode_cmd);
+ fb->gtt = gt;
+ return 0;
+}
+
+/**
+ * psb_framebuffer_create - create a framebuffer backed by gt
+ * @dev: our DRM device
+ * @mode_cmd: the description of the requested mode
+ * @gt: the backing object
+ *
+ * Create a framebuffer object backed by the gt, and fill in the
+ * boilerplate required
+ *
+ * TODO: review object references
+ */
static struct drm_framebuffer *psb_framebuffer_create
- (struct drm_device *dev, struct drm_mode_fb_cmd *r,
+ (struct drm_device *dev,
+ struct drm_mode_fb_cmd *mode_cmd,
struct gtt_range *gt)
{
struct psb_framebuffer *fb;
@@ -313,22 +363,14 @@ static struct drm_framebuffer *psb_framebuffer_create

fb = kzalloc(sizeof(*fb), GFP_KERNEL);
if (!fb)
- return NULL;
-
- ret = drm_framebuffer_init(dev, &fb->base, &psb_fb_funcs);
-
- if (ret)
- goto err;
-
- drm_helper_mode_fill_fb_struct(&fb->base, r);
-
- fb->gtt = gt;
-
- return &fb->base;
+ return ERR_PTR(-ENOMEM);

-err:
- kfree(fb);
- return NULL;
+ ret = psb_framebuffer_init(dev, fb, mode_cmd, gt);
+ if (ret) {
+ kfree(fb);
+ return ERR_PTR(ret);
+ }
+ return &fb->base;
}

/**
@@ -380,56 +422,63 @@ static int psbfb_create(struct psb_fbdev *fbdev,


struct drm_psb_private *dev_priv = dev->dev_private;

struct fb_info *info;
struct drm_framebuffer *fb;
- struct psb_framebuffer *psbfb;
+ struct psb_framebuffer *psbfb = &fbdev->pfb;
struct drm_mode_fb_cmd mode_cmd;
struct device *device = &dev->pdev->dev;
- int size, aligned_size;
+ int size;
int ret;
struct gtt_range *backing;

mode_cmd.width = sizes->surface_width;
mode_cmd.height = sizes->surface_height;
+ mode_cmd.bpp = sizes->surface_bpp;
+
+ /* No 24bit packed */
+ if (mode_cmd.bpp == 24)
+ mode_cmd.bpp = 32;

- mode_cmd.bpp = 32;
/* HW requires pitch to be 64 byte aligned */
- mode_cmd.pitch = ALIGN(mode_cmd.width * ((mode_cmd.bpp + 1) / 8), 64);
- mode_cmd.depth = 24;
+ mode_cmd.pitch = ALIGN(mode_cmd.width * ((mode_cmd.bpp + 7) / 8), 64);
+ mode_cmd.depth = sizes->surface_depth;

size = mode_cmd.pitch * mode_cmd.height;
- aligned_size = ALIGN(size, PAGE_SIZE);
+ size = ALIGN(size, PAGE_SIZE);

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

mutex_lock(&dev->struct_mutex);
- fb = psb_framebuffer_create(dev, &mode_cmd, backing);
- if (!fb) {
- DRM_ERROR("failed to allocate fb.\n");
- ret = -ENOMEM;
- goto out_err1;
- }
- psbfb = to_psb_fb(fb);

- info = framebuffer_alloc(sizeof(struct psb_fbdev), device);
+ info = framebuffer_alloc(0, device);
if (!info) {
ret = -ENOMEM;
- goto out_err0;
+ goto out_err1;
}
-
info->par = fbdev;

+ ret = psb_framebuffer_init(dev, psbfb, &mode_cmd, backing);
+ if (ret)
+ goto out_unref;
+
+ fb = &psbfb->base;
psbfb->fbdev = info;

fbdev->psb_fb_helper.fb = fb;
fbdev->psb_fb_helper.fbdev = info;
- fbdev->pfb = psbfb;

strcpy(info->fix.id, "psbfb");

info->flags = FBINFO_DEFAULT;
info->fbops = &psbfb_ops;
+
+ ret = fb_alloc_cmap(&info->cmap, 256, 0);
+ if (ret) {
+ ret = -ENOMEM;
+ goto out_unref;
+ }
+


info->fix.smem_start = dev->mode_config.fb_base;
info->fix.smem_len = size;

@@ -445,18 +494,18 @@ static int psbfb_create(struct psb_fbdev *fbdev,


if (info->screen_base == NULL) {

psb_gtt_unpin(backing);
ret = -ENOMEM;
- goto out_err0;
+ goto out_unref;
}
psbfb->vm_map = 1;
}
info->screen_size = size;
- memset(info->screen_base, 0, size);
+/* memset(info->screen_base, 0, size); */

if (dev_priv->pg->stolen_size) {
info->apertures = alloc_apertures(1);
if (!info->apertures) {
ret = -ENOMEM;
- goto out_err0;
+ goto out_unref;


}
info->apertures->ranges[0].base = dev->mode_config.fb_base;

info->apertures->ranges[0].size = dev_priv->pg->stolen_size;

@@ -484,8 +533,14 @@ static int psbfb_create(struct psb_fbdev *fbdev,
mutex_unlock(&dev->struct_mutex);

return 0;
-out_err0:
- fb->funcs->destroy(fb);
+out_unref:
+ if (backing->stolen)
+ psb_gtt_free_range(dev, backing);
+ else {
+ if (psbfb->vm_map)
+ vm_unmap_ram(info->screen_base, backing->npage);
+ drm_gem_object_unreference(&backing->gem);
+ }
out_err1:
mutex_unlock(&dev->struct_mutex);
psb_gtt_free_range(dev, backing);
@@ -506,7 +561,6 @@ static struct drm_framebuffer *psb_user_framebuffer_create
{
struct gtt_range *r;
struct drm_gem_object *obj;
- struct psb_framebuffer *psbfb;

/* Find the GEM object and thus the gtt range object that is
to back this space */
@@ -514,23 +568,9 @@ static struct drm_framebuffer *psb_user_framebuffer_create
if (obj == NULL)
return ERR_PTR(-ENOENT);

- /* Allocate a framebuffer */
- psbfb = kzalloc(sizeof(*psbfb), GFP_KERNEL);
- if (psbfb == NULL) {
- drm_gem_object_unreference_unlocked(obj);
- return ERR_PTR(-ENOMEM);
- }
-
/* Let the core code do all the work */
r = container_of(obj, struct gtt_range, gem);
- if (psb_framebuffer_create(dev, cmd, r) == NULL) {
- drm_gem_object_unreference_unlocked(obj);
- kfree(psbfb);
- return ERR_PTR(-EINVAL);
- }
- /* Return the drm_framebuffer contained within the psb fbdev which
- has been initialized by the framebuffer creation */
- return &psbfb->base;
+ return psb_framebuffer_create(dev, cmd, r);
}

static void psbfb_gamma_set(struct drm_crtc *crtc, u16 red, u16 green,
@@ -572,7 +612,7 @@ struct drm_fb_helper_funcs psb_fb_helper_funcs = {


int psb_fbdev_destroy(struct drm_device *dev, struct psb_fbdev *fbdev)

{
struct fb_info *info;
- struct psb_framebuffer *psbfb = fbdev->pfb;
+ struct psb_framebuffer *psbfb = &fbdev->pfb;



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

@@ -583,6 +623,15 @@ int psb_fbdev_destroy(struct drm_device *dev, struct psb_fbdev *fbdev)


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);
+ framebuffer_release(info);
+ }
+ drm_fb_helper_fini(&fbdev->psb_fb_helper);
+ drm_framebuffer_cleanup(&psbfb->base);
+
+ if (psbfb->gtt) {


/* FIXME: this is a bit more inside knowledge than I'd like
but I don't see how to make a fake GEM object of the
stolen space nicely */

@@ -590,13 +639,7 @@ int psb_fbdev_destroy(struct drm_device *dev, struct psb_fbdev *fbdev)
psb_gtt_free_range(dev, psbfb->gtt);
else
drm_gem_object_unreference(&psbfb->gtt->gem);
- unregister_framebuffer(info);
- iounmap(info->screen_base);
- framebuffer_release(info);
- }
-
- drm_fb_helper_fini(&fbdev->psb_fb_helper);
- drm_framebuffer_cleanup(&psbfb->base);
+ }
return 0;
}

@@ -644,22 +687,6 @@ static void psbfb_output_poll_changed(struct drm_device *dev)
drm_fb_helper_hotplug_event(&fbdev->psb_fb_helper);
}

-int psbfb_remove(struct drm_device *dev, struct drm_framebuffer *fb)
-{
- struct fb_info *info;
- struct psb_framebuffer *psbfb = to_psb_fb(fb);
-
- if (drm_psb_no_fb)
- return 0;
-
- info = psbfb->fbdev;
-
- if (info)
- framebuffer_release(info);
- return 0;
-}
-/*EXPORT_SYMBOL(psbfb_remove); */
-
/**
* psb_user_framebuffer_create_handle - add hamdle to a framebuffer
* @fb: framebuffer
@@ -690,15 +717,13 @@ static int psb_user_framebuffer_create_handle(struct drm_framebuffer *fb,
*/


static void psb_user_framebuffer_destroy(struct drm_framebuffer *fb)

{
- struct drm_device *dev = fb->dev;


struct psb_framebuffer *psbfb = to_psb_fb(fb);
struct gtt_range *r = psbfb->gtt;

+ /* Should never get stolen memory for a user fb */
+ WARN_ON(r->stolen);


pr_err("user framebuffer destroy %p, fbdev %p\n",

psbfb, psbfb->fbdev);
- if (psbfb->fbdev)
- psbfb_remove(dev, fb);
-
/* Let DRM do its clean up */
drm_framebuffer_cleanup(fb);
/* We are no longer using the resource in GEM */
diff --git a/drivers/staging/gma500/psb_fb.h b/drivers/staging/gma500/psb_fb.h
index 2153c74..fd7e51a 100644
--- a/drivers/staging/gma500/psb_fb.h
+++ b/drivers/staging/gma500/psb_fb.h
@@ -38,7 +38,7 @@ struct psb_framebuffer {

struct psb_fbdev {
struct drm_fb_helper psb_fb_helper;
- struct psb_framebuffer *pfb;
+ struct psb_framebuffer pfb;
};


diff --git a/drivers/staging/gma500/psb_gem.c b/drivers/staging/gma500/psb_gem.c
index 98d8ab3..b24b964 100644
--- a/drivers/staging/gma500/psb_gem.c
+++ b/drivers/staging/gma500/psb_gem.c
@@ -51,6 +51,7 @@ void psb_gem_free_object(struct drm_gem_object *obj)
}
drm_gem_object_release(obj);


/* This must occur last as it frees up the memory of the GEM object */

+ pr_err("GEM destroyed %p, %p\n", gtt, obj);
psb_gtt_free_range(obj->dev, gtt);
}

@@ -176,21 +177,28 @@ static int psb_gem_create(struct drm_file *file,

size = roundup(size, PAGE_SIZE);

+ dev_err(dev->dev, "GEM creating %lld\n", size);
+
/* Allocate our object - for now a direct gtt range which is not
stolen memory backed */
r = psb_gtt_alloc_range(dev, size, "gem", 0);
- if (r == NULL)
+ if (r == NULL) {
+ dev_err(dev->dev, "no memory for %lld byte GEM object\n", size);
return -ENOSPC;
+ }
/* 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 */
+ dev_err(dev->dev, "GEM init failed for %lld\n", size);
return -ENOMEM;
}
/* Give the object a handle so we can carry it more easily */
ret = drm_gem_handle_create(file, &r->gem, &handle);
if (ret) {
+ dev_err(dev->dev, "GEM handle failed for %p, %lld\n",
+ &r->gem, size);
drm_gem_object_release(&r->gem);
psb_gtt_free_range(dev, r);
return ret;
@@ -198,6 +206,8 @@ static int psb_gem_create(struct drm_file *file,
/* We have the initial and handle reference but need only one now */
drm_gem_object_unreference(&r->gem);
*handlep = handle;
+ dev_err(dev->dev, "GEM handle %x for %p OK\n",
+ handle, &r->gem);
return 0;
}

@@ -273,9 +283,12 @@ int psb_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
something from beneath our feet */
mutex_lock(&dev->struct_mutex);

+ dev_err(dev->dev, "Fault on GTT %p\n", r);
+
/* For now the mmap pins the object and it stays pinned. As things
stand that will do us no harm */
if (r->mmapping == 0) {
+ dev_err(dev->dev, "Need to pin %p\n", r);
ret = psb_gtt_pin(r);
if (ret < 0) {
DRM_ERROR("gma500: pin failed: %d\n", ret);
@@ -289,10 +302,13 @@ int psb_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf)


page_offset = ((unsigned long) vmf->virtual_address - vma->vm_start)
>> PAGE_SHIFT;

+ dev_err(dev->dev, "Page offset %p %d\n", r, (int)page_offset);


/* CPU view of the page, don't go via the GART for CPU writes */

pfn = page_to_phys(r->pages[page_offset]) >> PAGE_SHIFT;
ret = vm_insert_pfn(vma, (unsigned long)vmf->virtual_address, pfn);

+ dev_err(dev->dev, "PFN %ld for VA %p = %d\n", pfn, vmf->virtual_address, ret);
+
fail:
mutex_unlock(&dev->struct_mutex);
switch (ret) {
diff --git a/drivers/staging/gma500/psb_gtt.c b/drivers/staging/gma500/psb_gtt.c
index 5a296e1..c6a7492 100644
--- a/drivers/staging/gma500/psb_gtt.c
+++ b/drivers/staging/gma500/psb_gtt.c
@@ -314,6 +314,7 @@ struct gtt_range *psb_gtt_alloc_range(struct drm_device *dev, int len,


len, start, end, PAGE_SIZE, NULL, NULL);
if (ret == 0) {

gt->offset = gt->resource.start - r->start;

+ dev_err(dev->dev, "GTT new %p, %d\n", gt, gt->stolen);
return gt;
}
kfree(gt);
@@ -340,6 +341,7 @@ static void psb_gtt_destroy(struct kref *kref)
}
WARN_ON(gt->in_gart && !gt->stolen);
release_resource(&gt->resource);
+ pr_err("GTT destroyed %p, %d\n", gt, gt->stolen);
kfree(gt);

Alan Cox

unread,
Jun 8, 2011, 6:13:54 AM6/8/11
to gr...@kroah.com, linux-...@vger.kernel.org, dri-...@lists.freedesktop.org
From: Alan Cox <al...@linux.intel.com>

If we get a user frame buffer destroyed which is being displayed then clean
up the mess nicely. We can now run a slightly modified modetest including setting
modes, and handling crashes.

Modetest still blows up but this is because libdrm 2.4.25 is busted.


Signed-off-by: Alan Cox <al...@linux.intel.com>
---

drivers/staging/gma500/psb_fb.c | 24 +++++++++++++++++++++++-
drivers/staging/gma500/psb_intel_display.c | 22 +++++++++++++---------
2 files changed, 36 insertions(+), 10 deletions(-)

diff --git a/drivers/staging/gma500/psb_fb.c b/drivers/staging/gma500/psb_fb.c
index 5977add..d005025 100644
--- a/drivers/staging/gma500/psb_fb.c
+++ b/drivers/staging/gma500/psb_fb.c
@@ -719,16 +719,38 @@ static void psb_user_framebuffer_destroy(struct drm_framebuffer *fb)
{


struct psb_framebuffer *psbfb = to_psb_fb(fb);
struct gtt_range *r = psbfb->gtt;

+ struct drm_device *dev = fb->dev;
+ struct drm_psb_private *dev_priv = dev->dev_private;
+ struct psb_fbdev *fbdev = dev_priv->fbdev;
+ struct drm_crtc *crtc;
+ int reset = 0;



/* Should never get stolen memory for a user fb */

WARN_ON(r->stolen);
pr_err("user framebuffer destroy %p, fbdev %p\n",
psbfb, psbfb->fbdev);

+ /* Check if we are erroneously live */
+ list_for_each_entry(crtc, &dev->mode_config.crtc_list, head)
+ if (crtc->fb == fb)
+ reset = 1;
+
+ if (reset)
+ pr_err("DRM: gma500, forcing reset\n");
+
+ if (reset)
+ /*
+ * Now force a sane response before we permit the DRM crc layer to
+ * do stupid things like blank the display. Instead we reset this
+ * framebuffer as if the user had forced a reset. We must do this
+ * before the cleanup so that the DRM layer doesn't get a chance
+ * to stick its oar in where it isn't wanted.
+ */
+ drm_fb_helper_restore_fbdev_mode(&fbdev->psb_fb_helper);
+


/* Let DRM do its clean up */
drm_framebuffer_cleanup(fb);
/* We are no longer using the resource in GEM */

drm_gem_object_unreference_unlocked(&r->gem);
-
kfree(fb);
}

diff --git a/drivers/staging/gma500/psb_intel_display.c b/drivers/staging/gma500/psb_intel_display.c
index a99271d..c7c55b1 100644
--- a/drivers/staging/gma500/psb_intel_display.c
+++ b/drivers/staging/gma500/psb_intel_display.c
@@ -352,15 +352,15 @@ int psb_intel_pipe_set_base(struct drm_crtc *crtc,

PSB_DEBUG_ENTRY("\n");

+ if (!gma_power_begin(dev, true))
+ return 0;
+
/* no fb bound */
if (!crtc->fb) {
DRM_DEBUG("No FB bound\n");
- return 0;
+ goto psb_intel_pipe_cleaner;
}

- if (!gma_power_begin(dev, true))
- return 0;
-
/* We are displaying this buffer, make sure it is actually loaded
into the GTT */
ret = psb_gtt_pin(psbfb->gtt);
@@ -409,6 +409,7 @@ int psb_intel_pipe_set_base(struct drm_crtc *crtc,
REG_READ(dspbase);
}

+psb_intel_pipe_cleaner:
/* If there was a previous display we can now unpin it */
if (old_fb)
psb_gtt_unpin(to_psb_fb(old_fb)->gtt);
@@ -588,6 +589,7 @@ static int psb_intel_crtc_mode_set(struct drm_crtc *crtc,
{
struct drm_device *dev = crtc->dev;
struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc);
+ struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
int pipe = psb_intel_crtc->pipe;
int fp_reg = (pipe == 0) ? FPA0 : FPB0;
int dpll_reg = (pipe == 0) ? DPLL_A : DPLL_B;
@@ -610,6 +612,12 @@ static int psb_intel_crtc_mode_set(struct drm_crtc *crtc,
struct drm_mode_config *mode_config = &dev->mode_config;
struct drm_connector *connector;

+ /* No scan out no play */
+ if (crtc->fb == NULL) {
+ crtc_funcs->mode_set_base(crtc, x, y, old_fb);


+ return 0;
+ }
+

list_for_each_entry(connector, &mode_config->connector_list, head) {
struct psb_intel_output *psb_intel_output =
to_psb_intel_output(connector);
@@ -786,11 +794,7 @@ static int psb_intel_crtc_mode_set(struct drm_crtc *crtc,
REG_WRITE(dspcntr_reg, dspcntr);

/* Flush the plane changes */
- {
- struct drm_crtc_helper_funcs *crtc_funcs =
- crtc->helper_private;
- crtc_funcs->mode_set_base(crtc, x, y, old_fb);
- }
+ crtc_funcs->mode_set_base(crtc, x, y, old_fb);

psb_intel_wait_for_vblank(dev);

Alan Cox

unread,
Jun 8, 2011, 6:14:12 AM6/8/11
to gr...@kroah.com, linux-...@vger.kernel.org, dri-...@lists.freedesktop.org
From: Alan Cox <al...@linux.intel.com>

Signed-off-by: Alan Cox <al...@linux.intel.com>
---

drivers/staging/gma500/psb_fb.c | 6 +-----
drivers/staging/gma500/psb_gem.c | 11 -----------
drivers/staging/gma500/psb_gtt.c | 2 --
3 files changed, 1 insertions(+), 18 deletions(-)

diff --git a/drivers/staging/gma500/psb_fb.c b/drivers/staging/gma500/psb_fb.c
index d005025..156f8ad 100644
--- a/drivers/staging/gma500/psb_fb.c
+++ b/drivers/staging/gma500/psb_fb.c
@@ -727,17 +727,13 @@ static void psb_user_framebuffer_destroy(struct drm_framebuffer *fb)



/* Should never get stolen memory for a user fb */
WARN_ON(r->stolen);

- pr_err("user framebuffer destroy %p, fbdev %p\n",
- psbfb, psbfb->fbdev);


+
/* Check if we are erroneously live */

list_for_each_entry(crtc, &dev->mode_config.crtc_list, head)


if (crtc->fb == fb)

reset = 1;

if (reset)
- pr_err("DRM: gma500, forcing reset\n");
-
- if (reset)
/*

* Now force a sane response before we permit the DRM crc layer to

* do stupid things like blank the display. Instead we reset this

diff --git a/drivers/staging/gma500/psb_gem.c b/drivers/staging/gma500/psb_gem.c
index b24b964..125ea6b 100644
--- a/drivers/staging/gma500/psb_gem.c
+++ b/drivers/staging/gma500/psb_gem.c
@@ -51,7 +51,6 @@ void psb_gem_free_object(struct drm_gem_object *obj)


}
drm_gem_object_release(obj);
/* This must occur last as it frees up the memory of the GEM object */

- pr_err("GEM destroyed %p, %p\n", gtt, obj);
psb_gtt_free_range(obj->dev, gtt);
}

@@ -177,8 +176,6 @@ static int psb_gem_create(struct drm_file *file,

size = roundup(size, PAGE_SIZE);

- dev_err(dev->dev, "GEM creating %lld\n", size);
-


/* Allocate our object - for now a direct gtt range which is not
stolen memory backed */
r = psb_gtt_alloc_range(dev, size, "gem", 0);

@@ -206,8 +203,6 @@ static int psb_gem_create(struct drm_file *file,


/* We have the initial and handle reference but need only one now */
drm_gem_object_unreference(&r->gem);
*handlep = handle;

- dev_err(dev->dev, "GEM handle %x for %p OK\n",
- handle, &r->gem);
return 0;
}

@@ -283,12 +278,9 @@ int psb_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf)


something from beneath our feet */
mutex_lock(&dev->struct_mutex);

- dev_err(dev->dev, "Fault on GTT %p\n", r);
-


/* For now the mmap pins the object and it stays pinned. As things
stand that will do us no harm */
if (r->mmapping == 0) {

- dev_err(dev->dev, "Need to pin %p\n", r);


ret = psb_gtt_pin(r);
if (ret < 0) {
DRM_ERROR("gma500: pin failed: %d\n", ret);

@@ -302,13 +294,10 @@ int psb_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf)


page_offset = ((unsigned long) vmf->virtual_address - vma->vm_start)
>> PAGE_SHIFT;

- dev_err(dev->dev, "Page offset %p %d\n", r, (int)page_offset);


/* CPU view of the page, don't go via the GART for CPU writes */
pfn = page_to_phys(r->pages[page_offset]) >> PAGE_SHIFT;
ret = vm_insert_pfn(vma, (unsigned long)vmf->virtual_address, pfn);

- dev_err(dev->dev, "PFN %ld for VA %p = %d\n", pfn, vmf->virtual_address, ret);
-


fail:
mutex_unlock(&dev->struct_mutex);
switch (ret) {
diff --git a/drivers/staging/gma500/psb_gtt.c b/drivers/staging/gma500/psb_gtt.c

index c6a7492..5a296e1 100644
--- a/drivers/staging/gma500/psb_gtt.c
+++ b/drivers/staging/gma500/psb_gtt.c
@@ -314,7 +314,6 @@ struct gtt_range *psb_gtt_alloc_range(struct drm_device *dev, int len,


len, start, end, PAGE_SIZE, NULL, NULL);
if (ret == 0) {
gt->offset = gt->resource.start - r->start;

- dev_err(dev->dev, "GTT new %p, %d\n", gt, gt->stolen);
return gt;
}
kfree(gt);
@@ -341,7 +340,6 @@ static void psb_gtt_destroy(struct kref *kref)


}
WARN_ON(gt->in_gart && !gt->stolen);
release_resource(&gt->resource);

- pr_err("GTT destroyed %p, %d\n", gt, gt->stolen);
kfree(gt);
}

Alan Cox

unread,
Jun 8, 2011, 6:14:26 AM6/8/11
to gr...@kroah.com, linux-...@vger.kernel.org, dri-...@lists.freedesktop.org
From: Alan Cox <al...@linux.intel.com>

Give the driver its own proper DRM name, clean up copyright headers and so
forth

Signed-off-by: Alan Cox <al...@linux.intel.com>
---

drivers/staging/gma500/mrst_crtc.c | 4 +
drivers/staging/gma500/mrst_lvds.c | 2 -
drivers/staging/gma500/psb_2d.c | 7 --
drivers/staging/gma500/psb_bl.c | 4 +
drivers/staging/gma500/psb_drm.h | 90 +-------------------------------
drivers/staging/gma500/psb_drv.c | 4 +
drivers/staging/gma500/psb_drv.h | 85 +++++++++++++++---------------
drivers/staging/gma500/psb_fb.c | 3 -
drivers/staging/gma500/psb_fb.h | 3 -
drivers/staging/gma500/psb_gtt.h | 7 +-
drivers/staging/gma500/psb_intel_drv.h | 19 +------
drivers/staging/gma500/psb_irq.h | 8 +--
drivers/staging/gma500/psb_powermgmt.c | 4 +
drivers/staging/gma500/psb_powermgmt.h | 2 -
drivers/staging/gma500/psb_reg.h | 2 -
15 files changed, 67 insertions(+), 177 deletions(-)

diff --git a/drivers/staging/gma500/mrst_crtc.c b/drivers/staging/gma500/mrst_crtc.c
index e4a0c03..fd97c80 100644
--- a/drivers/staging/gma500/mrst_crtc.c
+++ b/drivers/staging/gma500/mrst_crtc.c
@@ -86,7 +86,7 @@ static const struct mrst_limit_t *mrst_limit(struct drm_crtc *crtc)
{
const struct mrst_limit_t *limit = NULL;


struct drm_device *dev = crtc->dev;

- DRM_DRIVER_PRIVATE_T *dev_priv = dev->dev_private;


+ struct drm_psb_private *dev_priv = dev->dev_private;

if (psb_intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)
|| psb_intel_pipe_has_type(crtc, INTEL_OUTPUT_MIPI)) {
@@ -296,7 +296,7 @@ static int mrst_crtc_mode_set(struct drm_crtc *crtc,


{
struct drm_device *dev = crtc->dev;
struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc);

- DRM_DRIVER_PRIVATE_T *dev_priv = dev->dev_private;


+ struct drm_psb_private *dev_priv = dev->dev_private;

int pipe = psb_intel_crtc->pipe;

int fp_reg = (pipe == 0) ? MRST_FPA0 : FPB0;
int dpll_reg = (pipe == 0) ? MRST_DPLL_A : DPLL_B;
diff --git a/drivers/staging/gma500/mrst_lvds.c b/drivers/staging/gma500/mrst_lvds.c
index 4a08b74..22ea00e 100644
--- a/drivers/staging/gma500/mrst_lvds.c
+++ b/drivers/staging/gma500/mrst_lvds.c
@@ -46,7 +46,7 @@ static void mrst_lvds_set_power(struct drm_device *dev,
struct psb_intel_output *output, bool on)
{
u32 pp_status;
- DRM_DRIVER_PRIVATE_T *dev_priv = dev->dev_private;


+ struct drm_psb_private *dev_priv = dev->dev_private;

PSB_DEBUG_ENTRY("\n");

if (!gma_power_begin(dev, true))
diff --git a/drivers/staging/gma500/psb_2d.c b/drivers/staging/gma500/psb_2d.c
index 060eeaf..c3d7085 100644
--- a/drivers/staging/gma500/psb_2d.c
+++ b/drivers/staging/gma500/psb_2d.c
@@ -1,5 +1,5 @@
/**************************************************************************
- * Copyright (c) 2007, Intel Corporation.
+ * Copyright (c) 2007-2011, Intel Corporation.
* All Rights Reserved.
*
* This program is free software; you can redistribute it and/or modify it
@@ -396,8 +396,3 @@ int psbfb_sync(struct fb_info *info)
out:
return (busy) ? -EBUSY : 0;
}
-
-/*
- info->fix.accel = FB_ACCEL_I830;
- info->flags = FBINFO_DEFAULT;
-*/
diff --git a/drivers/staging/gma500/psb_bl.c b/drivers/staging/gma500/psb_bl.c
index 5dffc71..2f9674d 100644
--- a/drivers/staging/gma500/psb_bl.c
+++ b/drivers/staging/gma500/psb_bl.c
@@ -1,7 +1,7 @@
/*
- * psb backlight interface
+ * GMA500 Backlight Interface
*
- * Copyright (c) 2009, Intel Corporation.
+ * Copyright (c) 2009-2011, Intel Corporation.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
diff --git a/drivers/staging/gma500/psb_drm.h b/drivers/staging/gma500/psb_drm.h
index 49ffdd5..b005293 100644
--- a/drivers/staging/gma500/psb_drm.h
+++ b/drivers/staging/gma500/psb_drm.h
@@ -1,5 +1,5 @@
/**************************************************************************
- * Copyright (c) 2007, Intel Corporation.
+ * Copyright (c) 2007-2011, Intel Corporation.
* All Rights Reserved.
* Copyright (c) 2008, Tungsten Graphics Inc. Cedar Park, TX., USA.
* All Rights Reserved.
@@ -22,84 +22,8 @@
#ifndef _PSB_DRM_H_
#define _PSB_DRM_H_

-#if defined(__linux__) && !defined(__KERNEL__)
-#include<stdint.h>
-#include <linux/types.h>
-#include "drm_mode.h"
-#endif
-
-#define DRM_PSB_SAREA_MAJOR 0
-#define DRM_PSB_SAREA_MINOR 2
-#define PSB_FIXED_SHIFT 16
-
#define PSB_NUM_PIPE 3

-/*
- * Public memory types.
- */
-
-typedef s32 psb_fixed;
-typedef u32 psb_ufixed;
-
-static inline s32 psb_int_to_fixed(int a)
-{
- return a * (1 << PSB_FIXED_SHIFT);
-}
-
-static inline u32 psb_unsigned_to_ufixed(unsigned int a)
-{
- return a << PSB_FIXED_SHIFT;
-}
-
-/*Status of the command sent to the gfx device.*/
-typedef enum {
- DRM_CMD_SUCCESS,
- DRM_CMD_FAILED,
- DRM_CMD_HANG
-} drm_cmd_status_t;
-
-struct drm_psb_scanout {
- u32 buffer_id; /* DRM buffer object ID */
- u32 rotation; /* Rotation as in RR_rotation definitions */
- u32 stride; /* Buffer stride in bytes */
- u32 depth; /* Buffer depth in bits (NOT) bpp */
- u32 width; /* Buffer width in pixels */
- u32 height; /* Buffer height in lines */
- s32 transform[3][3]; /* Buffer composite transform */
- /* (scaling, rot, reflect) */
-};
-
-#define DRM_PSB_SAREA_OWNERS 16
-#define DRM_PSB_SAREA_OWNER_2D 0
-#define DRM_PSB_SAREA_OWNER_3D 1
-
-#define DRM_PSB_SAREA_SCANOUTS 3
-
-struct drm_psb_sarea {
- /* Track changes of this data structure */
-
- u32 major;
- u32 minor;
-
- /* Last context to touch part of hw */
- u32 ctx_owners[DRM_PSB_SAREA_OWNERS];
-
- /* Definition of front- and rotated buffers */
- u32 num_scanouts;
- struct drm_psb_scanout scanouts[DRM_PSB_SAREA_SCANOUTS];
-
- int planeA_x;
- int planeA_y;
- int planeA_w;
- int planeA_h;
- int planeB_x;
- int planeB_y;
- int planeB_w;
- int planeB_h;
- /* Number of active scanouts */
- u32 num_active_scanouts;
-};
-
#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)
@@ -223,20 +147,14 @@ struct drm_psb_register_rw_arg {

#define DRM_PSB_KMS_OFF 0x00
#define DRM_PSB_KMS_ON 0x01
-#define DRM_PSB_VT_LEAVE 0x02
-#define DRM_PSB_VT_ENTER 0x03
-#define DRM_PSB_EXTENSION 0x06
#define DRM_PSB_SIZES 0x07
#define DRM_PSB_FUSE_REG 0x08
-#define DRM_PSB_VBT 0x09
#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
-#define DRM_PSB_GTT_MAP 0x0F
-#define DRM_PSB_GTT_UNMAP 0x10
-#define DRM_PSB_GETPAGEADDRS 0x11
+
/**
* NOTE: Add new commands here, but increment
* the values below and increment their
@@ -249,10 +167,6 @@ struct drm_psb_register_rw_arg {
#define DRM_PVR_RESERVED4 0x15
#define DRM_PVR_RESERVED5 0x16

-#define DRM_PSB_HIST_ENABLE 0x17
-#define DRM_PSB_HIST_STATUS 0x18
-#define DRM_PSB_UPDATE_GUARD 0x19
-#define DRM_PSB_INIT_COMM 0x1A
#define DRM_PSB_DPST 0x1B
#define DRM_PSB_GAMMA 0x1C
#define DRM_PSB_DPST_BL 0x1D
diff --git a/drivers/staging/gma500/psb_drv.c b/drivers/staging/gma500/psb_drv.c
index aa87b1b..9bd0a5d 100644
--- a/drivers/staging/gma500/psb_drv.c
+++ b/drivers/staging/gma500/psb_drv.c
@@ -1,5 +1,5 @@
/**************************************************************************
- * Copyright (c) 2007, Intel Corporation.
+ * Copyright (c) 2007-2011, Intel Corporation.
* All Rights Reserved.
* Copyright (c) 2008, Tungsten Graphics, Inc. Cedar Park, TX., USA.
* All Rights Reserved.
@@ -1462,6 +1462,6 @@ static void __exit psb_exit(void)
late_initcall(psb_init);
module_exit(psb_exit);

-MODULE_AUTHOR(DRIVER_AUTHOR);
+MODULE_AUTHOR("Alan Cox <al...@linux.intel.com> and others");
MODULE_DESCRIPTION(DRIVER_DESC);
MODULE_LICENSE("GPL");
diff --git a/drivers/staging/gma500/psb_drv.h b/drivers/staging/gma500/psb_drv.h
index e19a454..c0468ee 100644
--- a/drivers/staging/gma500/psb_drv.h
+++ b/drivers/staging/gma500/psb_drv.h
@@ -1,5 +1,5 @@
/**************************************************************************
- * Copyright (c) 2007-2008, Intel Corporation.
+ * Copyright (c) 2007-2011, Intel Corporation.
* All Rights Reserved.
*
* This program is free software; you can redistribute it and/or modify it
@@ -32,40 +32,32 @@
#include "psb_powermgmt.h"
#include "mrst.h"

-/*Append new drm mode definition here, align with libdrm definition*/
+/* Append new drm mode definition here, align with libdrm definition */
#define DRM_MODE_SCALE_NO_SCALE 2

enum {
- CHIP_PSB_8108 = 0,
- CHIP_PSB_8109 = 1,
- CHIP_MRST_4100 = 2,
+ CHIP_PSB_8108 = 0, /* Poulsbo */
+ CHIP_PSB_8109 = 1, /* Poulsbo */
+ CHIP_MRST_4100 = 2, /* Moorestown/Oaktrail */
};

#define IS_MRST(dev) (((dev)->pci_device & 0xfffc) == 0x4100)

/*
- *Hardware bugfixes
+ * Driver definitions
*/

-#define DRIVER_NAME "pvrsrvkm"
-#define DRIVER_DESC "drm driver for the Intel GMA500"
-#define DRIVER_AUTHOR "Intel Corporation"
+#define DRIVER_NAME "gma500"
+#define DRIVER_DESC "DRM driver for the Intel GMA500"

-#define PSB_DRM_DRIVER_DATE "2009-03-10"
-#define PSB_DRM_DRIVER_MAJOR 8
-#define PSB_DRM_DRIVER_MINOR 1
+#define PSB_DRM_DRIVER_DATE "2011-06-06"
+#define PSB_DRM_DRIVER_MAJOR 1
+#define PSB_DRM_DRIVER_MINOR 0
#define PSB_DRM_DRIVER_PATCHLEVEL 0

/*
- *TTM driver private offsets.
+ * Hardware offsets
*/
-
-#define DRM_PSB_FILE_PAGE_OFFSET (0x100000000ULL >> PAGE_SHIFT)
-
-#define PSB_OBJECT_HASH_ORDER 13
-#define PSB_FILE_OBJECT_HASH_ORDER 12
-#define PSB_BO_HASH_ORDER 12
-
#define PSB_VDC_OFFSET 0x00000000
#define PSB_VDC_SIZE 0x000080000
#define MRST_MMIO_SIZE 0x0000C0000
@@ -73,42 +65,52 @@ enum {
#define PSB_SGX_SIZE 0x8000
#define PSB_SGX_OFFSET 0x00040000
#define MRST_SGX_OFFSET 0x00080000
+/*
+ * PCI resource identifiers
+ */
#define PSB_MMIO_RESOURCE 0
#define PSB_GATT_RESOURCE 2
#define PSB_GTT_RESOURCE 3
+/*
+ * PCI configuration
+ */
#define PSB_GMCH_CTRL 0x52
#define PSB_BSM 0x5C
#define _PSB_GMCH_ENABLED 0x4
#define PSB_PGETBL_CTL 0x2020
#define _PSB_PGETBL_ENABLED 0x00000001
#define PSB_SGX_2D_SLAVE_PORT 0x4000
+
+/* To get rid of */
#define PSB_TT_PRIV0_LIMIT (256*1024*1024)
#define PSB_TT_PRIV0_PLIMIT (PSB_TT_PRIV0_LIMIT >> PAGE_SHIFT)
-#define PSB_NUM_VALIDATE_BUFFERS 2048

/*
- *Flags for external memory type field.
+ * SGX side MMU definitions (these can probably go)
*/

+/*
+ * Flags for external memory type field.
+ */
#define PSB_MMU_CACHED_MEMORY 0x0001 /* Bind to MMU only */
#define PSB_MMU_RO_MEMORY 0x0002 /* MMU RO memory */
#define PSB_MMU_WO_MEMORY 0x0004 /* MMU WO memory */
-
/*
- *PTE's and PDE's
+ * PTE's and PDE's
*/
-
#define PSB_PDE_MASK 0x003FFFFF
#define PSB_PDE_SHIFT 22
#define PSB_PTE_SHIFT 12
-
+/*
+ * Cache control
+ */
#define PSB_PTE_VALID 0x0001 /* PTE / PDE valid */
#define PSB_PTE_WO 0x0002 /* Write only */
#define PSB_PTE_RO 0x0004 /* Read only */
#define PSB_PTE_CACHED 0x0008 /* CPU cache coherent */

/*
- *VDC registers and bits
+ * VDC registers and bits
*/
#define PSB_MSVDX_CLOCKGATING 0x2064
#define PSB_TOPAZ_CLOCKGATING 0x2068
@@ -278,7 +280,7 @@ struct drm_psb_private {
int display_count;

/*
- *Modesetting
+ * Modesetting
*/
struct psb_intel_mode_device mode_dev;

@@ -287,12 +289,8 @@ struct drm_psb_private {
uint32_t num_pipe;

/*
- *Memory managers
+ * OSPM info (Power management base) (can go ?)
*/
-
- /*
- *OSPM info
- */
uint32_t ospm_base;

/*
@@ -304,11 +302,11 @@ struct drm_psb_private {
u32 fuse_reg_value;
u32 video_device_fuse;

- /* pci revision id for B0:D2:F0 */
+ /* PCI revision ID for B0:D2:F0 */
uint8_t platform_rev_id;

/*
- *LVDS info
+ * LVDS info
*/
int backlight_duty_cycle; /* restore backlight to this value */
bool panel_wants_dither;
@@ -316,10 +314,10 @@ struct drm_psb_private {
struct drm_display_mode *lfp_lvds_vbt_mode;
struct drm_display_mode *sdvo_lvds_vbt_mode;

- struct bdb_lvds_backlight *lvds_bl; /*LVDS backlight info from VBT*/
+ struct bdb_lvds_backlight *lvds_bl; /* LVDS backlight info from VBT */
struct psb_intel_i2c_chan *lvds_i2c_bus;

- /* Feature bits from the VBIOS*/
+ /* Feature bits from the VBIOS */
unsigned int int_tv_support:1;
unsigned int lvds_dither:1;
unsigned int lvds_vbt:1;
@@ -332,7 +330,7 @@ struct drm_psb_private {
unsigned int core_freq;
uint32_t iLVDS_enable;

- /*runtime PM state*/
+ /* Runtime PM state */
int rpm_enabled;

/* Moorestown specific */
@@ -350,7 +348,7 @@ struct drm_psb_private {
uint32_t dspcntr2;

/*
- *Register state
+ * Register state
*/
uint32_t saveDSPACNTR;
uint32_t saveDSPBCNTR;
@@ -468,7 +466,7 @@ struct drm_psb_private {
u32 lid_last_state;

/*
- *Watchdog
+ * Watchdog
*/

uint32_t apm_reg;
@@ -497,7 +495,7 @@ static inline struct drm_psb_private *psb_priv(struct drm_device *dev)
}

/*
- *MMU stuff.
+ * MMU stuff.
*/

extern struct psb_mmu_driver *psb_mmu_driver_init(uint8_t __iomem * registers,
@@ -525,7 +523,7 @@ extern int psb_mmu_virtual_to_pfn(struct psb_mmu_pd *pd, uint32_t virtual,
unsigned long *pfn);

/*
- *Enable / disable MMU for different requestors.
+ * Enable / disable MMU for different requestors.
*/


@@ -598,7 +596,7 @@ extern int psbfb_2d_submit(struct drm_psb_private *dev_priv, uint32_t *cmdbuf,
unsigned size);

/*
- *psb_reset.c
+ * psb_reset.c
*/

extern void psb_lid_timer_init(struct drm_psb_private *dev_priv);
@@ -710,7 +708,6 @@ extern int drm_idle_check_interval;
/*
*Utilities
*/
-#define DRM_DRIVER_PRIVATE_T struct drm_psb_private

static inline u32 MRST_MSG_READ32(uint port, uint offset)
{
diff --git a/drivers/staging/gma500/psb_fb.c b/drivers/staging/gma500/psb_fb.c
index 156f8ad..0a77abf 100644
--- a/drivers/staging/gma500/psb_fb.c
+++ b/drivers/staging/gma500/psb_fb.c
@@ -1,5 +1,5 @@
/**************************************************************************
- * Copyright (c) 2007, Intel Corporation.
+ * Copyright (c) 2007-2011, Intel Corporation.
* All Rights Reserved.
*
* This program is free software; you can redistribute it and/or modify it
@@ -56,7 +56,6 @@ void *psbfb_vdc_reg(struct drm_device *dev)
dev_priv = (struct drm_psb_private *) dev->dev_private;
return dev_priv->vdc_reg;
}
-/*EXPORT_SYMBOL(psbfb_vdc_reg); */

static int psbfb_setcolreg(unsigned regno, unsigned red, unsigned green,
unsigned blue, unsigned transp,
diff --git a/drivers/staging/gma500/psb_fb.h b/drivers/staging/gma500/psb_fb.h
index fd7e51a..ed6e856 100644
--- a/drivers/staging/gma500/psb_fb.h
+++ b/drivers/staging/gma500/psb_fb.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2008, Intel Corporation
+ * Copyright (c) 2008-2011, Intel Corporation
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
@@ -41,7 +41,6 @@ struct psb_fbdev {
struct psb_framebuffer pfb;
};

-
#define to_psb_fb(x) container_of(x, struct psb_framebuffer, base)

extern int psb_intel_connector_clones(struct drm_device *dev, int type_mask);
diff --git a/drivers/staging/gma500/psb_gtt.h b/drivers/staging/gma500/psb_gtt.h
index 37287eb..7e1f21e 100644
--- a/drivers/staging/gma500/psb_gtt.h
+++ b/drivers/staging/gma500/psb_gtt.h
@@ -22,6 +22,7 @@

#include <drm/drmP.h>

+/* This wants cleaning up with respect to the psb_dev and un-needed stuff */
struct psb_gtt {
struct drm_device *dev;
uint32_t gatt_start;
@@ -41,9 +42,9 @@ extern void psb_gtt_takedown(struct drm_device *dev);

/* Each gtt_range describes an allocation in the GTT area */
struct gtt_range {
- struct resource resource;
- u32 offset;
- struct kref kref;
+ struct resource resource; /* Resource for our allocation */
+ u32 offset; /* GTT offset of our object */
+ struct kref kref; /* Can probably go FIXME - GEM kref will do */


struct drm_gem_object gem; /* GEM high level stuff */
int in_gart; /* Currently in the GART (ref ct) */

bool stolen; /* Backed from stolen RAM */

diff --git a/drivers/staging/gma500/psb_intel_drv.h b/drivers/staging/gma500/psb_intel_drv.h
index 6006ddd..75a95f7 100644
--- a/drivers/staging/gma500/psb_intel_drv.h
+++ b/drivers/staging/gma500/psb_intel_drv.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2009, Intel Corporation.
+ * Copyright (c) 2009-2011, Intel Corporation.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
@@ -26,11 +26,6 @@
#include <linux/gpio.h>

/*
- * MOORESTOWN defines
- */
-#define DELAY_TIME1 2000 /* 1000 = 1ms */
-
-/*
* Display related stuff
*/

@@ -61,16 +56,10 @@
#define INTEL_DVO_CHIP_TMDS 2
#define INTEL_DVO_CHIP_TVOUT 4

-enum mipi_panel_type {
- NSC_800X480 = 1,
- LGE_480X1024 = 2,
- TPO_864X480 = 3
-};
-
-/**
+/*
* Hold information useally put on the device driver privates here,
* since it needs to be shared across multiple of devices drivers privates.
-*/
+ */
struct psb_intel_mode_device {

/*
@@ -79,7 +68,7 @@ struct psb_intel_mode_device {
size_t(*bo_offset) (struct drm_device *dev, void *bo);

/*
- * Cursor
+ * Cursor (Can go ?)
*/
int cursor_needs_physical;

diff --git a/drivers/staging/gma500/psb_irq.h b/drivers/staging/gma500/psb_irq.h
index 3e56f33..216fda3 100644
--- a/drivers/staging/gma500/psb_irq.h
+++ b/drivers/staging/gma500/psb_irq.h
@@ -1,5 +1,5 @@
/**************************************************************************
- * Copyright (c) 2009, Intel Corporation.
+ * Copyright (c) 2009-2011, Intel Corporation.
* All Rights Reserved.
*
* This program is free software; you can redistribute it and/or modify it
@@ -34,10 +34,6 @@ int psb_irq_postinstall(struct drm_device *dev);
void psb_irq_uninstall(struct drm_device *dev);
irqreturn_t psb_irq_handler(DRM_IRQ_ARGS);

-void psb_irq_preinstall_islands(struct drm_device *dev, int hw_islands);
-int psb_irq_postinstall_islands(struct drm_device *dev, int hw_islands);
-void psb_irq_uninstall_islands(struct drm_device *dev, int hw_islands);
-
int psb_irq_enable_dpst(struct drm_device *dev);
int psb_irq_disable_dpst(struct drm_device *dev);
void psb_irq_turn_on_dpst(struct drm_device *dev);
@@ -46,4 +42,4 @@ int psb_enable_vblank(struct drm_device *dev, int pipe);
void psb_disable_vblank(struct drm_device *dev, int pipe);
u32 psb_get_vblank_counter(struct drm_device *dev, int pipe);

-#endif //_SYSIRQ_H_
+#endif /* _SYSIRQ_H_ */
diff --git a/drivers/staging/gma500/psb_powermgmt.c b/drivers/staging/gma500/psb_powermgmt.c
index 1495415..50f2234 100644
--- a/drivers/staging/gma500/psb_powermgmt.c
+++ b/drivers/staging/gma500/psb_powermgmt.c
@@ -1,7 +1,7 @@
/**************************************************************************
- * Copyright (c) 2009, Intel Corporation.
+ * Copyright (c) 2009-2011, Intel Corporation.
* All Rights Reserved.
-
+ *
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
diff --git a/drivers/staging/gma500/psb_powermgmt.h b/drivers/staging/gma500/psb_powermgmt.h
index e005229..333b28d 100644
--- a/drivers/staging/gma500/psb_powermgmt.h
+++ b/drivers/staging/gma500/psb_powermgmt.h
@@ -1,5 +1,5 @@
/**************************************************************************
- * Copyright (c) 2009, Intel Corporation.
+ * Copyright (c) 2009-2011, Intel Corporation.
* All Rights Reserved.

* Permission is hereby granted, free of charge, to any person obtaining a
diff --git a/drivers/staging/gma500/psb_reg.h b/drivers/staging/gma500/psb_reg.h
index 9ad4989..529fda8 100644
--- a/drivers/staging/gma500/psb_reg.h
+++ b/drivers/staging/gma500/psb_reg.h
@@ -573,7 +573,7 @@
#define MDFLD_PWRGT_DISPLAY_C_CNTR 0x00030000
#define MDFLD_PWRGT_DISP_MIPI_CNTR 0x000c0000
#define MDFLD_PWRGT_DISPLAY_CNTR (MDFLD_PWRGT_DISPLAY_A_CNTR | MDFLD_PWRGT_DISPLAY_B_CNTR | MDFLD_PWRGT_DISPLAY_C_CNTR | MDFLD_PWRGT_DISP_MIPI_CNTR)// 0x000fc00c
-// Display SSS register bits are different in A0 vs. B0
+/* Display SSS register bits are different in A0 vs. B0 */
#define PSB_PWRGT_GFX_MASK 0x3
#define MDFLD_PWRGT_DISPLAY_A_STS 0x000000c0
#define MDFLD_PWRGT_DISPLAY_B_STS 0x00000300

Alan Cox

unread,
Jun 8, 2011, 6:14:50 AM6/8/11
to gr...@kroah.com, linux-...@vger.kernel.org, dri-...@lists.freedesktop.org
From: Alan Cox <al...@linux.intel.com>

We have a FIXME to do the power management for which the framework now
exists, and we also need to deal with an erratum. Some operations exactly 8
pixels wide or high fail. The work around is to do two smaller ones (see
the Intel released X driver bits) but for console quite frankly if it's
8bits wide and/or high its not worth it so fall back.

Signed-off-by: Alan Cox <al...@linux.intel.com>
---

drivers/staging/gma500/psb_2d.c | 19 +++++++++++++------
1 files changed, 13 insertions(+), 6 deletions(-)

diff --git a/drivers/staging/gma500/psb_2d.c b/drivers/staging/gma500/psb_2d.c
index c3d7085..494bad5 100644
--- a/drivers/staging/gma500/psb_2d.c
+++ b/drivers/staging/gma500/psb_2d.c
@@ -183,10 +183,14 @@ static void psbfb_fillrect_accel(struct fb_info *info,
cfb_fillrect(info, r);
return;
}
-
+ if (!gma_power_begin(dev, false)) {
+ cfb_fillrect(info, r);
+ return;
+ }
psb_accel_2d_fillrect(dev_priv,
offset, stride, format,
r->dx, r->dy, r->width, r->height, r->color);
+ gma_power_end(dev);
}

void psbfb_fillrect(struct fb_info *info,
@@ -198,9 +202,7 @@ void psbfb_fillrect(struct fb_info *info,
if (1 || (info->flags & FBINFO_HWACCEL_DISABLED))
return cfb_fillrect(info, rect);

- /*psb_check_power_state(dev, PSB_DEVICE_SGX); */
psbfb_fillrect_accel(info, rect);
- /* Drop power again here on MRST FIXMEAC */
}

static u32 psb_accel_2d_copy_direction(int xdir, int ydir)
@@ -331,10 +333,15 @@ static void psbfb_copyarea_accel(struct fb_info *info,
return;
}

+ if (!gma_power_begin(dev, false)) {
+ cfb_copyarea(info, a);
+ return;
+ }
psb_accel_2d_copy(dev_priv,
offset, stride, src_format,
offset, stride, dst_format,
a->sx, a->sy, a->dx, a->dy, a->width, a->height);
+ gma_power_end(dev);
}

void psbfb_copyarea(struct fb_info *info,
@@ -343,12 +350,12 @@ void psbfb_copyarea(struct fb_info *info,
if (unlikely(info->state != FBINFO_STATE_RUNNING))
return;

- if (info->flags & FBINFO_HWACCEL_DISABLED)
+ /* Avoid the 8 pixel erratum */
+ if (region->width == 8 || region->height == 8 ||
+ (info->flags & FBINFO_HWACCEL_DISABLED))
return cfb_copyarea(info, region);

- /* psb_check_power_state(dev, PSB_DEVICE_SGX); */
psbfb_copyarea_accel(info, region);
- /* Need to power back off here for MRST FIXMEAC */


}

void psbfb_imageblit(struct fb_info *info, const struct fb_image *image)

--

Alan Cox

unread,
Jun 8, 2011, 6:15:04 AM6/8/11
to gr...@kroah.com, linux-...@vger.kernel.org, dri-...@lists.freedesktop.org
From: Alan Cox <al...@linux.intel.com>

We don't seem to need this for our task.

Signed-off-by: Alan Cox <al...@linux.intel.com>
---

drivers/staging/gma500/psb_drv.c | 6 ----
drivers/staging/gma500/psb_gtt.c | 62 ++++++++++++--------------------------
2 files changed, 19 insertions(+), 49 deletions(-)

diff --git a/drivers/staging/gma500/psb_drv.c b/drivers/staging/gma500/psb_drv.c
index 9bd0a5d..ab1da30 100644
--- a/drivers/staging/gma500/psb_drv.c
+++ b/drivers/staging/gma500/psb_drv.c
@@ -409,8 +409,6 @@ static int psb_do_init(struct drm_device *dev)
struct psb_gtt *pg = dev_priv->pg;

uint32_t stolen_gtt;
- uint32_t tt_start;
- uint32_t tt_pages;

int ret = -ENOMEM;

@@ -449,10 +447,6 @@ static int psb_do_init(struct drm_device *dev)

spin_lock_init(&dev_priv->irqmask_lock);

- tt_pages = (pg->gatt_pages < PSB_TT_PRIV0_PLIMIT) ?
- pg->gatt_pages : PSB_TT_PRIV0_PLIMIT;
- tt_start = dev_priv->gatt_free_offset - pg->mmu_gatt_start;
- tt_pages -= tt_start >> PAGE_SHIFT;
/* FIXME: can we kill ta_mem_size ? */
dev_priv->sizes.ta_mem_size = 0;

diff --git a/drivers/staging/gma500/psb_gtt.c b/drivers/staging/gma500/psb_gtt.c
index 5a296e1..8fcb833 100644
--- a/drivers/staging/gma500/psb_gtt.c
+++ b/drivers/staging/gma500/psb_gtt.c
@@ -138,8 +138,6 @@ static void psb_gtt_remove(struct drm_device *dev, struct gtt_range *r)
*
* 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
- *
- * FIXME: Do we need to cache flush when we update the GTT
*/


static int psb_gtt_attach_pages(struct gtt_range *gt)

{
@@ -185,8 +183,6 @@ err:


* Undo the effect of psb_gtt_attach_pages. At this point the pages

* must have been removed from the GTT as they could now be paged out
* and move bus address.

- *
- * FIXME: Do we need to cache flush when we update the GTT
*/


static void psb_gtt_detach_pages(struct gtt_range *gt)

{
@@ -194,7 +190,6 @@ static void psb_gtt_detach_pages(struct gtt_range *gt)


for (i = 0; i < gt->npage; i++) {
/* FIXME: do we need to force dirty */
set_page_dirty(gt->pages[i]);

- /* Undo the reference we took when populating the table */
page_cache_release(gt->pages[i]);
}
kfree(gt->pages);
@@ -384,7 +379,6 @@ void psb_gtt_takedown(struct drm_device *dev)
{


struct drm_psb_private *dev_priv = dev->dev_private;

- /* FIXME: iounmap dev_priv->vram_addr etc */
if (dev_priv->gtt_map) {
iounmap(dev_priv->gtt_map);
dev_priv->gtt_map = NULL;
@@ -395,6 +389,8 @@ void psb_gtt_takedown(struct drm_device *dev)
PSB_WVDC32(dev_priv->pge_ctl, PSB_PGETBL_CTL);
(void) PSB_RVDC32(PSB_PGETBL_CTL);
}
+ if (dev_priv->vram_addr)
+ iounmap(dev_priv->gtt_map);
kfree(dev_priv->pg);
dev_priv->pg = NULL;
}
@@ -407,8 +403,6 @@ int psb_gtt_init(struct drm_device *dev, int resume)
unsigned i, num_pages;
unsigned pfn_base;
uint32_t vram_pages;
- uint32_t tt_pages;
- uint32_t *ttm_gtt_map;
uint32_t dvmt_mode = 0;
struct psb_gtt *pg;

@@ -421,6 +415,7 @@ int psb_gtt_init(struct drm_device *dev, int resume)
if (pg == NULL)
return -ENOMEM;

+ /* Enable the GTT */


pci_read_config_word(dev->pdev, PSB_GMCH_CTRL, &dev_priv->gmch_ctrl);
pci_write_config_word(dev->pdev, PSB_GMCH_CTRL,

dev_priv->gmch_ctrl | _PSB_GMCH_ENABLED);
@@ -431,30 +426,26 @@ int psb_gtt_init(struct drm_device *dev, int resume)

/* The root resource we allocate address space from */
dev_priv->gtt_mem = &dev->pdev->resource[PSB_GATT_RESOURCE];
-
dev_priv->gtt_initialized = 1;

pg->gtt_phys_start = dev_priv->pge_ctl & PAGE_MASK;

pg->gatt_start = pci_resource_start(dev->pdev, PSB_GATT_RESOURCE);
- /* fix me: video mmu has hw bug to access 0x0D0000000,
- * then make gatt start at 0x0e000,0000 */
+ /*
+ * FIXME: video mmu has hw bug to access 0x0D0000000,
+ * then make gatt start at 0x0e000,0000
+ */
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;
- pg->gatt_pages = pci_resource_len(dev->pdev, PSB_GATT_RESOURCE)
- >> PAGE_SHIFT;
+ gtt_pages = pci_resource_len(dev->pdev, PSB_GTT_RESOURCE) >> PAGE_SHIFT;
+ pg->gatt_pages = pci_resource_len(dev->pdev, PSB_GATT_RESOURCE) >> PAGE_SHIFT;

pci_read_config_dword(dev->pdev, PSB_BSM, &dev_priv->stolen_base);
vram_stolen_size = pg->gtt_phys_start - dev_priv->stolen_base - PAGE_SIZE;

stolen_size = vram_stolen_size;

- printk(KERN_INFO"GMMADR(region 0) start: 0x%08x (%dM).\n",
- pg->gatt_start, pg->gatt_pages/256);
- printk(KERN_INFO"GTTADR(region 3) start: 0x%08x (can map %dM RAM), and actual RAM base 0x%08x.\n",
- pg->gtt_start, gtt_pages * 4, pg->gtt_phys_start);
printk(KERN_INFO "Stolen memory information\n");
printk(KERN_INFO " base in RAM: 0x%x\n", dev_priv->stolen_base);
printk(KERN_INFO " size: %luK, calculated by (GTT RAM base) - (Stolen base), seems wrong\n",
@@ -473,8 +464,11 @@ int psb_gtt_init(struct drm_device *dev, int resume)
pg->gtt_pages = gtt_pages;
pg->stolen_size = stolen_size;
dev_priv->vram_stolen_size = vram_stolen_size;
- dev_priv->gtt_map =
- ioremap_nocache(pg->gtt_phys_start, gtt_pages << PAGE_SHIFT);
+
+ /*
+ * Map the GTT and the stolen memory area
+ */
+ dev_priv->gtt_map = ioremap_nocache(pg->gtt_phys_start, gtt_pages << PAGE_SHIFT);
if (!dev_priv->gtt_map) {
DRM_ERROR("Failure to map gtt.\n");
ret = -ENOMEM;
@@ -488,15 +482,8 @@ int psb_gtt_init(struct drm_device *dev, int resume)
goto out_err;
}

- DRM_DEBUG("gma500: vram kernel virtual address %p\n", dev_priv->vram_addr);
-
- tt_pages = (pg->gatt_pages < PSB_TT_PRIV0_PLIMIT) ?
- (pg->gatt_pages) : PSB_TT_PRIV0_PLIMIT;
-
- ttm_gtt_map = dev_priv->gtt_map + tt_pages / 2;
-
/*
- * insert vram stolen pages.
+ * Insert vram stolen pages into the GTT
*/

pfn_base = dev_priv->stolen_base >> PAGE_SHIFT;
@@ -509,26 +496,15 @@ int psb_gtt_init(struct drm_device *dev, int resume)
}

/*
- * Init rest of gtt managed by IMG.
- */
- pfn_base = page_to_pfn(dev_priv->scratch_page);
- pte = psb_gtt_mask_pte(pfn_base, 0);
- for (; i < tt_pages / 2 - 1; ++i)
- iowrite32(pte, dev_priv->gtt_map + i);
-
- /*
- * Init rest of gtt managed by TTM.
+ * Init rest of GTT to the scratch page to avoid accidents or scribbles
*/

pfn_base = page_to_pfn(dev_priv->scratch_page);
pte = psb_gtt_mask_pte(pfn_base, 0);
- PSB_DEBUG_INIT("Initializing the rest of a total "
- "of %d gtt pages.\n", pg->gatt_pages);
+ for (; i < gtt_pages; ++i)
+ iowrite32(pte, dev_priv->gtt_map + i);

- for (; i < pg->gatt_pages - tt_pages / 2; ++i)
- iowrite32(pte, ttm_gtt_map + i);
(void) ioread32(dev_priv->gtt_map + i - 1);
-
return 0;

out_err:

Alan Cox

unread,
Jun 8, 2011, 6:15:19 AM6/8/11
to gr...@kroah.com, linux-...@vger.kernel.org, dri-...@lists.freedesktop.org
From: Alan Cox <al...@linux.intel.com>

Lose all the PSB debug gunge. We can replace it with dev_dbg() like normal
drivers if and when we need debug on stuff.

Signed-off-by: Alan Cox <al...@linux.intel.com>
---

drivers/staging/gma500/mrst_crtc.c | 23 ++----
drivers/staging/gma500/mrst_lvds.c | 12 +--
drivers/staging/gma500/psb_bl.c | 8 --
drivers/staging/gma500/psb_drv.c | 33 +++------
drivers/staging/gma500/psb_drv.h | 96 +++-----------------------
drivers/staging/gma500/psb_fb.c | 34 +--------
drivers/staging/gma500/psb_gem.c | 6 +-
drivers/staging/gma500/psb_gtt.c | 6 +-
drivers/staging/gma500/psb_intel_bios.c | 17 +----
drivers/staging/gma500/psb_intel_display.c | 99 +++------------------------
drivers/staging/gma500/psb_intel_lvds.c | 53 ++------------
drivers/staging/gma500/psb_intel_opregion.c | 7 --
drivers/staging/gma500/psb_intel_sdvo.c | 34 ++++-----
drivers/staging/gma500/psb_irq.c | 33 ++-------
14 files changed, 87 insertions(+), 374 deletions(-)

diff --git a/drivers/staging/gma500/mrst_crtc.c b/drivers/staging/gma500/mrst_crtc.c
index fd97c80..fb9f2a2 100644
--- a/drivers/staging/gma500/mrst_crtc.c
+++ b/drivers/staging/gma500/mrst_crtc.c
@@ -103,7 +103,7 @@ static const struct mrst_limit_t *mrst_limit(struct drm_crtc *crtc)
}
} else {
limit = NULL;
- PSB_DEBUG_ENTRY("mrst_limit Wrong display type.\n");
+ dev_err(dev->dev, "mrst_limit Wrong display type.\n");
}

return limit;
@@ -117,7 +117,7 @@ static void mrst_clock(int refclk, struct mrst_clock_t *clock)

void mrstPrintPll(char *prefix, struct mrst_clock_t *clock)
{
- PSB_DEBUG_ENTRY("%s: dotclock = %d, m = %d, p1 = %d.\n",
+ pr_debug("%s: dotclock = %d, m = %d, p1 = %d.\n",
prefix, clock->dot, clock->m, clock->p1);
}

@@ -149,8 +149,7 @@ mrstFindBestPLL(struct drm_crtc *crtc, int target, int refclk,
}
}
}
- DRM_DEBUG("mrstFindBestPLL err = %d.\n", err);
-
+ dev_dbg(crtc->dev->dev, "mrstFindBestPLL err = %d.\n", err);
return err != target;
}

@@ -172,8 +171,6 @@ static void mrst_crtc_dpms(struct drm_crtc *crtc, int mode)
u32 temp;
bool enabled;

- PSB_DEBUG_ENTRY("mode = %d, pipe = %d\n", mode, pipe);
-
if (!gma_power_begin(dev, true))
return;

@@ -320,8 +317,6 @@ static int mrst_crtc_mode_set(struct drm_crtc *crtc,
uint64_t scalingType = DRM_MODE_SCALE_FULLSCREEN;
struct drm_encoder *encoder;

- PSB_DEBUG_ENTRY("pipe = 0x%x\n", pipe);
-
if (!gma_power_begin(dev, true))
return 0;

@@ -446,10 +441,9 @@ static int mrst_crtc_mode_set(struct drm_crtc *crtc,
ok = mrstFindBestPLL(crtc, adjusted_mode->clock, refclk, &clock);

if (!ok) {
- PSB_DEBUG_ENTRY(
- "mrstFindBestPLL fail in mrst_crtc_mode_set.\n");
+ dev_dbg(dev->dev, "mrstFindBestPLL fail in mrst_crtc_mode_set.\n");
} else {
- PSB_DEBUG_ENTRY("mrst_crtc_mode_set pixel clock = %d,"
+ dev_dbg(dev->dev, "mrst_crtc_mode_set pixel clock = %d,"
"m = %x, p1 = %x.\n", clock.dot, clock.m,
clock.p1);
}
@@ -540,11 +534,9 @@ int mrst_pipe_set_base(struct drm_crtc *crtc,
u32 dspcntr;
int ret = 0;

- PSB_DEBUG_ENTRY("\n");
-


/* no fb bound */
if (!crtc->fb) {

- DRM_DEBUG("No FB bound\n");
+ dev_dbg(dev->dev, "No FB bound\n");
return 0;
}

@@ -574,13 +566,12 @@ int mrst_pipe_set_base(struct drm_crtc *crtc,
dspcntr |= DISPPLANE_32BPP_NO_ALPHA;
break;
default:
- DRM_ERROR("Unknown color depth\n");
+ dev_err(dev->dev, "Unknown color depth\n");
ret = -EINVAL;
goto pipe_set_base_exit;
}
REG_WRITE(dspcntr_reg, dspcntr);

- DRM_DEBUG("Writing base %08lX %08lX %d %d\n", start, offset, x, y);
if (0 /* FIXMEAC - check what PSB needs */) {
REG_WRITE(dspbase, offset);
REG_READ(dspbase);
diff --git a/drivers/staging/gma500/mrst_lvds.c b/drivers/staging/gma500/mrst_lvds.c
index 22ea00e..aac80cc 100644
--- a/drivers/staging/gma500/mrst_lvds.c
+++ b/drivers/staging/gma500/mrst_lvds.c
@@ -47,7 +47,6 @@ static void mrst_lvds_set_power(struct drm_device *dev,
{
u32 pp_status;


struct drm_psb_private *dev_priv = dev->dev_private;

- PSB_DEBUG_ENTRY("\n");

if (!gma_power_begin(dev, true))
return;
@@ -77,8 +76,6 @@ static void mrst_lvds_dpms(struct drm_encoder *encoder, int mode)
struct drm_device *dev = encoder->dev;
struct psb_intel_output *output = enc_to_psb_intel_output(encoder);

- PSB_DEBUG_ENTRY("\n");
-
if (mode == DRM_MODE_DPMS_ON)
mrst_lvds_set_power(dev, output, true);
else
@@ -97,8 +94,6 @@ static void mrst_lvds_mode_set(struct drm_encoder *encoder,
u32 lvds_port;
uint64_t v = DRM_MODE_SCALE_FULLSCREEN;

- PSB_DEBUG_ENTRY("\n");
-
if (!gma_power_begin(dev, true))
return;

@@ -252,8 +247,6 @@ void mrst_lvds_init(struct drm_device *dev,
struct i2c_adapter *i2c_adap;
struct drm_display_mode *scan; /* *modes, *bios_mode; */

- PSB_DEBUG_ENTRY("\n");
-
psb_intel_output = kzalloc(sizeof(struct psb_intel_output), GFP_KERNEL);
if (!psb_intel_output)
return;
@@ -348,8 +341,7 @@ void mrst_lvds_init(struct drm_device *dev,

/* If we still don't have a mode after all that, give up. */
if (!mode_dev->panel_fixed_mode) {
- DRM_DEBUG
- ("Found no modes on the lvds, ignoring the LVDS\n");
+ dev_err(dev->dev, "Found no modes on the lvds, ignoring the LVDS\n");
goto failed_find;
}

@@ -358,7 +350,7 @@ out:
return;

failed_find:
- DRM_DEBUG("No LVDS modes found, disabling.\n");
+ dev_dbg(dev->dev, "No LVDS modes found, disabling.\n");
if (psb_intel_output->ddc_bus)
psb_intel_i2c_destroy(psb_intel_output->ddc_bus);

diff --git a/drivers/staging/gma500/psb_bl.c b/drivers/staging/gma500/psb_bl.c
index 2f9674d..4a00047 100644
--- a/drivers/staging/gma500/psb_bl.c
+++ b/drivers/staging/gma500/psb_bl.c
@@ -56,8 +56,6 @@ int psb_set_brightness(struct backlight_device *bd)
struct drm_device *dev = bl_get_data(psb_backlight_device);
int level = bd->props.brightness;

- DRM_DEBUG_DRIVER("backlight level set to %d\n", level);
-
/* Percentage 1-100% being valid */
if (level < 1)
level = 1;
@@ -75,8 +73,6 @@ int mrst_set_brightness(struct backlight_device *bd)
u32 blc_pwm_ctl;
u32 max_pwm_blc;

- DRM_DEBUG_DRIVER("backlight level set to %d\n", level);
-
/* Percentage 1-100% being valid */
if (level < 1)
level = 1;
@@ -111,8 +107,6 @@ int mrst_set_brightness(struct backlight_device *bd)

int psb_get_brightness(struct backlight_device *bd)
{
- DRM_DEBUG_DRIVER("brightness = 0x%x\n", psb_brightness);
-
/* return locally cached var instead of HW read (due to DPST etc.) */
/* FIXME: ideally return actual value in case firmware fiddled with
it */
@@ -144,7 +138,7 @@ static int device_backlight_init(struct drm_device *dev)
} else {
/* get bl_max_freq and pol from dev_priv*/
if (!dev_priv->lvds_bl) {
- DRM_ERROR("Has no valid LVDS backlight info\n");
+ dev_err(dev->dev, "Has no valid LVDS backlight info\n");
return 1;
}
bl_max_freq = dev_priv->lvds_bl->freq;
diff --git a/drivers/staging/gma500/psb_drv.c b/drivers/staging/gma500/psb_drv.c
index ab1da30..6ea06dd 100644
--- a/drivers/staging/gma500/psb_drv.c
+++ b/drivers/staging/gma500/psb_drv.c
@@ -35,17 +35,14 @@
#include <linux/pm_runtime.h>
#include <acpi/video.h>

-int drm_psb_debug;
static int drm_psb_trap_pagefaults;

int drm_psb_no_fb;

static int psb_probe(struct pci_dev *pdev, const struct pci_device_id *ent);

-MODULE_PARM_DESC(debug, "Enable debug output");
MODULE_PARM_DESC(no_fb, "Disable FBdev");
MODULE_PARM_DESC(trap_pagefaults, "Error and reset on MMU pagefaults");
-module_param_named(debug, drm_psb_debug, int, 0600);
module_param_named(no_fb, drm_psb_no_fb, int, 0600);
module_param_named(trap_pagefaults, drm_psb_trap_pagefaults, int, 0600);

@@ -215,7 +212,8 @@ void mrst_get_fuse_settings(struct drm_device *dev)
dev_priv->core_freq = 166;
break;
default:
- DRM_ERROR("Invalid SKU values, SKU value = 0x%08x\n", fuse_value_tmp);
+ dev_warn(dev->dev, "Invalid SKU values, SKU value = 0x%08x\n",
+ fuse_value_tmp);
dev_priv->core_freq = 0;
}
DRM_INFO("LNC core clk is %dMHz.\n", dev_priv->core_freq);
@@ -231,7 +229,8 @@ void mid_get_pci_revID (struct drm_psb_private *dev_priv)
pci_read_config_dword(pci_gfx_root, 0x08, &platform_rev_id);
dev_priv->platform_rev_id = (uint8_t) platform_rev_id;
pci_dev_put(pci_gfx_root);
- PSB_DEBUG_ENTRY("platform_rev_id is %x\n", dev_priv->platform_rev_id);
+ dev_info(dev_priv->dev->dev, "platform_rev_id is %x\n",
+ dev_priv->platform_rev_id);
}

void mrst_get_vbt_data(struct drm_psb_private *dev_priv)
@@ -413,7 +412,7 @@ static int psb_do_init(struct drm_device *dev)
int ret = -ENOMEM;

if (pg->mmu_gatt_start & 0x0FFFFFFF) {
- DRM_ERROR("Gatt must be 256M aligned. This is a bug.\n");
+ dev_err(dev->dev, "Gatt must be 256M aligned. This is a bug.\n");
ret = -EINVAL;
goto out_err;
}
@@ -447,9 +446,6 @@ static int psb_do_init(struct drm_device *dev)

spin_lock_init(&dev_priv->irqmask_lock);

- /* FIXME: can we kill ta_mem_size ? */
- dev_priv->sizes.ta_mem_size = 0;
-
PSB_WSGX32(0x00000000, PSB_CR_BIF_BANK0);
PSB_WSGX32(0x00000000, PSB_CR_BIF_BANK1);
PSB_RSGX32(PSB_CR_BIF_BANK1);
@@ -553,7 +549,6 @@ static int psb_driver_load(struct drm_device *dev, unsigned long chipset)
dev->dev_private = (void *) dev_priv;
dev_priv->chipset = chipset;

- PSB_DEBUG_INIT("Mapping MMIO\n");
resource_start = pci_resource_start(dev->pdev, PSB_MMIO_RESOURCE);

dev_priv->vdc_reg =
@@ -679,7 +674,6 @@ static int psb_driver_load(struct drm_device *dev, unsigned long chipset)
pm_runtime_set_active(&dev->pdev->dev);
#endif
/*Intel drm driver load is done, continue doing pvr load*/
- DRM_DEBUG("Pvr driver load\n");
return 0;
out_err:
psb_driver_unload(dev);
@@ -721,7 +715,7 @@ static int psb_dc_state_ioctl(struct drm_device *dev, void * data,
obj = drm_mode_object_find(dev, obj_id,
DRM_MODE_OBJECT_CRTC);
if (!obj) {
- DRM_DEBUG("Invalid CRTC object.\n");
+ dev_dbg(dev->dev, "Invalid CRTC object.\n");
return -EINVAL;
}

@@ -741,7 +735,7 @@ static int psb_dc_state_ioctl(struct drm_device *dev, void * data,
obj = drm_mode_object_find(dev, obj_id,
DRM_MODE_OBJECT_CONNECTOR);
if (!obj) {
- DRM_DEBUG("Invalid connector id.\n");
+ dev_dbg(dev->dev, "Invalid connector id.\n");
return -EINVAL;
}

@@ -753,8 +747,6 @@ static int psb_dc_state_ioctl(struct drm_device *dev, void * data,

return 0;
}
-
- DRM_DEBUG("Bad flags 0x%x\n", flags);
return -EINVAL;
}

@@ -832,7 +824,7 @@ static int psb_gamma_ioctl(struct drm_device *dev, void *data,
obj_id = lut_arg->output_id;
obj = drm_mode_object_find(dev, obj_id, DRM_MODE_OBJECT_CONNECTOR);
if (!obj) {
- DRM_DEBUG("Invalid Connector object.\n");
+ dev_dbg(dev->dev, "Invalid Connector object.\n");
return -EINVAL;
}

@@ -873,7 +865,7 @@ static int psb_mode_operation_ioctl(struct drm_device *dev, void *data,
case PSB_MODE_OPERATION_SET_DC_BASE:
obj = drm_mode_object_find(dev, obj_id, DRM_MODE_OBJECT_FB);
if (!obj) {
- DRM_ERROR("Invalid FB id %d\n", obj_id);
+ dev_dbg(dev->dev, "Invalid FB id %d\n", obj_id);
return -EINVAL;
}

@@ -945,7 +937,7 @@ mode_op_out:
return ret;

default:
- DRM_DEBUG("Unsupported psb mode operation");
+ dev_dbg(dev->dev, "Unsupported psb mode operation\n");
return -EOPNOTSUPP;
}

@@ -1336,9 +1328,6 @@ static long psb_unlocked_ioctl(struct file *filp, unsigned int cmd,
struct drm_device *dev = file_priv->minor->dev;


struct drm_psb_private *dev_priv = dev->dev_private;

static unsigned int runtime_allowed;
- unsigned int nr = DRM_IOCTL_NR(cmd);
-
- DRM_DEBUG("cmd = %x, nr = %x\n", cmd, nr);

if (runtime_allowed == 1 && dev_priv->is_lvds_on) {
runtime_allowed++;
@@ -1439,7 +1428,7 @@ 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))
- DRM_ERROR("Enable MSI failed!\n");
+ dev_warn(&pdev->dev, "Enable MSI failed!\n");
return drm_get_pci_dev(pdev, ent, &driver);
}

diff --git a/drivers/staging/gma500/psb_drv.h b/drivers/staging/gma500/psb_drv.h
index c0468ee..45752aa 100644
--- a/drivers/staging/gma500/psb_drv.h
+++ b/drivers/staging/gma500/psb_drv.h
@@ -659,54 +659,12 @@ extern int psb_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf);
#define PSB_D_MSVDX (1 << 9)
#define PSB_D_TOPAZ (1 << 10)

-#ifndef DRM_DEBUG_CODE
-/* To enable debug printout, set drm_psb_debug in psb_drv.c
- * to any combination of above print flags.
- */
-/* #define DRM_DEBUG_CODE 2 */
-#endif
-
-extern int drm_psb_debug;
extern int drm_psb_no_fb;
extern int drm_idle_check_interval;

-#define PSB_DEBUG_GENERAL(_fmt, _arg...) \
- PSB_DEBUG(PSB_D_GENERAL, _fmt, ##_arg)
-#define PSB_DEBUG_INIT(_fmt, _arg...) \
- PSB_DEBUG(PSB_D_INIT, _fmt, ##_arg)
-#define PSB_DEBUG_IRQ(_fmt, _arg...) \
- PSB_DEBUG(PSB_D_IRQ, _fmt, ##_arg)
-#define PSB_DEBUG_ENTRY(_fmt, _arg...) \
- PSB_DEBUG(PSB_D_ENTRY, _fmt, ##_arg)
-#define PSB_DEBUG_HV(_fmt, _arg...) \
- PSB_DEBUG(PSB_D_HV, _fmt, ##_arg)
-#define PSB_DEBUG_DBI_BF(_fmt, _arg...) \
- PSB_DEBUG(PSB_D_DBI_BF, _fmt, ##_arg)
-#define PSB_DEBUG_PM(_fmt, _arg...) \
- PSB_DEBUG(PSB_D_PM, _fmt, ##_arg)
-#define PSB_DEBUG_RENDER(_fmt, _arg...) \
- PSB_DEBUG(PSB_D_RENDER, _fmt, ##_arg)
-#define PSB_DEBUG_REG(_fmt, _arg...) \
- PSB_DEBUG(PSB_D_REG, _fmt, ##_arg)
-#define PSB_DEBUG_MSVDX(_fmt, _arg...) \
- PSB_DEBUG(PSB_D_MSVDX, _fmt, ##_arg)
-#define PSB_DEBUG_TOPAZ(_fmt, _arg...) \
- PSB_DEBUG(PSB_D_TOPAZ, _fmt, ##_arg)
-
-#if DRM_DEBUG_CODE
-#define PSB_DEBUG(_flag, _fmt, _arg...) \
- do { \
- if (unlikely((_flag) & drm_psb_debug)) \
- printk(KERN_DEBUG \
- "[psb:0x%02x:%s] " _fmt , _flag, \
- __func__ , ##_arg); \
- } while (0)
-#else
-#define PSB_DEBUG(_fmt, _arg...) do { } while (0)
-#endif

/*
- *Utilities
+ * Utilities
*/



static inline u32 MRST_MSG_READ32(uint port, uint offset)

@@ -749,19 +707,15 @@ static inline void MDFLD_MSG_WRITE32(uint port, uint offset, u32 value)
static inline uint32_t REGISTER_READ(struct drm_device *dev, uint32_t reg)


{
struct drm_psb_private *dev_priv = dev->dev_private;

- int reg_val = ioread32(dev_priv->vdc_reg + (reg));
- PSB_DEBUG_REG("reg = 0x%x. reg_val = 0x%x. \n", reg, reg_val);
- return reg_val;
+ return ioread32(dev_priv->vdc_reg + reg);
}

#define REG_READ(reg) REGISTER_READ(dev, (reg))
+
static inline void REGISTER_WRITE(struct drm_device *dev, uint32_t reg,
uint32_t val)


{
struct drm_psb_private *dev_priv = dev->dev_private;

- if ((reg < 0x70084 || reg >0x70088) && (reg < 0xa000 || reg >0xa3ff))
- PSB_DEBUG_REG("reg = 0x%x, val = 0x%x. \n", reg, val);
-
iowrite32((val), dev_priv->vdc_reg + (reg));
}

@@ -771,9 +725,6 @@ static inline void REGISTER_WRITE16(struct drm_device *dev,
uint32_t reg, uint32_t val)


{
struct drm_psb_private *dev_priv = dev->dev_private;
-

- PSB_DEBUG_REG("reg = 0x%x, val = 0x%x. \n", reg, val);
-
iowrite16((val), dev_priv->vdc_reg + (reg));
}

@@ -783,20 +734,13 @@ static inline void REGISTER_WRITE8(struct drm_device *dev,
uint32_t reg, uint32_t val)


{
struct drm_psb_private *dev_priv = dev->dev_private;
-

- PSB_DEBUG_REG("reg = 0x%x, val = 0x%x. \n", reg, val);
-
iowrite8((val), dev_priv->vdc_reg + (reg));
}

-#define REG_WRITE8(reg, val) REGISTER_WRITE8(dev, (reg), (val))
+#define REG_WRITE8(reg, val) REGISTER_WRITE8(dev, (reg), (val))

-#define PSB_ALIGN_TO(_val, _align) \
- (((_val) + ((_align) - 1)) & ~((_align) - 1))
-#define PSB_WVDC32(_val, _offs) \
- iowrite32(_val, dev_priv->vdc_reg + (_offs))
-#define PSB_RVDC32(_offs) \
- ioread32(dev_priv->vdc_reg + (_offs))
+#define PSB_WVDC32(_val, _offs) iowrite32(_val, dev_priv->vdc_reg + (_offs))
+#define PSB_RVDC32(_offs) ioread32(dev_priv->vdc_reg + (_offs))

/* #define TRAP_SGX_PM_FAULT 1 */
#ifdef TRAP_SGX_PM_FAULT
@@ -810,33 +754,13 @@ static inline void REGISTER_WRITE8(struct drm_device *dev,
ioread32(dev_priv->sgx_reg + (_offs)); \
})
#else
-#define PSB_RSGX32(_offs) \
- ioread32(dev_priv->sgx_reg + (_offs))
+#define PSB_RSGX32(_offs) ioread32(dev_priv->sgx_reg + (_offs))
#endif
-#define PSB_WSGX32(_val, _offs) \
- iowrite32(_val, dev_priv->sgx_reg + (_offs))
+#define PSB_WSGX32(_val, _offs) iowrite32(_val, dev_priv->sgx_reg + (_offs))

#define MSVDX_REG_DUMP 0
-#if MSVDX_REG_DUMP
-
-#define PSB_WMSVDX32(_val, _offs) \
- printk("MSVDX: write %08x to reg 0x%08x\n", (unsigned int)(_val), (unsigned int)(_offs));\
- iowrite32(_val, dev_priv->msvdx_reg + (_offs))
-#define PSB_RMSVDX32(_offs) \
- ioread32(dev_priv->msvdx_reg + (_offs))
-
-#else
-
-#define PSB_WMSVDX32(_val, _offs) \
- iowrite32(_val, dev_priv->msvdx_reg + (_offs))
-#define PSB_RMSVDX32(_offs) \
- ioread32(dev_priv->msvdx_reg + (_offs))
-
-#endif

-#define PSB_ALPL(_val, _base) \
- (((_val) >> (_base ## _ALIGNSHIFT)) << (_base ## _SHIFT))
-#define PSB_ALPLM(_val, _base) \
- ((((_val) >> (_base ## _ALIGNSHIFT)) << (_base ## _SHIFT)) & (_base ## _MASK))
+#define PSB_WMSVDX32(_val, _offs) iowrite32(_val, dev_priv->msvdx_reg + (_offs))
+#define PSB_RMSVDX32(_offs) ioread32(dev_priv->msvdx_reg + (_offs))

#endif
diff --git a/drivers/staging/gma500/psb_fb.c b/drivers/staging/gma500/psb_fb.c
index 0a77abf..988f4db 100644
--- a/drivers/staging/gma500/psb_fb.c
+++ b/drivers/staging/gma500/psb_fb.c
@@ -100,7 +100,6 @@ static int psbfb_kms_off(struct drm_device *dev, int suspend)
{
struct drm_framebuffer *fb = 0;


struct psb_framebuffer *psbfb = to_psb_fb(fb);

- DRM_DEBUG("psbfb_kms_off_ioctl\n");

mutex_lock(&dev->mode_config.mutex);
list_for_each_entry(fb, &dev->mode_config.fb_list, head) {
@@ -134,8 +133,6 @@ static int psbfb_kms_on(struct drm_device *dev, int resume)
struct drm_framebuffer *fb = 0;


struct psb_framebuffer *psbfb = to_psb_fb(fb);

- DRM_DEBUG("psbfb_kms_on_ioctl\n");
-
mutex_lock(&dev->mode_config.mutex);
list_for_each_entry(fb, &dev->mode_config.fb_list, head) {
struct fb_info *info = psbfb->fbdev;
@@ -217,12 +214,10 @@ static int psbfb_vm_fault(struct vm_area_struct *vma, struct vm_fault *vmf)

static void psbfb_vm_open(struct vm_area_struct *vma)
{
- DRM_DEBUG("vm_open\n");
}

static void psbfb_vm_close(struct vm_area_struct *vma)
{
- DRM_DEBUG("vm_close\n");


}

static struct vm_operations_struct psbfb_vm_ops = {

@@ -237,7 +232,6 @@ static int psbfb_mmap(struct fb_info *info, struct vm_area_struct *vma)


struct psb_framebuffer *psbfb = &fbdev->pfb;

char *fb_screen_base = NULL;
struct drm_device *dev = psbfb->base.dev;
- struct drm_psb_private *dev_priv = dev->dev_private;

if (vma->vm_pgoff != 0)
return -EINVAL;
@@ -249,10 +243,6 @@ static int psbfb_mmap(struct fb_info *info, struct vm_area_struct *vma)

fb_screen_base = (char *)info->screen_base;

- DRM_DEBUG("vm_pgoff 0x%lx, screen base %p vram_addr %p\n",
- vma->vm_pgoff, fb_screen_base,
- dev_priv->vram_addr);
-


/* If this is a GEM object then info->screen_base is the virtual

kernel remapping of the object. FIXME: Review if this is

suitable for our mmap work */

@@ -523,14 +513,10 @@ static int psbfb_create(struct psb_fbdev *fbdev,
info->pixmap.flags = FB_PIXMAP_SYSTEM;
info->pixmap.scan_align = 1;

- DRM_DEBUG("fb depth is %d\n", fb->depth);
- DRM_DEBUG(" pitch is %d\n", fb->pitch);
-
- printk(KERN_INFO"allocated %dx%d fb\n",
- psbfb->base.width, psbfb->base.height);
+ dev_info(dev->dev, "allocated %dx%d fb\n",
+ psbfb->base.width, psbfb->base.height);

mutex_unlock(&dev->struct_mutex);
-
return 0;
out_unref:
if (backing->stolen)
@@ -575,13 +561,11 @@ static struct drm_framebuffer *psb_user_framebuffer_create


static void psbfb_gamma_set(struct drm_crtc *crtc, u16 red, u16 green,

u16 blue, int regno)
{
- DRM_DEBUG("%s\n", __func__);
}

static void psbfb_gamma_get(struct drm_crtc *crtc, u16 *red,
u16 *green, u16 *blue, int regno)
{
- DRM_DEBUG("%s\n", __func__);
}

static int psbfb_probe(struct drm_fb_helper *helper,
@@ -591,8 +575,6 @@ static int psbfb_probe(struct drm_fb_helper *helper,
int new_fb = 0;
int ret;

- DRM_DEBUG("%s\n", __func__);
-
if (!helper->fb) {
ret = psbfb_create(psb_fbdev, sizes);
if (ret)
@@ -650,7 +632,7 @@ int psb_fbdev_init(struct drm_device *dev)

fbdev = kzalloc(sizeof(struct psb_fbdev), GFP_KERNEL);
if (!fbdev) {
- DRM_ERROR("no memory\n");
+ dev_err(dev->dev, "no memory\n");
return -ENOMEM;
}

@@ -781,8 +763,6 @@ static void psb_setup_outputs(struct drm_device *dev)


(struct drm_psb_private *) dev->dev_private;

struct drm_connector *connector;

- PSB_DEBUG_ENTRY("\n");
-
drm_mode_create_scaling_mode_property(dev);

psb_create_backlight_property(dev);
@@ -791,7 +771,7 @@ static void psb_setup_outputs(struct drm_device *dev)
if (dev_priv->iLVDS_enable)
mrst_lvds_init(dev, &dev_priv->mode_dev);
else
- DRM_ERROR("DSI is not supported\n");
+ dev_err(dev->dev, "DSI is not supported\n");
} else {
psb_intel_lvds_init(dev, &dev_priv->mode_dev);
psb_intel_sdvo_init(dev, SDVOB);
@@ -811,7 +791,6 @@ static void psb_setup_outputs(struct drm_device *dev)
clone_mask = (1 << INTEL_OUTPUT_SDVO);
break;
case INTEL_OUTPUT_LVDS:
- PSB_DEBUG_ENTRY("LVDS.\n");
if (IS_MRST(dev))
crtc_mask = (1 << 0);
else
@@ -819,17 +798,14 @@ static void psb_setup_outputs(struct drm_device *dev)
clone_mask = (1 << INTEL_OUTPUT_LVDS);
break;
case INTEL_OUTPUT_MIPI:
- PSB_DEBUG_ENTRY("MIPI.\n");
crtc_mask = (1 << 0);
clone_mask = (1 << INTEL_OUTPUT_MIPI);
break;
case INTEL_OUTPUT_MIPI2:
- PSB_DEBUG_ENTRY("MIPI2.\n");
crtc_mask = (1 << 2);
clone_mask = (1 << INTEL_OUTPUT_MIPI2);
break;
case INTEL_OUTPUT_HDMI:
- PSB_DEBUG_ENTRY("HDMI.\n");
crtc_mask = (1 << 1);
clone_mask = (1 << INTEL_OUTPUT_HDMI);
break;
@@ -849,8 +825,6 @@ void psb_modeset_init(struct drm_device *dev)
struct psb_intel_mode_device *mode_dev = &dev_priv->mode_dev;
int i;

- PSB_DEBUG_ENTRY("\n");
-
drm_mode_config_init(dev);

dev->mode_config.min_width = 0;
diff --git a/drivers/staging/gma500/psb_gem.c b/drivers/staging/gma500/psb_gem.c
index 125ea6b..7f6f479 100644
--- a/drivers/staging/gma500/psb_gem.c
+++ b/drivers/staging/gma500/psb_gem.c
@@ -87,7 +87,7 @@ static int psb_gem_create_mmap_offset(struct drm_gem_object *obj)
list->file_offset_node = drm_mm_search_free(&mm->offset_manager,
obj->size / PAGE_SIZE, 0, 0);
if (!list->file_offset_node) {
- DRM_ERROR("failed to allocate offset for bo %d\n", obj->name);
+ dev_err(dev->dev, "failed to allocate offset for bo %d\n", obj->name);
ret = -ENOSPC;
goto free_it;
}
@@ -100,7 +100,7 @@ static int psb_gem_create_mmap_offset(struct drm_gem_object *obj)
list->hash.key = list->file_offset_node->start;
ret = drm_ht_insert_item(&mm->offset_hash, &list->hash);
if (ret) {
- DRM_ERROR("failed to add to map hash\n");
+ dev_err(dev->dev, "failed to add to map hash\n");
goto free_mm;
}
return 0;
@@ -283,7 +283,7 @@ int psb_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf)


if (r->mmapping == 0) {

ret = psb_gtt_pin(r);
if (ret < 0) {

- DRM_ERROR("gma500: pin failed: %d\n", ret);
+ dev_err(dev->dev, "gma500: pin failed: %d\n", ret);
goto fail;
}
r->mmapping = 1;
diff --git a/drivers/staging/gma500/psb_gtt.c b/drivers/staging/gma500/psb_gtt.c
index 8fcb833..54a9308 100644
--- a/drivers/staging/gma500/psb_gtt.c
+++ b/drivers/staging/gma500/psb_gtt.c
@@ -456,7 +456,7 @@ int psb_gtt_init(struct drm_device *dev, int resume)

if (resume && (gtt_pages != pg->gtt_pages) &&
(stolen_size != pg->stolen_size)) {
- DRM_ERROR("GTT resume error.\n");
+ dev_err(dev->dev, "GTT resume error.\n");
ret = -EINVAL;
goto out_err;
}
@@ -470,14 +470,14 @@ int psb_gtt_init(struct drm_device *dev, int resume)
*/


dev_priv->gtt_map = ioremap_nocache(pg->gtt_phys_start, gtt_pages << PAGE_SHIFT);
if (!dev_priv->gtt_map) {

- DRM_ERROR("Failure to map gtt.\n");
+ dev_err(dev->dev, "Failure to map gtt.\n");
ret = -ENOMEM;
goto out_err;
}

dev_priv->vram_addr = ioremap_wc(dev_priv->stolen_base, stolen_size);
if (!dev_priv->vram_addr) {
- DRM_ERROR("Failure to map stolen base.\n");
+ dev_err(dev->dev, "Failure to map stolen base.\n");
ret = -ENOMEM;
goto out_err;
}
diff --git a/drivers/staging/gma500/psb_intel_bios.c b/drivers/staging/gma500/psb_intel_bios.c
index 417965d..5b3e88c 100644
--- a/drivers/staging/gma500/psb_intel_bios.c
+++ b/drivers/staging/gma500/psb_intel_bios.c
@@ -96,25 +96,20 @@ static void parse_backlight_data(struct drm_psb_private *dev_priv,

dev_priv->lvds_bl = NULL;

- if (lvds_opts) {
- DRM_DEBUG("lvds_options found at %p\n", lvds_opts);
+ if (lvds_opts)
p_type = lvds_opts->panel_type;
- } else {
- DRM_DEBUG("no lvds_options\n");
+ else
return;
- }

bl_start = find_section(bdb, BDB_LVDS_BACKLIGHT);
vbt_lvds_bl = (struct bdb_lvds_backlight *)(bl_start + 1) + p_type;

lvds_bl = kzalloc(sizeof(*vbt_lvds_bl), GFP_KERNEL);
if (!lvds_bl) {
- DRM_DEBUG("No memory\n");
+ dev_err(dev_priv->dev->dev, "out of memory for backlight data\n");
return;
}
-
memcpy(lvds_bl, vbt_lvds_bl, sizeof(*vbt_lvds_bl));
-
dev_priv->lvds_bl = lvds_bl;
}

@@ -156,14 +151,12 @@ static void parse_lfp_panel_data(struct drm_psb_private *dev_priv,



if (panel_fixed_mode->htotal > 0 && panel_fixed_mode->vtotal > 0) {

dev_priv->lfp_lvds_vbt_mode = panel_fixed_mode;
- DRM_DEBUG("Found panel mode in BIOS VBT tables:\n");

drm_mode_debug_printmodeline(panel_fixed_mode);
} else {
- DRM_DEBUG("Ignoring bogus LVDS VBT mode.\n");
+ dev_dbg(dev_priv->dev->dev, "ignoring invalid LVDS VBT\n");
dev_priv->lvds_vbt = 0;
kfree(panel_fixed_mode);
}
-
return;
}

@@ -257,7 +250,7 @@ bool psb_intel_init_bios(struct drm_device *dev)
}

if (!vbt) {
- DRM_ERROR("VBT signature missing\n");
+ dev_err(dev->dev, "VBT signature missing\n");
pci_unmap_rom(pdev, bios);
return -1;
}
diff --git a/drivers/staging/gma500/psb_intel_display.c b/drivers/staging/gma500/psb_intel_display.c
index c7c55b1..be7e1f9 100644
--- a/drivers/staging/gma500/psb_intel_display.c
+++ b/drivers/staging/gma500/psb_intel_display.c
@@ -350,14 +350,12 @@ int psb_intel_pipe_set_base(struct drm_crtc *crtc,
u32 dspcntr;
int ret = 0;

- PSB_DEBUG_ENTRY("\n");
-
if (!gma_power_begin(dev, true))
return 0;



/* no fb bound */
if (!crtc->fb) {

- DRM_DEBUG("No FB bound\n");
+ dev_dbg(dev->dev, "No FB bound\n");
goto psb_intel_pipe_cleaner;
}

@@ -390,7 +388,7 @@ int psb_intel_pipe_set_base(struct drm_crtc *crtc,
dspcntr |= DISPPLANE_32BPP_NO_ALPHA;
break;
default:
- DRM_ERROR("Unknown color depth\n");
+ dev_err(dev->dev, "Unknown color depth\n");
ret = -EINVAL;
psb_gtt_unpin(psbfb->gtt);
goto psb_intel_pipe_set_base_exit;
@@ -398,7 +396,6 @@ int psb_intel_pipe_set_base(struct drm_crtc *crtc,
REG_WRITE(dspcntr_reg, dspcntr);


- DRM_DEBUG("Writing base %08lX %08lX %d %d\n", start, offset, x, y);
if (0 /* FIXMEAC - check what PSB needs */) {
REG_WRITE(dspbase, offset);
REG_READ(dspbase);
@@ -650,7 +647,7 @@ static int psb_intel_crtc_mode_set(struct drm_crtc *crtc,
ok = psb_intel_find_best_PLL(crtc, adjusted_mode->clock, refclk,
&clock);
if (!ok) {
- DRM_ERROR("Couldn't find PLL settings for mode!\n");
+ dev_err(dev->dev, "Couldn't find PLL settings for mode!\n");
return 0;
}

@@ -714,7 +711,6 @@ static int psb_intel_crtc_mode_set(struct drm_crtc *crtc,
if (psb_intel_panel_fitter_pipe(dev) == pipe)
REG_WRITE(PFIT_CONTROL, 0);

- DRM_DEBUG("Mode for pipe %c:\n", pipe == 0 ? 'A' : 'B');
drm_mode_debug_printmodeline(mode);

if (dpll & DPLL_VCO_ENABLE) {
@@ -825,7 +821,7 @@ void psb_intel_crtc_load_lut(struct drm_crtc *crtc)
palreg = PALETTE_C;
break;
default:
- DRM_ERROR("Illegal Pipe Number.\n");
+ dev_err(dev->dev, "Illegal Pipe Number.\n");
return;
}

@@ -868,10 +864,8 @@ static void psb_intel_crtc_save(struct drm_crtc *crtc)
uint32_t paletteReg;
int i;

- DRM_DEBUG("\n");
-
if (!crtc_state) {
- DRM_DEBUG("No CRTC state found\n");
+ dev_err(dev->dev, "No CRTC state found\n");
return;
}

@@ -895,25 +889,6 @@ static void psb_intel_crtc_save(struct drm_crtc *crtc)

crtc_state->saveDSPBASE = REG_READ(pipeA ? DSPABASE : DSPBBASE);

- DRM_DEBUG("(%x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x)\n",
- crtc_state->saveDSPCNTR,
- crtc_state->savePIPECONF,
- crtc_state->savePIPESRC,
- crtc_state->saveFP0,
- crtc_state->saveFP1,
- crtc_state->saveDPLL,
- crtc_state->saveHTOTAL,
- crtc_state->saveHBLANK,
- crtc_state->saveHSYNC,
- crtc_state->saveVTOTAL,
- crtc_state->saveVBLANK,
- crtc_state->saveVSYNC,
- crtc_state->saveDSPSTRIDE,
- crtc_state->saveDSPSIZE,
- crtc_state->saveDSPPOS,
- crtc_state->saveDSPBASE
- );
-
paletteReg = pipeA ? PALETTE_A : PALETTE_B;
for (i = 0; i < 256; ++i)
crtc_state->savePalette[i] = REG_READ(paletteReg + (i << 2));
@@ -934,60 +909,15 @@ static void psb_intel_crtc_restore(struct drm_crtc *crtc)
uint32_t paletteReg;
int i;

- DRM_DEBUG("\n");
-
if (!crtc_state) {
- DRM_DEBUG("No crtc state\n");
+ dev_err(dev->dev, "No crtc state\n");
return;
}

- DRM_DEBUG(
- "current:(%x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x)\n",
- REG_READ(pipeA ? DSPACNTR : DSPBCNTR),
- REG_READ(pipeA ? PIPEACONF : PIPEBCONF),
- REG_READ(pipeA ? PIPEASRC : PIPEBSRC),
- REG_READ(pipeA ? FPA0 : FPB0),
- REG_READ(pipeA ? FPA1 : FPB1),
- REG_READ(pipeA ? DPLL_A : DPLL_B),
- REG_READ(pipeA ? HTOTAL_A : HTOTAL_B),
- REG_READ(pipeA ? HBLANK_A : HBLANK_B),
- REG_READ(pipeA ? HSYNC_A : HSYNC_B),
- REG_READ(pipeA ? VTOTAL_A : VTOTAL_B),
- REG_READ(pipeA ? VBLANK_A : VBLANK_B),
- REG_READ(pipeA ? VSYNC_A : VSYNC_B),
- REG_READ(pipeA ? DSPASTRIDE : DSPBSTRIDE),
- REG_READ(pipeA ? DSPASIZE : DSPBSIZE),
- REG_READ(pipeA ? DSPAPOS : DSPBPOS),
- REG_READ(pipeA ? DSPABASE : DSPBBASE)
- );
-
- DRM_DEBUG(
- "saved: (%x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x)\n",
- crtc_state->saveDSPCNTR,
- crtc_state->savePIPECONF,
- crtc_state->savePIPESRC,
- crtc_state->saveFP0,
- crtc_state->saveFP1,
- crtc_state->saveDPLL,
- crtc_state->saveHTOTAL,
- crtc_state->saveHBLANK,
- crtc_state->saveHSYNC,
- crtc_state->saveVTOTAL,
- crtc_state->saveVBLANK,
- crtc_state->saveVSYNC,
- crtc_state->saveDSPSTRIDE,
- crtc_state->saveDSPSIZE,
- crtc_state->saveDSPPOS,
- crtc_state->saveDSPBASE
- );
-
-
if (crtc_state->saveDPLL & DPLL_VCO_ENABLE) {
REG_WRITE(pipeA ? DPLL_A : DPLL_B,
crtc_state->saveDPLL & ~DPLL_VCO_ENABLE);
REG_READ(pipeA ? DPLL_A : DPLL_B);
- DRM_DEBUG("write dpll: %x\n",
- REG_READ(pipeA ? DPLL_A : DPLL_B));
udelay(150);
}

@@ -1044,11 +974,8 @@ static int psb_intel_crtc_cursor_set(struct drm_crtc *crtc,
struct drm_gem_object *obj;
int ret;

- DRM_DEBUG("\n");
-
/* if we want to turn of the cursor ignore width and height */
if (!handle) {
- DRM_DEBUG("cursor off\n");
/* turn off the cursor */
temp = CURSOR_MODE_DISABLE;

@@ -1072,7 +999,7 @@ static int psb_intel_crtc_cursor_set(struct drm_crtc *crtc,

/* Currently we only support 64x64 cursors */
if (width != 64 || height != 64) {
- DRM_ERROR("we currently only support 64x64 cursors\n");
+ dev_dbg(dev->dev, "we currently only support 64x64 cursors\n");
return -EINVAL;
}

@@ -1081,7 +1008,7 @@ static int psb_intel_crtc_cursor_set(struct drm_crtc *crtc,
return -ENOENT;

if (obj->size < width * height * 4) {
- DRM_ERROR("buffer is to small\n");
+ dev_dbg(dev->dev, "buffer is to small\n");
return -ENOMEM;
}

@@ -1090,7 +1017,7 @@ static int psb_intel_crtc_cursor_set(struct drm_crtc *crtc,
/* Pin the memory into the GTT */
ret = psb_gtt_pin(gt);
if (ret) {
- DRM_ERROR("Can not pin down handle 0x%x\n", handle);
+ dev_err(dev->dev, "Can not pin down handle 0x%x\n", handle);
return ret;
}

@@ -1359,8 +1286,6 @@ void psb_intel_crtc_init(struct drm_device *dev, int pipe,
int i;
uint16_t *r_base, *g_base, *b_base;

- PSB_DEBUG_ENTRY("\n");
-
/* We allocate a extra array of drm_connector pointers
* for fbdev after the crtc */
psb_intel_crtc =
@@ -1373,7 +1298,7 @@ void psb_intel_crtc_init(struct drm_device *dev, int pipe,
psb_intel_crtc->crtc_state =
kzalloc(sizeof(struct psb_intel_crtc_state), GFP_KERNEL);
if (!psb_intel_crtc->crtc_state) {
- DRM_INFO("Crtc state error: No memory\n");
+ dev_err(dev->dev, "Crtc state error: No memory\n");
kfree(psb_intel_crtc);
return;
}
@@ -1430,7 +1355,7 @@ int psb_intel_get_pipe_from_crtc_id(struct drm_device *dev, void *data,
struct psb_intel_crtc *crtc;

if (!dev_priv) {
- DRM_ERROR("called with no initialization\n");
+ dev_err(dev->dev, "called with no initialization\n");
return -EINVAL;
}

@@ -1438,7 +1363,7 @@ int psb_intel_get_pipe_from_crtc_id(struct drm_device *dev, void *data,
DRM_MODE_OBJECT_CRTC);

if (!drmmode_obj) {
- DRM_ERROR("no such CRTC id\n");
+ dev_err(dev->dev, "no such CRTC id\n");
return -EINVAL;
}

diff --git a/drivers/staging/gma500/psb_intel_lvds.c b/drivers/staging/gma500/psb_intel_lvds.c
index b0a225b..1cbc9bc 100644
--- a/drivers/staging/gma500/psb_intel_lvds.c
+++ b/drivers/staging/gma500/psb_intel_lvds.c
@@ -126,13 +126,13 @@ static int psb_lvds_i2c_set_brightness(struct drm_device *dev,
out_buf[1] = (u8)blc_i2c_brightness;

if (i2c_transfer(&lvds_i2c_bus->adapter, msgs, 1) == 1) {
- DRM_DEBUG("I2C set brightness.(command, value) (%d, %d)\n",
+ dev_dbg(dev->dev, "I2C set brightness.(command, value) (%d, %d)\n",
dev_priv->lvds_bl->brightnesscmd,
blc_i2c_brightness);
return 0;
}

- DRM_ERROR("I2C transfer error\n");
+ dev_err(dev->dev, "I2C transfer error\n");
return -1;
}

@@ -172,10 +172,10 @@ void psb_intel_lvds_set_brightness(struct drm_device *dev, int level)
struct drm_psb_private *dev_priv =
(struct drm_psb_private *)dev->dev_private;

- DRM_DEBUG("backlight level is %d\n", level);
+ dev_dbg(dev->dev, "backlight level is %d\n", level);

if (!dev_priv->lvds_bl) {
- DRM_ERROR("NO LVDS Backlight Info\n");
+ dev_err(dev->dev, "NO LVDS Backlight Info\n");
return;
}

@@ -289,7 +289,7 @@ static void psb_intel_lvds_save(struct drm_connector *connector)
dev_priv->backlight_duty_cycle =
psb_intel_lvds_get_max_backlight(dev);

- DRM_DEBUG("(0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x)\n",
+ dev_dbg(dev->dev, "(0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x)\n",
lvds_priv->savePP_ON,
lvds_priv->savePP_OFF,
lvds_priv->saveLVDS,
@@ -310,7 +310,7 @@ static void psb_intel_lvds_restore(struct drm_connector *connector)
struct psb_intel_lvds_priv *lvds_priv =
(struct psb_intel_lvds_priv *)psb_intel_output->dev_priv;

- DRM_DEBUG("(0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x)\n",
+ dev_dbg(dev->dev, "(0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x)\n",
lvds_priv->savePP_ON,
lvds_priv->savePP_OFF,
lvds_priv->saveLVDS,
@@ -351,8 +351,6 @@ int psb_intel_lvds_mode_valid(struct drm_connector *connector,
struct drm_display_mode *fixed_mode =
psb_intel_output->mode_dev->panel_fixed_mode;

- PSB_DEBUG_ENTRY("\n");
-
if (psb_intel_output->type == INTEL_OUTPUT_MIPI2)
fixed_mode = psb_intel_output->mode_dev->panel_fixed_mode2;

@@ -387,9 +385,6 @@ bool psb_intel_lvds_mode_fixup(struct drm_encoder *encoder,
struct psb_intel_output *psb_intel_output =
enc_to_psb_intel_output(encoder);

- PSB_DEBUG_ENTRY("type = 0x%x, pipe = %d.\n",
- psb_intel_output->type, psb_intel_crtc->pipe);
-
if (psb_intel_output->type == INTEL_OUTPUT_MIPI2)
panel_fixed_mode = mode_dev->panel_fixed_mode2;

@@ -448,8 +443,6 @@ void psb_intel_lvds_prepare(struct drm_encoder *encoder)
struct psb_intel_output *output = enc_to_psb_intel_output(encoder);
struct psb_intel_mode_device *mode_dev = output->mode_dev;

- PSB_DEBUG_ENTRY("\n");
-
if (!gma_power_begin(dev, true))
return;

@@ -468,8 +461,6 @@ void psb_intel_lvds_commit(struct drm_encoder *encoder)
struct psb_intel_output *output = enc_to_psb_intel_output(encoder);
struct psb_intel_mode_device *mode_dev = output->mode_dev;

- PSB_DEBUG_ENTRY("\n");
-
if (mode_dev->backlight_duty_cycle == 0)
mode_dev->backlight_duty_cycle =
psb_intel_lvds_get_max_backlight(dev);
@@ -585,15 +576,11 @@ int psb_intel_lvds_set_property(struct drm_connector *connector,
{
struct drm_encoder *pEncoder = connector->encoder;

- PSB_DEBUG_ENTRY("\n");
-
if (!strcmp(property->name, "scaling mode") && pEncoder) {
struct psb_intel_crtc *pPsbCrtc =
to_psb_intel_crtc(pEncoder->crtc);
uint64_t curValue;

- PSB_DEBUG_ENTRY("scaling mode\n");
-
if (!pPsbCrtc)
goto set_prop_error;

@@ -631,8 +618,6 @@ int psb_intel_lvds_set_property(struct drm_connector *connector,
goto set_prop_error;
}
} else if (!strcmp(property->name, "backlight") && pEncoder) {
- PSB_DEBUG_ENTRY("backlight\n");
-
if (drm_connector_property_set_value(connector,
property,
value))
@@ -647,7 +632,6 @@ int psb_intel_lvds_set_property(struct drm_connector *connector,
} else if (!strcmp(property->name, "DPMS") && pEncoder) {
struct drm_encoder_helper_funcs *pEncHFuncs
= pEncoder->helper_private;
- PSB_DEBUG_ENTRY("DPMS\n");
pEncHFuncs->dpms(pEncoder, value);
}

@@ -722,7 +706,7 @@ void psb_intel_lvds_init(struct drm_device *dev,
lvds_priv = kzalloc(sizeof(struct psb_intel_lvds_priv), GFP_KERNEL);
if (!lvds_priv) {
kfree(psb_intel_output);
- DRM_DEBUG("LVDS private allocation error\n");
+ dev_err(dev->dev, "LVDS private allocation error\n");
return;
}

@@ -838,8 +822,7 @@ void psb_intel_lvds_init(struct drm_device *dev,

/* If we still don't have a mode after all that, give up. */
if (!mode_dev->panel_fixed_mode) {
- DRM_DEBUG
- ("Found no modes on the lvds, ignoring the LVDS\n");
+ dev_err(dev->dev, "Found no modes on the lvds, ignoring the LVDS\n");
goto failed_find;
}

@@ -849,26 +832,6 @@ void psb_intel_lvds_init(struct drm_device *dev,
*/
out:
drm_sysfs_connector_add(connector);
-
- PSB_DEBUG_ENTRY("hdisplay = %d\n",
- mode_dev->panel_fixed_mode->hdisplay);
- PSB_DEBUG_ENTRY(" vdisplay = %d\n",
- mode_dev->panel_fixed_mode->vdisplay);
- PSB_DEBUG_ENTRY(" hsync_start = %d\n",
- mode_dev->panel_fixed_mode->hsync_start);
- PSB_DEBUG_ENTRY(" hsync_end = %d\n",
- mode_dev->panel_fixed_mode->hsync_end);
- PSB_DEBUG_ENTRY(" htotal = %d\n",
- mode_dev->panel_fixed_mode->htotal);
- PSB_DEBUG_ENTRY(" vsync_start = %d\n",
- mode_dev->panel_fixed_mode->vsync_start);
- PSB_DEBUG_ENTRY(" vsync_end = %d\n",
- mode_dev->panel_fixed_mode->vsync_end);
- PSB_DEBUG_ENTRY(" vtotal = %d\n",
- mode_dev->panel_fixed_mode->vtotal);
- PSB_DEBUG_ENTRY(" clock = %d\n",
- mode_dev->panel_fixed_mode->clock);
-
return;

failed_find:
diff --git a/drivers/staging/gma500/psb_intel_opregion.c b/drivers/staging/gma500/psb_intel_opregion.c
index 65e3e9b..51cf1d6 100644
--- a/drivers/staging/gma500/psb_intel_opregion.c
+++ b/drivers/staging/gma500/psb_intel_opregion.c
@@ -58,11 +58,8 @@ int psb_intel_opregion_init(struct drm_device *dev)
dev_priv->lid_state = NULL;

pci_read_config_dword(dev->pdev, 0xfc, &opregion_phy);
- if (opregion_phy == 0) {
- DRM_DEBUG("Opregion not supported, won't support lid-switch\n");
+ if (opregion_phy == 0)
return -ENOTSUPP;
- }
- DRM_DEBUG("OpRegion detected at 0x%8x\n", opregion_phy);

base = ioremap(opregion_phy, 8*1024);
if (!base)
@@ -70,8 +67,6 @@ int psb_intel_opregion_init(struct drm_device *dev)

lid_state = base + 0x01ac;

- DRM_DEBUG("Lid switch state 0x%08x\n", *lid_state);
-
dev_priv->lid_state = lid_state;
dev_priv->lid_last_state = *lid_state;
return 0;
diff --git a/drivers/staging/gma500/psb_intel_sdvo.c b/drivers/staging/gma500/psb_intel_sdvo.c
index df1c006..e313ce2 100644
--- a/drivers/staging/gma500/psb_intel_sdvo.c
+++ b/drivers/staging/gma500/psb_intel_sdvo.c
@@ -107,14 +107,10 @@ static bool psb_intel_sdvo_read_byte(

ret = i2c_transfer(&sdvo_priv->i2c_bus->adapter, msgs, 2);
if (ret == 2) {
- /* DRM_DEBUG("got back from addr %02X = %02x\n",
- * out_buf[0], buf[0]);
- */
*ch = buf[0];
return true;
}

- DRM_DEBUG("i2c transfer returned %d\n", ret);
return false;
}

@@ -205,24 +201,24 @@ static void psb_intel_sdvo_write_cmd(struct psb_intel_output *psb_intel_output,
int i;

if (0) {
- DRM_DEBUG("%s: W: %02X ", SDVO_NAME(sdvo_priv), cmd);
+ printk(KERN_DEBUG "%s: W: %02X ", SDVO_NAME(sdvo_priv), cmd);
for (i = 0; i < args_len; i++)
- printk(KERN_INFO"%02X ", ((u8 *) args)[i]);
+ printk(KERN_CONT "%02X ", ((u8 *) args)[i]);
for (; i < 8; i++)
- printk(" ");
+ printk(KERN_CONT " ");


for (i = 0;
i <

sizeof(sdvo_cmd_names) / sizeof(sdvo_cmd_names[0]);
i++) {
if (cmd == sdvo_cmd_names[i].cmd) {
- printk("(%s)", sdvo_cmd_names[i].name);
+ printk(KERN_CONT "(%s)", sdvo_cmd_names[i].name);
break;
}
}
if (i ==
sizeof(sdvo_cmd_names) / sizeof(sdvo_cmd_names[0]))
- printk("(%02X)", cmd);
- printk("\n");
+ printk(KERN_CONT "(%02X)", cmd);
+ printk(KERN_CONT "\n");
}

for (i = 0; i < args_len; i++) {
@@ -267,17 +263,17 @@ static u8 psb_intel_sdvo_read_response(
&status);

if (0) {
- DRM_DEBUG("%s: R: ", SDVO_NAME(sdvo_priv));
+ pr_debug("%s: R: ", SDVO_NAME(sdvo_priv));
for (i = 0; i < response_len; i++)
- printk(KERN_INFO"%02X ", ((u8 *) response)[i]);
+ printk(KERN_CONT "%02X ", ((u8 *) response)[i]);
for (; i < 8; i++)
printk(" ");
if (status <= SDVO_CMD_STATUS_SCALING_NOT_SUPP)
- printk(KERN_INFO"(%s)",
+ printk(KERN_CONT "(%s)",
cmd_status_names[status]);
else
- printk(KERN_INFO"(??? %d)", status);
- printk("\n");
+ printk(KERN_CONT "(??? %d)", status);
+ printk(KERN_CONT "\n");
}

if (status != SDVO_CMD_STATUS_PENDING)
@@ -997,7 +993,6 @@ int psb_intel_sdvo_supports_hotplug(struct drm_connector *connector)
u8 response[2];
u8 status;
struct psb_intel_output *psb_intel_output;
- DRM_DEBUG("\n");

if (!connector)
return 0;
@@ -1198,7 +1193,7 @@ void psb_intel_sdvo_init(struct drm_device *dev, int output_device)
/* Read the regs to test if we can talk to the device */
for (i = 0; i < 0x40; i++) {
if (!psb_intel_sdvo_read_byte(psb_intel_output, i, &ch[i])) {
- DRM_DEBUG("No SDVO device found on SDVO%c\n",
+ dev_dbg(dev->dev, "No SDVO device found on SDVO%c\n",
output_device == SDVOB ? 'B' : 'C');
goto err_i2c;
}
@@ -1242,8 +1237,7 @@ void psb_intel_sdvo_init(struct drm_device *dev, int output_device)
unsigned char bytes[2];

memcpy(bytes, &sdvo_priv->caps.output_flags, 2);
- DRM_DEBUG
- ("%s: No active RGB or TMDS outputs (0x%02x%02x)\n",
+ dev_dbg(dev->dev, "%s: No active RGB or TMDS outputs (0x%02x%02x)\n",
SDVO_NAME(sdvo_priv), bytes[0], bytes[1]);
goto err_i2c;
}
@@ -1267,7 +1261,7 @@ void psb_intel_sdvo_init(struct drm_device *dev, int output_device)
pixel_clock_max);


- DRM_DEBUG("%s device VID/DID: %02X:%02X.%02X, "
+ dev_dbg(dev->dev, "%s device VID/DID: %02X:%02X.%02X, "
"clock range %dMHz - %dMHz, "
"input 1: %c, input 2: %c, "
"output 1: %c, output 2: %c\n",
diff --git a/drivers/staging/gma500/psb_irq.c b/drivers/staging/gma500/psb_irq.c
index 9ea37e5..1cbfeb6 100644
--- a/drivers/staging/gma500/psb_irq.c
+++ b/drivers/staging/gma500/psb_irq.c
@@ -187,7 +187,8 @@ static void mid_pipe_event_handler(struct drm_device *dev, uint32_t pipe)
}

if (i == WAIT_STATUS_CLEAR_LOOP_COUNT)
- DRM_ERROR("%s, can't clear the status bits in pipe_stat_reg, its value = 0x%x.\n",
+ 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));

if (pipe_stat_val & PIPE_VBLANK_STATUS)
@@ -219,21 +220,11 @@ irqreturn_t psb_irq_handler(DRM_IRQ_ARGS)

vdc_stat = PSB_RVDC32(PSB_INT_IDENTITY_R);

- if (vdc_stat & _MDFLD_DISP_ALL_IRQ_FLAG) {
- PSB_DEBUG_IRQ("Got DISP interrupt\n");
+ if (vdc_stat & _MDFLD_DISP_ALL_IRQ_FLAG)
dsp_int = 1;
- }

- if (vdc_stat & _PSB_IRQ_SGX_FLAG) {
- PSB_DEBUG_IRQ("Got SGX interrupt\n");
+ if (vdc_stat & _PSB_IRQ_SGX_FLAG)
sgx_int = 1;
- }
- if (vdc_stat & _PSB_IRQ_MSVDX_FLAG)
- PSB_DEBUG_IRQ("Got MSVDX interrupt\n");
-
- if (vdc_stat & _LNC_IRQ_TOPAZ_FLAG)
- PSB_DEBUG_IRQ("Got TOPAZ interrupt\n");
-

vdc_stat &= dev_priv->vdc_irq_mask;
spin_unlock(&dev_priv->irqmask_lock);
@@ -293,8 +284,6 @@ int psb_irq_postinstall(struct drm_device *dev)


(struct drm_psb_private *) dev->dev_private;

unsigned long irqflags;

- PSB_DEBUG_ENTRY("\n");
-
spin_lock_irqsave(&dev_priv->irqmask_lock, irqflags);

/* This register is safe even if display island is off */
@@ -326,8 +315,6 @@ void psb_irq_uninstall(struct drm_device *dev)


(struct drm_psb_private *) dev->dev_private;

unsigned long irqflags;

- PSB_DEBUG_ENTRY("\n");
-
spin_lock_irqsave(&dev_priv->irqmask_lock, irqflags);

PSB_WVDC32(0xFFFFFFFF, PSB_HWSTAM);
@@ -395,8 +382,6 @@ int psb_irq_enable_dpst(struct drm_device *dev)


(struct drm_psb_private *) dev->dev_private;

unsigned long irqflags;

- PSB_DEBUG_ENTRY("\n");
-
spin_lock_irqsave(&dev_priv->irqmask_lock, irqflags);

/* enable DPST */
@@ -435,8 +420,6 @@ int psb_irq_disable_dpst(struct drm_device *dev)


(struct drm_psb_private *) dev->dev_private;

unsigned long irqflags;

- PSB_DEBUG_ENTRY("\n");
-
spin_lock_irqsave(&dev_priv->irqmask_lock, irqflags);

mid_disable_pipe_event(dev_priv, 0);
@@ -472,8 +455,6 @@ int psb_enable_vblank(struct drm_device *dev, int pipe)
uint32_t reg_val = 0;
uint32_t pipeconf_reg = mid_pipeconf(pipe);

- PSB_DEBUG_ENTRY("\n");
-
if (gma_power_begin(dev, false)) {
reg_val = REG_READ(pipeconf_reg);
gma_power_end(dev);
@@ -500,8 +481,6 @@ void psb_disable_vblank(struct drm_device *dev, int pipe)


struct drm_psb_private *dev_priv = dev->dev_private;

unsigned long irqflags;

- PSB_DEBUG_ENTRY("\n");
-
spin_lock_irqsave(&dev_priv->irqmask_lock, irqflags);

mid_disable_pipe_event(dev_priv, pipe);
@@ -535,7 +514,7 @@ u32 psb_get_vblank_counter(struct drm_device *dev, int pipe)
pipeconf_reg = PIPECCONF;
break;
default:
- DRM_ERROR("%s, invalded pipe.\n", __func__);
+ dev_err(dev->dev, "%s, invalid pipe.\n", __func__);
return 0;
}

@@ -545,7 +524,7 @@ u32 psb_get_vblank_counter(struct drm_device *dev, int pipe)
reg_val = REG_READ(pipeconf_reg);

if (!(reg_val & PIPEACONF_ENABLE)) {
- DRM_ERROR("trying to get vblank count for disabled pipe %d\n",
+ dev_err(dev->dev, "trying to get vblank count for disabled pipe %d\n",
pipe);
goto psb_get_vblank_counter_exit;

Alan Cox

unread,
Jun 8, 2011, 6:15:32 AM6/8/11
to gr...@kroah.com, linux-...@vger.kernel.org, dri-...@lists.freedesktop.org
From: Alan Cox <al...@linux.intel.com>

We are using the underlying kref in the GEM object so we don't need our own

Signed-off-by: Alan Cox <al...@linux.intel.com>
---

drivers/staging/gma500/psb_fb.c | 1 -
drivers/staging/gma500/psb_gtt.c | 41 ++++++--------------------------------
drivers/staging/gma500/psb_gtt.h | 1 -
3 files changed, 6 insertions(+), 37 deletions(-)

diff --git a/drivers/staging/gma500/psb_fb.c b/drivers/staging/gma500/psb_fb.c
index 988f4db..fb75aba 100644
--- a/drivers/staging/gma500/psb_fb.c
+++ b/drivers/staging/gma500/psb_fb.c
@@ -231,7 +231,6 @@ static int psbfb_mmap(struct fb_info *info, struct vm_area_struct *vma)


struct psb_fbdev *fbdev = info->par;

struct psb_framebuffer *psbfb = &fbdev->pfb;
char *fb_screen_base = NULL;

- struct drm_device *dev = psbfb->base.dev;



if (vma->vm_pgoff != 0)
return -EINVAL;

diff --git a/drivers/staging/gma500/psb_gtt.c b/drivers/staging/gma500/psb_gtt.c
index 54a9308..9da1375 100644
--- a/drivers/staging/gma500/psb_gtt.c
+++ b/drivers/staging/gma500/psb_gtt.c
@@ -303,8 +303,6 @@ struct gtt_range *psb_gtt_alloc_range(struct drm_device *dev, int len,
gt->in_gart = backed;


/* Ensure this is set for non GEM objects */

gt->gem.dev = dev;
- kref_init(&gt->kref);
-


ret = allocate_resource(dev_priv->gtt_mem, &gt->resource,

len, start, end, PAGE_SIZE, NULL, NULL);
if (ret == 0) {

@@ -316,18 +314,15 @@ struct gtt_range *psb_gtt_alloc_range(struct drm_device *dev, int len,
}

/**
- * psb_gtt_destroy - final free up of a gtt
- * @kref: the kref of the gtt
- *
- * Called from the kernel kref put when the final reference to our
- * GTT object is dropped. At that point we can free up the resources.
+ * psb_gtt_free_range - release GTT address space


+ * @dev: our DRM device

+ * @gt: a mapping created with psb_gtt_alloc_range
*
- * For now we handle mmap clean up here to work around limits in GEM
+ * Release a resource that was allocated with psb_gtt_alloc_range. If the object
+ * has been pinned by mmap users we clean this up here currently.
*/
-static void psb_gtt_destroy(struct kref *kref)
+void psb_gtt_free_range(struct drm_device *dev, struct gtt_range *gt)
{
- struct gtt_range *gt = container_of(kref, struct gtt_range, kref);
-
/* Undo the mmap pin if we are destroying the object */
if (gt->mmapping) {
psb_gtt_unpin(gt);
@@ -338,30 +333,6 @@ static void psb_gtt_destroy(struct kref *kref)
kfree(gt);
}

-/**
- * psb_gtt_kref_put - drop reference to a GTT object
- * @gt: the GT being dropped
- *
- * Drop a reference to a psb gtt
- */
-void psb_gtt_kref_put(struct gtt_range *gt)
-{
- kref_put(&gt->kref, psb_gtt_destroy);
-}
-
-/**
- * psb_gtt_free_range - release GTT address space
- * @dev: our DRM device
- * @gt: a mapping created with psb_gtt_alloc_range
- *
- * Release a resource that was allocated with psb_gtt_alloc_range
- */
-void psb_gtt_free_range(struct drm_device *dev, struct gtt_range *gt)
-{
- psb_gtt_kref_put(gt);
-}
-
-
struct psb_gtt *psb_gtt_alloc(struct drm_device *dev)
{
struct psb_gtt *tmp = kzalloc(sizeof(*tmp), GFP_KERNEL);
diff --git a/drivers/staging/gma500/psb_gtt.h b/drivers/staging/gma500/psb_gtt.h
index 7e1f21e..4d6dc5f 100644
--- a/drivers/staging/gma500/psb_gtt.h
+++ b/drivers/staging/gma500/psb_gtt.h
@@ -44,7 +44,6 @@ extern void psb_gtt_takedown(struct drm_device *dev);
struct gtt_range {


struct resource resource; /* Resource for our allocation */

u32 offset; /* GTT offset of our object */

- struct kref kref; /* Can probably go FIXME - GEM kref will do */


struct drm_gem_object gem; /* GEM high level stuff */
int in_gart; /* Currently in the GART (ref ct) */
bool stolen; /* Backed from stolen RAM */

--

Lukasz

unread,
Jun 8, 2011, 7:15:25 AM6/8/11
to linux-...@vger.kernel.org
Alan Cox <alan <at> lxorguk.ukuu.org.uk> writes:

> Vblank support is also possible but doesn't seem terribly useful.

Sorry for being gross off-topic.

But I see the vblank (the feature that lets the (whatever space) programs
know when the vertical return occurs ?) as a quite useful thing...

Because then the rendering rate is (supposed to be) limited to whatever
the monitor supports (say 60Hz, 1 frame every 15ms) it may be useful as a
comparision how much _free_ cpu time is left when the program
is ready for another frame, that including any (e.g. AI, engine or) system
tasks running (e.g. network communications, debugger)
IMvhO it so would be useful for tracing/profiling these apps, without
stress-testing and give you reproductible results for the performance
of your graphic engine... because there is plenty of time left
for everything else and it does not step on each others toes or turning
your machine into a (blow)heater :)

Just my thoughts.
L.

Alan Cox

unread,
Jun 8, 2011, 8:24:49 AM6/8/11
to Lukasz, linux-...@vger.kernel.org
> But I see the vblank (the feature that lets the (whatever space) programs
> know when the vertical return occurs ?) as a quite useful thing...

Nothing much in the 2D world seems to use it for anything. In the 3D
world yes vblank syncing and page flipping is important, but the driver
is 2D only.

Alan

Patrik Jakobsson

unread,
Jun 8, 2011, 9:10:03 PM6/8/11
to Alan Cox, gr...@kroah.com, linux-...@vger.kernel.org, dri-...@lists.freedesktop.org
Hi Alan

Just a thought. Shouldn't we use the DRM macros for printing debug info?

-Patrik

Alan Cox

unread,
Jun 9, 2011, 4:11:03 AM6/9/11
to Patrik Jakobsson, gr...@kroah.com, linux-...@vger.kernel.org, dri-...@lists.freedesktop.org
On Thu, 9 Jun 2011 03:10:03 +0200
Patrik Jakobsson <patrik.r....@gmail.com> wrote:

> Hi Alan
>
> Just a thought. Shouldn't we use the DRM macros for printing debug info?

Linux has perfectly good printing functions and using them means we can
use dev_dbg() which supports things like nice runtime switching.

Dave Airlie

unread,
Jun 9, 2011, 6:36:51 AM6/9/11
to Alan Cox, Patrik Jakobsson, gr...@kroah.com, linux-...@vger.kernel.org, dri-...@lists.freedesktop.org
On Thu, 2011-06-09 at 09:11 +0100, Alan Cox wrote:
> On Thu, 9 Jun 2011 03:10:03 +0200
> Patrik Jakobsson <patrik.r....@gmail.com> wrote:
>
> > Hi Alan
> >
> > Just a thought. Shouldn't we use the DRM macros for printing debug info?
>
> Linux has perfectly good printing functions and using them means we can
> use dev_dbg() which supports things like nice runtime switching.

You mean like the drm debug functions runtime switching? that predated
the kernel ones and nobody ever ported :-)

Though if psb wants to be different to other drm drivers it can lead the
way, though it'll be a total nightmare for all the people who follow
documentation on how to debug drm drivers using drm.debug=1,2,4,8. for
various code paths.

Dave.

Patrik Jakobsson

unread,
Jun 9, 2011, 7:45:51 AM6/9/11
to Dave Airlie, Alan Cox, gr...@kroah.com, linux-...@vger.kernel.org, dri-...@lists.freedesktop.org
On Thu, Jun 9, 2011 at 12:36 PM, Dave Airlie wrote:
> On Thu, 2011-06-09 at 09:11 +0100, Alan Cox wrote:
>> On Thu, 9 Jun 2011 03:10:03 +0200
>> Patrik Jakobsson wrote:
>>
>> > Hi Alan
>> >
>> > Just a thought. Shouldn't we use the DRM macros for printing debug info?
>>
>> Linux has perfectly good printing functions and using them means we can
>> use dev_dbg() which supports things like nice runtime switching.
>
> You mean like the drm debug functions runtime switching? that predated
> the kernel ones and nobody ever ported :-)
>
> Though if psb wants to be different to other drm drivers it can lead the
> way, though it'll be a total nightmare for all the people who follow
> documentation on how to debug drm drivers using drm.debug=1,2,4,8. for
> various code paths.

Yes, my concern was about drm.debug and use of all the DRM portability stuff
(like using DRM_IRQ_HANDLED instead of IRQ_HANDLED, etc...)

The portability might not be important at this point but I just wanted to raise
the question so I know what is right / wrong.

Alan, I've been working on the output code but think I've reached a dead end.
I'm up to 20000 lines of changes and it's just a big mess. I'm gonna go for
slowly fixing up the current code instead. I also got my hands on a laptop
with a gma500 so I can test that my changes doesn't break LVDS. Stay tuned.

Thanks

Alan Cox

unread,
Jun 9, 2011, 7:55:21 AM6/9/11
to Dave Airlie, Patrik Jakobsson, gr...@kroah.com, linux-...@vger.kernel.org, dri-...@lists.freedesktop.org
> Though if psb wants to be different to other drm drivers it can lead the
> way, though it'll be a total nightmare for all the people who follow
> documentation on how to debug drm drivers using drm.debug=1,2,4,8. for
> various code paths.

Actually it seems to work out nicely because you can debug DRM core
goings on and driver goings on separately. Also the driver ones can be
turned on/off on their own at runtime which is a godsend.

As you can imagine I've been testing the debugging a fair bit !

Alan

Alan Cox

unread,
Jun 9, 2011, 8:04:31 AM6/9/11
to Patrik Jakobsson, Dave Airlie, gr...@kroah.com, linux-...@vger.kernel.org, dri-...@lists.freedesktop.org
> Yes, my concern was about drm.debug and use of all the DRM portability stuff
> (like using DRM_IRQ_HANDLED instead of IRQ_HANDLED, etc...)
>
> The portability might not be important at this point but I just wanted to raise
> the question so I know what is right / wrong.

The gma500 driver uses a lot of direct Linux services rather than
disappearing into the weird world of drm_mm and the like so any
portability is going to be a bit of an illusion at best.

If someone ports it to another GPL licensed OS then I may have to
reconsider a bit, we shall see.



> Alan, I've been working on the output code but think I've reached a dead end.
> I'm up to 20000 lines of changes and it's just a big mess. I'm gonna go for
> slowly fixing up the current code instead. I also got my hands on a laptop
> with a gma500 so I can test that my changes doesn't break LVDS. Stay tuned.

Will do. Got another chunk of patches to fire at Greg shortly and I've
now beaten pretty much all of it into passing CodingStyle so hopefully
any noise will settle down at that point.

Still not ready to leave staging, passing CodingStyle and being clean are
not quite the same thing in this case !

Daniel Vetter

unread,
Jun 12, 2011, 3:02:41 PM6/12/11
to Alan Cox, Patrik Jakobsson, Dave Airlie, linux-...@vger.kernel.org, dri-...@lists.freedesktop.org, gr...@kroah.com
Hi Alan.

On Thu, Jun 9, 2011 at 14:04, Alan Cox <al...@lxorguk.ukuu.org.uk> wrote:
> The gma500 driver uses a lot of direct Linux services rather than
> disappearing into the weird world of drm_mm and the like so any
> portability is going to be a bit of an illusion at best.

Given that I've mucked around in drm_mm quite a bit I'd be very interested
in your opinion about what's weird in it (and presumably what could be
improved). Can you elaborate?

Thanks a lot, Daniel
--
Daniel Vetter
daniel...@ffwll.ch - +41 (0) 79 364 57 48 - http://blog.ffwll.ch

Alan Cox

unread,
Jun 13, 2011, 11:44:03 AM6/13/11
to Daniel Vetter, Patrik Jakobsson, Dave Airlie, linux-...@vger.kernel.org, dri-...@lists.freedesktop.org, gr...@kroah.com
> Given that I've mucked around in drm_mm quite a bit I'd be very interested
> in your opinion about what's weird in it (and presumably what could be
> improved). Can you elaborate?

Mostly the API, which is also somewhat poorly documented. I've not dug
into the internals beyond trying to figure out how to use it. Looking at
the users the API is non-obvious, the interface involves a mix of calls
and digging deep into struct internals.

I'd have expected an API that had allocate/free type methods and exposed
the needed information directly or very easily not one that has drivers
doing. drm_sman seems to be attempt in that direction but its also rather
odd with interfaces like


item = drm_sman_alloc(&dev_priv->sman, mem->type, tmpSize, 0,
(unsigned long)file_priv);
mutex_unlock(&dev->struct_mutex);
if (item) {
mem->offset = ((mem->type == VIA_MEM_VIDEO) ?
dev_priv->vram_offset :
dev_priv->agp_offset) + (item->mm->
offset(item->mm, item->mm_info) <<
VIA_MM_ALIGN_SHIFT); mem->index = item->user_hash.key;


where the item->... gymnastics are spectacular to say the least given the
basic function of the allocator appears to be to provide said offset in
the first place.

And ultimately this is why I went with using allocate_region and friends
plus using GEM to do handles, which was a good choice for other reasons
as GEM is rather nicely designed barring the lack of a couple of helpers
and the few lines needed to split the shmem/handle abstraction properly.

Possibly drm_sman and friends should just wrap whatever simple native
allocator exists on the OS ?

Alan

Daniel Vetter

unread,
Jun 13, 2011, 3:35:32 PM6/13/11
to Alan Cox, Daniel Vetter, Patrik Jakobsson, Dave Airlie, linux-...@vger.kernel.org, dri-...@lists.freedesktop.org, gr...@kroah.com
On Mon, Jun 13, 2011 at 04:44:03PM +0100, Alan Cox wrote:
> > Given that I've mucked around in drm_mm quite a bit I'd be very interested
> > in your opinion about what's weird in it (and presumably what could be
> > improved). Can you elaborate?
>
> Mostly the API, which is also somewhat poorly documented. I've not dug
> into the internals beyond trying to figure out how to use it. Looking at
> the users the API is non-obvious, the interface involves a mix of calls
> and digging deep into struct internals.

Well, I've rewritten the api but that transition is not yet complete, i.e.
the new interface is there, but no driver is converted yet. The old api
has a two-step allocation (search_free + get_block) and frees allocated
ranges with put_block. The new api has just insert_node and remove_node,
struct drm_mm_node must be allocated by the caller (to get rid of the racy
preallocation scheme and allow embedding of drm_mm_node).

There's also the lru scanning helpers (only used by intel). Under specific
conditions (should be all documented in comments) this can be used as an
eviction roaster.

Generally only node->start should be used by drivers, otherwise
drm_mm_node should be opaque. At least that's the idea.

btw, old conversion patches for i915 to the new interface are at:

http://cgit.freedesktop.org/~danvet/drm/log/?h=embed-gtt-space

When creating the new interfaces I've tried to document them. Ideas to
improve that highly welcome.

> I'd have expected an API that had allocate/free type methods and exposed
> the needed information directly or very easily not one that has drivers
> doing. drm_sman seems to be attempt in that direction but its also rather
> odd with interfaces like

Should be fixed, see above ;-)

[snip]

> Possibly drm_sman and friends should just wrap whatever simple native
> allocator exists on the OS ?

Well, drm_mm has some graphics specific magic (range restricted scans and
the eviction helpers). But simpler stuff like sman is imo just "drm likes
to reinvent the wheel". Unfortunately I don't have the hw, so I haven't
dared to touch it (the snippet you've posted is a prime example why).

Yours, Daniel
--
Daniel Vetter
Mail: dan...@ffwll.ch
Mobile: +41 (0)79 365 57 48

Pasi Kärkkäinen

unread,
Jun 14, 2011, 5:24:55 AM6/14/11
to Alan Cox, Lukasz, linux-...@vger.kernel.org
On Wed, Jun 08, 2011 at 01:24:49PM +0100, Alan Cox wrote:
> > But I see the vblank (the feature that lets the (whatever space) programs
> > know when the vertical return occurs ?) as a quite useful thing...
>
> Nothing much in the 2D world seems to use it for anything. In the 3D
> world yes vblank syncing and page flipping is important, but the driver
> is 2D only.
>

Video players probably want to use it to provide tear/stutter-free playback?

-- Pasi

Alan Cox

unread,
Jun 16, 2011, 12:06:09 PM6/16/11
to gr...@kroah.com, linux-...@vger.kernel.org
From: Alan Cox <al...@linux.intel.com>

Signed-off-by: Alan Cox <al...@linux.intel.com>
---

drivers/staging/gma500/psb_gtt.c | 3 +--
1 files changed, 1 insertions(+), 2 deletions(-)

diff --git a/drivers/staging/gma500/psb_gtt.c b/drivers/staging/gma500/psb_gtt.c
index 280f9d4..ec31ffe 100644
--- a/drivers/staging/gma500/psb_gtt.c
+++ b/drivers/staging/gma500/psb_gtt.c
@@ -78,7 +78,6 @@ u32 *psb_gtt_entry(struct drm_device *dev, struct gtt_range *r)
*/
static int psb_gtt_insert(struct drm_device *dev, struct gtt_range *r)
{


- struct drm_psb_private *dev_priv = dev->dev_private;

u32 *gtt_slot, pte;
int numpages = resource_size(&r->resource) >> PAGE_SHIFT;
struct page **pages;
@@ -490,7 +489,7 @@ int psb_gtt_init(struct drm_device *dev, int resume)
goto out_err;
}

- DRM_DEBUG("%s: vram kernel virtual address %p\n", dev_priv->vram_addr);
+ DRM_DEBUG("gma500: vram kernel virtual address %p\n", dev_priv->vram_addr);



tt_pages = (pg->gatt_pages < PSB_TT_PRIV0_PLIMIT) ?

(pg->gatt_pages) : PSB_TT_PRIV0_PLIMIT;

Alan Cox

unread,
Jun 16, 2011, 12:05:39 PM6/16/11
to gr...@kroah.com, linux-...@vger.kernel.org
The bulk of this is the initial addition of Medfield support and the beginning
of the modularisation work that is going to be needed to keep the driver sane
as we add more devices.

With this lot applied the Poulsbo driver just needs a 2D acceleration interface
for X to use to replace the debug hack one it has now, the mrst/oaktrail support
will need a fair bit of debugging and testing on actual platforms before it
is ready and the Medfield support needs a fair bit of further output work.

---

Alan Cox (27):
gma500: enable Medfield CRTC support
gma500: Read the GCT panel type information for Medfield
gma500: Fix early Medfield crash
gma500: continue abstracting platform specific code
gma500: being abstracting out devices a bit more
gma500: Only fiddle with clock gating on PSB
gma500: Update the GEM todo
gma500: psb_fb tidy/cleanup pass
gma500: Extract BIOSisy stuff from psb_drv
gma500: Move our other GEM helper into the bits want to push into GEM
gma500: Medfield support
gma500: 2D polish
gma500: CodingStyle pass
gma500: Use the GEM tweaks to provide a GEM frame buffer
gma500: GEM glue
gma500: Kill spare kref
gma500: nuke the PSB debug stuff
gma500: nuke the last bits of TTM code
gma500: 2D acceleration tidying
gma500: polish for completion of this phase
gma500: trim some of the debug
gma500: Do sane FB cleanup
gma500: revamp frame buffer creation and handling
gma500: Set the correct bits according to the pipe
gma500: Ensure the frame buffer has a linear virtual mapping
gma500: Make GTT pages uncached
gma500: fix warnings

Andre Bartke (1):
gma500: Fix uninitialized variable and style issues

Andrew Morton (1):
gma500: drivers/staging/gma501/psb_intel_display.c: fix build


drivers/staging/gma500/Makefile | 21
drivers/staging/gma500/backlight.c | 46 +
drivers/staging/gma500/displays/hdmi.h | 33 +
drivers/staging/gma500/displays/pyr_cmd.h | 34 +
drivers/staging/gma500/displays/pyr_vid.h | 34 +
drivers/staging/gma500/displays/tmd_cmd.h | 34 +
drivers/staging/gma500/displays/tmd_vid.h | 34 +
drivers/staging/gma500/displays/tpo_cmd.h | 35 +
drivers/staging/gma500/displays/tpo_vid.h | 33 +
drivers/staging/gma500/gem_glue.c | 110 ++
drivers/staging/gma500/gem_glue.h | 4
drivers/staging/gma500/mdfld_device.c | 702 ++++++++++++
drivers/staging/gma500/mdfld_dsi_dbi.c | 872 +++++++++++++++
drivers/staging/gma500/mdfld_dsi_dbi.h | 188 +++
drivers/staging/gma500/mdfld_dsi_dbi_dpu.h | 157 +++
drivers/staging/gma500/mdfld_dsi_dpi.c | 991 ++++++++++++++++++
drivers/staging/gma500/mdfld_dsi_dpi.h | 80 +
drivers/staging/gma500/mdfld_dsi_output.c | 980 +++++++++++++++++
drivers/staging/gma500/mdfld_dsi_output.h | 328 ++++++
drivers/staging/gma500/mdfld_dsi_pkg_sender.c | 1097 +++++++++++++++++++
drivers/staging/gma500/mdfld_dsi_pkg_sender.h | 158 +++
drivers/staging/gma500/mdfld_intel_display.c | 1415 +++++++++++++++++++++++++
drivers/staging/gma500/mdfld_msic.h | 31 +
drivers/staging/gma500/mdfld_output.c | 144 +++
drivers/staging/gma500/mdfld_output.h | 80 +
drivers/staging/gma500/mdfld_pyr_cmd.c | 575 ++++++++++
drivers/staging/gma500/mdfld_tmd_vid.c | 144 +++
drivers/staging/gma500/mdfld_tpo_cmd.c | 495 +++++++++
drivers/staging/gma500/mdfld_tpo_vid.c | 140 ++
drivers/staging/gma500/mrst.h | 38 -
drivers/staging/gma500/mrst_bios.c | 263 +++++
drivers/staging/gma500/mrst_bios.h | 22
drivers/staging/gma500/mrst_crtc.c | 27
drivers/staging/gma500/mrst_device.c | 367 ++++++
drivers/staging/gma500/mrst_lvds.c | 22
drivers/staging/gma500/power.c | 320 ++++++
drivers/staging/gma500/psb_2d.c | 235 ++--
drivers/staging/gma500/psb_bl.c | 227 ----
drivers/staging/gma500/psb_device.c | 297 +++++
drivers/staging/gma500/psb_drm.h | 109 --
drivers/staging/gma500/psb_drv.c | 344 +-----
drivers/staging/gma500/psb_drv.h | 428 ++++----
drivers/staging/gma500/psb_fb.c | 492 ++++-----
drivers/staging/gma500/psb_fb.h | 6
drivers/staging/gma500/psb_gem.c | 122 --
drivers/staging/gma500/psb_gtt.c | 200 +---
drivers/staging/gma500/psb_gtt.h | 11
drivers/staging/gma500/psb_intel_bios.c | 17
drivers/staging/gma500/psb_intel_display.c | 149 +--
drivers/staging/gma500/psb_intel_display.h | 3
drivers/staging/gma500/psb_intel_drv.h | 22
drivers/staging/gma500/psb_intel_lvds.c | 85 --
drivers/staging/gma500/psb_intel_opregion.c | 15
drivers/staging/gma500/psb_intel_reg.h | 1055 +++++++++----------
drivers/staging/gma500/psb_intel_sdvo.c | 35 -
drivers/staging/gma500/psb_intel_sdvo_regs.h | 14
drivers/staging/gma500/psb_irq.c | 92 +-
drivers/staging/gma500/psb_irq.h | 8
drivers/staging/gma500/psb_powermgmt.c | 489 ---------
drivers/staging/gma500/psb_powermgmt.h | 2
drivers/staging/gma500/psb_reg.h | 842 +++++++--------
61 files changed, 12195 insertions(+), 3158 deletions(-)
create mode 100644 drivers/staging/gma500/backlight.c
create mode 100644 drivers/staging/gma500/displays/hdmi.h
create mode 100644 drivers/staging/gma500/displays/pyr_cmd.h
create mode 100644 drivers/staging/gma500/displays/pyr_vid.h
create mode 100644 drivers/staging/gma500/displays/tmd_cmd.h
create mode 100644 drivers/staging/gma500/displays/tmd_vid.h
create mode 100644 drivers/staging/gma500/displays/tpo_cmd.h
create mode 100644 drivers/staging/gma500/displays/tpo_vid.h
create mode 100644 drivers/staging/gma500/gem_glue.c
create mode 100644 drivers/staging/gma500/gem_glue.h
create mode 100644 drivers/staging/gma500/mdfld_device.c
create mode 100644 drivers/staging/gma500/mdfld_dsi_dbi.c
create mode 100644 drivers/staging/gma500/mdfld_dsi_dbi.h
create mode 100644 drivers/staging/gma500/mdfld_dsi_dbi_dpu.h
create mode 100644 drivers/staging/gma500/mdfld_dsi_dpi.c
create mode 100644 drivers/staging/gma500/mdfld_dsi_dpi.h
create mode 100644 drivers/staging/gma500/mdfld_dsi_output.c
create mode 100644 drivers/staging/gma500/mdfld_dsi_output.h
create mode 100644 drivers/staging/gma500/mdfld_dsi_pkg_sender.c
create mode 100644 drivers/staging/gma500/mdfld_dsi_pkg_sender.h
create mode 100644 drivers/staging/gma500/mdfld_intel_display.c
create mode 100644 drivers/staging/gma500/mdfld_msic.h
create mode 100644 drivers/staging/gma500/mdfld_output.c
create mode 100644 drivers/staging/gma500/mdfld_output.h
create mode 100644 drivers/staging/gma500/mdfld_pyr_cmd.c
create mode 100644 drivers/staging/gma500/mdfld_tmd_vid.c
create mode 100644 drivers/staging/gma500/mdfld_tpo_cmd.c
create mode 100644 drivers/staging/gma500/mdfld_tpo_vid.c
create mode 100644 drivers/staging/gma500/mrst_bios.c
create mode 100644 drivers/staging/gma500/mrst_bios.h
create mode 100644 drivers/staging/gma500/mrst_device.c
create mode 100644 drivers/staging/gma500/power.c
delete mode 100644 drivers/staging/gma500/psb_bl.c
create mode 100644 drivers/staging/gma500/psb_device.c
delete mode 100644 drivers/staging/gma500/psb_powermgmt.c

--
Signature

Alan Cox

unread,
Jun 16, 2011, 12:06:31 PM6/16/11
to gr...@kroah.com, linux-...@vger.kernel.org
From: Alan Cox <al...@linux.intel.com>

Clean up the GTT code a bit, make the pages uncached and go via the proper
interfaces. This avoids any aliasing problems.

On the CPU side we need to access the pages via their true addresses not via
the GTT. This is fine for GEM created fb objects for X. For the kernel fb
when not in stolen RAM we are going to need to use vm_map_ram() and hope we
have enough virtual address space to steal.

Signed-off-by: Alan Cox <al...@linux.intel.com>
---

drivers/staging/gma500/psb_fb.c | 9 ++++++++-
drivers/staging/gma500/psb_gem.c | 26 +++++++-------------------
drivers/staging/gma500/psb_gtt.c | 27 ++++++++++++++-------------
3 files changed, 29 insertions(+), 33 deletions(-)

diff --git a/drivers/staging/gma500/psb_fb.c b/drivers/staging/gma500/psb_fb.c
index 084c36b..b276fe9 100644
--- a/drivers/staging/gma500/psb_fb.c
+++ b/drivers/staging/gma500/psb_fb.c
@@ -346,6 +346,11 @@ err:
* and back it with a GEM object.
*
* 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.
+ * FIXME: we need to vm_map_ram a linear mapping if the object has to
+ * be GEM host mapped, otherwise the cfb layer's brain will fall out.
*/
static struct gtt_range *psbfb_alloc(struct drm_device *dev, int aligned_size)
{
@@ -436,7 +441,7 @@ static int psbfb_create(struct psb_fbdev *fbdev,

/* Accessed via stolen memory directly, This only works for stolem
memory however. Need to address this once we start using gtt
- pages we allocate */
+ pages we allocate. FIXME: vm_map_ram for that case */
info->screen_base = (char *)dev_priv->vram_addr + backing->offset;


info->screen_size = size;
memset(info->screen_base, 0, size);

@@ -676,6 +681,8 @@ static void psb_user_framebuffer_destroy(struct drm_framebuffer *fb)


struct psb_framebuffer *psbfb = to_psb_fb(fb);

struct gtt_range *r = psbfb->gtt;

+ pr_err("user framebuffer destroy %p, fbdev %p\n",
+ psbfb, psbfb->fbdev);
if (psbfb->fbdev)
psbfb_remove(dev, fb);

diff --git a/drivers/staging/gma500/psb_gem.c b/drivers/staging/gma500/psb_gem.c
index 76ff7ba..98d8ab3 100644
--- a/drivers/staging/gma500/psb_gem.c
+++ b/drivers/staging/gma500/psb_gem.c
@@ -40,7 +40,6 @@ int psb_gem_init_object(struct drm_gem_object *obj)
void psb_gem_free_object(struct drm_gem_object *obj)
{
struct gtt_range *gtt = container_of(obj, struct gtt_range, gem);
- psb_gtt_free_range(obj->dev, gtt);
if (obj->map_list.map) {
/* Do things GEM should do for us */
struct drm_gem_mm *mm = obj->dev->mm_private;
@@ -51,6 +50,8 @@ void psb_gem_free_object(struct drm_gem_object *obj)
list->map = NULL;
}
drm_gem_object_release(obj);
+ /* This must occur last as it frees up the memory of the GEM object */
+ psb_gtt_free_range(obj->dev, gtt);
}

int psb_gem_get_aperture(struct drm_device *dev, void *data,
@@ -245,19 +246,13 @@ int psb_gem_dumb_destroy(struct drm_file *file, struct drm_device *dev,
* but we need to do the actual page work.
*
* This code eventually needs to handle faulting objects in and out
- * of the GART and repacking it when we run out of space. We can put
+ * of the GTT and repacking it when we run out of space. We can put
* that off for now and for our simple uses
*
* 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.
*
- * To avoid aliasing and cache funnies we want to map the object
- * through the GART. For the moment this is slightly hackish. It would
- * be nicer if GEM provided mmap opened/closed hooks for us giving
- * the object so that we could track things nicely. That needs changes
- * to the core GEM code so must be tackled post staging
- *
* FIXME
*/


int psb_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf)

@@ -289,20 +284,13 @@ int psb_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
r->mmapping = 1;
}

- /* FIXME: Locking. We may also need to repack the GART sometimes */
-
- /* Page relative to the VMA start */
+ /* Page relative to the VMA start - we must calculate this ourselves
+ because vmf->pgoff is the fake GEM offset */


page_offset = ((unsigned long) vmf->virtual_address - vma->vm_start)
>> PAGE_SHIFT;

- /* Bus address of the page is gart + object offset + page offset */
- /* Assumes gtt allocations are page aligned */
- pfn = (r->resource.start >> PAGE_SHIFT) + page_offset;
-
- pr_debug("Object GTT base at %p\n", (void *)(r->resource.start));
- pr_debug("Inserting %p pfn %lx, pa %lx\n", vmf->virtual_address,
- pfn, pfn << PAGE_SHIFT);
-
+ /* CPU view of the page, don't go via the GART for CPU writes */
+ pfn = page_to_phys(r->pages[page_offset]) >> PAGE_SHIFT;


ret = vm_insert_pfn(vma, (unsigned long)vmf->virtual_address, pfn);

fail:
diff --git a/drivers/staging/gma500/psb_gtt.c b/drivers/staging/gma500/psb_gtt.c
index ec31ffe..2ddab50 100644
--- a/drivers/staging/gma500/psb_gtt.c
+++ b/drivers/staging/gma500/psb_gtt.c
@@ -28,11 +28,11 @@
*/

/**
- * psb_gtt_mask_pte - generate GART pte entry
+ * psb_gtt_mask_pte - generate GTT pte entry
* @pfn: page number to encode
- * @type: type of memory in the GART
+ * @type: type of memory in the GTT
*
- * Set the GART entry for the appropriate memory type.
+ * Set the GTT entry for the appropriate memory type.
*/


static inline uint32_t psb_gtt_mask_pte(uint32_t pfn, int type)

{
@@ -49,11 +49,11 @@ static inline uint32_t psb_gtt_mask_pte(uint32_t pfn, int type)
}

/**
- * psb_gtt_entry - find the GART entries for a gtt_range
+ * psb_gtt_entry - find the GTT entries for a gtt_range


* @dev: our DRM device

* @r: our GTT range
*
- * Given a gtt_range object return the GART offset of the page table
+ * Given a gtt_range object return the GTT offset of the page table
* entries for this gtt_range
*/


u32 *psb_gtt_entry(struct drm_device *dev, struct gtt_range *r)

@@ -67,12 +67,12 @@ u32 *psb_gtt_entry(struct drm_device *dev, struct gtt_range *r)
}

/**
- * psb_gtt_insert - put an object into the GART
+ * psb_gtt_insert - put an object into the GTT


* @dev: our DRM device

* @r: our GTT range
*
* Take our preallocated GTT range and insert the GEM object into
- * the GART.
+ * the GTT.
*
* FIXME: gtt lock ?
*/
@@ -93,10 +93,10 @@ static int psb_gtt_insert(struct drm_device *dev, struct gtt_range *r)
gtt_slot = psb_gtt_entry(dev, r);
pages = r->pages;

- /* Make sure we have no alias present */
- wbinvd();
+ /* Make sure changes are visible to the GPU */
+ set_pages_array_uc(pages, numpages);

- /* Write our page entries into the GART itself */
+ /* Write our page entries into the GTT itself */
for (i = 0; i < numpages; i++) {
pte = psb_gtt_mask_pte(page_to_pfn(*pages++), 0/*type*/);
iowrite32(pte, gtt_slot++);
@@ -108,11 +108,11 @@ static int psb_gtt_insert(struct drm_device *dev, struct gtt_range *r)
}

/**
- * psb_gtt_remove - remove an object from the GART
+ * psb_gtt_remove - remove an object from the GTT


* @dev: our DRM device

* @r: our GTT range
*
- * Remove a preallocated GTT range from the GART. Overwrite all the
+ * Remove a preallocated GTT range from the GTT. Overwrite all the
* page table entries with the dummy page
*/

@@ -131,6 +131,7 @@ static void psb_gtt_remove(struct drm_device *dev, struct gtt_range *r)
for (i = 0; i < numpages; i++)
iowrite32(pte, gtt_slot++);
ioread32(gtt_slot - 1);
+ set_pages_array_wb(r->pages, numpages);
}

/**
@@ -182,7 +183,7 @@ err:
* @gt: the gtt range
*


* Undo the effect of psb_gtt_attach_pages. At this point the pages

- * must have been removed from the GART 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.

*


* FIXME: Do we need to cache flush when we update the GTT

--

Alan Cox

unread,
Jun 16, 2011, 12:07:01 PM6/16/11
to gr...@kroah.com, linux-...@vger.kernel.org
From: Alan Cox <al...@linux.intel.com>

We need this for the framebuffer in order to ensure that the kernel
framebuffer layer can handle it when using KMS. Except for the base
framebuffer this isn't a concern.

Add an npage field to the gtt as too many copies of the page calculation
are getting spread around the code.

Signed-off-by: Alan Cox <al...@linux.intel.com>
---

drivers/staging/gma500/psb_fb.c | 47 ++++++++++++++++++++++++--------------
drivers/staging/gma500/psb_fb.h | 1 +
drivers/staging/gma500/psb_gtt.c | 18 ++++++---------
drivers/staging/gma500/psb_gtt.h | 5 ++--
4 files changed, 42 insertions(+), 29 deletions(-)

diff --git a/drivers/staging/gma500/psb_fb.c b/drivers/staging/gma500/psb_fb.c
index b276fe9..4b05cdc 100644
--- a/drivers/staging/gma500/psb_fb.c
+++ b/drivers/staging/gma500/psb_fb.c
@@ -254,17 +254,13 @@ static int psbfb_mmap(struct fb_info *info, struct vm_area_struct *vma)
vma->vm_pgoff, fb_screen_base,
dev_priv->vram_addr);

- /* FIXME: ultimately this needs to become 'if entirely stolen memory' */
- if (1 || fb_screen_base == dev_priv->vram_addr) {
- vma->vm_ops = &psbfb_vm_ops;
- vma->vm_private_data = (void *)psbfb;
- vma->vm_flags |= VM_RESERVED | VM_IO |
- VM_MIXEDMAP | VM_DONTEXPAND;
- } else {
- /* GTT memory backed by kernel/user pages, needs a different
- approach ? - GEM ? */
- }
-
+ /* If this is a GEM object then info->screen_base is the virtual
+ kernel remapping of the object. FIXME: Review if this is
+ suitable for our mmap work */
+ vma->vm_ops = &psbfb_vm_ops;
+ vma->vm_private_data = (void *)psbfb;
+ vma->vm_flags |= VM_RESERVED | VM_IO |
+ VM_MIXEDMAP | VM_DONTEXPAND;
return 0;
}

@@ -349,8 +345,6 @@ err:
*


* FIXME: console speed up - allocate twice the space if room and use

* hardware scrolling for acceleration.

- * FIXME: we need to vm_map_ram a linear mapping if the object has to
- * be GEM host mapped, otherwise the cfb layer's brain will fall out.


*/
static struct gtt_range *psbfb_alloc(struct drm_device *dev, int aligned_size)
{

@@ -439,10 +433,22 @@ static int psbfb_create(struct psb_fbdev *fbdev,


info->fix.smem_start = dev->mode_config.fb_base;
info->fix.smem_len = size;

- /* Accessed via stolen memory directly, This only works for stolem
- memory however. Need to address this once we start using gtt
- pages we allocate. FIXME: vm_map_ram for that case */
- info->screen_base = (char *)dev_priv->vram_addr + backing->offset;
+ if (backing->stolen) {
+ /* 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_err0;
+ }
+ psbfb->vm_map = 1;
+ }


info->screen_size = size;
memset(info->screen_base, 0, size);

@@ -570,6 +576,13 @@ 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);
+ }


/* FIXME: this is a bit more inside knowledge than I'd like
but I don't see how to make a fake GEM object of the
stolen space nicely */

diff --git a/drivers/staging/gma500/psb_fb.h b/drivers/staging/gma500/psb_fb.h
index c8ec0d6..2153c74 100644
--- a/drivers/staging/gma500/psb_fb.h
+++ b/drivers/staging/gma500/psb_fb.h
@@ -33,6 +33,7 @@ struct psb_framebuffer {
struct address_space *addr_space;
struct fb_info *fbdev;
struct gtt_range *gtt;
+ bool vm_map; /* True if we must undo a vm_map_ram */
};

struct psb_fbdev {
diff --git a/drivers/staging/gma500/psb_gtt.c b/drivers/staging/gma500/psb_gtt.c
index 2ddab50..6a24246 100644
--- a/drivers/staging/gma500/psb_gtt.c
+++ b/drivers/staging/gma500/psb_gtt.c
@@ -79,7 +79,6 @@ u32 *psb_gtt_entry(struct drm_device *dev, struct gtt_range *r)


static int psb_gtt_insert(struct drm_device *dev, struct gtt_range *r)

{
u32 *gtt_slot, pte;
- int numpages = resource_size(&r->resource) >> PAGE_SHIFT;
struct page **pages;
int i;

@@ -94,10 +93,10 @@ static int psb_gtt_insert(struct drm_device *dev, struct gtt_range *r)
pages = r->pages;



/* Make sure changes are visible to the GPU */

- set_pages_array_uc(pages, numpages);
+ set_pages_array_uc(pages, r->npage);



/* Write our page entries into the GTT itself */

- for (i = 0; i < numpages; i++) {
+ for (i = 0; i < r->npage; i++) {


pte = psb_gtt_mask_pte(page_to_pfn(*pages++), 0/*type*/);
iowrite32(pte, gtt_slot++);
}

@@ -120,7 +119,6 @@ static void psb_gtt_remove(struct drm_device *dev, struct gtt_range *r)
{


struct drm_psb_private *dev_priv = dev->dev_private;
u32 *gtt_slot, pte;

- int numpages = resource_size(&r->resource) >> PAGE_SHIFT;
int i;

WARN_ON(r->stolen);
@@ -128,10 +126,10 @@ static void psb_gtt_remove(struct drm_device *dev, struct gtt_range *r)
gtt_slot = psb_gtt_entry(dev, r);


pte = psb_gtt_mask_pte(page_to_pfn(dev_priv->scratch_page), 0);;

- for (i = 0; i < numpages; i++)
+ for (i = 0; i < r->npage; i++)


iowrite32(pte, gtt_slot++);
ioread32(gtt_slot - 1);

- set_pages_array_wb(r->pages, numpages);
+ set_pages_array_wb(r->pages, r->npage);
}

/**
@@ -149,7 +147,7 @@ static int psb_gtt_attach_pages(struct gtt_range *gt)
struct address_space *mapping;
int i;
struct page *p;
- int pages = resource_size(&gt->resource) >> PAGE_SHIFT;
+ int pages = gt->gem.size / PAGE_SIZE;

WARN_ON(gt->pages);

@@ -160,6 +158,8 @@ static int psb_gtt_attach_pages(struct gtt_range *gt)
gt->pages = kmalloc(pages * sizeof(struct page *), GFP_KERNEL);
if (gt->pages == NULL)
return -ENOMEM;
+ gt->npage = pages;
+
for (i = 0; i < pages; i++) {
/* FIXME: review flags later */
p = read_cache_page_gfp(mapping, i,
@@ -191,9 +191,7 @@ err:


static void psb_gtt_detach_pages(struct gtt_range *gt)
{

int i;
- int pages = resource_size(&gt->resource) >> PAGE_SHIFT;
-
- for (i = 0; i < pages; i++) {
+ for (i = 0; i < gt->npage; i++) {


/* FIXME: do we need to force dirty */
set_page_dirty(gt->pages[i]);

/* Undo the reference we took when populating the table */

diff --git a/drivers/staging/gma500/psb_gtt.h b/drivers/staging/gma500/psb_gtt.h
index 535ae00..37287eb 100644
--- a/drivers/staging/gma500/psb_gtt.h
+++ b/drivers/staging/gma500/psb_gtt.h
@@ -46,9 +46,10 @@ struct gtt_range {
struct kref kref;


struct drm_gem_object gem; /* GEM high level stuff */
int in_gart; /* Currently in the GART (ref ct) */

- bool stolen; /* Backed from stolen RAM */
- bool mmapping; /* Is mmappable */
+ bool stolen; /* Backed from stolen RAM */
+ bool mmapping; /* Is mmappable */
struct page **pages; /* Backing pages if present */
+ int npage; /* Number of backing pages */
};

extern struct gtt_range *psb_gtt_alloc_range(struct drm_device *dev, int len,

Alan Cox

unread,
Jun 16, 2011, 12:07:27 PM6/16/11
to gr...@kroah.com, linux-...@vger.kernel.org
From: Alan Cox <al...@linux.intel.com>

Squash a hardcoded assumption we shouldn't really make

Signed-off-by: Alan Cox <al...@linux.intel.com>
---

drivers/staging/gma500/psb_intel_display.c | 11 ++++++-----
1 files changed, 6 insertions(+), 5 deletions(-)

diff --git a/drivers/staging/gma500/psb_intel_display.c b/drivers/staging/gma500/psb_intel_display.c
index 4f47d09..a99271d 100644
--- a/drivers/staging/gma500/psb_intel_display.c
+++ b/drivers/staging/gma500/psb_intel_display.c
@@ -723,17 +723,18 @@ static int psb_intel_crtc_mode_set(struct drm_crtc *crtc,
if (is_lvds) {
u32 lvds = REG_READ(LVDS);

- lvds |=
- LVDS_PORT_EN | LVDS_A0A2_CLKA_POWER_UP |
- LVDS_PIPEB_SELECT;
+ lvds &= ~LVDS_PIPEB_SELECT;
+ if (pipe == 1)
+ lvds |= LVDS_PIPEB_SELECT;
+
+ lvds |= LVDS_PORT_EN | LVDS_A0A2_CLKA_POWER_UP;
/* Set the B0-B3 data pairs corresponding to
* whether we're going to
* set the DPLLs for dual-channel mode or not.
*/
+ lvds &= ~(LVDS_B0B3_POWER_UP | LVDS_CLKB_POWER_UP);
if (clock.p2 == 7)
lvds |= LVDS_B0B3_POWER_UP | LVDS_CLKB_POWER_UP;
- else
- lvds &= ~(LVDS_B0B3_POWER_UP | LVDS_CLKB_POWER_UP);

/* It would be nice to set 24 vs 18-bit mode (LVDS_A3_POWER_UP)
* appropriately here, but we need to look more

Alan Cox

unread,
Jun 16, 2011, 12:07:45 PM6/16/11
to gr...@kroah.com, linux-...@vger.kernel.org
From: Andre Bartke <andre....@googlemail.com>

The return variable of psb_gtt_pin() may be used
uninitialized. Also fixed some coding style issues.

Signed-off-by: Andre Bartke <andre....@gmail.com>
[Reapplied by hand due to other changes]


Signed-off-by: Alan Cox <al...@linux.intel.com>
---

drivers/staging/gma500/psb_gtt.c | 36 ++++++++++++++++++------------------
1 files changed, 18 insertions(+), 18 deletions(-)

diff --git a/drivers/staging/gma500/psb_gtt.c b/drivers/staging/gma500/psb_gtt.c
index 6a24246..5a296e1 100644
--- a/drivers/staging/gma500/psb_gtt.c
+++ b/drivers/staging/gma500/psb_gtt.c
@@ -58,7 +58,7 @@ static inline uint32_t psb_gtt_mask_pte(uint32_t pfn, int type)
*/


u32 *psb_gtt_entry(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;
unsigned long offset;

offset = r->resource.start - dev_priv->gtt_mem->start;
@@ -124,7 +124,7 @@ static void psb_gtt_remove(struct drm_device *dev, struct gtt_range *r)
WARN_ON(r->stolen);

gtt_slot = psb_gtt_entry(dev, r);
- pte = psb_gtt_mask_pte(page_to_pfn(dev_priv->scratch_page), 0);;
+ pte = psb_gtt_mask_pte(page_to_pfn(dev_priv->scratch_page), 0);



for (i = 0; i < r->npage; i++)
iowrite32(pte, gtt_slot++);

@@ -213,7 +213,7 @@ static void psb_gtt_detach_pages(struct gtt_range *gt)
*/
int psb_gtt_pin(struct gtt_range *gt)
{
- int ret;
+ int ret = 0;
struct drm_device *dev = gt->gem.dev;


struct drm_psb_private *dev_priv = dev->dev_private;

@@ -289,33 +289,33 @@ struct gtt_range *psb_gtt_alloc_range(struct drm_device *dev, int len,
struct resource *r = dev_priv->gtt_mem;
int ret;
unsigned long start, end;
-
+
if (backed) {
- /* The start of the GTT is the stolen pages */
- start = r->start;
- end = r->start + dev_priv->pg->stolen_size - 1;
+ /* The start of the GTT is the stolen pages */
+ start = r->start;
+ end = r->start + dev_priv->pg->stolen_size - 1;
} else {
- /* The rest we will use for GEM backed objects */
- start = r->start + dev_priv->pg->stolen_size;
- end = r->end;
+ /* The rest we will use for GEM backed objects */
+ start = r->start + dev_priv->pg->stolen_size;
+ end = r->end;
}

gt = kzalloc(sizeof(struct gtt_range), GFP_KERNEL);
if (gt == NULL)
return NULL;
- gt->resource.name = name;
- gt->stolen = backed;
- gt->in_gart = backed;
- /* Ensure this is set for non GEM objects */
- gt->gem.dev = dev;
+ gt->resource.name = name;
+ gt->stolen = backed;
+ gt->in_gart = backed;
+ /* Ensure this is set for non GEM objects */
+ gt->gem.dev = dev;
kref_init(&gt->kref);



ret = allocate_resource(dev_priv->gtt_mem, &gt->resource,
len, start, end, PAGE_SIZE, NULL, NULL);
if (ret == 0) {

- gt->offset = gt->resource.start - r->start;
+ gt->offset = gt->resource.start - r->start;
return gt;
- }
+ }
kfree(gt);
return NULL;
}
@@ -419,7 +419,7 @@ int psb_gtt_init(struct drm_device *dev, int resume)

dev_priv->pg = pg = psb_gtt_alloc(dev);
if (pg == NULL)
- return -ENOMEM;
+ return -ENOMEM;



pci_read_config_word(dev->pdev, PSB_GMCH_CTRL, &dev_priv->gmch_ctrl);
pci_write_config_word(dev->pdev, PSB_GMCH_CTRL,

--

Alan Cox

unread,
Jun 16, 2011, 12:08:00 PM6/16/11
to gr...@kroah.com, linux-...@vger.kernel.org
From: Alan Cox <al...@linux.intel.com>

Restructure this to work the same way as the i915 frame buffer does. That
cleans up various chunks of code.

We can now set a mode in modetest but mode restore is a bit iffy

Signed-off-by: Alan Cox <al...@linux.intel.com>
---

drivers/staging/gma500/psb_2d.c | 13 +--
drivers/staging/gma500/psb_fb.c | 195 +++++++++++++++++++++-----------------
drivers/staging/gma500/psb_fb.h | 2
drivers/staging/gma500/psb_gem.c | 18 +++-
drivers/staging/gma500/psb_gtt.c | 2
5 files changed, 133 insertions(+), 97 deletions(-)

diff --git a/drivers/staging/gma500/psb_2d.c b/drivers/staging/gma500/psb_2d.c
index 0bd834c..060eeaf 100644
--- a/drivers/staging/gma500/psb_2d.c
+++ b/drivers/staging/gma500/psb_2d.c
@@ -148,7 +148,7 @@ static void psbfb_fillrect_accel(struct fb_info *info,
const struct fb_fillrect *r)
{


struct psb_fbdev *fbdev = info->par;

- struct psb_framebuffer *psbfb = fbdev->pfb;
+ struct psb_framebuffer *psbfb = &fbdev->pfb;


struct drm_device *dev = psbfb->base.dev;

struct drm_framebuffer *fb = fbdev->psb_fb_helper.fb;


struct drm_psb_private *dev_priv = dev->dev_private;

@@ -291,7 +291,7 @@ static void psbfb_copyarea_accel(struct fb_info *info,
const struct fb_copyarea *a)
{


struct psb_fbdev *fbdev = info->par;

- struct psb_framebuffer *psbfb = fbdev->pfb;
+ struct psb_framebuffer *psbfb = &fbdev->pfb;


struct drm_device *dev = psbfb->base.dev;

struct drm_framebuffer *fb = fbdev->psb_fb_helper.fb;


struct drm_psb_private *dev_priv = dev->dev_private;

@@ -360,19 +360,12 @@ void psbfb_imageblit(struct fb_info *info, const struct fb_image *image)
int psbfb_sync(struct fb_info *info)
{


struct psb_fbdev *fbdev = info->par;

- struct psb_framebuffer *psbfb = fbdev->pfb;
+ struct psb_framebuffer *psbfb = &fbdev->pfb;


struct drm_device *dev = psbfb->base.dev;

struct drm_psb_private *dev_priv = dev->dev_private;

unsigned long _end = jiffies + DRM_HZ;
int busy = 0;

-#if 0
- /* Just a way to quickly test if cmd issue explodes */
- u32 test[2] = {
- PSB_2D_FENCE_BH,
- };
- psbfb_2d_submit(dev_priv, test, 1);
-#endif
/*
* First idle the 2D engine.
*/
diff --git a/drivers/staging/gma500/psb_fb.c b/drivers/staging/gma500/psb_fb.c
index 4b05cdc..5977add 100644
--- a/drivers/staging/gma500/psb_fb.c
+++ b/drivers/staging/gma500/psb_fb.c
@@ -235,7 +235,7 @@ static struct vm_operations_struct psbfb_vm_ops = {


static int psbfb_mmap(struct fb_info *info, struct vm_area_struct *vma)

{


struct psb_fbdev *fbdev = info->par;

- struct psb_framebuffer *psbfb = fbdev->pfb;
+ struct psb_framebuffer *psbfb = &fbdev->pfb;


char *fb_screen_base = NULL;
struct drm_device *dev = psbfb->base.dev;

struct drm_psb_private *dev_priv = dev->dev_private;

@@ -267,7 +267,7 @@ static int psbfb_mmap(struct fb_info *info, struct vm_area_struct *vma)
static int psbfb_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg)
{


struct psb_fbdev *fbdev = info->par;

- struct psb_framebuffer *psbfb = fbdev->pfb;
+ struct psb_framebuffer *psbfb = &fbdev->pfb;


struct drm_device *dev = psbfb->base.dev;

struct drm_psb_private *dev_priv = dev->dev_private;

u32 __user *p = (u32 __user *)arg;
@@ -304,8 +304,58 @@ static struct fb_ops psbfb_ops = {
.fb_ioctl = psbfb_ioctl,
};

+/**
+ * psb_framebuffer_init - initialize a framebuffer
+ * @dev: our DRM device
+ * @fb: framebuffer to set up
+ * @mode_cmd: mode description
+ * @gt: backing object
+ *
+ * Configure and fill in the boilerplate for our frame buffer. Return
+ * 0 on success or an error code if we fail.
+ */
+static int psb_framebuffer_init(struct drm_device *dev,
+ struct psb_framebuffer *fb,
+ struct drm_mode_fb_cmd *mode_cmd,
+ struct gtt_range *gt)
+{
+ int ret;
+
+ if (mode_cmd->pitch & 63)
+ return -EINVAL;
+ switch (mode_cmd->bpp) {
+ case 8:
+ case 16:
+ case 24:
+ case 32:
+ break;
+ default:
+ return -EINVAL;
+ }
+ ret = drm_framebuffer_init(dev, &fb->base, &psb_fb_funcs);
+ if (ret) {
+ dev_err(dev->dev, "framebuffer init failed: %d\n", ret);
+ return ret;
+ }
+ drm_helper_mode_fill_fb_struct(&fb->base, mode_cmd);
+ fb->gtt = gt;


+ return 0;
+}
+

+/**
+ * psb_framebuffer_create - create a framebuffer backed by gt
+ * @dev: our DRM device
+ * @mode_cmd: the description of the requested mode
+ * @gt: the backing object
+ *
+ * Create a framebuffer object backed by the gt, and fill in the
+ * boilerplate required
+ *
+ * TODO: review object references
+ */
static struct drm_framebuffer *psb_framebuffer_create
- (struct drm_device *dev, struct drm_mode_fb_cmd *r,
+ (struct drm_device *dev,
+ struct drm_mode_fb_cmd *mode_cmd,
struct gtt_range *gt)
{
struct psb_framebuffer *fb;
@@ -313,22 +363,14 @@ static struct drm_framebuffer *psb_framebuffer_create

fb = kzalloc(sizeof(*fb), GFP_KERNEL);
if (!fb)
- return NULL;
-
- ret = drm_framebuffer_init(dev, &fb->base, &psb_fb_funcs);
-
- if (ret)
- goto err;
-
- drm_helper_mode_fill_fb_struct(&fb->base, r);
-
- fb->gtt = gt;
-
- return &fb->base;
+ return ERR_PTR(-ENOMEM);

-err:
- kfree(fb);
- return NULL;
+ ret = psb_framebuffer_init(dev, fb, mode_cmd, gt);
+ if (ret) {
+ kfree(fb);
+ return ERR_PTR(ret);
+ }
+ return &fb->base;
}

/**
@@ -380,56 +422,63 @@ static int psbfb_create(struct psb_fbdev *fbdev,


struct drm_psb_private *dev_priv = dev->dev_private;

struct fb_info *info;
struct drm_framebuffer *fb;
- struct psb_framebuffer *psbfb;
+ struct psb_framebuffer *psbfb = &fbdev->pfb;
struct drm_mode_fb_cmd mode_cmd;
struct device *device = &dev->pdev->dev;
- int size, aligned_size;
+ int size;
int ret;
struct gtt_range *backing;

mode_cmd.width = sizes->surface_width;
mode_cmd.height = sizes->surface_height;
+ mode_cmd.bpp = sizes->surface_bpp;
+
+ /* No 24bit packed */
+ if (mode_cmd.bpp == 24)
+ mode_cmd.bpp = 32;

- mode_cmd.bpp = 32;
/* HW requires pitch to be 64 byte aligned */
- mode_cmd.pitch = ALIGN(mode_cmd.width * ((mode_cmd.bpp + 1) / 8), 64);
- mode_cmd.depth = 24;
+ mode_cmd.pitch = ALIGN(mode_cmd.width * ((mode_cmd.bpp + 7) / 8), 64);
+ mode_cmd.depth = sizes->surface_depth;

size = mode_cmd.pitch * mode_cmd.height;
- aligned_size = ALIGN(size, PAGE_SIZE);
+ size = ALIGN(size, PAGE_SIZE);

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

mutex_lock(&dev->struct_mutex);
- fb = psb_framebuffer_create(dev, &mode_cmd, backing);
- if (!fb) {
- DRM_ERROR("failed to allocate fb.\n");
- ret = -ENOMEM;
- goto out_err1;
- }
- psbfb = to_psb_fb(fb);

- info = framebuffer_alloc(sizeof(struct psb_fbdev), device);
+ info = framebuffer_alloc(0, device);
if (!info) {
ret = -ENOMEM;
- goto out_err0;
+ goto out_err1;
}
-
info->par = fbdev;

+ ret = psb_framebuffer_init(dev, psbfb, &mode_cmd, backing);
+ if (ret)
+ goto out_unref;
+
+ fb = &psbfb->base;
psbfb->fbdev = info;

fbdev->psb_fb_helper.fb = fb;
fbdev->psb_fb_helper.fbdev = info;
- fbdev->pfb = psbfb;

strcpy(info->fix.id, "psbfb");

info->flags = FBINFO_DEFAULT;
info->fbops = &psbfb_ops;
+
+ ret = fb_alloc_cmap(&info->cmap, 256, 0);
+ if (ret) {
+ ret = -ENOMEM;
+ goto out_unref;
+ }
+


info->fix.smem_start = dev->mode_config.fb_base;
info->fix.smem_len = size;

@@ -445,18 +494,18 @@ static int psbfb_create(struct psb_fbdev *fbdev,


if (info->screen_base == NULL) {

psb_gtt_unpin(backing);
ret = -ENOMEM;
- goto out_err0;
+ goto out_unref;
}
psbfb->vm_map = 1;
}
info->screen_size = size;
- memset(info->screen_base, 0, size);
+/* memset(info->screen_base, 0, size); */

if (dev_priv->pg->stolen_size) {
info->apertures = alloc_apertures(1);
if (!info->apertures) {
ret = -ENOMEM;
- goto out_err0;
+ goto out_unref;
}
info->apertures->ranges[0].base = dev->mode_config.fb_base;
info->apertures->ranges[0].size = dev_priv->pg->stolen_size;
@@ -484,8 +533,14 @@ static int psbfb_create(struct psb_fbdev *fbdev,
mutex_unlock(&dev->struct_mutex);

return 0;
-out_err0:
- fb->funcs->destroy(fb);
+out_unref:
+ if (backing->stolen)
+ psb_gtt_free_range(dev, backing);
+ else {
+ if (psbfb->vm_map)
+ vm_unmap_ram(info->screen_base, backing->npage);
+ drm_gem_object_unreference(&backing->gem);
+ }
out_err1:
mutex_unlock(&dev->struct_mutex);
psb_gtt_free_range(dev, backing);
@@ -506,7 +561,6 @@ static struct drm_framebuffer *psb_user_framebuffer_create
{
struct gtt_range *r;
struct drm_gem_object *obj;
- struct psb_framebuffer *psbfb;

/* Find the GEM object and thus the gtt range object that is
to back this space */
@@ -514,23 +568,9 @@ static struct drm_framebuffer *psb_user_framebuffer_create
if (obj == NULL)
return ERR_PTR(-ENOENT);

- /* Allocate a framebuffer */
- psbfb = kzalloc(sizeof(*psbfb), GFP_KERNEL);
- if (psbfb == NULL) {
- drm_gem_object_unreference_unlocked(obj);
- return ERR_PTR(-ENOMEM);
- }
-
/* Let the core code do all the work */
r = container_of(obj, struct gtt_range, gem);
- if (psb_framebuffer_create(dev, cmd, r) == NULL) {
- drm_gem_object_unreference_unlocked(obj);
- kfree(psbfb);
- return ERR_PTR(-EINVAL);
- }
- /* Return the drm_framebuffer contained within the psb fbdev which
- has been initialized by the framebuffer creation */
- return &psbfb->base;
+ return psb_framebuffer_create(dev, cmd, r);


}

static void psbfb_gamma_set(struct drm_crtc *crtc, u16 red, u16 green,

@@ -572,7 +612,7 @@ struct drm_fb_helper_funcs psb_fb_helper_funcs = {


int psb_fbdev_destroy(struct drm_device *dev, struct psb_fbdev *fbdev)

{
struct fb_info *info;
- struct psb_framebuffer *psbfb = fbdev->pfb;
+ struct psb_framebuffer *psbfb = &fbdev->pfb;



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

@@ -583,6 +623,15 @@ int psb_fbdev_destroy(struct drm_device *dev, struct psb_fbdev *fbdev)


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);
+ framebuffer_release(info);
+ }
+ drm_fb_helper_fini(&fbdev->psb_fb_helper);
+ drm_framebuffer_cleanup(&psbfb->base);
+
+ if (psbfb->gtt) {


/* FIXME: this is a bit more inside knowledge than I'd like
but I don't see how to make a fake GEM object of the
stolen space nicely */

@@ -590,13 +639,7 @@ int psb_fbdev_destroy(struct drm_device *dev, struct psb_fbdev *fbdev)
psb_gtt_free_range(dev, psbfb->gtt);
else
drm_gem_object_unreference(&psbfb->gtt->gem);
- unregister_framebuffer(info);
- iounmap(info->screen_base);
- framebuffer_release(info);
- }
-
- drm_fb_helper_fini(&fbdev->psb_fb_helper);
- drm_framebuffer_cleanup(&psbfb->base);
+ }
return 0;
}

@@ -644,22 +687,6 @@ static void psbfb_output_poll_changed(struct drm_device *dev)
drm_fb_helper_hotplug_event(&fbdev->psb_fb_helper);
}

-int psbfb_remove(struct drm_device *dev, struct drm_framebuffer *fb)
-{
- struct fb_info *info;
- struct psb_framebuffer *psbfb = to_psb_fb(fb);
-
- if (drm_psb_no_fb)
- return 0;
-
- info = psbfb->fbdev;
-
- if (info)
- framebuffer_release(info);
- return 0;
-}
-/*EXPORT_SYMBOL(psbfb_remove); */
-
/**
* psb_user_framebuffer_create_handle - add hamdle to a framebuffer
* @fb: framebuffer
@@ -690,15 +717,13 @@ static int psb_user_framebuffer_create_handle(struct drm_framebuffer *fb,
*/


static void psb_user_framebuffer_destroy(struct drm_framebuffer *fb)

{
- struct drm_device *dev = fb->dev;


struct psb_framebuffer *psbfb = to_psb_fb(fb);
struct gtt_range *r = psbfb->gtt;

+ /* Should never get stolen memory for a user fb */
+ WARN_ON(r->stolen);


pr_err("user framebuffer destroy %p, fbdev %p\n",

psbfb, psbfb->fbdev);
- if (psbfb->fbdev)
- psbfb_remove(dev, fb);
-


/* Let DRM do its clean up */
drm_framebuffer_cleanup(fb);

/* We are no longer using the resource in GEM */
diff --git a/drivers/staging/gma500/psb_fb.h b/drivers/staging/gma500/psb_fb.h
index 2153c74..fd7e51a 100644
--- a/drivers/staging/gma500/psb_fb.h
+++ b/drivers/staging/gma500/psb_fb.h
@@ -38,7 +38,7 @@ struct psb_framebuffer {

struct psb_fbdev {
struct drm_fb_helper psb_fb_helper;
- struct psb_framebuffer *pfb;
+ struct psb_framebuffer pfb;
};


diff --git a/drivers/staging/gma500/psb_gem.c b/drivers/staging/gma500/psb_gem.c
index 98d8ab3..b24b964 100644
--- a/drivers/staging/gma500/psb_gem.c
+++ b/drivers/staging/gma500/psb_gem.c
@@ -51,6 +51,7 @@ void psb_gem_free_object(struct drm_gem_object *obj)
}
drm_gem_object_release(obj);


/* This must occur last as it frees up the memory of the GEM object */

+ pr_err("GEM destroyed %p, %p\n", gtt, obj);
psb_gtt_free_range(obj->dev, gtt);
}

@@ -176,21 +177,28 @@ static int psb_gem_create(struct drm_file *file,

size = roundup(size, PAGE_SIZE);

+ dev_err(dev->dev, "GEM creating %lld\n", size);
+


/* Allocate our object - for now a direct gtt range which is not
stolen memory backed */
r = psb_gtt_alloc_range(dev, size, "gem", 0);

- if (r == NULL)
+ if (r == NULL) {
+ dev_err(dev->dev, "no memory for %lld byte GEM object\n", size);
return -ENOSPC;
+ }
/* 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 */
+ dev_err(dev->dev, "GEM init failed for %lld\n", size);
return -ENOMEM;
}
/* Give the object a handle so we can carry it more easily */
ret = drm_gem_handle_create(file, &r->gem, &handle);
if (ret) {
+ dev_err(dev->dev, "GEM handle failed for %p, %lld\n",
+ &r->gem, size);
drm_gem_object_release(&r->gem);
psb_gtt_free_range(dev, r);
return ret;
@@ -198,6 +206,8 @@ static int psb_gem_create(struct drm_file *file,


/* We have the initial and handle reference but need only one now */
drm_gem_object_unreference(&r->gem);
*handlep = handle;

+ dev_err(dev->dev, "GEM handle %x for %p OK\n",
+ handle, &r->gem);
return 0;
}

@@ -273,9 +283,12 @@ int psb_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf)


something from beneath our feet */
mutex_lock(&dev->struct_mutex);

+ dev_err(dev->dev, "Fault on GTT %p\n", r);
+


/* For now the mmap pins the object and it stays pinned. As things
stand that will do us no harm */

if (r->mmapping == 0) {

+ dev_err(dev->dev, "Need to pin %p\n", r);


ret = psb_gtt_pin(r);
if (ret < 0) {

DRM_ERROR("gma500: pin failed: %d\n", ret);

@@ -289,10 +302,13 @@ int psb_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf)


page_offset = ((unsigned long) vmf->virtual_address - vma->vm_start)
>> PAGE_SHIFT;

+ dev_err(dev->dev, "Page offset %p %d\n", r, (int)page_offset);


/* CPU view of the page, don't go via the GART for CPU writes */

pfn = page_to_phys(r->pages[page_offset]) >> PAGE_SHIFT;
ret = vm_insert_pfn(vma, (unsigned long)vmf->virtual_address, pfn);

+ dev_err(dev->dev, "PFN %ld for VA %p = %d\n", pfn, vmf->virtual_address, ret);
+


fail:
mutex_unlock(&dev->struct_mutex);
switch (ret) {

diff --git a/drivers/staging/gma500/psb_gtt.c b/drivers/staging/gma500/psb_gtt.c
index 5a296e1..c6a7492 100644
--- a/drivers/staging/gma500/psb_gtt.c
+++ b/drivers/staging/gma500/psb_gtt.c
@@ -314,6 +314,7 @@ struct gtt_range *psb_gtt_alloc_range(struct drm_device *dev, int len,


len, start, end, PAGE_SIZE, NULL, NULL);
if (ret == 0) {

gt->offset = gt->resource.start - r->start;

+ dev_err(dev->dev, "GTT new %p, %d\n", gt, gt->stolen);
return gt;
}
kfree(gt);
@@ -340,6 +341,7 @@ static void psb_gtt_destroy(struct kref *kref)


}
WARN_ON(gt->in_gart && !gt->stolen);
release_resource(&gt->resource);

+ pr_err("GTT destroyed %p, %d\n", gt, gt->stolen);
kfree(gt);
}

Alan Cox

unread,
Jun 16, 2011, 12:08:44 PM6/16/11
to gr...@kroah.com, linux-...@vger.kernel.org
From: Alan Cox <al...@linux.intel.com>

Signed-off-by: Alan Cox <al...@linux.intel.com>
---

drivers/staging/gma500/psb_fb.c | 6 +-----


drivers/staging/gma500/psb_gem.c | 11 -----------
drivers/staging/gma500/psb_gtt.c | 2 --
3 files changed, 1 insertions(+), 18 deletions(-)

diff --git a/drivers/staging/gma500/psb_fb.c b/drivers/staging/gma500/psb_fb.c
index d005025..156f8ad 100644
--- a/drivers/staging/gma500/psb_fb.c
+++ b/drivers/staging/gma500/psb_fb.c
@@ -727,17 +727,13 @@ static void psb_user_framebuffer_destroy(struct drm_framebuffer *fb)



/* Should never get stolen memory for a user fb */

WARN_ON(r->stolen);
- pr_err("user framebuffer destroy %p, fbdev %p\n",
- psbfb, psbfb->fbdev);
+
/* Check if we are erroneously live */
list_for_each_entry(crtc, &dev->mode_config.crtc_list, head)
if (crtc->fb == fb)
reset = 1;

if (reset)

- pr_err("DRM: gma500, forcing reset\n");
-


- if (reset)
/*
* Now force a sane response before we permit the DRM crc layer to
* do stupid things like blank the display. Instead we reset this

diff --git a/drivers/staging/gma500/psb_gem.c b/drivers/staging/gma500/psb_gem.c
index b24b964..125ea6b 100644
--- a/drivers/staging/gma500/psb_gem.c
+++ b/drivers/staging/gma500/psb_gem.c
@@ -51,7 +51,6 @@ void psb_gem_free_object(struct drm_gem_object *obj)


}
drm_gem_object_release(obj);
/* This must occur last as it frees up the memory of the GEM object */

- pr_err("GEM destroyed %p, %p\n", gtt, obj);
psb_gtt_free_range(obj->dev, gtt);
}

@@ -177,8 +176,6 @@ static int psb_gem_create(struct drm_file *file,

size = roundup(size, PAGE_SIZE);

- dev_err(dev->dev, "GEM creating %lld\n", size);
-


/* Allocate our object - for now a direct gtt range which is not
stolen memory backed */
r = psb_gtt_alloc_range(dev, size, "gem", 0);

@@ -206,8 +203,6 @@ static int psb_gem_create(struct drm_file *file,


/* We have the initial and handle reference but need only one now */
drm_gem_object_unreference(&r->gem);
*handlep = handle;

- dev_err(dev->dev, "GEM handle %x for %p OK\n",
- handle, &r->gem);
return 0;
}

@@ -283,12 +278,9 @@ int psb_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf)


something from beneath our feet */
mutex_lock(&dev->struct_mutex);

- dev_err(dev->dev, "Fault on GTT %p\n", r);
-


/* For now the mmap pins the object and it stays pinned. As things
stand that will do us no harm */
if (r->mmapping == 0) {

- dev_err(dev->dev, "Need to pin %p\n", r);


ret = psb_gtt_pin(r);
if (ret < 0) {
DRM_ERROR("gma500: pin failed: %d\n", ret);

@@ -302,13 +294,10 @@ int psb_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf)


page_offset = ((unsigned long) vmf->virtual_address - vma->vm_start)
>> PAGE_SHIFT;

- dev_err(dev->dev, "Page offset %p %d\n", r, (int)page_offset);


/* CPU view of the page, don't go via the GART for CPU writes */
pfn = page_to_phys(r->pages[page_offset]) >> PAGE_SHIFT;
ret = vm_insert_pfn(vma, (unsigned long)vmf->virtual_address, pfn);

- dev_err(dev->dev, "PFN %ld for VA %p = %d\n", pfn, vmf->virtual_address, ret);
-


fail:
mutex_unlock(&dev->struct_mutex);
switch (ret) {
diff --git a/drivers/staging/gma500/psb_gtt.c b/drivers/staging/gma500/psb_gtt.c

index c6a7492..5a296e1 100644
--- a/drivers/staging/gma500/psb_gtt.c
+++ b/drivers/staging/gma500/psb_gtt.c
@@ -314,7 +314,6 @@ struct gtt_range *psb_gtt_alloc_range(struct drm_device *dev, int len,


len, start, end, PAGE_SIZE, NULL, NULL);
if (ret == 0) {
gt->offset = gt->resource.start - r->start;

- dev_err(dev->dev, "GTT new %p, %d\n", gt, gt->stolen);
return gt;
}
kfree(gt);
@@ -341,7 +340,6 @@ static void psb_gtt_destroy(struct kref *kref)


}
WARN_ON(gt->in_gart && !gt->stolen);
release_resource(&gt->resource);

- pr_err("GTT destroyed %p, %d\n", gt, gt->stolen);
kfree(gt);
}

Alan Cox

unread,
Jun 16, 2011, 12:08:28 PM6/16/11
to gr...@kroah.com, linux-...@vger.kernel.org
From: Alan Cox <al...@linux.intel.com>

If we get a user frame buffer destroyed which is being displayed then clean
up the mess nicely. We can now run a slightly modified modetest including setting
modes, and handling crashes.

Modetest still blows up but this is because libdrm 2.4.25 is busted.


Signed-off-by: Alan Cox <al...@linux.intel.com>
---

drivers/staging/gma500/psb_fb.c | 24 +++++++++++++++++++++++-
drivers/staging/gma500/psb_intel_display.c | 22 +++++++++++++---------
2 files changed, 36 insertions(+), 10 deletions(-)

diff --git a/drivers/staging/gma500/psb_fb.c b/drivers/staging/gma500/psb_fb.c
index 5977add..d005025 100644
--- a/drivers/staging/gma500/psb_fb.c
+++ b/drivers/staging/gma500/psb_fb.c
@@ -719,16 +719,38 @@ static void psb_user_framebuffer_destroy(struct drm_framebuffer *fb)
{


struct psb_framebuffer *psbfb = to_psb_fb(fb);
struct gtt_range *r = psbfb->gtt;

+ struct drm_device *dev = fb->dev;
+ struct drm_psb_private *dev_priv = dev->dev_private;
+ struct psb_fbdev *fbdev = dev_priv->fbdev;
+ struct drm_crtc *crtc;
+ int reset = 0;



/* Should never get stolen memory for a user fb */
WARN_ON(r->stolen);

pr_err("user framebuffer destroy %p, fbdev %p\n",

psbfb, psbfb->fbdev);
+ /* Check if we are erroneously live */

+ list_for_each_entry(crtc, &dev->mode_config.crtc_list, head)
+ if (crtc->fb == fb)
+ reset = 1;
+
+ if (reset)
+ pr_err("DRM: gma500, forcing reset\n");
+
+ if (reset)
+ /*
+ * Now force a sane response before we permit the DRM crc layer to
+ * do stupid things like blank the display. Instead we reset this
+ * framebuffer as if the user had forced a reset. We must do this
+ * before the cleanup so that the DRM layer doesn't get a chance
+ * to stick its oar in where it isn't wanted.
+ */
+ drm_fb_helper_restore_fbdev_mode(&fbdev->psb_fb_helper);
+


/* Let DRM do its clean up */
drm_framebuffer_cleanup(fb);
/* We are no longer using the resource in GEM */

drm_gem_object_unreference_unlocked(&r->gem);
-
kfree(fb);
}

diff --git a/drivers/staging/gma500/psb_intel_display.c b/drivers/staging/gma500/psb_intel_display.c
index a99271d..c7c55b1 100644
--- a/drivers/staging/gma500/psb_intel_display.c
+++ b/drivers/staging/gma500/psb_intel_display.c
@@ -352,15 +352,15 @@ int psb_intel_pipe_set_base(struct drm_crtc *crtc,

PSB_DEBUG_ENTRY("\n");

+ if (!gma_power_begin(dev, true))
+ return 0;
+


/* no fb bound */
if (!crtc->fb) {

DRM_DEBUG("No FB bound\n");

- return 0;
+ goto psb_intel_pipe_cleaner;
}

- if (!gma_power_begin(dev, true))
- return 0;
-
/* We are displaying this buffer, make sure it is actually loaded
into the GTT */
ret = psb_gtt_pin(psbfb->gtt);
@@ -409,6 +409,7 @@ int psb_intel_pipe_set_base(struct drm_crtc *crtc,
REG_READ(dspbase);
}

+psb_intel_pipe_cleaner:
/* If there was a previous display we can now unpin it */
if (old_fb)
psb_gtt_unpin(to_psb_fb(old_fb)->gtt);
@@ -588,6 +589,7 @@ static int psb_intel_crtc_mode_set(struct drm_crtc *crtc,


{
struct drm_device *dev = crtc->dev;
struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc);

+ struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;


int pipe = psb_intel_crtc->pipe;

int fp_reg = (pipe == 0) ? FPA0 : FPB0;
int dpll_reg = (pipe == 0) ? DPLL_A : DPLL_B;
@@ -610,6 +612,12 @@ static int psb_intel_crtc_mode_set(struct drm_crtc *crtc,
struct drm_mode_config *mode_config = &dev->mode_config;
struct drm_connector *connector;

+ /* No scan out no play */
+ if (crtc->fb == NULL) {
+ crtc_funcs->mode_set_base(crtc, x, y, old_fb);


+ return 0;
+ }
+

list_for_each_entry(connector, &mode_config->connector_list, head) {
struct psb_intel_output *psb_intel_output =
to_psb_intel_output(connector);
@@ -786,11 +794,7 @@ static int psb_intel_crtc_mode_set(struct drm_crtc *crtc,
REG_WRITE(dspcntr_reg, dspcntr);

/* Flush the plane changes */
- {
- struct drm_crtc_helper_funcs *crtc_funcs =
- crtc->helper_private;
- crtc_funcs->mode_set_base(crtc, x, y, old_fb);
- }
+ crtc_funcs->mode_set_base(crtc, x, y, old_fb);

psb_intel_wait_for_vblank(dev);

Alan Cox

unread,
Jun 16, 2011, 12:09:01 PM6/16/11
to gr...@kroah.com, linux-...@vger.kernel.org
From: Alan Cox <al...@linux.intel.com>

Give the driver its own proper DRM name, clean up copyright headers and so
forth

Signed-off-by: Alan Cox <al...@linux.intel.com>
---

drivers/staging/gma500/mrst_crtc.c | 4 +
drivers/staging/gma500/mrst_lvds.c | 2 -
drivers/staging/gma500/psb_2d.c | 7 --
drivers/staging/gma500/psb_bl.c | 4 +
drivers/staging/gma500/psb_drm.h | 90 +-------------------------------
drivers/staging/gma500/psb_drv.c | 4 +
drivers/staging/gma500/psb_drv.h | 85 +++++++++++++++---------------
drivers/staging/gma500/psb_fb.c | 3 -
drivers/staging/gma500/psb_fb.h | 3 -
drivers/staging/gma500/psb_gtt.h | 7 +-
drivers/staging/gma500/psb_intel_drv.h | 19 +------
drivers/staging/gma500/psb_irq.h | 8 +--
drivers/staging/gma500/psb_powermgmt.c | 4 +
drivers/staging/gma500/psb_powermgmt.h | 2 -
drivers/staging/gma500/psb_reg.h | 2 -
15 files changed, 67 insertions(+), 177 deletions(-)

diff --git a/drivers/staging/gma500/mrst_crtc.c b/drivers/staging/gma500/mrst_crtc.c
index e4a0c03..fd97c80 100644
--- a/drivers/staging/gma500/mrst_crtc.c
+++ b/drivers/staging/gma500/mrst_crtc.c
@@ -86,7 +86,7 @@ static const struct mrst_limit_t *mrst_limit(struct drm_crtc *crtc)
{
const struct mrst_limit_t *limit = NULL;


struct drm_device *dev = crtc->dev;

- DRM_DRIVER_PRIVATE_T *dev_priv = dev->dev_private;


+ struct drm_psb_private *dev_priv = dev->dev_private;

if (psb_intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)
|| psb_intel_pipe_has_type(crtc, INTEL_OUTPUT_MIPI)) {
@@ -296,7 +296,7 @@ static int mrst_crtc_mode_set(struct drm_crtc *crtc,


{
struct drm_device *dev = crtc->dev;
struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc);

- DRM_DRIVER_PRIVATE_T *dev_priv = dev->dev_private;


+ struct drm_psb_private *dev_priv = dev->dev_private;

int pipe = psb_intel_crtc->pipe;

int fp_reg = (pipe == 0) ? MRST_FPA0 : FPB0;
int dpll_reg = (pipe == 0) ? MRST_DPLL_A : DPLL_B;
diff --git a/drivers/staging/gma500/mrst_lvds.c b/drivers/staging/gma500/mrst_lvds.c
index 4a08b74..22ea00e 100644
--- a/drivers/staging/gma500/mrst_lvds.c
+++ b/drivers/staging/gma500/mrst_lvds.c
@@ -46,7 +46,7 @@ static void mrst_lvds_set_power(struct drm_device *dev,
struct psb_intel_output *output, bool on)
{
u32 pp_status;
- DRM_DRIVER_PRIVATE_T *dev_priv = dev->dev_private;


+ struct drm_psb_private *dev_priv = dev->dev_private;

PSB_DEBUG_ENTRY("\n");

if (!gma_power_begin(dev, true))

diff --git a/drivers/staging/gma500/psb_2d.c b/drivers/staging/gma500/psb_2d.c
index 060eeaf..c3d7085 100644
--- a/drivers/staging/gma500/psb_2d.c
+++ b/drivers/staging/gma500/psb_2d.c
@@ -1,5 +1,5 @@
/**************************************************************************
- * Copyright (c) 2007, Intel Corporation.
+ * Copyright (c) 2007-2011, Intel Corporation.
* All Rights Reserved.
*
* This program is free software; you can redistribute it and/or modify it
@@ -396,8 +396,3 @@ int psbfb_sync(struct fb_info *info)
out:
return (busy) ? -EBUSY : 0;
}
-
-/*
- info->fix.accel = FB_ACCEL_I830;
- info->flags = FBINFO_DEFAULT;
-*/
diff --git a/drivers/staging/gma500/psb_bl.c b/drivers/staging/gma500/psb_bl.c
index 5dffc71..2f9674d 100644
--- a/drivers/staging/gma500/psb_bl.c
+++ b/drivers/staging/gma500/psb_bl.c
@@ -1,7 +1,7 @@
/*
- * psb backlight interface
+ * GMA500 Backlight Interface
*
- * Copyright (c) 2009, Intel Corporation.
+ * Copyright (c) 2009-2011, Intel Corporation.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
diff --git a/drivers/staging/gma500/psb_drm.h b/drivers/staging/gma500/psb_drm.h
index 49ffdd5..b005293 100644
--- a/drivers/staging/gma500/psb_drm.h
+++ b/drivers/staging/gma500/psb_drm.h
@@ -1,5 +1,5 @@
/**************************************************************************
- * Copyright (c) 2007, Intel Corporation.
+ * Copyright (c) 2007-2011, Intel Corporation.
* All Rights Reserved.
* Copyright (c) 2008, Tungsten Graphics Inc. Cedar Park, TX., USA.
* All Rights Reserved.
@@ -22,84 +22,8 @@
#ifndef _PSB_DRM_H_
#define _PSB_DRM_H_

-#if defined(__linux__) && !defined(__KERNEL__)
-#include<stdint.h>
-#include <linux/types.h>
-#include "drm_mode.h"
-#endif
-
-#define DRM_PSB_SAREA_MAJOR 0
-#define DRM_PSB_SAREA_MINOR 2
-#define PSB_FIXED_SHIFT 16
-
#define PSB_NUM_PIPE 3

-/*
- * Public memory types.
- */
-
-typedef s32 psb_fixed;
-typedef u32 psb_ufixed;
-
-static inline s32 psb_int_to_fixed(int a)
-{
- return a * (1 << PSB_FIXED_SHIFT);
-}
-
-static inline u32 psb_unsigned_to_ufixed(unsigned int a)
-{
- return a << PSB_FIXED_SHIFT;
-}
-
-/*Status of the command sent to the gfx device.*/
-typedef enum {
- DRM_CMD_SUCCESS,
- DRM_CMD_FAILED,
- DRM_CMD_HANG
-} drm_cmd_status_t;
-
-struct drm_psb_scanout {
- u32 buffer_id; /* DRM buffer object ID */
- u32 rotation; /* Rotation as in RR_rotation definitions */
- u32 stride; /* Buffer stride in bytes */
- u32 depth; /* Buffer depth in bits (NOT) bpp */
- u32 width; /* Buffer width in pixels */
- u32 height; /* Buffer height in lines */
- s32 transform[3][3]; /* Buffer composite transform */
- /* (scaling, rot, reflect) */
-};
-
-#define DRM_PSB_SAREA_OWNERS 16
-#define DRM_PSB_SAREA_OWNER_2D 0
-#define DRM_PSB_SAREA_OWNER_3D 1
-
-#define DRM_PSB_SAREA_SCANOUTS 3
-
-struct drm_psb_sarea {
- /* Track changes of this data structure */
-
- u32 major;
- u32 minor;
-
- /* Last context to touch part of hw */
- u32 ctx_owners[DRM_PSB_SAREA_OWNERS];
-
- /* Definition of front- and rotated buffers */
- u32 num_scanouts;
- struct drm_psb_scanout scanouts[DRM_PSB_SAREA_SCANOUTS];
-
- int planeA_x;
- int planeA_y;
- int planeA_w;
- int planeA_h;
- int planeB_x;
- int planeB_y;
- int planeB_w;
- int planeB_h;
- /* Number of active scanouts */
- u32 num_active_scanouts;
-};
-
#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)
@@ -223,20 +147,14 @@ struct drm_psb_register_rw_arg {

#define DRM_PSB_KMS_OFF 0x00
#define DRM_PSB_KMS_ON 0x01
-#define DRM_PSB_VT_LEAVE 0x02
-#define DRM_PSB_VT_ENTER 0x03
-#define DRM_PSB_EXTENSION 0x06
#define DRM_PSB_SIZES 0x07
#define DRM_PSB_FUSE_REG 0x08
-#define DRM_PSB_VBT 0x09
#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
-#define DRM_PSB_GTT_MAP 0x0F
-#define DRM_PSB_GTT_UNMAP 0x10
-#define DRM_PSB_GETPAGEADDRS 0x11
+
/**
* NOTE: Add new commands here, but increment
* the values below and increment their
@@ -249,10 +167,6 @@ struct drm_psb_register_rw_arg {
#define DRM_PVR_RESERVED4 0x15
#define DRM_PVR_RESERVED5 0x16

-#define DRM_PSB_HIST_ENABLE 0x17
-#define DRM_PSB_HIST_STATUS 0x18
-#define DRM_PSB_UPDATE_GUARD 0x19
-#define DRM_PSB_INIT_COMM 0x1A
#define DRM_PSB_DPST 0x1B
#define DRM_PSB_GAMMA 0x1C
#define DRM_PSB_DPST_BL 0x1D
diff --git a/drivers/staging/gma500/psb_drv.c b/drivers/staging/gma500/psb_drv.c
index aa87b1b..9bd0a5d 100644
--- a/drivers/staging/gma500/psb_drv.c
+++ b/drivers/staging/gma500/psb_drv.c
@@ -1,5 +1,5 @@
/**************************************************************************
- * Copyright (c) 2007, Intel Corporation.
+ * Copyright (c) 2007-2011, Intel Corporation.
* All Rights Reserved.
* Copyright (c) 2008, Tungsten Graphics, Inc. Cedar Park, TX., USA.
* All Rights Reserved.
@@ -1462,6 +1462,6 @@ static void __exit psb_exit(void)
late_initcall(psb_init);
module_exit(psb_exit);

-MODULE_AUTHOR(DRIVER_AUTHOR);
+MODULE_AUTHOR("Alan Cox <al...@linux.intel.com> and others");
MODULE_DESCRIPTION(DRIVER_DESC);
MODULE_LICENSE("GPL");
diff --git a/drivers/staging/gma500/psb_drv.h b/drivers/staging/gma500/psb_drv.h
index e19a454..c0468ee 100644
--- a/drivers/staging/gma500/psb_drv.h
+++ b/drivers/staging/gma500/psb_drv.h
@@ -1,5 +1,5 @@
/**************************************************************************
- * Copyright (c) 2007-2008, Intel Corporation.
+ * Copyright (c) 2007-2011, Intel Corporation.
* All Rights Reserved.
*
* This program is free software; you can redistribute it and/or modify it
@@ -32,40 +32,32 @@
#include "psb_powermgmt.h"
#include "mrst.h"

-/*Append new drm mode definition here, align with libdrm definition*/
+/* Append new drm mode definition here, align with libdrm definition */
#define DRM_MODE_SCALE_NO_SCALE 2

enum {
- CHIP_PSB_8108 = 0,
- CHIP_PSB_8109 = 1,
- CHIP_MRST_4100 = 2,
+ CHIP_PSB_8108 = 0, /* Poulsbo */
+ CHIP_PSB_8109 = 1, /* Poulsbo */
+ CHIP_MRST_4100 = 2, /* Moorestown/Oaktrail */
};

#define IS_MRST(dev) (((dev)->pci_device & 0xfffc) == 0x4100)

/*
- *Hardware bugfixes
+ * Driver definitions
*/

-#define DRIVER_NAME "pvrsrvkm"
-#define DRIVER_DESC "drm driver for the Intel GMA500"
-#define DRIVER_AUTHOR "Intel Corporation"
+#define DRIVER_NAME "gma500"
+#define DRIVER_DESC "DRM driver for the Intel GMA500"

-#define PSB_DRM_DRIVER_DATE "2009-03-10"
-#define PSB_DRM_DRIVER_MAJOR 8
-#define PSB_DRM_DRIVER_MINOR 1
+#define PSB_DRM_DRIVER_DATE "2011-06-06"
+#define PSB_DRM_DRIVER_MAJOR 1
+#define PSB_DRM_DRIVER_MINOR 0
#define PSB_DRM_DRIVER_PATCHLEVEL 0

/*
- *TTM driver private offsets.
+ * Hardware offsets
*/
-
-#define DRM_PSB_FILE_PAGE_OFFSET (0x100000000ULL >> PAGE_SHIFT)
-
-#define PSB_OBJECT_HASH_ORDER 13
-#define PSB_FILE_OBJECT_HASH_ORDER 12
-#define PSB_BO_HASH_ORDER 12
-
#define PSB_VDC_OFFSET 0x00000000
#define PSB_VDC_SIZE 0x000080000
#define MRST_MMIO_SIZE 0x0000C0000
@@ -73,42 +65,52 @@ enum {
#define PSB_SGX_SIZE 0x8000
#define PSB_SGX_OFFSET 0x00040000
#define MRST_SGX_OFFSET 0x00080000
+/*
+ * PCI resource identifiers
+ */
#define PSB_MMIO_RESOURCE 0
#define PSB_GATT_RESOURCE 2
#define PSB_GTT_RESOURCE 3
+/*
+ * PCI configuration
+ */
#define PSB_GMCH_CTRL 0x52
#define PSB_BSM 0x5C
#define _PSB_GMCH_ENABLED 0x4
#define PSB_PGETBL_CTL 0x2020
#define _PSB_PGETBL_ENABLED 0x00000001
#define PSB_SGX_2D_SLAVE_PORT 0x4000
+
+/* To get rid of */
#define PSB_TT_PRIV0_LIMIT (256*1024*1024)
#define PSB_TT_PRIV0_PLIMIT (PSB_TT_PRIV0_LIMIT >> PAGE_SHIFT)
-#define PSB_NUM_VALIDATE_BUFFERS 2048

/*
- *Flags for external memory type field.
+ * SGX side MMU definitions (these can probably go)
*/

+/*
+ * Flags for external memory type field.
+ */
#define PSB_MMU_CACHED_MEMORY 0x0001 /* Bind to MMU only */
#define PSB_MMU_RO_MEMORY 0x0002 /* MMU RO memory */
#define PSB_MMU_WO_MEMORY 0x0004 /* MMU WO memory */
-
/*
- *PTE's and PDE's
+ * PTE's and PDE's
*/
-
#define PSB_PDE_MASK 0x003FFFFF
#define PSB_PDE_SHIFT 22
#define PSB_PTE_SHIFT 12
-
+/*
+ * Cache control
+ */
#define PSB_PTE_VALID 0x0001 /* PTE / PDE valid */
#define PSB_PTE_WO 0x0002 /* Write only */
#define PSB_PTE_RO 0x0004 /* Read only */
#define PSB_PTE_CACHED 0x0008 /* CPU cache coherent */

/*
- *VDC registers and bits
+ * VDC registers and bits
*/
#define PSB_MSVDX_CLOCKGATING 0x2064
#define PSB_TOPAZ_CLOCKGATING 0x2068
@@ -278,7 +280,7 @@ struct drm_psb_private {
int display_count;

/*
- *Modesetting
+ * Modesetting
*/
struct psb_intel_mode_device mode_dev;

@@ -287,12 +289,8 @@ struct drm_psb_private {
uint32_t num_pipe;

/*
- *Memory managers
+ * OSPM info (Power management base) (can go ?)
*/
-
- /*
- *OSPM info
- */
uint32_t ospm_base;

/*
@@ -304,11 +302,11 @@ struct drm_psb_private {
u32 fuse_reg_value;
u32 video_device_fuse;

- /* pci revision id for B0:D2:F0 */
+ /* PCI revision ID for B0:D2:F0 */
uint8_t platform_rev_id;

/*
- *LVDS info
+ * LVDS info
*/
int backlight_duty_cycle; /* restore backlight to this value */
bool panel_wants_dither;
@@ -316,10 +314,10 @@ struct drm_psb_private {
struct drm_display_mode *lfp_lvds_vbt_mode;
struct drm_display_mode *sdvo_lvds_vbt_mode;

- struct bdb_lvds_backlight *lvds_bl; /*LVDS backlight info from VBT*/
+ struct bdb_lvds_backlight *lvds_bl; /* LVDS backlight info from VBT */
struct psb_intel_i2c_chan *lvds_i2c_bus;

- /* Feature bits from the VBIOS*/
+ /* Feature bits from the VBIOS */
unsigned int int_tv_support:1;
unsigned int lvds_dither:1;
unsigned int lvds_vbt:1;
@@ -332,7 +330,7 @@ struct drm_psb_private {
unsigned int core_freq;
uint32_t iLVDS_enable;

- /*runtime PM state*/
+ /* Runtime PM state */
int rpm_enabled;

/* Moorestown specific */
@@ -350,7 +348,7 @@ struct drm_psb_private {
uint32_t dspcntr2;

/*
- *Register state
+ * Register state
*/
uint32_t saveDSPACNTR;
uint32_t saveDSPBCNTR;
@@ -468,7 +466,7 @@ struct drm_psb_private {
u32 lid_last_state;

/*
- *Watchdog
+ * Watchdog
*/

uint32_t apm_reg;
@@ -497,7 +495,7 @@ static inline struct drm_psb_private *psb_priv(struct drm_device *dev)
}

/*
- *MMU stuff.
+ * MMU stuff.
*/

extern struct psb_mmu_driver *psb_mmu_driver_init(uint8_t __iomem * registers,
@@ -525,7 +523,7 @@ extern int psb_mmu_virtual_to_pfn(struct psb_mmu_pd *pd, uint32_t virtual,
unsigned long *pfn);

/*
- *Enable / disable MMU for different requestors.
+ * Enable / disable MMU for different requestors.
*/


@@ -598,7 +596,7 @@ extern int psbfb_2d_submit(struct drm_psb_private *dev_priv, uint32_t *cmdbuf,
unsigned size);

/*
- *psb_reset.c
+ * psb_reset.c
*/

extern void psb_lid_timer_init(struct drm_psb_private *dev_priv);
@@ -710,7 +708,6 @@ extern int drm_idle_check_interval;
/*
*Utilities
*/
-#define DRM_DRIVER_PRIVATE_T struct drm_psb_private



static inline u32 MRST_MSG_READ32(uint port, uint offset)

{
diff --git a/drivers/staging/gma500/psb_fb.c b/drivers/staging/gma500/psb_fb.c
index 156f8ad..0a77abf 100644
--- a/drivers/staging/gma500/psb_fb.c
+++ b/drivers/staging/gma500/psb_fb.c
@@ -1,5 +1,5 @@
/**************************************************************************
- * Copyright (c) 2007, Intel Corporation.
+ * Copyright (c) 2007-2011, Intel Corporation.
* All Rights Reserved.
*
* This program is free software; you can redistribute it and/or modify it
@@ -56,7 +56,6 @@ void *psbfb_vdc_reg(struct drm_device *dev)
dev_priv = (struct drm_psb_private *) dev->dev_private;
return dev_priv->vdc_reg;
}
-/*EXPORT_SYMBOL(psbfb_vdc_reg); */

static int psbfb_setcolreg(unsigned regno, unsigned red, unsigned green,
unsigned blue, unsigned transp,
diff --git a/drivers/staging/gma500/psb_fb.h b/drivers/staging/gma500/psb_fb.h
index fd7e51a..ed6e856 100644
--- a/drivers/staging/gma500/psb_fb.h
+++ b/drivers/staging/gma500/psb_fb.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2008, Intel Corporation
+ * Copyright (c) 2008-2011, Intel Corporation
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
@@ -41,7 +41,6 @@ struct psb_fbdev {
struct psb_framebuffer pfb;
};

-
#define to_psb_fb(x) container_of(x, struct psb_framebuffer, base)

extern int psb_intel_connector_clones(struct drm_device *dev, int type_mask);
diff --git a/drivers/staging/gma500/psb_gtt.h b/drivers/staging/gma500/psb_gtt.h
index 37287eb..7e1f21e 100644
--- a/drivers/staging/gma500/psb_gtt.h
+++ b/drivers/staging/gma500/psb_gtt.h
@@ -22,6 +22,7 @@

#include <drm/drmP.h>

+/* This wants cleaning up with respect to the psb_dev and un-needed stuff */
struct psb_gtt {
struct drm_device *dev;
uint32_t gatt_start;
@@ -41,9 +42,9 @@ extern void psb_gtt_takedown(struct drm_device *dev);

/* Each gtt_range describes an allocation in the GTT area */
struct gtt_range {
- struct resource resource;
- u32 offset;
- struct kref kref;
+ struct resource resource; /* Resource for our allocation */
+ u32 offset; /* GTT offset of our object */
+ struct kref kref; /* Can probably go FIXME - GEM kref will do */


struct drm_gem_object gem; /* GEM high level stuff */
int in_gart; /* Currently in the GART (ref ct) */

bool stolen; /* Backed from stolen RAM */

diff --git a/drivers/staging/gma500/psb_intel_drv.h b/drivers/staging/gma500/psb_intel_drv.h
index 6006ddd..75a95f7 100644
--- a/drivers/staging/gma500/psb_intel_drv.h
+++ b/drivers/staging/gma500/psb_intel_drv.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2009, Intel Corporation.
+ * Copyright (c) 2009-2011, Intel Corporation.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
@@ -26,11 +26,6 @@
#include <linux/gpio.h>

/*
- * MOORESTOWN defines
- */
-#define DELAY_TIME1 2000 /* 1000 = 1ms */
-
-/*
* Display related stuff
*/

@@ -61,16 +56,10 @@
#define INTEL_DVO_CHIP_TMDS 2
#define INTEL_DVO_CHIP_TVOUT 4

-enum mipi_panel_type {
- NSC_800X480 = 1,
- LGE_480X1024 = 2,
- TPO_864X480 = 3
-};
-
-/**
+/*
* Hold information useally put on the device driver privates here,
* since it needs to be shared across multiple of devices drivers privates.
-*/
+ */
struct psb_intel_mode_device {

/*
@@ -79,7 +68,7 @@ struct psb_intel_mode_device {
size_t(*bo_offset) (struct drm_device *dev, void *bo);

/*
- * Cursor
+ * Cursor (Can go ?)
*/
int cursor_needs_physical;

diff --git a/drivers/staging/gma500/psb_irq.h b/drivers/staging/gma500/psb_irq.h
index 3e56f33..216fda3 100644
--- a/drivers/staging/gma500/psb_irq.h
+++ b/drivers/staging/gma500/psb_irq.h
@@ -1,5 +1,5 @@
/**************************************************************************
- * Copyright (c) 2009, Intel Corporation.
+ * Copyright (c) 2009-2011, Intel Corporation.
* All Rights Reserved.
*
* This program is free software; you can redistribute it and/or modify it
@@ -34,10 +34,6 @@ int psb_irq_postinstall(struct drm_device *dev);
void psb_irq_uninstall(struct drm_device *dev);
irqreturn_t psb_irq_handler(DRM_IRQ_ARGS);

-void psb_irq_preinstall_islands(struct drm_device *dev, int hw_islands);
-int psb_irq_postinstall_islands(struct drm_device *dev, int hw_islands);
-void psb_irq_uninstall_islands(struct drm_device *dev, int hw_islands);
-
int psb_irq_enable_dpst(struct drm_device *dev);
int psb_irq_disable_dpst(struct drm_device *dev);
void psb_irq_turn_on_dpst(struct drm_device *dev);
@@ -46,4 +42,4 @@ int psb_enable_vblank(struct drm_device *dev, int pipe);
void psb_disable_vblank(struct drm_device *dev, int pipe);
u32 psb_get_vblank_counter(struct drm_device *dev, int pipe);

-#endif //_SYSIRQ_H_
+#endif /* _SYSIRQ_H_ */
diff --git a/drivers/staging/gma500/psb_powermgmt.c b/drivers/staging/gma500/psb_powermgmt.c
index 1495415..50f2234 100644
--- a/drivers/staging/gma500/psb_powermgmt.c
+++ b/drivers/staging/gma500/psb_powermgmt.c
@@ -1,7 +1,7 @@
/**************************************************************************
- * Copyright (c) 2009, Intel Corporation.
+ * Copyright (c) 2009-2011, Intel Corporation.
* All Rights Reserved.
-
+ *
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
diff --git a/drivers/staging/gma500/psb_powermgmt.h b/drivers/staging/gma500/psb_powermgmt.h
index e005229..333b28d 100644
--- a/drivers/staging/gma500/psb_powermgmt.h
+++ b/drivers/staging/gma500/psb_powermgmt.h
@@ -1,5 +1,5 @@
/**************************************************************************
- * Copyright (c) 2009, Intel Corporation.
+ * Copyright (c) 2009-2011, Intel Corporation.
* All Rights Reserved.

* Permission is hereby granted, free of charge, to any person obtaining a
diff --git a/drivers/staging/gma500/psb_reg.h b/drivers/staging/gma500/psb_reg.h
index 9ad4989..529fda8 100644
--- a/drivers/staging/gma500/psb_reg.h
+++ b/drivers/staging/gma500/psb_reg.h
@@ -573,7 +573,7 @@
#define MDFLD_PWRGT_DISPLAY_C_CNTR 0x00030000
#define MDFLD_PWRGT_DISP_MIPI_CNTR 0x000c0000
#define MDFLD_PWRGT_DISPLAY_CNTR (MDFLD_PWRGT_DISPLAY_A_CNTR | MDFLD_PWRGT_DISPLAY_B_CNTR | MDFLD_PWRGT_DISPLAY_C_CNTR | MDFLD_PWRGT_DISP_MIPI_CNTR)// 0x000fc00c
-// Display SSS register bits are different in A0 vs. B0
+/* Display SSS register bits are different in A0 vs. B0 */
#define PSB_PWRGT_GFX_MASK 0x3
#define MDFLD_PWRGT_DISPLAY_A_STS 0x000000c0
#define MDFLD_PWRGT_DISPLAY_B_STS 0x00000300

Alan Cox

unread,
Jun 16, 2011, 12:34:13 PM6/16/11
to gr...@kroah.com, linux-...@vger.kernel.org
From: Alan Cox <al...@linux.intel.com>

We have a FIXME to do the power management for which the framework now
exists, and we also need to deal with an erratum. Some operations exactly 8
pixels wide or high fail. The work around is to do two smaller ones (see
the Intel released X driver bits) but for console quite frankly if it's
8bits wide and/or high its not worth it so fall back.

Signed-off-by: Alan Cox <al...@linux.intel.com>
---

drivers/staging/gma500/psb_2d.c | 19 +++++++++++++------
1 files changed, 13 insertions(+), 6 deletions(-)

diff --git a/drivers/staging/gma500/psb_2d.c b/drivers/staging/gma500/psb_2d.c
index c3d7085..494bad5 100644
--- a/drivers/staging/gma500/psb_2d.c
+++ b/drivers/staging/gma500/psb_2d.c
@@ -183,10 +183,14 @@ static void psbfb_fillrect_accel(struct fb_info *info,
cfb_fillrect(info, r);
return;
}
-
+ if (!gma_power_begin(dev, false)) {
+ cfb_fillrect(info, r);
+ return;
+ }
psb_accel_2d_fillrect(dev_priv,
offset, stride, format,
r->dx, r->dy, r->width, r->height, r->color);
+ gma_power_end(dev);
}

void psbfb_fillrect(struct fb_info *info,
@@ -198,9 +202,7 @@ void psbfb_fillrect(struct fb_info *info,
if (1 || (info->flags & FBINFO_HWACCEL_DISABLED))
return cfb_fillrect(info, rect);

- /*psb_check_power_state(dev, PSB_DEVICE_SGX); */
psbfb_fillrect_accel(info, rect);
- /* Drop power again here on MRST FIXMEAC */
}

static u32 psb_accel_2d_copy_direction(int xdir, int ydir)
@@ -331,10 +333,15 @@ static void psbfb_copyarea_accel(struct fb_info *info,
return;
}

+ if (!gma_power_begin(dev, false)) {
+ cfb_copyarea(info, a);
+ return;
+ }
psb_accel_2d_copy(dev_priv,
offset, stride, src_format,
offset, stride, dst_format,
a->sx, a->sy, a->dx, a->dy, a->width, a->height);
+ gma_power_end(dev);
}

void psbfb_copyarea(struct fb_info *info,
@@ -343,12 +350,12 @@ void psbfb_copyarea(struct fb_info *info,
if (unlikely(info->state != FBINFO_STATE_RUNNING))
return;

- if (info->flags & FBINFO_HWACCEL_DISABLED)
+ /* Avoid the 8 pixel erratum */
+ if (region->width == 8 || region->height == 8 ||
+ (info->flags & FBINFO_HWACCEL_DISABLED))
return cfb_copyarea(info, region);

- /* psb_check_power_state(dev, PSB_DEVICE_SGX); */
psbfb_copyarea_accel(info, region);
- /* Need to power back off here for MRST FIXMEAC */


}

void psbfb_imageblit(struct fb_info *info, const struct fb_image *image)

--

Alan Cox

unread,
Jun 16, 2011, 12:34:29 PM6/16/11
to gr...@kroah.com, linux-...@vger.kernel.org
From: Alan Cox <al...@linux.intel.com>

We don't seem to need this for our task.

Signed-off-by: Alan Cox <al...@linux.intel.com>
---

drivers/staging/gma500/psb_drv.c | 6 ----
drivers/staging/gma500/psb_gtt.c | 62 ++++++++++++--------------------------
2 files changed, 19 insertions(+), 49 deletions(-)

diff --git a/drivers/staging/gma500/psb_drv.c b/drivers/staging/gma500/psb_drv.c
index 9bd0a5d..ab1da30 100644
--- a/drivers/staging/gma500/psb_drv.c
+++ b/drivers/staging/gma500/psb_drv.c
@@ -409,8 +409,6 @@ static int psb_do_init(struct drm_device *dev)
struct psb_gtt *pg = dev_priv->pg;

uint32_t stolen_gtt;
- uint32_t tt_start;
- uint32_t tt_pages;

int ret = -ENOMEM;

@@ -449,10 +447,6 @@ static int psb_do_init(struct drm_device *dev)

spin_lock_init(&dev_priv->irqmask_lock);

- tt_pages = (pg->gatt_pages < PSB_TT_PRIV0_PLIMIT) ?
- pg->gatt_pages : PSB_TT_PRIV0_PLIMIT;
- tt_start = dev_priv->gatt_free_offset - pg->mmu_gatt_start;
- tt_pages -= tt_start >> PAGE_SHIFT;


/* FIXME: can we kill ta_mem_size ? */

dev_priv->sizes.ta_mem_size = 0;

diff --git a/drivers/staging/gma500/psb_gtt.c b/drivers/staging/gma500/psb_gtt.c
index 5a296e1..8fcb833 100644
--- a/drivers/staging/gma500/psb_gtt.c
+++ b/drivers/staging/gma500/psb_gtt.c
@@ -138,8 +138,6 @@ static void psb_gtt_remove(struct drm_device *dev, struct gtt_range *r)
*
* 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
- *
- * FIXME: Do we need to cache flush when we update the GTT
*/


static int psb_gtt_attach_pages(struct gtt_range *gt)

{
@@ -185,8 +183,6 @@ err:


* Undo the effect of psb_gtt_attach_pages. At this point the pages

* must have been removed from the GTT as they could now be paged out
* and move bus address.

- *
- * FIXME: Do we need to cache flush when we update the GTT
*/


static void psb_gtt_detach_pages(struct gtt_range *gt)

{
@@ -194,7 +190,6 @@ static void psb_gtt_detach_pages(struct gtt_range *gt)


for (i = 0; i < gt->npage; i++) {
/* FIXME: do we need to force dirty */
set_page_dirty(gt->pages[i]);

- /* Undo the reference we took when populating the table */
page_cache_release(gt->pages[i]);
}
kfree(gt->pages);
@@ -384,7 +379,6 @@ void psb_gtt_takedown(struct drm_device *dev)
{


struct drm_psb_private *dev_priv = dev->dev_private;

- /* FIXME: iounmap dev_priv->vram_addr etc */
if (dev_priv->gtt_map) {
iounmap(dev_priv->gtt_map);
dev_priv->gtt_map = NULL;
@@ -395,6 +389,8 @@ void psb_gtt_takedown(struct drm_device *dev)
PSB_WVDC32(dev_priv->pge_ctl, PSB_PGETBL_CTL);
(void) PSB_RVDC32(PSB_PGETBL_CTL);
}
+ if (dev_priv->vram_addr)
+ iounmap(dev_priv->gtt_map);
kfree(dev_priv->pg);
dev_priv->pg = NULL;
}
@@ -407,8 +403,6 @@ int psb_gtt_init(struct drm_device *dev, int resume)
unsigned i, num_pages;
unsigned pfn_base;
uint32_t vram_pages;
- uint32_t tt_pages;
- uint32_t *ttm_gtt_map;
uint32_t dvmt_mode = 0;
struct psb_gtt *pg;

@@ -421,6 +415,7 @@ int psb_gtt_init(struct drm_device *dev, int resume)
if (pg == NULL)
return -ENOMEM;

+ /* Enable the GTT */


pci_read_config_word(dev->pdev, PSB_GMCH_CTRL, &dev_priv->gmch_ctrl);
pci_write_config_word(dev->pdev, PSB_GMCH_CTRL,

dev_priv->gmch_ctrl | _PSB_GMCH_ENABLED);
@@ -431,30 +426,26 @@ int psb_gtt_init(struct drm_device *dev, int resume)

/* The root resource we allocate address space from */
dev_priv->gtt_mem = &dev->pdev->resource[PSB_GATT_RESOURCE];
-
dev_priv->gtt_initialized = 1;

pg->gtt_phys_start = dev_priv->pge_ctl & PAGE_MASK;

pg->gatt_start = pci_resource_start(dev->pdev, PSB_GATT_RESOURCE);
- /* fix me: video mmu has hw bug to access 0x0D0000000,
- * then make gatt start at 0x0e000,0000 */
+ /*
+ * FIXME: video mmu has hw bug to access 0x0D0000000,
+ * then make gatt start at 0x0e000,0000
+ */
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;
- pg->gatt_pages = pci_resource_len(dev->pdev, PSB_GATT_RESOURCE)
- >> PAGE_SHIFT;
+ gtt_pages = pci_resource_len(dev->pdev, PSB_GTT_RESOURCE) >> PAGE_SHIFT;
+ pg->gatt_pages = pci_resource_len(dev->pdev, PSB_GATT_RESOURCE) >> PAGE_SHIFT;

pci_read_config_dword(dev->pdev, PSB_BSM, &dev_priv->stolen_base);
vram_stolen_size = pg->gtt_phys_start - dev_priv->stolen_base - PAGE_SIZE;

stolen_size = vram_stolen_size;

- printk(KERN_INFO"GMMADR(region 0) start: 0x%08x (%dM).\n",
- pg->gatt_start, pg->gatt_pages/256);
- printk(KERN_INFO"GTTADR(region 3) start: 0x%08x (can map %dM RAM), and actual RAM base 0x%08x.\n",
- pg->gtt_start, gtt_pages * 4, pg->gtt_phys_start);
printk(KERN_INFO "Stolen memory information\n");
printk(KERN_INFO " base in RAM: 0x%x\n", dev_priv->stolen_base);
printk(KERN_INFO " size: %luK, calculated by (GTT RAM base) - (Stolen base), seems wrong\n",
@@ -473,8 +464,11 @@ int psb_gtt_init(struct drm_device *dev, int resume)
pg->gtt_pages = gtt_pages;
pg->stolen_size = stolen_size;
dev_priv->vram_stolen_size = vram_stolen_size;
- dev_priv->gtt_map =
- ioremap_nocache(pg->gtt_phys_start, gtt_pages << PAGE_SHIFT);
+
+ /*
+ * Map the GTT and the stolen memory area
+ */
+ dev_priv->gtt_map = ioremap_nocache(pg->gtt_phys_start, gtt_pages << PAGE_SHIFT);
if (!dev_priv->gtt_map) {


DRM_ERROR("Failure to map gtt.\n");

ret = -ENOMEM;
@@ -488,15 +482,8 @@ int psb_gtt_init(struct drm_device *dev, int resume)
goto out_err;
}

- DRM_DEBUG("gma500: vram kernel virtual address %p\n", dev_priv->vram_addr);
-
- tt_pages = (pg->gatt_pages < PSB_TT_PRIV0_PLIMIT) ?
- (pg->gatt_pages) : PSB_TT_PRIV0_PLIMIT;
-
- ttm_gtt_map = dev_priv->gtt_map + tt_pages / 2;
-
/*
- * insert vram stolen pages.
+ * Insert vram stolen pages into the GTT
*/

pfn_base = dev_priv->stolen_base >> PAGE_SHIFT;
@@ -509,26 +496,15 @@ int psb_gtt_init(struct drm_device *dev, int resume)
}

/*
- * Init rest of gtt managed by IMG.
- */
- pfn_base = page_to_pfn(dev_priv->scratch_page);
- pte = psb_gtt_mask_pte(pfn_base, 0);
- for (; i < tt_pages / 2 - 1; ++i)
- iowrite32(pte, dev_priv->gtt_map + i);
-
- /*
- * Init rest of gtt managed by TTM.
+ * Init rest of GTT to the scratch page to avoid accidents or scribbles
*/

pfn_base = page_to_pfn(dev_priv->scratch_page);
pte = psb_gtt_mask_pte(pfn_base, 0);
- PSB_DEBUG_INIT("Initializing the rest of a total "
- "of %d gtt pages.\n", pg->gatt_pages);
+ for (; i < gtt_pages; ++i)
+ iowrite32(pte, dev_priv->gtt_map + i);

- for (; i < pg->gatt_pages - tt_pages / 2; ++i)
- iowrite32(pte, ttm_gtt_map + i);
(void) ioread32(dev_priv->gtt_map + i - 1);
-
return 0;

out_err:

Alan Cox

unread,
Jun 16, 2011, 12:34:48 PM6/16/11
to gr...@kroah.com, linux-...@vger.kernel.org
From: Alan Cox <al...@linux.intel.com>

Lose all the PSB debug gunge. We can replace it with dev_dbg() like normal
drivers if and when we need debug on stuff.

Signed-off-by: Alan Cox <al...@linux.intel.com>
---

drivers/staging/gma500/mrst_crtc.c | 23 ++----


drivers/staging/gma500/mrst_lvds.c | 12 +--
drivers/staging/gma500/psb_bl.c | 8 --
drivers/staging/gma500/psb_drv.c | 33 +++------
drivers/staging/gma500/psb_drv.h | 96 +++-----------------------
drivers/staging/gma500/psb_fb.c | 34 +--------
drivers/staging/gma500/psb_gem.c | 6 +-
drivers/staging/gma500/psb_gtt.c | 6 +-
drivers/staging/gma500/psb_intel_bios.c | 17 +----
drivers/staging/gma500/psb_intel_display.c | 99 +++------------------------
drivers/staging/gma500/psb_intel_lvds.c | 53 ++------------
drivers/staging/gma500/psb_intel_opregion.c | 7 --
drivers/staging/gma500/psb_intel_sdvo.c | 34 ++++-----
drivers/staging/gma500/psb_irq.c | 33 ++-------

14 files changed, 87 insertions(+), 374 deletions(-)

diff --git a/drivers/staging/gma500/mrst_crtc.c b/drivers/staging/gma500/mrst_crtc.c
index fd97c80..fb9f2a2 100644
--- a/drivers/staging/gma500/mrst_crtc.c
+++ b/drivers/staging/gma500/mrst_crtc.c
@@ -103,7 +103,7 @@ static const struct mrst_limit_t *mrst_limit(struct drm_crtc *crtc)


}
} else {
limit = NULL;
- PSB_DEBUG_ENTRY("mrst_limit Wrong display type.\n");
+ dev_err(dev->dev, "mrst_limit Wrong display type.\n");
}

return limit;
@@ -117,7 +117,7 @@ static void mrst_clock(int refclk, struct mrst_clock_t *clock)

void mrstPrintPll(char *prefix, struct mrst_clock_t *clock)
{
- PSB_DEBUG_ENTRY("%s: dotclock = %d, m = %d, p1 = %d.\n",
+ pr_debug("%s: dotclock = %d, m = %d, p1 = %d.\n",
prefix, clock->dot, clock->m, clock->p1);
}

@@ -149,8 +149,7 @@ mrstFindBestPLL(struct drm_crtc *crtc, int target, int refclk,
}
}
}
- DRM_DEBUG("mrstFindBestPLL err = %d.\n", err);
-
+ dev_dbg(crtc->dev->dev, "mrstFindBestPLL err = %d.\n", err);
return err != target;
}

@@ -172,8 +171,6 @@ static void mrst_crtc_dpms(struct drm_crtc *crtc, int mode)
u32 temp;
bool enabled;

- PSB_DEBUG_ENTRY("mode = %d, pipe = %d\n", mode, pipe);
-
if (!gma_power_begin(dev, true))
return;

@@ -320,8 +317,6 @@ static int mrst_crtc_mode_set(struct drm_crtc *crtc,


uint64_t scalingType = DRM_MODE_SCALE_FULLSCREEN;
struct drm_encoder *encoder;

- PSB_DEBUG_ENTRY("pipe = 0x%x\n", pipe);
-
if (!gma_power_begin(dev, true))
return 0;

@@ -446,10 +441,9 @@ static int mrst_crtc_mode_set(struct drm_crtc *crtc,


ok = mrstFindBestPLL(crtc, adjusted_mode->clock, refclk, &clock);

if (!ok) {
- PSB_DEBUG_ENTRY(
- "mrstFindBestPLL fail in mrst_crtc_mode_set.\n");
+ dev_dbg(dev->dev, "mrstFindBestPLL fail in mrst_crtc_mode_set.\n");
} else {
- PSB_DEBUG_ENTRY("mrst_crtc_mode_set pixel clock = %d,"
+ dev_dbg(dev->dev, "mrst_crtc_mode_set pixel clock = %d,"
"m = %x, p1 = %x.\n", clock.dot, clock.m,
clock.p1);
}
@@ -540,11 +534,9 @@ int mrst_pipe_set_base(struct drm_crtc *crtc,
u32 dspcntr;
int ret = 0;

- PSB_DEBUG_ENTRY("\n");
-

/* no fb bound */
if (!crtc->fb) {

- DRM_DEBUG("No FB bound\n");
+ dev_dbg(dev->dev, "No FB bound\n");


return 0;
}

@@ -574,13 +566,12 @@ int mrst_pipe_set_base(struct drm_crtc *crtc,
dspcntr |= DISPPLANE_32BPP_NO_ALPHA;
break;
default:
- DRM_ERROR("Unknown color depth\n");
+ dev_err(dev->dev, "Unknown color depth\n");
ret = -EINVAL;
goto pipe_set_base_exit;
}
REG_WRITE(dspcntr_reg, dspcntr);

- DRM_DEBUG("Writing base %08lX %08lX %d %d\n", start, offset, x, y);
if (0 /* FIXMEAC - check what PSB needs */) {
REG_WRITE(dspbase, offset);
REG_READ(dspbase);

diff --git a/drivers/staging/gma500/mrst_lvds.c b/drivers/staging/gma500/mrst_lvds.c
index 22ea00e..aac80cc 100644
--- a/drivers/staging/gma500/mrst_lvds.c
+++ b/drivers/staging/gma500/mrst_lvds.c
@@ -47,7 +47,6 @@ static void mrst_lvds_set_power(struct drm_device *dev,
{
u32 pp_status;


struct drm_psb_private *dev_priv = dev->dev_private;

- PSB_DEBUG_ENTRY("\n");

if (!gma_power_begin(dev, true))

diff --git a/drivers/staging/gma500/psb_bl.c b/drivers/staging/gma500/psb_bl.c
index 2f9674d..4a00047 100644
--- a/drivers/staging/gma500/psb_bl.c
+++ b/drivers/staging/gma500/psb_bl.c

diff --git a/drivers/staging/gma500/psb_drv.c b/drivers/staging/gma500/psb_drv.c
index ab1da30..6ea06dd 100644
--- a/drivers/staging/gma500/psb_drv.c
+++ b/drivers/staging/gma500/psb_drv.c

@@ -413,7 +412,7 @@ static int psb_do_init(struct drm_device *dev)


int ret = -ENOMEM;

if (pg->mmu_gatt_start & 0x0FFFFFFF) {
- DRM_ERROR("Gatt must be 256M aligned. This is a bug.\n");
+ dev_err(dev->dev, "Gatt must be 256M aligned. This is a bug.\n");
ret = -EINVAL;
goto out_err;
}

@@ -447,9 +446,6 @@ static int psb_do_init(struct drm_device *dev)

spin_lock_init(&dev_priv->irqmask_lock);

- /* FIXME: can we kill ta_mem_size ? */

struct drm_psb_private *dev_priv = dev->dev_private;

static unsigned int runtime_allowed;
- unsigned int nr = DRM_IOCTL_NR(cmd);
-
- DRM_DEBUG("cmd = %x, nr = %x\n", cmd, nr);

if (runtime_allowed == 1 && dev_priv->is_lvds_on) {
runtime_allowed++;
@@ -1439,7 +1428,7 @@ 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))
- DRM_ERROR("Enable MSI failed!\n");
+ dev_warn(&pdev->dev, "Enable MSI failed!\n");
return drm_get_pci_dev(pdev, ent, &driver);
}

diff --git a/drivers/staging/gma500/psb_drv.h b/drivers/staging/gma500/psb_drv.h
index c0468ee..45752aa 100644
--- a/drivers/staging/gma500/psb_drv.h
+++ b/drivers/staging/gma500/psb_drv.h
@@ -659,54 +659,12 @@ extern int psb_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf);

static inline u32 MRST_MSG_READ32(uint port, uint offset)

@@ -749,19 +707,15 @@ static inline void MDFLD_MSG_WRITE32(uint port, uint offset, u32 value)
static inline uint32_t REGISTER_READ(struct drm_device *dev, uint32_t reg)

{
struct drm_psb_private *dev_priv = dev->dev_private;

- int reg_val = ioread32(dev_priv->vdc_reg + (reg));


- PSB_DEBUG_REG("reg = 0x%x. reg_val = 0x%x. \n", reg, reg_val);
- return reg_val;
+ return ioread32(dev_priv->vdc_reg + reg);
}

#define REG_READ(reg) REGISTER_READ(dev, (reg))
+
static inline void REGISTER_WRITE(struct drm_device *dev, uint32_t reg,
uint32_t val)

{
struct drm_psb_private *dev_priv = dev->dev_private;

- if ((reg < 0x70084 || reg >0x70088) && (reg < 0xa000 || reg >0xa3ff))


- PSB_DEBUG_REG("reg = 0x%x, val = 0x%x. \n", reg, val);
-
iowrite32((val), dev_priv->vdc_reg + (reg));
}

@@ -771,9 +725,6 @@ static inline void REGISTER_WRITE16(struct drm_device *dev,
uint32_t reg, uint32_t val)

{
struct drm_psb_private *dev_priv = dev->dev_private;
-

- PSB_DEBUG_REG("reg = 0x%x, val = 0x%x. \n", reg, val);
-
iowrite16((val), dev_priv->vdc_reg + (reg));
}

@@ -783,20 +734,13 @@ static inline void REGISTER_WRITE8(struct drm_device *dev,
uint32_t reg, uint32_t val)

{
struct drm_psb_private *dev_priv = dev->dev_private;
-

diff --git a/drivers/staging/gma500/psb_fb.c b/drivers/staging/gma500/psb_fb.c
index 0a77abf..988f4db 100644
--- a/drivers/staging/gma500/psb_fb.c
+++ b/drivers/staging/gma500/psb_fb.c


@@ -100,7 +100,6 @@ static int psbfb_kms_off(struct drm_device *dev, int suspend)
{
struct drm_framebuffer *fb = 0;

struct psb_framebuffer *psbfb = to_psb_fb(fb);

- DRM_DEBUG("psbfb_kms_off_ioctl\n");

mutex_lock(&dev->mode_config.mutex);
list_for_each_entry(fb, &dev->mode_config.fb_list, head) {
@@ -134,8 +133,6 @@ static int psbfb_kms_on(struct drm_device *dev, int resume)
struct drm_framebuffer *fb = 0;

struct psb_framebuffer *psbfb = to_psb_fb(fb);

- DRM_DEBUG("psbfb_kms_on_ioctl\n");
-
mutex_lock(&dev->mode_config.mutex);
list_for_each_entry(fb, &dev->mode_config.fb_list, head) {
struct fb_info *info = psbfb->fbdev;

@@ -217,12 +214,10 @@ static int psbfb_vm_fault(struct vm_area_struct *vma, struct vm_fault *vmf)



static void psbfb_vm_open(struct vm_area_struct *vma)
{
- DRM_DEBUG("vm_open\n");
}

static void psbfb_vm_close(struct vm_area_struct *vma)
{
- DRM_DEBUG("vm_close\n");
}

static struct vm_operations_struct psbfb_vm_ops = {

@@ -237,7 +232,6 @@ static int psbfb_mmap(struct fb_info *info, struct vm_area_struct *vma)


struct psb_framebuffer *psbfb = &fbdev->pfb;

char *fb_screen_base = NULL;
struct drm_device *dev = psbfb->base.dev;
- struct drm_psb_private *dev_priv = dev->dev_private;



if (vma->vm_pgoff != 0)
return -EINVAL;

@@ -249,10 +243,6 @@ static int psbfb_mmap(struct fb_info *info, struct vm_area_struct *vma)



fb_screen_base = (char *)info->screen_base;

- DRM_DEBUG("vm_pgoff 0x%lx, screen base %p vram_addr %p\n",
- vma->vm_pgoff, fb_screen_base,
- dev_priv->vram_addr);
-

/* If this is a GEM object then info->screen_base is the virtual

kernel remapping of the object. FIXME: Review if this is

suitable for our mmap work */

@@ -523,14 +513,10 @@ static int psbfb_create(struct psb_fbdev *fbdev,


info->pixmap.flags = FB_PIXMAP_SYSTEM;
info->pixmap.scan_align = 1;

- DRM_DEBUG("fb depth is %d\n", fb->depth);
- DRM_DEBUG(" pitch is %d\n", fb->pitch);
-
- printk(KERN_INFO"allocated %dx%d fb\n",
- psbfb->base.width, psbfb->base.height);
+ dev_info(dev->dev, "allocated %dx%d fb\n",
+ psbfb->base.width, psbfb->base.height);

mutex_unlock(&dev->struct_mutex);
-
return 0;
out_unref:
if (backing->stolen)

@@ -575,13 +561,11 @@ static struct drm_framebuffer *psb_user_framebuffer_create


static void psbfb_gamma_set(struct drm_crtc *crtc, u16 red, u16 green,

u16 blue, int regno)
{
- DRM_DEBUG("%s\n", __func__);
}

static void psbfb_gamma_get(struct drm_crtc *crtc, u16 *red,
u16 *green, u16 *blue, int regno)
{
- DRM_DEBUG("%s\n", __func__);
}

static int psbfb_probe(struct drm_fb_helper *helper,
@@ -591,8 +575,6 @@ static int psbfb_probe(struct drm_fb_helper *helper,
int new_fb = 0;
int ret;

- DRM_DEBUG("%s\n", __func__);
-
if (!helper->fb) {
ret = psbfb_create(psb_fbdev, sizes);
if (ret)
@@ -650,7 +632,7 @@ int psb_fbdev_init(struct drm_device *dev)

fbdev = kzalloc(sizeof(struct psb_fbdev), GFP_KERNEL);
if (!fbdev) {
- DRM_ERROR("no memory\n");

+ dev_err(dev->dev, "no memory\n");


return -ENOMEM;
}

@@ -781,8 +763,6 @@ static void psb_setup_outputs(struct drm_device *dev)

(struct drm_psb_private *) dev->dev_private;

diff --git a/drivers/staging/gma500/psb_gem.c b/drivers/staging/gma500/psb_gem.c
index 125ea6b..7f6f479 100644
--- a/drivers/staging/gma500/psb_gem.c
+++ b/drivers/staging/gma500/psb_gem.c


@@ -87,7 +87,7 @@ static int psb_gem_create_mmap_offset(struct drm_gem_object *obj)
list->file_offset_node = drm_mm_search_free(&mm->offset_manager,
obj->size / PAGE_SIZE, 0, 0);
if (!list->file_offset_node) {

- DRM_ERROR("failed to allocate offset for bo %d\n", obj->name);


+ dev_err(dev->dev, "failed to allocate offset for bo %d\n", obj->name);
ret = -ENOSPC;
goto free_it;
}
@@ -100,7 +100,7 @@ static int psb_gem_create_mmap_offset(struct drm_gem_object *obj)
list->hash.key = list->file_offset_node->start;
ret = drm_ht_insert_item(&mm->offset_hash, &list->hash);
if (ret) {
- DRM_ERROR("failed to add to map hash\n");
+ dev_err(dev->dev, "failed to add to map hash\n");
goto free_mm;
}
return 0;

@@ -283,7 +283,7 @@ int psb_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf)


if (r->mmapping == 0) {

ret = psb_gtt_pin(r);
if (ret < 0) {

- DRM_ERROR("gma500: pin failed: %d\n", ret);
+ dev_err(dev->dev, "gma500: pin failed: %d\n", ret);


goto fail;
}
r->mmapping = 1;

diff --git a/drivers/staging/gma500/psb_gtt.c b/drivers/staging/gma500/psb_gtt.c
index 8fcb833..54a9308 100644
--- a/drivers/staging/gma500/psb_gtt.c
+++ b/drivers/staging/gma500/psb_gtt.c
@@ -456,7 +456,7 @@ int psb_gtt_init(struct drm_device *dev, int resume)



if (resume && (gtt_pages != pg->gtt_pages) &&
(stolen_size != pg->stolen_size)) {
- DRM_ERROR("GTT resume error.\n");
+ dev_err(dev->dev, "GTT resume error.\n");
ret = -EINVAL;
goto out_err;
}

@@ -470,14 +470,14 @@ int psb_gtt_init(struct drm_device *dev, int resume)
*/


dev_priv->gtt_map = ioremap_nocache(pg->gtt_phys_start, gtt_pages << PAGE_SHIFT);
if (!dev_priv->gtt_map) {

- DRM_ERROR("Failure to map gtt.\n");
+ dev_err(dev->dev, "Failure to map gtt.\n");
ret = -ENOMEM;


goto out_err;
}

dev_priv->vram_addr = ioremap_wc(dev_priv->stolen_base, stolen_size);
if (!dev_priv->vram_addr) {
- DRM_ERROR("Failure to map stolen base.\n");

+ dev_err(dev->dev, "Failure to map stolen base.\n");
ret = -ENOMEM;

diff --git a/drivers/staging/gma500/psb_intel_display.c b/drivers/staging/gma500/psb_intel_display.c
index c7c55b1..be7e1f9 100644
--- a/drivers/staging/gma500/psb_intel_display.c
+++ b/drivers/staging/gma500/psb_intel_display.c
@@ -350,14 +350,12 @@ int psb_intel_pipe_set_base(struct drm_crtc *crtc,


u32 dspcntr;
int ret = 0;

- PSB_DEBUG_ENTRY("\n");
-
if (!gma_power_begin(dev, true))
return 0;

/* no fb bound */
if (!crtc->fb) {

- DRM_DEBUG("No FB bound\n");
+ dev_dbg(dev->dev, "No FB bound\n");
goto psb_intel_pipe_cleaner;
}

@@ -390,7 +388,7 @@ int psb_intel_pipe_set_base(struct drm_crtc *crtc,


dspcntr |= DISPPLANE_32BPP_NO_ALPHA;
break;
default:
- DRM_ERROR("Unknown color depth\n");
+ dev_err(dev->dev, "Unknown color depth\n");
ret = -EINVAL;
psb_gtt_unpin(psbfb->gtt);
goto psb_intel_pipe_set_base_exit;

@@ -398,7 +396,6 @@ int psb_intel_pipe_set_base(struct drm_crtc *crtc,


REG_WRITE(dspcntr_reg, dspcntr);


- DRM_DEBUG("Writing base %08lX %08lX %d %d\n", start, offset, x, y);
if (0 /* FIXMEAC - check what PSB needs */) {
REG_WRITE(dspbase, offset);
REG_READ(dspbase);

@@ -650,7 +647,7 @@ static int psb_intel_crtc_mode_set(struct drm_crtc *crtc,


ok = psb_intel_find_best_PLL(crtc, adjusted_mode->clock, refclk,
&clock);
if (!ok) {
- DRM_ERROR("Couldn't find PLL settings for mode!\n");
+ dev_err(dev->dev, "Couldn't find PLL settings for mode!\n");
return 0;
}

@@ -714,7 +711,6 @@ static int psb_intel_crtc_mode_set(struct drm_crtc *crtc,

/* Pin the memory into the GTT */

- PSB_DEBUG_ENTRY("type = 0x%x, pipe = %d.\n",
- psb_intel_output->type, psb_intel_crtc->pipe);

for (i = 0; i < args_len; i++)
- printk(KERN_INFO"%02X ", ((u8 *) args)[i]);
+ printk(KERN_CONT "%02X ", ((u8 *) args)[i]);
for (; i < 8; i++)
- printk(" ");
+ printk(KERN_CONT " ");

for (i = 0;
i <

sizeof(sdvo_cmd_names) / sizeof(sdvo_cmd_names[0]);
i++) {
if (cmd == sdvo_cmd_names[i].cmd) {
- printk("(%s)", sdvo_cmd_names[i].name);
+ printk(KERN_CONT "(%s)", sdvo_cmd_names[i].name);
break;
}
}
if (i ==
sizeof(sdvo_cmd_names) / sizeof(sdvo_cmd_names[0]))
- printk("(%02X)", cmd);
- printk("\n");
+ printk(KERN_CONT "(%02X)", cmd);
+ printk(KERN_CONT "\n");
}

for (i = 0; i < args_len; i++) {
@@ -267,17 +263,17 @@ static u8 psb_intel_sdvo_read_response(
&status);

if (0) {
- DRM_DEBUG("%s: R: ", SDVO_NAME(sdvo_priv));
+ pr_debug("%s: R: ", SDVO_NAME(sdvo_priv));

for (i = 0; i < response_len; i++)
- printk(KERN_INFO"%02X ", ((u8 *) response)[i]);
+ printk(KERN_CONT "%02X ", ((u8 *) response)[i]);
for (; i < 8; i++)
printk(" ");
if (status <= SDVO_CMD_STATUS_SCALING_NOT_SUPP)
- printk(KERN_INFO"(%s)",
+ printk(KERN_CONT "(%s)",
cmd_status_names[status]);
else
- printk(KERN_INFO"(??? %d)", status);
- printk("\n");
+ printk(KERN_CONT "(??? %d)", status);
+ printk(KERN_CONT "\n");
}

if (status != SDVO_CMD_STATUS_PENDING)
@@ -997,7 +993,6 @@ int psb_intel_sdvo_supports_hotplug(struct drm_connector *connector)
u8 response[2];
u8 status;
struct psb_intel_output *psb_intel_output;
- DRM_DEBUG("\n");

if (!connector)
return 0;
@@ -1198,7 +1193,7 @@ void psb_intel_sdvo_init(struct drm_device *dev, int output_device)
/* Read the regs to test if we can talk to the device */

- PSB_DEBUG_IRQ("Got MSVDX interrupt\n");
-
- if (vdc_stat & _LNC_IRQ_TOPAZ_FLAG)


- PSB_DEBUG_IRQ("Got TOPAZ interrupt\n");
-

vdc_stat &= dev_priv->vdc_irq_mask;
spin_unlock(&dev_priv->irqmask_lock);

@@ -293,8 +284,6 @@ int psb_irq_postinstall(struct drm_device *dev)


(struct drm_psb_private *) dev->dev_private;

unsigned long irqflags;

- PSB_DEBUG_ENTRY("\n");
-
spin_lock_irqsave(&dev_priv->irqmask_lock, irqflags);

/* This register is safe even if display island is off */
@@ -326,8 +315,6 @@ void psb_irq_uninstall(struct drm_device *dev)

(struct drm_psb_private *) dev->dev_private;

unsigned long irqflags;

- PSB_DEBUG_ENTRY("\n");
-
spin_lock_irqsave(&dev_priv->irqmask_lock, irqflags);

PSB_WVDC32(0xFFFFFFFF, PSB_HWSTAM);
@@ -395,8 +382,6 @@ int psb_irq_enable_dpst(struct drm_device *dev)

(struct drm_psb_private *) dev->dev_private;

unsigned long irqflags;

- PSB_DEBUG_ENTRY("\n");
-
spin_lock_irqsave(&dev_priv->irqmask_lock, irqflags);

/* enable DPST */
@@ -435,8 +420,6 @@ int psb_irq_disable_dpst(struct drm_device *dev)

(struct drm_psb_private *) dev->dev_private;

unsigned long irqflags;

- PSB_DEBUG_ENTRY("\n");
-
spin_lock_irqsave(&dev_priv->irqmask_lock, irqflags);

mid_disable_pipe_event(dev_priv, 0);

@@ -472,8 +455,6 @@ int psb_enable_vblank(struct drm_device *dev, int pipe)


uint32_t reg_val = 0;
uint32_t pipeconf_reg = mid_pipeconf(pipe);

- PSB_DEBUG_ENTRY("\n");
-
if (gma_power_begin(dev, false)) {
reg_val = REG_READ(pipeconf_reg);
gma_power_end(dev);

@@ -500,8 +481,6 @@ void psb_disable_vblank(struct drm_device *dev, int pipe)


struct drm_psb_private *dev_priv = dev->dev_private;

unsigned long irqflags;

- PSB_DEBUG_ENTRY("\n");
-
spin_lock_irqsave(&dev_priv->irqmask_lock, irqflags);

mid_disable_pipe_event(dev_priv, pipe);

@@ -535,7 +514,7 @@ u32 psb_get_vblank_counter(struct drm_device *dev, int pipe)


pipeconf_reg = PIPECCONF;
break;
default:
- DRM_ERROR("%s, invalded pipe.\n", __func__);
+ dev_err(dev->dev, "%s, invalid pipe.\n", __func__);
return 0;
}

@@ -545,7 +524,7 @@ u32 psb_get_vblank_counter(struct drm_device *dev, int pipe)


reg_val = REG_READ(pipeconf_reg);

if (!(reg_val & PIPEACONF_ENABLE)) {
- DRM_ERROR("trying to get vblank count for disabled pipe %d\n",
+ dev_err(dev->dev, "trying to get vblank count for disabled pipe %d\n",
pipe);
goto psb_get_vblank_counter_exit;
}

--

Alan Cox

unread,
Jun 16, 2011, 12:36:46 PM6/16/11
to gr...@kroah.com, linux-...@vger.kernel.org
From: Alan Cox <al...@linux.intel.com>

We are using the underlying kref in the GEM object so we don't need our own

Signed-off-by: Alan Cox <al...@linux.intel.com>
---

drivers/staging/gma500/psb_fb.c | 1 -
drivers/staging/gma500/psb_gtt.c | 41 ++++++--------------------------------
drivers/staging/gma500/psb_gtt.h | 1 -
3 files changed, 6 insertions(+), 37 deletions(-)

diff --git a/drivers/staging/gma500/psb_fb.c b/drivers/staging/gma500/psb_fb.c
index 988f4db..fb75aba 100644
--- a/drivers/staging/gma500/psb_fb.c
+++ b/drivers/staging/gma500/psb_fb.c
@@ -231,7 +231,6 @@ static int psbfb_mmap(struct fb_info *info, struct vm_area_struct *vma)


struct psb_fbdev *fbdev = info->par;

struct psb_framebuffer *psbfb = &fbdev->pfb;
char *fb_screen_base = NULL;

- struct drm_device *dev = psbfb->base.dev;



if (vma->vm_pgoff != 0)
return -EINVAL;

diff --git a/drivers/staging/gma500/psb_gtt.c b/drivers/staging/gma500/psb_gtt.c
index 54a9308..9da1375 100644
--- a/drivers/staging/gma500/psb_gtt.c
+++ b/drivers/staging/gma500/psb_gtt.c
@@ -303,8 +303,6 @@ struct gtt_range *psb_gtt_alloc_range(struct drm_device *dev, int len,
gt->in_gart = backed;


/* Ensure this is set for non GEM objects */

gt->gem.dev = dev;
- kref_init(&gt->kref);
-


ret = allocate_resource(dev_priv->gtt_mem, &gt->resource,

len, start, end, PAGE_SIZE, NULL, NULL);
if (ret == 0) {

@@ -316,18 +314,15 @@ struct gtt_range *psb_gtt_alloc_range(struct drm_device *dev, int len,
}

/**
- * psb_gtt_destroy - final free up of a gtt
- * @kref: the kref of the gtt
- *
- * Called from the kernel kref put when the final reference to our
- * GTT object is dropped. At that point we can free up the resources.
+ * psb_gtt_free_range - release GTT address space


+ * @dev: our DRM device

+ * @gt: a mapping created with psb_gtt_alloc_range
*
- * For now we handle mmap clean up here to work around limits in GEM
+ * Release a resource that was allocated with psb_gtt_alloc_range. If the object
+ * has been pinned by mmap users we clean this up here currently.
*/
-static void psb_gtt_destroy(struct kref *kref)
+void psb_gtt_free_range(struct drm_device *dev, struct gtt_range *gt)
{
- struct gtt_range *gt = container_of(kref, struct gtt_range, kref);
-
/* Undo the mmap pin if we are destroying the object */
if (gt->mmapping) {
psb_gtt_unpin(gt);
@@ -338,30 +333,6 @@ static void psb_gtt_destroy(struct kref *kref)
kfree(gt);
}

-/**
- * psb_gtt_kref_put - drop reference to a GTT object
- * @gt: the GT being dropped
- *
- * Drop a reference to a psb gtt
- */
-void psb_gtt_kref_put(struct gtt_range *gt)
-{
- kref_put(&gt->kref, psb_gtt_destroy);
-}
-
-/**
- * psb_gtt_free_range - release GTT address space
- * @dev: our DRM device
- * @gt: a mapping created with psb_gtt_alloc_range
- *
- * Release a resource that was allocated with psb_gtt_alloc_range
- */
-void psb_gtt_free_range(struct drm_device *dev, struct gtt_range *gt)
-{
- psb_gtt_kref_put(gt);
-}
-
-
struct psb_gtt *psb_gtt_alloc(struct drm_device *dev)
{
struct psb_gtt *tmp = kzalloc(sizeof(*tmp), GFP_KERNEL);
diff --git a/drivers/staging/gma500/psb_gtt.h b/drivers/staging/gma500/psb_gtt.h
index 7e1f21e..4d6dc5f 100644
--- a/drivers/staging/gma500/psb_gtt.h
+++ b/drivers/staging/gma500/psb_gtt.h
@@ -44,7 +44,6 @@ extern void psb_gtt_takedown(struct drm_device *dev);
struct gtt_range {


struct resource resource; /* Resource for our allocation */

u32 offset; /* GTT offset of our object */

- struct kref kref; /* Can probably go FIXME - GEM kref will do */


struct drm_gem_object gem; /* GEM high level stuff */
int in_gart; /* Currently in the GART (ref ct) */
bool stolen; /* Backed from stolen RAM */

--

Alan Cox

unread,
Jun 16, 2011, 12:37:07 PM6/16/11
to gr...@kroah.com, linux-...@vger.kernel.org
From: Alan Cox <al...@linux.intel.com>

Add this temporarily so we can keep making progress and also bundle all the
GEM bits we need together in our staging driver while we get them into GEM
itself.

Signed-off-by: Alan Cox <al...@linux.intel.com>
---

drivers/staging/gma500/Makefile | 3 ++
drivers/staging/gma500/gem_glue.c | 47 +++++++++++++++++++++++++++++++++++++
drivers/staging/gma500/gem_glue.h | 4 +++
3 files changed, 53 insertions(+), 1 deletions(-)


create mode 100644 drivers/staging/gma500/gem_glue.c
create mode 100644 drivers/staging/gma500/gem_glue.h

diff --git a/drivers/staging/gma500/Makefile b/drivers/staging/gma500/Makefile
index db73ec6..01aaa28 100644
--- a/drivers/staging/gma500/Makefile
+++ b/drivers/staging/gma500/Makefile
@@ -3,7 +3,8 @@
#
ccflags-y += -Iinclude/drm

-psb_gfx-y += psb_bl.o \
+psb_gfx-y += gem_glue.o \
+ psb_bl.o \
psb_drv.o \
psb_gem.o \
psb_fb.o \
diff --git a/drivers/staging/gma500/gem_glue.c b/drivers/staging/gma500/gem_glue.c
new file mode 100644
index 0000000..0817497
--- /dev/null
+++ b/drivers/staging/gma500/gem_glue.c
@@ -0,0 +1,47 @@
+/**************************************************************************
+ * Copyright (c) 2011, Intel Corporation.
+ * 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.
+ *
+ **************************************************************************/
+
+#include <drm/drmP.h>
+#include <drm/drm.h>
+
+/**
+ * Initialize an already allocated GEM object of the specified size with
+ * no GEM provided backing store. Instead the caller is responsible for
+ * backing the object and handling it.
+ */
+int drm_gem_private_object_init(struct drm_device *dev,
+ struct drm_gem_object *obj, size_t size)
+{
+ BUG_ON((size & (PAGE_SIZE - 1)) != 0);
+
+ obj->dev = dev;
+ obj->filp = NULL;
+
+ kref_init(&obj->refcount);
+ atomic_set(&obj->handle_count, 0);
+ obj->size = size;
+


+ return 0;
+}
+

+void drm_gem_object_release_wrap(struct drm_gem_object *obj)
+{
+ if (obj->filp)
+ drm_gem_object_release(obj);
+}
diff --git a/drivers/staging/gma500/gem_glue.h b/drivers/staging/gma500/gem_glue.h
new file mode 100644
index 0000000..c38285b
--- /dev/null
+++ b/drivers/staging/gma500/gem_glue.h
@@ -0,0 +1,4 @@
+extern void drm_gem_object_release_wrap(struct drm_gem_object *obj);
+extern int drm_gem_private_object_init(struct drm_device *dev,
+ struct drm_gem_object *obj, size_t size);
+

Alan Cox

unread,
Jun 16, 2011, 12:37:19 PM6/16/11
to gr...@kroah.com, linux-...@vger.kernel.org
From: Alan Cox <al...@linux.intel.com>

We can now make our system frame buffer a GEM object.

Signed-off-by: Alan Cox <al...@linux.intel.com>
---

drivers/staging/gma500/psb_fb.c | 11 +++++++----
drivers/staging/gma500/psb_gem.c | 11 ++++++++---
2 files changed, 15 insertions(+), 7 deletions(-)

diff --git a/drivers/staging/gma500/psb_fb.c b/drivers/staging/gma500/psb_fb.c
index fb75aba..400dbee 100644
--- a/drivers/staging/gma500/psb_fb.c
+++ b/drivers/staging/gma500/psb_fb.c
@@ -186,6 +186,8 @@ static int psbfb_vm_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
struct psb_framebuffer *psbfb = vma->vm_private_data;


struct drm_device *dev = psbfb->base.dev;

struct drm_psb_private *dev_priv = dev->dev_private;

+
+ /* FIXME: assumes fb at stolen base which may not be true */
unsigned long phys_addr = (unsigned long)dev_priv->stolen_base;

page_num = (vma->vm_end - vma->vm_start) >> PAGE_SHIFT;
@@ -381,8 +383,11 @@ static struct gtt_range *psbfb_alloc(struct drm_device *dev, int aligned_size)
struct gtt_range *backing;
/* Begin by trying to use stolen memory backing */
backing = psb_gtt_alloc_range(dev, aligned_size, "fb", 1);
- if (backing)
- return backing;
+ if (backing) {
+ if (drm_gem_private_object_init(dev, &backing->gem, aligned_size) == 0)
+ 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)
@@ -683,8 +688,6 @@ static int psb_user_framebuffer_create_handle(struct drm_framebuffer *fb,
{


struct psb_framebuffer *psbfb = to_psb_fb(fb);

struct gtt_range *r = psbfb->gtt;

- if (r->stolen)
- return -EOPNOTSUPP;
return drm_gem_handle_create(file_priv, &r->gem, handle);
}

diff --git a/drivers/staging/gma500/psb_gem.c b/drivers/staging/gma500/psb_gem.c
index 7f6f479..4aec38c 100644
--- a/drivers/staging/gma500/psb_gem.c
+++ b/drivers/staging/gma500/psb_gem.c
@@ -49,7 +49,7 @@ void psb_gem_free_object(struct drm_gem_object *obj)
kfree(list->map);
list->map = NULL;
}
- drm_gem_object_release(obj);
+ drm_gem_object_release_wrap(obj);


/* This must occur last as it frees up the memory of the GEM object */

psb_gtt_free_range(obj->dev, gtt);
}
@@ -268,9 +268,11 @@ int psb_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
unsigned long pfn;
pgoff_t page_offset;
struct drm_device *dev;
+ struct drm_psb_private *dev_priv;

obj = vma->vm_private_data; /* GEM object */
dev = obj->dev;
+ dev_priv = dev->dev_private;

r = container_of(obj, struct gtt_range, gem); /* Get the gtt range */

@@ -294,8 +296,11 @@ int psb_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf)


page_offset = ((unsigned long) vmf->virtual_address - vma->vm_start)
>> PAGE_SHIFT;

- /* CPU view of the page, don't go via the GART for CPU writes */
- pfn = page_to_phys(r->pages[page_offset]) >> PAGE_SHIFT;
+ /* CPU view of the page, don't go via the GART for CPU writes */
+ if (r->stolen)
+ pfn = (dev_priv->stolen_base + r->offset) >> PAGE_SHIFT;
+ else
+ pfn = page_to_pfn(r->pages[page_offset]);


ret = vm_insert_pfn(vma, (unsigned long)vmf->virtual_address, pfn);

fail:

Alan Cox

unread,
Jun 16, 2011, 12:38:03 PM6/16/11
to gr...@kroah.com, linux-...@vger.kernel.org
From: Alan Cox <al...@linux.intel.com>

Tidy up the 2D bits. For the fill case the CPU seems to be able to
outperform the graphics engine for the cases we get, so don't bother
fixing it but throw it out.

Signed-off-by: Alan Cox <al...@linux.intel.com>
---

drivers/staging/gma500/psb_2d.c | 191 ++++++++++++++------------------------
drivers/staging/gma500/psb_drv.h | 6 -
drivers/staging/gma500/psb_fb.c | 4 -
3 files changed, 74 insertions(+), 127 deletions(-)

diff --git a/drivers/staging/gma500/psb_2d.c b/drivers/staging/gma500/psb_2d.c
index dea4bc1..df4c519 100644
--- a/drivers/staging/gma500/psb_2d.c
+++ b/drivers/staging/gma500/psb_2d.c
@@ -41,6 +41,14 @@
#include "psb_drv.h"
#include "psb_fb.h"

+/**
+ * psb_spank - reset the 2D engine
+ * @dev_priv: our PSB DRM device
+ *
+ * Soft reset the graphics engine and then reload the necessary registers.
+ * We use this at initialisation time but it will become relevant for
+ * accelerated X later
+ */
void psb_spank(struct drm_psb_private *dev_priv)
{
PSB_WSGX32(_PSB_CS_RESET_BIF_RESET | _PSB_CS_RESET_DPM_RESET |
@@ -65,6 +73,14 @@ void psb_spank(struct drm_psb_private *dev_priv)
PSB_WSGX32(dev_priv->pg->gatt_start, PSB_CR_BIF_TWOD_REQ_BASE);
}

+/**
+ * psb2_2d_wait_available - wait for FIFO room
+ * @dev_priv: our DRM device
+ * @size: size (in dwords) of the command we want to issue
+ *
+ * Wait until there is room to load the FIFO with our data. If the
+ * device is not responding then reset it
+ */
static int psb_2d_wait_available(struct drm_psb_private *dev_priv,
unsigned size)
{
@@ -81,9 +97,15 @@ static int psb_2d_wait_available(struct drm_psb_private *dev_priv,
return 0;
}

-/* FIXME: Remember if we expose the 2D engine to the DRM we need to serialize
- it with console use */
-
+/**
+ * psb_2d_submit - submit a 2D command
+ * @dev_priv: our DRM device
+ * @cmdbuf: command to issue
+ * @size: length (in dwords)
+ *
+ * Issue one or more 2D commands to the accelerator. This needs to be
+ * serialized later when we add the GEM interfaces for acceleration
+ */


int psbfb_2d_submit(struct drm_psb_private *dev_priv, uint32_t *cmdbuf,
unsigned size)

{
@@ -108,104 +130,15 @@ int psbfb_2d_submit(struct drm_psb_private *dev_priv, uint32_t *cmdbuf,
return 0;
}

-static int psb_accel_2d_fillrect(struct drm_psb_private *dev_priv,
- uint32_t dst_offset, uint32_t dst_stride,
- uint32_t dst_format, uint16_t dst_x,
- uint16_t dst_y, uint16_t size_x,
- uint16_t size_y, uint32_t fill)
-{
- uint32_t buffer[10];
- uint32_t *buf;
-
- buf = buffer;
-
- *buf++ = PSB_2D_FENCE_BH;
-
- *buf++ =
- PSB_2D_DST_SURF_BH | dst_format | (dst_stride <<
- PSB_2D_DST_STRIDE_SHIFT);
- *buf++ = dst_offset;
-
- *buf++ =
- PSB_2D_BLIT_BH |
- PSB_2D_ROT_NONE |
- PSB_2D_COPYORDER_TL2BR |
- PSB_2D_DSTCK_DISABLE |
- PSB_2D_SRCCK_DISABLE | PSB_2D_USE_FILL | PSB_2D_ROP3_PATCOPY;
-
- *buf++ = fill << PSB_2D_FILLCOLOUR_SHIFT;
- *buf++ =
- (dst_x << PSB_2D_DST_XSTART_SHIFT) | (dst_y <<
- PSB_2D_DST_YSTART_SHIFT);
- *buf++ =
- (size_x << PSB_2D_DST_XSIZE_SHIFT) | (size_y <<
- PSB_2D_DST_YSIZE_SHIFT);
- *buf++ = PSB_2D_FLUSH_BH;
-
- return psbfb_2d_submit(dev_priv, buffer, buf - buffer);
-}
-
-static void psbfb_fillrect_accel(struct fb_info *info,
- const struct fb_fillrect *r)
-{
- struct psb_fbdev *fbdev = info->par;
- struct psb_framebuffer *psbfb = &fbdev->pfb;
- struct drm_device *dev = psbfb->base.dev;
- struct drm_framebuffer *fb = fbdev->psb_fb_helper.fb;
- struct drm_psb_private *dev_priv = dev->dev_private;
-
- uint32_t offset;
- uint32_t stride;
- uint32_t format;
-
- if (!fb)
- return;
-
- offset = psbfb->gtt->offset;
- stride = fb->pitch;
-
- switch (fb->depth) {
- case 8:
- format = PSB_2D_DST_332RGB;
- break;
- case 15:
- format = PSB_2D_DST_555RGB;
- break;
- case 16:
- format = PSB_2D_DST_565RGB;
- break;
- case 24:
- case 32:
- /* this is wrong but since we don't do blending its okay */
- format = PSB_2D_DST_8888ARGB;
- break;
- default:
- /* software fallback */
- cfb_fillrect(info, r);
- return;
- }
- if (!gma_power_begin(dev, false)) {
- cfb_fillrect(info, r);
- return;
- }
- psb_accel_2d_fillrect(dev_priv,
- offset, stride, format,
- r->dx, r->dy, r->width, r->height, r->color);
- gma_power_end(dev);
-}
-
-void psbfb_fillrect(struct fb_info *info,
- const struct fb_fillrect *rect)
-{
- if (unlikely(info->state != FBINFO_STATE_RUNNING))
- return;
-
- if (1 || (info->flags & FBINFO_HWACCEL_DISABLED))
- return cfb_fillrect(info, rect);
-
- psbfb_fillrect_accel(info, rect);
-}

+/**
+ * psb_accel_2d_copy_direction - compute blit order
+ * @xdir: X direction of move
+ * @ydir: Y direction of move
+ *
+ * Compute the correct order setings to ensure that an overlapping blit
+ * correctly copies all the pixels.
+ */


static u32 psb_accel_2d_copy_direction(int xdir, int ydir)

{
if (xdir < 0)
@@ -216,19 +149,23 @@ static u32 psb_accel_2d_copy_direction(int xdir, int ydir)
PSB_2D_COPYORDER_TL2BR;
}

-/*
- * @src_offset in bytes
- * @src_stride in bytes
- * @src_format psb 2D format defines
- * @dst_offset in bytes
- * @dst_stride in bytes
- * @dst_format psb 2D format defines
- * @src_x offset in pixels
- * @src_y offset in pixels
- * @dst_x offset in pixels
- * @dst_y offset in pixels
- * @size_x of the copied area
- * @size_y of the copied area
+/**
+ * psb_accel_2d_copy - accelerated 2D copy
+ * @dev_priv: our DRM device
+ * @src_offset in bytes
+ * @src_stride in bytes
+ * @src_format psb 2D format defines
+ * @dst_offset in bytes
+ * @dst_stride in bytes
+ * @dst_format psb 2D format defines
+ * @src_x offset in pixels
+ * @src_y offset in pixels
+ * @dst_x offset in pixels
+ * @dst_y offset in pixels
+ * @size_x of the copied area
+ * @size_y of the copied area
+ *
+ * Format and issue a 2D accelerated copy command.
*/
static int psb_accel_2d_copy(struct drm_psb_private *dev_priv,
uint32_t src_offset, uint32_t src_stride,
@@ -290,6 +227,13 @@ static int psb_accel_2d_copy(struct drm_psb_private *dev_priv,
return psbfb_2d_submit(dev_priv, buffer, buf - buffer);
}

+/**
+ * psbfb_copyarea_accel - copyarea acceleration for /dev/fb
+ * @info: our framebuffer
+ * @a: copyarea parameters from the framebuffer core
+ *
+ * Perform a 2D copy via the accelerator
+ */


static void psbfb_copyarea_accel(struct fb_info *info,

const struct fb_copyarea *a)
{
@@ -345,6 +289,14 @@ static void psbfb_copyarea_accel(struct fb_info *info,
gma_power_end(dev);
}

+/**
+ * psbfb_copyarea - 2D copy interface
+ * @info: our framebuffer
+ * @region: region to copy
+ *
+ * Copy an area of the framebuffer console either by the accelerator
+ * or directly using the cfb helpers according to the request
+ */
void psbfb_copyarea(struct fb_info *info,
const struct fb_copyarea *region)
{
@@ -359,12 +311,13 @@ void psbfb_copyarea(struct fb_info *info,
psbfb_copyarea_accel(info, region);
}

-void psbfb_imageblit(struct fb_info *info, const struct fb_image *image)
-{
- /* For now */
- cfb_imageblit(info, image);
-}
-
+/**
+ * psbfb_sync - synchronize 2D
+ * @info: our framebuffer
+ *
+ * Wait for the 2D engine to quiesce so that we can do CPU
+ * access to the framebuffer again
+ */
int psbfb_sync(struct fb_info *info)
{


struct psb_fbdev *fbdev = info->par;

diff --git a/drivers/staging/gma500/psb_drv.h b/drivers/staging/gma500/psb_drv.h
index 1114021..cafbfcd 100644
--- a/drivers/staging/gma500/psb_drv.h
+++ b/drivers/staging/gma500/psb_drv.h
@@ -587,16 +587,10 @@ extern void *psbfb_vdc_reg(struct drm_device* dev);
/*
* psb_2d.c
*/
-extern void psbfb_fillrect(struct fb_info *info,
- const struct fb_fillrect *rect);
extern void psbfb_copyarea(struct fb_info *info,
const struct fb_copyarea *region);
-extern void psbfb_imageblit(struct fb_info *info,
- const struct fb_image *image);
extern int psbfb_sync(struct fb_info *info);
-
extern void psb_spank(struct drm_psb_private *dev_priv);
-


extern int psbfb_2d_submit(struct drm_psb_private *dev_priv, uint32_t *cmdbuf,
unsigned size);

diff --git a/drivers/staging/gma500/psb_fb.c b/drivers/staging/gma500/psb_fb.c
index f1a7e8d..c2d4b23 100644
--- a/drivers/staging/gma500/psb_fb.c
+++ b/drivers/staging/gma500/psb_fb.c
@@ -289,9 +289,9 @@ static struct fb_ops psbfb_ops = {
.fb_set_par = drm_fb_helper_set_par,
.fb_blank = drm_fb_helper_blank,
.fb_setcolreg = psbfb_setcolreg,
- .fb_fillrect = psbfb_fillrect,
+ .fb_fillrect = cfb_fillrect,
.fb_copyarea = psbfb_copyarea,
- .fb_imageblit = psbfb_imageblit,
+ .fb_imageblit = cfb_imageblit,
.fb_mmap = psbfb_mmap,
.fb_sync = psbfb_sync,
.fb_ioctl = psbfb_ioctl,

Alan Cox

unread,
Jun 16, 2011, 12:37:50 PM6/16/11
to gr...@kroah.com, linux-...@vger.kernel.org
From: Alan Cox <al...@linux.intel.com>

Start the style cleanup

Signed-off-by: Alan Cox <al...@linux.intel.com>
---

drivers/staging/gma500/mrst.h | 38 -
drivers/staging/gma500/mrst_lvds.c | 8
drivers/staging/gma500/psb_2d.c | 23 -
drivers/staging/gma500/psb_drm.h | 8
drivers/staging/gma500/psb_drv.c | 25 -
drivers/staging/gma500/psb_drv.h | 63 +-
drivers/staging/gma500/psb_fb.c | 145 ++--
drivers/staging/gma500/psb_gem.c | 19
drivers/staging/gma500/psb_gtt.c | 35 -
drivers/staging/gma500/psb_intel_display.c | 12
drivers/staging/gma500/psb_intel_opregion.c | 8
drivers/staging/gma500/psb_intel_reg.h | 1055 +++++++++++++-------------
drivers/staging/gma500/psb_intel_sdvo.c | 3
drivers/staging/gma500/psb_intel_sdvo_regs.h | 14
drivers/staging/gma500/psb_reg.h | 840 ++++++++++-----------
15 files changed, 1156 insertions(+), 1140 deletions(-)

diff --git a/drivers/staging/gma500/mrst.h b/drivers/staging/gma500/mrst.h
index 5e4aaeb..7bacb9a 100644
--- a/drivers/staging/gma500/mrst.h
+++ b/drivers/staging/gma500/mrst.h
@@ -25,7 +25,7 @@ struct mrst_vbt {
u8 size;
u8 checksum;
void *mrst_gct;
-} __attribute__ ((packed));
+} __packed;

struct mrst_timing_info {
u16 pixel_clock;
@@ -58,7 +58,7 @@ struct mrst_timing_info {
u8 stereo:1;
u8 unknown6:1;
u8 interlaced:1;
-} __attribute__((packed));
+} __packed;

struct gct_r10_timing_info {
u16 pixel_clock;
@@ -82,7 +82,7 @@ struct gct_r10_timing_info {
u16 vsync_pulse_width_hi:2;
u16 vsync_positive:1;
u16 rsvd_2:3;
-} __attribute__((packed));
+} __packed;

struct mrst_panel_descriptor_v1 {
u32 Panel_Port_Control; /* 1 dword, Register 0x61180 if LVDS */
@@ -111,7 +111,7 @@ struct mrst_panel_descriptor_v1 {
/* Bit 6, Reserved, 2 bits, 00b */
/* Bit 8, Minimum Supported Frame Rate, 6 bits, 0 - 63Hz */
/* Bit 14, Reserved, 2 bits, 00b */
-} __attribute__ ((packed));
+} __packed;

struct mrst_panel_descriptor_v2 {
u32 Panel_Port_Control; /* 1 dword, Register 0x61180 if LVDS */
@@ -141,10 +141,10 @@ struct mrst_panel_descriptor_v2 {
/* Bit 6, Reserved, 2 bits, 00b */
/* Bit 8, Minimum Supported Frame Rate, 6 bits, 0 - 63Hz */
/* Bit 14, Reserved, 2 bits, 00b */
-} __attribute__ ((packed));
+} __packed;

union mrst_panel_rx {
- struct{
+ struct {
u16 NumberOfLanes:2; /*Num of Lanes, 2 bits,0 = 1 lane,*/
/* 1 = 2 lanes, 2 = 3 lanes, 3 = 4 lanes. */
u16 MaxLaneFreq:3; /* 0: 100MHz, 1: 200MHz, 2: 300MHz, */
@@ -159,10 +159,10 @@ union mrst_panel_rx {
u16 Rsvd:5;/*5 bits,00000b */
} panelrx;
u16 panel_receiver;
-} __attribute__ ((packed));
+} __packed;

struct mrst_gct_v1 {
- union{ /*8 bits,Defined as follows: */
+ union { /*8 bits,Defined as follows: */
struct {
u8 PanelType:4; /*4 bits, Bit field for panels*/
/* 0 - 3: 0 = LVDS, 1 = MIPI*/
@@ -176,10 +176,10 @@ struct mrst_gct_v1 {
};
struct mrst_panel_descriptor_v1 panel[4];/*panel descrs,38 bytes each*/
union mrst_panel_rx panelrx[4]; /* panel receivers*/
-} __attribute__ ((packed));
+} __packed;

struct mrst_gct_v2 {
- union{ /*8 bits,Defined as follows: */
+ union { /*8 bits,Defined as follows: */
struct {
u8 PanelType:4; /*4 bits, Bit field for panels*/
/* 0 - 3: 0 = LVDS, 1 = MIPI*/
@@ -193,7 +193,7 @@ struct mrst_gct_v2 {
};
struct mrst_panel_descriptor_v2 panel[4];/*panel descrs,38 bytes each*/
union mrst_panel_rx panelrx[4]; /* panel receivers*/
-} __attribute__ ((packed));
+} __packed;

struct mrst_gct_data {
u8 bpi; /* boot panel index, number of panel used during boot */
@@ -205,13 +205,13 @@ struct mrst_gct_data {
u32 PP_Cycle_Delay;
u16 Panel_Backlight_Inverter_Descriptor;
u16 Panel_MIPI_Display_Descriptor;
-} __attribute__ ((packed));
+} __packed;

-#define MODE_SETTING_IN_CRTC 0x1
-#define MODE_SETTING_IN_ENCODER 0x2
-#define MODE_SETTING_ON_GOING 0x3
-#define MODE_SETTING_IN_DSR 0x4
-#define MODE_SETTING_ENCODER_DONE 0x8
-#define GCT_R10_HEADER_SIZE 16
-#define GCT_R10_DISPLAY_DESC_SIZE 28
+#define MODE_SETTING_IN_CRTC 0x1
+#define MODE_SETTING_IN_ENCODER 0x2
+#define MODE_SETTING_ON_GOING 0x3
+#define MODE_SETTING_IN_DSR 0x4
+#define MODE_SETTING_ENCODER_DONE 0x8

+#define GCT_R10_HEADER_SIZE 16
+#define GCT_R10_DISPLAY_DESC_SIZE 28
diff --git a/drivers/staging/gma500/mrst_lvds.c b/drivers/staging/gma500/mrst_lvds.c
index aac80cc..a746571 100644
--- a/drivers/staging/gma500/mrst_lvds.c
+++ b/drivers/staging/gma500/mrst_lvds.c
@@ -298,10 +298,10 @@ void mrst_lvds_init(struct drm_device *dev,
/* This ifdef can go once the cpu ident stuff is cleaned up in arch */
#if defined(CONFIG_X86_MRST)
if (mrst_identify_cpu())
- i2c_adap = i2c_get_adapter(2);
- else /* Oaktrail uses I2C 1 */
-#endif
- i2c_adap = i2c_get_adapter(1);
+ i2c_adap = i2c_get_adapter(2);
+ else /* Oaktrail uses I2C 1 */
+#endif
+ i2c_adap = i2c_get_adapter(1);

if (i2c_adap == NULL)
printk(KERN_ALERT "No ddc adapter available!\n");
diff --git a/drivers/staging/gma500/psb_2d.c b/drivers/staging/gma500/psb_2d.c
index 494bad5..dea4bc1 100644
--- a/drivers/staging/gma500/psb_2d.c
+++ b/drivers/staging/gma500/psb_2d.c
@@ -43,11 +43,11 @@

void psb_spank(struct drm_psb_private *dev_priv)
{
- PSB_WSGX32(_PSB_CS_RESET_BIF_RESET | _PSB_CS_RESET_DPM_RESET |
+ PSB_WSGX32(_PSB_CS_RESET_BIF_RESET | _PSB_CS_RESET_DPM_RESET |
_PSB_CS_RESET_TA_RESET | _PSB_CS_RESET_USE_RESET |
_PSB_CS_RESET_ISP_RESET | _PSB_CS_RESET_TSP_RESET |
_PSB_CS_RESET_TWOD_RESET, PSB_CR_SOFT_RESET);
- (void) PSB_RSGX32(PSB_CR_SOFT_RESET);
+ PSB_RSGX32(PSB_CR_SOFT_RESET);

msleep(1);

@@ -71,7 +71,7 @@ static int psb_2d_wait_available(struct drm_psb_private *dev_priv,
uint32_t avail = PSB_RSGX32(PSB_CR_2D_SOCIF);
unsigned long t = jiffies + HZ;

- while(avail < size) {
+ while (avail < size) {
avail = PSB_RSGX32(PSB_CR_2D_SOCIF);
if (time_after(jiffies, t)) {
psb_spank(dev_priv);
@@ -85,7 +85,7 @@ static int psb_2d_wait_available(struct drm_psb_private *dev_priv,


it with console use */

int psbfb_2d_submit(struct drm_psb_private *dev_priv, uint32_t *cmdbuf,

- unsigned size)
+ unsigned size)
{
int ret = 0;
int i;
@@ -99,9 +99,10 @@ int psbfb_2d_submit(struct drm_psb_private *dev_priv, uint32_t *cmdbuf,
return ret;

submit_size <<= 2;
- for (i = 0; i < submit_size; i += 4) {
+
+ for (i = 0; i < submit_size; i += 4)
PSB_WSGX32(*cmdbuf++, PSB_SGX_2D_SLAVE_PORT + i);
- }
+
(void)PSB_RSGX32(PSB_SGX_2D_SLAVE_PORT + i - 4);
}
return 0;
@@ -209,10 +210,10 @@ static u32 psb_accel_2d_copy_direction(int xdir, int ydir)
{
if (xdir < 0)
return (ydir < 0) ? PSB_2D_COPYORDER_BR2TL :
- PSB_2D_COPYORDER_TR2BL;
+ PSB_2D_COPYORDER_TR2BL;
else
return (ydir < 0) ? PSB_2D_COPYORDER_BL2TR :
- PSB_2D_COPYORDER_TL2BR;
+ PSB_2D_COPYORDER_TL2BR;
}

/*
@@ -350,9 +351,9 @@ void psbfb_copyarea(struct fb_info *info,


if (unlikely(info->state != FBINFO_STATE_RUNNING))

return;

- /* Avoid the 8 pixel erratum */


+ /* Avoid the 8 pixel erratum */

if (region->width == 8 || region->height == 8 ||

- (info->flags & FBINFO_HWACCEL_DISABLED))


+ (info->flags & FBINFO_HWACCEL_DISABLED))
return cfb_copyarea(info, region);

psbfb_copyarea_accel(info, region);
@@ -360,7 +361,7 @@ void psbfb_copyarea(struct fb_info *info,



void psbfb_imageblit(struct fb_info *info, const struct fb_image *image)
{

- /* For now */
+ /* For now */
cfb_imageblit(info, image);
}

diff --git a/drivers/staging/gma500/psb_drm.h b/drivers/staging/gma500/psb_drm.h
index b005293..8c259b8 100644
--- a/drivers/staging/gma500/psb_drm.h
+++ b/drivers/staging/gma500/psb_drm.h
@@ -118,10 +118,10 @@ struct drm_psb_register_rw_arg {
u32 OGAMC3;
u32 OGAMC4;
u32 OGAMC5;
- u32 IEP_ENABLED;
- u32 IEP_BLE_MINMAX;
- u32 IEP_BSSCC_CONTROL;
- u32 b_wait_vblank;
+ u32 IEP_ENABLED;
+ u32 IEP_BLE_MINMAX;
+ u32 IEP_BSSCC_CONTROL;
+ u32 b_wait_vblank;
} overlay;

u32 sprite_enable_mask;
diff --git a/drivers/staging/gma500/psb_drv.c b/drivers/staging/gma500/psb_drv.c
index 6ea06dd..3c2363a 100644
--- a/drivers/staging/gma500/psb_drv.c
+++ b/drivers/staging/gma500/psb_drv.c
@@ -47,7 +47,7 @@ module_param_named(no_fb, drm_psb_no_fb, int, 0600);
module_param_named(trap_pagefaults, drm_psb_trap_pagefaults, int, 0600);


-static struct pci_device_id pciidlist[] = {
+static DEFINE_PCI_DEVICE_TABLE(pciidlist) = {
{ 0x8086, 0x8108, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_PSB_8108 },
{ 0x8086, 0x8109, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_PSB_8109 },
{ 0x8086, 0x4100, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_MRST_4100},
@@ -185,8 +185,7 @@ void mrst_get_fuse_settings(struct drm_device *dev)
if (dev_priv->iLVDS_enable) {
dev_priv->is_lvds_on = true;
dev_priv->is_mipi_on = false;
- }
- else {
+ } else {
dev_priv->is_mipi_on = true;
dev_priv->is_lvds_on = false;
}
@@ -196,7 +195,7 @@ void mrst_get_fuse_settings(struct drm_device *dev)
pci_write_config_dword(pci_root, 0xD0, FB_REG09);
pci_read_config_dword(pci_root, 0xD4, &fuse_value);

- DRM_INFO("SKU values is 0x%x. \n", fuse_value);
+ DRM_INFO("SKU values is 0x%x.\n", fuse_value);
fuse_value_tmp = (fuse_value & FB_SKU_MASK) >> FB_SKU_SHIFT;

dev_priv->fuse_reg_value = fuse_value;
@@ -220,7 +219,7 @@ void mrst_get_fuse_settings(struct drm_device *dev)
pci_dev_put(pci_root);
}

-void mid_get_pci_revID (struct drm_psb_private *dev_priv)
+void mid_get_pci_revID(struct drm_psb_private *dev_priv)
{
uint32_t platform_rev_id = 0;
struct pci_dev *pci_gfx_root = pci_get_bus_and_slot(0, PCI_DEVFN(2, 0));
@@ -230,7 +229,7 @@ void mid_get_pci_revID (struct drm_psb_private *dev_priv)


dev_priv->platform_rev_id = (uint8_t) platform_rev_id;
pci_dev_put(pci_gfx_root);

dev_info(dev_priv->dev->dev, "platform_rev_id is %x\n",

- dev_priv->platform_rev_id);


+ dev_priv->platform_rev_id);
}

void mrst_get_vbt_data(struct drm_psb_private *dev_priv)

@@ -285,7 +284,7 @@ void mrst_get_vbt_data(struct drm_psb_private *dev_priv)
dev_priv->gct_data.Panel_Port_Control =
((struct mrst_gct_v1 *)pGCT)->panel[bpi].Panel_Port_Control;
dev_priv->gct_data.Panel_MIPI_Display_Descriptor =
- ((struct mrst_gct_v1 *)pGCT)->panel[bpi].Panel_MIPI_Display_Descriptor;
+ ((struct mrst_gct_v1 *)pGCT)->panel[bpi].Panel_MIPI_Display_Descriptor;
break;
case 1:
vbt->mrst_gct = NULL;
@@ -303,7 +302,7 @@ void mrst_get_vbt_data(struct drm_psb_private *dev_priv)
dev_priv->gct_data.Panel_Port_Control =
((struct mrst_gct_v2 *)pGCT)->panel[bpi].Panel_Port_Control;
dev_priv->gct_data.Panel_MIPI_Display_Descriptor =
- ((struct mrst_gct_v2 *)pGCT)->panel[bpi].Panel_MIPI_Display_Descriptor;
+ ((struct mrst_gct_v2 *)pGCT)->panel[bpi].Panel_MIPI_Display_Descriptor;
break;
case 0x10:
/*header definition changed from rev 01 (v2) to rev 10h. */
@@ -449,13 +448,12 @@ static int psb_do_init(struct drm_device *dev)


PSB_WSGX32(0x00000000, PSB_CR_BIF_BANK0);
PSB_WSGX32(0x00000000, PSB_CR_BIF_BANK1);
PSB_RSGX32(PSB_CR_BIF_BANK1);

- PSB_WSGX32(PSB_RSGX32(PSB_CR_BIF_CTRL) | _PSB_MMU_ER_MASK,
+ PSB_WSGX32(PSB_RSGX32(PSB_CR_BIF_CTRL) | _PSB_MMU_ER_MASK,
PSB_CR_BIF_CTRL);
psb_spank(dev_priv);

/* mmu_gatt ?? */
- PSB_WSGX32(pg->gatt_start, PSB_CR_BIF_TWOD_REQ_BASE);
-
+ PSB_WSGX32(pg->gatt_start, PSB_CR_BIF_TWOD_REQ_BASE);
return 0;
out_err:
psb_do_takedown(dev);
@@ -1335,7 +1333,6 @@ static long psb_unlocked_ioctl(struct file *filp, unsigned int cmd,
dev_priv->rpm_enabled = 1;
}
return drm_ioctl(filp, cmd, arg);
-
/* FIXME: do we need to wrap the other side of this */
}

@@ -1367,7 +1364,7 @@ static struct vm_operations_struct psb_gem_vm_ops = {

static struct drm_driver driver = {
.driver_features = DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED | \
- DRIVER_IRQ_VBL | DRIVER_MODESET| DRIVER_GEM ,
+ DRIVER_IRQ_VBL | DRIVER_MODESET | DRIVER_GEM ,
.load = psb_driver_load,
.unload = psb_driver_unload,

@@ -1428,7 +1425,7 @@ 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");


+ dev_warn(&pdev->dev, "Enable MSI failed!\n");
return drm_get_pci_dev(pdev, ent, &driver);
}

diff --git a/drivers/staging/gma500/psb_drv.h b/drivers/staging/gma500/psb_drv.h
index 45752aa..1114021 100644
--- a/drivers/staging/gma500/psb_drv.h
+++ b/drivers/staging/gma500/psb_drv.h
@@ -25,6 +25,7 @@

#include <drm/drmP.h>
#include "drm_global.h"
+#include "gem_glue.h"
#include "psb_drm.h"
#include "psb_reg.h"
#include "psb_intel_drv.h"
@@ -132,8 +133,12 @@ enum {
#define _LNC_IRQ_TOPAZ_FLAG (1<<20)

/* 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 | \
- _PSB_PIPEA_EVENT_FLAG | _PSB_VSYNC_PIPEA_FLAG | _MDFLD_MIPIA_FLAG | _MDFLD_MIPIC_FLAG)
+#define _MDFLD_DISP_ALL_IRQ_FLAG (_MDFLD_PIPEC_EVENT_FLAG | \
+ _MDFLD_PIPEB_EVENT_FLAG | \
+ _PSB_PIPEA_EVENT_FLAG | \
+ _PSB_VSYNC_PIPEA_FLAG | \
+ _MDFLD_MIPIA_FLAG | \
+ _MDFLD_MIPIC_FLAG)
#define PSB_INT_IDENTITY_R 0x20A4
#define PSB_INT_MASK_R 0x20A8
#define PSB_INT_ENABLE_R 0x20A0
@@ -273,7 +278,7 @@ struct drm_psb_private {

/*
* Power
- */
+ */

bool suspended;
bool display_power;
@@ -480,7 +485,7 @@ struct drm_psb_private {
uint32_t blc_adj1;
uint32_t blc_adj2;

- void * fbdev;
+ void *fbdev;
};


@@ -550,7 +555,7 @@ extern void psb_irq_turn_on_dpst(struct drm_device *dev);
extern void psb_irq_turn_off_dpst(struct drm_device *dev);

extern void psb_irq_uninstall_islands(struct drm_device *dev, int hw_islands);
-extern int psb_vblank_wait2(struct drm_device *dev,unsigned int *sequence);
+extern int psb_vblank_wait2(struct drm_device *dev, unsigned int *sequence);
extern int psb_vblank_wait(struct drm_device *dev, unsigned int *sequence);
extern int psb_enable_vblank(struct drm_device *dev, int crtc);
extern void psb_disable_vblank(struct drm_device *dev, int crtc);
@@ -593,7 +598,7 @@ extern int psbfb_sync(struct fb_info *info);


extern void psb_spank(struct drm_psb_private *dev_priv);

extern int psbfb_2d_submit(struct drm_psb_private *dev_priv, uint32_t *cmdbuf,

- unsigned size);
+ unsigned size);

/*
* psb_reset.c
@@ -606,14 +611,14 @@ extern void psb_print_pagefault(struct drm_psb_private *dev_priv);
/* modesetting */
extern void psb_modeset_init(struct drm_device *dev);
extern void psb_modeset_cleanup(struct drm_device *dev);
-extern int psb_fbdev_init(struct drm_device * dev);
+extern int psb_fbdev_init(struct drm_device *dev);

/* psb_bl.c */
int psb_backlight_init(struct drm_device *dev);
void psb_backlight_exit(void);
int psb_set_brightness(struct backlight_device *bd);
int psb_get_brightness(struct backlight_device *bd);
-struct backlight_device * psb_get_backlight_device(void);
+struct backlight_device *psb_get_backlight_device(void);

/* mrst_crtc.c */
extern const struct drm_crtc_helper_funcs mrst_helper_funcs;
@@ -662,7 +667,6 @@ extern int psb_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf);


extern int drm_psb_no_fb;
extern int drm_idle_check_interval;

-

/*
* Utilities
*/
@@ -671,36 +675,36 @@ static inline u32 MRST_MSG_READ32(uint port, uint offset)
{
int mcr = (0xD0<<24) | (port << 16) | (offset << 8);
uint32_t ret_val = 0;
- struct pci_dev *pci_root = pci_get_bus_and_slot (0, 0);
- pci_write_config_dword (pci_root, 0xD0, mcr);
- pci_read_config_dword (pci_root, 0xD4, &ret_val);
+ struct pci_dev *pci_root = pci_get_bus_and_slot(0, 0);
+ pci_write_config_dword(pci_root, 0xD0, mcr);
+ pci_read_config_dword(pci_root, 0xD4, &ret_val);
pci_dev_put(pci_root);
return ret_val;
}
static inline void MRST_MSG_WRITE32(uint port, uint offset, u32 value)
{
int mcr = (0xE0<<24) | (port << 16) | (offset << 8) | 0xF0;
- struct pci_dev *pci_root = pci_get_bus_and_slot (0, 0);
- pci_write_config_dword (pci_root, 0xD4, value);
- pci_write_config_dword (pci_root, 0xD0, mcr);
+ struct pci_dev *pci_root = pci_get_bus_and_slot(0, 0);
+ pci_write_config_dword(pci_root, 0xD4, value);
+ pci_write_config_dword(pci_root, 0xD0, mcr);
pci_dev_put(pci_root);
}
static inline u32 MDFLD_MSG_READ32(uint port, uint offset)
{
int mcr = (0x10<<24) | (port << 16) | (offset << 8);
uint32_t ret_val = 0;
- struct pci_dev *pci_root = pci_get_bus_and_slot (0, 0);
- pci_write_config_dword (pci_root, 0xD0, mcr);
- pci_read_config_dword (pci_root, 0xD4, &ret_val);
+ struct pci_dev *pci_root = pci_get_bus_and_slot(0, 0);
+ pci_write_config_dword(pci_root, 0xD0, mcr);
+ pci_read_config_dword(pci_root, 0xD4, &ret_val);
pci_dev_put(pci_root);
return ret_val;


}
static inline void MDFLD_MSG_WRITE32(uint port, uint offset, u32 value)

{
int mcr = (0x11<<24) | (port << 16) | (offset << 8) | 0xF0;
- struct pci_dev *pci_root = pci_get_bus_and_slot (0, 0);
- pci_write_config_dword (pci_root, 0xD4, value);
- pci_write_config_dword (pci_root, 0xD0, mcr);
+ struct pci_dev *pci_root = pci_get_bus_and_slot(0, 0);
+ pci_write_config_dword(pci_root, 0xD4, value);
+ pci_write_config_dword(pci_root, 0xD0, mcr);
pci_dev_put(pci_root);
}

@@ -744,14 +748,15 @@ static inline void REGISTER_WRITE8(struct drm_device *dev,



/* #define TRAP_SGX_PM_FAULT 1 */
#ifdef TRAP_SGX_PM_FAULT

-#define PSB_RSGX32(_offs) \
-({ \
- if (inl(dev_priv->apm_base + PSB_APM_STS) & 0x3) { \
- printk(KERN_ERR "access sgx when it's off!! (READ) %s, %d\n", \
- __FILE__, __LINE__); \
- mdelay(1000); \
- } \


- ioread32(dev_priv->sgx_reg + (_offs)); \

+#define PSB_RSGX32(_offs) \
+({ \
+ if (inl(dev_priv->apm_base + PSB_APM_STS) & 0x3) { \
+ printk(KERN_ERR \
+ "access sgx when it's off!! (READ) %s, %d\n", \
+ __FILE__, __LINE__); \
+ melay(1000); \
+ } \
+ ioread32(dev_priv->sgx_reg + (_offs)); \
})
#else


#define PSB_RSGX32(_offs) ioread32(dev_priv->sgx_reg + (_offs))

diff --git a/drivers/staging/gma500/psb_fb.c b/drivers/staging/gma500/psb_fb.c
index 400dbee..f1a7e8d 100644
--- a/drivers/staging/gma500/psb_fb.c
+++ b/drivers/staging/gma500/psb_fb.c
@@ -244,9 +244,11 @@ static int psbfb_mmap(struct fb_info *info, struct vm_area_struct *vma)



fb_screen_base = (char *)info->screen_base;

- /* If this is a GEM object then info->screen_base is the virtual
- kernel remapping of the object. FIXME: Review if this is
- suitable for our mmap work */
+ /*
+ * If this is a GEM object then info->screen_base is the virtual
+ * kernel remapping of the object. FIXME: Review if this is
+ * suitable for our mmap work
+ */
vma->vm_ops = &psbfb_vm_ops;


vma->vm_private_data = (void *)psbfb;

vma->vm_flags |= VM_RESERVED | VM_IO |

@@ -254,7 +256,8 @@ static int psbfb_mmap(struct fb_info *info, struct vm_area_struct *vma)
return 0;
}

-static int psbfb_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg)
+static int psbfb_ioctl(struct fb_info *info, unsigned int cmd,
+ unsigned long arg)
{


struct psb_fbdev *fbdev = info->par;

struct psb_framebuffer *psbfb = &fbdev->pfb;

@@ -305,33 +308,33 @@ static struct fb_ops psbfb_ops = {


* 0 on success or an error code if we fail.

*/
static int psb_framebuffer_init(struct drm_device *dev,
- struct psb_framebuffer *fb,
- struct drm_mode_fb_cmd *mode_cmd,
- struct gtt_range *gt)


+ struct psb_framebuffer *fb,
+ struct drm_mode_fb_cmd *mode_cmd,
+ struct gtt_range *gt)

{
- int ret;
-
- if (mode_cmd->pitch & 63)
- return -EINVAL;
- switch (mode_cmd->bpp) {
- case 8:
- case 16:


- case 24:
- case 32:

- break;
- default:
- return -EINVAL;


- }
- ret = drm_framebuffer_init(dev, &fb->base, &psb_fb_funcs);

- if (ret) {
- dev_err(dev->dev, "framebuffer init failed: %d\n", ret);
- return ret;
- }
- drm_helper_mode_fill_fb_struct(&fb->base, mode_cmd);


- fb->gtt = gt;

- return 0;


+ int ret;
+
+ if (mode_cmd->pitch & 63)
+ return -EINVAL;
+ switch (mode_cmd->bpp) {
+ case 8:
+ case 16:
+ case 24:
+ case 32:
+ break;
+ default:
+ return -EINVAL;
+ }
+ ret = drm_framebuffer_init(dev, &fb->base, &psb_fb_funcs);
+ if (ret) {
+ dev_err(dev->dev, "framebuffer init failed: %d\n", ret);
+ return ret;
+ }
+ drm_helper_mode_fill_fb_struct(&fb->base, mode_cmd);
+ fb->gtt = gt;
+ return 0;
}

-
+
/**


* psb_framebuffer_create - create a framebuffer backed by gt

* @dev: our DRM device

@@ -357,10 +360,10 @@ static struct drm_framebuffer *psb_framebuffer_create



ret = psb_framebuffer_init(dev, fb, mode_cmd, gt);

if (ret) {
- kfree(fb);
- return ERR_PTR(ret);


- }
- return &fb->base;

+ kfree(fb);
+ return ERR_PTR(ret);
+ }
+ return &fb->base;
}

/**

@@ -373,7 +376,7 @@ static struct drm_framebuffer *psb_framebuffer_create
* stolen memory or the system has no stolen memory we allocate a range


* and back it with a GEM object.
*

- * In this case the GEM object has no handle.
+ * 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.

@@ -384,10 +387,11 @@ static struct gtt_range *psbfb_alloc(struct drm_device *dev, int aligned_size)


/* Begin by trying to use stolen memory backing */
backing = psb_gtt_alloc_range(dev, aligned_size, "fb", 1);

if (backing) {
- if (drm_gem_private_object_init(dev, &backing->gem, aligned_size) == 0)
- return backing;
- psb_gtt_free_range(dev, backing);
- }
+ if (drm_gem_private_object_init(dev,
+ &backing->gem, aligned_size) == 0)


+ 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)

@@ -400,7 +404,7 @@ static struct gtt_range *psbfb_alloc(struct drm_device *dev, int aligned_size)
}
return backing;
}
-
+
/**
* psbfb_create - create a framebuffer
* @fbdev: the framebuffer device
@@ -428,7 +432,7 @@ static int psbfb_create(struct psb_fbdev *fbdev,



/* No 24bit packed */

if (mode_cmd.bpp == 24)
- mode_cmd.bpp = 32;
+ mode_cmd.bpp = 32;



/* HW requires pitch to be 64 byte aligned */

mode_cmd.pitch = ALIGN(mode_cmd.width * ((mode_cmd.bpp + 7) / 8), 64);

@@ -440,7 +444,7 @@ static int psbfb_create(struct psb_fbdev *fbdev,


/* Allocate the framebuffer in the GTT with stolen page backing */

backing = psbfb_alloc(dev, size);
if (backing == NULL)

- return -ENOMEM;
+ return -ENOMEM;

mutex_lock(&dev->struct_mutex);

@@ -455,7 +459,7 @@ static int psbfb_create(struct psb_fbdev *fbdev,
if (ret)
goto out_unref;

- fb = &psbfb->base;


+ fb = &psbfb->base;
psbfb->fbdev = info;

fbdev->psb_fb_helper.fb = fb;

@@ -523,13 +527,13 @@ static int psbfb_create(struct psb_fbdev *fbdev,
mutex_unlock(&dev->struct_mutex);
return 0;
out_unref:
- if (backing->stolen)
- psb_gtt_free_range(dev, backing);
- else {
- if (psbfb->vm_map)
- vm_unmap_ram(info->screen_base, backing->npage);
- drm_gem_object_unreference(&backing->gem);
- }


+ if (backing->stolen)
+ psb_gtt_free_range(dev, backing);
+ else {
+ if (psbfb->vm_map)
+ vm_unmap_ram(info->screen_base, backing->npage);
+ drm_gem_object_unreference(&backing->gem);
+ }
out_err1:
mutex_unlock(&dev->struct_mutex);
psb_gtt_free_range(dev, backing);

@@ -548,17 +552,19 @@ static struct drm_framebuffer *psb_user_framebuffer_create
(struct drm_device *dev, struct drm_file *filp,
struct drm_mode_fb_cmd *cmd)
{
- struct gtt_range *r;
- struct drm_gem_object *obj;
+ struct gtt_range *r;
+ struct drm_gem_object *obj;

- /* Find the GEM object and thus the gtt range object that is
- to back this space */
+ /*
+ * Find the GEM object and thus the gtt range object that is
+ * to back this space
+ */
obj = drm_gem_object_lookup(dev, filp, cmd->handle);
if (obj == NULL)
- return ERR_PTR(-ENOENT);
+ return ERR_PTR(-ENOENT);

- /* Let the core code do all the work */
- r = container_of(obj, struct gtt_range, gem);
+ /* Let the core code do all the work */
+ r = container_of(obj, struct gtt_range, gem);
return psb_framebuffer_create(dev, cmd, r);
}

@@ -610,12 +616,12 @@ int psb_fbdev_destroy(struct drm_device *dev, struct psb_fbdev *fbdev)
}
unregister_framebuffer(info);
if (info->cmap.len)
- fb_dealloc_cmap(&info->cmap);
+ fb_dealloc_cmap(&info->cmap);
framebuffer_release(info);
}
drm_fb_helper_fini(&fbdev->psb_fb_helper);
drm_framebuffer_cleanup(&psbfb->base);
-

+
if (psbfb->gtt) {
/* FIXME: this is a bit more inside knowledge than I'd like
but I don't see how to make a fake GEM object of the

@@ -624,7 +630,7 @@ int psb_fbdev_destroy(struct drm_device *dev, struct psb_fbdev *fbdev)


psb_gtt_free_range(dev, psbfb->gtt);
else
drm_gem_object_unreference(&psbfb->gtt->gem);
- }

+ }
return 0;
}

@@ -686,9 +692,9 @@ static int psb_user_framebuffer_create_handle(struct drm_framebuffer *fb,
struct drm_file *file_priv,
unsigned int *handle)
{
- struct psb_framebuffer *psbfb = to_psb_fb(fb);
- struct gtt_range *r = psbfb->gtt;
- return drm_gem_handle_create(file_priv, &r->gem, handle);
+ struct psb_framebuffer *psbfb = to_psb_fb(fb);
+ struct gtt_range *r = psbfb->gtt;
+ return drm_gem_handle_create(file_priv, &r->gem, handle);
}

/**
@@ -717,16 +723,17 @@ static void psb_user_framebuffer_destroy(struct drm_framebuffer *fb)


reset = 1;

if (reset)

- /*
- * Now force a sane response before we permit the DRM crc layer to
- * do stupid things like blank the display. Instead we reset this
- * framebuffer as if the user had forced a reset. We must do this
- * before the cleanup so that the DRM layer doesn't get a chance
- * to stick its oar in where it isn't wanted.
+ /*
+ * Now force a sane response before we permit the DRM CRTC
+ * layer to do stupid things like blank the display. Instead
+ * we reset this framebuffer as if the user had forced a reset.
+ * We must do this before the cleanup so that the DRM layer
+ * doesn't get a chance to stick its oar in where it isn't
+ * wanted.
*/
drm_fb_helper_restore_fbdev_mode(&fbdev->psb_fb_helper);

- /* Let DRM do its clean up */


+ /* Let DRM do its clean up */
drm_framebuffer_cleanup(fb);
/* We are no longer using the resource in GEM */
drm_gem_object_unreference_unlocked(&r->gem);

diff --git a/drivers/staging/gma500/psb_gem.c b/drivers/staging/gma500/psb_gem.c
index 4aec38c..3f658e4 100644
--- a/drivers/staging/gma500/psb_gem.c
+++ b/drivers/staging/gma500/psb_gem.c
@@ -82,12 +82,13 @@ static int psb_gem_create_mmap_offset(struct drm_gem_object *obj)
map = list->map;
map->type = _DRM_GEM;
map->size = obj->size;
- map->handle =obj;
+ map->handle = obj;



list->file_offset_node = drm_mm_search_free(&mm->offset_manager,
obj->size / PAGE_SIZE, 0, 0);
if (!list->file_offset_node) {

- dev_err(dev->dev, "failed to allocate offset for bo %d\n", obj->name);


+ dev_err(dev->dev, "failed to allocate offset for bo %d\n",

+ obj->name);


ret = -ENOSPC;
goto free_it;
}

@@ -130,7 +131,7 @@ int psb_gem_dumb_map_gtt(struct drm_file *file, struct drm_device *dev,

if (!(dev->driver->driver_features & DRIVER_GEM))
return -ENODEV;
-
+
mutex_lock(&dev->struct_mutex);

/* GEM does all our handle to object mapping */
@@ -140,7 +141,7 @@ int psb_gem_dumb_map_gtt(struct drm_file *file, struct drm_device *dev,
goto unlock;
}
/* What validation is needed here ? */
-
+
/* Make it mmapable */
if (!obj->map_list.map) {
ret = psb_gem_create_mmap_offset(obj);
@@ -176,7 +177,7 @@ static int psb_gem_create(struct drm_file *file,

size = roundup(size, PAGE_SIZE);

- /* Allocate our object - for now a direct gtt range which is not
+ /* Allocate our object - for now a direct gtt range which is not


stolen memory backed */
r = psb_gtt_alloc_range(dev, size, "gem", 0);

if (r == NULL) {
@@ -285,9 +286,9 @@ int psb_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf)


if (r->mmapping == 0) {
ret = psb_gtt_pin(r);
if (ret < 0) {

- dev_err(dev->dev, "gma500: pin failed: %d\n", ret);
- goto fail;
- }


+ dev_err(dev->dev, "gma500: pin failed: %d\n", ret);

+ goto fail;
+ }
r->mmapping = 1;
}

@@ -304,7 +305,7 @@ int psb_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf)


ret = vm_insert_pfn(vma, (unsigned long)vmf->virtual_address, pfn);

fail:

- mutex_unlock(&dev->struct_mutex);
+ mutex_unlock(&dev->struct_mutex);
switch (ret) {
case 0:
case -ERESTARTSYS:
diff --git a/drivers/staging/gma500/psb_gtt.c b/drivers/staging/gma500/psb_gtt.c
index 9da1375..6cfa59b 100644
--- a/drivers/staging/gma500/psb_gtt.c
+++ b/drivers/staging/gma500/psb_gtt.c
@@ -52,7 +52,7 @@ static inline uint32_t psb_gtt_mask_pte(uint32_t pfn, int type)


* psb_gtt_entry - find the GTT entries for a gtt_range

* @dev: our DRM device

* @r: our GTT range

- *
+ *


* Given a gtt_range object return the GTT offset of the page table
* entries for this gtt_range
*/

@@ -102,7 +102,6 @@ static int psb_gtt_insert(struct drm_device *dev, struct gtt_range *r)
}
/* Make sure all the entries are set before we return */
ioread32(gtt_slot - 1);
-
return 0;
}

@@ -257,7 +256,7 @@ void psb_gtt_unpin(struct gtt_range *gt)
}
mutex_unlock(&dev_priv->gtt_mutex);
}
-
+
/*
* GTT resource allocator - allocate and manage GTT address space
*/
@@ -289,11 +288,11 @@ struct gtt_range *psb_gtt_alloc_range(struct drm_device *dev, int len,


/* The start of the GTT is the stolen pages */

start = r->start;


end = r->start + dev_priv->pg->stolen_size - 1;

- } else {


- /* The rest we will use for GEM backed objects */
- start = r->start + dev_priv->pg->stolen_size;
- end = r->end;

- }
+ } else {


+ /* The rest we will use for GEM backed objects */
+ start = r->start + dev_priv->pg->stolen_size;
+ end = r->end;

+ }



gt = kzalloc(sizeof(struct gtt_range), GFP_KERNEL);
if (gt == NULL)

@@ -318,8 +317,8 @@ struct gtt_range *psb_gtt_alloc_range(struct drm_device *dev, int len,


* @dev: our DRM device

* @gt: a mapping created with psb_gtt_alloc_range
*

- * Release a resource that was allocated with psb_gtt_alloc_range. If the object
- * has been pinned by mmap users we clean this up here currently.


+ * Release a resource that was allocated with psb_gtt_alloc_range. If the

+ * object has been pinned by mmap users we clean this up here currently.
*/


void psb_gtt_free_range(struct drm_device *dev, struct gtt_range *gt)
{

@@ -386,7 +385,7 @@ int psb_gtt_init(struct drm_device *dev, int resume)


if (pg == NULL)
return -ENOMEM;

- /* Enable the GTT */


+ /* Enable the GTT */
pci_read_config_word(dev->pdev, PSB_GMCH_CTRL, &dev_priv->gmch_ctrl);
pci_write_config_word(dev->pdev, PSB_GMCH_CTRL,
dev_priv->gmch_ctrl | _PSB_GMCH_ENABLED);

@@ -402,18 +401,21 @@ int psb_gtt_init(struct drm_device *dev, int resume)


pg->gtt_phys_start = dev_priv->pge_ctl & PAGE_MASK;

pg->gatt_start = pci_resource_start(dev->pdev, PSB_GATT_RESOURCE);
- /*

+ /*


* FIXME: video mmu has hw bug to access 0x0D0000000,

* then make gatt start at 0x0e000,0000
*/

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;
- pg->gatt_pages = pci_resource_len(dev->pdev, PSB_GATT_RESOURCE) >> PAGE_SHIFT;


+ gtt_pages = pci_resource_len(dev->pdev, PSB_GTT_RESOURCE)

+ >> PAGE_SHIFT;


+ pg->gatt_pages = pci_resource_len(dev->pdev, PSB_GATT_RESOURCE)

+ >> PAGE_SHIFT;



pci_read_config_dword(dev->pdev, PSB_BSM, &dev_priv->stolen_base);

- vram_stolen_size = pg->gtt_phys_start - dev_priv->stolen_base - PAGE_SIZE;
+ vram_stolen_size = pg->gtt_phys_start - dev_priv->stolen_base
+ - PAGE_SIZE;

stolen_size = vram_stolen_size;

@@ -439,7 +441,8 @@ int psb_gtt_init(struct drm_device *dev, int resume)
/*


* Map the GTT and the stolen memory area

*/
- dev_priv->gtt_map = ioremap_nocache(pg->gtt_phys_start, gtt_pages << PAGE_SHIFT);
+ dev_priv->gtt_map = ioremap_nocache(pg->gtt_phys_start,
+ gtt_pages << PAGE_SHIFT);
if (!dev_priv->gtt_map) {


dev_err(dev->dev, "Failure to map gtt.\n");
ret = -ENOMEM;

diff --git a/drivers/staging/gma500/psb_intel_display.c b/drivers/staging/gma500/psb_intel_display.c
index be7e1f9..1bb2144 100644
--- a/drivers/staging/gma500/psb_intel_display.c
+++ b/drivers/staging/gma500/psb_intel_display.c
@@ -388,7 +388,7 @@ int psb_intel_pipe_set_base(struct drm_crtc *crtc,


dspcntr |= DISPPLANE_32BPP_NO_ALPHA;
break;
default:

- dev_err(dev->dev, "Unknown color depth\n");


+ dev_err(dev->dev, "Unknown color depth\n");
ret = -EINVAL;
psb_gtt_unpin(psbfb->gtt);
goto psb_intel_pipe_set_base_exit;

@@ -611,9 +611,9 @@ static int psb_intel_crtc_mode_set(struct drm_crtc *crtc,



/* No scan out no play */

if (crtc->fb == NULL) {

- crtc_funcs->mode_set_base(crtc, x, y, old_fb);

- return 0;


- }
+ crtc_funcs->mode_set_base(crtc, x, y, old_fb);

+ return 0;


+ }

list_for_each_entry(connector, &mode_config->connector_list, head) {
struct psb_intel_output *psb_intel_output =

@@ -728,8 +728,8 @@ static int psb_intel_crtc_mode_set(struct drm_crtc *crtc,
u32 lvds = REG_READ(LVDS);

lvds &= ~LVDS_PIPEB_SELECT;
- if (pipe == 1)
- lvds |= LVDS_PIPEB_SELECT;


+ if (pipe == 1)
+ lvds |= LVDS_PIPEB_SELECT;

lvds |= LVDS_PORT_EN | LVDS_A0A2_CLKA_POWER_UP;
/* Set the B0-B3 data pairs corresponding to

diff --git a/drivers/staging/gma500/psb_intel_opregion.c b/drivers/staging/gma500/psb_intel_opregion.c
index 51cf1d6..97a8b00 100644
--- a/drivers/staging/gma500/psb_intel_opregion.c
+++ b/drivers/staging/gma500/psb_intel_opregion.c
@@ -33,19 +33,19 @@ struct opregion_header {
u8 driver_ver[16];
u32 mboxes;
u8 reserved[164];
-} __attribute__((packed));
+} __packed;

struct opregion_apci {
/*FIXME: add it later*/
-} __attribute__((packed));
+} __packed;

struct opregion_swsci {
/*FIXME: add it later*/
-} __attribute__((packed));
+} __packed;

struct opregion_acpi {
/*FIXME: add it later*/
-} __attribute__((packed));
+} __packed;

int psb_intel_opregion_init(struct drm_device *dev)
{
diff --git a/drivers/staging/gma500/psb_intel_reg.h b/drivers/staging/gma500/psb_intel_reg.h
index 1c28314..c9630a2 100644
--- a/drivers/staging/gma500/psb_intel_reg.h
+++ b/drivers/staging/gma500/psb_intel_reg.h
@@ -28,8 +28,8 @@
*
* The actual value is this field multiplied by two.
*/
-#define BACKLIGHT_MODULATION_FREQ_MASK (0x7fff << 17)
-#define BLM_LEGACY_MODE (1 << 16)
+#define BACKLIGHT_MODULATION_FREQ_MASK (0x7fff << 17)
+#define BLM_LEGACY_MODE (1 << 16)
/*
* This is the number of cycles out of the backlight modulation cycle for which
* the backlight is on.
@@ -37,55 +37,55 @@
* This field must be no greater than the number of cycles in the complete
* backlight modulation cycle.
*/
-#define BACKLIGHT_DUTY_CYCLE_SHIFT (0)
-#define BACKLIGHT_DUTY_CYCLE_MASK (0xffff)
+#define BACKLIGHT_DUTY_CYCLE_SHIFT (0)
+#define BACKLIGHT_DUTY_CYCLE_MASK (0xffff)

#define I915_GCFGC 0xf0
-#define I915_LOW_FREQUENCY_ENABLE (1 << 7)
-#define I915_DISPLAY_CLOCK_190_200_MHZ (0 << 4)
-#define I915_DISPLAY_CLOCK_333_MHZ (4 << 4)
-#define I915_DISPLAY_CLOCK_MASK (7 << 4)
+#define I915_LOW_FREQUENCY_ENABLE (1 << 7)
+#define I915_DISPLAY_CLOCK_190_200_MHZ (0 << 4)
+#define I915_DISPLAY_CLOCK_333_MHZ (4 << 4)
+#define I915_DISPLAY_CLOCK_MASK (7 << 4)

#define I855_HPLLCC 0xc0
-#define I855_CLOCK_CONTROL_MASK (3 << 0)
-#define I855_CLOCK_133_200 (0 << 0)
-#define I855_CLOCK_100_200 (1 << 0)
-#define I855_CLOCK_100_133 (2 << 0)
-#define I855_CLOCK_166_250 (3 << 0)
+#define I855_CLOCK_CONTROL_MASK (3 << 0)
+#define I855_CLOCK_133_200 (0 << 0)
+#define I855_CLOCK_100_200 (1 << 0)
+#define I855_CLOCK_100_133 (2 << 0)
+#define I855_CLOCK_166_250 (3 << 0)

/* I830 CRTC registers */
-#define HTOTAL_A 0x60000
-#define HBLANK_A 0x60004
-#define HSYNC_A 0x60008
-#define VTOTAL_A 0x6000c
-#define VBLANK_A 0x60010
-#define VSYNC_A 0x60014
-#define PIPEASRC 0x6001c
-#define BCLRPAT_A 0x60020
-#define VSYNCSHIFT_A 0x60028
-
-#define HTOTAL_B 0x61000
-#define HBLANK_B 0x61004
-#define HSYNC_B 0x61008
-#define VTOTAL_B 0x6100c
-#define VBLANK_B 0x61010
-#define VSYNC_B 0x61014
-#define PIPEBSRC 0x6101c
-#define BCLRPAT_B 0x61020
-#define VSYNCSHIFT_B 0x61028
-
-#define HTOTAL_C 0x62000
-#define HBLANK_C 0x62004
-#define HSYNC_C 0x62008
-#define VTOTAL_C 0x6200c
-#define VBLANK_C 0x62010
-#define VSYNC_C 0x62014
-#define PIPECSRC 0x6201c
-#define BCLRPAT_C 0x62020
-#define VSYNCSHIFT_C 0x62028
-
-#define PP_STATUS 0x61200
-# define PP_ON (1 << 31)
+#define HTOTAL_A 0x60000
+#define HBLANK_A 0x60004
+#define HSYNC_A 0x60008
+#define VTOTAL_A 0x6000c
+#define VBLANK_A 0x60010
+#define VSYNC_A 0x60014
+#define PIPEASRC 0x6001c
+#define BCLRPAT_A 0x60020
+#define VSYNCSHIFT_A 0x60028
+
+#define HTOTAL_B 0x61000
+#define HBLANK_B 0x61004
+#define HSYNC_B 0x61008
+#define VTOTAL_B 0x6100c
+#define VBLANK_B 0x61010
+#define VSYNC_B 0x61014
+#define PIPEBSRC 0x6101c
+#define BCLRPAT_B 0x61020
+#define VSYNCSHIFT_B 0x61028
+
+#define HTOTAL_C 0x62000
+#define HBLANK_C 0x62004
+#define HSYNC_C 0x62008
+#define VTOTAL_C 0x6200c
+#define VBLANK_C 0x62010
+#define VSYNC_C 0x62014
+#define PIPECSRC 0x6201c
+#define BCLRPAT_C 0x62020
+#define VSYNCSHIFT_C 0x62028
+
+#define PP_STATUS 0x61200
+# define PP_ON (1 << 31)
/*
* Indicates that all dependencies of the panel are on:
*
@@ -93,56 +93,55 @@
* - pipe enabled
* - LVDS/DVOB/DVOC on
*/
-# define PP_READY (1 << 30)
-# define PP_SEQUENCE_NONE (0 << 28)
-# define PP_SEQUENCE_ON (1 << 28)
-# define PP_SEQUENCE_OFF (2 << 28)
-# define PP_SEQUENCE_MASK 0x30000000
-#define PP_CONTROL 0x61204
-# define POWER_TARGET_ON (1 << 0)
-
-#define LVDSPP_ON 0x61208
-#define LVDSPP_OFF 0x6120c
-#define PP_CYCLE 0x61210
-
-#define PFIT_CONTROL 0x61230
-# define PFIT_ENABLE (1 << 31)
-# define PFIT_PIPE_MASK (3 << 29)
-# define PFIT_PIPE_SHIFT 29
-# define PFIT_SCALING_MODE_PILLARBOX (1 << 27)
-# define PFIT_SCALING_MODE_LETTERBOX (3 << 26)
-# define VERT_INTERP_DISABLE (0 << 10)
-# define VERT_INTERP_BILINEAR (1 << 10)
-# define VERT_INTERP_MASK (3 << 10)
-# define VERT_AUTO_SCALE (1 << 9)
-# define HORIZ_INTERP_DISABLE (0 << 6)
-# define HORIZ_INTERP_BILINEAR (1 << 6)
-# define HORIZ_INTERP_MASK (3 << 6)
-# define HORIZ_AUTO_SCALE (1 << 5)
-# define PANEL_8TO6_DITHER_ENABLE (1 << 3)
-
-#define PFIT_PGM_RATIOS 0x61234
-# define PFIT_VERT_SCALE_MASK 0xfff00000
-# define PFIT_HORIZ_SCALE_MASK 0x0000fff0
+#define PP_READY (1 << 30)
+#define PP_SEQUENCE_NONE (0 << 28)
+#define PP_SEQUENCE_ON (1 << 28)
+#define PP_SEQUENCE_OFF (2 << 28)
+#define PP_SEQUENCE_MASK 0x30000000
+#define PP_CONTROL 0x61204
+#define POWER_TARGET_ON (1 << 0)
+
+#define LVDSPP_ON 0x61208
+#define LVDSPP_OFF 0x6120c
+#define PP_CYCLE 0x61210
+
+#define PFIT_CONTROL 0x61230
+#define PFIT_ENABLE (1 << 31)
+#define PFIT_PIPE_MASK (3 << 29)
+#define PFIT_PIPE_SHIFT 29
+#define PFIT_SCALING_MODE_PILLARBOX (1 << 27)
+#define PFIT_SCALING_MODE_LETTERBOX (3 << 26)
+#define VERT_INTERP_DISABLE (0 << 10)
+#define VERT_INTERP_BILINEAR (1 << 10)
+#define VERT_INTERP_MASK (3 << 10)
+#define VERT_AUTO_SCALE (1 << 9)
+#define HORIZ_INTERP_DISABLE (0 << 6)
+#define HORIZ_INTERP_BILINEAR (1 << 6)
+#define HORIZ_INTERP_MASK (3 << 6)
+#define HORIZ_AUTO_SCALE (1 << 5)
+#define PANEL_8TO6_DITHER_ENABLE (1 << 3)
+
+#define PFIT_PGM_RATIOS 0x61234
+#define PFIT_VERT_SCALE_MASK 0xfff00000
+#define PFIT_HORIZ_SCALE_MASK 0x0000fff0

#define PFIT_AUTO_RATIOS 0x61238

-
-#define DPLL_A 0x06014
-#define DPLL_B 0x06018
-# define DPLL_VCO_ENABLE (1 << 31)
-# define DPLL_DVO_HIGH_SPEED (1 << 30)
-# define DPLL_SYNCLOCK_ENABLE (1 << 29)
-# define DPLL_VGA_MODE_DIS (1 << 28)
-# define DPLLB_MODE_DAC_SERIAL (1 << 26) /* i915 */
-# define DPLLB_MODE_LVDS (2 << 26) /* i915 */
-# define DPLL_MODE_MASK (3 << 26)
-# define DPLL_DAC_SERIAL_P2_CLOCK_DIV_10 (0 << 24) /* i915 */
-# define DPLL_DAC_SERIAL_P2_CLOCK_DIV_5 (1 << 24) /* i915 */
-# define DPLLB_LVDS_P2_CLOCK_DIV_14 (0 << 24) /* i915 */
-# define DPLLB_LVDS_P2_CLOCK_DIV_7 (1 << 24) /* i915 */
-# define DPLL_P2_CLOCK_DIV_MASK 0x03000000 /* i915 */
-# define DPLL_FPA01_P1_POST_DIV_MASK 0x00ff0000 /* i915 */
+#define DPLL_A 0x06014
+#define DPLL_B 0x06018
+#define DPLL_VCO_ENABLE (1 << 31)
+#define DPLL_DVO_HIGH_SPEED (1 << 30)
+#define DPLL_SYNCLOCK_ENABLE (1 << 29)
+#define DPLL_VGA_MODE_DIS (1 << 28)
+#define DPLLB_MODE_DAC_SERIAL (1 << 26) /* i915 */
+#define DPLLB_MODE_LVDS (2 << 26) /* i915 */
+#define DPLL_MODE_MASK (3 << 26)
+#define DPLL_DAC_SERIAL_P2_CLOCK_DIV_10 (0 << 24) /* i915 */
+#define DPLL_DAC_SERIAL_P2_CLOCK_DIV_5 (1 << 24) /* i915 */
+#define DPLLB_LVDS_P2_CLOCK_DIV_14 (0 << 24) /* i915 */
+#define DPLLB_LVDS_P2_CLOCK_DIV_7 (1 << 24) /* i915 */
+#define DPLL_P2_CLOCK_DIV_MASK 0x03000000 /* i915 */
+#define DPLL_FPA01_P1_POST_DIV_MASK 0x00ff0000 /* i915 */
/*
* The i830 generation, in DAC/serial mode, defines p1 as two plus this
* bitfield, or just 2 if PLL_P1_DIVIDE_BY_TWO is set.
@@ -152,35 +151,35 @@
* The i830 generation, in LVDS mode, defines P1 as the bit number set within
* this field (only one bit may be set).
*/
-# define DPLL_FPA01_P1_POST_DIV_MASK_I830_LVDS 0x003f0000
-# define DPLL_FPA01_P1_POST_DIV_SHIFT 16
-# define PLL_P2_DIVIDE_BY_4 (1 << 23) /* i830, required
+#define DPLL_FPA01_P1_POST_DIV_MASK_I830_LVDS 0x003f0000
+#define DPLL_FPA01_P1_POST_DIV_SHIFT 16
+#define PLL_P2_DIVIDE_BY_4 (1 << 23) /* i830, required
* in DVO non-gang */
-# define PLL_P1_DIVIDE_BY_TWO (1 << 21) /* i830 */
-# define PLL_REF_INPUT_DREFCLK (0 << 13)
-# define PLL_REF_INPUT_TVCLKINA (1 << 13) /* i830 */
-# define PLL_REF_INPUT_TVCLKINBC (2 << 13) /* SDVO
+# define PLL_P1_DIVIDE_BY_TWO (1 << 21) /* i830 */
+#define PLL_REF_INPUT_DREFCLK (0 << 13)
+#define PLL_REF_INPUT_TVCLKINA (1 << 13) /* i830 */
+#define PLL_REF_INPUT_TVCLKINBC (2 << 13) /* SDVO
* TVCLKIN */
-# define PLLB_REF_INPUT_SPREADSPECTRUMIN (3 << 13)
-# define PLL_REF_INPUT_MASK (3 << 13)
-# define PLL_LOAD_PULSE_PHASE_SHIFT 9
+#define PLLB_REF_INPUT_SPREADSPECTRUMIN (3 << 13)
+#define PLL_REF_INPUT_MASK (3 << 13)
+#define PLL_LOAD_PULSE_PHASE_SHIFT 9
/*
* Parallel to Serial Load Pulse phase selection.
* Selects the phase for the 10X DPLL clock for the PCIe
* digital display port. The range is 4 to 13; 10 or more
* is just a flip delay. The default is 6
*/
-# define PLL_LOAD_PULSE_PHASE_MASK (0xf << PLL_LOAD_PULSE_PHASE_SHIFT)
-# define DISPLAY_RATE_SELECT_FPA1 (1 << 8)
+#define PLL_LOAD_PULSE_PHASE_MASK (0xf << PLL_LOAD_PULSE_PHASE_SHIFT)
+#define DISPLAY_RATE_SELECT_FPA1 (1 << 8)

/*
* SDVO multiplier for 945G/GM. Not used on 965.
*
* DPLL_MD_UDI_MULTIPLIER_MASK
*/
-# define SDVO_MULTIPLIER_MASK 0x000000ff
-# define SDVO_MULTIPLIER_SHIFT_HIRES 4
-# define SDVO_MULTIPLIER_SHIFT_VGA 0
+#define SDVO_MULTIPLIER_MASK 0x000000ff
+#define SDVO_MULTIPLIER_SHIFT_HIRES 4
+#define SDVO_MULTIPLIER_SHIFT_VGA 0

/*
* PLL_MD
@@ -194,11 +193,11 @@
*
* Value is pixels minus 1. Must be set to 1 pixel for SDVO.
*/
-# define DPLL_MD_UDI_DIVIDER_MASK 0x3f000000
-# define DPLL_MD_UDI_DIVIDER_SHIFT 24
+#define DPLL_MD_UDI_DIVIDER_MASK 0x3f000000
+#define DPLL_MD_UDI_DIVIDER_SHIFT 24
/* UDI pixel divider for VGA, same as DPLL_MD_UDI_DIVIDER_MASK. */
-# define DPLL_MD_VGA_UDI_DIVIDER_MASK 0x003f0000
-# define DPLL_MD_VGA_UDI_DIVIDER_SHIFT 16
+#define DPLL_MD_VGA_UDI_DIVIDER_MASK 0x003f0000
+#define DPLL_MD_VGA_UDI_DIVIDER_SHIFT 16
/*
* SDVO/UDI pixel multiplier.
*
@@ -216,80 +215,80 @@
* This register field has values of multiplication factor minus 1, with
* a maximum multiplier of 5 for SDVO.
*/
-# define DPLL_MD_UDI_MULTIPLIER_MASK 0x00003f00
-# define DPLL_MD_UDI_MULTIPLIER_SHIFT 8
+#define DPLL_MD_UDI_MULTIPLIER_MASK 0x00003f00
+#define DPLL_MD_UDI_MULTIPLIER_SHIFT 8
/*
* SDVO/UDI pixel multiplier for VGA, same as DPLL_MD_UDI_MULTIPLIER_MASK.
* This best be set to the default value (3) or the CRT won't work. No,
* I don't entirely understand what this does...
*/
-# define DPLL_MD_VGA_UDI_MULTIPLIER_MASK 0x0000003f
-# define DPLL_MD_VGA_UDI_MULTIPLIER_SHIFT 0
+#define DPLL_MD_VGA_UDI_MULTIPLIER_MASK 0x0000003f
+#define DPLL_MD_VGA_UDI_MULTIPLIER_SHIFT 0

#define DPLL_TEST 0x606c
-# define DPLLB_TEST_SDVO_DIV_1 (0 << 22)
-# define DPLLB_TEST_SDVO_DIV_2 (1 << 22)
-# define DPLLB_TEST_SDVO_DIV_4 (2 << 22)
-# define DPLLB_TEST_SDVO_DIV_MASK (3 << 22)
-# define DPLLB_TEST_N_BYPASS (1 << 19)
-# define DPLLB_TEST_M_BYPASS (1 << 18)
-# define DPLLB_INPUT_BUFFER_ENABLE (1 << 16)
-# define DPLLA_TEST_N_BYPASS (1 << 3)
-# define DPLLA_TEST_M_BYPASS (1 << 2)
-# define DPLLA_INPUT_BUFFER_ENABLE (1 << 0)
+#define DPLLB_TEST_SDVO_DIV_1 (0 << 22)
+#define DPLLB_TEST_SDVO_DIV_2 (1 << 22)
+#define DPLLB_TEST_SDVO_DIV_4 (2 << 22)
+#define DPLLB_TEST_SDVO_DIV_MASK (3 << 22)
+#define DPLLB_TEST_N_BYPASS (1 << 19)
+#define DPLLB_TEST_M_BYPASS (1 << 18)
+#define DPLLB_INPUT_BUFFER_ENABLE (1 << 16)
+#define DPLLA_TEST_N_BYPASS (1 << 3)
+#define DPLLA_TEST_M_BYPASS (1 << 2)
+#define DPLLA_INPUT_BUFFER_ENABLE (1 << 0)

#define ADPA 0x61100
-#define ADPA_DAC_ENABLE (1<<31)
-#define ADPA_DAC_DISABLE 0
-#define ADPA_PIPE_SELECT_MASK (1<<30)
-#define ADPA_PIPE_A_SELECT 0
-#define ADPA_PIPE_B_SELECT (1<<30)
-#define ADPA_USE_VGA_HVPOLARITY (1<<15)
-#define ADPA_SETS_HVPOLARITY 0
-#define ADPA_VSYNC_CNTL_DISABLE (1<<11)
-#define ADPA_VSYNC_CNTL_ENABLE 0
-#define ADPA_HSYNC_CNTL_DISABLE (1<<10)
-#define ADPA_HSYNC_CNTL_ENABLE 0
-#define ADPA_VSYNC_ACTIVE_HIGH (1<<4)
-#define ADPA_VSYNC_ACTIVE_LOW 0
-#define ADPA_HSYNC_ACTIVE_HIGH (1<<3)
-#define ADPA_HSYNC_ACTIVE_LOW 0
-
-#define FPA0 0x06040
-#define FPA1 0x06044
-#define FPB0 0x06048
-#define FPB1 0x0604c
-# define FP_N_DIV_MASK 0x003f0000
-# define FP_N_DIV_SHIFT 16
-# define FP_M1_DIV_MASK 0x00003f00
-# define FP_M1_DIV_SHIFT 8
-# define FP_M2_DIV_MASK 0x0000003f
-# define FP_M2_DIV_SHIFT 0
-
+#define ADPA_DAC_ENABLE (1 << 31)
+#define ADPA_DAC_DISABLE 0
+#define ADPA_PIPE_SELECT_MASK (1 << 30)
+#define ADPA_PIPE_A_SELECT 0
+#define ADPA_PIPE_B_SELECT (1 << 30)
+#define ADPA_USE_VGA_HVPOLARITY (1 << 15)
+#define ADPA_SETS_HVPOLARITY 0
+#define ADPA_VSYNC_CNTL_DISABLE (1 << 11)
+#define ADPA_VSYNC_CNTL_ENABLE 0
+#define ADPA_HSYNC_CNTL_DISABLE (1 << 10)
+#define ADPA_HSYNC_CNTL_ENABLE 0
+#define ADPA_VSYNC_ACTIVE_HIGH (1 << 4)
+#define ADPA_VSYNC_ACTIVE_LOW 0
+#define ADPA_HSYNC_ACTIVE_HIGH (1 << 3)
+#define ADPA_HSYNC_ACTIVE_LOW 0
+
+#define FPA0 0x06040
+#define FPA1 0x06044
+#define FPB0 0x06048
+#define FPB1 0x0604c
+#define FP_N_DIV_MASK 0x003f0000
+#define FP_N_DIV_SHIFT 16
+#define FP_M1_DIV_MASK 0x00003f00
+#define FP_M1_DIV_SHIFT 8
+#define FP_M2_DIV_MASK 0x0000003f
+#define FP_M2_DIV_SHIFT 0

#define PORT_HOTPLUG_EN 0x61110
-# define SDVOB_HOTPLUG_INT_EN (1 << 26)
-# define SDVOC_HOTPLUG_INT_EN (1 << 25)
-# define TV_HOTPLUG_INT_EN (1 << 18)
-# define CRT_HOTPLUG_INT_EN (1 << 9)
-# define CRT_HOTPLUG_FORCE_DETECT (1 << 3)
+#define SDVOB_HOTPLUG_INT_EN (1 << 26)
+#define SDVOC_HOTPLUG_INT_EN (1 << 25)
+#define TV_HOTPLUG_INT_EN (1 << 18)
+#define CRT_HOTPLUG_INT_EN (1 << 9)
+#define CRT_HOTPLUG_FORCE_DETECT (1 << 3)

#define PORT_HOTPLUG_STAT 0x61114
-# define CRT_HOTPLUG_INT_STATUS (1 << 11)
-# define TV_HOTPLUG_INT_STATUS (1 << 10)
-# define CRT_HOTPLUG_MONITOR_MASK (3 << 8)
-# define CRT_HOTPLUG_MONITOR_COLOR (3 << 8)
-# define CRT_HOTPLUG_MONITOR_MONO (2 << 8)
-# define CRT_HOTPLUG_MONITOR_NONE (0 << 8)
-# define SDVOC_HOTPLUG_INT_STATUS (1 << 7)
-# define SDVOB_HOTPLUG_INT_STATUS (1 << 6)
+#define CRT_HOTPLUG_INT_STATUS (1 << 11)
+#define TV_HOTPLUG_INT_STATUS (1 << 10)
+#define CRT_HOTPLUG_MONITOR_MASK (3 << 8)
+#define CRT_HOTPLUG_MONITOR_COLOR (3 << 8)
+#define CRT_HOTPLUG_MONITOR_MONO (2 << 8)
+#define CRT_HOTPLUG_MONITOR_NONE (0 << 8)
+#define SDVOC_HOTPLUG_INT_STATUS (1 << 7)
+#define SDVOB_HOTPLUG_INT_STATUS (1 << 6)

#define SDVOB 0x61140
#define SDVOC 0x61160
-#define SDVO_ENABLE (1 << 31)
-#define SDVO_PIPE_B_SELECT (1 << 30)
-#define SDVO_STALL_SELECT (1 << 29)
-#define SDVO_INTERRUPT_ENABLE (1 << 26)
+#define SDVO_ENABLE (1 << 31)
+#define SDVO_PIPE_B_SELECT (1 << 30)
+#define SDVO_STALL_SELECT (1 << 29)
+#define SDVO_INTERRUPT_ENABLE (1 << 26)
+
/**
* 915G/GM SDVO pixel multiplier.
*
@@ -297,18 +296,18 @@
*
* DPLL_MD_UDI_MULTIPLIER_MASK
*/
-#define SDVO_PORT_MULTIPLY_MASK (7 << 23)
-#define SDVO_PORT_MULTIPLY_SHIFT 23
-#define SDVO_PHASE_SELECT_MASK (15 << 19)
-#define SDVO_PHASE_SELECT_DEFAULT (6 << 19)
-#define SDVO_CLOCK_OUTPUT_INVERT (1 << 18)
-#define SDVOC_GANG_MODE (1 << 16)
-#define SDVO_BORDER_ENABLE (1 << 7)
-#define SDVOB_PCIE_CONCURRENCY (1 << 3)
-#define SDVO_DETECTED (1 << 2)
+#define SDVO_PORT_MULTIPLY_MASK (7 << 23)
+#define SDVO_PORT_MULTIPLY_SHIFT 23
+#define SDVO_PHASE_SELECT_MASK (15 << 19)
+#define SDVO_PHASE_SELECT_DEFAULT (6 << 19)
+#define SDVO_CLOCK_OUTPUT_INVERT (1 << 18)
+#define SDVOC_GANG_MODE (1 << 16)
+#define SDVO_BORDER_ENABLE (1 << 7)
+#define SDVOB_PCIE_CONCURRENCY (1 << 3)
+#define SDVO_DETECTED (1 << 2)
/* Bits to be preserved when writing */
#define SDVOB_PRESERVE_MASK ((1 << 17) | (1 << 16) | (1 << 14))
-#define SDVOC_PRESERVE_MASK (1 << 17)
+#define SDVOC_PRESERVE_MASK (1 << 17)

/*
* This register controls the LVDS output enable, pipe selection, and data
@@ -321,116 +320,116 @@
* Enables the LVDS port. This bit must be set before DPLLs are enabled, as
* the DPLL semantics change when the LVDS is assigned to that pipe.
*/
-# define LVDS_PORT_EN (1 << 31)
+#define LVDS_PORT_EN (1 << 31)
/* Selects pipe B for LVDS data. Must be set on pre-965. */
-# define LVDS_PIPEB_SELECT (1 << 30)
+#define LVDS_PIPEB_SELECT (1 << 30)

/* Turns on border drawing to allow centered display. */
-# define LVDS_BORDER_EN (1 << 15)
+#define LVDS_BORDER_EN (1 << 15)

/*
* Enables the A0-A2 data pairs and CLKA, containing 18 bits of color data per
* pixel.
*/
-# define LVDS_A0A2_CLKA_POWER_MASK (3 << 8)
-# define LVDS_A0A2_CLKA_POWER_DOWN (0 << 8)
-# define LVDS_A0A2_CLKA_POWER_UP (3 << 8)
+#define LVDS_A0A2_CLKA_POWER_MASK (3 << 8)
+#define LVDS_A0A2_CLKA_POWER_DOWN (0 << 8)
+#define LVDS_A0A2_CLKA_POWER_UP (3 << 8)
/*
* Controls the A3 data pair, which contains the additional LSBs for 24 bit
* mode. Only enabled if LVDS_A0A2_CLKA_POWER_UP also indicates it should be
* on.
*/
-# define LVDS_A3_POWER_MASK (3 << 6)
-# define LVDS_A3_POWER_DOWN (0 << 6)
-# define LVDS_A3_POWER_UP (3 << 6)
+#define LVDS_A3_POWER_MASK (3 << 6)
+#define LVDS_A3_POWER_DOWN (0 << 6)
+#define LVDS_A3_POWER_UP (3 << 6)
/*
* Controls the CLKB pair. This should only be set when LVDS_B0B3_POWER_UP
* is set.
*/
-# define LVDS_CLKB_POWER_MASK (3 << 4)
-# define LVDS_CLKB_POWER_DOWN (0 << 4)
-# define LVDS_CLKB_POWER_UP (3 << 4)
+#define LVDS_CLKB_POWER_MASK (3 << 4)
+#define LVDS_CLKB_POWER_DOWN (0 << 4)
+#define LVDS_CLKB_POWER_UP (3 << 4)
/*
* Controls the B0-B3 data pairs. This must be set to match the DPLL p2
* setting for whether we are in dual-channel mode. The B3 pair will
* additionally only be powered up when LVDS_A3_POWER_UP is set.
*/
-# define LVDS_B0B3_POWER_MASK (3 << 2)
-# define LVDS_B0B3_POWER_DOWN (0 << 2)
-# define LVDS_B0B3_POWER_UP (3 << 2)
-
-#define PIPEACONF 0x70008
-#define PIPEACONF_ENABLE (1<<31)
-#define PIPEACONF_DISABLE 0
-#define PIPEACONF_DOUBLE_WIDE (1<<30)
-#define PIPECONF_ACTIVE (1<<30)
-#define I965_PIPECONF_ACTIVE (1<<30)
-#define PIPECONF_DSIPLL_LOCK (1<<29)
-#define PIPEACONF_SINGLE_WIDE 0
-#define PIPEACONF_PIPE_UNLOCKED 0
-#define PIPEACONF_DSR (1<<26)
-#define PIPEACONF_PIPE_LOCKED (1<<25)
-#define PIPEACONF_PALETTE 0
-#define PIPECONF_FORCE_BORDER (1<<25)
-#define PIPEACONF_GAMMA (1<<24)
-#define PIPECONF_PROGRESSIVE (0 << 21)
+#define LVDS_B0B3_POWER_MASK (3 << 2)
+#define LVDS_B0B3_POWER_DOWN (0 << 2)
+#define LVDS_B0B3_POWER_UP (3 << 2)
+
+#define PIPEACONF 0x70008
+#define PIPEACONF_ENABLE (1 << 31)
+#define PIPEACONF_DISABLE 0
+#define PIPEACONF_DOUBLE_WIDE (1 << 30)
+#define PIPECONF_ACTIVE (1 << 30)
+#define I965_PIPECONF_ACTIVE (1 << 30)
+#define PIPECONF_DSIPLL_LOCK (1 << 29)
+#define PIPEACONF_SINGLE_WIDE 0
+#define PIPEACONF_PIPE_UNLOCKED 0
+#define PIPEACONF_DSR (1 << 26)
+#define PIPEACONF_PIPE_LOCKED (1 << 25)
+#define PIPEACONF_PALETTE 0
+#define PIPECONF_FORCE_BORDER (1 << 25)
+#define PIPEACONF_GAMMA (1 << 24)
+#define PIPECONF_PROGRESSIVE (0 << 21)
#define PIPECONF_INTERLACE_W_FIELD_INDICATION (6 << 21)
#define PIPECONF_INTERLACE_FIELD_0_ONLY (7 << 21)
-#define PIPECONF_PLANE_OFF (1<<19)
-#define PIPECONF_CURSOR_OFF (1<<18)
+#define PIPECONF_PLANE_OFF (1 << 19)
+#define PIPECONF_CURSOR_OFF (1 << 18)

+#define PIPEBCONF 0x71008
+#define PIPEBCONF_ENABLE (1 << 31)
+#define PIPEBCONF_DISABLE 0
+#define PIPEBCONF_DOUBLE_WIDE (1 << 30)
+#define PIPEBCONF_DISABLE 0
+#define PIPEBCONF_GAMMA (1 << 24)
+#define PIPEBCONF_PALETTE 0

-#define PIPEBCONF 0x71008
-#define PIPEBCONF_ENABLE (1<<31)
-#define PIPEBCONF_DISABLE 0
-#define PIPEBCONF_DOUBLE_WIDE (1<<30)
-#define PIPEBCONF_DISABLE 0
-#define PIPEBCONF_GAMMA (1<<24)
-#define PIPEBCONF_PALETTE 0
-
-#define PIPECCONF 0x72008
+#define PIPECCONF 0x72008

#define PIPEBGCMAXRED 0x71010
#define PIPEBGCMAXGREEN 0x71014
#define PIPEBGCMAXBLUE 0x71018

-#define PIPEASTAT 0x70024
+#define PIPEASTAT 0x70024
#define PIPEBSTAT 0x71024
#define PIPECSTAT 0x72024
-#define PIPE_VBLANK_INTERRUPT_STATUS (1UL<<1)
-#define PIPE_START_VBLANK_INTERRUPT_STATUS (1UL<<2)
-#define PIPE_VBLANK_CLEAR (1 << 1)
-#define PIPE_VBLANK_STATUS (1 << 1)
-#define PIPE_TE_STATUS (1UL<<6)
-#define PIPE_DPST_EVENT_STATUS (1UL<<7)
-#define PIPE_VSYNC_CLEAR (1UL<<9)
-#define PIPE_VSYNC_STATUS (1UL<<9)
-#define PIPE_HDMI_AUDIO_UNDERRUN_STATUS (1UL<<10)
-#define PIPE_HDMI_AUDIO_BUFFER_DONE_STATUS (1UL<<11)
-#define PIPE_VBLANK_INTERRUPT_ENABLE (1UL<<17)
-#define PIPE_START_VBLANK_INTERRUPT_ENABLE (1UL<<18)
-#define PIPE_TE_ENABLE (1UL<<22)
-#define PIPE_DPST_EVENT_ENABLE (1UL<<23)
-#define PIPE_VSYNC_ENABL (1UL<<25)
-#define PIPE_HDMI_AUDIO_UNDERRUN (1UL<<26)
-#define PIPE_HDMI_AUDIO_BUFFER_DONE (1UL<<27)
-#define PIPE_HDMI_AUDIO_INT_MASK (PIPE_HDMI_AUDIO_UNDERRUN | PIPE_HDMI_AUDIO_BUFFER_DONE)
+#define PIPE_VBLANK_INTERRUPT_STATUS (1UL << 1)
+#define PIPE_START_VBLANK_INTERRUPT_STATUS (1UL << 2)
+#define PIPE_VBLANK_CLEAR (1 << 1)
+#define PIPE_VBLANK_STATUS (1 << 1)
+#define PIPE_TE_STATUS (1UL << 6)
+#define PIPE_DPST_EVENT_STATUS (1UL << 7)
+#define PIPE_VSYNC_CLEAR (1UL << 9)
+#define PIPE_VSYNC_STATUS (1UL << 9)
+#define PIPE_HDMI_AUDIO_UNDERRUN_STATUS (1UL << 10)
+#define PIPE_HDMI_AUDIO_BUFFER_DONE_STATUS (1UL << 11)
+#define PIPE_VBLANK_INTERRUPT_ENABLE (1UL << 17)
+#define PIPE_START_VBLANK_INTERRUPT_ENABLE (1UL << 18)
+#define PIPE_TE_ENABLE (1UL << 22)
+#define PIPE_DPST_EVENT_ENABLE (1UL << 23)
+#define PIPE_VSYNC_ENABL (1UL << 25)
+#define PIPE_HDMI_AUDIO_UNDERRUN (1UL << 26)
+#define PIPE_HDMI_AUDIO_BUFFER_DONE (1UL << 27)
+#define PIPE_HDMI_AUDIO_INT_MASK (PIPE_HDMI_AUDIO_UNDERRUN | \
+ PIPE_HDMI_AUDIO_BUFFER_DONE)
#define PIPE_EVENT_MASK ((1 << 29)|(1 << 28)|(1 << 27)|(1 << 26)|(1 << 24)|(1 << 23)|(1 << 22)|(1 << 21)|(1 << 20)|(1 << 16))
#define PIPE_VBLANK_MASK ((1 << 25)|(1 << 24)|(1 << 18)|(1 << 17))
#define HISTOGRAM_INT_CONTROL 0x61268
#define HISTOGRAM_BIN_DATA 0X61264
#define HISTOGRAM_LOGIC_CONTROL 0x61260
#define PWM_CONTROL_LOGIC 0x61250
-#define PIPE_HOTPLUG_INTERRUPT_STATUS (1UL<<10)
-#define HISTOGRAM_INTERRUPT_ENABLE (1UL<<31)
-#define HISTOGRAM_LOGIC_ENABLE (1UL<<31)
-#define PWM_LOGIC_ENABLE (1UL<<31)
-#define PWM_PHASEIN_ENABLE (1UL<<25)
-#define PWM_PHASEIN_INT_ENABLE (1UL<<24)
-#define PWM_PHASEIN_VB_COUNT 0x00001f00
-#define PWM_PHASEIN_INC 0x0000001f
-#define HISTOGRAM_INT_CTRL_CLEAR (1UL<<30)
-#define DPST_YUV_LUMA_MODE 0
+#define PIPE_HOTPLUG_INTERRUPT_STATUS (1UL << 10)
+#define HISTOGRAM_INTERRUPT_ENABLE (1UL << 31)
+#define HISTOGRAM_LOGIC_ENABLE (1UL << 31)
+#define PWM_LOGIC_ENABLE (1UL << 31)
+#define PWM_PHASEIN_ENABLE (1UL << 25)
+#define PWM_PHASEIN_INT_ENABLE (1UL << 24)
+#define PWM_PHASEIN_VB_COUNT 0x00001f00
+#define PWM_PHASEIN_INC 0x0000001f
+#define HISTOGRAM_INT_CTRL_CLEAR (1UL << 30)
+#define DPST_YUV_LUMA_MODE 0

struct dpst_ie_histogram_control {
union {
@@ -470,12 +469,12 @@ struct dpst_guardband {
#define PIPEBFRAMEPIXEL 0x71044
#define PIPECFRAMEHIGH 0x72040
#define PIPECFRAMEPIXEL 0x72044
-#define PIPE_FRAME_HIGH_MASK 0x0000ffff
-#define PIPE_FRAME_HIGH_SHIFT 0
-#define PIPE_FRAME_LOW_MASK 0xff000000
-#define PIPE_FRAME_LOW_SHIFT 24
-#define PIPE_PIXEL_MASK 0x00ffffff
-#define PIPE_PIXEL_SHIFT 0
+#define PIPE_FRAME_HIGH_MASK 0x0000ffff
+#define PIPE_FRAME_HIGH_SHIFT 0
+#define PIPE_FRAME_LOW_MASK 0xff000000
+#define PIPE_FRAME_LOW_SHIFT 24
+#define PIPE_PIXEL_MASK 0x00ffffff
+#define PIPE_PIXEL_SHIFT 0

#define DSPARB 0x70030
#define DSPFW1 0x70034
@@ -488,30 +487,30 @@ struct dpst_guardband {
#define DSPACNTR 0x70180
#define DSPBCNTR 0x71180
#define DSPCCNTR 0x72180
-#define DISPLAY_PLANE_ENABLE (1<<31)
+#define DISPLAY_PLANE_ENABLE (1 << 31)
#define DISPLAY_PLANE_DISABLE 0
-#define DISPPLANE_GAMMA_ENABLE (1<<30)
+#define DISPPLANE_GAMMA_ENABLE (1 << 30)
#define DISPPLANE_GAMMA_DISABLE 0
-#define DISPPLANE_PIXFORMAT_MASK (0xf<<26)
-#define DISPPLANE_8BPP (0x2<<26)
-#define DISPPLANE_15_16BPP (0x4<<26)
-#define DISPPLANE_16BPP (0x5<<26)
-#define DISPPLANE_32BPP_NO_ALPHA (0x6<<26)
-#define DISPPLANE_32BPP (0x7<<26)
-#define DISPPLANE_STEREO_ENABLE (1<<25)
+#define DISPPLANE_PIXFORMAT_MASK (0xf << 26)
+#define DISPPLANE_8BPP (0x2 << 26)
+#define DISPPLANE_15_16BPP (0x4 << 26)
+#define DISPPLANE_16BPP (0x5 << 26)
+#define DISPPLANE_32BPP_NO_ALPHA (0x6 << 26)
+#define DISPPLANE_32BPP (0x7 << 26)
+#define DISPPLANE_STEREO_ENABLE (1 << 25)
#define DISPPLANE_STEREO_DISABLE 0
-#define DISPPLANE_SEL_PIPE_MASK (1<<24)
+#define DISPPLANE_SEL_PIPE_MASK (1 << 24)
#define DISPPLANE_SEL_PIPE_POS 24
#define DISPPLANE_SEL_PIPE_A 0
-#define DISPPLANE_SEL_PIPE_B (1<<24)
-#define DISPPLANE_SRC_KEY_ENABLE (1<<22)
+#define DISPPLANE_SEL_PIPE_B (1 << 24)
+#define DISPPLANE_SRC_KEY_ENABLE (1 << 22)
#define DISPPLANE_SRC_KEY_DISABLE 0
-#define DISPPLANE_LINE_DOUBLE (1<<20)
+#define DISPPLANE_LINE_DOUBLE (1 << 20)
#define DISPPLANE_NO_LINE_DOUBLE 0
#define DISPPLANE_STEREO_POLARITY_FIRST 0
-#define DISPPLANE_STEREO_POLARITY_SECOND (1<<18)
+#define DISPPLANE_STEREO_POLARITY_SECOND (1 << 18)
/* plane B only */
-#define DISPPLANE_ALPHA_TRANS_ENABLE (1<<15)
+#define DISPPLANE_ALPHA_TRANS_ENABLE (1 << 15)
#define DISPPLANE_ALPHA_TRANS_DISABLE 0
#define DISPPLANE_SPRITE_ABOVE_DISPLAYA 0
#define DISPPLANE_SPRITE_ABOVE_OVERLAY (1)
@@ -548,25 +547,25 @@ struct dpst_guardband {

#define DSPCSURF 0x7219C
#define DSPCTILEOFF 0x721A4
-#define DSPCKEYMAXVAL 0x721A0
-#define DSPCKEYMINVAL 0x72194
-#define DSPCKEYMSK 0x72198
+#define DSPCKEYMAXVAL 0x721A0
+#define DSPCKEYMINVAL 0x72194
+#define DSPCKEYMSK 0x72198

#define VGACNTRL 0x71400
-# define VGA_DISP_DISABLE (1 << 31)
-# define VGA_2X_MODE (1 << 30)
-# define VGA_PIPE_B_SELECT (1 << 29)
+#define VGA_DISP_DISABLE (1 << 31)
+#define VGA_2X_MODE (1 << 30)
+#define VGA_PIPE_B_SELECT (1 << 29)

/*
* Overlay registers
*/
#define OV_C_OFFSET 0x08000
#define OV_OVADD 0x30000
-#define OV_DOVASTA 0x30008
-# define OV_PIPE_SELECT ((1 << 6)|(1 << 7))
-# define OV_PIPE_SELECT_POS 6
-# define OV_PIPE_A 0
-# define OV_PIPE_C 1
+#define OV_DOVASTA 0x30008
+# define OV_PIPE_SELECT ((1 << 6)|(1 << 7))
+# define OV_PIPE_SELECT_POS 6
+# define OV_PIPE_A 0
+# define OV_PIPE_C 1
#define OV_OGAMC5 0x30010
#define OV_OGAMC4 0x30014
#define OV_OGAMC3 0x30018
@@ -574,7 +573,7 @@ struct dpst_guardband {
#define OV_OGAMC1 0x30020
#define OV_OGAMC0 0x30024
#define OVC_OVADD 0x38000
-#define OVC_DOVCSTA 0x38008
+#define OVC_DOVCSTA 0x38008
#define OVC_OGAMC5 0x38010
#define OVC_OGAMC4 0x38014
#define OVC_OGAMC3 0x38018
@@ -627,16 +626,16 @@ struct dpst_guardband {

/* Cursor A & B regs */
#define CURACNTR 0x70080
-#define CURSOR_MODE_DISABLE 0x00
-#define CURSOR_MODE_64_32B_AX 0x07
-#define CURSOR_MODE_64_ARGB_AX ((1 << 5) | CURSOR_MODE_64_32B_AX)
-#define MCURSOR_GAMMA_ENABLE (1 << 26)
+#define CURSOR_MODE_DISABLE 0x00
+#define CURSOR_MODE_64_32B_AX 0x07
+#define CURSOR_MODE_64_ARGB_AX ((1 << 5) | CURSOR_MODE_64_32B_AX)
+#define MCURSOR_GAMMA_ENABLE (1 << 26)
#define CURABASE 0x70084
#define CURAPOS 0x70088
-#define CURSOR_POS_MASK 0x007FF
-#define CURSOR_POS_SIGN 0x8000
-#define CURSOR_X_SHIFT 0
-#define CURSOR_Y_SHIFT 16
+#define CURSOR_POS_MASK 0x007FF
+#define CURSOR_POS_SIGN 0x8000
+#define CURSOR_X_SHIFT 0
+#define CURSOR_Y_SHIFT 16
#define CURBCNTR 0x700c0
#define CURBBASE 0x700c4
#define CURBPOS 0x700c8
@@ -647,22 +646,22 @@ struct dpst_guardband {
/*
* Interrupt Registers
*/
-#define IER 0x020a0
-#define IIR 0x020a4
-#define IMR 0x020a8
-#define ISR 0x020ac
+#define IER 0x020a0
+#define IIR 0x020a4
+#define IMR 0x020a8
+#define ISR 0x020ac

/*
* MOORESTOWN delta registers
*/
#define MRST_DPLL_A 0x0f014
#define MDFLD_DPLL_B 0x0f018
-#define MDFLD_INPUT_REF_SEL (1 << 14)
-#define MDFLD_VCO_SEL (1 << 16)
-#define DPLLA_MODE_LVDS (2 << 26) /* mrst */
-#define MDFLD_PLL_LATCHEN (1 << 28)
-#define MDFLD_PWR_GATE_EN (1 << 30)
-#define MDFLD_P1_MASK (0x1FF << 17)
+#define MDFLD_INPUT_REF_SEL (1 << 14)
+#define MDFLD_VCO_SEL (1 << 16)
+#define DPLLA_MODE_LVDS (2 << 26) /* mrst */
+#define MDFLD_PLL_LATCHEN (1 << 28)
+#define MDFLD_PWR_GATE_EN (1 << 30)
+#define MDFLD_P1_MASK (0x1FF << 17)
#define MRST_FPA0 0x0f040
#define MRST_FPA1 0x0f044
#define MDFLD_DPLL_DIV0 0x0f048
@@ -672,45 +671,45 @@ struct dpst_guardband {
/*
* MEDFIELD HDMI registers
*/
-#define HDMIPHYMISCCTL 0x61134
-# define HDMI_PHY_POWER_DOWN 0x7f
-#define HDMIB_CONTROL 0x61140
-# define HDMIB_PORT_EN (1 << 31)
-# define HDMIB_PIPE_B_SELECT (1 << 30)
-# define HDMIB_NULL_PACKET (1 << 9)
-#define HDMIB_HDCP_PORT (1 << 5)
+#define HDMIPHYMISCCTL 0x61134
+#define HDMI_PHY_POWER_DOWN 0x7f
+#define HDMIB_CONTROL 0x61140
+#define HDMIB_PORT_EN (1 << 31)
+#define HDMIB_PIPE_B_SELECT (1 << 30)
+#define HDMIB_NULL_PACKET (1 << 9)
+#define HDMIB_HDCP_PORT (1 << 5)

/* #define LVDS 0x61180 */
-# define MRST_PANEL_8TO6_DITHER_ENABLE (1 << 25)
-# define MRST_PANEL_24_DOT_1_FORMAT (1 << 24)
-# define LVDS_A3_POWER_UP_0_OUTPUT (1 << 6)
+#define MRST_PANEL_8TO6_DITHER_ENABLE (1 << 25)
+#define MRST_PANEL_24_DOT_1_FORMAT (1 << 24)
+#define LVDS_A3_POWER_UP_0_OUTPUT (1 << 6)

#define MIPI 0x61190
#define MIPI_C 0x62190
-# define MIPI_PORT_EN (1 << 31)
+#define MIPI_PORT_EN (1 << 31)
/* Turns on border drawing to allow centered display. */
-# define SEL_FLOPPED_HSTX (1 << 23)
-# define PASS_FROM_SPHY_TO_AFE (1 << 16)
-# define MIPI_BORDER_EN (1 << 15)
-# define MIPIA_3LANE_MIPIC_1LANE 0x1
-# define MIPIA_2LANE_MIPIC_2LANE 0x2
-# define TE_TRIGGER_DSI_PROTOCOL (1 << 2)
-# define TE_TRIGGER_GPIO_PIN (1 << 3)
-#define MIPI_TE_COUNT 0x61194
+#define SEL_FLOPPED_HSTX (1 << 23)
+#define PASS_FROM_SPHY_TO_AFE (1 << 16)
+#define MIPI_BORDER_EN (1 << 15)
+#define MIPIA_3LANE_MIPIC_1LANE 0x1
+#define MIPIA_2LANE_MIPIC_2LANE 0x2
+#define TE_TRIGGER_DSI_PROTOCOL (1 << 2)
+#define TE_TRIGGER_GPIO_PIN (1 << 3)
+#define MIPI_TE_COUNT 0x61194

/* #define PP_CONTROL 0x61204 */
-# define POWER_DOWN_ON_RESET (1 << 1)
+#define POWER_DOWN_ON_RESET (1 << 1)

/* #define PFIT_CONTROL 0x61230 */
-# define PFIT_PIPE_SELECT (3 << 29)
-# define PFIT_PIPE_SELECT_SHIFT (29)
+#define PFIT_PIPE_SELECT (3 << 29)
+#define PFIT_PIPE_SELECT_SHIFT (29)

/* #define BLC_PWM_CTL 0x61254 */
-#define MRST_BACKLIGHT_MODULATION_FREQ_SHIFT (16)
-#define MRST_BACKLIGHT_MODULATION_FREQ_MASK (0xffff << 16)
+#define MRST_BACKLIGHT_MODULATION_FREQ_SHIFT (16)
+#define MRST_BACKLIGHT_MODULATION_FREQ_MASK (0xffff << 16)

/* #define PIPEACONF 0x70008 */
-#define PIPEACONF_PIPE_STATE (1<<30)
+#define PIPEACONF_PIPE_STATE (1 << 30)
/* #define DSPACNTR 0x70180 */

#define MRST_DSPABASE 0x7019c
@@ -724,281 +723,286 @@ struct dpst_guardband {
/*
* MIPI IP registers
*/
-#define MIPIC_REG_OFFSET 0x800
-#define DEVICE_READY_REG 0xb000
-#define LP_OUTPUT_HOLD (1 << 16)
-#define EXIT_ULPS_DEV_READY 0x3
-#define LP_OUTPUT_HOLD_RELEASE 0x810000
-# define ENTERING_ULPS (2 << 1)
-# define EXITING_ULPS (1 << 1)
-# define ULPS_MASK (3 << 1)
-# define BUS_POSSESSION (1 << 3)
-#define INTR_STAT_REG 0xb004
-#define RX_SOT_ERROR (1 << 0)
-#define RX_SOT_SYNC_ERROR (1 << 1)
-#define RX_ESCAPE_MODE_ENTRY_ERROR (1 << 3)
-#define RX_LP_TX_SYNC_ERROR (1 << 4)
-#define RX_HS_RECEIVE_TIMEOUT_ERROR (1 << 5)
-#define RX_FALSE_CONTROL_ERROR (1 << 6)
-#define RX_ECC_SINGLE_BIT_ERROR (1 << 7)
-#define RX_ECC_MULTI_BIT_ERROR (1 << 8)
-#define RX_CHECKSUM_ERROR (1 << 9)
-#define RX_DSI_DATA_TYPE_NOT_RECOGNIZED (1 << 10)
-#define RX_DSI_VC_ID_INVALID (1 << 11)
-#define TX_FALSE_CONTROL_ERROR (1 << 12)
-#define TX_ECC_SINGLE_BIT_ERROR (1 << 13)
-#define TX_ECC_MULTI_BIT_ERROR (1 << 14)
-#define TX_CHECKSUM_ERROR (1 << 15)
-#define TX_DSI_DATA_TYPE_NOT_RECOGNIZED (1 << 16)
-#define TX_DSI_VC_ID_INVALID (1 << 17)
-#define HIGH_CONTENTION (1 << 18)
-#define LOW_CONTENTION (1 << 19)
-#define DPI_FIFO_UNDER_RUN (1 << 20)
-#define HS_TX_TIMEOUT (1 << 21)
-#define LP_RX_TIMEOUT (1 << 22)
-#define TURN_AROUND_ACK_TIMEOUT (1 << 23)
-#define ACK_WITH_NO_ERROR (1 << 24)
-#define HS_GENERIC_WR_FIFO_FULL (1 << 27)
-#define LP_GENERIC_WR_FIFO_FULL (1 << 28)
-#define SPL_PKT_SENT (1 << 30)
-#define INTR_EN_REG 0xb008
-#define DSI_FUNC_PRG_REG 0xb00c
-#define DPI_CHANNEL_NUMBER_POS 0x03
-#define DBI_CHANNEL_NUMBER_POS 0x05
-#define FMT_DPI_POS 0x07
-#define FMT_DBI_POS 0x0A
-#define DBI_DATA_WIDTH_POS 0x0D
+#define MIPIC_REG_OFFSET 0x800
+
+#define DEVICE_READY_REG 0xb000
+#define LP_OUTPUT_HOLD (1 << 16)
+#define EXIT_ULPS_DEV_READY 0x3
+#define LP_OUTPUT_HOLD_RELEASE 0x810000
+# define ENTERING_ULPS (2 << 1)
+# define EXITING_ULPS (1 << 1)
+# define ULPS_MASK (3 << 1)
+# define BUS_POSSESSION (1 << 3)
+#define INTR_STAT_REG 0xb004
+#define RX_SOT_ERROR (1 << 0)
+#define RX_SOT_SYNC_ERROR (1 << 1)
+#define RX_ESCAPE_MODE_ENTRY_ERROR (1 << 3)
+#define RX_LP_TX_SYNC_ERROR (1 << 4)
+#define RX_HS_RECEIVE_TIMEOUT_ERROR (1 << 5)
+#define RX_FALSE_CONTROL_ERROR (1 << 6)
+#define RX_ECC_SINGLE_BIT_ERROR (1 << 7)
+#define RX_ECC_MULTI_BIT_ERROR (1 << 8)
+#define RX_CHECKSUM_ERROR (1 << 9)
+#define RX_DSI_DATA_TYPE_NOT_RECOGNIZED (1 << 10)
+#define RX_DSI_VC_ID_INVALID (1 << 11)
+#define TX_FALSE_CONTROL_ERROR (1 << 12)
+#define TX_ECC_SINGLE_BIT_ERROR (1 << 13)
+#define TX_ECC_MULTI_BIT_ERROR (1 << 14)
+#define TX_CHECKSUM_ERROR (1 << 15)
+#define TX_DSI_DATA_TYPE_NOT_RECOGNIZED (1 << 16)
+#define TX_DSI_VC_ID_INVALID (1 << 17)
+#define HIGH_CONTENTION (1 << 18)
+#define LOW_CONTENTION (1 << 19)
+#define DPI_FIFO_UNDER_RUN (1 << 20)
+#define HS_TX_TIMEOUT (1 << 21)
+#define LP_RX_TIMEOUT (1 << 22)
+#define TURN_AROUND_ACK_TIMEOUT (1 << 23)
+#define ACK_WITH_NO_ERROR (1 << 24)
+#define HS_GENERIC_WR_FIFO_FULL (1 << 27)
+#define LP_GENERIC_WR_FIFO_FULL (1 << 28)
+#define SPL_PKT_SENT (1 << 30)
+#define INTR_EN_REG 0xb008
+#define DSI_FUNC_PRG_REG 0xb00c
+#define DPI_CHANNEL_NUMBER_POS 0x03
+#define DBI_CHANNEL_NUMBER_POS 0x05
+#define FMT_DPI_POS 0x07
+#define FMT_DBI_POS 0x0A
+#define DBI_DATA_WIDTH_POS 0x0D
+
/* DPI PIXEL FORMATS */
-#define RGB_565_FMT 0x01 /* RGB 565 FORMAT */
-#define RGB_666_FMT 0x02 /* RGB 666 FORMAT */
-#define LRGB_666_FMT 0x03 /* RGB LOOSELY PACKED
- * 666 FORMAT
- */
-#define RGB_888_FMT 0x04 /* RGB 888 FORMAT */
-#define VIRTUAL_CHANNEL_NUMBER_0 0x00 /* Virtual channel 0 */
-#define VIRTUAL_CHANNEL_NUMBER_1 0x01 /* Virtual channel 1 */
-#define VIRTUAL_CHANNEL_NUMBER_2 0x02 /* Virtual channel 2 */
-#define VIRTUAL_CHANNEL_NUMBER_3 0x03 /* Virtual channel 3 */
-#define DBI_NOT_SUPPORTED 0x00 /* command mode
- * is not supported
- */
-#define DBI_DATA_WIDTH_16BIT 0x01 /* 16 bit data */
+#define RGB_565_FMT 0x01 /* RGB 565 FORMAT */
+#define RGB_666_FMT 0x02 /* RGB 666 FORMAT */
+#define LRGB_666_FMT 0x03 /* RGB LOOSELY PACKED
+ * 666 FORMAT
+ */
+#define RGB_888_FMT 0x04 /* RGB 888 FORMAT */
+#define VIRTUAL_CHANNEL_NUMBER_0 0x00 /* Virtual channel 0 */
+#define VIRTUAL_CHANNEL_NUMBER_1 0x01 /* Virtual channel 1 */
+#define VIRTUAL_CHANNEL_NUMBER_2 0x02 /* Virtual channel 2 */
+#define VIRTUAL_CHANNEL_NUMBER_3 0x03 /* Virtual channel 3 */
+
+#define DBI_NOT_SUPPORTED 0x00 /* command mode
+ * is not supported
+ */
+#define DBI_DATA_WIDTH_16BIT 0x01 /* 16 bit data */
#define DBI_DATA_WIDTH_9BIT 0x02 /* 9 bit data */
#define DBI_DATA_WIDTH_8BIT 0x03 /* 8 bit data */
-#define DBI_DATA_WIDTH_OPT1 0x04 /* option 1 */
-#define DBI_DATA_WIDTH_OPT2 0x05 /* option 2 */
-#define HS_TX_TIMEOUT_REG 0xb010
-#define LP_RX_TIMEOUT_REG 0xb014
-#define TURN_AROUND_TIMEOUT_REG 0xb018
-#define DEVICE_RESET_REG 0xb01C
-#define DPI_RESOLUTION_REG 0xb020
-#define RES_V_POS 0x10
-#define DBI_RESOLUTION_REG 0xb024 /* Reserved for MDFLD */
-#define HORIZ_SYNC_PAD_COUNT_REG 0xb028
-#define HORIZ_BACK_PORCH_COUNT_REG 0xb02C
-#define HORIZ_FRONT_PORCH_COUNT_REG 0xb030
-#define HORIZ_ACTIVE_AREA_COUNT_REG 0xb034
-#define VERT_SYNC_PAD_COUNT_REG 0xb038
-#define VERT_BACK_PORCH_COUNT_REG 0xb03c
-#define VERT_FRONT_PORCH_COUNT_REG 0xb040
-#define HIGH_LOW_SWITCH_COUNT_REG 0xb044
-#define DPI_CONTROL_REG 0xb048
-#define DPI_SHUT_DOWN (1 << 0)
-#define DPI_TURN_ON (1 << 1)
-#define DPI_COLOR_MODE_ON (1 << 2)
-#define DPI_COLOR_MODE_OFF (1 << 3)
-#define DPI_BACK_LIGHT_ON (1 << 4)
-#define DPI_BACK_LIGHT_OFF (1 << 5)
-#define DPI_LP (1 << 6)
-#define DPI_DATA_REG 0xb04c
-#define DPI_BACK_LIGHT_ON_DATA 0x07
-#define DPI_BACK_LIGHT_OFF_DATA 0x17
-#define INIT_COUNT_REG 0xb050
-#define MAX_RET_PAK_REG 0xb054
-#define VIDEO_FMT_REG 0xb058
-#define COMPLETE_LAST_PCKT (1 << 2)
-#define EOT_DISABLE_REG 0xb05c
-#define ENABLE_CLOCK_STOPPING (1 << 1)
-#define LP_BYTECLK_REG 0xb060
-#define LP_GEN_DATA_REG 0xb064
-#define HS_GEN_DATA_REG 0xb068
-#define LP_GEN_CTRL_REG 0xb06C
-#define HS_GEN_CTRL_REG 0xb070
-#define DCS_CHANNEL_NUMBER_POS 0x06
-#define MCS_COMMANDS_POS 0x8
-#define WORD_COUNTS_POS 0x8
-#define MCS_PARAMETER_POS 0x10
-#define GEN_FIFO_STAT_REG 0xb074
-#define HS_DATA_FIFO_FULL (1 << 0)
-#define HS_DATA_FIFO_HALF_EMPTY (1 << 1)
-#define HS_DATA_FIFO_EMPTY (1 << 2)
-#define LP_DATA_FIFO_FULL (1 << 8)
-#define LP_DATA_FIFO_HALF_EMPTY (1 << 9)
-#define LP_DATA_FIFO_EMPTY (1 << 10)
-#define HS_CTRL_FIFO_FULL (1 << 16)
-#define HS_CTRL_FIFO_HALF_EMPTY (1 << 17)
-#define HS_CTRL_FIFO_EMPTY (1 << 18)
-#define LP_CTRL_FIFO_FULL (1 << 24)
-#define LP_CTRL_FIFO_HALF_EMPTY (1 << 25)
-#define LP_CTRL_FIFO_EMPTY (1 << 26)
-#define DBI_FIFO_EMPTY (1 << 27)
-#define DPI_FIFO_EMPTY (1 << 28)
-#define HS_LS_DBI_ENABLE_REG 0xb078
-#define TXCLKESC_REG 0xb07c
-#define DPHY_PARAM_REG 0xb080
-#define DBI_BW_CTRL_REG 0xb084
-#define CLK_LANE_SWT_REG 0xb088
+#define DBI_DATA_WIDTH_OPT1 0x04 /* option 1 */
+#define DBI_DATA_WIDTH_OPT2 0x05 /* option 2 */
+
+#define HS_TX_TIMEOUT_REG 0xb010
+#define LP_RX_TIMEOUT_REG 0xb014
+#define TURN_AROUND_TIMEOUT_REG 0xb018
+#define DEVICE_RESET_REG 0xb01C
+#define DPI_RESOLUTION_REG 0xb020
+#define RES_V_POS 0x10
+#define DBI_RESOLUTION_REG 0xb024 /* Reserved for MDFLD */
+#define HORIZ_SYNC_PAD_COUNT_REG 0xb028
+#define HORIZ_BACK_PORCH_COUNT_REG 0xb02C
+#define HORIZ_FRONT_PORCH_COUNT_REG 0xb030
+#define HORIZ_ACTIVE_AREA_COUNT_REG 0xb034
+#define VERT_SYNC_PAD_COUNT_REG 0xb038
+#define VERT_BACK_PORCH_COUNT_REG 0xb03c
+#define VERT_FRONT_PORCH_COUNT_REG 0xb040
+#define HIGH_LOW_SWITCH_COUNT_REG 0xb044
+#define DPI_CONTROL_REG 0xb048
+#define DPI_SHUT_DOWN (1 << 0)
+#define DPI_TURN_ON (1 << 1)
+#define DPI_COLOR_MODE_ON (1 << 2)
+#define DPI_COLOR_MODE_OFF (1 << 3)
+#define DPI_BACK_LIGHT_ON (1 << 4)
+#define DPI_BACK_LIGHT_OFF (1 << 5)
+#define DPI_LP (1 << 6)
+#define DPI_DATA_REG 0xb04c
+#define DPI_BACK_LIGHT_ON_DATA 0x07
+#define DPI_BACK_LIGHT_OFF_DATA 0x17
+#define INIT_COUNT_REG 0xb050
+#define MAX_RET_PAK_REG 0xb054
+#define VIDEO_FMT_REG 0xb058
+#define COMPLETE_LAST_PCKT (1 << 2)
+#define EOT_DISABLE_REG 0xb05c
+#define ENABLE_CLOCK_STOPPING (1 << 1)
+#define LP_BYTECLK_REG 0xb060
+#define LP_GEN_DATA_REG 0xb064
+#define HS_GEN_DATA_REG 0xb068
+#define LP_GEN_CTRL_REG 0xb06C
+#define HS_GEN_CTRL_REG 0xb070
+#define DCS_CHANNEL_NUMBER_POS 0x6
+#define MCS_COMMANDS_POS 0x8
+#define WORD_COUNTS_POS 0x8
+#define MCS_PARAMETER_POS 0x10
+#define GEN_FIFO_STAT_REG 0xb074
+#define HS_DATA_FIFO_FULL (1 << 0)
+#define HS_DATA_FIFO_HALF_EMPTY (1 << 1)
+#define HS_DATA_FIFO_EMPTY (1 << 2)
+#define LP_DATA_FIFO_FULL (1 << 8)
+#define LP_DATA_FIFO_HALF_EMPTY (1 << 9)
+#define LP_DATA_FIFO_EMPTY (1 << 10)
+#define HS_CTRL_FIFO_FULL (1 << 16)
+#define HS_CTRL_FIFO_HALF_EMPTY (1 << 17)
+#define HS_CTRL_FIFO_EMPTY (1 << 18)
+#define LP_CTRL_FIFO_FULL (1 << 24)
+#define LP_CTRL_FIFO_HALF_EMPTY (1 << 25)
+#define LP_CTRL_FIFO_EMPTY (1 << 26)
+#define DBI_FIFO_EMPTY (1 << 27)
+#define DPI_FIFO_EMPTY (1 << 28)
+#define HS_LS_DBI_ENABLE_REG 0xb078
+#define TXCLKESC_REG 0xb07c
+#define DPHY_PARAM_REG 0xb080
+#define DBI_BW_CTRL_REG 0xb084
+#define CLK_LANE_SWT_REG 0xb088

/*
* MIPI Adapter registers
*/
-#define MIPI_CONTROL_REG 0xb104
-#define MIPI_2X_CLOCK_BITS ((1 << 0) | (1 << 1))
-#define MIPI_DATA_ADDRESS_REG 0xb108
-#define MIPI_DATA_LENGTH_REG 0xb10C
-#define MIPI_COMMAND_ADDRESS_REG 0xb110
-#define MIPI_COMMAND_LENGTH_REG 0xb114
-#define MIPI_READ_DATA_RETURN_REG0 0xb118
-#define MIPI_READ_DATA_RETURN_REG1 0xb11C
-#define MIPI_READ_DATA_RETURN_REG2 0xb120
-#define MIPI_READ_DATA_RETURN_REG3 0xb124
-#define MIPI_READ_DATA_RETURN_REG4 0xb128
-#define MIPI_READ_DATA_RETURN_REG5 0xb12C
-#define MIPI_READ_DATA_RETURN_REG6 0xb130
-#define MIPI_READ_DATA_RETURN_REG7 0xb134
-#define MIPI_READ_DATA_VALID_REG 0xb138
+#define MIPI_CONTROL_REG 0xb104
+#define MIPI_2X_CLOCK_BITS ((1 << 0) | (1 << 1))
+#define MIPI_DATA_ADDRESS_REG 0xb108
+#define MIPI_DATA_LENGTH_REG 0xb10C
+#define MIPI_COMMAND_ADDRESS_REG 0xb110
+#define MIPI_COMMAND_LENGTH_REG 0xb114
+#define MIPI_READ_DATA_RETURN_REG0 0xb118
+#define MIPI_READ_DATA_RETURN_REG1 0xb11C
+#define MIPI_READ_DATA_RETURN_REG2 0xb120
+#define MIPI_READ_DATA_RETURN_REG3 0xb124
+#define MIPI_READ_DATA_RETURN_REG4 0xb128
+#define MIPI_READ_DATA_RETURN_REG5 0xb12C
+#define MIPI_READ_DATA_RETURN_REG6 0xb130
+#define MIPI_READ_DATA_RETURN_REG7 0xb134
+#define MIPI_READ_DATA_VALID_REG 0xb138
+
/* DBI COMMANDS */
-#define soft_reset 0x01
+#define soft_reset 0x01
/*
* The display module performs a software reset.
* Registers are written with their SW Reset default values.
*/
-#define get_power_mode 0x0a
+#define get_power_mode 0x0a
/*
* The display module returns the current power mode
*/
-#define get_address_mode 0x0b
+#define get_address_mode 0x0b
/*
* The display module returns the current status.
*/
-#define get_pixel_format 0x0c
+#define get_pixel_format 0x0c
/*
* This command gets the pixel format for the RGB image data
* used by the interface.
*/
-#define get_display_mode 0x0d
+#define get_display_mode 0x0d
/*
* The display module returns the Display Image Mode status.
*/
-#define get_signal_mode 0x0e
+#define get_signal_mode 0x0e
/*
* The display module returns the Display Signal Mode.
*/
-#define get_diagnostic_result 0x0f
+#define get_diagnostic_result 0x0f
/*
* The display module returns the self-diagnostic results following
* a Sleep Out command.
*/
-#define enter_sleep_mode 0x10
+#define enter_sleep_mode 0x10
/*
* This command causes the display module to enter the Sleep mode.
* In this mode, all unnecessary blocks inside the display module are
* disabled except interface communication. This is the lowest power
* mode the display module supports.
*/
-#define exit_sleep_mode 0x11
+#define exit_sleep_mode 0x11
/*
* This command causes the display module to exit Sleep mode.
* All blocks inside the display module are enabled.
*/
-#define enter_partial_mode 0x12
+#define enter_partial_mode 0x12
/*
* This command causes the display module to enter the Partial Display
* Mode. The Partial Display Mode window is described by the
* set_partial_area command.
*/
-#define enter_normal_mode 0x13
+#define enter_normal_mode 0x13
/*
* This command causes the display module to enter the Normal mode.
* Normal Mode is defined as Partial Display mode and Scroll mode are off
*/
-#define exit_invert_mode 0x20
+#define exit_invert_mode 0x20
/*
* This command causes the display module to stop inverting the image
* data on the display device. The frame memory contents remain unchanged.
* No status bits are changed.
*/
-#define enter_invert_mode 0x21
+#define enter_invert_mode 0x21
/*
* This command causes the display module to invert the image data only on
* the display device. The frame memory contents remain unchanged.
* No status bits are changed.
*/
-#define set_gamma_curve 0x26
+#define set_gamma_curve 0x26
/*
* This command selects the desired gamma curve for the display device.
* Four fixed gamma curves are defined in section DCS spec.
*/
-#define set_display_off 0x28
+#define set_display_off 0x28
/* ************************************************************************* *\
This command causes the display module to stop displaying the image data
on the display device. The frame memory contents remain unchanged.
No status bits are changed.
\* ************************************************************************* */
-#define set_display_on 0x29
+#define set_display_on 0x29
/* ************************************************************************* *\
This command causes the display module to start displaying the image data
on the display device. The frame memory contents remain unchanged.
No status bits are changed.
\* ************************************************************************* */
-#define set_column_address 0x2a
+#define set_column_address 0x2a
/*
* This command defines the column extent of the frame memory accessed by
* the hostprocessor with the read_memory_continue and
* write_memory_continue commands.
* No status bits are changed.
*/
-#define set_page_addr 0x2b
+#define set_page_addr 0x2b
/*
* This command defines the page extent of the frame memory accessed by
* the host processor with the write_memory_continue and
- * read_memory_continue command.
+ * read_memory_continue command.
* No status bits are changed.
*/
-#define write_mem_start 0x2c
+#define write_mem_start 0x2c
/*
* This command transfers image data from the host processor to the
- * display module s frame memory starting at the pixel location specified
+ * display modules frame memory starting at the pixel location specified
* by preceding set_column_address and set_page_address commands.
*/
-#define set_partial_area 0x30
+#define set_partial_area 0x30
/*
* This command defines the Partial Display mode s display area.
* There are two parameters associated with this command, the first
* defines the Start Row (SR) and the second the End Row (ER). SR and ER
* refer to the Frame Memory Line Pointer.
*/
-#define set_scroll_area 0x33
+#define set_scroll_area 0x33
/*
* This command defines the display modules Vertical Scrolling Area.
*/
-#define set_tear_off 0x34
+#define set_tear_off 0x34
/*
* This command turns off the display modules Tearing Effect output
* signal on the TE signal line.
*/
-#define set_tear_on 0x35
+#define set_tear_on 0x35
/*
* This command turns on the display modules Tearing Effect output signal
* on the TE signal line.
*/
-#define set_address_mode 0x36
+#define set_address_mode 0x36
/*
* This command sets the data order for transfers from the host processor
* to display modules frame memory,bits B[7:5] and B3, and from the
* display modules frame memory to the display device, bits B[2:0] and B4.
*/
-#define set_scroll_start 0x37
+#define set_scroll_start 0x37
/*
* This command sets the start of the vertical scrolling area in the frame
* memory. The vertical scrolling area is fully defined when this command
@@ -1007,18 +1011,18 @@ No status bits are changed.
* line in the frame memory that is written to the display device as the
* first line of the vertical scroll area.
*/
-#define exit_idle_mode 0x38
+#define exit_idle_mode 0x38
/*
* This command causes the display module to exit Idle mode.
*/
-#define enter_idle_mode 0x39
+#define enter_idle_mode 0x39
/*
* This command causes the display module to enter Idle Mode.
* In Idle Mode, color expression is reduced. Colors are shown on the
* display device using the MSB of each of the R, G and B color
* components in the frame memory
*/
-#define set_pixel_format 0x3a
+#define set_pixel_format 0x3a
/*
* This command sets the pixel format for the RGB image data used by the
* interface.
@@ -1026,25 +1030,27 @@ No status bits are changed.
* Bits D[2:0] DBI Pixel Format Definition
* Bits D7 and D3 are not used.
*/
- #define DCS_PIXEL_FORMAT_3bbp 0x1
- #define DCS_PIXEL_FORMAT_8bbp 0x2
- #define DCS_PIXEL_FORMAT_12bbp 0x3
- #define DCS_PIXEL_FORMAT_16bbp 0x5
- #define DCS_PIXEL_FORMAT_18bbp 0x6
- #define DCS_PIXEL_FORMAT_24bbp 0x7
-#define write_mem_cont 0x3c
+#define DCS_PIXEL_FORMAT_3bpp 0x1
+#define DCS_PIXEL_FORMAT_8bpp 0x2
+#define DCS_PIXEL_FORMAT_12bpp 0x3
+#define DCS_PIXEL_FORMAT_16bpp 0x5
+#define DCS_PIXEL_FORMAT_18bpp 0x6
+#define DCS_PIXEL_FORMAT_24bpp 0x7
+
+#define write_mem_cont 0x3c
+
/*
* This command transfers image data from the host processor to the
* display module's frame memory continuing from the pixel location
* following the previous write_memory_continue or write_memory_start
* command.
*/
-#define set_tear_scanline 0x44
+#define set_tear_scanline 0x44
/*
* This command turns on the display modules Tearing Effect output signal
* on the TE signal line when the display module reaches line N.
*/
-#define get_scanline 0x45
+#define get_scanline 0x45
/*
* The display module returns the current scanline, N, used to update the
* display device. The total number of scanlines on a display device is
@@ -1094,22 +1100,22 @@ No status bits are changed.
#define GAMMA_AUTO (1 << 0)

/* DCS Interface Pixel Formats */
-#define DCS_PIXEL_FORMAT_3BPP 0x1
-#define DCS_PIXEL_FORMAT_8BPP 0x2
-#define DCS_PIXEL_FORMAT_12BPP 0x3
-#define DCS_PIXEL_FORMAT_16BPP 0x5
-#define DCS_PIXEL_FORMAT_18BPP 0x6
-#define DCS_PIXEL_FORMAT_24BPP 0x7
+#define DCS_PIXEL_FORMAT_3BPP 0x1
+#define DCS_PIXEL_FORMAT_8BPP 0x2
+#define DCS_PIXEL_FORMAT_12BPP 0x3
+#define DCS_PIXEL_FORMAT_16BPP 0x5
+#define DCS_PIXEL_FORMAT_18BPP 0x6
+#define DCS_PIXEL_FORMAT_24BPP 0x7
/* ONE PARAMETER READ DATA */
-#define addr_mode_data 0xfc
-#define diag_res_data 0x00
-#define disp_mode_data 0x23
-#define pxl_fmt_data 0x77
-#define pwr_mode_data 0x74
-#define sig_mode_data 0x00
+#define addr_mode_data 0xfc
+#define diag_res_data 0x00
+#define disp_mode_data 0x23
+#define pxl_fmt_data 0x77
+#define pwr_mode_data 0x74
+#define sig_mode_data 0x00
/* TWO PARAMETERS READ DATA */
-#define scanline_data1 0xff
-#define scanline_data2 0xff
+#define scanline_data1 0xff
+#define scanline_data2 0xff
#define NON_BURST_MODE_SYNC_PULSE 0x01 /* Non Burst Mode
* with Sync Pulse
*/
@@ -1117,7 +1123,8 @@ No status bits are changed.
* with Sync events
*/
#define BURST_MODE 0x03 /* Burst Mode */
-#define DBI_COMMAND_BUFFER_SIZE 0x240 /* 0x32 */ /* 0x120 */ /* Allocate at least
+#define DBI_COMMAND_BUFFER_SIZE 0x240 /* 0x32 */ /* 0x120 */
+ /* Allocate at least
* 0x100 Byte with 32
* byte alignment
*/
@@ -1125,13 +1132,13 @@ No status bits are changed.
* 0x100 Byte with 32
* byte alignment
*/
-#define DBI_CB_TIME_OUT 0xFFFF
-
-#define GEN_FB_TIME_OUT 2000
-#define ALIGNMENT_32BYTE_MASK (~((1 << 0)|(1 << 1)|(1 << 2)|(1 << 3)|(1 << 4)))
-#define SKU_83 0x01
-#define SKU_100 0x02
-#define SKU_100L 0x04
-#define SKU_BYPASS 0x08
+#define DBI_CB_TIME_OUT 0xFFFF
+
+#define GEN_FB_TIME_OUT 2000
+
+#define SKU_83 0x01
+#define SKU_100 0x02
+#define SKU_100L 0x04
+#define SKU_BYPASS 0x08

#endif
diff --git a/drivers/staging/gma500/psb_intel_sdvo.c b/drivers/staging/gma500/psb_intel_sdvo.c
index e313ce2..a4bad1a 100644
--- a/drivers/staging/gma500/psb_intel_sdvo.c
+++ b/drivers/staging/gma500/psb_intel_sdvo.c
@@ -211,7 +211,8 @@ static void psb_intel_sdvo_write_cmd(struct psb_intel_output *psb_intel_output,


sizeof(sdvo_cmd_names) / sizeof(sdvo_cmd_names[0]);
i++) {
if (cmd == sdvo_cmd_names[i].cmd) {

- printk(KERN_CONT "(%s)", sdvo_cmd_names[i].name);
+ printk(KERN_CONT
+ "(%s)", sdvo_cmd_names[i].name);
break;
}
}
diff --git a/drivers/staging/gma500/psb_intel_sdvo_regs.h b/drivers/staging/gma500/psb_intel_sdvo_regs.h
index c7107a3..96862ea 100644
--- a/drivers/staging/gma500/psb_intel_sdvo_regs.h
+++ b/drivers/staging/gma500/psb_intel_sdvo_regs.h
@@ -51,7 +51,7 @@ struct psb_intel_sdvo_caps {
unsigned int stall_support:1;
unsigned int pad:1;
u16 output_flags;
-} __attribute__ ((packed));
+} __packed;

/** This matches the EDID DTD structure, more or less */
struct psb_intel_sdvo_dtd {
@@ -82,18 +82,18 @@ struct psb_intel_sdvo_dtd {
u8 v_sync_off_high;
u8 reserved;
} part2;
-} __attribute__ ((packed));
+} __packed;

struct psb_intel_sdvo_pixel_clock_range {
u16 min; /**< pixel clock, in 10kHz units */
u16 max; /**< pixel clock, in 10kHz units */
-} __attribute__ ((packed));
+} __packed;

struct psb_intel_sdvo_preferred_input_timing_args {
u16 clock;
u16 width;
u16 height;
-} __attribute__ ((packed));
+} __packed;

/* I2C registers for SDVO */
#define SDVO_I2C_ARG_0 0x07
@@ -147,7 +147,7 @@ struct psb_intel_sdvo_get_trained_inputs_response {
unsigned int input0_trained:1;
unsigned int input1_trained:1;
unsigned int pad:6;
-} __attribute__ ((packed));
+} __packed;

/** Returns a struct psb_intel_sdvo_output_flags of active outputs. */
#define SDVO_CMD_GET_ACTIVE_OUTPUTS 0x04
@@ -201,7 +201,7 @@ struct psb_intel_sdvo_get_interrupt_event_source_response {
u16 interrupt_status;
unsigned int ambient_light_interrupt:1;
unsigned int pad:7;
-} __attribute__ ((packed));
+} __packed;

/**
* Selects which input is affected by future input commands.
@@ -214,7 +214,7 @@ struct psb_intel_sdvo_get_interrupt_event_source_response {
struct psb_intel_sdvo_set_target_input_args {
unsigned int target_1:1;
unsigned int pad:7;
-} __attribute__ ((packed));
+} __packed;

/**
* Takes a struct psb_intel_sdvo_output_flags of which outputs are targeted by
diff --git a/drivers/staging/gma500/psb_reg.h b/drivers/staging/gma500/psb_reg.h
index 529fda8..b81c7c1 100644
--- a/drivers/staging/gma500/psb_reg.h
+++ b/drivers/staging/gma500/psb_reg.h
@@ -22,161 +22,157 @@
#ifndef _PSB_REG_H_
#define _PSB_REG_H_

-#define PSB_CR_CLKGATECTL 0x0000
-#define _PSB_C_CLKGATECTL_AUTO_MAN_REG (1 << 24)
-#define _PSB_C_CLKGATECTL_USE_CLKG_SHIFT (20)
-#define _PSB_C_CLKGATECTL_USE_CLKG_MASK (0x3 << 20)
-#define _PSB_C_CLKGATECTL_DPM_CLKG_SHIFT (16)
-#define _PSB_C_CLKGATECTL_DPM_CLKG_MASK (0x3 << 16)
-#define _PSB_C_CLKGATECTL_TA_CLKG_SHIFT (12)
-#define _PSB_C_CLKGATECTL_TA_CLKG_MASK (0x3 << 12)
-#define _PSB_C_CLKGATECTL_TSP_CLKG_SHIFT (8)
-#define _PSB_C_CLKGATECTL_TSP_CLKG_MASK (0x3 << 8)
-#define _PSB_C_CLKGATECTL_ISP_CLKG_SHIFT (4)
-#define _PSB_C_CLKGATECTL_ISP_CLKG_MASK (0x3 << 4)
-#define _PSB_C_CLKGATECTL_2D_CLKG_SHIFT (0)
-#define _PSB_C_CLKGATECTL_2D_CLKG_MASK (0x3 << 0)
-#define _PSB_C_CLKGATECTL_CLKG_ENABLED (0)
-#define _PSB_C_CLKGATECTL_CLKG_DISABLED (1)
-#define _PSB_C_CLKGATECTL_CLKG_AUTO (2)
-
-#define PSB_CR_CORE_ID 0x0010
-#define _PSB_CC_ID_ID_SHIFT (16)
-#define _PSB_CC_ID_ID_MASK (0xFFFF << 16)
-#define _PSB_CC_ID_CONFIG_SHIFT (0)
-#define _PSB_CC_ID_CONFIG_MASK (0xFFFF << 0)
-
-#define PSB_CR_CORE_REVISION 0x0014
-#define _PSB_CC_REVISION_DESIGNER_SHIFT (24)
-#define _PSB_CC_REVISION_DESIGNER_MASK (0xFF << 24)
-#define _PSB_CC_REVISION_MAJOR_SHIFT (16)
-#define _PSB_CC_REVISION_MAJOR_MASK (0xFF << 16)
-#define _PSB_CC_REVISION_MINOR_SHIFT (8)
-#define _PSB_CC_REVISION_MINOR_MASK (0xFF << 8)
-#define _PSB_CC_REVISION_MAINTENANCE_SHIFT (0)
-#define _PSB_CC_REVISION_MAINTENANCE_MASK (0xFF << 0)
-
-#define PSB_CR_DESIGNER_REV_FIELD1 0x0018
-
-#define PSB_CR_SOFT_RESET 0x0080
-#define _PSB_CS_RESET_TSP_RESET (1 << 6)
-#define _PSB_CS_RESET_ISP_RESET (1 << 5)
-#define _PSB_CS_RESET_USE_RESET (1 << 4)
-#define _PSB_CS_RESET_TA_RESET (1 << 3)
-#define _PSB_CS_RESET_DPM_RESET (1 << 2)
-#define _PSB_CS_RESET_TWOD_RESET (1 << 1)
-#define _PSB_CS_RESET_BIF_RESET (1 << 0)
-
-#define PSB_CR_DESIGNER_REV_FIELD2 0x001C
-
-#define PSB_CR_EVENT_HOST_ENABLE2 0x0110
-
-#define PSB_CR_EVENT_STATUS2 0x0118
-
-#define PSB_CR_EVENT_HOST_CLEAR2 0x0114
-#define _PSB_CE2_BIF_REQUESTER_FAULT (1 << 4)
-
-#define PSB_CR_EVENT_STATUS 0x012C
-
-#define PSB_CR_EVENT_HOST_ENABLE 0x0130
-
-#define PSB_CR_EVENT_HOST_CLEAR 0x0134
-#define _PSB_CE_MASTER_INTERRUPT (1 << 31)
-#define _PSB_CE_TA_DPM_FAULT (1 << 28)
-#define _PSB_CE_TWOD_COMPLETE (1 << 27)
-#define _PSB_CE_DPM_OUT_OF_MEMORY_ZLS (1 << 25)
-#define _PSB_CE_DPM_TA_MEM_FREE (1 << 24)
-#define _PSB_CE_PIXELBE_END_RENDER (1 << 18)
-#define _PSB_CE_SW_EVENT (1 << 14)
-#define _PSB_CE_TA_FINISHED (1 << 13)
-#define _PSB_CE_TA_TERMINATE (1 << 12)
-#define _PSB_CE_DPM_REACHED_MEM_THRESH (1 << 3)
-#define _PSB_CE_DPM_OUT_OF_MEMORY_GBL (1 << 2)
-#define _PSB_CE_DPM_OUT_OF_MEMORY_MT (1 << 1)
-#define _PSB_CE_DPM_3D_MEM_FREE (1 << 0)
-
-
-#define PSB_USE_OFFSET_MASK 0x0007FFFF
-#define PSB_USE_OFFSET_SIZE (PSB_USE_OFFSET_MASK + 1)
-#define PSB_CR_USE_CODE_BASE0 0x0A0C
-#define PSB_CR_USE_CODE_BASE1 0x0A10
-#define PSB_CR_USE_CODE_BASE2 0x0A14
-#define PSB_CR_USE_CODE_BASE3 0x0A18
-#define PSB_CR_USE_CODE_BASE4 0x0A1C
-#define PSB_CR_USE_CODE_BASE5 0x0A20
-#define PSB_CR_USE_CODE_BASE6 0x0A24
-#define PSB_CR_USE_CODE_BASE7 0x0A28
-#define PSB_CR_USE_CODE_BASE8 0x0A2C
-#define PSB_CR_USE_CODE_BASE9 0x0A30
-#define PSB_CR_USE_CODE_BASE10 0x0A34
-#define PSB_CR_USE_CODE_BASE11 0x0A38
-#define PSB_CR_USE_CODE_BASE12 0x0A3C
-#define PSB_CR_USE_CODE_BASE13 0x0A40
-#define PSB_CR_USE_CODE_BASE14 0x0A44
-#define PSB_CR_USE_CODE_BASE15 0x0A48
-#define PSB_CR_USE_CODE_BASE(_i) (0x0A0C + ((_i) << 2))
-#define _PSB_CUC_BASE_DM_SHIFT (25)
-#define _PSB_CUC_BASE_DM_MASK (0x3 << 25)
-#define _PSB_CUC_BASE_ADDR_SHIFT (0) /* 1024-bit aligned address? */
-#define _PSB_CUC_BASE_ADDR_ALIGNSHIFT (7)
-#define _PSB_CUC_BASE_ADDR_MASK (0x1FFFFFF << 0)
-#define _PSB_CUC_DM_VERTEX (0)
-#define _PSB_CUC_DM_PIXEL (1)
-#define _PSB_CUC_DM_RESERVED (2)
-#define _PSB_CUC_DM_EDM (3)
-
-#define PSB_CR_PDS_EXEC_BASE 0x0AB8
-#define _PSB_CR_PDS_EXEC_BASE_ADDR_SHIFT (20) /* 1MB aligned address */
-#define _PSB_CR_PDS_EXEC_BASE_ADDR_ALIGNSHIFT (20)
-
-#define PSB_CR_EVENT_KICKER 0x0AC4
-#define _PSB_CE_KICKER_ADDRESS_SHIFT (4) /* 128-bit aligned address */
-
-#define PSB_CR_EVENT_KICK 0x0AC8
-#define _PSB_CE_KICK_NOW (1 << 0)
-
-
-#define PSB_CR_BIF_DIR_LIST_BASE1 0x0C38
-
-#define PSB_CR_BIF_CTRL 0x0C00
-#define _PSB_CB_CTRL_CLEAR_FAULT (1 << 4)
-#define _PSB_CB_CTRL_INVALDC (1 << 3)
-#define _PSB_CB_CTRL_FLUSH (1 << 2)
-
-#define PSB_CR_BIF_INT_STAT 0x0C04
-
-#define PSB_CR_BIF_FAULT 0x0C08
-#define _PSB_CBI_STAT_PF_N_RW (1 << 14)
-#define _PSB_CBI_STAT_FAULT_SHIFT (0)
-#define _PSB_CBI_STAT_FAULT_MASK (0x3FFF << 0)
-#define _PSB_CBI_STAT_FAULT_CACHE (1 << 1)
-#define _PSB_CBI_STAT_FAULT_TA (1 << 2)
-#define _PSB_CBI_STAT_FAULT_VDM (1 << 3)
-#define _PSB_CBI_STAT_FAULT_2D (1 << 4)
-#define _PSB_CBI_STAT_FAULT_PBE (1 << 5)
-#define _PSB_CBI_STAT_FAULT_TSP (1 << 6)
-#define _PSB_CBI_STAT_FAULT_ISP (1 << 7)
-#define _PSB_CBI_STAT_FAULT_USSEPDS (1 << 8)
-#define _PSB_CBI_STAT_FAULT_HOST (1 << 9)
-
-#define PSB_CR_BIF_BANK0 0x0C78
-
-#define PSB_CR_BIF_BANK1 0x0C7C
-
-#define PSB_CR_BIF_DIR_LIST_BASE0 0x0C84
-
-#define PSB_CR_BIF_TWOD_REQ_BASE 0x0C88
-#define PSB_CR_BIF_3D_REQ_BASE 0x0CAC
-
-#define PSB_CR_2D_SOCIF 0x0E18
-#define _PSB_C2_SOCIF_FREESPACE_SHIFT (0)
-#define _PSB_C2_SOCIF_FREESPACE_MASK (0xFF << 0)
-#define _PSB_C2_SOCIF_EMPTY (0x80 << 0)
-
-#define PSB_CR_2D_BLIT_STATUS 0x0E04
-#define _PSB_C2B_STATUS_BUSY (1 << 24)
-#define _PSB_C2B_STATUS_COMPLETE_SHIFT (0)
-#define _PSB_C2B_STATUS_COMPLETE_MASK (0xFFFFFF << 0)
+#define PSB_CR_CLKGATECTL 0x0000
+#define _PSB_C_CLKGATECTL_AUTO_MAN_REG (1 << 24)
+#define _PSB_C_CLKGATECTL_USE_CLKG_SHIFT (20)
+#define _PSB_C_CLKGATECTL_USE_CLKG_MASK (0x3 << 20)
+#define _PSB_C_CLKGATECTL_DPM_CLKG_SHIFT (16)
+#define _PSB_C_CLKGATECTL_DPM_CLKG_MASK (0x3 << 16)
+#define _PSB_C_CLKGATECTL_TA_CLKG_SHIFT (12)
+#define _PSB_C_CLKGATECTL_TA_CLKG_MASK (0x3 << 12)
+#define _PSB_C_CLKGATECTL_TSP_CLKG_SHIFT (8)
+#define _PSB_C_CLKGATECTL_TSP_CLKG_MASK (0x3 << 8)
+#define _PSB_C_CLKGATECTL_ISP_CLKG_SHIFT (4)
+#define _PSB_C_CLKGATECTL_ISP_CLKG_MASK (0x3 << 4)
+#define _PSB_C_CLKGATECTL_2D_CLKG_SHIFT (0)
+#define _PSB_C_CLKGATECTL_2D_CLKG_MASK (0x3 << 0)
+#define _PSB_C_CLKGATECTL_CLKG_ENABLED (0)
+#define _PSB_C_CLKGATECTL_CLKG_DISABLED (1)
+#define _PSB_C_CLKGATECTL_CLKG_AUTO (2)
+
+#define PSB_CR_CORE_ID 0x0010
+#define _PSB_CC_ID_ID_SHIFT (16)
+#define _PSB_CC_ID_ID_MASK (0xFFFF << 16)
+#define _PSB_CC_ID_CONFIG_SHIFT (0)
+#define _PSB_CC_ID_CONFIG_MASK (0xFFFF << 0)
+
+#define PSB_CR_CORE_REVISION 0x0014
+#define _PSB_CC_REVISION_DESIGNER_SHIFT (24)
+#define _PSB_CC_REVISION_DESIGNER_MASK (0xFF << 24)
+#define _PSB_CC_REVISION_MAJOR_SHIFT (16)
+#define _PSB_CC_REVISION_MAJOR_MASK (0xFF << 16)
+#define _PSB_CC_REVISION_MINOR_SHIFT (8)
+#define _PSB_CC_REVISION_MINOR_MASK (0xFF << 8)
+#define _PSB_CC_REVISION_MAINTENANCE_SHIFT (0)
+#define _PSB_CC_REVISION_MAINTENANCE_MASK (0xFF << 0)
+
+#define PSB_CR_DESIGNER_REV_FIELD1 0x0018
+
+#define PSB_CR_SOFT_RESET 0x0080
+#define _PSB_CS_RESET_TSP_RESET (1 << 6)
+#define _PSB_CS_RESET_ISP_RESET (1 << 5)
+#define _PSB_CS_RESET_USE_RESET (1 << 4)
+#define _PSB_CS_RESET_TA_RESET (1 << 3)
+#define _PSB_CS_RESET_DPM_RESET (1 << 2)
+#define _PSB_CS_RESET_TWOD_RESET (1 << 1)
+#define _PSB_CS_RESET_BIF_RESET (1 << 0)
+
+#define PSB_CR_DESIGNER_REV_FIELD2 0x001C
+
+#define PSB_CR_EVENT_HOST_ENABLE2 0x0110
+
+#define PSB_CR_EVENT_STATUS2 0x0118
+
+#define PSB_CR_EVENT_HOST_CLEAR2 0x0114
+#define _PSB_CE2_BIF_REQUESTER_FAULT (1 << 4)
+
+#define PSB_CR_EVENT_STATUS 0x012C
+
+#define PSB_CR_EVENT_HOST_ENABLE 0x0130
+
+#define PSB_CR_EVENT_HOST_CLEAR 0x0134
+#define _PSB_CE_MASTER_INTERRUPT (1 << 31)
+#define _PSB_CE_TA_DPM_FAULT (1 << 28)
+#define _PSB_CE_TWOD_COMPLETE (1 << 27)
+#define _PSB_CE_DPM_OUT_OF_MEMORY_ZLS (1 << 25)
+#define _PSB_CE_DPM_TA_MEM_FREE (1 << 24)
+#define _PSB_CE_PIXELBE_END_RENDER (1 << 18)
+#define _PSB_CE_SW_EVENT (1 << 14)
+#define _PSB_CE_TA_FINISHED (1 << 13)
+#define _PSB_CE_TA_TERMINATE (1 << 12)
+#define _PSB_CE_DPM_REACHED_MEM_THRESH (1 << 3)
+#define _PSB_CE_DPM_OUT_OF_MEMORY_GBL (1 << 2)
+#define _PSB_CE_DPM_OUT_OF_MEMORY_MT (1 << 1)
+#define _PSB_CE_DPM_3D_MEM_FREE (1 << 0)
+
+
+#define PSB_USE_OFFSET_MASK 0x0007FFFF
+#define PSB_USE_OFFSET_SIZE (PSB_USE_OFFSET_MASK + 1)
+#define PSB_CR_USE_CODE_BASE0 0x0A0C
+#define PSB_CR_USE_CODE_BASE1 0x0A10
+#define PSB_CR_USE_CODE_BASE2 0x0A14
+#define PSB_CR_USE_CODE_BASE3 0x0A18
+#define PSB_CR_USE_CODE_BASE4 0x0A1C
+#define PSB_CR_USE_CODE_BASE5 0x0A20
+#define PSB_CR_USE_CODE_BASE6 0x0A24
+#define PSB_CR_USE_CODE_BASE7 0x0A28
+#define PSB_CR_USE_CODE_BASE8 0x0A2C
+#define PSB_CR_USE_CODE_BASE9 0x0A30
+#define PSB_CR_USE_CODE_BASE10 0x0A34
+#define PSB_CR_USE_CODE_BASE11 0x0A38
+#define PSB_CR_USE_CODE_BASE12 0x0A3C
+#define PSB_CR_USE_CODE_BASE13 0x0A40
+#define PSB_CR_USE_CODE_BASE14 0x0A44
+#define PSB_CR_USE_CODE_BASE15 0x0A48
+#define PSB_CR_USE_CODE_BASE(_i) (0x0A0C + ((_i) << 2))
+#define _PSB_CUC_BASE_DM_SHIFT (25)
+#define _PSB_CUC_BASE_DM_MASK (0x3 << 25)
+#define _PSB_CUC_BASE_ADDR_SHIFT (0) /* 1024-bit aligned address? */
+#define _PSB_CUC_BASE_ADDR_ALIGNSHIFT (7)
+#define _PSB_CUC_BASE_ADDR_MASK (0x1FFFFFF << 0)
+#define _PSB_CUC_DM_VERTEX (0)
+#define _PSB_CUC_DM_PIXEL (1)
+#define _PSB_CUC_DM_RESERVED (2)
+#define _PSB_CUC_DM_EDM (3)
+
+#define PSB_CR_PDS_EXEC_BASE 0x0AB8
+#define _PSB_CR_PDS_EXEC_BASE_ADDR_SHIFT (20) /* 1MB aligned address */
+#define _PSB_CR_PDS_EXEC_BASE_ADDR_ALIGNSHIFT (20)
+
+#define PSB_CR_EVENT_KICKER 0x0AC4
+#define _PSB_CE_KICKER_ADDRESS_SHIFT (4) /* 128-bit aligned address */
+
+#define PSB_CR_EVENT_KICK 0x0AC8
+#define _PSB_CE_KICK_NOW (1 << 0)
+
+#define PSB_CR_BIF_DIR_LIST_BASE1 0x0C38
+
+#define PSB_CR_BIF_CTRL 0x0C00
+#define _PSB_CB_CTRL_CLEAR_FAULT (1 << 4)
+#define _PSB_CB_CTRL_INVALDC (1 << 3)
+#define _PSB_CB_CTRL_FLUSH (1 << 2)
+
+#define PSB_CR_BIF_INT_STAT 0x0C04
+
+#define PSB_CR_BIF_FAULT 0x0C08
+#define _PSB_CBI_STAT_PF_N_RW (1 << 14)
+#define _PSB_CBI_STAT_FAULT_SHIFT (0)
+#define _PSB_CBI_STAT_FAULT_MASK (0x3FFF << 0)
+#define _PSB_CBI_STAT_FAULT_CACHE (1 << 1)
+#define _PSB_CBI_STAT_FAULT_TA (1 << 2)
+#define _PSB_CBI_STAT_FAULT_VDM (1 << 3)
+#define _PSB_CBI_STAT_FAULT_2D (1 << 4)
+#define _PSB_CBI_STAT_FAULT_PBE (1 << 5)
+#define _PSB_CBI_STAT_FAULT_TSP (1 << 6)
+#define _PSB_CBI_STAT_FAULT_ISP (1 << 7)
+#define _PSB_CBI_STAT_FAULT_USSEPDS (1 << 8)
+#define _PSB_CBI_STAT_FAULT_HOST (1 << 9)
+
+#define PSB_CR_BIF_BANK0 0x0C78
+#define PSB_CR_BIF_BANK1 0x0C7C
+#define PSB_CR_BIF_DIR_LIST_BASE0 0x0C84
+#define PSB_CR_BIF_TWOD_REQ_BASE 0x0C88
+#define PSB_CR_BIF_3D_REQ_BASE 0x0CAC
+
+#define PSB_CR_2D_SOCIF 0x0E18
+#define _PSB_C2_SOCIF_FREESPACE_SHIFT (0)
+#define _PSB_C2_SOCIF_FREESPACE_MASK (0xFF << 0)
+#define _PSB_C2_SOCIF_EMPTY (0x80 << 0)
+
+#define PSB_CR_2D_BLIT_STATUS 0x0E04
+#define _PSB_C2B_STATUS_BUSY (1 << 24)
+#define _PSB_C2B_STATUS_COMPLETE_SHIFT (0)
+#define _PSB_C2B_STATUS_COMPLETE_MASK (0xFFFFFF << 0)

/*
* 2D defs.
@@ -186,121 +182,121 @@
* 2D Slave Port Data : Block Header's Object Type
*/

-#define PSB_2D_CLIP_BH (0x00000000)
-#define PSB_2D_PAT_BH (0x10000000)
-#define PSB_2D_CTRL_BH (0x20000000)
-#define PSB_2D_SRC_OFF_BH (0x30000000)
-#define PSB_2D_MASK_OFF_BH (0x40000000)
-#define PSB_2D_RESERVED1_BH (0x50000000)
-#define PSB_2D_RESERVED2_BH (0x60000000)
-#define PSB_2D_FENCE_BH (0x70000000)
-#define PSB_2D_BLIT_BH (0x80000000)
-#define PSB_2D_SRC_SURF_BH (0x90000000)
-#define PSB_2D_DST_SURF_BH (0xA0000000)
-#define PSB_2D_PAT_SURF_BH (0xB0000000)
-#define PSB_2D_SRC_PAL_BH (0xC0000000)
-#define PSB_2D_PAT_PAL_BH (0xD0000000)
-#define PSB_2D_MASK_SURF_BH (0xE0000000)
-#define PSB_2D_FLUSH_BH (0xF0000000)
+#define PSB_2D_CLIP_BH (0x00000000)
+#define PSB_2D_PAT_BH (0x10000000)
+#define PSB_2D_CTRL_BH (0x20000000)
+#define PSB_2D_SRC_OFF_BH (0x30000000)
+#define PSB_2D_MASK_OFF_BH (0x40000000)
+#define PSB_2D_RESERVED1_BH (0x50000000)
+#define PSB_2D_RESERVED2_BH (0x60000000)
+#define PSB_2D_FENCE_BH (0x70000000)
+#define PSB_2D_BLIT_BH (0x80000000)
+#define PSB_2D_SRC_SURF_BH (0x90000000)
+#define PSB_2D_DST_SURF_BH (0xA0000000)
+#define PSB_2D_PAT_SURF_BH (0xB0000000)
+#define PSB_2D_SRC_PAL_BH (0xC0000000)
+#define PSB_2D_PAT_PAL_BH (0xD0000000)
+#define PSB_2D_MASK_SURF_BH (0xE0000000)
+#define PSB_2D_FLUSH_BH (0xF0000000)

/*
* Clip Definition block (PSB_2D_CLIP_BH)
*/
-#define PSB_2D_CLIPCOUNT_MAX (1)
-#define PSB_2D_CLIPCOUNT_MASK (0x00000000)
-#define PSB_2D_CLIPCOUNT_CLRMASK (0xFFFFFFFF)
-#define PSB_2D_CLIPCOUNT_SHIFT (0)
+#define PSB_2D_CLIPCOUNT_MAX (1)
+#define PSB_2D_CLIPCOUNT_MASK (0x00000000)
+#define PSB_2D_CLIPCOUNT_CLRMASK (0xFFFFFFFF)
+#define PSB_2D_CLIPCOUNT_SHIFT (0)
/* clip rectangle min & max */
-#define PSB_2D_CLIP_XMAX_MASK (0x00FFF000)
-#define PSB_2D_CLIP_XMAX_CLRMASK (0xFF000FFF)
-#define PSB_2D_CLIP_XMAX_SHIFT (12)
-#define PSB_2D_CLIP_XMIN_MASK (0x00000FFF)
-#define PSB_2D_CLIP_XMIN_CLRMASK (0x00FFF000)
-#define PSB_2D_CLIP_XMIN_SHIFT (0)
+#define PSB_2D_CLIP_XMAX_MASK (0x00FFF000)
+#define PSB_2D_CLIP_XMAX_CLRMASK (0xFF000FFF)
+#define PSB_2D_CLIP_XMAX_SHIFT (12)
+#define PSB_2D_CLIP_XMIN_MASK (0x00000FFF)
+#define PSB_2D_CLIP_XMIN_CLRMASK (0x00FFF000)
+#define PSB_2D_CLIP_XMIN_SHIFT (0)
/* clip rectangle offset */
-#define PSB_2D_CLIP_YMAX_MASK (0x00FFF000)
-#define PSB_2D_CLIP_YMAX_CLRMASK (0xFF000FFF)
-#define PSB_2D_CLIP_YMAX_SHIFT (12)
-#define PSB_2D_CLIP_YMIN_MASK (0x00000FFF)
-#define PSB_2D_CLIP_YMIN_CLRMASK (0x00FFF000)
-#define PSB_2D_CLIP_YMIN_SHIFT (0)
+#define PSB_2D_CLIP_YMAX_MASK (0x00FFF000)
+#define PSB_2D_CLIP_YMAX_CLRMASK (0xFF000FFF)
+#define PSB_2D_CLIP_YMAX_SHIFT (12)
+#define PSB_2D_CLIP_YMIN_MASK (0x00000FFF)
+#define PSB_2D_CLIP_YMIN_CLRMASK (0x00FFF000)
+#define PSB_2D_CLIP_YMIN_SHIFT (0)

/*
* Pattern Control (PSB_2D_PAT_BH)
*/
-#define PSB_2D_PAT_HEIGHT_MASK (0x0000001F)
-#define PSB_2D_PAT_HEIGHT_SHIFT (0)
-#define PSB_2D_PAT_WIDTH_MASK (0x000003E0)
-#define PSB_2D_PAT_WIDTH_SHIFT (5)
-#define PSB_2D_PAT_YSTART_MASK (0x00007C00)
-#define PSB_2D_PAT_YSTART_SHIFT (10)
-#define PSB_2D_PAT_XSTART_MASK (0x000F8000)
-#define PSB_2D_PAT_XSTART_SHIFT (15)
+#define PSB_2D_PAT_HEIGHT_MASK (0x0000001F)
+#define PSB_2D_PAT_HEIGHT_SHIFT (0)
+#define PSB_2D_PAT_WIDTH_MASK (0x000003E0)
+#define PSB_2D_PAT_WIDTH_SHIFT (5)
+#define PSB_2D_PAT_YSTART_MASK (0x00007C00)
+#define PSB_2D_PAT_YSTART_SHIFT (10)
+#define PSB_2D_PAT_XSTART_MASK (0x000F8000)
+#define PSB_2D_PAT_XSTART_SHIFT (15)

/*
* 2D Control block (PSB_2D_CTRL_BH)
*/
/* Present Flags */
-#define PSB_2D_SRCCK_CTRL (0x00000001)
-#define PSB_2D_DSTCK_CTRL (0x00000002)
-#define PSB_2D_ALPHA_CTRL (0x00000004)
+#define PSB_2D_SRCCK_CTRL (0x00000001)
+#define PSB_2D_DSTCK_CTRL (0x00000002)
+#define PSB_2D_ALPHA_CTRL (0x00000004)
/* Colour Key Colour (SRC/DST)*/
-#define PSB_2D_CK_COL_MASK (0xFFFFFFFF)
-#define PSB_2D_CK_COL_CLRMASK (0x00000000)
-#define PSB_2D_CK_COL_SHIFT (0)
+#define PSB_2D_CK_COL_MASK (0xFFFFFFFF)
+#define PSB_2D_CK_COL_CLRMASK (0x00000000)
+#define PSB_2D_CK_COL_SHIFT (0)
/* Colour Key Mask (SRC/DST)*/
-#define PSB_2D_CK_MASK_MASK (0xFFFFFFFF)
-#define PSB_2D_CK_MASK_CLRMASK (0x00000000)
-#define PSB_2D_CK_MASK_SHIFT (0)
+#define PSB_2D_CK_MASK_MASK (0xFFFFFFFF)
+#define PSB_2D_CK_MASK_CLRMASK (0x00000000)
+#define PSB_2D_CK_MASK_SHIFT (0)
/* Alpha Control (Alpha/RGB)*/
-#define PSB_2D_GBLALPHA_MASK (0x000FF000)
-#define PSB_2D_GBLALPHA_CLRMASK (0xFFF00FFF)
-#define PSB_2D_GBLALPHA_SHIFT (12)
-#define PSB_2D_SRCALPHA_OP_MASK (0x00700000)
-#define PSB_2D_SRCALPHA_OP_CLRMASK (0xFF8FFFFF)
-#define PSB_2D_SRCALPHA_OP_SHIFT (20)
-#define PSB_2D_SRCALPHA_OP_ONE (0x00000000)
-#define PSB_2D_SRCALPHA_OP_SRC (0x00100000)
-#define PSB_2D_SRCALPHA_OP_DST (0x00200000)
-#define PSB_2D_SRCALPHA_OP_SG (0x00300000)
-#define PSB_2D_SRCALPHA_OP_DG (0x00400000)
-#define PSB_2D_SRCALPHA_OP_GBL (0x00500000)
-#define PSB_2D_SRCALPHA_OP_ZERO (0x00600000)
-#define PSB_2D_SRCALPHA_INVERT (0x00800000)
-#define PSB_2D_SRCALPHA_INVERT_CLR (0xFF7FFFFF)
-#define PSB_2D_DSTALPHA_OP_MASK (0x07000000)
-#define PSB_2D_DSTALPHA_OP_CLRMASK (0xF8FFFFFF)
-#define PSB_2D_DSTALPHA_OP_SHIFT (24)
-#define PSB_2D_DSTALPHA_OP_ONE (0x00000000)
-#define PSB_2D_DSTALPHA_OP_SRC (0x01000000)
-#define PSB_2D_DSTALPHA_OP_DST (0x02000000)
-#define PSB_2D_DSTALPHA_OP_SG (0x03000000)
-#define PSB_2D_DSTALPHA_OP_DG (0x04000000)
-#define PSB_2D_DSTALPHA_OP_GBL (0x05000000)
-#define PSB_2D_DSTALPHA_OP_ZERO (0x06000000)
-#define PSB_2D_DSTALPHA_INVERT (0x08000000)
-#define PSB_2D_DSTALPHA_INVERT_CLR (0xF7FFFFFF)
-
-#define PSB_2D_PRE_MULTIPLICATION_ENABLE (0x10000000)
-#define PSB_2D_PRE_MULTIPLICATION_CLRMASK (0xEFFFFFFF)
-#define PSB_2D_ZERO_SOURCE_ALPHA_ENABLE (0x20000000)
-#define PSB_2D_ZERO_SOURCE_ALPHA_CLRMASK (0xDFFFFFFF)
+#define PSB_2D_GBLALPHA_MASK (0x000FF000)
+#define PSB_2D_GBLALPHA_CLRMASK (0xFFF00FFF)
+#define PSB_2D_GBLALPHA_SHIFT (12)
+#define PSB_2D_SRCALPHA_OP_MASK (0x00700000)
+#define PSB_2D_SRCALPHA_OP_CLRMASK (0xFF8FFFFF)
+#define PSB_2D_SRCALPHA_OP_SHIFT (20)
+#define PSB_2D_SRCALPHA_OP_ONE (0x00000000)
+#define PSB_2D_SRCALPHA_OP_SRC (0x00100000)
+#define PSB_2D_SRCALPHA_OP_DST (0x00200000)
+#define PSB_2D_SRCALPHA_OP_SG (0x00300000)
+#define PSB_2D_SRCALPHA_OP_DG (0x00400000)
+#define PSB_2D_SRCALPHA_OP_GBL (0x00500000)
+#define PSB_2D_SRCALPHA_OP_ZERO (0x00600000)
+#define PSB_2D_SRCALPHA_INVERT (0x00800000)
+#define PSB_2D_SRCALPHA_INVERT_CLR (0xFF7FFFFF)
+#define PSB_2D_DSTALPHA_OP_MASK (0x07000000)
+#define PSB_2D_DSTALPHA_OP_CLRMASK (0xF8FFFFFF)
+#define PSB_2D_DSTALPHA_OP_SHIFT (24)
+#define PSB_2D_DSTALPHA_OP_ONE (0x00000000)
+#define PSB_2D_DSTALPHA_OP_SRC (0x01000000)
+#define PSB_2D_DSTALPHA_OP_DST (0x02000000)
+#define PSB_2D_DSTALPHA_OP_SG (0x03000000)
+#define PSB_2D_DSTALPHA_OP_DG (0x04000000)
+#define PSB_2D_DSTALPHA_OP_GBL (0x05000000)
+#define PSB_2D_DSTALPHA_OP_ZERO (0x06000000)
+#define PSB_2D_DSTALPHA_INVERT (0x08000000)
+#define PSB_2D_DSTALPHA_INVERT_CLR (0xF7FFFFFF)
+
+#define PSB_2D_PRE_MULTIPLICATION_ENABLE (0x10000000)
+#define PSB_2D_PRE_MULTIPLICATION_CLRMASK (0xEFFFFFFF)
+#define PSB_2D_ZERO_SOURCE_ALPHA_ENABLE (0x20000000)
+#define PSB_2D_ZERO_SOURCE_ALPHA_CLRMASK (0xDFFFFFFF)

/*
*Source Offset (PSB_2D_SRC_OFF_BH)
*/
-#define PSB_2D_SRCOFF_XSTART_MASK ((0x00000FFF) << 12)
-#define PSB_2D_SRCOFF_XSTART_SHIFT (12)
-#define PSB_2D_SRCOFF_YSTART_MASK (0x00000FFF)
-#define PSB_2D_SRCOFF_YSTART_SHIFT (0)
+#define PSB_2D_SRCOFF_XSTART_MASK ((0x00000FFF) << 12)
+#define PSB_2D_SRCOFF_XSTART_SHIFT (12)
+#define PSB_2D_SRCOFF_YSTART_MASK (0x00000FFF)
+#define PSB_2D_SRCOFF_YSTART_SHIFT (0)

/*
* Mask Offset (PSB_2D_MASK_OFF_BH)
*/
-#define PSB_2D_MASKOFF_XSTART_MASK ((0x00000FFF) << 12)
-#define PSB_2D_MASKOFF_XSTART_SHIFT (12)
-#define PSB_2D_MASKOFF_YSTART_MASK (0x00000FFF)
-#define PSB_2D_MASKOFF_YSTART_SHIFT (0)
+#define PSB_2D_MASKOFF_XSTART_MASK ((0x00000FFF) << 12)
+#define PSB_2D_MASKOFF_XSTART_SHIFT (12)
+#define PSB_2D_MASKOFF_YSTART_MASK (0x00000FFF)
+#define PSB_2D_MASKOFF_YSTART_SHIFT (0)

/*
* 2D Fence (see PSB_2D_FENCE_BH): bits 0:27 are ignored
@@ -310,118 +306,118 @@
*Blit Rectangle (PSB_2D_BLIT_BH)
*/

-#define PSB_2D_ROT_MASK (3<<25)
-#define PSB_2D_ROT_CLRMASK (~PSB_2D_ROT_MASK)
-#define PSB_2D_ROT_NONE (0<<25)
-#define PSB_2D_ROT_90DEGS (1<<25)
-#define PSB_2D_ROT_180DEGS (2<<25)
-#define PSB_2D_ROT_270DEGS (3<<25)
-
-#define PSB_2D_COPYORDER_MASK (3<<23)
-#define PSB_2D_COPYORDER_CLRMASK (~PSB_2D_COPYORDER_MASK)
-#define PSB_2D_COPYORDER_TL2BR (0<<23)
-#define PSB_2D_COPYORDER_BR2TL (1<<23)
-#define PSB_2D_COPYORDER_TR2BL (2<<23)
-#define PSB_2D_COPYORDER_BL2TR (3<<23)
-
-#define PSB_2D_DSTCK_CLRMASK (0xFF9FFFFF)
-#define PSB_2D_DSTCK_DISABLE (0x00000000)
-#define PSB_2D_DSTCK_PASS (0x00200000)
-#define PSB_2D_DSTCK_REJECT (0x00400000)
-
-#define PSB_2D_SRCCK_CLRMASK (0xFFE7FFFF)
-#define PSB_2D_SRCCK_DISABLE (0x00000000)
-#define PSB_2D_SRCCK_PASS (0x00080000)
-#define PSB_2D_SRCCK_REJECT (0x00100000)
-
-#define PSB_2D_CLIP_ENABLE (0x00040000)
-
-#define PSB_2D_ALPHA_ENABLE (0x00020000)
-
-#define PSB_2D_PAT_CLRMASK (0xFFFEFFFF)
-#define PSB_2D_PAT_MASK (0x00010000)
-#define PSB_2D_USE_PAT (0x00010000)
-#define PSB_2D_USE_FILL (0x00000000)
+#define PSB_2D_ROT_MASK (3 << 25)
+#define PSB_2D_ROT_CLRMASK (~PSB_2D_ROT_MASK)
+#define PSB_2D_ROT_NONE (0 << 25)
+#define PSB_2D_ROT_90DEGS (1 << 25)
+#define PSB_2D_ROT_180DEGS (2 << 25)
+#define PSB_2D_ROT_270DEGS (3 << 25)
+
+#define PSB_2D_COPYORDER_MASK (3 << 23)
+#define PSB_2D_COPYORDER_CLRMASK (~PSB_2D_COPYORDER_MASK)
+#define PSB_2D_COPYORDER_TL2BR (0 << 23)
+#define PSB_2D_COPYORDER_BR2TL (1 << 23)
+#define PSB_2D_COPYORDER_TR2BL (2 << 23)
+#define PSB_2D_COPYORDER_BL2TR (3 << 23)
+
+#define PSB_2D_DSTCK_CLRMASK (0xFF9FFFFF)
+#define PSB_2D_DSTCK_DISABLE (0x00000000)
+#define PSB_2D_DSTCK_PASS (0x00200000)
+#define PSB_2D_DSTCK_REJECT (0x00400000)
+
+#define PSB_2D_SRCCK_CLRMASK (0xFFE7FFFF)
+#define PSB_2D_SRCCK_DISABLE (0x00000000)
+#define PSB_2D_SRCCK_PASS (0x00080000)
+#define PSB_2D_SRCCK_REJECT (0x00100000)
+
+#define PSB_2D_CLIP_ENABLE (0x00040000)
+
+#define PSB_2D_ALPHA_ENABLE (0x00020000)
+
+#define PSB_2D_PAT_CLRMASK (0xFFFEFFFF)
+#define PSB_2D_PAT_MASK (0x00010000)
+#define PSB_2D_USE_PAT (0x00010000)
+#define PSB_2D_USE_FILL (0x00000000)
/*
* Tungsten Graphics note on rop codes: If rop A and rop B are
* identical, the mask surface will not be read and need not be
* set up.
*/

-#define PSB_2D_ROP3B_MASK (0x0000FF00)
-#define PSB_2D_ROP3B_CLRMASK (0xFFFF00FF)
-#define PSB_2D_ROP3B_SHIFT (8)
+#define PSB_2D_ROP3B_MASK (0x0000FF00)
+#define PSB_2D_ROP3B_CLRMASK (0xFFFF00FF)
+#define PSB_2D_ROP3B_SHIFT (8)
/* rop code A */
-#define PSB_2D_ROP3A_MASK (0x000000FF)
-#define PSB_2D_ROP3A_CLRMASK (0xFFFFFF00)
-#define PSB_2D_ROP3A_SHIFT (0)
+#define PSB_2D_ROP3A_MASK (0x000000FF)
+#define PSB_2D_ROP3A_CLRMASK (0xFFFFFF00)
+#define PSB_2D_ROP3A_SHIFT (0)

-#define PSB_2D_ROP4_MASK (0x0000FFFF)
+#define PSB_2D_ROP4_MASK (0x0000FFFF)
/*
* DWORD0: (Only pass if Pattern control == Use Fill Colour)
* Fill Colour RGBA8888
*/
-#define PSB_2D_FILLCOLOUR_MASK (0xFFFFFFFF)
-#define PSB_2D_FILLCOLOUR_SHIFT (0)
+#define PSB_2D_FILLCOLOUR_MASK (0xFFFFFFFF)
+#define PSB_2D_FILLCOLOUR_SHIFT (0)
/*
* DWORD1: (Always Present)
* X Start (Dest)
* Y Start (Dest)
*/
-#define PSB_2D_DST_XSTART_MASK (0x00FFF000)
-#define PSB_2D_DST_XSTART_CLRMASK (0xFF000FFF)
-#define PSB_2D_DST_XSTART_SHIFT (12)
-#define PSB_2D_DST_YSTART_MASK (0x00000FFF)
-#define PSB_2D_DST_YSTART_CLRMASK (0xFFFFF000)
-#define PSB_2D_DST_YSTART_SHIFT (0)
+#define PSB_2D_DST_XSTART_MASK (0x00FFF000)
+#define PSB_2D_DST_XSTART_CLRMASK (0xFF000FFF)
+#define PSB_2D_DST_XSTART_SHIFT (12)
+#define PSB_2D_DST_YSTART_MASK (0x00000FFF)
+#define PSB_2D_DST_YSTART_CLRMASK (0xFFFFF000)
+#define PSB_2D_DST_YSTART_SHIFT (0)
/*
* DWORD2: (Always Present)
* X Size (Dest)
* Y Size (Dest)
*/
-#define PSB_2D_DST_XSIZE_MASK (0x00FFF000)
-#define PSB_2D_DST_XSIZE_CLRMASK (0xFF000FFF)
-#define PSB_2D_DST_XSIZE_SHIFT (12)
-#define PSB_2D_DST_YSIZE_MASK (0x00000FFF)
-#define PSB_2D_DST_YSIZE_CLRMASK (0xFFFFF000)
-#define PSB_2D_DST_YSIZE_SHIFT (0)
+#define PSB_2D_DST_XSIZE_MASK (0x00FFF000)
+#define PSB_2D_DST_XSIZE_CLRMASK (0xFF000FFF)
+#define PSB_2D_DST_XSIZE_SHIFT (12)
+#define PSB_2D_DST_YSIZE_MASK (0x00000FFF)
+#define PSB_2D_DST_YSIZE_CLRMASK (0xFFFFF000)
+#define PSB_2D_DST_YSIZE_SHIFT (0)

/*
* Source Surface (PSB_2D_SRC_SURF_BH)
*/
/*
- * WORD 0
+ * WORD 0
*/

-#define PSB_2D_SRC_FORMAT_MASK (0x00078000)
-#define PSB_2D_SRC_1_PAL (0x00000000)
-#define PSB_2D_SRC_2_PAL (0x00008000)
-#define PSB_2D_SRC_4_PAL (0x00010000)
-#define PSB_2D_SRC_8_PAL (0x00018000)
-#define PSB_2D_SRC_8_ALPHA (0x00020000)
-#define PSB_2D_SRC_4_ALPHA (0x00028000)
-#define PSB_2D_SRC_332RGB (0x00030000)
-#define PSB_2D_SRC_4444ARGB (0x00038000)
-#define PSB_2D_SRC_555RGB (0x00040000)
-#define PSB_2D_SRC_1555ARGB (0x00048000)
-#define PSB_2D_SRC_565RGB (0x00050000)
-#define PSB_2D_SRC_0888ARGB (0x00058000)
-#define PSB_2D_SRC_8888ARGB (0x00060000)
-#define PSB_2D_SRC_8888UYVY (0x00068000)
-#define PSB_2D_SRC_RESERVED (0x00070000)
-#define PSB_2D_SRC_1555ARGB_LOOKUP (0x00078000)
-
-
-#define PSB_2D_SRC_STRIDE_MASK (0x00007FFF)
-#define PSB_2D_SRC_STRIDE_CLRMASK (0xFFFF8000)
-#define PSB_2D_SRC_STRIDE_SHIFT (0)
+#define PSB_2D_SRC_FORMAT_MASK (0x00078000)
+#define PSB_2D_SRC_1_PAL (0x00000000)
+#define PSB_2D_SRC_2_PAL (0x00008000)
+#define PSB_2D_SRC_4_PAL (0x00010000)
+#define PSB_2D_SRC_8_PAL (0x00018000)
+#define PSB_2D_SRC_8_ALPHA (0x00020000)
+#define PSB_2D_SRC_4_ALPHA (0x00028000)
+#define PSB_2D_SRC_332RGB (0x00030000)
+#define PSB_2D_SRC_4444ARGB (0x00038000)
+#define PSB_2D_SRC_555RGB (0x00040000)
+#define PSB_2D_SRC_1555ARGB (0x00048000)
+#define PSB_2D_SRC_565RGB (0x00050000)
+#define PSB_2D_SRC_0888ARGB (0x00058000)
+#define PSB_2D_SRC_8888ARGB (0x00060000)
+#define PSB_2D_SRC_8888UYVY (0x00068000)
+#define PSB_2D_SRC_RESERVED (0x00070000)
+#define PSB_2D_SRC_1555ARGB_LOOKUP (0x00078000)
+
+
+#define PSB_2D_SRC_STRIDE_MASK (0x00007FFF)
+#define PSB_2D_SRC_STRIDE_CLRMASK (0xFFFF8000)
+#define PSB_2D_SRC_STRIDE_SHIFT (0)
/*
* WORD 1 - Base Address
*/
-#define PSB_2D_SRC_ADDR_MASK (0x0FFFFFFC)
-#define PSB_2D_SRC_ADDR_CLRMASK (0x00000003)
-#define PSB_2D_SRC_ADDR_SHIFT (2)
-#define PSB_2D_SRC_ADDR_ALIGNSHIFT (2)
+#define PSB_2D_SRC_ADDR_MASK (0x0FFFFFFC)
+#define PSB_2D_SRC_ADDR_CLRMASK (0x00000003)
+#define PSB_2D_SRC_ADDR_SHIFT (2)
+#define PSB_2D_SRC_ADDR_ALIGNSHIFT (2)

/*
* Pattern Surface (PSB_2D_PAT_SURF_BH)
@@ -430,31 +426,31 @@
* WORD 0
*/

-#define PSB_2D_PAT_FORMAT_MASK (0x00078000)
-#define PSB_2D_PAT_1_PAL (0x00000000)
-#define PSB_2D_PAT_2_PAL (0x00008000)
-#define PSB_2D_PAT_4_PAL (0x00010000)
-#define PSB_2D_PAT_8_PAL (0x00018000)
-#define PSB_2D_PAT_8_ALPHA (0x00020000)
-#define PSB_2D_PAT_4_ALPHA (0x00028000)
-#define PSB_2D_PAT_332RGB (0x00030000)
-#define PSB_2D_PAT_4444ARGB (0x00038000)
-#define PSB_2D_PAT_555RGB (0x00040000)
-#define PSB_2D_PAT_1555ARGB (0x00048000)
-#define PSB_2D_PAT_565RGB (0x00050000)
-#define PSB_2D_PAT_0888ARGB (0x00058000)
-#define PSB_2D_PAT_8888ARGB (0x00060000)
-
-#define PSB_2D_PAT_STRIDE_MASK (0x00007FFF)
-#define PSB_2D_PAT_STRIDE_CLRMASK (0xFFFF8000)
-#define PSB_2D_PAT_STRIDE_SHIFT (0)
+#define PSB_2D_PAT_FORMAT_MASK (0x00078000)
+#define PSB_2D_PAT_1_PAL (0x00000000)
+#define PSB_2D_PAT_2_PAL (0x00008000)
+#define PSB_2D_PAT_4_PAL (0x00010000)
+#define PSB_2D_PAT_8_PAL (0x00018000)
+#define PSB_2D_PAT_8_ALPHA (0x00020000)
+#define PSB_2D_PAT_4_ALPHA (0x00028000)
+#define PSB_2D_PAT_332RGB (0x00030000)
+#define PSB_2D_PAT_4444ARGB (0x00038000)
+#define PSB_2D_PAT_555RGB (0x00040000)
+#define PSB_2D_PAT_1555ARGB (0x00048000)
+#define PSB_2D_PAT_565RGB (0x00050000)
+#define PSB_2D_PAT_0888ARGB (0x00058000)
+#define PSB_2D_PAT_8888ARGB (0x00060000)
+
+#define PSB_2D_PAT_STRIDE_MASK (0x00007FFF)
+#define PSB_2D_PAT_STRIDE_CLRMASK (0xFFFF8000)
+#define PSB_2D_PAT_STRIDE_SHIFT (0)
/*
* WORD 1 - Base Address
*/
-#define PSB_2D_PAT_ADDR_MASK (0x0FFFFFFC)
-#define PSB_2D_PAT_ADDR_CLRMASK (0x00000003)
-#define PSB_2D_PAT_ADDR_SHIFT (2)
-#define PSB_2D_PAT_ADDR_ALIGNSHIFT (2)
+#define PSB_2D_PAT_ADDR_MASK (0x0FFFFFFC)
+#define PSB_2D_PAT_ADDR_CLRMASK (0x00000003)
+#define PSB_2D_PAT_ADDR_SHIFT (2)
+#define PSB_2D_PAT_ADDR_ALIGNSHIFT (2)

/*
* Destination Surface (PSB_2D_DST_SURF_BH)
@@ -463,26 +459,26 @@
* WORD 0
*/

-#define PSB_2D_DST_FORMAT_MASK (0x00078000)
-#define PSB_2D_DST_332RGB (0x00030000)
-#define PSB_2D_DST_4444ARGB (0x00038000)
-#define PSB_2D_DST_555RGB (0x00040000)
-#define PSB_2D_DST_1555ARGB (0x00048000)
-#define PSB_2D_DST_565RGB (0x00050000)
-#define PSB_2D_DST_0888ARGB (0x00058000)
-#define PSB_2D_DST_8888ARGB (0x00060000)
-#define PSB_2D_DST_8888AYUV (0x00070000)
-
-#define PSB_2D_DST_STRIDE_MASK (0x00007FFF)
-#define PSB_2D_DST_STRIDE_CLRMASK (0xFFFF8000)
-#define PSB_2D_DST_STRIDE_SHIFT (0)
+#define PSB_2D_DST_FORMAT_MASK (0x00078000)
+#define PSB_2D_DST_332RGB (0x00030000)
+#define PSB_2D_DST_4444ARGB (0x00038000)
+#define PSB_2D_DST_555RGB (0x00040000)
+#define PSB_2D_DST_1555ARGB (0x00048000)
+#define PSB_2D_DST_565RGB (0x00050000)
+#define PSB_2D_DST_0888ARGB (0x00058000)
+#define PSB_2D_DST_8888ARGB (0x00060000)
+#define PSB_2D_DST_8888AYUV (0x00070000)
+
+#define PSB_2D_DST_STRIDE_MASK (0x00007FFF)
+#define PSB_2D_DST_STRIDE_CLRMASK (0xFFFF8000)
+#define PSB_2D_DST_STRIDE_SHIFT (0)
/*
* WORD 1 - Base Address
*/
-#define PSB_2D_DST_ADDR_MASK (0x0FFFFFFC)
-#define PSB_2D_DST_ADDR_CLRMASK (0x00000003)
-#define PSB_2D_DST_ADDR_SHIFT (2)
-#define PSB_2D_DST_ADDR_ALIGNSHIFT (2)
+#define PSB_2D_DST_ADDR_MASK (0x0FFFFFFC)
+#define PSB_2D_DST_ADDR_CLRMASK (0x00000003)
+#define PSB_2D_DST_ADDR_SHIFT (2)
+#define PSB_2D_DST_ADDR_ALIGNSHIFT (2)

/*
* Mask Surface (PSB_2D_MASK_SURF_BH)
@@ -490,99 +486,97 @@
/*
* WORD 0
*/
-#define PSB_2D_MASK_STRIDE_MASK (0x00007FFF)
-#define PSB_2D_MASK_STRIDE_CLRMASK (0xFFFF8000)
-#define PSB_2D_MASK_STRIDE_SHIFT (0)
+#define PSB_2D_MASK_STRIDE_MASK (0x00007FFF)
+#define PSB_2D_MASK_STRIDE_CLRMASK (0xFFFF8000)
+#define PSB_2D_MASK_STRIDE_SHIFT (0)
/*
* WORD 1 - Base Address
*/
-#define PSB_2D_MASK_ADDR_MASK (0x0FFFFFFC)
-#define PSB_2D_MASK_ADDR_CLRMASK (0x00000003)
-#define PSB_2D_MASK_ADDR_SHIFT (2)
-#define PSB_2D_MASK_ADDR_ALIGNSHIFT (2)
+#define PSB_2D_MASK_ADDR_MASK (0x0FFFFFFC)
+#define PSB_2D_MASK_ADDR_CLRMASK (0x00000003)
+#define PSB_2D_MASK_ADDR_SHIFT (2)
+#define PSB_2D_MASK_ADDR_ALIGNSHIFT (2)

/*
* Source Palette (PSB_2D_SRC_PAL_BH)
*/

-#define PSB_2D_SRCPAL_ADDR_SHIFT (0)
-#define PSB_2D_SRCPAL_ADDR_CLRMASK (0xF0000007)
-#define PSB_2D_SRCPAL_ADDR_MASK (0x0FFFFFF8)
-#define PSB_2D_SRCPAL_BYTEALIGN (1024)
+#define PSB_2D_SRCPAL_ADDR_SHIFT (0)
+#define PSB_2D_SRCPAL_ADDR_CLRMASK (0xF0000007)
+#define PSB_2D_SRCPAL_ADDR_MASK (0x0FFFFFF8)
+#define PSB_2D_SRCPAL_BYTEALIGN (1024)

/*
* Pattern Palette (PSB_2D_PAT_PAL_BH)
*/

-#define PSB_2D_PATPAL_ADDR_SHIFT (0)
-#define PSB_2D_PATPAL_ADDR_CLRMASK (0xF0000007)
-#define PSB_2D_PATPAL_ADDR_MASK (0x0FFFFFF8)
-#define PSB_2D_PATPAL_BYTEALIGN (1024)
+#define PSB_2D_PATPAL_ADDR_SHIFT (0)
+#define PSB_2D_PATPAL_ADDR_CLRMASK (0xF0000007)
+#define PSB_2D_PATPAL_ADDR_MASK (0x0FFFFFF8)
+#define PSB_2D_PATPAL_BYTEALIGN (1024)

/*
* Rop3 Codes (2 LS bytes)
*/

-#define PSB_2D_ROP3_SRCCOPY (0xCCCC)
-#define PSB_2D_ROP3_PATCOPY (0xF0F0)
-#define PSB_2D_ROP3_WHITENESS (0xFFFF)
-#define PSB_2D_ROP3_BLACKNESS (0x0000)
-#define PSB_2D_ROP3_SRC (0xCC)
-#define PSB_2D_ROP3_PAT (0xF0)
-#define PSB_2D_ROP3_DST (0xAA)
-
+#define PSB_2D_ROP3_SRCCOPY (0xCCCC)
+#define PSB_2D_ROP3_PATCOPY (0xF0F0)
+#define PSB_2D_ROP3_WHITENESS (0xFFFF)
+#define PSB_2D_ROP3_BLACKNESS (0x0000)
+#define PSB_2D_ROP3_SRC (0xCC)
+#define PSB_2D_ROP3_PAT (0xF0)
+#define PSB_2D_ROP3_DST (0xAA)

/*
* Sizes.
*/

-#define PSB_SCENE_HW_COOKIE_SIZE 16
-#define PSB_TA_MEM_HW_COOKIE_SIZE 16
+#define PSB_SCENE_HW_COOKIE_SIZE 16
+#define PSB_TA_MEM_HW_COOKIE_SIZE 16

/*
* Scene stuff.
*/

-#define PSB_NUM_HW_SCENES 2
+#define PSB_NUM_HW_SCENES 2

/*
* Scheduler completion actions.
*/

-#define PSB_RASTER_BLOCK 0
-#define PSB_RASTER 1
-#define PSB_RETURN 2
-#define PSB_TA 3
-
-
-/*Power management*/
-#define PSB_PUNIT_PORT 0x04
-#define PSB_OSPMBA 0x78
-#define PSB_APMBA 0x7a
-#define PSB_APM_CMD 0x0
-#define PSB_APM_STS 0x04
-#define PSB_PWRGT_VID_ENC_MASK 0x30
-#define PSB_PWRGT_VID_DEC_MASK 0xc
-#define PSB_PWRGT_GL3_MASK 0xc0
-
-#define PSB_PM_SSC 0x20
-#define PSB_PM_SSS 0x30
-#define PSB_PWRGT_DISPLAY_MASK 0xc /*on a different BA than video/gfx*/
-#define MDFLD_PWRGT_DISPLAY_A_CNTR 0x0000000c
-#define MDFLD_PWRGT_DISPLAY_B_CNTR 0x0000c000
-#define MDFLD_PWRGT_DISPLAY_C_CNTR 0x00030000
-#define MDFLD_PWRGT_DISP_MIPI_CNTR 0x000c0000
-#define MDFLD_PWRGT_DISPLAY_CNTR (MDFLD_PWRGT_DISPLAY_A_CNTR | MDFLD_PWRGT_DISPLAY_B_CNTR | MDFLD_PWRGT_DISPLAY_C_CNTR | MDFLD_PWRGT_DISP_MIPI_CNTR)// 0x000fc00c
+#define PSB_RASTER_BLOCK 0
+#define PSB_RASTER 1
+#define PSB_RETURN 2
+#define PSB_TA 3
+
+/* Power management */
+#define PSB_PUNIT_PORT 0x04
+#define PSB_OSPMBA 0x78
+#define PSB_APMBA 0x7a
+#define PSB_APM_CMD 0x0
+#define PSB_APM_STS 0x04
+#define PSB_PWRGT_VID_ENC_MASK 0x30
+#define PSB_PWRGT_VID_DEC_MASK 0xc
+#define PSB_PWRGT_GL3_MASK 0xc0
+
+#define PSB_PM_SSC 0x20
+#define PSB_PM_SSS 0x30
+#define PSB_PWRGT_DISPLAY_MASK 0xc /*on a different BA than video/gfx*/
+#define MDFLD_PWRGT_DISPLAY_A_CNTR 0x0000000c
+#define MDFLD_PWRGT_DISPLAY_B_CNTR 0x0000c000
+#define MDFLD_PWRGT_DISPLAY_C_CNTR 0x00030000
+#define MDFLD_PWRGT_DISP_MIPI_CNTR 0x000c0000
+#define MDFLD_PWRGT_DISPLAY_CNTR (MDFLD_PWRGT_DISPLAY_A_CNTR | MDFLD_PWRGT_DISPLAY_B_CNTR | MDFLD_PWRGT_DISPLAY_C_CNTR | MDFLD_PWRGT_DISP_MIPI_CNTR) /* 0x000fc00c */


/* Display SSS register bits are different in A0 vs. B0 */

-#define PSB_PWRGT_GFX_MASK 0x3
-#define MDFLD_PWRGT_DISPLAY_A_STS 0x000000c0
-#define MDFLD_PWRGT_DISPLAY_B_STS 0x00000300
-#define MDFLD_PWRGT_DISPLAY_C_STS 0x00000c00
-#define PSB_PWRGT_GFX_MASK_B0 0xc3
+#define PSB_PWRGT_GFX_MASK 0x3
+#define MDFLD_PWRGT_DISPLAY_A_STS 0x000000c0
+#define MDFLD_PWRGT_DISPLAY_B_STS 0x00000300
+#define MDFLD_PWRGT_DISPLAY_C_STS 0x00000c00
+#define PSB_PWRGT_GFX_MASK_B0 0xc3
#define MDFLD_PWRGT_DISPLAY_A_STS_B0 0x0000000c
-#define MDFLD_PWRGT_DISPLAY_B_STS_B0 0x0000c000
-#define MDFLD_PWRGT_DISPLAY_C_STS_B0 0x00030000
-#define MDFLD_PWRGT_DISP_MIPI_STS 0x000c0000
-#define MDFLD_PWRGT_DISPLAY_STS_A0 (MDFLD_PWRGT_DISPLAY_A_STS | MDFLD_PWRGT_DISPLAY_B_STS | MDFLD_PWRGT_DISPLAY_C_STS | MDFLD_PWRGT_DISP_MIPI_STS)// 0x000fc00c
-#define MDFLD_PWRGT_DISPLAY_STS_B0 (MDFLD_PWRGT_DISPLAY_A_STS_B0 | MDFLD_PWRGT_DISPLAY_B_STS_B0 | MDFLD_PWRGT_DISPLAY_C_STS_B0 | MDFLD_PWRGT_DISP_MIPI_STS)// 0x000fc00c
+#define MDFLD_PWRGT_DISPLAY_B_STS_B0 0x0000c000
+#define MDFLD_PWRGT_DISPLAY_C_STS_B0 0x00030000
+#define MDFLD_PWRGT_DISP_MIPI_STS 0x000c0000
+#define MDFLD_PWRGT_DISPLAY_STS_A0 (MDFLD_PWRGT_DISPLAY_A_STS | MDFLD_PWRGT_DISPLAY_B_STS | MDFLD_PWRGT_DISPLAY_C_STS | MDFLD_PWRGT_DISP_MIPI_STS) /* 0x000fc00c */
+#define MDFLD_PWRGT_DISPLAY_STS_B0 (MDFLD_PWRGT_DISPLAY_A_STS_B0 | MDFLD_PWRGT_DISPLAY_B_STS_B0 | MDFLD_PWRGT_DISPLAY_C_STS_B0 | MDFLD_PWRGT_DISP_MIPI_STS) /* 0x000fc00c */
#endif

Alan Cox

unread,
Jun 16, 2011, 12:38:15 PM6/16/11
to gr...@kroah.com, linux-...@vger.kernel.org
From: Alan Cox <al...@linux.intel.com>

This large patch adds all the basics for Medfield support. Lots of clean up
needed in this area still.

Signed-off-by: Alan Cox <al...@linux.intel.com>
---

drivers/staging/gma500/Makefile | 12

drivers/staging/gma500/displays/hdmi.h | 33 +
drivers/staging/gma500/displays/pyr_cmd.h | 34 +
drivers/staging/gma500/displays/pyr_vid.h | 34 +
drivers/staging/gma500/displays/tmd_cmd.h | 34 +
drivers/staging/gma500/displays/tmd_vid.h | 34 +
drivers/staging/gma500/displays/tpo_cmd.h | 35 +
drivers/staging/gma500/displays/tpo_vid.h | 33 +

drivers/staging/gma500/mdfld_dsi_dbi.c | 872 ++++++++++++++++


drivers/staging/gma500/mdfld_dsi_dbi.h | 188 +++
drivers/staging/gma500/mdfld_dsi_dbi_dpu.h | 157 +++
drivers/staging/gma500/mdfld_dsi_dpi.c | 991 ++++++++++++++++++
drivers/staging/gma500/mdfld_dsi_dpi.h | 80 +

drivers/staging/gma500/mdfld_dsi_output.c | 977 ++++++++++++++++++
drivers/staging/gma500/mdfld_dsi_output.h | 328 ++++++
drivers/staging/gma500/mdfld_dsi_pkg_sender.c | 1097 ++++++++++++++++++++
drivers/staging/gma500/mdfld_dsi_pkg_sender.h | 158 +++
drivers/staging/gma500/mdfld_intel_display.c | 1388 +++++++++++++++++++++++++
drivers/staging/gma500/mdfld_msic.h | 31 +
drivers/staging/gma500/mdfld_output.c | 135 ++
drivers/staging/gma500/mdfld_output.h | 77 +


drivers/staging/gma500/mdfld_pyr_cmd.c | 575 ++++++++++
drivers/staging/gma500/mdfld_tmd_vid.c | 144 +++
drivers/staging/gma500/mdfld_tpo_cmd.c | 495 +++++++++

drivers/staging/gma500/mdfld_tpo_vid.c | 140 +++
drivers/staging/gma500/psb_bl.c | 68 +
drivers/staging/gma500/psb_drm.h | 7
drivers/staging/gma500/psb_drv.c | 25
drivers/staging/gma500/psb_drv.h | 132 ++
drivers/staging/gma500/psb_fb.c | 28 -
drivers/staging/gma500/psb_intel_display.c | 18
drivers/staging/gma500/psb_intel_display.h | 3
drivers/staging/gma500/psb_intel_drv.h | 3
drivers/staging/gma500/psb_intel_lvds.c | 1
drivers/staging/gma500/psb_irq.c | 61 +
drivers/staging/gma500/psb_powermgmt.c | 626 +++++++++++
36 files changed, 9005 insertions(+), 49 deletions(-)


create mode 100644 drivers/staging/gma500/displays/hdmi.h
create mode 100644 drivers/staging/gma500/displays/pyr_cmd.h
create mode 100644 drivers/staging/gma500/displays/pyr_vid.h
create mode 100644 drivers/staging/gma500/displays/tmd_cmd.h
create mode 100644 drivers/staging/gma500/displays/tmd_vid.h
create mode 100644 drivers/staging/gma500/displays/tpo_cmd.h
create mode 100644 drivers/staging/gma500/displays/tpo_vid.h

create mode 100644 drivers/staging/gma500/mdfld_dsi_dbi.c
create mode 100644 drivers/staging/gma500/mdfld_dsi_dbi.h
create mode 100644 drivers/staging/gma500/mdfld_dsi_dbi_dpu.h
create mode 100644 drivers/staging/gma500/mdfld_dsi_dpi.c
create mode 100644 drivers/staging/gma500/mdfld_dsi_dpi.h
create mode 100644 drivers/staging/gma500/mdfld_dsi_output.c
create mode 100644 drivers/staging/gma500/mdfld_dsi_output.h
create mode 100644 drivers/staging/gma500/mdfld_dsi_pkg_sender.c
create mode 100644 drivers/staging/gma500/mdfld_dsi_pkg_sender.h
create mode 100644 drivers/staging/gma500/mdfld_intel_display.c
create mode 100644 drivers/staging/gma500/mdfld_msic.h
create mode 100644 drivers/staging/gma500/mdfld_output.c
create mode 100644 drivers/staging/gma500/mdfld_output.h
create mode 100644 drivers/staging/gma500/mdfld_pyr_cmd.c
create mode 100644 drivers/staging/gma500/mdfld_tmd_vid.c
create mode 100644 drivers/staging/gma500/mdfld_tpo_cmd.c
create mode 100644 drivers/staging/gma500/mdfld_tpo_vid.c

diff --git a/drivers/staging/gma500/Makefile b/drivers/staging/gma500/Makefile
index 01aaa28..4c9c475 100644
--- a/drivers/staging/gma500/Makefile
+++ b/drivers/staging/gma500/Makefile
@@ -22,6 +22,16 @@ psb_gfx-y += gem_glue.o \
psb_powermgmt.o \
psb_irq.o \
mrst_crtc.o \
- mrst_lvds.o
+ mrst_lvds.o \
+ mdfld_output.o \
+ mdfld_pyr_cmd.o \
+ mdfld_tmd_vid.o \
+ mdfld_tpo_cmd.o \
+ mdfld_tpo_vid.o \
+ mdfld_dsi_pkg_sender.o \
+ mdfld_dsi_dpi.o \
+ mdfld_dsi_output.o \
+ mdfld_dsi_dbi.o \
+ mdfld_intel_display.o

obj-$(CONFIG_DRM_PSB) += psb_gfx.o
diff --git a/drivers/staging/gma500/displays/hdmi.h b/drivers/staging/gma500/displays/hdmi.h
new file mode 100644
index 0000000..d58ba9b
--- /dev/null
+++ b/drivers/staging/gma500/displays/hdmi.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2010 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ * Thomas Eaton <thomas....@intel.com>
+ * Scott Rowe <scott....@intel.com>
+ */
+
+#ifndef HDMI_H
+#define HDMI_H
+
+extern void hdmi_init(struct drm_device *dev);
+
+#endif
diff --git a/drivers/staging/gma500/displays/pyr_cmd.h b/drivers/staging/gma500/displays/pyr_cmd.h
new file mode 100644
index 0000000..84bae5c
--- /dev/null
+++ b/drivers/staging/gma500/displays/pyr_cmd.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2010 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicensen
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ * Thomas Eaton <thomas....@intel.com>
+ * Scott Rowe <scott....@intel.com>
+ */
+
+#ifndef PYR_CMD_H
+#define PYR_CMD_H
+
+extern void pyr_cmd_init(struct drm_device *dev, struct panel_funcs *p_funcs);
+
+#endif
+
diff --git a/drivers/staging/gma500/displays/pyr_vid.h b/drivers/staging/gma500/displays/pyr_vid.h
new file mode 100644
index 0000000..ce98860
--- /dev/null
+++ b/drivers/staging/gma500/displays/pyr_vid.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2010 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicensen
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ * Thomas Eaton <thomas....@intel.com>
+ * Scott Rowe <scott....@intel.com>
+*/
+
+#ifndef PYR_VID_H
+#define PYR_VID_H
+
+extern void pyr_vid_init(struct drm_device *dev, struct panel_funcs *p_funcs);
+extern struct drm_display_mode *pyr_vid_get_config_mode(struct drm_device* dev);
+
+#endif
diff --git a/drivers/staging/gma500/displays/tmd_cmd.h b/drivers/staging/gma500/displays/tmd_cmd.h
new file mode 100644
index 0000000..641e85e
--- /dev/null
+++ b/drivers/staging/gma500/displays/tmd_cmd.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2010 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicensen
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ * Thomas Eaton <thomas....@intel.com>
+ * Scott Rowe <scott....@intel.com>
+ */
+
+#ifndef TMD_CMD_H
+#define TMD_CMD_H
+
+extern void tmd_cmd_init(struct drm_device *dev, struct panel_funcs *p_funcs);
+extern struct drm_display_mode *tmd_cmd_get_config_mode(struct drm_device *dev);
+
+#endif
diff --git a/drivers/staging/gma500/displays/tmd_vid.h b/drivers/staging/gma500/displays/tmd_vid.h
new file mode 100644
index 0000000..7a5fa3b
--- /dev/null
+++ b/drivers/staging/gma500/displays/tmd_vid.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2010 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicensen
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ * Thomas Eaton <thomas....@intel.com>
+ * Scott Rowe <scott....@intel.com>
+*/
+
+#ifndef TMD_VID_H
+#define TMD_VID_H
+
+extern void tmd_vid_init(struct drm_device *dev, struct panel_funcs *p_funcs);
+extern struct drm_display_mode *tmd_vid_get_config_mode(struct drm_device *dev);
+
+#endif
diff --git a/drivers/staging/gma500/displays/tpo_cmd.h b/drivers/staging/gma500/displays/tpo_cmd.h
new file mode 100644
index 0000000..6105527
--- /dev/null
+++ b/drivers/staging/gma500/displays/tpo_cmd.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2010 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicensen
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ * Thomas Eaton <thomas....@intel.com>
+ * Scott Rowe <scott....@intel.com>
+*/
+
+#ifndef TPO_CMD_H
+#define TPO_CMD_H
+
+extern void tpo_cmd_init(struct drm_device *dev, struct panel_funcs *p_funcs);
+/* extern struct drm_display_mode * */
+/* tpo_cmd_get_config_mode(struct drm_device *dev); */
+
+#endif
diff --git a/drivers/staging/gma500/displays/tpo_vid.h b/drivers/staging/gma500/displays/tpo_vid.h
new file mode 100644
index 0000000..c24f057
--- /dev/null
+++ b/drivers/staging/gma500/displays/tpo_vid.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2010 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicensen
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ * Thomas Eaton <thomas....@intel.com>
+ * Scott Rowe <scott....@intel.com>
+ */
+
+#ifndef TPO_VID_H
+#define TPO_VID_H
+
+extern void tpo_vid_init(struct drm_device *dev, struct panel_funcs *p_funcs);
+
+#endif
diff --git a/drivers/staging/gma500/mdfld_dsi_dbi.c b/drivers/staging/gma500/mdfld_dsi_dbi.c
new file mode 100644
index 0000000..15055c8
--- /dev/null
+++ b/drivers/staging/gma500/mdfld_dsi_dbi.c
@@ -0,0 +1,872 @@
+/*
+ * Copyright © 2010 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ * jim liu <jim...@intel.com>
+ * Jackie Li<yaodo...@intel.com>
+ */
+
+#include "mdfld_dsi_dbi.h"
+#include "mdfld_dsi_dbi_dpu.h"
+#include "mdfld_dsi_pkg_sender.h"
+
+#include "psb_powermgmt.h"
+#include <linux/pm_runtime.h>
+
+int enable_gfx_rtpm;
+
+extern struct drm_device *gpDrmDevice;
+extern int gfxrtdelay;
+int enter_dsr;
+struct mdfld_dsi_dbi_output *gdbi_output;
+extern bool gbgfxsuspended;
+extern int gfxrtdelay;
+
+#ifdef CONFIG_GFX_RTPM
+static void psb_runtimepm_wq_handler(struct work_struct *work);
+DECLARE_DELAYED_WORK(rtpm_work, psb_runtimepm_wq_handler);
+
+void psb_runtimepm_wq_handler(struct work_struct *work)
+{
+ struct drm_psb_private *dev_priv = gpDrmDevice->dev_private;
+
+ if (drm_psb_ospm && !enable_gfx_rtpm) {
+ pr_info("Enable GFX runtime_pm\n");
+ dev_priv->rpm_enabled = 1;
+ enable_gfx_rtpm = 1;
+
+ pm_runtime_enable(&gpDrmDevice->pdev->dev);
+ pm_runtime_set_active(&gpDrmDevice->pdev->dev);
+
+ pm_runtime_allow(&gpDrmDevice->pdev->dev);
+ }
+}
+#endif
+
+
+/*
+ * set refreshing area
+ */
+int mdfld_dsi_dbi_update_area(struct mdfld_dsi_dbi_output *dbi_output,
+ u16 x1, u16 y1, u16 x2, u16 y2)
+{
+ struct mdfld_dsi_pkg_sender *sender =
+ mdfld_dsi_encoder_get_pkg_sender(&dbi_output->base);
+ u8 param[4];
+ u8 cmd;
+ int err;
+
+ if (!sender) {
+ WARN_ON(1);


+ return -EINVAL;
+ }
+

+ /*set column*/
+ cmd = set_column_address;
+ param[0] = x1 >> 8;
+ param[1] = x1;
+ param[2] = x2 >> 8;
+ param[3] = x2;
+
+ err = mdfld_dsi_send_dcs(sender,
+ cmd,
+ param,
+ 4,
+ CMD_DATA_SRC_SYSTEM_MEM,
+ MDFLD_DSI_QUEUE_PACKAGE);
+ if (err) {
+ dev_err(sender->dev->dev, "DCS 0x%x sent failed\n", cmd);
+ goto err_out;
+ }
+
+ /*set page*/
+ cmd = set_page_addr;
+ param[0] = y1 >> 8;
+ param[1] = y1;
+ param[2] = y2 >> 8;
+ param[3] = y2;
+
+ err = mdfld_dsi_send_dcs(sender,
+ cmd,
+ param,
+ 4,
+ CMD_DATA_SRC_SYSTEM_MEM,
+ MDFLD_DSI_QUEUE_PACKAGE);
+ if (err) {
+ dev_err(sender->dev->dev, "DCS 0x%x sent failed\n", cmd);
+ goto err_out;
+ }
+
+ /*update screen*/
+ err = mdfld_dsi_send_dcs(sender,
+ write_mem_start,
+ NULL,
+ 0,
+ CMD_DATA_SRC_PIPE,
+ MDFLD_DSI_QUEUE_PACKAGE);
+ if (err) {
+ dev_err(sender->dev->dev, "DCS 0x%x sent failed\n", cmd);
+ goto err_out;
+ }
+ mdfld_dsi_cmds_kick_out(sender);
+err_out:
+ return err;
+}
+
+/*
+ * set panel's power state
+ */
+int mdfld_dsi_dbi_update_power(struct mdfld_dsi_dbi_output *dbi_output,
+ int mode)
+{
+ struct drm_device *dev = dbi_output->dev;
+ struct drm_psb_private *dev_priv = dev->dev_private;
+ struct mdfld_dsi_pkg_sender *sender =
+ mdfld_dsi_encoder_get_pkg_sender(&dbi_output->base);
+ u8 param = 0;
+ u32 err = 0;
+
+ if (!dev_priv->dispstatus && mode != DRM_MODE_DPMS_ON) {
+ dev_err(dev->dev, "%s: already OFF ignoring\n", __func__);
+ return 0;
+ }
+ if (dev_priv->dispstatus && mode == DRM_MODE_DPMS_ON) {
+ dev_err(dev->dev, "%s: already ON ignoring\n", __func__);


+ return 0;
+ }
+

+ if (!sender) {
+ WARN_ON(1);


+ return -EINVAL;
+ }
+

+ if (mode == DRM_MODE_DPMS_ON) {
+ /*exit sleep mode*/
+ err = mdfld_dsi_send_dcs(sender,
+ exit_sleep_mode,
+ NULL,
+ 0,
+ CMD_DATA_SRC_SYSTEM_MEM,
+ MDFLD_DSI_QUEUE_PACKAGE);
+ if (err) {
+ dev_err(dev->dev, "DCS 0x%x sent failed\n",
+ exit_sleep_mode);
+ goto power_err;
+ }
+
+ /*set display on*/
+ err = mdfld_dsi_send_dcs(sender,
+ set_display_on,
+ NULL,
+ 0,
+ CMD_DATA_SRC_SYSTEM_MEM,
+ MDFLD_DSI_QUEUE_PACKAGE);
+ if (err) {
+ dev_err(dev->dev, "DCS 0x%x sent failed\n",
+ set_display_on);
+ goto power_err;
+ }
+
+ /* set tear effect on */
+ err = mdfld_dsi_send_dcs(sender,
+ set_tear_on,
+ &param,
+ 1,
+ CMD_DATA_SRC_SYSTEM_MEM,
+ MDFLD_DSI_QUEUE_PACKAGE);
+ if (err) {
+ dev_err(dev->dev, "DCS 0x%x sent failed\n",
+ set_tear_on);
+ goto power_err;
+ }
+
+ /**
+ * FIXME: remove this later
+ */
+ err = mdfld_dsi_send_dcs(sender,
+ write_mem_start,
+ NULL,
+ 0,
+ CMD_DATA_SRC_PIPE,
+ MDFLD_DSI_QUEUE_PACKAGE);
+ if (err) {
+ dev_err(dev->dev, "DCS 0x%x sent failed\n",
+ set_display_on);
+ goto power_err;
+ }
+ } else {
+ /*set tear effect off */
+ err = mdfld_dsi_send_dcs(sender,
+ set_tear_off,
+ NULL,
+ 0,
+ CMD_DATA_SRC_SYSTEM_MEM,
+ MDFLD_DSI_QUEUE_PACKAGE);
+ if (err) {
+ dev_err(dev->dev, "DCS 0x%x sent failed\n",
+ set_tear_off);
+ goto power_err;
+ }
+
+ /*set display off*/
+ err = mdfld_dsi_send_dcs(sender,
+ set_display_off,
+ NULL,
+ 0,
+ CMD_DATA_SRC_SYSTEM_MEM,
+ MDFLD_DSI_QUEUE_PACKAGE);
+ if (err) {
+ dev_err(dev->dev, "DCS 0x%x sent failed\n",
+ set_display_off);
+ goto power_err;
+ }
+
+ /*enter sleep mode*/
+ err = mdfld_dsi_send_dcs(sender,
+ enter_sleep_mode,
+ NULL,
+ 0,
+ CMD_DATA_SRC_SYSTEM_MEM,
+ MDFLD_DSI_QUEUE_PACKAGE);
+ if (err) {
+ dev_err(dev->dev, "DCS 0x%x sent failed\n",
+ enter_sleep_mode);
+ goto power_err;
+ }
+ }
+ mdfld_dsi_cmds_kick_out(sender);
+power_err:
+ return err;
+}
+
+/*
+ * send a generic DCS command with a parameter list
+ */
+int mdfld_dsi_dbi_send_dcs(struct mdfld_dsi_dbi_output *dbi_output,
+ u8 dcs, u8 *param, u32 num, u8 data_src)
+{
+ struct mdfld_dsi_pkg_sender *sender =
+ mdfld_dsi_encoder_get_pkg_sender(&dbi_output->base);
+ int ret;
+
+ if (!sender) {
+ WARN_ON(1);


+ return -EINVAL;
+ }
+

+ ret = mdfld_dsi_send_dcs(sender,
+ dcs,
+ param,
+ num,
+ data_src,
+ MDFLD_DSI_SEND_PACKAGE);
+


+ return ret;
+}
+

+
+/*
+ * Enter DSR
+ */
+void mdfld_dsi_dbi_enter_dsr(struct mdfld_dsi_dbi_output *dbi_output, int pipe)
+{
+ u32 reg_val;
+ struct drm_device *dev = dbi_output->dev;
+ struct drm_psb_private *dev_priv = dev->dev_private;
+ struct drm_crtc *crtc = dbi_output->base.base.crtc;
+ struct psb_intel_crtc *psb_crtc = (crtc) ?
+ to_psb_intel_crtc(crtc) : NULL;
+ u32 dpll_reg = MRST_DPLL_A;
+ u32 pipeconf_reg = PIPEACONF;
+ u32 dspcntr_reg = DSPACNTR;
+
+ dev_priv->is_in_idle = true;
+
+ if (!dbi_output)
+ return;
+
+ gdbi_output = dbi_output;
+ if ((dbi_output->mode_flags & MODE_SETTING_ON_GOING) ||
+ (psb_crtc && psb_crtc->mode_flags & MODE_SETTING_ON_GOING))
+ return;
+
+ if (pipe == 2) {
+ dpll_reg = MRST_DPLL_A;
+ pipeconf_reg = PIPECCONF;
+ dspcntr_reg = DSPCCNTR;
+ }
+
+ if (!gma_power_begin(dev, true)) {
+ dev_err(dev->dev, "hw begin failed\n");
+ return;
+ }
+ /*disable te interrupts. */
+ mdfld_disable_te(dev, pipe);
+
+ /*disable plane*/
+ reg_val = REG_READ(dspcntr_reg);
+ if (!(reg_val & DISPLAY_PLANE_ENABLE)) {
+ REG_WRITE(dspcntr_reg, reg_val & ~DISPLAY_PLANE_ENABLE);
+ REG_READ(dspcntr_reg);
+ }
+ /*disable pipe*/
+ reg_val = REG_READ(pipeconf_reg);
+ if (!(reg_val & DISPLAY_PLANE_ENABLE)) {
+ reg_val &= ~DISPLAY_PLANE_ENABLE;
+ reg_val |= (PIPECONF_PLANE_OFF | PIPECONF_CURSOR_OFF);
+ REG_WRITE(pipeconf_reg, reg_val);
+ REG_READ(pipeconf_reg);
+ mdfldWaitForPipeDisable(dev, pipe);
+ }
+
+ /*disable DPLL*/
+ reg_val = REG_READ(dpll_reg);
+ if (!(reg_val & DPLL_VCO_ENABLE)) {
+ reg_val &= ~DPLL_VCO_ENABLE;
+ REG_WRITE(dpll_reg, reg_val);
+ REG_READ(dpll_reg);
+ udelay(500);
+ }
+
+ gma_power_end(dev);
+ dbi_output->mode_flags |= MODE_SETTING_IN_DSR;
+ if (pipe == 2) {
+ enter_dsr = 1;
+ /* pm_schedule_suspend(&dev->pdev->dev, gfxrtdelay); */
+ }
+}
+
+#ifndef CONFIG_MDFLD_DSI_DPU
+static void mdfld_dbi_output_exit_dsr(struct mdfld_dsi_dbi_output *dbi_output,
+ int pipe, void *p_surfaceAddr, bool check_hw_on_only)
+{
+ struct drm_device *dev = dbi_output->dev;
+ struct drm_psb_private *dev_priv = dev->dev_private;
+ struct drm_crtc *crtc = dbi_output->base.base.crtc;
+ struct psb_intel_crtc *psb_crtc = (crtc) ?
+ to_psb_intel_crtc(crtc) : NULL;
+ u32 reg_val;
+ u32 dpll_reg = MRST_DPLL_A;
+ u32 pipeconf_reg = PIPEACONF;
+ u32 dspcntr_reg = DSPACNTR;
+ u32 dspsurf_reg = DSPASURF;
+ u32 reg_offset = 0;
+
+ /*if mode setting on-going, back off*/
+ if ((dbi_output->mode_flags & MODE_SETTING_ON_GOING) ||
+ (psb_crtc && psb_crtc->mode_flags & MODE_SETTING_ON_GOING))
+ return;
+
+ if (pipe == 2) {
+ dpll_reg = MRST_DPLL_A;
+ pipeconf_reg = PIPECCONF;
+ dspcntr_reg = DSPCCNTR;
+ dspsurf_reg = DSPCSURF;
+ reg_offset = MIPIC_REG_OFFSET;
+ }
+
+ if (check_hw_on_only) {
+ if (0/* FIXME!ospm_power_is_hw_on(_DISPLAY_ISLAND)*/) {
+ dev_err(dev->dev, "hw begin failed\n");
+ return;
+ }
+ } else if (!gma_power_begin(dev, true)) {
+ dev_err(dev->dev, "hw begin failed\n");
+ return;
+ }
+
+ /*enable DPLL*/
+ reg_val = REG_READ(dpll_reg);
+ if (!(reg_val & DPLL_VCO_ENABLE)) {
+
+ if (reg_val & MDFLD_PWR_GATE_EN) {
+ reg_val &= ~MDFLD_PWR_GATE_EN;
+ REG_WRITE(dpll_reg, reg_val);
+ REG_READ(dpll_reg);
+ udelay(500);
+ }
+
+ reg_val |= DPLL_VCO_ENABLE;
+ REG_WRITE(dpll_reg, reg_val);
+ REG_READ(dpll_reg);
+ udelay(500);
+
+ /* Add timeout */
+ while (!(REG_READ(pipeconf_reg) & PIPECONF_DSIPLL_LOCK))
+ cpu_relax();
+ }
+
+ /*enable pipe*/
+ reg_val = REG_READ(pipeconf_reg);
+ if (!(reg_val & PIPEACONF_ENABLE)) {
+ reg_val |= PIPEACONF_ENABLE;
+ REG_WRITE(pipeconf_reg, reg_val);
+ REG_READ(pipeconf_reg);
+ udelay(500);
+ mdfldWaitForPipeEnable(dev, pipe);
+ }
+
+ /*enable plane*/
+ reg_val = REG_READ(dspcntr_reg);
+ if (!(reg_val & DISPLAY_PLANE_ENABLE)) {
+ reg_val |= DISPLAY_PLANE_ENABLE;
+ REG_WRITE(dspcntr_reg, reg_val);
+ REG_READ(dspcntr_reg);
+ udelay(500);
+ }
+
+ /* update the surface base address. */
+ if (p_surfaceAddr)
+ REG_WRITE(dspsurf_reg, *((u32 *)p_surfaceAddr));
+
+ if (!check_hw_on_only)
+ gma_power_end(dev);
+
+ /*enable TE interrupt on this pipe*/
+ mdfld_enable_te(dev, pipe);
+
+ /*clean IN_DSR flag*/
+ dbi_output->mode_flags &= ~MODE_SETTING_IN_DSR;
+}
+
+/*
+ * Exit from DSR
+ */
+void mdfld_dsi_dbi_exit_dsr(struct drm_device *dev, u32 update_src,
+ void *p_surfaceAddr, bool check_hw_on_only)
+{
+ struct drm_psb_private *dev_priv = dev->dev_private;
+ struct mdfld_dbi_dsr_info *dsr_info = dev_priv->dbi_dsr_info;
+ struct mdfld_dsi_dbi_output **dbi_output;
+ int i;
+
+ dev_priv->is_in_idle = false;
+ dbi_output = dsr_info->dbi_outputs;
+
+#ifdef CONFIG_PM_RUNTIME
+ if (!enable_gfx_rtpm) {
+/* pm_runtime_allow(&gpDrmDevice->pdev->dev); */
+/* schedule_delayed_work(&rtpm_work, 120 * 1000); */
+ }
+#endif
+
+ /*for each output, exit dsr*/
+ for (i = 0; i < dsr_info->dbi_output_num; i++) {
+ /*if panel has been turned off, skip*/
+ if (!dbi_output[i]->dbi_panel_on)
+ continue;
+ if (dbi_output[i]->mode_flags & MODE_SETTING_IN_DSR) {
+ enter_dsr = 0;
+ mdfld_dbi_output_exit_dsr(dbi_output[i], dbi_output[i]->channel_num ? 2 : 0, p_surfaceAddr, check_hw_on_only);
+ }
+ }
+ dev_priv->dsr_fb_update |= update_src;
+}
+
+static bool mdfld_dbi_is_in_dsr(struct drm_device *dev)
+{
+ if (REG_READ(MRST_DPLL_A) & DPLL_VCO_ENABLE)
+ return false;
+ if ((REG_READ(PIPEACONF) & PIPEACONF_ENABLE) ||
+ (REG_READ(PIPECCONF) & PIPEACONF_ENABLE))
+ return false;
+ if ((REG_READ(DSPACNTR) & DISPLAY_PLANE_ENABLE) ||
+ (REG_READ(DSPCCNTR) & DISPLAY_PLANE_ENABLE))
+ return false;
+
+ return true;
+}
+
+/* Perodically update dbi panel */
+void mdfld_dbi_update_panel(struct drm_device *dev, int pipe)
+{
+ struct drm_psb_private *dev_priv = dev->dev_private;
+ struct mdfld_dbi_dsr_info *dsr_info = dev_priv->dbi_dsr_info;
+ struct mdfld_dsi_dbi_output **dbi_outputs;
+ struct mdfld_dsi_dbi_output *dbi_output;
+ int i;
+ int enter_dsr = 0;
+ u32 damage_mask = 0;
+
+ dbi_outputs = dsr_info->dbi_outputs;
+ dbi_output = pipe ? dbi_outputs[1] : dbi_outputs[0];
+
+ if (!dbi_output)
+ return;
+
+ if (pipe == 0)
+ damage_mask = dev_priv->dsr_fb_update & (MDFLD_DSR_DAMAGE_MASK_0);
+ else if (pipe == 2)
+ damage_mask = dev_priv->dsr_fb_update & (MDFLD_DSR_DAMAGE_MASK_2);
+ else
+ return;
+
+ /*if FB is damaged and panel is on update on-panel FB*/
+ if (damage_mask && dbi_output->dbi_panel_on) {
+ dbi_output->dsr_fb_update_done = false;
+
+ if (dbi_output->p_funcs->update_fb)
+ dbi_output->p_funcs->update_fb(dbi_output, pipe);
+
+ if (dev_priv->dsr_enable && dbi_output->dsr_fb_update_done)
+ dev_priv->dsr_fb_update &= ~damage_mask;
+
+ /*clean IN_DSR flag*/
+ dbi_output->mode_flags &= ~MODE_SETTING_IN_DSR;
+
+ dbi_output->dsr_idle_count = 0;
+ } else {
+ dbi_output->dsr_idle_count++;
+ }
+
+ /*try to enter DSR*/
+ if (dbi_outputs[0]->dsr_idle_count > 1
+ && dbi_outputs[1]->dsr_idle_count > 1) {
+ for (i = 0; i < dsr_info->dbi_output_num; i++) {
+ if (!mdfld_dbi_is_in_dsr(dev) &&
+ !(dbi_outputs[i]->mode_flags & MODE_SETTING_ON_GOING)) {
+ mdfld_dsi_dbi_enter_dsr(dbi_outputs[i],
+ dbi_outputs[i]->channel_num ? 2 : 0);
+#if 0
+ enter_dsr = 1;
+ pr_err("%s: enter_dsr = 1\n", __func__);
+#endif
+ }
+ }
+ /*schedule rpm suspend after gfxrtdelay*/
+#ifdef CONFIG_GFX_RTPM
+ if (!dev_priv->rpm_enabled
+ || !enter_dsr
+ /* || (REG_READ(HDMIB_CONTROL) & HDMIB_PORT_EN) */
+ || pm_schedule_suspend(&dev->pdev->dev, gfxrtdelay))
+ dev_warn(dev->dev,
+ "Runtime PM schedule suspend failed, rpm %d\n",
+ dev_priv->rpm_enabled);
+#endif
+ }
+}
+
+/*timers for DSR*/
+static void mdfld_dsi_dbi_dsr_timer_func(unsigned long data)
+{
+ struct drm_device *dev = (struct drm_device *)data;
+ struct drm_psb_private *dev_priv = dev->dev_private;
+ struct mdfld_dbi_dsr_info *dsr_info = dev_priv->dbi_dsr_info;
+ struct timer_list *dsr_timer = &dsr_info->dsr_timer;
+ unsigned long flags;
+
+ mdfld_dbi_update_panel(dev, 0);
+
+ if (dsr_info->dsr_idle_count > 1)
+ return;
+
+ spin_lock_irqsave(&dsr_info->dsr_timer_lock, flags);
+ if (!timer_pending(dsr_timer)) {
+ dsr_timer->expires = jiffies + MDFLD_DSR_DELAY;
+ add_timer(dsr_timer);
+ }
+ spin_unlock_irqrestore(&dsr_info->dsr_timer_lock, flags);
+}
+
+static int mdfld_dsi_dbi_dsr_timer_init(struct drm_device *dev)
+{
+ struct drm_psb_private *dev_priv = dev->dev_private;
+ struct mdfld_dbi_dsr_info *dsr_info = dev_priv->dbi_dsr_info;
+ struct timer_list *dsr_timer = &dsr_info->dsr_timer;
+ unsigned long flags;
+
+ spin_lock_init(&dsr_info->dsr_timer_lock);
+ spin_lock_irqsave(&dsr_info->dsr_timer_lock, flags);
+
+ init_timer(dsr_timer);
+
+ dsr_timer->data = (unsigned long)dev;
+ dsr_timer->function = mdfld_dsi_dbi_dsr_timer_func;
+ dsr_timer->expires = jiffies + MDFLD_DSR_DELAY;
+
+ spin_unlock_irqrestore(&dsr_info->dsr_timer_lock, flags);


+ return 0;
+}
+

+void mdfld_dbi_dsr_timer_start(struct mdfld_dbi_dsr_info *dsr_info)
+{
+ struct timer_list *dsr_timer = &dsr_info->dsr_timer;
+ unsigned long flags;
+
+ spin_lock_irqsave(&dsr_info->dsr_timer_lock, flags);
+ if (!timer_pending(dsr_timer)) {
+ dsr_timer->expires = jiffies + MDFLD_DSR_DELAY;
+ add_timer(dsr_timer);
+ }
+ spin_unlock_irqrestore(&dsr_info->dsr_timer_lock, flags);
+}
+
+int mdfld_dbi_dsr_init(struct drm_device *dev)
+{
+ struct drm_psb_private *dev_priv = dev->dev_private;
+ struct mdfld_dbi_dsr_info *dsr_info = dev_priv->dbi_dsr_info;
+
+ if (!dsr_info || IS_ERR(dsr_info)) {
+ dsr_info = kzalloc(sizeof(struct mdfld_dbi_dsr_info),
+ GFP_KERNEL);
+ if (!dsr_info) {
+ dev_err(dev->dev, "No memory\n");
+ return -ENOMEM;
+ }
+ dev_priv->dbi_dsr_info = dsr_info;


+ }
+ return 0;
+}
+

+void mdfld_dbi_dsr_exit(struct drm_device *dev)
+{
+ struct drm_psb_private *dev_priv = dev->dev_private;
+ struct mdfld_dbi_dsr_info *dsr_info = dev_priv->dbi_dsr_info;
+
+ if (!dsr_info) {
+ del_timer_sync(&dsr_info->dsr_timer);
+ kfree(dsr_info);
+ dev_priv->dbi_dsr_info = NULL;
+ }
+}
+#endif
+
+void mdfld_dsi_controller_dbi_init(struct mdfld_dsi_config *dsi_config,
+ int pipe)
+{
+ struct drm_device *dev = dsi_config->dev;
+ u32 reg_offset = pipe ? MIPIC_REG_OFFSET : 0;
+ int lane_count = dsi_config->lane_count;
+ u32 val = 0;
+
+ dev_dbg(dev->dev, "Init DBI interface on pipe %d...\n", pipe);
+
+ /*un-ready device*/
+ REG_WRITE((MIPIA_DEVICE_READY_REG + reg_offset), 0x00000000);
+
+ /*init dsi adapter before kicking off*/
+ REG_WRITE((MIPIA_CONTROL_REG + reg_offset), 0x00000018);
+
+ /*TODO: figure out how to setup these registers*/
+ REG_WRITE((MIPIA_DPHY_PARAM_REG + reg_offset), 0x150c3408);
+ REG_WRITE((MIPIA_CLK_LANE_SWITCH_TIME_CNT_REG + reg_offset),
+ 0x000a0014);
+ REG_WRITE((MIPIA_DBI_BW_CTRL_REG + reg_offset), 0x00000400);
+ REG_WRITE((MIPIA_DBI_FIFO_THROTTLE_REG + reg_offset), 0x00000001);
+ REG_WRITE((MIPIA_HS_LS_DBI_ENABLE_REG + reg_offset), 0x00000000);
+
+ /*enable all interrupts*/
+ REG_WRITE((MIPIA_INTR_EN_REG + reg_offset), 0xffffffff);
+ /*max value: 20 clock cycles of txclkesc*/
+ REG_WRITE((MIPIA_TURN_AROUND_TIMEOUT_REG + reg_offset), 0x0000001f);
+ /*min 21 txclkesc, max: ffffh*/
+ REG_WRITE((MIPIA_DEVICE_RESET_TIMER_REG + reg_offset), 0x0000ffff);
+ /*min: 7d0 max: 4e20*/
+ REG_WRITE((MIPIA_INIT_COUNT_REG + reg_offset), 0x00000fa0);
+
+ /*set up func_prg*/
+ val |= lane_count;
+ val |= (dsi_config->channel_num << DSI_DBI_VIRT_CHANNEL_OFFSET);
+ val |= DSI_DBI_COLOR_FORMAT_OPTION2;
+ REG_WRITE((MIPIA_DSI_FUNC_PRG_REG + reg_offset), val);
+
+ REG_WRITE((MIPIA_HS_TX_TIMEOUT_REG + reg_offset), 0x3fffff);
+ REG_WRITE((MIPIA_LP_RX_TIMEOUT_REG + reg_offset), 0xffff);
+
+ /*de-assert dbi_stall when half of DBI FIFO is empty*/
+ /* REG_WRITE((MIPIA_DBI_FIFO_THROTTLE_REG + reg_offset), 0x00000000); */
+
+ REG_WRITE((MIPIA_HIGH_LOW_SWITCH_COUNT_REG + reg_offset), 0x46);
+ REG_WRITE((MIPIA_EOT_DISABLE_REG + reg_offset), 0x00000000);
+ REG_WRITE((MIPIA_LP_BYTECLK_REG + reg_offset), 0x00000004);
+ REG_WRITE((MIPIA_DEVICE_READY_REG + reg_offset), 0x00000001);
+}
+
+#if 0
+/*DBI encoder helper funcs*/
+static const struct drm_encoder_helper_funcs mdfld_dsi_dbi_helper_funcs = {
+ .dpms = mdfld_dsi_dbi_dpms,
+ .mode_fixup = mdfld_dsi_dbi_mode_fixup,
+ .prepare = mdfld_dsi_dbi_prepare,
+ .mode_set = mdfld_dsi_dbi_mode_set,
+ .commit = mdfld_dsi_dbi_commit,
+};
+
+/*DBI encoder funcs*/
+static const struct drm_encoder_funcs mdfld_dsi_dbi_encoder_funcs = {
+ .destroy = drm_encoder_cleanup,
+};
+
+#endif
+
+static int mdfld_dbi_panel_reset(struct mdfld_dsi_dbi_output *output)
+{
+ unsigned gpio;
+ int ret;
+
+ switch (output->channel_num) {
+ case 0:
+ gpio = 128;
+ break;
+ case 1:
+ gpio = 34;
+ break;
+ default:
+ pr_err("Invalid output\n");


+ return -EINVAL;
+ }
+

+ ret = gpio_request(gpio, "gfx");
+ if (ret) {
+ pr_err("gpio_rqueset failed\n");


+ return ret;
+ }
+

+ ret = gpio_direction_output(gpio, 1);
+ if (ret) {
+ pr_err("gpio_direction_output failed\n");
+ goto gpio_error;
+ }
+ gpio_get_value(128);
+gpio_error:
+ if (gpio_is_valid(gpio))
+ gpio_free(gpio);
+


+ return ret;
+}
+

+/*
+ * Init DSI DBI encoder.
+ * Allocate an mdfld_dsi_encoder and attach it to given @dsi_connector
+ * return pointer of newly allocated DBI encoder, NULL on error
+ */
+struct mdfld_dsi_encoder *mdfld_dsi_dbi_init(struct drm_device *dev,
+ struct mdfld_dsi_connector *dsi_connector,
+ struct panel_funcs *p_funcs)
+{
+ struct drm_psb_private *dev_priv = dev->dev_private;
+ struct mdfld_dsi_dbi_output *dbi_output = NULL;
+ struct mdfld_dsi_config *dsi_config;
+ struct drm_connector *connector = NULL;
+ struct drm_encoder *encoder = NULL;
+ struct drm_display_mode *fixed_mode = NULL;
+ struct psb_gtt *pg = dev_priv ? (dev_priv->pg) : NULL;
+
+#ifdef CONFIG_MDFLD_DSI_DPU
+ struct mdfld_dbi_dpu_info *dpu_info = dev_priv ? (dev_priv->dbi_dpu_info) : NULL;
+#else
+ struct mdfld_dbi_dsr_info *dsr_info = dev_priv ? (dev_priv->dbi_dsr_info) : NULL;
+#endif
+ int ret;
+
+ if (!pg || !dsi_connector) {
+ WARN_ON(1);
+ return NULL;
+ }
+
+ dbi_output = kzalloc(sizeof(struct mdfld_dsi_dbi_output), GFP_KERNEL);
+ if (!dbi_output) {
+ dev_err(dev->dev, "No memory\n");
+ return NULL;
+ }
+
+ if (dsi_connector->pipe == 0) {
+ dbi_output->channel_num = 0;
+ dev_priv->dbi_output = dbi_output;
+ } else if (dsi_connector->pipe == 2) {
+ dbi_output->channel_num = 1;
+ dev_priv->dbi_output2 = dbi_output;
+ } else {
+ dev_err(dev->dev, "only support 2 DSI outputs\n");
+ goto out_err1;
+ }
+
+ dbi_output->dev = dev;
+ dbi_output->p_funcs = p_funcs;
+
+ /*panel reset*/
+ ret = mdfld_dbi_panel_reset(dbi_output);
+ if (ret) {
+ dev_err(dev->dev, "reset panel error\n");
+ goto out_err1;
+ }
+
+ /*TODO: get panel info from DDB*/
+
+ /*get fixed mode*/
+ dsi_config = mdfld_dsi_get_config(dsi_connector);
+ fixed_mode = dsi_config->fixed_mode;
+
+ dbi_output->panel_fixed_mode = fixed_mode;
+
+ /*create drm encoder object*/
+ connector = &dsi_connector->base.base;
+ encoder = &dbi_output->base.base;
+ drm_encoder_init(dev,
+ encoder,
+ p_funcs->encoder_funcs,
+ DRM_MODE_ENCODER_MIPI);
+ drm_encoder_helper_add(encoder, p_funcs->encoder_helper_funcs);
+
+ /*attach to given connector*/
+ drm_mode_connector_attach_encoder(connector, encoder);
+
+ /*set possible crtcs and clones*/
+ if (dsi_connector->pipe) {
+ encoder->possible_crtcs = (1 << 2);
+ encoder->possible_clones = (1 << 1);
+ } else {
+ encoder->possible_crtcs = (1 << 0);
+ encoder->possible_clones = (1 << 0);
+ }
+
+ dev_priv->dsr_fb_update = 0;
+ dev_priv->dsr_enable = false;
+ dev_priv->exit_idle = mdfld_dsi_dbi_exit_dsr;
+#if defined(CONFIG_MDFLD_DSI_DPU) || defined(CONFIG_MDFLD_DSI_DSR)
+ dev_priv->dsr_enable_config = false;
+#endif /*CONFIG_MDFLD_DSI_DSR*/
+
+ dbi_output->first_boot = true;
+ dbi_output->mode_flags = MODE_SETTING_IN_ENCODER;
+
+#ifdef CONFIG_MDFLD_DSI_DPU
+ /*add this output to dpu_info*/
+ if (dsi_connector->pipe == 0)
+ dpu_info->dbi_outputs[0] = dbi_output;
+ } else {
+ dpu_info->dbi_outputs[1] = dbi_output;
+ }
+ dpu_info->dbi_output_num++;
+#else /*CONFIG_MDFLD_DSI_DPU*/
+ /*add this output to dsr_info*/
+ if (dsi_connector->pipe == 0)
+ dsr_info->dbi_outputs[0] = dbi_output;
+ else
+ dsr_info->dbi_outputs[1] = dbi_output;
+ dsr_info->dbi_output_num++;
+#endif
+ return &dbi_output->base;
+out_err1:
+ kfree(dbi_output);
+ return NULL;
+}
diff --git a/drivers/staging/gma500/mdfld_dsi_dbi.h b/drivers/staging/gma500/mdfld_dsi_dbi.h
new file mode 100644
index 0000000..5b04951
--- /dev/null
+++ b/drivers/staging/gma500/mdfld_dsi_dbi.h
@@ -0,0 +1,188 @@
+/*
+ * Copyright © 2010 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ * jim liu <jim...@intel.com>
+ * Jackie Li<yaodo...@intel.com>
+ */
+
+#ifndef __MDFLD_DSI_DBI_H__
+#define __MDFLD_DSI_DBI_H__
+
+#include <linux/backlight.h>
+#include <linux/version.h>
+#include <drm/drmP.h>
+#include <drm/drm.h>
+#include <drm/drm_crtc.h>
+#include <drm/drm_edid.h>
+
+#include "psb_drv.h"
+#include "psb_intel_drv.h"
+#include "psb_intel_reg.h"
+#include "psb_powermgmt.h"
+
+#include "mdfld_dsi_output.h"
+#include "mdfld_output.h"
+
+#define DRM_MODE_ENCODER_MIPI 5
+
+
+/*
+ * DBI encoder which inherits from mdfld_dsi_encoder
+ */
+struct mdfld_dsi_dbi_output {
+ struct mdfld_dsi_encoder base;
+ struct drm_display_mode *panel_fixed_mode;
+ u8 last_cmd;
+ u8 lane_count;
+ u8 channel_num;
+ struct drm_device *dev;
+
+ /* Backlight operations */
+
+ /* DSR timer */
+ spinlock_t dsr_timer_lock;
+ struct timer_list dsr_timer;
+ void(*dsi_timer_func)(unsigned long data);
+ u32 dsr_idle_count;
+ bool dsr_fb_update_done;
+
+ /* Mode setting flags */
+ u32 mode_flags;
+
+ /* Panel status */
+ bool dbi_panel_on;
+ bool first_boot;
+ struct panel_funcs *p_funcs;
+};
+
+#define MDFLD_DSI_DBI_OUTPUT(dsi_encoder) \
+ container_of(dsi_encoder, struct mdfld_dsi_dbi_output, base)
+
+struct mdfld_dbi_dsr_info {
+ int dbi_output_num;
+ struct mdfld_dsi_dbi_output *dbi_outputs[2];
+
+ spinlock_t dsr_timer_lock;
+ struct timer_list dsr_timer;
+ u32 dsr_idle_count;
+};
+
+#define DBI_CB_TIMEOUT_COUNT 0xffff
+
+/* DCS commands */
+#define enter_sleep_mode 0x10
+#define exit_sleep_mode 0x11
+#define set_display_off 0x28
+#define set_dispaly_on 0x29
+#define set_column_address 0x2a
+#define set_page_addr 0x2b
+#define write_mem_start 0x2c
+
+/* Offsets */
+#define CMD_MEM_ADDR_OFFSET 0
+
+#define CMD_DATA_SRC_SYSTEM_MEM 0
+#define CMD_DATA_SRC_PIPE 1
+
+static inline int mdfld_dsi_dbi_fifo_ready(struct mdfld_dsi_dbi_output *dbi_output)
+{
+ struct drm_device *dev = dbi_output->dev;
+ u32 retry = DBI_CB_TIMEOUT_COUNT;
+ int reg_offset = (dbi_output->channel_num == 1) ? MIPIC_REG_OFFSET : 0;


+ int ret = 0;

+
+ /* Query the dbi fifo status*/
+ while (retry--) {
+ if (REG_READ(MIPIA_GEN_FIFO_STAT_REG + reg_offset) & (1 << 27))
+ break;
+ }
+
+ if (!retry) {
+ DRM_ERROR("Timeout waiting for DBI FIFO empty\n");
+ ret = -EAGAIN;
+ }


+ return ret;
+}
+

+static inline int mdfld_dsi_dbi_cmd_sent(struct mdfld_dsi_dbi_output *dbi_output)
+{
+ struct drm_device *dev = dbi_output->dev;
+ u32 retry = DBI_CB_TIMEOUT_COUNT;
+ int reg_offset = (dbi_output->channel_num == 1) ? MIPIC_REG_OFFSET : 0;


+ int ret = 0;

+
+ /* Query the command execution status */
+ while (retry--)
+ if (!(REG_READ(MIPIA_CMD_ADD_REG + reg_offset) & (1 << 10)))
+ break;
+
+ if (!retry) {
+ DRM_ERROR("Timeout waiting for DBI command status\n");
+ ret = -EAGAIN;
+ }
+


+ return ret;
+}
+

+static inline int mdfld_dsi_dbi_cb_ready(struct mdfld_dsi_dbi_output *dbi_output)
+{


+ int ret = 0;

+
+ /* Query the command execution status*/
+ ret = mdfld_dsi_dbi_cmd_sent(dbi_output);
+ if (ret) {
+ DRM_ERROR("Peripheral is busy\n");
+ ret = -EAGAIN;
+ }
+ /* Query the dbi fifo status*/
+ ret = mdfld_dsi_dbi_fifo_ready(dbi_output);
+ if (ret) {
+ DRM_ERROR("DBI FIFO is not empty\n");
+ ret = -EAGAIN;
+ }


+ return ret;
+}
+

+extern void mdfld_dsi_dbi_output_init(struct drm_device *dev,
+ struct psb_intel_mode_device *mode_dev, int pipe);
+extern void mdfld_dsi_dbi_exit_dsr(struct drm_device *dev, u32 update_src,
+ void *p_surfaceAddr, bool check_hw_on_only);
+extern void mdfld_dsi_dbi_enter_dsr(struct mdfld_dsi_dbi_output *dbi_output,
+ int pipe);
+extern int mdfld_dbi_dsr_init(struct drm_device *dev);
+extern void mdfld_dbi_dsr_exit(struct drm_device *dev);
+extern void mdfld_dbi_dsr_timer_start(struct mdfld_dbi_dsr_info *dsr_info);
+extern struct mdfld_dsi_encoder *mdfld_dsi_dbi_init(struct drm_device *dev,
+ struct mdfld_dsi_connector *dsi_connector,
+ struct panel_funcs *p_funcs);
+extern int mdfld_dsi_dbi_send_dcs(struct mdfld_dsi_dbi_output *dbi_output,
+ u8 dcs, u8 *param, u32 num, u8 data_src);
+extern int mdfld_dsi_dbi_update_area(struct mdfld_dsi_dbi_output *dbi_output,
+ u16 x1, u16 y1, u16 x2, u16 y2);
+extern void mdfld_dbi_dsr_timer_start(struct mdfld_dbi_dsr_info *dsr_info);
+extern int mdfld_dsi_dbi_update_power(struct mdfld_dsi_dbi_output *dbi_output,
+ int mode);
+extern void mdfld_dsi_controller_dbi_init(struct mdfld_dsi_config *dsi_config,
+ int pipe);
+
+#endif /*__MDFLD_DSI_DBI_H__*/
diff --git a/drivers/staging/gma500/mdfld_dsi_dbi_dpu.h b/drivers/staging/gma500/mdfld_dsi_dbi_dpu.h
new file mode 100644
index 0000000..4ca9682
--- /dev/null
+++ b/drivers/staging/gma500/mdfld_dsi_dbi_dpu.h
@@ -0,0 +1,157 @@
+/*
+ * Copyright © 2010 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ * jim liu <jim...@intel.com>
+ * Jackie Li<yaodo...@intel.com>
+ */
+
+#ifndef __MDFLD_DSI_DBI_DPU_H__
+#define __MDFLD_DSI_DBI_DPU_H__
+
+#include "mdfld_dsi_dbi.h"
+
+typedef enum {
+ MDFLD_PLANEA,
+ MDFLD_PLANEC,
+ MDFLD_CURSORA,
+ MDFLD_CURSORC,
+ MDFLD_OVERLAYA,
+ MDFLD_OVERLAYC,
+ MDFLD_PLANE_NUM,
+} mdfld_plane_t;
+
+#define MDFLD_PIPEA_PLANE_MASK 0x15
+#define MDFLD_PIPEC_PLANE_MASK 0x2A
+
+struct mdfld_cursor_info {
+ int x, y;
+ int size;
+};
+
+#define MDFLD_CURSOR_SIZE 64
+
+/*
+ * enter DSR mode if screen has no update for 2 frames.
+ */
+#define MDFLD_MAX_IDLE_COUNT 2
+
+struct mdfld_dbi_dpu_info {
+ struct drm_device *dev;
+ /* Lock */
+ spinlock_t dpu_update_lock;
+
+ /* Cursor postion */
+ struct mdfld_cursor_info cursors[2];
+
+ /* Damaged area for each plane */
+ struct psb_drm_dpu_rect damaged_rects[MDFLD_PLANE_NUM];
+
+ /* Final damaged area */
+ struct psb_drm_dpu_rect damage_pipea;
+ struct psb_drm_dpu_rect damage_pipec;
+
+ /* Pending */
+ u32 pending;
+
+ /* DPU timer */
+ struct timer_list dpu_timer;
+ spinlock_t dpu_timer_lock;
+
+ /* DPU idle count */
+ u32 idle_count;
+
+ /* DSI outputs */
+ struct mdfld_dsi_dbi_output *dbi_outputs[2];
+ int dbi_output_num;
+};
+
+static inline int mdfld_dpu_region_extent(struct psb_drm_dpu_rect *origin,
+ struct psb_drm_dpu_rect *rect)
+{
+ int x1, y1, x2, y2;
+
+ /* PSB_DEBUG_ENTRY("rect (%d, %d, %d, %d)\n",
+ rect->x, rect->y, rect->width, rect->height); */
+
+ x1 = origin->x + origin->width;
+ y1 = origin->y + origin->height;
+
+ x2 = rect->x + rect->width;
+ y2 = rect->y + rect->height;
+
+ origin->x = min(origin->x, rect->x);
+ origin->y = min(origin->y, rect->y);
+ origin->width = max(x1, x2) - origin->x;
+ origin->height = max(y1, y2) - origin->y;


+
+ return 0;
+}
+

+static inline void mdfld_check_boundary(struct mdfld_dbi_dpu_info *dpu_info,
+ struct psb_drm_dpu_rect *rect)
+{
+ if (rect->x < 0)
+ rect->x = 0;
+ if (rect->y < 0)
+ rect->y = 0;
+
+ if (rect->x + rect->width > 864)
+ rect->width = 864 - rect->x;
+ if (rect->y + rect->height > 480)
+ rect->height = 480 - rect->height;
+
+ if (!rect->width)
+ rect->width = 1;
+ if (!rect->height)
+ rect->height = 1;
+}
+
+static inline void mdfld_dpu_init_damage(struct mdfld_dbi_dpu_info *dpu_info,
+ int pipe)
+{
+ struct psb_drm_dpu_rect *rect;
+
+ if (pipe == 0)
+ rect = &dpu_info->damage_pipea;
+ else
+ rect = &dpu_info->damage_pipec;
+
+ rect->x = 864;
+ rect->y = 480;
+ rect->width = -864;
+ rect->height = -480;
+}
+
+extern int mdfld_dsi_dbi_dsr_off(struct drm_device *dev,
+ struct psb_drm_dpu_rect *rect);
+extern int mdfld_dbi_dpu_report_damage(struct drm_device *dev,
+ mdfld_plane_t plane,
+ struct psb_drm_dpu_rect *rect);
+extern int mdfld_dbi_dpu_report_fullscreen_damage(struct drm_device *dev);
+extern int mdfld_dpu_exit_dsr(struct drm_device *dev);
+extern void mdfld_dbi_dpu_timer_start(struct mdfld_dbi_dpu_info *dpu_info);
+extern int mdfld_dbi_dpu_init(struct drm_device *dev);
+extern void mdfld_dbi_dpu_exit(struct drm_device *dev);
+extern void mdfld_dpu_update_panel(struct drm_device *dev);
+
+#endif /*__MDFLD_DSI_DBI_DPU_H__*/
diff --git a/drivers/staging/gma500/mdfld_dsi_dpi.c b/drivers/staging/gma500/mdfld_dsi_dpi.c
new file mode 100644
index 0000000..fce3c20
--- /dev/null
+++ b/drivers/staging/gma500/mdfld_dsi_dpi.c
@@ -0,0 +1,991 @@
+/*
+ * Copyright © 2010 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ * jim liu <jim...@intel.com>
+ * Jackie Li<yaodo...@intel.com>
+ */
+
+#include "mdfld_dsi_dpi.h"
+#include "mdfld_output.h"
+#include "mdfld_dsi_pkg_sender.h"
+
+
+static void mdfld_wait_for_HS_DATA_FIFO(struct drm_device *dev, u32 pipe)
+{
+ u32 gen_fifo_stat_reg = MIPIA_GEN_FIFO_STAT_REG;
+ int timeout = 0;
+
+ if (pipe == 2)
+ gen_fifo_stat_reg += MIPIC_REG_OFFSET;
+
+ udelay(500);
+
+ /* This will time out after approximately 2+ seconds */
+ while ((timeout < 20000) && (REG_READ(gen_fifo_stat_reg) & DSI_FIFO_GEN_HS_DATA_FULL)) {
+ udelay(100);
+ timeout++;
+ }
+
+ if (timeout == 20000)
+ dev_warn(dev->dev, "MIPI: HS Data FIFO was never cleared!\n");
+}
+
+static void mdfld_wait_for_HS_CTRL_FIFO(struct drm_device *dev, u32 pipe)
+{
+ u32 gen_fifo_stat_reg = MIPIA_GEN_FIFO_STAT_REG;
+ int timeout = 0;
+
+ if (pipe == 2)
+ gen_fifo_stat_reg += MIPIC_REG_OFFSET;
+
+ udelay(500);
+
+ /* This will time out after approximately 2+ seconds */
+ while ((timeout < 20000) && (REG_READ(gen_fifo_stat_reg) & DSI_FIFO_GEN_HS_CTRL_FULL)) {
+ udelay(100);
+ timeout++;
+ }
+ if (timeout == 20000)
+ dev_warn(dev->dev, "MIPI: HS CMD FIFO was never cleared!\n");
+}
+
+static void mdfld_wait_for_PIPEA_DISABLE(struct drm_device *dev, u32 pipe)
+{
+ u32 pipeconf_reg = PIPEACONF;
+ int timeout = 0;
+
+ if (pipe == 2)
+ pipeconf_reg = PIPECCONF;
+
+ udelay(500);
+
+ /* This will time out after approximately 2+ seconds */
+ while ((timeout < 20000) && (REG_READ(pipeconf_reg) & 0x40000000)) {
+ udelay(100);
+ timeout++;
+ }
+
+ if (timeout == 20000)
+ dev_warn(dev->dev, "MIPI: PIPE was not disabled!\n");
+}
+
+static void mdfld_wait_for_DPI_CTRL_FIFO(struct drm_device *dev, u32 pipe)
+{
+ u32 gen_fifo_stat_reg = MIPIA_GEN_FIFO_STAT_REG;
+ int timeout = 0;
+
+ if (pipe == 2)
+ gen_fifo_stat_reg += MIPIC_REG_OFFSET;
+
+ udelay(500);
+
+ /* This will time out after approximately 2+ seconds */
+ while ((timeout < 20000) && ((REG_READ(gen_fifo_stat_reg) & DPI_FIFO_EMPTY)
+ != DPI_FIFO_EMPTY)) {
+ udelay(100);
+ timeout++;
+ }
+
+ if (timeout == 20000)
+ dev_warn(dev->dev, "MIPI: DPI FIFO was never cleared!\n");
+}
+
+static void mdfld_wait_for_SPL_PKG_SENT(struct drm_device *dev, u32 pipe)
+{
+ u32 intr_stat_reg = MIPIA_INTR_STAT_REG;
+ int timeout = 0;
+
+ if (pipe == 2)
+ intr_stat_reg += MIPIC_REG_OFFSET;
+
+ udelay(500);
+
+ /* This will time out after approximately 2+ seconds */
+ while ((timeout < 20000) && (!(REG_READ(intr_stat_reg) & DSI_INTR_STATE_SPL_PKG_SENT))) {
+ udelay(100);
+ timeout++;
+ }
+
+ if (timeout == 20000)
+ dev_warn(dev->dev, "MIPI: SPL_PKT_SENT_INTERRUPT was not sent successfully!\n");
+}
+
+
+/* ************************************************************************* *\
+ * FUNCTION: mdfld_dsi_tpo_ic_init
+ *
+ * DESCRIPTION: This function is called only by mrst_dsi_mode_set and
+ * restore_display_registers. since this function does not
+ * acquire the mutex, it is important that the calling function
+ * does!
+\* ************************************************************************* */
+void mdfld_dsi_tpo_ic_init(struct mdfld_dsi_config *dsi_config, u32 pipe)
+{
+ struct drm_device *dev = dsi_config->dev;
+ u32 dcsChannelNumber = dsi_config->channel_num;
+ u32 gen_data_reg = MIPIA_HS_GEN_DATA_REG;
+ u32 gen_ctrl_reg = MIPIA_HS_GEN_CTRL_REG;
+ u32 gen_ctrl_val = GEN_LONG_WRITE;
+
+ dev_warn(dev->dev, "Enter mrst init TPO MIPI display.\n");
+
+ if (pipe == 2) {
+ gen_data_reg = HS_GEN_DATA_REG + MIPIC_REG_OFFSET;
+ gen_ctrl_reg = HS_GEN_CTRL_REG + MIPIC_REG_OFFSET;
+ }
+
+ gen_ctrl_val |= dcsChannelNumber << DCS_CHANNEL_NUMBER_POS;
+
+ /* Flip page order */
+ mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
+ REG_WRITE(gen_data_reg, 0x00008036);
+ mdfld_wait_for_HS_CTRL_FIFO(dev, pipe);
+ REG_WRITE(gen_ctrl_reg, gen_ctrl_val | (0x02 << WORD_COUNTS_POS));
+
+ /* 0xF0 */
+ mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
+ REG_WRITE(gen_data_reg, 0x005a5af0);
+ mdfld_wait_for_HS_CTRL_FIFO(dev, pipe);
+ REG_WRITE(gen_ctrl_reg, gen_ctrl_val | (0x03 << WORD_COUNTS_POS));
+
+ /* Write protection key */
+ mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
+ REG_WRITE(gen_data_reg, 0x005a5af1);
+ mdfld_wait_for_HS_CTRL_FIFO(dev, pipe);
+ REG_WRITE(gen_ctrl_reg, gen_ctrl_val | (0x03 << WORD_COUNTS_POS));
+
+ /* 0xFC */
+ mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
+ REG_WRITE(gen_data_reg, 0x005a5afc);
+ mdfld_wait_for_HS_CTRL_FIFO(dev, pipe);
+ REG_WRITE(gen_ctrl_reg, gen_ctrl_val | (0x03 << WORD_COUNTS_POS));
+
+ /* 0xB7 */
+ mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
+ REG_WRITE(gen_data_reg, 0x770000b7);
+ mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
+ REG_WRITE(gen_data_reg, 0x00000044);
+ mdfld_wait_for_HS_CTRL_FIFO(dev, pipe);
+ REG_WRITE(gen_ctrl_reg, gen_ctrl_val | (0x05 << WORD_COUNTS_POS));
+
+ /* 0xB6 */
+ mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
+ REG_WRITE(gen_data_reg, 0x000a0ab6);
+ mdfld_wait_for_HS_CTRL_FIFO(dev, pipe);
+ REG_WRITE(gen_ctrl_reg, gen_ctrl_val | (0x03 << WORD_COUNTS_POS));
+
+ /* 0xF2 */
+ mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
+ REG_WRITE(gen_data_reg, 0x081010f2);
+ mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
+ REG_WRITE(gen_data_reg, 0x4a070708);
+ mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
+ REG_WRITE(gen_data_reg, 0x000000c5);
+ mdfld_wait_for_HS_CTRL_FIFO(dev, pipe);
+ REG_WRITE(gen_ctrl_reg, gen_ctrl_val | (0x09 << WORD_COUNTS_POS));
+
+ /* 0xF8 */
+ mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
+ REG_WRITE(gen_data_reg, 0x024003f8);
+ mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
+ REG_WRITE(gen_data_reg, 0x01030a04);
+ mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
+ REG_WRITE(gen_data_reg, 0x0e020220);
+ mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
+ REG_WRITE(gen_data_reg, 0x00000004);
+ mdfld_wait_for_HS_CTRL_FIFO(dev, pipe);
+ REG_WRITE(gen_ctrl_reg, gen_ctrl_val | (0x0d << WORD_COUNTS_POS));
+
+ /* 0xE2 */
+ mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
+ REG_WRITE(gen_data_reg, 0x398fc3e2);
+ mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
+ REG_WRITE(gen_data_reg, 0x0000916f);
+ mdfld_wait_for_HS_CTRL_FIFO(dev, pipe);
+ REG_WRITE(gen_ctrl_reg, gen_ctrl_val | (0x06 << WORD_COUNTS_POS));
+
+ /* 0xB0 */
+ mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
+ REG_WRITE(gen_data_reg, 0x000000b0);
+ mdfld_wait_for_HS_CTRL_FIFO(dev, pipe);
+ REG_WRITE(gen_ctrl_reg, gen_ctrl_val | (0x02 << WORD_COUNTS_POS));
+
+ /* 0xF4 */
+ mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
+ REG_WRITE(gen_data_reg, 0x240242f4);
+ mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
+ REG_WRITE(gen_data_reg, 0x78ee2002);
+ mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
+ REG_WRITE(gen_data_reg, 0x2a071050);
+ mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
+ REG_WRITE(gen_data_reg, 0x507fee10);
+ mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
+ REG_WRITE(gen_data_reg, 0x10300710);
+ mdfld_wait_for_HS_CTRL_FIFO(dev, pipe);
+ REG_WRITE(gen_ctrl_reg, gen_ctrl_val | (0x14 << WORD_COUNTS_POS));
+
+ /* 0xBA */
+ mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
+ REG_WRITE(gen_data_reg, 0x19fe07ba);
+ mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
+ REG_WRITE(gen_data_reg, 0x101c0a31);
+ mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
+ REG_WRITE(gen_data_reg, 0x00000010);
+ mdfld_wait_for_HS_CTRL_FIFO(dev, pipe);
+ REG_WRITE(gen_ctrl_reg, gen_ctrl_val | (0x09 << WORD_COUNTS_POS));
+
+ /* 0xBB */
+ mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
+ REG_WRITE(gen_data_reg, 0x28ff07bb);
+ mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
+ REG_WRITE(gen_data_reg, 0x24280a31);
+ mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
+ REG_WRITE(gen_data_reg, 0x00000034);
+ mdfld_wait_for_HS_CTRL_FIFO(dev, pipe);
+ REG_WRITE(gen_ctrl_reg, gen_ctrl_val | (0x09 << WORD_COUNTS_POS));
+
+ /* 0xFB */
+ mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
+ REG_WRITE(gen_data_reg, 0x535d05fb);
+ mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
+ REG_WRITE(gen_data_reg, 0x1b1a2130);
+ mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
+ REG_WRITE(gen_data_reg, 0x221e180e);
+ mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
+ REG_WRITE(gen_data_reg, 0x131d2120);
+ mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
+ REG_WRITE(gen_data_reg, 0x535d0508);
+ mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
+ REG_WRITE(gen_data_reg, 0x1c1a2131);
+ mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
+ REG_WRITE(gen_data_reg, 0x231f160d);
+ mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
+ REG_WRITE(gen_data_reg, 0x111b2220);
+ mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
+ REG_WRITE(gen_data_reg, 0x535c2008);
+ mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
+ REG_WRITE(gen_data_reg, 0x1f1d2433);
+ mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
+ REG_WRITE(gen_data_reg, 0x2c251a10);
+ mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
+ REG_WRITE(gen_data_reg, 0x2c34372d);
+ mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
+ REG_WRITE(gen_data_reg, 0x00000023);
+ mdfld_wait_for_HS_CTRL_FIFO(dev, pipe);
+ REG_WRITE(gen_ctrl_reg, gen_ctrl_val | (0x31 << WORD_COUNTS_POS));
+
+ /* 0xFA */
+ mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
+ REG_WRITE(gen_data_reg, 0x525c0bfa);
+ mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
+ REG_WRITE(gen_data_reg, 0x1c1c232f);
+ mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
+ REG_WRITE(gen_data_reg, 0x2623190e);
+ mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
+ REG_WRITE(gen_data_reg, 0x18212625);
+ mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
+ REG_WRITE(gen_data_reg, 0x545d0d0e);
+ mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
+ REG_WRITE(gen_data_reg, 0x1e1d2333);
+ mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
+ REG_WRITE(gen_data_reg, 0x26231a10);
+ mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
+ REG_WRITE(gen_data_reg, 0x1a222725);
+ mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
+ REG_WRITE(gen_data_reg, 0x545d280f);
+ mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
+ REG_WRITE(gen_data_reg, 0x21202635);
+ mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
+ REG_WRITE(gen_data_reg, 0x31292013);
+ mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
+ REG_WRITE(gen_data_reg, 0x31393d33);
+ mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
+ REG_WRITE(gen_data_reg, 0x00000029);
+ mdfld_wait_for_HS_CTRL_FIFO(dev, pipe);
+ REG_WRITE(gen_ctrl_reg, gen_ctrl_val | (0x31 << WORD_COUNTS_POS));
+
+ /* Set DM */
+ mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
+ REG_WRITE(gen_data_reg, 0x000100f7);
+ mdfld_wait_for_HS_CTRL_FIFO(dev, pipe);
+ REG_WRITE(gen_ctrl_reg, gen_ctrl_val | (0x03 << WORD_COUNTS_POS));
+}
+
+/* ************************************************************************* *\
+ * FUNCTION: mdfld_init_TMD_MIPI
+ *
+ * DESCRIPTION: This function is called only by mrst_dsi_mode_set and
+ * restore_display_registers. since this function does not
+ * acquire the mutex, it is important that the calling function
+ * does!
+\* ************************************************************************* */
+
+static u32 tmd_cmd_mcap_off[] = {0x000000b2};
+static u32 tmd_cmd_enable_lane_switch[] = {0x000101ef};
+static u32 tmd_cmd_set_lane_num[] = {0x006360ef};
+static u32 tmd_cmd_set_mode[] = {0x000000b3};
+static u32 tmd_cmd_set_sync_pulse_mode[] = {0x000961ef};
+static u32 tmd_cmd_set_video_mode[] = {0x00000153};
+static u32 tmd_cmd_enable_backlight[] = {0x00005ab4};//no auto_bl,need add in furtrue
+static u32 tmd_cmd_set_backlight_dimming[] = {0x00000ebd};
+
+void mdfld_dsi_tmd_drv_ic_init(struct mdfld_dsi_config *dsi_config, u32 pipe)
+{
+ struct mdfld_dsi_pkg_sender *sender = mdfld_dsi_get_pkg_sender(dsi_config);
+
+ if(!sender) {
+ WARN_ON(1);
+ return;
+ }
+
+ if(dsi_config->dvr_ic_inited)
+ return;
+
+ msleep(3);
+
+ mdfld_dsi_send_gen_long_lp(sender, tmd_cmd_mcap_off, 1, 0);
+ mdfld_dsi_send_gen_long_lp(sender, tmd_cmd_enable_lane_switch, 1, 0);
+ mdfld_dsi_send_gen_long_lp(sender, tmd_cmd_set_lane_num, 1, 0);
+ mdfld_dsi_send_gen_long_lp(sender, tmd_cmd_set_mode, 1, 0);
+ mdfld_dsi_send_gen_long_lp(sender, tmd_cmd_set_sync_pulse_mode, 1, 0);
+ /*TODO: set page and column here*/
+ mdfld_dsi_send_gen_long_lp(sender, tmd_cmd_set_video_mode, 1, 0);
+ mdfld_dsi_send_gen_long_lp(sender, tmd_cmd_enable_backlight, 1, 0);
+ mdfld_dsi_send_gen_long_lp(sender, tmd_cmd_set_backlight_dimming,1,0);
+ dsi_config->dvr_ic_inited = 1;
+}
+
+static u16 mdfld_dsi_dpi_to_byte_clock_count(int pixel_clock_count, int num_lane, int bpp)
+{
+ return (u16)((pixel_clock_count * bpp) / (num_lane * 8));
+}
+
+/*
+ * Calculate the dpi time basing on a given drm mode @mode
+ * return 0 on success.
+ * FIXME: I was using proposed mode value for calculation, may need to
+ * use crtc mode values later
+ */
+int mdfld_dsi_dpi_timing_calculation(struct drm_display_mode *mode,
+ struct mdfld_dsi_dpi_timing *dpi_timing,
+ int num_lane, int bpp)
+{
+ int pclk_hsync, pclk_hfp, pclk_hbp, pclk_hactive;
+ int pclk_vsync, pclk_vfp, pclk_vbp, pclk_vactive;
+
+ if(!mode || !dpi_timing) {
+ DRM_ERROR("Invalid parameter\n");


+ return -EINVAL;
+ }
+

+ pclk_hactive = mode->hdisplay;
+ pclk_hfp = mode->hsync_start - mode->hdisplay;
+ pclk_hsync = mode->hsync_end - mode->hsync_start;
+ pclk_hbp = mode->htotal - mode->hsync_end;
+
+ pclk_vactive = mode->vdisplay;
+ pclk_vfp = mode->vsync_start - mode->vdisplay;
+ pclk_vsync = mode->vsync_end - mode->vsync_start;
+ pclk_vbp = mode->vtotal - mode->vsync_end;
+
+#ifdef MIPI_DEBUG_LOG
+ printk(KERN_ALERT "[DISPLAY] %s: pclk_hactive = %d\n", __func__, pclk_hactive);
+ printk(KERN_ALERT "[DISPLAY] %s: pclk_hfp = %d\n", __func__, pclk_hfp);
+ printk(KERN_ALERT "[DISPLAY] %s: pclk_hsync = %d\n", __func__, pclk_hsync);
+ printk(KERN_ALERT "[DISPLAY] %s: pclk_hbp = %d\n", __func__, pclk_hbp);
+ printk(KERN_ALERT "[DISPLAY] %s: pclk_vactive = %d\n", __func__, pclk_vactive);
+ printk(KERN_ALERT "[DISPLAY] %s: pclk_vfp = %d\n", __func__, pclk_vfp);
+ printk(KERN_ALERT "[DISPLAY] %s: pclk_vsync = %d\n", __func__, pclk_vsync);
+ printk(KERN_ALERT "[DISPLAY] %s: pclk_vbp = %d\n", __func__, pclk_vbp);
+#endif
+ /*
+ * byte clock counts were calculated by following formula
+ * bclock_count = pclk_count * bpp / num_lane / 8
+ */
+ dpi_timing->hsync_count = mdfld_dsi_dpi_to_byte_clock_count(pclk_hsync, num_lane, bpp);
+ dpi_timing->hbp_count = mdfld_dsi_dpi_to_byte_clock_count(pclk_hbp, num_lane, bpp);
+ dpi_timing->hfp_count = mdfld_dsi_dpi_to_byte_clock_count(pclk_hfp, num_lane, bpp);
+ dpi_timing->hactive_count = mdfld_dsi_dpi_to_byte_clock_count(pclk_hactive, num_lane, bpp);
+ dpi_timing->vsync_count = mdfld_dsi_dpi_to_byte_clock_count(pclk_vsync, num_lane, bpp);
+ dpi_timing->vbp_count = mdfld_dsi_dpi_to_byte_clock_count(pclk_vbp, num_lane, bpp);
+ dpi_timing->vfp_count = mdfld_dsi_dpi_to_byte_clock_count(pclk_vfp, num_lane, bpp);


+
+ return 0;
+}
+

+void mdfld_dsi_dpi_controller_init(struct mdfld_dsi_config *dsi_config, int pipe)
+{
+ struct drm_device *dev = dsi_config->dev;
+ u32 reg_offset = pipe ? MIPIC_REG_OFFSET : 0;
+ int lane_count = dsi_config->lane_count;
+ struct mdfld_dsi_dpi_timing dpi_timing;
+ struct drm_display_mode *mode = dsi_config->mode;
+ u32 val = 0;
+
+ /*un-ready device*/
+ REG_WRITE((MIPIA_DEVICE_READY_REG + reg_offset), 0x00000000);
+
+ /*init dsi adapter before kicking off*/
+ REG_WRITE((MIPIA_CONTROL_REG + reg_offset), 0x00000018);
+
+ /*enable all interrupts*/
+ REG_WRITE((MIPIA_INTR_EN_REG + reg_offset), 0xffffffff);
+
+
+ /*set up func_prg*/
+ val |= lane_count;
+ val |= dsi_config->channel_num << DSI_DPI_VIRT_CHANNEL_OFFSET;
+
+ switch(dsi_config->bpp) {
+ case 16:
+ val |= DSI_DPI_COLOR_FORMAT_RGB565;
+ break;
+ case 18:
+ val |= DSI_DPI_COLOR_FORMAT_RGB666;
+ break;
+ case 24:
+ val |= DSI_DPI_COLOR_FORMAT_RGB888;
+ break;
+ default:
+ DRM_ERROR("unsupported color format, bpp = %d\n", dsi_config->bpp);
+ }
+ REG_WRITE((MIPIA_DSI_FUNC_PRG_REG + reg_offset), val);
+
+ REG_WRITE((MIPIA_HS_TX_TIMEOUT_REG + reg_offset),
+ (mode->vtotal * mode->htotal * dsi_config->bpp / (8 * lane_count)) & DSI_HS_TX_TIMEOUT_MASK);
+ REG_WRITE((MIPIA_LP_RX_TIMEOUT_REG + reg_offset), 0xffff & DSI_LP_RX_TIMEOUT_MASK);
+
+ /*max value: 20 clock cycles of txclkesc*/
+ REG_WRITE((MIPIA_TURN_AROUND_TIMEOUT_REG + reg_offset), 0x14 & DSI_TURN_AROUND_TIMEOUT_MASK);
+
+ /*min 21 txclkesc, max: ffffh*/
+ REG_WRITE((MIPIA_DEVICE_RESET_TIMER_REG + reg_offset), 0xffff & DSI_RESET_TIMER_MASK);
+
+ REG_WRITE((MIPIA_DPI_RESOLUTION_REG + reg_offset), mode->vdisplay << 16 | mode->hdisplay);
+
+ /*set DPI timing registers*/
+ mdfld_dsi_dpi_timing_calculation(mode, &dpi_timing, dsi_config->lane_count, dsi_config->bpp);
+
+ REG_WRITE((MIPIA_HSYNC_COUNT_REG + reg_offset), dpi_timing.hsync_count & DSI_DPI_TIMING_MASK);
+ REG_WRITE((MIPIA_HBP_COUNT_REG + reg_offset), dpi_timing.hbp_count & DSI_DPI_TIMING_MASK);
+ REG_WRITE((MIPIA_HFP_COUNT_REG + reg_offset), dpi_timing.hfp_count & DSI_DPI_TIMING_MASK);
+ REG_WRITE((MIPIA_HACTIVE_COUNT_REG + reg_offset), dpi_timing.hactive_count & DSI_DPI_TIMING_MASK);
+ REG_WRITE((MIPIA_VSYNC_COUNT_REG + reg_offset), dpi_timing.vsync_count & DSI_DPI_TIMING_MASK);
+ REG_WRITE((MIPIA_VBP_COUNT_REG + reg_offset), dpi_timing.vbp_count & DSI_DPI_TIMING_MASK);
+ REG_WRITE((MIPIA_VFP_COUNT_REG + reg_offset), dpi_timing.vfp_count & DSI_DPI_TIMING_MASK);
+
+ REG_WRITE((MIPIA_HIGH_LOW_SWITCH_COUNT_REG + reg_offset), 0x46);
+
+ /*min: 7d0 max: 4e20*/
+ REG_WRITE((MIPIA_INIT_COUNT_REG + reg_offset), 0x000007d0);
+
+ /*set up video mode*/
+ val = 0;
+ val = dsi_config->video_mode | DSI_DPI_COMPLETE_LAST_LINE;
+ REG_WRITE((MIPIA_VIDEO_MODE_FORMAT_REG + reg_offset), val);
+
+ REG_WRITE((MIPIA_EOT_DISABLE_REG + reg_offset), 0x00000000);
+
+ REG_WRITE((MIPIA_LP_BYTECLK_REG + reg_offset), 0x00000004);
+
+ /*TODO: figure out how to setup these registers*/
+ REG_WRITE((MIPIA_DPHY_PARAM_REG + reg_offset), 0x150c3408);
+
+ REG_WRITE((MIPIA_CLK_LANE_SWITCH_TIME_CNT_REG + reg_offset), (0xa << 16) | 0x14);
+ /*set device ready*/
+ REG_WRITE((MIPIA_DEVICE_READY_REG + reg_offset), 0x00000001);
+}
+
+void mdfld_dsi_dpi_turn_on(struct mdfld_dsi_dpi_output *output, int pipe)
+{
+ struct drm_device *dev = output->dev;
+ /* struct drm_psb_private *dev_priv = dev->dev_private; */
+ u32 reg_offset = 0;
+
+ if(output->panel_on)
+ return;
+
+ if(pipe)
+ reg_offset = MIPIC_REG_OFFSET;
+
+ /* clear special packet sent bit */
+ if(REG_READ(MIPIA_INTR_STAT_REG + reg_offset) & DSI_INTR_STATE_SPL_PKG_SENT) {
+ REG_WRITE((MIPIA_INTR_STAT_REG + reg_offset), DSI_INTR_STATE_SPL_PKG_SENT);
+ }
+
+ /*send turn on package*/
+ REG_WRITE((MIPIA_DPI_CONTROL_REG + reg_offset), DSI_DPI_CTRL_HS_TURN_ON);
+
+ /*wait for SPL_PKG_SENT interrupt*/
+ mdfld_wait_for_SPL_PKG_SENT(dev, pipe);
+
+ if(REG_READ(MIPIA_INTR_STAT_REG + reg_offset) & DSI_INTR_STATE_SPL_PKG_SENT) {
+ REG_WRITE((MIPIA_INTR_STAT_REG + reg_offset), DSI_INTR_STATE_SPL_PKG_SENT);
+ }
+
+ output->panel_on = 1;
+
+ /* FIXME the following is disabled to WA the X slow start issue for TMD panel */
+ /* if(pipe == 2) */
+ /* dev_priv->dpi_panel_on2 = true; */
+ /* else if (pipe == 0) */
+ /* dev_priv->dpi_panel_on = true; */
+}
+
+static void mdfld_dsi_dpi_shut_down(struct mdfld_dsi_dpi_output *output, int pipe)
+{
+ struct drm_device *dev = output->dev;
+ /* struct drm_psb_private *dev_priv = dev->dev_private; */
+ u32 reg_offset = 0;
+
+ /*if output is on, or mode setting didn't happen, ignore this*/
+ if((!output->panel_on) || output->first_boot) {
+ output->first_boot = 0;
+ return;
+ }
+
+ if(pipe)
+ reg_offset = MIPIC_REG_OFFSET;
+
+ /* Wait for dpi fifo to empty */
+ mdfld_wait_for_DPI_CTRL_FIFO(dev, pipe);
+
+ /* Clear the special packet interrupt bit if set */
+ if(REG_READ(MIPIA_INTR_STAT_REG + reg_offset) & DSI_INTR_STATE_SPL_PKG_SENT) {
+ REG_WRITE((MIPIA_INTR_STAT_REG + reg_offset), DSI_INTR_STATE_SPL_PKG_SENT);
+ }
+
+ if(REG_READ(MIPIA_DPI_CONTROL_REG + reg_offset) == DSI_DPI_CTRL_HS_SHUTDOWN) {
+ goto shutdown_out;
+ }
+
+ REG_WRITE((MIPIA_DPI_CONTROL_REG + reg_offset), DSI_DPI_CTRL_HS_SHUTDOWN);
+
+shutdown_out:
+ output->panel_on = 0;
+ output->first_boot = 0;
+
+ /* FIXME the following is disabled to WA the X slow start issue for TMD panel */
+ /* if(pipe == 2) */
+ /* dev_priv->dpi_panel_on2 = false; */
+ /* else if (pipe == 0) */
+ /* dev_priv->dpi_panel_on = false; */
+}
+
+void mdfld_dsi_dpi_set_power(struct drm_encoder *encoder, bool on)
+{
+ struct mdfld_dsi_encoder *dsi_encoder = MDFLD_DSI_ENCODER(encoder);
+ struct mdfld_dsi_dpi_output *dpi_output = MDFLD_DSI_DPI_OUTPUT(dsi_encoder);
+ struct mdfld_dsi_config *dsi_config = mdfld_dsi_encoder_get_config(dsi_encoder);
+ int pipe = mdfld_dsi_encoder_get_pipe(dsi_encoder);
+ struct drm_device *dev = dsi_config->dev;
+ struct drm_psb_private *dev_priv = dev->dev_private;
+ u32 mipi_reg = MIPI;
+ u32 pipeconf_reg = PIPEACONF;
+
+ if(pipe) {
+ mipi_reg = MIPI_C;
+ pipeconf_reg = PIPECCONF;
+ }
+
+ /* Start up display island if it was shutdown */
+ if (!gma_power_begin(dev, true))
+ return;
+
+ if(on) {
+ if (mdfld_get_panel_type(dev, pipe) == TMD_VID){
+ mdfld_dsi_dpi_turn_on(dpi_output, pipe);
+ } else {
+ /*enable mipi port*/
+ REG_WRITE(mipi_reg, (REG_READ(mipi_reg) | (1 << 31)));
+ REG_READ(mipi_reg);
+
+ mdfld_dsi_dpi_turn_on(dpi_output, pipe);
+ mdfld_dsi_tpo_ic_init(dsi_config, pipe);
+ }
+
+ if(pipe == 2) {
+ dev_priv->dpi_panel_on2 = true;
+ }
+ else {
+ dev_priv->dpi_panel_on = true;
+ }
+
+ } else {
+ if (mdfld_get_panel_type(dev, pipe) == TMD_VID) {
+ mdfld_dsi_dpi_shut_down(dpi_output, pipe);
+ } else {
+ mdfld_dsi_dpi_shut_down(dpi_output, pipe);
+ /*disable mipi port*/
+ REG_WRITE(mipi_reg, (REG_READ(mipi_reg) & ~(1<<31)));
+ REG_READ(mipi_reg);
+ }
+
+ if(pipe == 2)
+ dev_priv->dpi_panel_on2 = false;
+ else
+ dev_priv->dpi_panel_on = false;
+ }
+ gma_power_end(dev);
+}
+
+void mdfld_dsi_dpi_dpms(struct drm_encoder *encoder, int mode)
+{
+ dev_dbg(encoder->dev->dev, "DPMS %s\n",
+ (mode == DRM_MODE_DPMS_ON ? "on":"off"));
+
+ if (mode == DRM_MODE_DPMS_ON)
+ mdfld_dsi_dpi_set_power(encoder, true);
+ else
+ mdfld_dsi_dpi_set_power(encoder, false);
+}
+
+bool mdfld_dsi_dpi_mode_fixup(struct drm_encoder *encoder,
+ struct drm_display_mode *mode,
+ struct drm_display_mode *adjusted_mode)
+{
+ struct mdfld_dsi_encoder *dsi_encoder = MDFLD_DSI_ENCODER(encoder);
+ struct mdfld_dsi_config *dsi_config = mdfld_dsi_encoder_get_config(dsi_encoder);
+ struct drm_display_mode *fixed_mode = dsi_config->fixed_mode;
+
+ if(fixed_mode) {
+ adjusted_mode->hdisplay = fixed_mode->hdisplay;
+ adjusted_mode->hsync_start = fixed_mode->hsync_start;
+ adjusted_mode->hsync_end = fixed_mode->hsync_end;
+ adjusted_mode->htotal = fixed_mode->htotal;
+ adjusted_mode->vdisplay = fixed_mode->vdisplay;
+ adjusted_mode->vsync_start = fixed_mode->vsync_start;
+ adjusted_mode->vsync_end = fixed_mode->vsync_end;
+ adjusted_mode->vtotal = fixed_mode->vtotal;
+ adjusted_mode->clock = fixed_mode->clock;
+ drm_mode_set_crtcinfo(adjusted_mode, CRTC_INTERLACE_HALVE_V);
+ }
+
+ return true;
+}
+
+void mdfld_dsi_dpi_prepare(struct drm_encoder *encoder)
+{
+ mdfld_dsi_dpi_set_power(encoder, false);
+}
+
+void mdfld_dsi_dpi_commit(struct drm_encoder *encoder)
+{
+ mdfld_dsi_dpi_set_power(encoder, true);
+}
+
+void dsi_debug_MIPI_reg(struct drm_device *dev)
+{
+ u32 temp_val = 0;
+
+ temp_val = REG_READ(MIPI);
+ printk(KERN_ALERT "[DISPLAY] MIPI = %x\n", temp_val);
+
+ /* set the lane speed */
+ temp_val = REG_READ(MIPI_CONTROL_REG);
+ printk(KERN_ALERT "[DISPLAY] MIPI_CONTROL_REG = %x\n", temp_val);
+
+ /* Enable all the error interrupt */
+ temp_val = REG_READ(INTR_EN_REG);
+ printk(KERN_ALERT "[DISPLAY] INTR_EN_REG = %x\n", temp_val);
+ temp_val = REG_READ(TURN_AROUND_TIMEOUT_REG);
+ printk(KERN_ALERT "[DISPLAY] TURN_AROUND_TIMEOUT_REG = %x\n", temp_val);
+ temp_val = REG_READ(DEVICE_RESET_REG);
+ printk(KERN_ALERT "[DISPLAY] DEVICE_RESET_REG = %x\n", temp_val);
+ temp_val = REG_READ(INIT_COUNT_REG);
+ printk(KERN_ALERT "[DISPLAY] INIT_COUNT_REG = %x\n", temp_val);
+
+ temp_val = REG_READ(DSI_FUNC_PRG_REG);
+ printk(KERN_ALERT "[DISPLAY] DSI_FUNC_PRG_REG = %x\n", temp_val);
+
+ temp_val = REG_READ(DPI_RESOLUTION_REG);
+ printk(KERN_ALERT "[DISPLAY] DPI_RESOLUTION_REG = %x\n", temp_val);
+
+ temp_val = REG_READ(VERT_SYNC_PAD_COUNT_REG);
+ printk(KERN_ALERT "[DISPLAY] VERT_SYNC_PAD_COUNT_REG = %x\n", temp_val);
+ temp_val = REG_READ(VERT_BACK_PORCH_COUNT_REG);
+ printk(KERN_ALERT "[DISPLAY] VERT_BACK_PORCH_COUNT_REG = %x\n", temp_val);
+ temp_val = REG_READ(VERT_FRONT_PORCH_COUNT_REG);
+ printk(KERN_ALERT "[DISPLAY] VERT_FRONT_PORCH_COUNT_REG = %x\n", temp_val);
+
+ temp_val = REG_READ(HORIZ_SYNC_PAD_COUNT_REG);
+ printk(KERN_ALERT "[DISPLAY] HORIZ_SYNC_PAD_COUNT_REG = %x\n", temp_val);
+ temp_val = REG_READ(HORIZ_BACK_PORCH_COUNT_REG);
+ printk(KERN_ALERT "[DISPLAY] HORIZ_BACK_PORCH_COUNT_REG = %x\n", temp_val);
+ temp_val = REG_READ(HORIZ_FRONT_PORCH_COUNT_REG);
+ printk(KERN_ALERT "[DISPLAY] HORIZ_FRONT_PORCH_COUNT_REG = %x\n", temp_val);
+ temp_val = REG_READ(HORIZ_ACTIVE_AREA_COUNT_REG);
+ printk(KERN_ALERT "[DISPLAY] HORIZ_ACTIVE_AREA_COUNT_REG = %x\n", temp_val);
+
+ temp_val = REG_READ(VIDEO_FMT_REG);
+ printk(KERN_ALERT "[DISPLAY] VIDEO_FMT_REG = %x\n", temp_val);
+
+ temp_val = REG_READ(HS_TX_TIMEOUT_REG);
+ printk(KERN_ALERT "[DISPLAY] HS_TX_TIMEOUT_REG = %x\n", temp_val);
+ temp_val = REG_READ(LP_RX_TIMEOUT_REG);
+ printk(KERN_ALERT "[DISPLAY] LP_RX_TIMEOUT_REG = %x\n", temp_val);
+
+ temp_val = REG_READ(HIGH_LOW_SWITCH_COUNT_REG);
+ printk(KERN_ALERT "[DISPLAY] HIGH_LOW_SWITCH_COUNT_REG = %x\n", temp_val);
+
+ temp_val = REG_READ(EOT_DISABLE_REG);
+ printk(KERN_ALERT "[DISPLAY] EOT_DISABLE_REG = %x\n", temp_val);
+
+ temp_val = REG_READ(LP_BYTECLK_REG);
+ printk(KERN_ALERT "[DISPLAY] LP_BYTECLK_REG = %x\n", temp_val);
+ temp_val = REG_READ(MAX_RET_PAK_REG);
+ printk(KERN_ALERT "[DISPLAY] MAX_RET_PAK_REG = %x\n", temp_val);
+ temp_val = REG_READ(DPI_CONTROL_REG);
+ printk(KERN_ALERT "[DISPLAY] DPI_CONTROL_REG = %x\n", temp_val);
+ temp_val = REG_READ(DPHY_PARAM_REG);
+ printk(KERN_ALERT "[DISPLAY] DPHY_PARAM_REG = %x\n", temp_val);
+// temp_val = REG_READ(PIPEACONF);
+// printk(KERN_INFO "[DISPLAY] PIPEACONF = %x\n", temp_val);
+// temp_val = REG_READ(DSPACNTR);
+// printk(KERN_INFO "[DISPLAY] DSPACNTR = %x\n", temp_val);
+}
+
+void mdfld_dsi_dpi_mode_set(struct drm_encoder *encoder,
+ struct drm_display_mode *mode,
+ struct drm_display_mode *adjusted_mode)
+{
+ struct mdfld_dsi_encoder *dsi_encoder = MDFLD_DSI_ENCODER(encoder);
+ struct mdfld_dsi_dpi_output *dpi_output = MDFLD_DSI_DPI_OUTPUT(dsi_encoder);
+ struct mdfld_dsi_config *dsi_config = mdfld_dsi_encoder_get_config(dsi_encoder);
+ struct drm_device *dev = dsi_config->dev;
+ struct drm_psb_private *dev_priv = dev->dev_private;
+ int pipe = mdfld_dsi_encoder_get_pipe(dsi_encoder);
+
+ u32 pipeconf_reg = PIPEACONF;
+ u32 dspcntr_reg = DSPACNTR;
+ u32 mipi_reg = MIPI;
+ u32 reg_offset = 0;
+
+ u32 pipeconf = dev_priv->pipeconf;
+ u32 dspcntr = dev_priv->dspcntr;
+ u32 mipi = MIPI_PORT_EN | PASS_FROM_SPHY_TO_AFE | SEL_FLOPPED_HSTX;
+
+ dev_dbg(dev->dev, "set mode %dx%d on pipe %d\n",
+ mode->hdisplay, mode->vdisplay, pipe);
+
+ if(pipe) {
+ pipeconf_reg = PIPECCONF;
+ dspcntr_reg = DSPCCNTR;
+ mipi_reg = MIPI_C;
+ reg_offset = MIPIC_REG_OFFSET;
+ } else {
+ mipi |= 2;
+ }
+
+ if (!gma_power_begin(dev, true))
+ return;
+
+ /* Set up mipi port FIXME: do at init time */
+ REG_WRITE(mipi_reg, mipi);
+ REG_READ(mipi_reg);
+
+ /* Set up DSI controller DPI interface*/
+ mdfld_dsi_dpi_controller_init(dsi_config, pipe);
+
+ if (mdfld_get_panel_type(dev, pipe) == TMD_VID) {
+ /* init driver ic */
+ mdfld_dsi_tmd_drv_ic_init(dsi_config, pipe);
+ } else {
+ /*turn on DPI interface*/
+ mdfld_dsi_dpi_turn_on(dpi_output, pipe);
+ }
+
+ /* Set up pipe */
+ REG_WRITE(pipeconf_reg, pipeconf);
+ REG_READ(pipeconf_reg);
+
+ /* Set up display plane */
+ REG_WRITE(dspcntr_reg, dspcntr);
+ REG_READ(dspcntr_reg);
+
+ msleep(20); /* FIXME: this should wait for vblank */
+
+ dev_dbg(dev->dev, "State %x, power %d\n",
+ REG_READ(MIPIA_INTR_STAT_REG + reg_offset),
+ dpi_output->panel_on);
+
+ if (mdfld_get_panel_type(dev, pipe) == TMD_VID) {
+ //mdfld_dsi_dpi_turn_on(dpi_output, pipe);
+ } else {
+ /* init driver ic */
+ mdfld_dsi_tpo_ic_init(dsi_config, pipe);
+ /*init backlight*/
+ mdfld_dsi_brightness_init(dsi_config, pipe);
+ }
+
+#ifdef MIPI_DEBUG_LOG
+ dsi_debug_MIPI_reg(dev);
+#endif
+ gma_power_end(dev);
+}
+
+static int mdfld_dpi_panel_reset(int pipe)
+{
+ unsigned gpio;


+ int ret = 0;

+
+ switch(pipe) {
+ case 0:
+ gpio = 128;
+ break;
+ case 2:
+ gpio = 34;
+ break;
+ default:
+ DRM_ERROR("Invalid output\n");


+ return -EINVAL;
+ }
+

+ ret = gpio_request(gpio, "gfx");
+ if(ret) {
+ DRM_ERROR("gpio_rqueset failed\n");
+ return ret;
+ }
+ ret = gpio_direction_output(gpio, 1);
+ if(ret) {
+ DRM_ERROR("gpio_direction_output failed\n");
+ goto gpio_error;
+ }
+
+ gpio_get_value(128);
+
+gpio_error:
+ if(gpio_is_valid(gpio))
+ gpio_free(gpio);


+ return ret;
+}
+

+/**
+ * Exit from DSR
+ */
+void mdfld_dsi_dpi_exit_idle (struct drm_device *dev, u32 update_src, void *p_surfaceAddr, bool check_hw_on_only)
+{
+ struct drm_psb_private *dev_priv = dev->dev_private;
+
+ if (!gma_power_begin(dev, true)) {
+ DRM_ERROR("hw begin failed\n");
+ return;
+ }
+
+ /* update the surface base address. */
+ if (p_surfaceAddr) {
+ REG_WRITE(DSPASURF, *((u32 *)p_surfaceAddr));
+#if defined(CONFIG_MDFD_DUAL_MIPI)
+ REG_WRITE(DSPCSURF, *((u32 *)p_surfaceAddr));
+#endif
+ }
+ mid_enable_pipe_event(dev_priv, 0);
+ psb_enable_pipestat(dev_priv, 0, PIPE_VBLANK_INTERRUPT_ENABLE);
+ dev_priv->is_in_idle = false;
+ dev_priv->dsr_idle_count = 0;
+}
+
+/*
+ * Init DSI DPI encoder.
+ * Allocate an mdfld_dsi_encoder and attach it to given @dsi_connector
+ * return pointer of newly allocated DPI encoder, NULL on error
+ */
+struct mdfld_dsi_encoder *mdfld_dsi_dpi_init(struct drm_device *dev,
+ struct mdfld_dsi_connector *dsi_connector,
+ struct panel_funcs*p_funcs)
+{
+ struct drm_psb_private *dev_priv = dev->dev_private;
+ struct mdfld_dsi_dpi_output *dpi_output = NULL;
+ struct mdfld_dsi_config *dsi_config;
+ struct drm_connector *connector = NULL;
+ struct drm_encoder *encoder = NULL;
+ struct drm_display_mode *fixed_mode = NULL;
+ int ret;
+
+ if (!dsi_connector) {
+ WARN_ON(1);
+ return NULL;
+ }
+
+ dpi_output = kzalloc(sizeof(struct mdfld_dsi_dpi_output), GFP_KERNEL);
+ if(!dpi_output) {
+ dev_err(dev->dev, "No memory for dsi_dpi_output\n");
+ return NULL;
+ }
+ /* Panel reset */
+ ret = mdfld_dpi_panel_reset(dsi_connector->pipe);
+ if(ret) {
+ DRM_ERROR("reset panel error\n");
+ goto out_err1;
+ }
+
+ if(dsi_connector->pipe)
+ dpi_output->panel_on = 0;
+
+ dpi_output->panel_on = 0;
+
+
+ dpi_output->dev = dev;
+ dpi_output->first_boot = 1;
+
+ /* Get fixed mode */
+ dsi_config = mdfld_dsi_get_config(dsi_connector);
+ fixed_mode = dsi_config->fixed_mode;
+
+ /* Create drm encoder object */
+ connector = &dsi_connector->base.base;
+ encoder = &dpi_output->base.base;
+ drm_encoder_init(dev,
+ encoder,
+ p_funcs->encoder_funcs,
+ DRM_MODE_ENCODER_MIPI);
+ drm_encoder_helper_add(encoder,
+ p_funcs->encoder_helper_funcs);
+
+ /* Attach to given connector */
+ drm_mode_connector_attach_encoder(connector, encoder);
+
+ /* Set possible crtcs and clones */
+ if(dsi_connector->pipe) {
+ encoder->possible_crtcs = (1 << 2);
+ encoder->possible_clones = (1 << 1);
+ } else {
+ encoder->possible_crtcs = (1 << 0);
+ encoder->possible_clones = (1 << 0);
+ }
+
+ dev_priv->dsr_fb_update = 0;
+ dev_priv->dsr_enable = false;
+ dev_priv->exit_idle = mdfld_dsi_dpi_exit_idle;
+#if defined(CONFIG_MDFLD_DSI_DPU) || defined(CONFIG_MDFLD_DSI_DSR)
+ dev_priv->dsr_enable_config = true;
+#endif /*CONFIG_MDFLD_DSI_DSR*/
+
+ return &dpi_output->base;
+
+out_err1:
+ if(dpi_output)
+ kfree(dpi_output);
+ return NULL;
+}
+
diff --git a/drivers/staging/gma500/mdfld_dsi_dpi.h b/drivers/staging/gma500/mdfld_dsi_dpi.h
new file mode 100644
index 0000000..68e65cc
--- /dev/null
+++ b/drivers/staging/gma500/mdfld_dsi_dpi.h
@@ -0,0 +1,80 @@
+/*
+ * Copyright © 2010 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ * jim liu <jim...@intel.com>
+ * Jackie Li<yaodo...@intel.com>
+ */
+
+#ifndef __MDFLD_DSI_DPI_H__
+#define __MDFLD_DSI_DPI_H__
+
+#include "mdfld_dsi_output.h"
+#include "mdfld_output.h"
+
+struct mdfld_dsi_dpi_timing {
+ u16 hsync_count;
+ u16 hbp_count;
+ u16 hfp_count;
+ u16 hactive_count;
+ u16 vsync_count;
+ u16 vbp_count;
+ u16 vfp_count;
+};
+
+struct mdfld_dsi_dpi_output {
+ struct mdfld_dsi_encoder base;
+ struct drm_device *dev;
+
+ int panel_on;
+ int first_boot;
+};
+
+#define MDFLD_DSI_DPI_OUTPUT(dsi_encoder) \
+ container_of(dsi_encoder, struct mdfld_dsi_dpi_output, base)
+
+extern int mdfld_dsi_dpi_timing_calculation(struct drm_display_mode *mode,
+ struct mdfld_dsi_dpi_timing *dpi_timing,
+ int num_lane, int bpp);
+extern struct mdfld_dsi_encoder *mdfld_dsi_dpi_init(struct drm_device *dev,
+ struct mdfld_dsi_connector *dsi_connector,
+ struct panel_funcs *p_funcs);
+
+/* Medfield DPI helper functions */
+extern void mdfld_dsi_dpi_dpms(struct drm_encoder *encoder, int mode);
+extern bool mdfld_dsi_dpi_mode_fixup(struct drm_encoder *encoder,
+ struct drm_display_mode *mode,
+ struct drm_display_mode *adjusted_mode);
+extern void mdfld_dsi_dpi_prepare(struct drm_encoder *encoder);
+extern void mdfld_dsi_dpi_commit(struct drm_encoder *encoder);
+extern void mdfld_dsi_dpi_mode_set(struct drm_encoder *encoder,
+ struct drm_display_mode *mode,
+ struct drm_display_mode *adjusted_mode);
+extern void mdfld_dsi_dpi_turn_on(struct mdfld_dsi_dpi_output *output,
+ int pipe);
+extern void mdfld_dsi_dpi_controller_init(struct mdfld_dsi_config *si_config,
+ int pipe);
+extern void mid_enable_pipe_event(struct drm_psb_private *dev_priv, int pipe);
+extern void psb_enable_pipestat(struct drm_psb_private *dev_priv, int pipe,
+ u32 mask);
+
+#endif /*__MDFLD_DSI_DPI_H__*/
diff --git a/drivers/staging/gma500/mdfld_dsi_output.c b/drivers/staging/gma500/mdfld_dsi_output.c
new file mode 100644
index 0000000..44ee3f6
--- /dev/null
+++ b/drivers/staging/gma500/mdfld_dsi_output.c
@@ -0,0 +1,977 @@
+/*
+ * Copyright © 2010 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ * jim liu <jim...@intel.com>
+ * Jackie Li<yaodo...@intel.com>
+ */
+
+#include "mdfld_dsi_output.h"
+#include "mdfld_dsi_dbi.h"
+#include "mdfld_dsi_dpi.h"
+#include "mdfld_output.h"
+#include <asm/intel_scu_ipc.h>
+#include "mdfld_dsi_pkg_sender.h"
+#include <linux/pm_runtime.h>
+
+#define MDFLD_DSI_BRIGHTNESS_MAX_LEVEL 100
+
+/* get the CABC LABC from command line. */
+static int CABC_control = 1;
+static int LABC_control = 1;
+
+#ifdef MODULE
+module_param (CABC_control, int, 0644);
+module_param (LABC_control, int, 0644);
+#else
+static int __init parse_CABC_control(char *arg)
+{
+ /* CABC control can be passed in as a cmdline parameter */
+ /* to enable this feature add CABC=1 to cmdline */
+ /* to disable this feature add CABC=0 to cmdline */
+ if (!arg)
+ return -EINVAL;
+
+ if (!strcasecmp(arg, "0"))
+ CABC_control = 0;
+ else if (!strcasecmp (arg, "1"))
+ CABC_control = 1;


+
+ return 0;
+}

+early_param ("CABC", parse_CABC_control);
+
+static int __init parse_LABC_control(char *arg)
+{
+ /* LABC control can be passed in as a cmdline parameter */
+ /* to enable this feature add LABC=1 to cmdline */
+ /* to disable this feature add LABC=0 to cmdline */
+ if (!arg)
+ return -EINVAL;
+
+ if (!strcasecmp(arg, "0"))
+ LABC_control = 0;
+ else if (!strcasecmp (arg, "1"))
+ LABC_control = 1;


+
+ return 0;
+}

+early_param ("LABC", parse_LABC_control);
+#endif
+
+/**
+ * make these MCS command global
+ * we don't need 'movl' everytime we send them.
+ * FIXME: these datas were provided by OEM, we should get them from GCT.
+ **/
+static u32 mdfld_dbi_mcs_hysteresis[] = {
+ 0x42000f57, 0x8c006400, 0xff00bf00, 0xffffffff,
+ 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+ 0x38000aff, 0x82005000, 0xff00ab00, 0xffffffff,
+ 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff,
+ 0x000000ff,
+};
+
+static u32 mdfld_dbi_mcs_display_profile[] = {
+ 0x50281450, 0x0000c882, 0x00000000, 0x00000000,
+ 0x00000000,
+};
+
+static u32 mdfld_dbi_mcs_kbbc_profile[] = {
+ 0x00ffcc60, 0x00000000, 0x00000000, 0x00000000,
+};
+
+static u32 mdfld_dbi_mcs_gamma_profile[] = {
+ 0x81111158, 0x88888888, 0x88888888,
+};
+
+/*
+ * write hysteresis values.
+ */
+static void mdfld_dsi_write_hysteresis (struct mdfld_dsi_config * dsi_config, int pipe)
+{
+ struct mdfld_dsi_pkg_sender * sender = mdfld_dsi_get_pkg_sender(dsi_config);
+
+ if(!sender) {
+ WARN_ON(1);
+ return;
+ }
+ mdfld_dsi_send_mcs_long_hs(sender,
+ mdfld_dbi_mcs_hysteresis,
+ 17,
+ MDFLD_DSI_SEND_PACKAGE);
+}
+
+/*
+ * write display profile values.
+ */
+static void mdfld_dsi_write_display_profile (struct mdfld_dsi_config * dsi_config, int pipe)
+{
+ struct mdfld_dsi_pkg_sender * sender = mdfld_dsi_get_pkg_sender(dsi_config);
+
+ if(!sender) {
+ WARN_ON(1);
+ return;
+ }
+ mdfld_dsi_send_mcs_long_hs(sender,
+ mdfld_dbi_mcs_display_profile,
+ 5,
+ MDFLD_DSI_SEND_PACKAGE);
+}
+
+/*
+ * write KBBC profile values.
+ */
+static void mdfld_dsi_write_kbbc_profile (struct mdfld_dsi_config * dsi_config, int pipe)
+{
+ struct mdfld_dsi_pkg_sender * sender = mdfld_dsi_get_pkg_sender(dsi_config);
+
+ if(!sender) {
+ WARN_ON(1);
+ return;
+ }
+ mdfld_dsi_send_mcs_long_hs(sender,
+ mdfld_dbi_mcs_kbbc_profile,
+ 4,
+ MDFLD_DSI_SEND_PACKAGE);
+}
+
+/**
+ * write gamma setting.
+ */
+static void mdfld_dsi_write_gamma_setting (struct mdfld_dsi_config * dsi_config, int pipe)
+{
+ struct mdfld_dsi_pkg_sender * sender = mdfld_dsi_get_pkg_sender(dsi_config);
+
+ if(!sender) {
+ WARN_ON(1);
+ return;
+ }
+ mdfld_dsi_send_mcs_long_hs(sender,
+ mdfld_dbi_mcs_gamma_profile,
+ 3,
+ MDFLD_DSI_SEND_PACKAGE);
+}
+
+/**
+ * Check and see if the generic control or data buffer is empty and ready.
+ */
+void mdfld_dsi_gen_fifo_ready (struct drm_device *dev, u32 gen_fifo_stat_reg, u32 fifo_stat)
+{
+ u32 GEN_BF_time_out_count = 0;
+
+ /* Check MIPI Adatper command registers */
+ for (GEN_BF_time_out_count = 0; GEN_BF_time_out_count < GEN_FB_TIME_OUT; GEN_BF_time_out_count++)
+ {
+ if ((REG_READ(gen_fifo_stat_reg) & fifo_stat) == fifo_stat)
+ break;
+ udelay (100);
+ }
+
+ if (GEN_BF_time_out_count == GEN_FB_TIME_OUT)
+ dev_err(dev->dev,
+ "mdfld_dsi_gen_fifo_ready, Timeout. gen_fifo_stat_reg = 0x%x. \n",
+ gen_fifo_stat_reg);
+}
+
+/**
+ * Manage the DSI MIPI keyboard and display brightness.
+ * FIXME: this is exported to OSPM code. should work out an specific
+ * display interface to OSPM.
+ */
+void mdfld_dsi_brightness_init (struct mdfld_dsi_config * dsi_config, int pipe)
+{
+ struct mdfld_dsi_pkg_sender * sender = mdfld_dsi_get_pkg_sender(dsi_config);
+ struct drm_device * dev = sender->dev;
+ struct drm_psb_private * dev_priv = dev->dev_private;
+ u32 gen_ctrl_val;
+
+ if(!sender) {
+ WARN_ON(1);
+ return;
+ }
+ /* Set default display backlight value to 85% (0xd8)*/
+ mdfld_dsi_send_mcs_short_hs(sender,
+ write_display_brightness,
+ 0xd8,
+ 1,
+ MDFLD_DSI_SEND_PACKAGE);
+
+ /* Set minimum brightness setting of CABC function to 20% (0x33)*/
+ mdfld_dsi_send_mcs_short_hs(sender,
+ write_cabc_min_bright,
+ 0x33,
+ 1,
+ MDFLD_DSI_SEND_PACKAGE);
+
+ mdfld_dsi_write_hysteresis (dsi_config, pipe);
+ mdfld_dsi_write_display_profile (dsi_config, pipe);
+ mdfld_dsi_write_kbbc_profile (dsi_config, pipe);
+ mdfld_dsi_write_gamma_setting (dsi_config, pipe);
+
+ /* Enable backlight or/and LABC */
+ gen_ctrl_val = BRIGHT_CNTL_BLOCK_ON | DISPLAY_DIMMING_ON| BACKLIGHT_ON;
+ if (LABC_control == 1 || CABC_control == 1)
+ gen_ctrl_val |= DISPLAY_DIMMING_ON| DISPLAY_BRIGHTNESS_AUTO | GAMMA_AUTO;
+
+ if (LABC_control == 1)
+ gen_ctrl_val |= AMBIENT_LIGHT_SENSE_ON;
+
+ dev_priv->mipi_ctrl_display = gen_ctrl_val;
+
+ mdfld_dsi_send_mcs_short_hs(sender,
+ write_ctrl_display,
+ (u8)gen_ctrl_val,
+ 1,
+ MDFLD_DSI_SEND_PACKAGE);
+
+ if (CABC_control == 0)
+ return;
+ mdfld_dsi_send_mcs_short_hs(sender,
+ write_ctrl_cabc,
+ UI_IMAGE,
+ 1,
+ MDFLD_DSI_SEND_PACKAGE);
+}
+
+/**
+ * Manage the mipi display brightness.
+ * TODO: refine this interface later
+ */
+void mdfld_dsi_brightness_control(struct drm_device *dev, int pipe, int level)
+{
+ struct mdfld_dsi_pkg_sender *sender;
+ struct drm_psb_private *dev_priv;
+ struct mdfld_dsi_config *dsi_config;
+ u32 gen_ctrl_val = 0;
+ int p_type = TMD_VID;
+
+ if (!dev || (pipe != 0 && pipe != 2)) {
+ dev_err(dev->dev, "Invalid parameter\n");
+ return;
+ }
+
+ p_type = mdfld_get_panel_type(dev, 0);
+


+ dev_priv = dev->dev_private;

+
+ if(pipe)
+ dsi_config = dev_priv->dsi_configs[1];
+ else
+ dsi_config = dev_priv->dsi_configs[0];
+
+ sender = mdfld_dsi_get_pkg_sender(dsi_config);
+
+ if(!sender) {
+ WARN_ON(1);
+ return;
+ }
+
+ gen_ctrl_val = ((level * 0xff) / MDFLD_DSI_BRIGHTNESS_MAX_LEVEL) & 0xff;
+
+ dev_dbg(dev->dev, "pipe = %d, gen_ctrl_val = %d. \n", pipe, gen_ctrl_val);
+
+ if(p_type == TMD_VID || p_type == TMD_CMD){
+ /* Set display backlight value */
+ mdfld_dsi_send_mcs_short_hs(sender,
+ tmd_write_display_brightness,
+ (u8)gen_ctrl_val,
+ 1,
+ MDFLD_DSI_SEND_PACKAGE);
+ } else {
+ /* Set display backlight value */
+ mdfld_dsi_send_mcs_short_hs(sender,
+ write_display_brightness,
+ (u8)gen_ctrl_val,
+ 1,
+ MDFLD_DSI_SEND_PACKAGE);
+
+
+ /* Enable backlight control */
+ if (level == 0)
+ gen_ctrl_val = 0;
+ else
+ gen_ctrl_val = dev_priv->mipi_ctrl_display;
+
+ mdfld_dsi_send_mcs_short_hs(sender,
+ write_ctrl_display,
+ (u8)gen_ctrl_val,
+ 1,
+ MDFLD_DSI_SEND_PACKAGE);
+ }
+}
+
+/*
+ * shut down DSI controller
+ */
+void mdfld_dsi_controller_shutdown(struct mdfld_dsi_config * dsi_config, int pipe)
+{
+ struct drm_device * dev;
+ u32 reg_offset = pipe ? MIPIC_REG_OFFSET : 0;
+ int retry = 100;
+
+ if (!dsi_config) {
+ WARN_ON(1);
+ return;
+ }
+
+ dev = dsi_config->dev;
+
+ if (!gma_power_begin(dev, true)) {
+ dev_err(dev->dev, "hw begin failed\n");
+ return;
+ }
+
+ if(!(REG_READ(MIPIA_DEVICE_READY_REG + reg_offset) & DSI_DEVICE_READY))
+ goto shutdown_out;
+
+ /*send shut down package, clean packet send bit first*/
+ if(REG_READ(MIPIA_INTR_STAT_REG + reg_offset) & DSI_INTR_STATE_SPL_PKG_SENT) {
+ REG_WRITE((MIPIA_INTR_STAT_REG + reg_offset),
+ (REG_READ(MIPIA_INTR_STAT_REG + reg_offset) | DSI_INTR_STATE_SPL_PKG_SENT));
+ }
+
+ /*send shut down package in HS*/
+ REG_WRITE((MIPIA_DPI_CONTROL_REG + reg_offset), DSI_DPI_CTRL_HS_SHUTDOWN);
+
+
+ /*
+ * make sure shut down is sent.
+ * FIXME: add max retry counter
+ */
+ while(!(REG_READ(MIPIA_INTR_STAT_REG + reg_offset) & DSI_INTR_STATE_SPL_PKG_SENT)) {
+ retry--;
+
+ if(!retry) {
+ dev_err(dev->dev, "timeout\n");
+ break;
+ }
+ }
+
+ /*sleep 1 ms to ensure shutdown finished*/
+ msleep(100);
+
+ /*un-ready device*/
+ REG_WRITE((MIPIA_DEVICE_READY_REG + reg_offset),
+ (REG_READ(MIPIA_DEVICE_READY_REG + reg_offset) & ~DSI_DEVICE_READY));
+
+shutdown_out:
+ gma_power_end(dev);
+}
+
+void mdfld_dsi_controller_startup(struct mdfld_dsi_config * dsi_config, int pipe)
+{
+ struct drm_device * dev;
+ u32 reg_offset = pipe ? MIPIC_REG_OFFSET : 0;
+ int retry = 100;
+
+
+ if (!dsi_config) {
+ WARN_ON(1);
+ return;
+ }
+
+ dev = dsi_config->dev;
+ dev_dbg(dev->dev, "starting up DSI controller on pipe %d...\n", pipe);
+
+ if (!gma_power_begin(dev, true)) {
+ dev_err(dev->dev, "hw begin failed\n");
+ return;
+ }
+
+ if((REG_READ(MIPIA_DEVICE_READY_REG + reg_offset) & DSI_DEVICE_READY))
+ goto startup_out;
+
+ /*if config DPI, turn on DPI interface*/
+ if(dsi_config->type == MDFLD_DSI_ENCODER_DPI) {
+ if(REG_READ(MIPIA_INTR_STAT_REG + reg_offset) & DSI_INTR_STATE_SPL_PKG_SENT) {
+ REG_WRITE((MIPIA_INTR_STAT_REG + reg_offset), DSI_INTR_STATE_SPL_PKG_SENT);
+ }
+
+ REG_WRITE((MIPIA_DPI_CONTROL_REG + reg_offset), DSI_DPI_CTRL_HS_TURN_ON);
+
+ /*
+ * make sure shut down is sent.
+ * FIXME: add max retry counter
+ */
+ while(!(REG_READ(MIPIA_INTR_STAT_REG + reg_offset) & DSI_INTR_STATE_SPL_PKG_SENT)) {
+ retry--;
+ if(!retry) {
+ dev_err(dev->dev, "timeout\n");
+ break;
+ }
+ }
+
+ msleep(100);
+ }
+
+ /*set device ready*/
+ REG_WRITE((MIPIA_DEVICE_READY_REG + reg_offset),
+ (REG_READ(MIPIA_DEVICE_READY_REG + reg_offset) | DSI_DEVICE_READY));
+
+startup_out:
+ gma_power_end(dev);
+}
+
+/*
+ * NOTE: this function was used by OSPM.
+ * TODO: will be removed later, should work out display interfaces for OSPM
+ */
+void mdfld_dsi_controller_init(struct mdfld_dsi_config * dsi_config, int pipe)
+{
+ if(!dsi_config || ((pipe != 0) && (pipe != 2))) {
+ WARN_ON(1);
+ return;
+ }
+
+ if(dsi_config->type)
+ mdfld_dsi_dpi_controller_init(dsi_config, pipe);
+ else
+ mdfld_dsi_controller_dbi_init(dsi_config, pipe);
+}
+
+static void mdfld_dsi_connector_save(struct drm_connector * connector)
+{
+}
+
+static void mdfld_dsi_connector_restore(struct drm_connector * connector)
+{
+}
+
+static enum drm_connector_status mdfld_dsi_connector_detect(struct drm_connector * connector, bool force)
+{
+ return connector_status_connected;
+}
+
+static int mdfld_dsi_connector_set_property(struct drm_connector * connector,
+ struct drm_property * property,
+ uint64_t value)
+{
+ struct drm_encoder * encoder = connector->encoder;
+ struct backlight_device * psb_bd;
+
+ if (!strcmp(property->name, "scaling mode") && encoder) {
+ struct psb_intel_crtc * psb_crtc = to_psb_intel_crtc(encoder->crtc);
+ bool bTransitionFromToCentered;
+ uint64_t curValue;
+
+ if (!psb_crtc)
+ goto set_prop_error;
+
+ switch (value) {
+ case DRM_MODE_SCALE_FULLSCREEN:
+ break;
+ case DRM_MODE_SCALE_NO_SCALE:
+ break;
+ case DRM_MODE_SCALE_ASPECT:
+ break;
+ default:
+ goto set_prop_error;
+ }
+
+ if (drm_connector_property_get_value(connector, property, &curValue))
+ goto set_prop_error;
+
+ if (curValue == value)
+ goto set_prop_done;
+
+ if (drm_connector_property_set_value(connector, property, value))
+ goto set_prop_error;
+
+ bTransitionFromToCentered = (curValue == DRM_MODE_SCALE_NO_SCALE) ||
+ (value == DRM_MODE_SCALE_NO_SCALE);
+
+ if (psb_crtc->saved_mode.hdisplay != 0 &&
+ psb_crtc->saved_mode.vdisplay != 0) {
+ if (bTransitionFromToCentered) {
+ if (!drm_crtc_helper_set_mode(encoder->crtc, &psb_crtc->saved_mode,
+ encoder->crtc->x, encoder->crtc->y, encoder->crtc->fb))
+ goto set_prop_error;
+ } else {
+ struct drm_encoder_helper_funcs *pEncHFuncs = encoder->helper_private;
+ pEncHFuncs->mode_set(encoder, &psb_crtc->saved_mode,
+ &psb_crtc->saved_adjusted_mode);
+ }
+ }
+ } else if (!strcmp(property->name, "backlight") && encoder) {
+ dev_dbg(encoder->dev->dev, "backlight level = %d\n", (int)value);
+ if (drm_connector_property_set_value(connector, property, value))
+ goto set_prop_error;
+ else {
+ dev_dbg(encoder->dev->dev,
+ "set brightness to %d", (int)value);
+ psb_bd = psb_get_backlight_device();
+ if(psb_bd) {
+ psb_bd->props.brightness = value;
+ psb_set_brightness(psb_bd);
+ }
+ }
+ }
+set_prop_done:
+ return 0;
+set_prop_error:
+ return -1;
+}
+
+static void mdfld_dsi_connector_destroy(struct drm_connector * connector)
+{
+ struct psb_intel_output * psb_output = to_psb_intel_output(connector);
+ struct mdfld_dsi_connector * dsi_connector = MDFLD_DSI_CONNECTOR(psb_output);
+ struct mdfld_dsi_pkg_sender * sender;
+
+ if(!dsi_connector)
+ return;
+
+ drm_sysfs_connector_remove(connector);
+ drm_connector_cleanup(connector);
+
+ sender = dsi_connector->pkg_sender;
+
+ mdfld_dsi_pkg_sender_destroy(sender);
+
+ kfree(dsi_connector);
+}
+
+static int mdfld_dsi_connector_get_modes(struct drm_connector * connector)
+{
+ struct psb_intel_output * psb_output = to_psb_intel_output(connector);
+ struct mdfld_dsi_connector * dsi_connector = MDFLD_DSI_CONNECTOR(psb_output);
+ struct mdfld_dsi_config * dsi_config = mdfld_dsi_get_config(dsi_connector);
+ struct drm_display_mode * fixed_mode = dsi_config->fixed_mode;
+ struct drm_display_mode * dup_mode = NULL;
+ struct drm_device * dev = connector->dev;
+
+ connector->display_info.min_vfreq = 0;
+ connector->display_info.max_vfreq = 200;
+ connector->display_info.min_hfreq = 0;
+ connector->display_info.max_hfreq = 200;
+
+ if(fixed_mode) {
+ dev_dbg(dev->dev, "fixed_mode %dx%d\n",
+ fixed_mode->hdisplay, fixed_mode->vdisplay);
+
+ dup_mode = drm_mode_duplicate(dev, fixed_mode);
+ drm_mode_probed_add(connector, dup_mode);
+ return 1;
+ }
+ dev_err(dev->dev, "Didn't get any modes!\n");


+ return 0;
+}
+

+static int mdfld_dsi_connector_mode_valid(struct drm_connector * connector, struct drm_display_mode * mode)
+{
+ struct psb_intel_output * psb_output = to_psb_intel_output(connector);
+ struct mdfld_dsi_connector * dsi_connector = MDFLD_DSI_CONNECTOR(psb_output);
+ struct mdfld_dsi_config * dsi_config = mdfld_dsi_get_config(dsi_connector);
+ struct drm_display_mode * fixed_mode = dsi_config->fixed_mode;
+
+ dev_dbg(connector->dev->dev, "mode %p, fixed mode %p\n",
+ mode, fixed_mode);
+
+ if(mode->flags & DRM_MODE_FLAG_DBLSCAN)
+ return MODE_NO_DBLESCAN;
+
+ if(mode->flags & DRM_MODE_FLAG_INTERLACE)
+ return MODE_NO_INTERLACE;
+
+ /**
+ * FIXME: current DC has no fitting unit, reject any mode setting request
+ * will figure out a way to do up-scaling(pannel fitting) later.
+ **/
+ if(fixed_mode) {
+ if(mode->hdisplay != fixed_mode->hdisplay)
+ return MODE_PANEL;
+
+ if(mode->vdisplay != fixed_mode->vdisplay)
+ return MODE_PANEL;
+ }
+ dev_dbg(connector->dev->dev, "mode ok\n");
+
+ return MODE_OK;
+}
+
+static void mdfld_dsi_connector_dpms(struct drm_connector *connector, int mode)
+{
+#ifdef CONFIG_PM_RUNTIME
+ struct drm_device * dev = connector->dev;
+ struct drm_psb_private * dev_priv = dev->dev_private;
+ bool panel_on, panel_on2;
+#endif
+ /* First, execute DPMS */
+ drm_helper_connector_dpms(connector, mode);
+
+#ifdef CONFIG_PM_RUNTIME
+ if(mdfld_panel_dpi(dev)) {
+ /* DPI panel */
+ panel_on = dev_priv->dpi_panel_on;
+ panel_on2 = dev_priv->dpi_panel_on2;
+ } else {
+ /* DBI panel */
+ panel_on = dev_priv->dbi_panel_on;
+ panel_on2 = dev_priv->dbi_panel_on2;
+ }
+
+ /* Then check all display panels + monitors status */
+ if(!panel_on && !panel_on2 && !(REG_READ(HDMIB_CONTROL)
+ & HDMIB_PORT_EN)) {
+ /*request rpm idle*/
+ if(dev_priv->rpm_enabled)
+ pm_request_idle(&dev->pdev->dev);
+ }
+ /*
+ * if rpm wasn't enabled yet, try to allow it
+ * FIXME: won't enable rpm for DPI since DPI
+ * CRTC setting is a little messy now.
+ * Enable it later!
+ */
+#if 0
+ if(!dev_priv->rpm_enabled && !mdfld_panel_dpi(dev))
+ ospm_runtime_pm_allow(dev);
+#endif
+#endif
+}
+
+static struct drm_encoder * mdfld_dsi_connector_best_encoder(
+ struct drm_connector * connector)
+{
+ struct psb_intel_output * psb_output = to_psb_intel_output(connector);
+ struct mdfld_dsi_connector * dsi_connector = MDFLD_DSI_CONNECTOR(psb_output);
+ struct mdfld_dsi_config * dsi_config = mdfld_dsi_get_config(dsi_connector);
+ struct mdfld_dsi_encoder * encoder = NULL;
+
+ if(dsi_config->type == MDFLD_DSI_ENCODER_DBI)
+ encoder = dsi_config->encoders[MDFLD_DSI_ENCODER_DBI];
+ else if (dsi_config->type == MDFLD_DSI_ENCODER_DPI)
+ encoder = dsi_config->encoders[MDFLD_DSI_ENCODER_DPI];
+
+ dev_dbg(connector->dev->dev, "get encoder %p\n", encoder);
+
+ if(!encoder) {
+ dev_err(connector->dev->dev,
+ "Invalid encoder for type %d\n", dsi_config->type);
+ return NULL;
+ }
+ dsi_config->encoder = encoder;
+ return &encoder->base;
+}
+
+/* DSI connector funcs */
+static const struct drm_connector_funcs mdfld_dsi_connector_funcs = {
+ .dpms = /*drm_helper_connector_dpms*/mdfld_dsi_connector_dpms,
+ .save = mdfld_dsi_connector_save,
+ .restore = mdfld_dsi_connector_restore,
+ .detect = mdfld_dsi_connector_detect,
+ .fill_modes = drm_helper_probe_single_connector_modes,
+ .set_property = mdfld_dsi_connector_set_property,
+ .destroy = mdfld_dsi_connector_destroy,
+};
+
+/* DSI connector helper funcs */
+static const struct drm_connector_helper_funcs mdfld_dsi_connector_helper_funcs = {
+ .get_modes = mdfld_dsi_connector_get_modes,
+ .mode_valid = mdfld_dsi_connector_mode_valid,
+ .best_encoder = mdfld_dsi_connector_best_encoder,
+};
+
+static int mdfld_dsi_get_default_config(struct drm_device * dev,
+ struct mdfld_dsi_config * config, int pipe)
+{
+ if(!dev || !config) {
+ WARN_ON(1);


+ return -EINVAL;
+ }
+

+ config->bpp = 24;
+ config->type = mdfld_panel_dpi(dev);
+ config->lane_count = 2;
+ config->channel_num = 0;
+ /*NOTE: video mode is ignored when type is MDFLD_DSI_ENCODER_DBI*/
+ if (mdfld_get_panel_type(dev, pipe) == TMD_VID) {
+ config->video_mode = MDFLD_DSI_VIDEO_NON_BURST_MODE_SYNC_PULSE;
+ } else {
+ config->video_mode = MDFLD_DSI_VIDEO_BURST_MODE;
+ }


+
+ return 0;
+}
+

+/*
+ * Returns the panel fixed mode from configuration.
+ */
+struct drm_display_mode *
+mdfld_dsi_get_configuration_mode(struct mdfld_dsi_config * dsi_config, int pipe)
+{
+ struct drm_device *dev = dsi_config->dev;
+ struct drm_display_mode *mode;
+ struct drm_psb_private *dev_priv = dev->dev_private;
+ struct mrst_timing_info *ti = &dev_priv->gct_data.DTD;
+ bool use_gct = false;
+
+ mode = kzalloc(sizeof(*mode), GFP_KERNEL);
+ if (!mode) {
+ dev_err(dev->dev, "Out of memory for mode\n");
+ return NULL;
+ }
+ if (use_gct) {
+ dev_dbg(dev->dev, "gct find MIPI panel.\n");
+
+ mode->hdisplay = (ti->hactive_hi << 8) | ti->hactive_lo;
+ mode->vdisplay = (ti->vactive_hi << 8) | ti->vactive_lo;
+ mode->hsync_start = mode->hdisplay + \
+ ((ti->hsync_offset_hi << 8) | \
+ ti->hsync_offset_lo);
+ mode->hsync_end = mode->hsync_start + \
+ ((ti->hsync_pulse_width_hi << 8) | \
+ ti->hsync_pulse_width_lo);
+ mode->htotal = mode->hdisplay + ((ti->hblank_hi << 8) | \
+ ti->hblank_lo);
+ mode->vsync_start = \
+ mode->vdisplay + ((ti->vsync_offset_hi << 8) | \
+ ti->vsync_offset_lo);
+ mode->vsync_end = \
+ mode->vsync_start + ((ti->vsync_pulse_width_hi << 8) | \
+ ti->vsync_pulse_width_lo);
+ mode->vtotal = mode->vdisplay + \
+ ((ti->vblank_hi << 8) | ti->vblank_lo);
+ mode->clock = ti->pixel_clock * 10;
+
+ dev_dbg(dev->dev, "hdisplay is %d\n", mode->hdisplay);
+ dev_dbg(dev->dev, "vdisplay is %d\n", mode->vdisplay);
+ dev_dbg(dev->dev, "HSS is %d\n", mode->hsync_start);
+ dev_dbg(dev->dev, "HSE is %d\n", mode->hsync_end);
+ dev_dbg(dev->dev, "htotal is %d\n", mode->htotal);
+ dev_dbg(dev->dev, "VSS is %d\n", mode->vsync_start);
+ dev_dbg(dev->dev, "VSE is %d\n", mode->vsync_end);
+ dev_dbg(dev->dev, "vtotal is %d\n", mode->vtotal);
+ dev_dbg(dev->dev, "clock is %d\n", mode->clock);
+ } else {
+ if(dsi_config->type == MDFLD_DSI_ENCODER_DPI) {
+ if (mdfld_get_panel_type(dev, pipe) == TMD_VID) {
+ mode->hdisplay = 480;
+ mode->vdisplay = 854;
+ mode->hsync_start = 487;
+ mode->hsync_end = 490;
+ mode->htotal = 499;
+ mode->vsync_start = 861;
+ mode->vsync_end = 865;
+ mode->vtotal = 873;
+ mode->clock = 33264;
+ } else {
+ mode->hdisplay = 864;
+ mode->vdisplay = 480;
+ mode->hsync_start = 873;
+ mode->hsync_end = 876;
+ mode->htotal = 887;
+ mode->vsync_start = 487;
+ mode->vsync_end = 490;
+ mode->vtotal = 499;
+ mode->clock = 33264;
+ }
+ } else if(dsi_config->type == MDFLD_DSI_ENCODER_DBI) {
+ mode->hdisplay = 864;
+ mode->vdisplay = 480;
+ mode->hsync_start = 872;
+ mode->hsync_end = 876;
+ mode->htotal = 884;
+ mode->vsync_start = 482;
+ mode->vsync_end = 494;
+ mode->vtotal = 486;
+ mode->clock = 25777;
+
+ }
+ }
+
+ drm_mode_set_name(mode);
+ drm_mode_set_crtcinfo(mode, 0);
+
+ mode->type |= DRM_MODE_TYPE_PREFERRED;
+
+ return mode;
+}
+
+/*
+ * MIPI output init
+ * @dev drm device
+ * @pipe pipe number. 0 or 2
+ * @config
+ *
+ * Do the initialization of a MIPI output, including create DRM mode objects
+ * initialization of DSI output on @pipe
+ */
+void mdfld_dsi_output_init(struct drm_device * dev,
+ int pipe,
+ struct mdfld_dsi_config * config,
+ struct panel_funcs* p_cmd_funcs,
+ struct panel_funcs* p_vid_funcs)
+{
+ struct mdfld_dsi_config * dsi_config;
+ struct mdfld_dsi_connector * dsi_connector;
+ struct psb_intel_output * psb_output;
+ struct drm_connector * connector;
+ struct mdfld_dsi_encoder * encoder;
+ struct drm_psb_private * dev_priv = dev->dev_private;
+ struct panel_info dsi_panel_info;
+ u32 width_mm, height_mm;
+
+ dev_dbg(dev->dev, "init DSI output on pipe %d\n", pipe);
+
+ if(!dev || ((pipe != 0) && (pipe != 2))) {
+ WARN_ON(1);
+ return;
+ }
+
+ /*create a new connetor*/
+ dsi_connector = kzalloc(sizeof(struct mdfld_dsi_connector), GFP_KERNEL);
+ if(!dsi_connector) {
+ DRM_ERROR("No memory");
+ return;
+ }
+
+ dsi_connector->pipe = pipe;
+
+ /*set DSI config*/
+ if(config) {
+ dsi_config = config;
+ } else {
+ dsi_config = kzalloc(sizeof(struct mdfld_dsi_config), GFP_KERNEL);
+ if(!dsi_config) {
+ dev_err(dev->dev,
+ "cannot allocate memory for DSI config\n");
+ goto dsi_init_err0;
+ }
+
+ mdfld_dsi_get_default_config(dev, dsi_config, pipe);
+ }
+
+ dsi_connector->private = dsi_config;
+
+ dsi_config->changed = 1;
+ dsi_config->dev = dev;
+
+ /*init fixed mode basing on DSI config type*/
+ if(dsi_config->type == MDFLD_DSI_ENCODER_DBI) {
+ dsi_config->fixed_mode = p_cmd_funcs->get_config_mode(dev);
+ if(p_cmd_funcs->get_panel_info(dev, pipe, &dsi_panel_info))
+ goto dsi_init_err0;
+ } else if(dsi_config->type == MDFLD_DSI_ENCODER_DPI) {
+ dsi_config->fixed_mode = p_vid_funcs->get_config_mode(dev);
+ if(p_vid_funcs->get_panel_info(dev, pipe, &dsi_panel_info))
+ goto dsi_init_err0;
+ }
+
+ width_mm = dsi_panel_info.width_mm;
+ height_mm = dsi_panel_info.height_mm;
+
+ dsi_config->mode = dsi_config->fixed_mode;
+ dsi_config->connector = dsi_connector;
+
+ if(!dsi_config->fixed_mode) {
+ dev_err(dev->dev, "No pannel fixed mode was found\n");
+ goto dsi_init_err0;
+ }
+
+ if(pipe && dev_priv->dsi_configs[0]) {
+ dsi_config->dvr_ic_inited = 0;
+ dev_priv->dsi_configs[1] = dsi_config;
+ } else if(pipe == 0) {
+ dsi_config->dvr_ic_inited = 1;
+ dev_priv->dsi_configs[0] = dsi_config;
+ } else {
+ dev_err(dev->dev, "Trying to init MIPI1 before MIPI0\n");
+ goto dsi_init_err0;
+ }
+
+ /*init drm connector object*/
+ psb_output = &dsi_connector->base;
+
+ psb_output->type = (pipe == 0) ? INTEL_OUTPUT_MIPI : INTEL_OUTPUT_MIPI2;
+
+ connector = &psb_output->base;
+ drm_connector_init(dev, connector, &mdfld_dsi_connector_funcs, DRM_MODE_CONNECTOR_MIPI);
+ drm_connector_helper_add(connector, &mdfld_dsi_connector_helper_funcs);
+
+ connector->display_info.subpixel_order = SubPixelHorizontalRGB;
+ connector->display_info.width_mm = width_mm;
+ connector->display_info.height_mm = height_mm;
+ connector->interlace_allowed = false;
+ connector->doublescan_allowed = false;
+
+ /*attach properties*/
+ drm_connector_attach_property(connector, dev->mode_config.scaling_mode_property, DRM_MODE_SCALE_FULLSCREEN);
+ drm_connector_attach_property(connector, dev_priv->backlight_property, MDFLD_DSI_BRIGHTNESS_MAX_LEVEL);
+
+ /*init DBI & DPI encoders*/
+ if(p_cmd_funcs) {
+ encoder = mdfld_dsi_dbi_init(dev, dsi_connector, p_cmd_funcs);
+ if(!encoder) {
+ dev_err(dev->dev, "Create DBI encoder failed\n");
+ goto dsi_init_err1;
+ }
+ encoder->private = dsi_config;
+ dsi_config->encoders[MDFLD_DSI_ENCODER_DBI] = encoder;
+ if(pipe == 2)
+ dev_priv->encoder2 = encoder;
+
+ if(pipe == 0)
+ dev_priv->encoder0 = encoder;
+
+ }
+
+ if(p_vid_funcs) {
+ encoder = mdfld_dsi_dpi_init(dev, dsi_connector, p_vid_funcs);
+ if(!encoder) {
+ dev_err(dev->dev, "Create DPI encoder failed\n");
+ goto dsi_init_err1;
+ }
+ encoder->private = dsi_config;
+ dsi_config->encoders[MDFLD_DSI_ENCODER_DPI] = encoder;
+
+ if(pipe == 2)
+ dev_priv->encoder2 = encoder;
+
+ if(pipe == 0)
+ dev_priv->encoder0 = encoder;
+ }
+
+ drm_sysfs_connector_add(connector);
+
+ /*init DSI package sender on this output*/
+ if(mdfld_dsi_pkg_sender_init(dsi_connector, pipe)) {
+ dev_err(dev->dev,
+ "Package Sender initialization failed on pipe %d\n",
+ pipe);
+ goto dsi_init_err2;
+ }
+
+ dev_dbg(dev->dev, "successfully\n");
+ return;
+
+ /*TODO: add code to destroy outputs on error*/
+dsi_init_err2:
+ drm_sysfs_connector_remove(connector);
+dsi_init_err1:
+ drm_connector_cleanup(connector);
+ kfree(dsi_config->fixed_mode);
+ kfree(dsi_config);
+dsi_init_err0:
+ kfree(dsi_connector);
+}
diff --git a/drivers/staging/gma500/mdfld_dsi_output.h b/drivers/staging/gma500/mdfld_dsi_output.h
new file mode 100644
index 0000000..ac25e55
--- /dev/null
+++ b/drivers/staging/gma500/mdfld_dsi_output.h
@@ -0,0 +1,328 @@
+/*
+ * Copyright © 2010 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ * jim liu <jim...@intel.com>
+ * Jackie Li<yaodo...@intel.com>
+ */
+
+#ifndef __MDFLD_DSI_OUTPUT_H__
+#define __MDFLD_DSI_OUTPUT_H__
+
+#include <linux/backlight.h>
+#include <linux/version.h>
+#include <drm/drmP.h>
+#include <drm/drm.h>
+#include <drm/drm_crtc.h>
+#include <drm/drm_edid.h>
+
+#include "psb_drv.h"
+#include "psb_intel_drv.h"
+#include "psb_intel_reg.h"
+#include "psb_powermgmt.h"
+#include "mdfld_output.h"
+
+#include <asm/mrst.h>
+
+#define DRM_MODE_ENCODER_MIPI 5
+
+/* Medfield DSI controller registers */
+
+#define MIPIA_DEVICE_READY_REG 0xb000
+#define MIPIA_INTR_STAT_REG 0xb004
+#define MIPIA_INTR_EN_REG 0xb008
+#define MIPIA_DSI_FUNC_PRG_REG 0xb00c
+#define MIPIA_HS_TX_TIMEOUT_REG 0xb010
+#define MIPIA_LP_RX_TIMEOUT_REG 0xb014
+#define MIPIA_TURN_AROUND_TIMEOUT_REG 0xb018
+#define MIPIA_DEVICE_RESET_TIMER_REG 0xb01c
+#define MIPIA_DPI_RESOLUTION_REG 0xb020
+#define MIPIA_DBI_FIFO_THROTTLE_REG 0xb024
+#define MIPIA_HSYNC_COUNT_REG 0xb028
+#define MIPIA_HBP_COUNT_REG 0xb02c
+#define MIPIA_HFP_COUNT_REG 0xb030
+#define MIPIA_HACTIVE_COUNT_REG 0xb034
+#define MIPIA_VSYNC_COUNT_REG 0xb038
+#define MIPIA_VBP_COUNT_REG 0xb03c
+#define MIPIA_VFP_COUNT_REG 0xb040
+#define MIPIA_HIGH_LOW_SWITCH_COUNT_REG 0xb044
+#define MIPIA_DPI_CONTROL_REG 0xb048
+#define MIPIA_DPI_DATA_REG 0xb04c
+#define MIPIA_INIT_COUNT_REG 0xb050
+#define MIPIA_MAX_RETURN_PACK_SIZE_REG 0xb054
+#define MIPIA_VIDEO_MODE_FORMAT_REG 0xb058
+#define MIPIA_EOT_DISABLE_REG 0xb05c
+#define MIPIA_LP_BYTECLK_REG 0xb060
+#define MIPIA_LP_GEN_DATA_REG 0xb064
+#define MIPIA_HS_GEN_DATA_REG 0xb068
+#define MIPIA_LP_GEN_CTRL_REG 0xb06c
+#define MIPIA_HS_GEN_CTRL_REG 0xb070
+#define MIPIA_GEN_FIFO_STAT_REG 0xb074
+#define MIPIA_HS_LS_DBI_ENABLE_REG 0xb078
+#define MIPIA_DPHY_PARAM_REG 0xb080
+#define MIPIA_DBI_BW_CTRL_REG 0xb084
+#define MIPIA_CLK_LANE_SWITCH_TIME_CNT_REG 0xb088
+
+#define DSI_DEVICE_READY (0x1)
+#define DSI_POWER_STATE_ULPS_ENTER (0x2 << 1)
+#define DSI_POWER_STATE_ULPS_EXIT (0x1 << 1)
+#define DSI_POWER_STATE_ULPS_OFFSET (0x1)
+
+
+#define DSI_ONE_DATA_LANE (0x1)
+#define DSI_TWO_DATA_LANE (0x2)
+#define DSI_THREE_DATA_LANE (0X3)
+#define DSI_FOUR_DATA_LANE (0x4)
+#define DSI_DPI_VIRT_CHANNEL_OFFSET (0x3)
+#define DSI_DBI_VIRT_CHANNEL_OFFSET (0x5)
+#define DSI_DPI_COLOR_FORMAT_RGB565 (0x01 << 7)
+#define DSI_DPI_COLOR_FORMAT_RGB666 (0x02 << 7)
+#define DSI_DPI_COLOR_FORMAT_RGB666_UNPACK (0x03 << 7)
+#define DSI_DPI_COLOR_FORMAT_RGB888 (0x04 << 7)
+#define DSI_DBI_COLOR_FORMAT_OPTION2 (0x05 << 13)
+
+#define DSI_INTR_STATE_RXSOTERROR 1
+
+#define DSI_INTR_STATE_SPL_PKG_SENT (1 << 30)
+#define DSI_INTR_STATE_TE (1 << 31)
+
+#define DSI_HS_TX_TIMEOUT_MASK (0xffffff)
+
+#define DSI_LP_RX_TIMEOUT_MASK (0xffffff)
+
+#define DSI_TURN_AROUND_TIMEOUT_MASK (0x3f)
+
+#define DSI_RESET_TIMER_MASK (0xffff)
+
+#define DSI_DBI_FIFO_WM_HALF (0x0)
+#define DSI_DBI_FIFO_WM_QUARTER (0x1)
+#define DSI_DBI_FIFO_WM_LOW (0x2)
+
+#define DSI_DPI_TIMING_MASK (0xffff)
+
+#define DSI_INIT_TIMER_MASK (0xffff)
+
+#define DSI_DBI_RETURN_PACK_SIZE_MASK (0x3ff)
+
+#define DSI_LP_BYTECLK_MASK (0x0ffff)
+
+#define DSI_HS_CTRL_GEN_SHORT_W0 (0x03)
+#define DSI_HS_CTRL_GEN_SHORT_W1 (0x13)
+#define DSI_HS_CTRL_GEN_SHORT_W2 (0x23)
+#define DSI_HS_CTRL_GEN_R0 (0x04)
+#define DSI_HS_CTRL_GEN_R1 (0x14)
+#define DSI_HS_CTRL_GEN_R2 (0x24)
+#define DSI_HS_CTRL_GEN_LONG_W (0x29)
+#define DSI_HS_CTRL_MCS_SHORT_W0 (0x05)
+#define DSI_HS_CTRL_MCS_SHORT_W1 (0x15)
+#define DSI_HS_CTRL_MCS_R0 (0x06)
+#define DSI_HS_CTRL_MCS_LONG_W (0x39)
+#define DSI_HS_CTRL_VC_OFFSET (0x06)
+#define DSI_HS_CTRL_WC_OFFSET (0x08)
+
+#define DSI_FIFO_GEN_HS_DATA_FULL (1 << 0)
+#define DSI_FIFO_GEN_HS_DATA_HALF_EMPTY (1 << 1)
+#define DSI_FIFO_GEN_HS_DATA_EMPTY (1 << 2)
+#define DSI_FIFO_GEN_LP_DATA_FULL (1 << 8)
+#define DSI_FIFO_GEN_LP_DATA_HALF_EMPTY (1 << 9)
+#define DSI_FIFO_GEN_LP_DATA_EMPTY (1 << 10)
+#define DSI_FIFO_GEN_HS_CTRL_FULL (1 << 16)
+#define DSI_FIFO_GEN_HS_CTRL_HALF_EMPTY (1 << 17)
+#define DSI_FIFO_GEN_HS_CTRL_EMPTY (1 << 18)
+#define DSI_FIFO_GEN_LP_CTRL_FULL (1 << 24)
+#define DSI_FIFO_GEN_LP_CTRL_HALF_EMPTY (1 << 25)
+#define DSI_FIFO_GEN_LP_CTRL_EMPTY (1 << 26)
+#define DSI_FIFO_DBI_EMPTY (1 << 27)
+#define DSI_FIFO_DPI_EMPTY (1 << 28)
+
+#define DSI_DBI_HS_LP_SWITCH_MASK (0x1)
+
+#define DSI_HS_LP_SWITCH_COUNTER_OFFSET (0x0)
+#define DSI_LP_HS_SWITCH_COUNTER_OFFSET (0x16)
+
+#define DSI_DPI_CTRL_HS_SHUTDOWN (0x00000001)
+#define DSI_DPI_CTRL_HS_TURN_ON (0x00000002)
+
+/* Medfield DSI adapter registers */
+#define MIPIA_CONTROL_REG 0xb104
+#define MIPIA_DATA_ADD_REG 0xb108
+#define MIPIA_DATA_LEN_REG 0xb10c
+#define MIPIA_CMD_ADD_REG 0xb110
+#define MIPIA_CMD_LEN_REG 0xb114
+
+enum {
+ MDFLD_DSI_ENCODER_DBI = 0,
+ MDFLD_DSI_ENCODER_DPI,
+};
+
+enum {
+ MDFLD_DSI_VIDEO_NON_BURST_MODE_SYNC_PULSE = 1,
+ MDFLD_DSI_VIDEO_NON_BURST_MODE_SYNC_EVENTS = 2,
+ MDFLD_DSI_VIDEO_BURST_MODE = 3,
+};
+
+#define DSI_DPI_COMPLETE_LAST_LINE (1 << 2)
+#define DSI_DPI_DISABLE_BTA (1 << 3)
+
+struct mdfld_dsi_connector_state {
+ u32 mipi_ctrl_reg;
+};
+
+struct mdfld_dsi_encoder_state {
+
+};
+
+struct mdfld_dsi_connector {
+ /*
+ * This is ugly, but I have to use connector in it! :-(
+ * FIXME: use drm_connector instead.
+ */
+ struct psb_intel_output base;
+
+ int pipe;
+ void *private;
+ void *pkg_sender;
+};
+
+struct mdfld_dsi_encoder {
+ struct drm_encoder base;
+ void *private;
+};
+
+/*
+ * DSI config, consists of one DSI connector, two DSI encoders.
+ * DRM will pick up on DSI encoder basing on differents configs.
+ */
+struct mdfld_dsi_config {
+ struct drm_device *dev;
+ struct drm_display_mode *fixed_mode;
+ struct drm_display_mode *mode;
+
+ struct mdfld_dsi_connector *connector;
+ struct mdfld_dsi_encoder *encoders[DRM_CONNECTOR_MAX_ENCODER];
+ struct mdfld_dsi_encoder *encoder;
+
+ int changed;
+
+ int bpp;
+ int type;
+ int lane_count;
+ /*Virtual channel number for this encoder*/
+ int channel_num;
+ /*video mode configure*/
+ int video_mode;
+
+ int dvr_ic_inited;
+};
+
+#define MDFLD_DSI_CONNECTOR(psb_output) \
+ (container_of(psb_output, struct mdfld_dsi_connector, base))
+
+#define MDFLD_DSI_ENCODER(encoder) \
+ (container_of(encoder, struct mdfld_dsi_encoder, base))
+
+static inline struct mdfld_dsi_config *
+ mdfld_dsi_get_config(struct mdfld_dsi_connector *connector)
+{
+ if (!connector)
+ return NULL;
+ return (struct mdfld_dsi_config *)connector->private;
+}
+
+static inline void *mdfld_dsi_get_pkg_sender(struct mdfld_dsi_config *config)
+{
+ struct mdfld_dsi_connector *dsi_connector;
+
+ if (!config)
+ return NULL;
+
+ dsi_connector = config->connector;
+
+ if (!dsi_connector)
+ return NULL;
+
+ return dsi_connector->pkg_sender;
+}
+
+static inline struct mdfld_dsi_config *
+ mdfld_dsi_encoder_get_config(struct mdfld_dsi_encoder *encoder)
+{
+ if (!encoder)
+ return NULL;
+ return (struct mdfld_dsi_config *)encoder->private;
+}
+
+static inline struct mdfld_dsi_connector *
+ mdfld_dsi_encoder_get_connector(struct mdfld_dsi_encoder *encoder)
+{
+ struct mdfld_dsi_config *config;
+
+ if (!encoder)
+ return NULL;
+
+ config = mdfld_dsi_encoder_get_config(encoder);
+ if (!config)
+ return NULL;
+
+ return config->connector;
+}
+
+static inline void *mdfld_dsi_encoder_get_pkg_sender(
+ struct mdfld_dsi_encoder *encoder)
+{
+ struct mdfld_dsi_config *dsi_config;
+
+ dsi_config = mdfld_dsi_encoder_get_config(encoder);
+ if (!dsi_config)
+ return NULL;
+
+ return mdfld_dsi_get_pkg_sender(dsi_config);
+}
+
+static inline int mdfld_dsi_encoder_get_pipe(struct mdfld_dsi_encoder *encoder)
+{
+ struct mdfld_dsi_connector *connector;
+
+ if (!encoder)
+ return -1;
+
+ connector = mdfld_dsi_encoder_get_connector(encoder);
+ if (!connector)
+ return -1;
+
+ return connector->pipe;
+}
+
+extern void mdfld_dsi_gen_fifo_ready(struct drm_device *dev,
+ u32 gen_fifo_stat_reg, u32 fifo_stat);
+extern void mdfld_dsi_brightness_init(struct mdfld_dsi_config *dsi_config,
+ int pipe);
+extern void mdfld_dsi_brightness_control(struct drm_device *dev, int pipe,
+ int level);
+extern void mdfld_dsi_output_init(struct drm_device *dev, int pipe,
+ struct mdfld_dsi_config *config,
+ struct panel_funcs *p_cmd_funcs,
+ struct panel_funcs *p_vid_funcs);
+extern void mdfld_dsi_controller_init(struct mdfld_dsi_config *dsi_config,
+ int pipe);
+
+#endif /*__MDFLD_DSI_OUTPUT_H__*/
diff --git a/drivers/staging/gma500/mdfld_dsi_pkg_sender.c b/drivers/staging/gma500/mdfld_dsi_pkg_sender.c
new file mode 100644
index 0000000..9198aa8
--- /dev/null
+++ b/drivers/staging/gma500/mdfld_dsi_pkg_sender.c
@@ -0,0 +1,1097 @@
+/*
+ * Copyright © 2010 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ * Jackie Li<yaodo...@intel.com>
+ */
+
+#include <linux/freezer.h>
+
+#include "mdfld_dsi_output.h"
+#include "mdfld_dsi_pkg_sender.h"
+#include "mdfld_dsi_dbi.h"
+
+#define MDFLD_DSI_DBI_FIFO_TIMEOUT 100
+
+static const char * const dsi_errors[] = {
+ "RX SOT Error",
+ "RX SOT Sync Error",
+ "RX EOT Sync Error",
+ "RX Escape Mode Entry Error",
+ "RX LP TX Sync Error",
+ "RX HS Receive Timeout Error",
+ "RX False Control Error",
+ "RX ECC Single Bit Error",
+ "RX ECC Multibit Error",
+ "RX Checksum Error",
+ "RX DSI Data Type Not Recognised",
+ "RX DSI VC ID Invalid",
+ "TX False Control Error",
+ "TX ECC Single Bit Error",
+ "TX ECC Multibit Error",
+ "TX Checksum Error",
+ "TX DSI Data Type Not Recognised",
+ "TX DSI VC ID invalid",
+ "High Contention",
+ "Low contention",
+ "DPI FIFO Under run",
+ "HS TX Timeout",
+ "LP RX Timeout",
+ "Turn Around ACK Timeout",
+ "ACK With No Error",
+ "RX Invalid TX Length",
+ "RX Prot Violation",
+ "HS Generic Write FIFO Full",
+ "LP Generic Write FIFO Full",
+ "Generic Read Data Avail"
+ "Special Packet Sent",
+ "Tearing Effect",
+};
+
+static int wait_for_gen_fifo_empty(struct mdfld_dsi_pkg_sender *sender,
+ u32 mask)
+{
+ struct drm_device *dev = sender->dev;
+ u32 gen_fifo_stat_reg = sender->mipi_gen_fifo_stat_reg;
+ int retry = 0xffff;
+
+ while (retry--) {
+ if ((mask & REG_READ(gen_fifo_stat_reg)) == mask)
+ return 0;
+ udelay(100);
+ }
+ dev_err(dev->dev, "fifo is NOT empty 0x%08x\n",
+ REG_READ(gen_fifo_stat_reg));
+ return -EIO;
+}
+
+static int wait_for_all_fifos_empty(struct mdfld_dsi_pkg_sender *sender)
+{
+ return wait_for_gen_fifo_empty(sender, (1 << 2) | (1 << 10) | (1 << 18)
+ | (1 << 26) | (1 << 27) | (1 << 28));
+}
+
+static int wait_for_lp_fifos_empty(struct mdfld_dsi_pkg_sender *sender)
+{
+ return wait_for_gen_fifo_empty(sender, (1 << 10) | (1 << 26));
+}
+
+static int wait_for_hs_fifos_empty(struct mdfld_dsi_pkg_sender *sender)
+{
+ return wait_for_gen_fifo_empty(sender, (1 << 2) | (1 << 18));
+}
+
+static int wait_for_dbi_fifo_empty(struct mdfld_dsi_pkg_sender *sender)
+{
+ return wait_for_gen_fifo_empty(sender, (1 << 27));
+}
+
+static int handle_dsi_error(struct mdfld_dsi_pkg_sender *sender, u32 mask)
+{
+ u32 intr_stat_reg = sender->mipi_intr_stat_reg;
+ struct drm_device *dev = sender->dev;
+
+ switch (mask) {
+ case (1 << 0):
+ case (1 << 1):
+ case (1 << 2):
+ case (1 << 3):
+ case (1 << 4):
+ case (1 << 5):
+ case (1 << 6):
+ case (1 << 7):
+ case (1 << 8):
+ case (1 << 9):
+ case (1 << 10):
+ case (1 << 11):
+ case (1 << 12):
+ case (1 << 13):
+ break;
+ case (1 << 14):
+ /*wait for all fifo empty*/
+ /*wait_for_all_fifos_empty(sender)*/;
+ break;
+ case (1 << 15):
+ break;
+ case (1 << 16):
+ break;
+ case (1 << 17):
+ break;
+ case (1 << 18):
+ case (1 << 19):
+ /*wait for contention recovery time*/
+ /*mdelay(10);*/
+ /*wait for all fifo empty*/
+ if (0)
+ wait_for_all_fifos_empty(sender);
+ break;
+ case (1 << 20):
+ break;
+ case (1 << 21):
+ /*wait for all fifo empty*/
+ /*wait_for_all_fifos_empty(sender);*/
+ break;
+ case (1 << 22):
+ break;
+ case (1 << 23):
+ case (1 << 24):
+ case (1 << 25):
+ case (1 << 26):
+ case (1 << 27):
+ /* HS Gen fifo full */
+ REG_WRITE(intr_stat_reg, mask);
+ wait_for_hs_fifos_empty(sender);
+ break;
+ case (1 << 28):
+ /* LP Gen fifo full\n */
+ REG_WRITE(intr_stat_reg, mask);
+ wait_for_lp_fifos_empty(sender);
+ break;
+ case (1 << 29):
+ case (1 << 30):
+ case (1 << 31):
+ break;
+ }
+
+ if (mask & REG_READ(intr_stat_reg))
+ dev_warn(dev->dev, "Cannot clean interrupt 0x%08x\n", mask);


+
+ return 0;
+}
+

+static int dsi_error_handler(struct mdfld_dsi_pkg_sender *sender)
+{
+ struct drm_device *dev = sender->dev;
+ u32 intr_stat_reg = sender->mipi_intr_stat_reg;
+ u32 mask;
+ u32 intr_stat;
+ int i;
+ int err = 0;
+
+ intr_stat = REG_READ(intr_stat_reg);
+
+ for (i = 0; i < 32; i++) {
+ mask = (0x00000001UL) << i;
+ if (intr_stat & mask) {
+ dev_dbg(dev->dev, "[DSI]: %s\n", dsi_errors[i]);
+ err = handle_dsi_error(sender, mask);
+ if (err)
+ dev_err(dev->dev, "Cannot handle error\n");
+ }
+ }
+ return err;
+}
+
+static inline int dbi_cmd_sent(struct mdfld_dsi_pkg_sender *sender)
+{
+ struct drm_device *dev = sender->dev;
+ u32 retry = 0xffff;
+ u32 dbi_cmd_addr_reg = sender->mipi_cmd_addr_reg;
+
+ /* Query the command execution status */
+ while (retry--) {
+ if (!(REG_READ(dbi_cmd_addr_reg) & (1 << 0)))
+ break;
+ }
+
+ if (!retry) {
+ dev_err(dev->dev, "Timeout waiting for DBI Command status\n");
+ return -EAGAIN;


+ }
+ return 0;
+}
+

+/*
+ * NOTE: this interface is abandoned expect for write_mem_start DCS
+ * other DCS are sent via generic pkg interfaces
+ */
+static int send_dcs_pkg(struct mdfld_dsi_pkg_sender *sender,
+ struct mdfld_dsi_pkg *pkg)
+{
+ struct drm_device *dev = sender->dev;
+ struct mdfld_dsi_dcs_pkg *dcs_pkg = &pkg->pkg.dcs_pkg;
+ u32 dbi_cmd_len_reg = sender->mipi_cmd_len_reg;
+ u32 dbi_cmd_addr_reg = sender->mipi_cmd_addr_reg;
+ u32 cb_phy = sender->dbi_cb_phy;
+ u32 index = 0;
+ u8 *cb = (u8 *)sender->dbi_cb_addr;
+ int i;
+ int ret;
+
+ if (!sender->dbi_pkg_support) {
+ dev_err(dev->dev, "Trying to send DCS on a non DBI output, abort!\n");
+ return -ENOTSUPP;
+ }
+
+ /*wait for DBI fifo empty*/
+ wait_for_dbi_fifo_empty(sender);
+
+ *(cb + (index++)) = dcs_pkg->cmd;
+ if (dcs_pkg->param_num) {
+ for (i = 0; i < dcs_pkg->param_num; i++)
+ *(cb + (index++)) = *(dcs_pkg->param + i);
+ }
+
+ REG_WRITE(dbi_cmd_len_reg, (1 + dcs_pkg->param_num));
+ REG_WRITE(dbi_cmd_addr_reg,
+ (cb_phy << CMD_MEM_ADDR_OFFSET)
+ | (1 << 0)
+ | ((dcs_pkg->data_src == CMD_DATA_SRC_PIPE) ? (1 << 1) : 0));
+
+ ret = dbi_cmd_sent(sender);
+ if (ret) {
+ dev_err(dev->dev, "command 0x%x not complete\n", dcs_pkg->cmd);
+ return -EAGAIN;


+ }
+ return 0;
+}
+

+static int __send_short_pkg(struct mdfld_dsi_pkg_sender *sender,
+ struct mdfld_dsi_pkg *pkg)
+{
+ struct drm_device *dev = sender->dev;
+ u32 hs_gen_ctrl_reg = sender->mipi_hs_gen_ctrl_reg;
+ u32 lp_gen_ctrl_reg = sender->mipi_lp_gen_ctrl_reg;
+ u32 gen_ctrl_val = 0;
+ struct mdfld_dsi_gen_short_pkg *short_pkg = &pkg->pkg.short_pkg;
+
+ gen_ctrl_val |= short_pkg->cmd << MCS_COMMANDS_POS;
+ gen_ctrl_val |= 0 << DCS_CHANNEL_NUMBER_POS;
+ gen_ctrl_val |= pkg->pkg_type;
+ gen_ctrl_val |= short_pkg->param << MCS_PARAMETER_POS;
+
+ if (pkg->transmission_type == MDFLD_DSI_HS_TRANSMISSION) {
+ /* wait for hs fifo empty */
+ /* wait_for_hs_fifos_empty(sender); */
+ /* Send pkg */
+ REG_WRITE(hs_gen_ctrl_reg, gen_ctrl_val);
+ } else if (pkg->transmission_type == MDFLD_DSI_LP_TRANSMISSION) {
+ /* wait_for_lp_fifos_empty(sender); */
+ /* Send pkg*/
+ REG_WRITE(lp_gen_ctrl_reg, gen_ctrl_val);
+ } else {
+ dev_err(dev->dev, "Unknown transmission type %d\n",
+ pkg->transmission_type);


+ return -EINVAL;
+ }
+

+ return 0;
+}
+

+static int __send_long_pkg(struct mdfld_dsi_pkg_sender *sender,
+ struct mdfld_dsi_pkg *pkg)
+{
+ struct drm_device *dev = sender->dev;
+ u32 hs_gen_ctrl_reg = sender->mipi_hs_gen_ctrl_reg;
+ u32 hs_gen_data_reg = sender->mipi_hs_gen_data_reg;
+ u32 lp_gen_ctrl_reg = sender->mipi_lp_gen_ctrl_reg;
+ u32 lp_gen_data_reg = sender->mipi_lp_gen_data_reg;
+ u32 gen_ctrl_val = 0;
+ u32 *dp;
+ int i;
+ struct mdfld_dsi_gen_long_pkg *long_pkg = &pkg->pkg.long_pkg;
+
+ dp = long_pkg->data;
+
+ /*
+ * Set up word count for long pkg
+ * FIXME: double check word count field.
+ * currently, using the byte counts of the payload as the word count.
+ * ------------------------------------------------------------
+ * | DI | WC | ECC| PAYLOAD |CHECKSUM|
+ * ------------------------------------------------------------
+ */
+ gen_ctrl_val |= (long_pkg->len << 2) << WORD_COUNTS_POS;
+ gen_ctrl_val |= 0 << DCS_CHANNEL_NUMBER_POS;
+ gen_ctrl_val |= pkg->pkg_type;
+
+ if (pkg->transmission_type == MDFLD_DSI_HS_TRANSMISSION) {
+ /* Wait for hs ctrl and data fifos to be empty */
+ /* wait_for_hs_fifos_empty(sender); */
+ for (i = 0; i < long_pkg->len; i++)
+ REG_WRITE(hs_gen_data_reg, *(dp + i));
+ REG_WRITE(hs_gen_ctrl_reg, gen_ctrl_val);
+ } else if (pkg->transmission_type == MDFLD_DSI_LP_TRANSMISSION) {
+ /* wait_for_lp_fifos_empty(sender); */
+ for (i = 0; i < long_pkg->len; i++)
+ REG_WRITE(lp_gen_data_reg, *(dp + i));
+ REG_WRITE(lp_gen_ctrl_reg, gen_ctrl_val);
+ } else {
+ dev_err(dev->dev, "Unknown transmission type %d\n",
+ pkg->transmission_type);


+ return -EINVAL;
+ }
+

+ return 0;
+
+}
+

+static int send_mcs_short_pkg(struct mdfld_dsi_pkg_sender *sender,
+ struct mdfld_dsi_pkg *pkg)
+{
+ return __send_short_pkg(sender, pkg);
+}
+
+static int send_mcs_long_pkg(struct mdfld_dsi_pkg_sender *sender,
+ struct mdfld_dsi_pkg *pkg)
+{
+ return __send_long_pkg(sender, pkg);
+}
+
+static int send_gen_short_pkg(struct mdfld_dsi_pkg_sender *sender,
+ struct mdfld_dsi_pkg *pkg)
+{
+ return __send_short_pkg(sender, pkg);
+}
+
+static int send_gen_long_pkg(struct mdfld_dsi_pkg_sender *sender,
+ struct mdfld_dsi_pkg *pkg)
+{
+ return __send_long_pkg(sender, pkg);
+}
+
+static int send_pkg_prepare(struct mdfld_dsi_pkg_sender *sender,
+ struct mdfld_dsi_pkg *pkg)
+{
+ u8 cmd;
+ u8 *data;
+
+ switch (pkg->pkg_type) {
+ case MDFLD_DSI_PKG_DCS:
+ cmd = pkg->pkg.dcs_pkg.cmd;
+ break;
+ case MDFLD_DSI_PKG_MCS_SHORT_WRITE_0:
+ case MDFLD_DSI_PKG_MCS_SHORT_WRITE_1:
+ cmd = pkg->pkg.short_pkg.cmd;
+ break;
+ case MDFLD_DSI_PKG_MCS_LONG_WRITE:
+ data = (u8 *)pkg->pkg.long_pkg.data;
+ cmd = *data;
+ break;
+ default:
+ return 0;
+ }
+
+ /* This prevents other package sending while doing msleep */
+ sender->status = MDFLD_DSI_PKG_SENDER_BUSY;
+
+ /* Check panel mode v.s. sending command */
+ if ((sender->panel_mode & MDFLD_DSI_PANEL_MODE_SLEEP) &&
+ cmd != exit_sleep_mode) {
+ dev_err(sender->dev->dev,
+ "sending 0x%x when panel sleep in\n", cmd);
+ sender->status = MDFLD_DSI_PKG_SENDER_FREE;


+ return -EINVAL;
+ }
+

+ /* Wait for 120 milliseconds in case exit_sleep_mode just be sent */
+ if (cmd == enter_sleep_mode)
+ mdelay(120);


+ return 0;
+}
+

+static int send_pkg_done(struct mdfld_dsi_pkg_sender *sender,
+ struct mdfld_dsi_pkg *pkg)
+{
+ u8 cmd;
+ u8 *data;
+
+ switch (pkg->pkg_type) {
+ case MDFLD_DSI_PKG_DCS:
+ cmd = pkg->pkg.dcs_pkg.cmd;
+ break;
+ case MDFLD_DSI_PKG_MCS_SHORT_WRITE_0:
+ case MDFLD_DSI_PKG_MCS_SHORT_WRITE_1:
+ cmd = pkg->pkg.short_pkg.cmd;
+ break;
+ case MDFLD_DSI_PKG_MCS_LONG_WRITE:
+ data = (u8 *)pkg->pkg.long_pkg.data;
+ cmd = *data;
+ break;
+ default:
+ return 0;
+ }
+
+ /* Update panel status */
+ if (cmd == enter_sleep_mode) {
+ sender->panel_mode |= MDFLD_DSI_PANEL_MODE_SLEEP;
+ /*TODO: replace it with msleep later*/
+ mdelay(120);
+ } else if (cmd == exit_sleep_mode) {
+ sender->panel_mode &= ~MDFLD_DSI_PANEL_MODE_SLEEP;
+ /*TODO: replace it with msleep later*/
+ mdelay(120);
+ }
+
+ sender->status = MDFLD_DSI_PKG_SENDER_FREE;


+ return 0;
+
+}
+

+static int do_send_pkg(struct mdfld_dsi_pkg_sender *sender,
+ struct mdfld_dsi_pkg *pkg)
+{
+ int ret;
+
+ if (sender->status == MDFLD_DSI_PKG_SENDER_BUSY) {
+ dev_err(sender->dev->dev, "sender is busy\n");
+ return -EAGAIN;
+ }
+
+ ret = send_pkg_prepare(sender, pkg);
+ if (ret) {
+ dev_err(sender->dev->dev, "send_pkg_prepare error\n");


+ return ret;
+ }
+

+ switch (pkg->pkg_type) {
+ case MDFLD_DSI_PKG_DCS:
+ ret = send_dcs_pkg(sender, pkg);
+ break;
+ case MDFLD_DSI_PKG_GEN_SHORT_WRITE_0:
+ case MDFLD_DSI_PKG_GEN_SHORT_WRITE_1:
+ case MDFLD_DSI_PKG_GEN_SHORT_WRITE_2:
+ ret = send_gen_short_pkg(sender, pkg);
+ break;
+ case MDFLD_DSI_PKG_GEN_LONG_WRITE:
+ ret = send_gen_long_pkg(sender, pkg);
+ break;
+ case MDFLD_DSI_PKG_MCS_SHORT_WRITE_0:
+ case MDFLD_DSI_PKG_MCS_SHORT_WRITE_1:
+ ret = send_mcs_short_pkg(sender, pkg);
+ break;
+ case MDFLD_DSI_PKG_MCS_LONG_WRITE:
+ ret = send_mcs_long_pkg(sender, pkg);
+ break;
+ default:
+ dev_err(sender->dev->dev, "Invalid pkg type 0x%x\n",
+ pkg->pkg_type);
+ ret = -EINVAL;
+ }
+ send_pkg_done(sender, pkg);


+ return ret;
+}
+

+static int send_pkg(struct mdfld_dsi_pkg_sender *sender,
+ struct mdfld_dsi_pkg *pkg)
+{
+ int err ;
+
+ /* Handle DSI error */
+ err = dsi_error_handler(sender);
+ if (err) {
+ dev_err(sender->dev->dev, "Error handling failed\n");
+ err = -EAGAIN;
+ goto send_pkg_err;
+ }
+
+ /* Send pkg */
+ err = do_send_pkg(sender, pkg);
+ if (err) {
+ dev_err(sender->dev->dev, "sent pkg failed\n");
+ err = -EAGAIN;
+ goto send_pkg_err;
+ }
+
+ /* FIXME: should I query complete and fifo empty here? */
+send_pkg_err:
+ return err;
+}
+
+static struct mdfld_dsi_pkg *pkg_sender_get_pkg_locked(
+ struct mdfld_dsi_pkg_sender *sender)
+{
+ struct mdfld_dsi_pkg *pkg;
+
+ if (list_empty(&sender->free_list)) {
+ dev_err(sender->dev->dev, "No free pkg left\n");
+ return NULL;
+ }
+ pkg = list_first_entry(&sender->free_list, struct mdfld_dsi_pkg, entry);
+ /* Detach from free list */
+ list_del_init(&pkg->entry);
+ return pkg;
+}
+
+static void pkg_sender_put_pkg_locked(struct mdfld_dsi_pkg_sender *sender,
+ struct mdfld_dsi_pkg *pkg)
+{
+ memset(pkg, 0, sizeof(struct mdfld_dsi_pkg));
+ INIT_LIST_HEAD(&pkg->entry);
+ list_add_tail(&pkg->entry, &sender->free_list);
+}
+
+static int mdfld_dbi_cb_init(struct mdfld_dsi_pkg_sender *sender,
+ struct psb_gtt *pg, int pipe)
+{
+ unsigned long phys;
+ void *virt_addr = NULL;
+
+ switch (pipe) {
+ case 0:
+ phys = pg->gtt_phys_start - 0x1000;
+ break;
+ case 2:
+ phys = pg->gtt_phys_start - 0x800;
+ break;
+ default:
+ dev_err(sender->dev->dev, "Unsupported channel %d\n", pipe);


+ return -EINVAL;
+ }
+

+ virt_addr = ioremap_nocache(phys, 0x800);
+ if (!virt_addr) {
+ dev_err(sender->dev->dev, "Map DBI command buffer error\n");
+ return -ENOMEM;
+ }
+ sender->dbi_cb_phy = phys;
+ sender->dbi_cb_addr = virt_addr;


+ return 0;
+}
+

+static void mdfld_dbi_cb_destroy(struct mdfld_dsi_pkg_sender *sender)
+{
+ if (sender && sender->dbi_cb_addr)
+ iounmap(sender->dbi_cb_addr);
+}
+
+static void pkg_sender_queue_pkg(struct mdfld_dsi_pkg_sender *sender,
+ struct mdfld_dsi_pkg *pkg,
+ int delay)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&sender->lock, flags);
+
+ if (!delay) {
+ send_pkg(sender, pkg);
+ pkg_sender_put_pkg_locked(sender, pkg);
+ } else {
+ /* Queue it */
+ list_add_tail(&pkg->entry, &sender->pkg_list);
+ }
+ spin_unlock_irqrestore(&sender->lock, flags);
+}
+
+static void process_pkg_list(struct mdfld_dsi_pkg_sender *sender)
+{
+ struct mdfld_dsi_pkg *pkg;
+ unsigned long flags;
+
+ spin_lock_irqsave(&sender->lock, flags);
+
+ while (!list_empty(&sender->pkg_list)) {
+ pkg = list_first_entry(&sender->pkg_list,
+ struct mdfld_dsi_pkg, entry);
+ send_pkg(sender, pkg);
+ list_del_init(&pkg->entry);
+ pkg_sender_put_pkg_locked(sender, pkg);
+ }
+
+ spin_unlock_irqrestore(&sender->lock, flags);
+}
+
+static int mdfld_dsi_send_mcs_long(struct mdfld_dsi_pkg_sender *sender,
+ u32 *data, u32 len, u8 transmission, int delay)
+{
+ struct mdfld_dsi_pkg *pkg;
+ unsigned long flags;
+
+ spin_lock_irqsave(&sender->lock, flags);
+ pkg = pkg_sender_get_pkg_locked(sender);
+ spin_unlock_irqrestore(&sender->lock, flags);
+
+ if (!pkg) {
+ dev_err(sender->dev->dev, "No memory\n");
+ return -ENOMEM;
+ }
+ pkg->pkg_type = MDFLD_DSI_PKG_MCS_LONG_WRITE;
+ pkg->transmission_type = transmission;
+ pkg->pkg.long_pkg.data = data;
+ pkg->pkg.long_pkg.len = len;
+ INIT_LIST_HEAD(&pkg->entry);
+
+ pkg_sender_queue_pkg(sender, pkg, delay);


+ return 0;
+}
+

+static int mdfld_dsi_send_mcs_short(struct mdfld_dsi_pkg_sender *sender,
+ u8 cmd, u8 param, u8 param_num,
+ u8 transmission,
+ int delay)
+{
+ struct mdfld_dsi_pkg *pkg;
+ unsigned long flags;
+
+ spin_lock_irqsave(&sender->lock, flags);
+ pkg = pkg_sender_get_pkg_locked(sender);
+ spin_unlock_irqrestore(&sender->lock, flags);
+
+ if (!pkg) {
+ dev_err(sender->dev->dev, "No memory\n");
+ return -ENOMEM;
+ }
+
+ if (param_num) {
+ pkg->pkg_type = MDFLD_DSI_PKG_MCS_SHORT_WRITE_1;
+ pkg->pkg.short_pkg.param = param;
+ } else {
+ pkg->pkg_type = MDFLD_DSI_PKG_MCS_SHORT_WRITE_0;
+ pkg->pkg.short_pkg.param = 0;
+ }
+ pkg->transmission_type = transmission;
+ pkg->pkg.short_pkg.cmd = cmd;
+ INIT_LIST_HEAD(&pkg->entry);
+
+ pkg_sender_queue_pkg(sender, pkg, delay);


+ return 0;
+}
+

+static int mdfld_dsi_send_gen_short(struct mdfld_dsi_pkg_sender *sender,
+ u8 param0, u8 param1, u8 param_num,
+ u8 transmission,
+ int delay)
+{
+ struct mdfld_dsi_pkg *pkg;
+ unsigned long flags;
+
+ spin_lock_irqsave(&sender->lock, flags);
+ pkg = pkg_sender_get_pkg_locked(sender);
+ spin_unlock_irqrestore(&sender->lock, flags);
+
+ if (!pkg) {
+ dev_err(sender->dev->dev, "No pkg memory\n");
+ return -ENOMEM;
+ }
+
+ switch (param_num) {
+ case 0:
+ pkg->pkg_type = MDFLD_DSI_PKG_GEN_SHORT_WRITE_0;
+ pkg->pkg.short_pkg.cmd = 0;
+ pkg->pkg.short_pkg.param = 0;
+ break;
+ case 1:
+ pkg->pkg_type = MDFLD_DSI_PKG_GEN_SHORT_WRITE_1;
+ pkg->pkg.short_pkg.cmd = param0;
+ pkg->pkg.short_pkg.param = 0;
+ break;
+ case 2:
+ pkg->pkg_type = MDFLD_DSI_PKG_GEN_SHORT_WRITE_2;
+ pkg->pkg.short_pkg.cmd = param0;
+ pkg->pkg.short_pkg.param = param1;
+ break;
+ }
+
+ pkg->transmission_type = transmission;
+ INIT_LIST_HEAD(&pkg->entry);
+
+ pkg_sender_queue_pkg(sender, pkg, delay);


+ return 0;
+}
+

+static int mdfld_dsi_send_gen_long(struct mdfld_dsi_pkg_sender *sender,
+ u32 *data, u32 len, u8 transmission, int delay)
+{
+ struct mdfld_dsi_pkg *pkg;
+ unsigned long flags;
+
+ spin_lock_irqsave(&sender->lock, flags);
+ pkg = pkg_sender_get_pkg_locked(sender);
+ spin_unlock_irqrestore(&sender->lock, flags);
+
+ if (!pkg) {
+ dev_err(sender->dev->dev, "No pkg memory\n");
+ return -ENOMEM;
+ }
+
+ pkg->pkg_type = MDFLD_DSI_PKG_GEN_LONG_WRITE;
+ pkg->transmission_type = transmission;
+ pkg->pkg.long_pkg.data = data;
+ pkg->pkg.long_pkg.len = len;
+
+ INIT_LIST_HEAD(&pkg->entry);
+
+ pkg_sender_queue_pkg(sender, pkg, delay);


+
+ return 0;
+}
+

+void mdfld_dsi_cmds_kick_out(struct mdfld_dsi_pkg_sender *sender)
+{
+ process_pkg_list(sender);
+}
+
+int mdfld_dsi_send_dcs(struct mdfld_dsi_pkg_sender *sender,
+ u8 dcs, u8 *param, u32 param_num, u8 data_src,
+ int delay)
+{
+ struct mdfld_dsi_pkg *pkg;
+ u32 cb_phy = sender->dbi_cb_phy;
+ struct drm_device *dev = sender->dev;
+ u32 index = 0;
+ u8 *cb = (u8 *)sender->dbi_cb_addr;
+ unsigned long flags;
+ int retry;
+ u8 *dst = NULL;
+ u32 len;
+
+ if (!sender) {
+ WARN_ON(1);


+ return -EINVAL;
+ }
+

+ if (!sender->dbi_pkg_support) {
+ dev_err(dev->dev, "No DBI pkg sending on this sender\n");
+ return -ENOTSUPP;
+ }
+
+ if (param_num > MDFLD_MAX_DCS_PARAM) {
+ dev_err(dev->dev, "Sender only supports up to %d DCS params\n",
+ MDFLD_MAX_DCS_PARAM);


+ return -EINVAL;
+ }
+

+ /*
+ * If dcs is write_mem_start, send it directly using DSI adapter
+ * interface
+ */
+ if (dcs == write_mem_start) {
+ if (!spin_trylock(&sender->lock))
+ return -EAGAIN;
+
+ /*
+ * query whether DBI FIFO is empty,
+ * if not wait it becoming empty
+ */
+ retry = MDFLD_DSI_DBI_FIFO_TIMEOUT;
+ while (retry &&
+ !(REG_READ(sender->mipi_gen_fifo_stat_reg) & (1 << 27))) {
+ udelay(500);
+ retry--;
+ }
+
+ /* If DBI FIFO timeout, drop this frame */
+ if (!retry) {
+ spin_unlock(&sender->lock);


+ return 0;
+ }
+

+ *(cb + (index++)) = write_mem_start;
+
+ REG_WRITE(sender->mipi_cmd_len_reg, 1);
+ REG_WRITE(sender->mipi_cmd_addr_reg,
+ cb_phy | (1 << 0) | (1 << 1));
+
+ retry = MDFLD_DSI_DBI_FIFO_TIMEOUT;
+ while (retry &&
+ (REG_READ(sender->mipi_cmd_addr_reg) & (1 << 0))) {
+ udelay(1);
+ retry--;
+ }
+
+ spin_unlock(&sender->lock);


+ return 0;
+ }
+

+ /* Get a free pkg */
+ spin_lock_irqsave(&sender->lock, flags);
+ pkg = pkg_sender_get_pkg_locked(sender);
+ spin_unlock_irqrestore(&sender->lock, flags);
+
+ if (!pkg) {
+ dev_err(dev->dev, "No packages memory\n");
+ return -ENOMEM;
+ }
+
+ dst = pkg->pkg.dcs_pkg.param;
+ memcpy(dst, param, param_num);
+
+ pkg->pkg_type = MDFLD_DSI_PKG_DCS;
+ pkg->transmission_type = MDFLD_DSI_DCS;
+ pkg->pkg.dcs_pkg.cmd = dcs;
+ pkg->pkg.dcs_pkg.param_num = param_num;
+ pkg->pkg.dcs_pkg.data_src = data_src;
+
+ INIT_LIST_HEAD(&pkg->entry);
+
+ if (param_num == 0)
+ return mdfld_dsi_send_mcs_short_hs(sender, dcs, 0, 0, delay);
+ else if (param_num == 1)
+ return mdfld_dsi_send_mcs_short_hs(sender, dcs,
+ param[0], 1, delay);
+ else if (param_num > 1) {
+ len = (param_num + 1) / 4;
+ if ((param_num + 1) % 4)
+ len++;
+ return mdfld_dsi_send_mcs_long_hs(sender,
+ (u32 *)&pkg->pkg.dcs_pkg, len, delay);


+ }
+ return 0;
+}
+

+int mdfld_dsi_send_mcs_short_hs(struct mdfld_dsi_pkg_sender *sender,
+ u8 cmd, u8 param, u8 param_num, int delay)
+{
+ if (!sender) {
+ WARN_ON(1);
+ return -EINVAL;
+ }
+ return mdfld_dsi_send_mcs_short(sender, cmd, param, param_num,
+ MDFLD_DSI_HS_TRANSMISSION, delay);
+}
+
+int mdfld_dsi_send_mcs_short_lp(struct mdfld_dsi_pkg_sender *sender,
+ u8 cmd, u8 param, u8 param_num, int delay)
+{
+ if (!sender) {
+ WARN_ON(1);
+ return -EINVAL;
+ }
+ return mdfld_dsi_send_mcs_short(sender, cmd, param, param_num,
+ MDFLD_DSI_LP_TRANSMISSION, delay);
+}
+
+int mdfld_dsi_send_mcs_long_hs(struct mdfld_dsi_pkg_sender *sender,
+ u32 *data,
+ u32 len,
+ int delay)
+{
+ if (!sender || !data || !len) {
+ DRM_ERROR("Invalid parameters\n");
+ return -EINVAL;
+ }
+ return mdfld_dsi_send_mcs_long(sender, data, len,
+ MDFLD_DSI_HS_TRANSMISSION, delay);
+}
+
+int mdfld_dsi_send_mcs_long_lp(struct mdfld_dsi_pkg_sender *sender,
+ u32 *data,
+ u32 len,
+ int delay)
+{
+ if (!sender || !data || !len) {
+ WARN_ON(1);
+ return -EINVAL;
+ }
+ return mdfld_dsi_send_mcs_long(sender, data, len,
+ MDFLD_DSI_LP_TRANSMISSION, delay);
+}
+
+int mdfld_dsi_send_gen_short_hs(struct mdfld_dsi_pkg_sender *sender,
+ u8 param0, u8 param1, u8 param_num, int delay)
+{
+ if (!sender) {
+ WARN_ON(1);
+ return -EINVAL;
+ }
+ return mdfld_dsi_send_gen_short(sender, param0, param1, param_num,
+ MDFLD_DSI_HS_TRANSMISSION, delay);
+}
+
+int mdfld_dsi_send_gen_short_lp(struct mdfld_dsi_pkg_sender *sender,
+ u8 param0, u8 param1, u8 param_num, int delay)
+{
+ if (!sender || param_num < 0 || param_num > 2) {
+ WARN_ON(1);
+ return -EINVAL;
+ }
+ return mdfld_dsi_send_gen_short(sender, param0, param1, param_num,
+ MDFLD_DSI_LP_TRANSMISSION, delay);
+}
+
+int mdfld_dsi_send_gen_long_hs(struct mdfld_dsi_pkg_sender *sender,
+ u32 *data,
+ u32 len,
+ int delay)
+{
+ if (!sender || !data || !len) {
+ WARN_ON(1);
+ return -EINVAL;
+ }
+ return mdfld_dsi_send_gen_long(sender, data, len,
+ MDFLD_DSI_HS_TRANSMISSION, delay);
+}
+
+int mdfld_dsi_send_gen_long_lp(struct mdfld_dsi_pkg_sender *sender,
+ u32 *data,
+ u32 len,
+ int delay)
+{
+ if (!sender || !data || !len) {
+ WARN_ON(1);
+ return -EINVAL;
+ }
+ return mdfld_dsi_send_gen_long(sender, data, len,
+ MDFLD_DSI_LP_TRANSMISSION, delay);
+}
+
+int mdfld_dsi_pkg_sender_init(struct mdfld_dsi_connector *dsi_connector,
+ int pipe)
+{
+ int ret;
+ struct mdfld_dsi_pkg_sender *pkg_sender;
+ struct mdfld_dsi_config *dsi_config =
+ mdfld_dsi_get_config(dsi_connector);
+ struct drm_device *dev = dsi_config->dev;
+ struct drm_psb_private *dev_priv = dev->dev_private;
+ struct psb_gtt *pg = dev_priv->pg;
+ int i;
+ struct mdfld_dsi_pkg *pkg, *tmp;
+
+ if (!dsi_connector) {
+ WARN_ON(1);


+ return -EINVAL;
+ }
+

+ pkg_sender = dsi_connector->pkg_sender;
+
+ if (!pkg_sender || IS_ERR(pkg_sender)) {
+ pkg_sender = kzalloc(sizeof(struct mdfld_dsi_pkg_sender),
+ GFP_KERNEL);
+ if (!pkg_sender) {
+ dev_err(dev->dev, "Create DSI pkg sender failed\n");
+ return -ENOMEM;
+ }
+
+ dsi_connector->pkg_sender = (void *)pkg_sender;
+ }
+
+ pkg_sender->dev = dev;
+ pkg_sender->dsi_connector = dsi_connector;
+ pkg_sender->pipe = pipe;
+ pkg_sender->pkg_num = 0;
+ pkg_sender->panel_mode = 0;
+ pkg_sender->status = MDFLD_DSI_PKG_SENDER_FREE;
+
+ /* Init dbi command buffer*/
+
+ if (dsi_config->type == MDFLD_DSI_ENCODER_DBI) {
+ pkg_sender->dbi_pkg_support = 1;
+ ret = mdfld_dbi_cb_init(pkg_sender, pg, pipe);
+ if (ret) {
+ dev_err(dev->dev, "DBI command buffer map failed\n");
+ goto mapping_err;
+ }
+ }
+
+ /* Init regs */
+ if (pipe == 0) {
+ pkg_sender->dpll_reg = MRST_DPLL_A;
+ pkg_sender->dspcntr_reg = DSPACNTR;
+ pkg_sender->pipeconf_reg = PIPEACONF;
+ pkg_sender->dsplinoff_reg = DSPALINOFF;
+ pkg_sender->dspsurf_reg = DSPASURF;
+ pkg_sender->pipestat_reg = PIPEASTAT;
+
+ pkg_sender->mipi_intr_stat_reg = MIPIA_INTR_STAT_REG;
+ pkg_sender->mipi_lp_gen_data_reg = MIPIA_LP_GEN_DATA_REG;
+ pkg_sender->mipi_hs_gen_data_reg = MIPIA_HS_GEN_DATA_REG;
+ pkg_sender->mipi_lp_gen_ctrl_reg = MIPIA_LP_GEN_CTRL_REG;
+ pkg_sender->mipi_hs_gen_ctrl_reg = MIPIA_HS_GEN_CTRL_REG;
+ pkg_sender->mipi_gen_fifo_stat_reg = MIPIA_GEN_FIFO_STAT_REG;
+ pkg_sender->mipi_data_addr_reg = MIPIA_DATA_ADD_REG;
+ pkg_sender->mipi_data_len_reg = MIPIA_DATA_LEN_REG;
+ pkg_sender->mipi_cmd_addr_reg = MIPIA_CMD_ADD_REG;
+ pkg_sender->mipi_cmd_len_reg = MIPIA_CMD_LEN_REG;
+ } else if (pipe == 2) {
+ pkg_sender->dpll_reg = MRST_DPLL_A;
+ pkg_sender->dspcntr_reg = DSPCCNTR;
+ pkg_sender->pipeconf_reg = PIPECCONF;
+ pkg_sender->dsplinoff_reg = DSPCLINOFF;
+ pkg_sender->dspsurf_reg = DSPCSURF;
+ pkg_sender->pipestat_reg = 72024;
+
+ pkg_sender->mipi_intr_stat_reg =
+ MIPIA_INTR_STAT_REG + MIPIC_REG_OFFSET;
+ pkg_sender->mipi_lp_gen_data_reg =
+ MIPIA_LP_GEN_DATA_REG + MIPIC_REG_OFFSET;
+ pkg_sender->mipi_hs_gen_data_reg =
+ MIPIA_HS_GEN_DATA_REG + MIPIC_REG_OFFSET;
+ pkg_sender->mipi_lp_gen_ctrl_reg =
+ MIPIA_LP_GEN_CTRL_REG + MIPIC_REG_OFFSET;
+ pkg_sender->mipi_hs_gen_ctrl_reg =
+ MIPIA_HS_GEN_CTRL_REG + MIPIC_REG_OFFSET;
+ pkg_sender->mipi_gen_fifo_stat_reg =
+ MIPIA_GEN_FIFO_STAT_REG + MIPIC_REG_OFFSET;
+ pkg_sender->mipi_data_addr_reg =
+ MIPIA_DATA_ADD_REG + MIPIC_REG_OFFSET;
+ pkg_sender->mipi_data_len_reg =
+ MIPIA_DATA_LEN_REG + MIPIC_REG_OFFSET;
+ pkg_sender->mipi_cmd_addr_reg =
+ MIPIA_CMD_ADD_REG + MIPIC_REG_OFFSET;
+ pkg_sender->mipi_cmd_len_reg =
+ MIPIA_CMD_LEN_REG + MIPIC_REG_OFFSET;
+ }
+
+ /* Init pkg list */
+ INIT_LIST_HEAD(&pkg_sender->pkg_list);
+ INIT_LIST_HEAD(&pkg_sender->free_list);
+
+ spin_lock_init(&pkg_sender->lock);
+
+ /* Allocate free pkg pool */
+ for (i = 0; i < MDFLD_MAX_PKG_NUM; i++) {
+ pkg = kzalloc(sizeof(struct mdfld_dsi_pkg), GFP_KERNEL);
+ if (!pkg) {
+ dev_err(dev->dev, "Out of memory allocating pkg pool");
+ ret = -ENOMEM;
+ goto pkg_alloc_err;
+ }
+ INIT_LIST_HEAD(&pkg->entry);
+ list_add_tail(&pkg->entry, &pkg_sender->free_list);


+ }
+ return 0;
+

+pkg_alloc_err:
+ list_for_each_entry_safe(pkg, tmp, &pkg_sender->free_list, entry) {
+ list_del(&pkg->entry);
+ kfree(pkg);
+ }
+
+ /* Free mapped command buffer */
+ mdfld_dbi_cb_destroy(pkg_sender);
+mapping_err:
+ kfree(pkg_sender);
+ dsi_connector->pkg_sender = NULL;


+ return ret;
+}
+

+void mdfld_dsi_pkg_sender_destroy(struct mdfld_dsi_pkg_sender *sender)
+{
+ struct mdfld_dsi_pkg *pkg, *tmp;
+
+ if (!sender || IS_ERR(sender))
+ return;
+
+ /* Free pkg pool */
+ list_for_each_entry_safe(pkg, tmp, &sender->free_list, entry) {
+ list_del(&pkg->entry);
+ kfree(pkg);
+ }
+ /* Free pkg list */
+ list_for_each_entry_safe(pkg, tmp, &sender->pkg_list, entry) {
+ list_del(&pkg->entry);
+ kfree(pkg);
+ }
+ mdfld_dbi_cb_destroy(sender); /* free mapped command buffer */
+ kfree(sender);
+}
diff --git a/drivers/staging/gma500/mdfld_dsi_pkg_sender.h b/drivers/staging/gma500/mdfld_dsi_pkg_sender.h
new file mode 100644
index 0000000..296b1ea
--- /dev/null
+++ b/drivers/staging/gma500/mdfld_dsi_pkg_sender.h
@@ -0,0 +1,158 @@
+/*
+ * Copyright © 2010 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ * Jackie Li<yaodo...@intel.com>
+ */
+#ifndef __MDFLD_DSI_PKG_SENDER_H__
+#define __MDFLD_DSI_PKG_SENDER_H__
+
+#include <linux/kthread.h>
+
+#define MDFLD_MAX_DCS_PARAM 8
+#define MDFLD_MAX_PKG_NUM 2048
+
+enum {
+ MDFLD_DSI_PKG_DCS,
+ MDFLD_DSI_PKG_GEN_SHORT_WRITE_0 = 0x03,
+ MDFLD_DSI_PKG_GEN_SHORT_WRITE_1 = 0x13,
+ MDFLD_DSI_PKG_GEN_SHORT_WRITE_2 = 0x23,
+ MDFLD_DSI_PKG_GEN_LONG_WRITE = 0x29,
+ MDFLD_DSI_PKG_MCS_SHORT_WRITE_0 = 0x05,
+ MDFLD_DSI_PKG_MCS_SHORT_WRITE_1 = 0x15,
+ MDFLD_DSI_PKG_MCS_LONG_WRITE = 0x39,
+};
+
+enum {
+ MDFLD_DSI_LP_TRANSMISSION,
+ MDFLD_DSI_HS_TRANSMISSION,
+ MDFLD_DSI_DCS,
+};
+
+enum {
+ MDFLD_DSI_PANEL_MODE_SLEEP = 0x1,
+};
+
+enum {
+ MDFLD_DSI_PKG_SENDER_FREE = 0x0,
+ MDFLD_DSI_PKG_SENDER_BUSY = 0x1,
+};
+
+enum {
+ MDFLD_DSI_SEND_PACKAGE,
+ MDFLD_DSI_QUEUE_PACKAGE,
+};
+
+struct mdfld_dsi_gen_short_pkg {
+ u8 cmd;
+ u8 param;
+};
+
+struct mdfld_dsi_gen_long_pkg {
+ u32 *data;
+ u32 len;
+};
+
+struct mdfld_dsi_dcs_pkg {
+ u8 cmd;
+ u8 param[MDFLD_MAX_DCS_PARAM];
+ u32 param_num;
+ u8 data_src;
+};
+
+struct mdfld_dsi_pkg {
+ u8 pkg_type;
+ u8 transmission_type;
+
+ union {
+ struct mdfld_dsi_gen_short_pkg short_pkg;
+ struct mdfld_dsi_gen_long_pkg long_pkg;
+ struct mdfld_dsi_dcs_pkg dcs_pkg;
+ } pkg;
+
+ struct list_head entry;
+};
+
+struct mdfld_dsi_pkg_sender {
+ struct drm_device *dev;
+ struct mdfld_dsi_connector *dsi_connector;
+ u32 status;
+
+ u32 panel_mode;
+
+ int pipe;
+
+ spinlock_t lock;
+ struct list_head pkg_list;
+ struct list_head free_list;
+
+ u32 pkg_num;
+
+ int dbi_pkg_support;
+
+ u32 dbi_cb_phy;
+ void *dbi_cb_addr;
+
+ /* Registers */
+ u32 dpll_reg;
+ u32 dspcntr_reg;
+ u32 pipeconf_reg;
+ u32 pipestat_reg;
+ u32 dsplinoff_reg;
+ u32 dspsurf_reg;
+
+ u32 mipi_intr_stat_reg;
+ u32 mipi_lp_gen_data_reg;
+ u32 mipi_hs_gen_data_reg;
+ u32 mipi_lp_gen_ctrl_reg;
+ u32 mipi_hs_gen_ctrl_reg;
+ u32 mipi_gen_fifo_stat_reg;
+ u32 mipi_data_addr_reg;
+ u32 mipi_data_len_reg;
+ u32 mipi_cmd_addr_reg;
+ u32 mipi_cmd_len_reg;
+};
+
+extern int mdfld_dsi_pkg_sender_init(struct mdfld_dsi_connector *dsi_connector,
+ int pipe);
+extern void mdfld_dsi_pkg_sender_destroy(struct mdfld_dsi_pkg_sender *sender);
+extern int mdfld_dsi_send_dcs(struct mdfld_dsi_pkg_sender *sender, u8 dcs,
+ u8 *param, u32 param_num, u8 data_src, int delay);
+extern int mdfld_dsi_send_mcs_short_hs(struct mdfld_dsi_pkg_sender *sender,
+ u8 cmd, u8 param, u8 param_num, int delay);
+extern int mdfld_dsi_send_mcs_short_lp(struct mdfld_dsi_pkg_sender *sender,
+ u8 cmd, u8 param, u8 param_num, int delay);
+extern int mdfld_dsi_send_mcs_long_hs(struct mdfld_dsi_pkg_sender *sender,
+ u32 *data, u32 len, int delay);
+extern int mdfld_dsi_send_mcs_long_lp(struct mdfld_dsi_pkg_sender *sender,
+ u32 *data, u32 len, int delay);
+extern int mdfld_dsi_send_gen_short_hs(struct mdfld_dsi_pkg_sender *sender,
+ u8 param0, u8 param1, u8 param_num, int delay);
+extern int mdfld_dsi_send_gen_short_lp(struct mdfld_dsi_pkg_sender *sender,
+ u8 param0, u8 param1, u8 param_num, int delay);
+extern int mdfld_dsi_send_gen_long_hs(struct mdfld_dsi_pkg_sender *sender,
+ u32 *data, u32 len, int delay);
+extern int mdfld_dsi_send_gen_long_lp(struct mdfld_dsi_pkg_sender *sender,
+ u32 *data, u32 len, int delay);
+extern void mdfld_dsi_cmds_kick_out(struct mdfld_dsi_pkg_sender *sender);
+
+#endif /* __MDFLD_DSI_PKG_SENDER_H__ */
diff --git a/drivers/staging/gma500/mdfld_intel_display.c b/drivers/staging/gma500/mdfld_intel_display.c
new file mode 100644
index 0000000..26d7f80
--- /dev/null
+++ b/drivers/staging/gma500/mdfld_intel_display.c
@@ -0,0 +1,1388 @@
+/*
+ * Copyright © 2006-2011 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ * Eric Anholt <er...@anholt.net>
+ */
+
+#include "psb_fb.h"
+#include "psb_intel_display.h"
+#include "mdfld_dsi_dbi.h"
+#include "mdfld_dsi_dpi.h"
+//#include "mdfld_dsi_output.h"
+#ifdef CONFIG_MDFLD_DSI_DPU
+#include "mdfld_dsi_dbi_dpu.h"
+#endif
+
+#include <linux/pm_runtime.h>
+
+#ifdef MIN
+#undef MIN
+#endif
+
+#define MIN(x, y) (((x) < (y)) ? (x) : (y))
+
+/* Hardcoded currently */
+static int ksel = KSEL_CRYSTAL_19;
+
+extern struct drm_device *gpDrmDevice;
+extern void mdfld_save_display(struct drm_device *dev);
+extern bool gbgfxsuspended;
+
+struct psb_intel_range_t {
+ int min, max;
+};
+
+struct mdfld_limit_t {
+ struct psb_intel_range_t dot, m, p1;
+};
+
+struct mdfld_intel_clock_t {
+ /* given values */
+ int n;
+ int m1, m2;
+ int p1, p2;
+ /* derived values */
+ int dot;
+ int vco;
+ int m;
+ int p;
+};
+
+
+
+#define COUNT_MAX 0x10000000
+
+void mdfldWaitForPipeDisable(struct drm_device *dev, int pipe)
+{
+ int count, temp;
+ u32 pipeconf_reg = PIPEACONF;
+
+ switch (pipe) {
+ case 0:
+ break;
+ case 1:
+ pipeconf_reg = PIPEBCONF;
+ break;
+ case 2:
+ pipeconf_reg = PIPECCONF;
+ break;
+ default:
+ DRM_ERROR("Illegal Pipe Number. \n");
+ return;
+ }
+
+ /* FIXME JLIU7_PO */
+ psb_intel_wait_for_vblank(dev);
+ return;
+
+ /* Wait for for the pipe disable to take effect. */
+ for (count = 0; count < COUNT_MAX; count++) {
+ temp = REG_READ(pipeconf_reg);
+ if ((temp & PIPEACONF_PIPE_STATE) == 0)
+ break;
+ }
+}
+
+void mdfldWaitForPipeEnable(struct drm_device *dev, int pipe)
+{
+ int count, temp;
+ u32 pipeconf_reg = PIPEACONF;
+
+ switch (pipe) {
+ case 0:
+ break;
+ case 1:
+ pipeconf_reg = PIPEBCONF;
+ break;
+ case 2:
+ pipeconf_reg = PIPECCONF;
+ break;
+ default:


+ dev_err(dev->dev, "Illegal Pipe Number.\n");

+ return;
+ }
+
+ /* FIXME JLIU7_PO */
+ psb_intel_wait_for_vblank(dev);
+ return;
+
+ /* Wait for for the pipe enable to take effect. */
+ for (count = 0; count < COUNT_MAX; count++) {
+ temp = REG_READ(pipeconf_reg);
+ if ((temp & PIPEACONF_PIPE_STATE) == 1)
+ break;
+ }
+}
+
+
+static int mdfld_intel_crtc_cursor_set(struct drm_crtc *crtc,
+ struct drm_file *file_priv,
+ uint32_t handle,
+ uint32_t width, uint32_t height)
+{
+ struct drm_device *dev = crtc->dev;
+ struct drm_psb_private * dev_priv = (struct drm_psb_private *)dev->dev_private;
+ struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc);
+ int pipe = psb_intel_crtc->pipe;
+ uint32_t control = CURACNTR;
+ uint32_t base = CURABASE;
+ uint32_t temp;
+ size_t addr = 0;
+ struct gtt_range *gt;
+ struct drm_gem_object *obj;
+ int ret;
+
+ switch (pipe) {
+ case 0:
+ break;
+ case 1:
+ control = CURBCNTR;
+ base = CURBBASE;
+ break;
+ case 2:
+ control = CURCCNTR;
+ base = CURCBASE;
+ break;
+ default:


+ dev_err(dev->dev, "Illegal Pipe Number. \n");

+ return -EINVAL;
+ }
+

+#if 1 /* FIXME_JLIU7 can't enalbe cursorB/C HW issue. need to remove after HW fix */
+ if (pipe != 0)
+ return 0;
+#endif
+ /* if we want to turn of the cursor ignore width and height */
+ if (!handle) {
+ dev_dbg(dev->dev, "cursor off\n");
+ /* turn off the cursor */
+ temp = 0;
+ temp |= CURSOR_MODE_DISABLE;
+
+ if (gma_power_begin(dev, true)) {
+ REG_WRITE(control, temp);
+ REG_WRITE(base, 0);
+ gma_power_end(dev);
+ }
+ /* Unpin the old GEM object */
+ if (psb_intel_crtc->cursor_obj) {
+ gt = container_of(psb_intel_crtc->cursor_obj,
+ struct gtt_range, gem);
+ psb_gtt_unpin(gt);
+ drm_gem_object_unreference(psb_intel_crtc->cursor_obj);
+ psb_intel_crtc->cursor_obj = NULL;


+ }
+ return 0;
+ }
+

+ /* Currently we only support 64x64 cursors */
+ if (width != 64 || height != 64) {
+ DRM_ERROR("we currently only support 64x64 cursors\n");


+ return -EINVAL;
+ }
+

+ obj = drm_gem_object_lookup(dev, file_priv, handle);
+ if (!obj)
+ return -ENOENT;
+
+ if (obj->size < width * height * 4) {


+ dev_dbg(dev->dev, "buffer is to small\n");

+ return -ENOMEM;
+ }
+
+ gt = container_of(obj, struct gtt_range, gem);
+
+ /* Pin the memory into the GTT */
+ ret = psb_gtt_pin(gt);
+ if (ret) {
+ dev_err(dev->dev, "Can not pin down handle 0x%x\n", handle);


+ return ret;
+ }
+

+
+ addr = gt->offset; /* Or resource.start ??? */
+
+ psb_intel_crtc->cursor_addr = addr;
+
+ temp = 0;
+ /* set the pipe for the cursor */
+ temp |= (pipe << 28);
+ temp |= CURSOR_MODE_64_ARGB_AX | MCURSOR_GAMMA_ENABLE;
+
+ if (gma_power_begin(dev, true)) {
+ REG_WRITE(control, temp);
+ REG_WRITE(base, addr);
+ gma_power_end(dev);
+ }
+#if 0
+ /* FIXME: COnvert to GEM */
+ /* unpin the old bo */
+ if (psb_intel_crtc->cursor_bo && psb_intel_crtc->cursor_bo != bo) {
+ mode_dev->bo_unpin_for_scanout(dev, psb_intel_crtc->cursor_bo);
+ psb_intel_crtc->cursor_bo = bo;
+ }
+#endif


+ return 0;
+}
+

+static int mdfld_intel_crtc_cursor_move(struct drm_crtc *crtc, int x, int y)
+{
+ struct drm_device *dev = crtc->dev;
+#ifndef CONFIG_MDFLD_DSI_DPU
+ struct drm_psb_private * dev_priv = (struct drm_psb_private *)dev->dev_private;
+#else
+ struct psb_drm_dpu_rect rect;
+#endif
+ struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc);
+ int pipe = psb_intel_crtc->pipe;
+ uint32_t pos = CURAPOS;
+ uint32_t base = CURABASE;
+ uint32_t temp = 0;
+ uint32_t addr;
+
+ switch (pipe) {
+ case 0:
+#ifndef CONFIG_MDFLD_DSI_DPU
+ if (!(dev_priv->dsr_fb_update & MDFLD_DSR_CURSOR_0))
+ mdfld_dsi_dbi_exit_dsr (dev, MDFLD_DSR_CURSOR_0, 0, 0);
+#else /*CONFIG_MDFLD_DSI_DPU*/
+ rect.x = x;
+ rect.y = y;
+
+ mdfld_dbi_dpu_report_damage(dev, MDFLD_CURSORA, &rect);
+ mdfld_dpu_exit_dsr(dev);
+#endif
+ break;
+ case 1:
+ pos = CURBPOS;
+ base = CURBBASE;
+ break;
+ case 2:
+#ifndef CONFIG_MDFLD_DSI_DPU
+ if (!(dev_priv->dsr_fb_update & MDFLD_DSR_CURSOR_2))
+ mdfld_dsi_dbi_exit_dsr (dev, MDFLD_DSR_CURSOR_2, 0, 0);
+#else /*CONFIG_MDFLD_DSI_DPU*/
+ mdfld_dbi_dpu_report_damage(dev, MDFLD_CURSORC, &rect);
+ mdfld_dpu_exit_dsr(dev);
+#endif
+ pos = CURCPOS;
+ base = CURCBASE;
+ break;
+ default:
+ DRM_ERROR("Illegal Pipe Number. \n");


+ return -EINVAL;
+ }
+

+#if 1 /* FIXME_JLIU7 can't enalbe cursorB/C HW issue. need to remove after HW fix */
+ if (pipe != 0)
+ return 0;
+#endif
+ if (x < 0) {
+ temp |= (CURSOR_POS_SIGN << CURSOR_X_SHIFT);
+ x = -x;
+ }
+ if (y < 0) {
+ temp |= (CURSOR_POS_SIGN << CURSOR_Y_SHIFT);
+ y = -y;
+ }
+
+ temp |= ((x & CURSOR_POS_MASK) << CURSOR_X_SHIFT);
+ temp |= ((y & CURSOR_POS_MASK) << CURSOR_Y_SHIFT);
+
+ addr = psb_intel_crtc->cursor_addr;
+
+ if (gma_power_begin(dev, true)) {
+ REG_WRITE(pos, temp);
+ REG_WRITE(base, addr);
+ gma_power_end(dev);
+ }


+
+ return 0;
+}
+

+const struct drm_crtc_funcs mdfld_intel_crtc_funcs = {
+ .cursor_set = mdfld_intel_crtc_cursor_set,
+ .cursor_move = mdfld_intel_crtc_cursor_move,
+ .gamma_set = psb_intel_crtc_gamma_set,
+ .set_config = drm_crtc_helper_set_config,
+ .destroy = psb_intel_crtc_destroy,
+};
+
+static struct drm_device globle_dev;
+
+void mdfld__intel_plane_set_alpha(int enable)
+{
+ struct drm_device *dev = &globle_dev;
+ int dspcntr_reg = DSPACNTR;
+ u32 dspcntr;
+
+ dspcntr = REG_READ(dspcntr_reg);
+
+ if (enable) {
+ dspcntr &= ~DISPPLANE_32BPP_NO_ALPHA;
+ dspcntr |= DISPPLANE_32BPP;
+ } else {
+ dspcntr &= ~DISPPLANE_32BPP;
+ dspcntr |= DISPPLANE_32BPP_NO_ALPHA;
+ }
+
+ REG_WRITE(dspcntr_reg, dspcntr);
+}
+
+int mdfld__intel_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);
+ struct psb_intel_mode_device *mode_dev = psb_intel_crtc->mode_dev;
+ int pipe = psb_intel_crtc->pipe;
+ unsigned long start, offset;
+ int dsplinoff = DSPALINOFF;
+ int dspsurf = DSPASURF;
+ int dspstride = DSPASTRIDE;
+ int dspcntr_reg = DSPACNTR;
+ u32 dspcntr;


+ int ret = 0;

+
+ memcpy(&globle_dev, dev, sizeof(struct drm_device));
+
+ if (!gma_power_begin(dev, true))
+ return 0;
+
+ /* no fb bound */
+ if (!crtc->fb) {
+ dev_err(dev->dev, "No FB bound\n");
+ goto psb_intel_pipe_cleaner;
+ }
+
+ switch (pipe) {
+ case 0:
+ dsplinoff = DSPALINOFF;
+ break;
+ case 1:
+ dsplinoff = DSPBLINOFF;
+ dspsurf = DSPBSURF;
+ dspstride = DSPBSTRIDE;
+ dspcntr_reg = DSPBCNTR;
+ break;
+ case 2:
+ dsplinoff = DSPCLINOFF;
+ dspsurf = DSPCSURF;
+ dspstride = DSPCSTRIDE;
+ dspcntr_reg = DSPCCNTR;
+ break;
+ default:


+ dev_err(dev->dev, "Illegal Pipe Number.\n");

+ return -EINVAL;
+ }
+

+ ret = psb_gtt_pin(psbfb->gtt);
+ if (ret < 0)
+ goto psb_intel_pipe_set_base_exit;
+
+ start = psbfb->gtt->offset;
+ offset = y * crtc->fb->pitch + x * (crtc->fb->bits_per_pixel / 8);
+
+ REG_WRITE(dspstride, crtc->fb->pitch);
+ dspcntr = REG_READ(dspcntr_reg);
+ dspcntr &= ~DISPPLANE_PIXFORMAT_MASK;
+
+ switch (crtc->fb->bits_per_pixel) {
+ case 8:
+ dspcntr |= DISPPLANE_8BPP;
+ break;
+ case 16:
+ if (crtc->fb->depth == 15)
+ dspcntr |= DISPPLANE_15_16BPP;
+ else
+ dspcntr |= DISPPLANE_16BPP;
+ break;


+ case 24:
+ case 32:

+ dspcntr |= DISPPLANE_32BPP_NO_ALPHA;
+ break;
+ default:
+ dev_err(dev->dev, "Unknown color depth\n");
+ ret = -EINVAL;
+ goto psb_intel_pipe_set_base_exit;
+ }
+ REG_WRITE(dspcntr_reg, dspcntr);
+
+ dev_dbg(dev->dev, "Writing base %08lX %08lX %d %d\n",
+ start, offset, x, y);
+
+ REG_WRITE(dsplinoff, offset);
+ REG_READ(dsplinoff);
+ REG_WRITE(dspsurf, start);
+ REG_READ(dspsurf);
+
+psb_intel_pipe_cleaner:
+ /* If there was a previous display we can now unpin it */
+ if (old_fb)
+ psb_gtt_unpin(to_psb_fb(old_fb)->gtt);
+
+psb_intel_pipe_set_base_exit:
+ gma_power_end(dev);


+ return ret;
+}
+

+/**
+ * Disable the pipe, plane and pll.
+ *
+ */
+void mdfld_disable_crtc (struct drm_device *dev, int pipe)
+{
+ int dpll_reg = MRST_DPLL_A;
+ int dspcntr_reg = DSPACNTR;
+ int dspbase_reg = MRST_DSPABASE;
+ int pipeconf_reg = PIPEACONF;
+ u32 gen_fifo_stat_reg = GEN_FIFO_STAT_REG;
+ u32 temp;
+
+ switch (pipe) {
+ case 0:
+ break;
+ case 1:
+ dpll_reg = MDFLD_DPLL_B;
+ dspcntr_reg = DSPBCNTR;
+ dspbase_reg = DSPBSURF;
+ pipeconf_reg = PIPEBCONF;
+ break;
+ case 2:
+ dpll_reg = MRST_DPLL_A;
+ dspcntr_reg = DSPCCNTR;
+ dspbase_reg = MDFLD_DSPCBASE;
+ pipeconf_reg = PIPECCONF;
+ gen_fifo_stat_reg = GEN_FIFO_STAT_REG + MIPIC_REG_OFFSET;
+ break;
+ default:


+ dev_err(dev->dev, "Illegal Pipe Number. \n");

+ return;
+ }
+
+ if (pipe != 1)
+ mdfld_dsi_gen_fifo_ready (dev, gen_fifo_stat_reg, HS_CTRL_FIFO_EMPTY | HS_DATA_FIFO_EMPTY);
+
+ /* Disable display plane */
+ temp = REG_READ(dspcntr_reg);
+ if ((temp & DISPLAY_PLANE_ENABLE) != 0) {
+ REG_WRITE(dspcntr_reg,
+ temp & ~DISPLAY_PLANE_ENABLE);
+ /* Flush the plane changes */
+ REG_WRITE(dspbase_reg, REG_READ(dspbase_reg));
+ REG_READ(dspbase_reg);
+ }
+
+ /* FIXME_JLIU7 MDFLD_PO revisit */
+ /* Wait for vblank for the disable to take effect */
+// MDFLD_PO_JLIU7 psb_intel_wait_for_vblank(dev);
+
+ /* Next, disable display pipes */
+ temp = REG_READ(pipeconf_reg);
+ if ((temp & PIPEACONF_ENABLE) != 0) {
+ temp &= ~PIPEACONF_ENABLE;
+ temp |= PIPECONF_PLANE_OFF | PIPECONF_CURSOR_OFF;
+ REG_WRITE(pipeconf_reg, temp);
+ REG_READ(pipeconf_reg);
+
+ /* Wait for for the pipe disable to take effect. */
+ mdfldWaitForPipeDisable(dev, pipe);
+ }
+
+ temp = REG_READ(dpll_reg);
+ if (temp & DPLL_VCO_ENABLE) {
+ if (((pipe != 1) && !((REG_READ(PIPEACONF) | REG_READ(PIPECCONF)) & PIPEACONF_ENABLE))
+ || (pipe == 1)){
+ temp &= ~(DPLL_VCO_ENABLE);
+ REG_WRITE(dpll_reg, temp);
+ REG_READ(dpll_reg);
+ /* Wait for the clocks to turn off. */
+ /* FIXME_MDFLD PO may need more delay */
+ udelay(500);
+
+ if (!(temp & MDFLD_PWR_GATE_EN)) {
+ /* gating power of DPLL */
+ REG_WRITE(dpll_reg, temp | MDFLD_PWR_GATE_EN);
+ /* FIXME_MDFLD PO - change 500 to 1 after PO */
+ udelay(5000);
+ }
+ }
+ }
+
+}
+
+/**
+ * Sets the power management mode of the pipe and plane.
+ *
+ * This code should probably grow support for turning the cursor off and back
+ * on appropriately at the same time as we're turning the pipe off/on.
+ */
+static void mdfld_crtc_dpms(struct drm_crtc *crtc, int mode)
+{
+ struct drm_device *dev = crtc->dev;
+ struct drm_psb_private *dev_priv = dev->dev_private;
+ struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc);
+ int pipe = psb_intel_crtc->pipe;
+ int dpll_reg = MRST_DPLL_A;
+ int dspcntr_reg = DSPACNTR;
+ int dspbase_reg = MRST_DSPABASE;
+ int pipeconf_reg = PIPEACONF;
+ u32 pipestat_reg = PIPEASTAT;
+ u32 gen_fifo_stat_reg = GEN_FIFO_STAT_REG;
+ u32 pipeconf = dev_priv->pipeconf;
+ u32 dspcntr = dev_priv->dspcntr;
+ u32 mipi_enable_reg = MIPIA_DEVICE_READY_REG;
+ u32 temp;
+ bool enabled;
+ int timeout = 0;
+
+ if (!gma_power_begin(dev, true))
+ return;
+
+ /* Ignore if system is already in DSR and in suspended state. */
+ if(gbgfxsuspended && dev_priv->dispstatus == false && mode == 3){
+ if(dev_priv->rpm_enabled && pipe == 1){
+ // dev_priv->is_mipi_on = false;
+ pm_request_idle(&gpDrmDevice->pdev->dev);
+ }
+ return;
+ }else if(mode == 0) {
+ //do not need to set gbdispstatus=true in crtc.
+ //this will be set in encoder such as mdfld_dsi_dbi_dpms
+ //gbdispstatus = true;
+ }
+
+
+/* FIXME_JLIU7 MDFLD_PO replaced w/ the following function */
+/* mdfld_dbi_dpms (struct drm_device *dev, int pipe, bool enabled) */
+
+ switch (pipe) {
+ case 0:
+ break;
+ case 1:
+ dpll_reg = DPLL_B;
+ dspcntr_reg = DSPBCNTR;
+ dspbase_reg = MRST_DSPBBASE;
+ pipeconf_reg = PIPEBCONF;
+ pipeconf = dev_priv->pipeconf1;
+ dspcntr = dev_priv->dspcntr1;
+ dpll_reg = MDFLD_DPLL_B;
+ break;
+ case 2:
+ dpll_reg = MRST_DPLL_A;
+ dspcntr_reg = DSPCCNTR;
+ dspbase_reg = MDFLD_DSPCBASE;
+ pipeconf_reg = PIPECCONF;
+ pipestat_reg = PIPECSTAT;
+ pipeconf = dev_priv->pipeconf2;
+ dspcntr = dev_priv->dspcntr2;
+ gen_fifo_stat_reg = GEN_FIFO_STAT_REG + MIPIC_REG_OFFSET;
+ mipi_enable_reg = MIPIA_DEVICE_READY_REG + MIPIC_REG_OFFSET;
+ break;
+ default:


+ dev_err(dev->dev, "Illegal Pipe Number.\n");

+ return;
+ }
+
+ /* XXX: When our outputs are all unaware of DPMS modes other than off
+ * and on, we should map those modes to DRM_MODE_DPMS_OFF in the CRTC.
+ */
+ switch (mode) {
+ case DRM_MODE_DPMS_ON:
+ case DRM_MODE_DPMS_STANDBY:
+ case DRM_MODE_DPMS_SUSPEND:
+ /* Enable the DPLL */
+ temp = REG_READ(dpll_reg);
+
+ if ((temp & DPLL_VCO_ENABLE) == 0) {
+ /* When ungating power of DPLL, needs to wait 0.5us before enable the VCO */
+ if (temp & MDFLD_PWR_GATE_EN) {
+ temp &= ~MDFLD_PWR_GATE_EN;
+ REG_WRITE(dpll_reg, temp);
+ /* FIXME_MDFLD PO - change 500 to 1 after PO */
+ udelay(500);
+ }
+
+ REG_WRITE(dpll_reg, temp);
+ REG_READ(dpll_reg);
+ /* FIXME_MDFLD PO - change 500 to 1 after PO */
+ udelay(500);
+
+ REG_WRITE(dpll_reg, temp | DPLL_VCO_ENABLE);
+ REG_READ(dpll_reg);
+
+ /**
+ * wait for DSI PLL to lock
+ * NOTE: only need to poll status of pipe 0 and pipe 1,
+ * since both MIPI pipes share the same PLL.
+ */
+ while ((pipe != 2) && (timeout < 20000) && !(REG_READ(pipeconf_reg) & PIPECONF_DSIPLL_LOCK)) {
+ udelay(150);
+ timeout ++;
+ }
+ }
+
+ /* Enable the plane */
+ temp = REG_READ(dspcntr_reg);
+ if ((temp & DISPLAY_PLANE_ENABLE) == 0) {
+ REG_WRITE(dspcntr_reg,
+ temp | DISPLAY_PLANE_ENABLE);
+ /* Flush the plane changes */
+ REG_WRITE(dspbase_reg, REG_READ(dspbase_reg));
+ }
+
+ /* Enable the pipe */
+ temp = REG_READ(pipeconf_reg);
+ if ((temp & PIPEACONF_ENABLE) == 0) {
+ REG_WRITE(pipeconf_reg, pipeconf);
+
+ /* Wait for for the pipe enable to take effect. */
+ mdfldWaitForPipeEnable(dev, pipe);
+ }
+
+ /*workaround for sighting 3741701 Random X blank display*/
+ /*perform w/a in video mode only on pipe A or C*/
+ if ((pipe == 0 || pipe == 2) &&
+ (mdfld_panel_dpi(dev) == true)) {
+ REG_WRITE(pipestat_reg, REG_READ(pipestat_reg));
+ msleep(100);
+ if(PIPE_VBLANK_STATUS & REG_READ(pipestat_reg)) {
+ printk(KERN_ALERT "OK");
+ } else {
+ printk(KERN_ALERT "STUCK!!!!");
+ /*shutdown controller*/
+ temp = REG_READ(dspcntr_reg);
+ REG_WRITE(dspcntr_reg, temp & ~DISPLAY_PLANE_ENABLE);
+ REG_WRITE(dspbase_reg, REG_READ(dspbase_reg));
+ /*mdfld_dsi_dpi_shut_down(dev, pipe);*/
+ REG_WRITE(0xb048, 1);
+ msleep(100);
+ temp = REG_READ(pipeconf_reg);
+ temp &= ~PIPEACONF_ENABLE;
+ REG_WRITE(pipeconf_reg, temp);
+ msleep(100); /*wait for pipe disable*/
+ /*printk(KERN_ALERT "70008 is %x\n", REG_READ(0x70008));
+ printk(KERN_ALERT "b074 is %x\n", REG_READ(0xb074));*/
+ REG_WRITE(mipi_enable_reg, 0);
+ msleep(100);
+ printk(KERN_ALERT "70008 is %x\n", REG_READ(0x70008));
+ printk(KERN_ALERT "b074 is %x\n", REG_READ(0xb074));
+ REG_WRITE(0xb004, REG_READ(0xb004));
+ /* try to bring the controller back up again*/
+ REG_WRITE(mipi_enable_reg, 1);
+ temp = REG_READ(dspcntr_reg);
+ REG_WRITE(dspcntr_reg, temp | DISPLAY_PLANE_ENABLE);
+ REG_WRITE(dspbase_reg, REG_READ(dspbase_reg));
+ /*mdfld_dsi_dpi_turn_on(dev, pipe);*/
+ REG_WRITE(0xb048, 2);
+ msleep(100);
+ temp = REG_READ(pipeconf_reg);
+ temp |= PIPEACONF_ENABLE;
+ REG_WRITE(pipeconf_reg, temp);
+ }
+ }
+
+ psb_intel_crtc_load_lut(crtc);
+
+ /* Give the overlay scaler a chance to enable
+ if it's on this pipe */
+ /* psb_intel_crtc_dpms_video(crtc, true); TODO */
+
+ break;
+ case DRM_MODE_DPMS_OFF:
+ /* Give the overlay scaler a chance to disable
+ * if it's on this pipe */
+ /* psb_intel_crtc_dpms_video(crtc, FALSE); TODO */
+ if (pipe != 1)
+ mdfld_dsi_gen_fifo_ready (dev, gen_fifo_stat_reg, HS_CTRL_FIFO_EMPTY | HS_DATA_FIFO_EMPTY);
+
+ /* Disable the VGA plane that we never use */
+ REG_WRITE(VGACNTRL, VGA_DISP_DISABLE);
+
+ /* Disable display plane */
+ temp = REG_READ(dspcntr_reg);
+ if ((temp & DISPLAY_PLANE_ENABLE) != 0) {
+ REG_WRITE(dspcntr_reg,
+ temp & ~DISPLAY_PLANE_ENABLE);
+ /* Flush the plane changes */
+ REG_WRITE(dspbase_reg, REG_READ(dspbase_reg));
+ REG_READ(dspbase_reg);
+ }
+
+ /* FIXME_JLIU7 MDFLD_PO revisit */
+ /* Wait for vblank for the disable to take effect */
+// MDFLD_PO_JLIU7 psb_intel_wait_for_vblank(dev);
+
+ /* Next, disable display pipes */
+ temp = REG_READ(pipeconf_reg);
+ if ((temp & PIPEACONF_ENABLE) != 0) {
+ temp &= ~PIPEACONF_ENABLE;
+ temp |= PIPECONF_PLANE_OFF | PIPECONF_CURSOR_OFF;
+ REG_WRITE(pipeconf_reg, temp);
+// REG_WRITE(pipeconf_reg, 0);
+ REG_READ(pipeconf_reg);
+
+ /* Wait for for the pipe disable to take effect. */
+ mdfldWaitForPipeDisable(dev, pipe);
+ }
+
+ temp = REG_READ(dpll_reg);
+ if (temp & DPLL_VCO_ENABLE) {
+ if (((pipe != 1) && !((REG_READ(PIPEACONF) | REG_READ(PIPECCONF)) & PIPEACONF_ENABLE))
+ || (pipe == 1)){
+ temp &= ~(DPLL_VCO_ENABLE);
+ REG_WRITE(dpll_reg, temp);
+ REG_READ(dpll_reg);
+ /* Wait for the clocks to turn off. */
+ /* FIXME_MDFLD PO may need more delay */
+ udelay(500);
+#if 0 /* MDFLD_PO_JLIU7 */
+ if (!(temp & MDFLD_PWR_GATE_EN)) {
+ /* gating power of DPLL */
+ REG_WRITE(dpll_reg, temp | MDFLD_PWR_GATE_EN);
+ /* FIXME_MDFLD PO - change 500 to 1 after PO */
+ udelay(5000);
+ }
+#endif /* MDFLD_PO_JLIU7 */
+ }
+ }
+ break;
+ }
+
+ enabled = crtc->enabled && mode != DRM_MODE_DPMS_OFF;
+
+#if 0 /* JB: Add vblank support later */
+ if (enabled)
+ dev_priv->vblank_pipe |= (1 << pipe);
+ else
+ dev_priv->vblank_pipe &= ~(1 << pipe);
+#endif
+
+ gma_power_end(dev);
+}
+
+
+#define MDFLD_LIMT_DPLL_19 0
+#define MDFLD_LIMT_DPLL_25 1
+#define MDFLD_LIMT_DPLL_83 2
+#define MDFLD_LIMT_DPLL_100 3
+#define MDFLD_LIMT_DSIPLL_19 4
+#define MDFLD_LIMT_DSIPLL_25 5
+#define MDFLD_LIMT_DSIPLL_83 6
+#define MDFLD_LIMT_DSIPLL_100 7
+
+#define MDFLD_DOT_MIN 19750 /* FIXME_MDFLD JLIU7 need to find out min & max for MDFLD */
+#define MDFLD_DOT_MAX 120000
+#define MDFLD_DPLL_M_MIN_19 113
+#define MDFLD_DPLL_M_MAX_19 155
+#define MDFLD_DPLL_P1_MIN_19 2
+#define MDFLD_DPLL_P1_MAX_19 10
+#define MDFLD_DPLL_M_MIN_25 101
+#define MDFLD_DPLL_M_MAX_25 130
+#define MDFLD_DPLL_P1_MIN_25 2
+#define MDFLD_DPLL_P1_MAX_25 10
+#define MDFLD_DPLL_M_MIN_83 64
+#define MDFLD_DPLL_M_MAX_83 64
+#define MDFLD_DPLL_P1_MIN_83 2
+#define MDFLD_DPLL_P1_MAX_83 2
+#define MDFLD_DPLL_M_MIN_100 64
+#define MDFLD_DPLL_M_MAX_100 64
+#define MDFLD_DPLL_P1_MIN_100 2
+#define MDFLD_DPLL_P1_MAX_100 2
+#define MDFLD_DSIPLL_M_MIN_19 131
+#define MDFLD_DSIPLL_M_MAX_19 175
+#define MDFLD_DSIPLL_P1_MIN_19 3
+#define MDFLD_DSIPLL_P1_MAX_19 8
+#define MDFLD_DSIPLL_M_MIN_25 97
+#define MDFLD_DSIPLL_M_MAX_25 140
+#define MDFLD_DSIPLL_P1_MIN_25 3
+#define MDFLD_DSIPLL_P1_MAX_25 9
+#define MDFLD_DSIPLL_M_MIN_83 33
+#define MDFLD_DSIPLL_M_MAX_83 92
+#define MDFLD_DSIPLL_P1_MIN_83 2
+#define MDFLD_DSIPLL_P1_MAX_83 3
+#define MDFLD_DSIPLL_M_MIN_100 97
+#define MDFLD_DSIPLL_M_MAX_100 140
+#define MDFLD_DSIPLL_P1_MIN_100 3
+#define MDFLD_DSIPLL_P1_MAX_100 9
+
+static const struct mdfld_limit_t mdfld_limits[] = {
+ { /* MDFLD_LIMT_DPLL_19 */
+ .dot = {.min = MDFLD_DOT_MIN, .max = MDFLD_DOT_MAX},
+ .m = {.min = MDFLD_DPLL_M_MIN_19, .max = MDFLD_DPLL_M_MAX_19},
+ .p1 = {.min = MDFLD_DPLL_P1_MIN_19, .max = MDFLD_DPLL_P1_MAX_19},
+ },
+ { /* MDFLD_LIMT_DPLL_25 */
+ .dot = {.min = MDFLD_DOT_MIN, .max = MDFLD_DOT_MAX},
+ .m = {.min = MDFLD_DPLL_M_MIN_25, .max = MDFLD_DPLL_M_MAX_25},
+ .p1 = {.min = MDFLD_DPLL_P1_MIN_25, .max = MDFLD_DPLL_P1_MAX_25},
+ },
+ { /* MDFLD_LIMT_DPLL_83 */
+ .dot = {.min = MDFLD_DOT_MIN, .max = MDFLD_DOT_MAX},
+ .m = {.min = MDFLD_DPLL_M_MIN_83, .max = MDFLD_DPLL_M_MAX_83},
+ .p1 = {.min = MDFLD_DPLL_P1_MIN_83, .max = MDFLD_DPLL_P1_MAX_83},
+ },
+ { /* MDFLD_LIMT_DPLL_100 */
+ .dot = {.min = MDFLD_DOT_MIN, .max = MDFLD_DOT_MAX},
+ .m = {.min = MDFLD_DPLL_M_MIN_100, .max = MDFLD_DPLL_M_MAX_100},
+ .p1 = {.min = MDFLD_DPLL_P1_MIN_100, .max = MDFLD_DPLL_P1_MAX_100},
+ },
+ { /* MDFLD_LIMT_DSIPLL_19 */
+ .dot = {.min = MDFLD_DOT_MIN, .max = MDFLD_DOT_MAX},
+ .m = {.min = MDFLD_DSIPLL_M_MIN_19, .max = MDFLD_DSIPLL_M_MAX_19},
+ .p1 = {.min = MDFLD_DSIPLL_P1_MIN_19, .max = MDFLD_DSIPLL_P1_MAX_19},
+ },
+ { /* MDFLD_LIMT_DSIPLL_25 */
+ .dot = {.min = MDFLD_DOT_MIN, .max = MDFLD_DOT_MAX},
+ .m = {.min = MDFLD_DSIPLL_M_MIN_25, .max = MDFLD_DSIPLL_M_MAX_25},
+ .p1 = {.min = MDFLD_DSIPLL_P1_MIN_25, .max = MDFLD_DSIPLL_P1_MAX_25},
+ },
+ { /* MDFLD_LIMT_DSIPLL_83 */
+ .dot = {.min = MDFLD_DOT_MIN, .max = MDFLD_DOT_MAX},
+ .m = {.min = MDFLD_DSIPLL_M_MIN_83, .max = MDFLD_DSIPLL_M_MAX_83},
+ .p1 = {.min = MDFLD_DSIPLL_P1_MIN_83, .max = MDFLD_DSIPLL_P1_MAX_83},
+ },
+ { /* MDFLD_LIMT_DSIPLL_100 */
+ .dot = {.min = MDFLD_DOT_MIN, .max = MDFLD_DOT_MAX},
+ .m = {.min = MDFLD_DSIPLL_M_MIN_100, .max = MDFLD_DSIPLL_M_MAX_100},
+ .p1 = {.min = MDFLD_DSIPLL_P1_MIN_100, .max = MDFLD_DSIPLL_P1_MAX_100},
+ },
+};
+
+#define MDFLD_M_MIN 21
+#define MDFLD_M_MAX 180
+static const u32 mdfld_m_converts[] = {
+/* M configuration table from 9-bit LFSR table */
+ 224, 368, 440, 220, 366, 439, 219, 365, 182, 347, /* 21 - 30 */
+ 173, 342, 171, 85, 298, 149, 74, 37, 18, 265, /* 31 - 40 */
+ 388, 194, 353, 432, 216, 108, 310, 155, 333, 166, /* 41 - 50 */
+ 83, 41, 276, 138, 325, 162, 337, 168, 340, 170, /* 51 - 60 */
+ 341, 426, 469, 234, 373, 442, 221, 110, 311, 411, /* 61 - 70 */
+ 461, 486, 243, 377, 188, 350, 175, 343, 427, 213, /* 71 - 80 */
+ 106, 53, 282, 397, 354, 227, 113, 56, 284, 142, /* 81 - 90 */
+ 71, 35, 273, 136, 324, 418, 465, 488, 500, 506, /* 91 - 100 */
+ 253, 126, 63, 287, 399, 455, 483, 241, 376, 444, /* 101 - 110 */
+ 478, 495, 503, 251, 381, 446, 479, 239, 375, 443, /* 111 - 120 */
+ 477, 238, 119, 315, 157, 78, 295, 147, 329, 420, /* 121 - 130 */
+ 210, 105, 308, 154, 77, 38, 275, 137, 68, 290, /* 131 - 140 */
+ 145, 328, 164, 82, 297, 404, 458, 485, 498, 249, /* 141 - 150 */
+ 380, 190, 351, 431, 471, 235, 117, 314, 413, 206, /* 151 - 160 */
+ 103, 51, 25, 12, 262, 387, 193, 96, 48, 280, /* 161 - 170 */
+ 396, 198, 99, 305, 152, 76, 294, 403, 457, 228, /* 171 - 180 */
+};
+
+static const struct mdfld_limit_t *mdfld_limit(struct drm_crtc *crtc)
+{
+ const struct mdfld_limit_t *limit = NULL;
+ struct drm_device *dev = crtc->dev;
+ struct drm_psb_private *dev_priv = dev->dev_private;
+
+ if (psb_intel_pipe_has_type(crtc, INTEL_OUTPUT_MIPI)
+ || psb_intel_pipe_has_type(crtc, INTEL_OUTPUT_MIPI2)) {
+ if ((ksel == KSEL_CRYSTAL_19) || (ksel == KSEL_BYPASS_19))
+ limit = &mdfld_limits[MDFLD_LIMT_DSIPLL_19];
+ else if (ksel == KSEL_BYPASS_25)
+ limit = &mdfld_limits[MDFLD_LIMT_DSIPLL_25];
+ else if ((ksel == KSEL_BYPASS_83_100) && (dev_priv->core_freq == 166))
+ limit = &mdfld_limits[MDFLD_LIMT_DSIPLL_83];
+ else if ((ksel == KSEL_BYPASS_83_100) &&
+ (dev_priv->core_freq == 100 || dev_priv->core_freq == 200))
+ limit = &mdfld_limits[MDFLD_LIMT_DSIPLL_100];
+ } else if (psb_intel_pipe_has_type(crtc, INTEL_OUTPUT_HDMI)) {
+ if ((ksel == KSEL_CRYSTAL_19) || (ksel == KSEL_BYPASS_19))
+ limit = &mdfld_limits[MDFLD_LIMT_DPLL_19];
+ else if (ksel == KSEL_BYPASS_25)
+ limit = &mdfld_limits[MDFLD_LIMT_DPLL_25];
+ else if ((ksel == KSEL_BYPASS_83_100) && (dev_priv->core_freq == 166))
+ limit = &mdfld_limits[MDFLD_LIMT_DPLL_83];
+ else if ((ksel == KSEL_BYPASS_83_100) &&
+ (dev_priv->core_freq == 100 || dev_priv->core_freq == 200))
+ limit = &mdfld_limits[MDFLD_LIMT_DPLL_100];
+ } else {
+ limit = NULL;
+ dev_err(dev->dev, "mdfld_limit Wrong display type.\n");
+ }
+
+ return limit;
+}
+
+/** Derive the pixel clock for the given refclk and divisors for 8xx chips. */
+static void mdfld_clock(int refclk, struct mdfld_intel_clock_t *clock)
+{
+ clock->dot = (refclk * clock->m) / clock->p1;
+}
+
+/**
+ * Returns a set of divisors for the desired target clock with the given refclk,
+ * or FALSE. Divisor values are the actual divisors for
+ */
+static bool
+mdfldFindBestPLL(struct drm_crtc *crtc, int target, int refclk,
+ struct mdfld_intel_clock_t *best_clock)
+{
+ struct mdfld_intel_clock_t clock;
+ const struct mdfld_limit_t *limit = mdfld_limit(crtc);
+ int err = target;
+
+ memset(best_clock, 0, sizeof(*best_clock));
+
+ for (clock.m = limit->m.min; clock.m <= limit->m.max; clock.m++) {
+ for (clock.p1 = limit->p1.min; clock.p1 <= limit->p1.max;
+ clock.p1++) {
+ int this_err;
+
+ mdfld_clock(refclk, &clock);
+
+ this_err = abs(clock.dot - target);
+ if (this_err < err) {
+ *best_clock = clock;
+ err = this_err;
+ }
+ }
+ }
+ return err != target;
+}
+
+/**
+ * Return the pipe currently connected to the panel fitter,
+ * or -1 if the panel fitter is not present or not in use
+ */
+static int mdfld_panel_fitter_pipe(struct drm_device *dev)
+{
+ u32 pfit_control;
+
+ pfit_control = REG_READ(PFIT_CONTROL);
+
+ /* See if the panel fitter is in use */
+ if ((pfit_control & PFIT_ENABLE) == 0)
+ return -1;
+ return (pfit_control >> 29) & 3;
+}
+
+static int mdfld_crtc_mode_set(struct drm_crtc *crtc,
+ struct drm_display_mode *mode,
+ struct drm_display_mode *adjusted_mode,
+ int x, int y,
+ struct drm_framebuffer *old_fb)
+{
+ struct drm_device *dev = crtc->dev;
+ struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc);
+ struct drm_psb_private *dev_priv = dev->dev_private;
+ int pipe = psb_intel_crtc->pipe;
+ int fp_reg = MRST_FPA0;
+ int dpll_reg = MRST_DPLL_A;
+ int dspcntr_reg = DSPACNTR;
+ int pipeconf_reg = PIPEACONF;
+ int htot_reg = HTOTAL_A;
+ int hblank_reg = HBLANK_A;
+ int hsync_reg = HSYNC_A;
+ int vtot_reg = VTOTAL_A;
+ int vblank_reg = VBLANK_A;
+ int vsync_reg = VSYNC_A;
+ int dspsize_reg = DSPASIZE;
+ int dsppos_reg = DSPAPOS;
+ int pipesrc_reg = PIPEASRC;
+ u32 *pipeconf = &dev_priv->pipeconf;
+ u32 *dspcntr = &dev_priv->dspcntr;
+ int refclk = 0;
+ int clk_n = 0, clk_p2 = 0, clk_byte = 1, clk = 0, m_conv = 0, clk_tmp = 0;
+ struct mdfld_intel_clock_t clock;
+ bool ok;
+ u32 dpll = 0, fp = 0;
+ bool is_crt = false, is_lvds = false, is_tv = false;
+ bool is_mipi = false, is_mipi2 = false, is_hdmi = false;
+ struct drm_mode_config *mode_config = &dev->mode_config;
+ struct psb_intel_output *psb_intel_output = NULL;
+ uint64_t scalingType = DRM_MODE_SCALE_FULLSCREEN;
+ struct drm_encoder *encoder;
+ struct drm_connector *connector;
+ int timeout = 0;
+
+ dev_dbg(dev->dev, "pipe = 0x%x \n", pipe);
+
+ switch (pipe) {
+ case 0:
+ break;
+ case 1:
+ fp_reg = FPB0;
+ dpll_reg = DPLL_B;
+ dspcntr_reg = DSPBCNTR;
+ pipeconf_reg = PIPEBCONF;
+ htot_reg = HTOTAL_B;
+ hblank_reg = HBLANK_B;
+ hsync_reg = HSYNC_B;
+ vtot_reg = VTOTAL_B;
+ vblank_reg = VBLANK_B;
+ vsync_reg = VSYNC_B;
+ dspsize_reg = DSPBSIZE;
+ dsppos_reg = DSPBPOS;
+ pipesrc_reg = PIPEBSRC;
+ pipeconf = &dev_priv->pipeconf1;
+ dspcntr = &dev_priv->dspcntr1;
+ fp_reg = MDFLD_DPLL_DIV0;
+ dpll_reg = MDFLD_DPLL_B;
+ break;
+ case 2:
+ dpll_reg = MRST_DPLL_A;
+ dspcntr_reg = DSPCCNTR;
+ pipeconf_reg = PIPECCONF;
+ htot_reg = HTOTAL_C;
+ hblank_reg = HBLANK_C;
+ hsync_reg = HSYNC_C;
+ vtot_reg = VTOTAL_C;
+ vblank_reg = VBLANK_C;
+ vsync_reg = VSYNC_C;
+ dspsize_reg = DSPCSIZE;
+ dsppos_reg = DSPCPOS;
+ pipesrc_reg = PIPECSRC;
+ pipeconf = &dev_priv->pipeconf2;
+ dspcntr = &dev_priv->dspcntr2;
+ break;
+ default:
+ DRM_ERROR("Illegal Pipe Number. \n");


+ return 0;
+ }
+

+ dev_dbg(dev->dev, "adjusted_hdisplay = %d\n",
+ adjusted_mode->hdisplay);
+ dev_dbg(dev->dev, "adjusted_vdisplay = %d\n",
+ adjusted_mode->vdisplay);
+ dev_dbg(dev->dev, "adjusted_hsync_start = %d\n",
+ adjusted_mode->hsync_start);
+ dev_dbg(dev->dev, "adjusted_hsync_end = %d\n",
+ adjusted_mode->hsync_end);
+ dev_dbg(dev->dev, "adjusted_htotal = %d\n",
+ adjusted_mode->htotal);
+ dev_dbg(dev->dev, "adjusted_vsync_start = %d\n",
+ adjusted_mode->vsync_start);
+ dev_dbg(dev->dev, "adjusted_vsync_end = %d\n",
+ adjusted_mode->vsync_end);
+ dev_dbg(dev->dev, "adjusted_vtotal = %d\n",
+ adjusted_mode->vtotal);
+ dev_dbg(dev->dev, "adjusted_clock = %d\n",
+ adjusted_mode->clock);
+ dev_dbg(dev->dev, "hdisplay = %d\n",
+ mode->hdisplay);
+ dev_dbg(dev->dev, "vdisplay = %d\n",
+ mode->vdisplay);
+
+ if (!gma_power_begin(dev, true))
+ return 0;
+
+ memcpy(&psb_intel_crtc->saved_mode, mode, sizeof(struct drm_display_mode));
+ memcpy(&psb_intel_crtc->saved_adjusted_mode, adjusted_mode, sizeof(struct drm_display_mode));
+


+ list_for_each_entry(connector, &mode_config->connector_list, head) {

+ if(!connector)
+ continue;
+
+ encoder = connector->encoder;
+
+ if(!encoder)
+ continue;
+
+ if (encoder->crtc != crtc)
+ continue;
+
+ psb_intel_output = to_psb_intel_output(connector);
+
+ dev_dbg(dev->dev, "output->type = 0x%x \n", psb_intel_output->type);
+
+ switch (psb_intel_output->type) {
+ case INTEL_OUTPUT_LVDS:
+ is_lvds = true;
+ break;
+ case INTEL_OUTPUT_TVOUT:
+ is_tv = true;
+ break;
+ case INTEL_OUTPUT_ANALOG:
+ is_crt = true;
+ break;
+ case INTEL_OUTPUT_MIPI:
+ is_mipi = true;
+ break;
+ case INTEL_OUTPUT_MIPI2:
+ is_mipi2 = true;
+ break;
+ case INTEL_OUTPUT_HDMI:
+ is_hdmi = true;
+ break;
+ }
+ }
+
+ /* Disable the VGA plane that we never use */
+ REG_WRITE(VGACNTRL, VGA_DISP_DISABLE);
+
+ /* Disable the panel fitter if it was on our pipe */
+ if (mdfld_panel_fitter_pipe(dev) == pipe)
+ REG_WRITE(PFIT_CONTROL, 0);
+
+ /* pipesrc and dspsize control the size that is scaled from,
+ * which should always be the user's requested size.
+ */


+ if (pipe == 1) {

+ /* FIXME: To make HDMI display with 864x480 (TPO), 480x864 (PYR) or 480x854 (TMD), set the sprite
+ * width/height and souce image size registers with the adjusted mode for pipe B. */
+
+ /* The defined sprite rectangle must always be completely contained within the displayable
+ * area of the screen image (frame buffer). */
+ REG_WRITE(dspsize_reg, ((MIN(mode->crtc_vdisplay, adjusted_mode->crtc_vdisplay) - 1) << 16)
+ | (MIN(mode->crtc_hdisplay, adjusted_mode->crtc_hdisplay) - 1));
+ /* Set the CRTC with encoder mode. */
+ REG_WRITE(pipesrc_reg, ((mode->crtc_hdisplay - 1) << 16)
+ | (mode->crtc_vdisplay - 1));
+ } else {
+ REG_WRITE(dspsize_reg, ((mode->crtc_vdisplay - 1) << 16) | (mode->crtc_hdisplay - 1));
+ REG_WRITE(pipesrc_reg, ((mode->crtc_hdisplay - 1) << 16) | (mode->crtc_vdisplay - 1));
+ }
+
+ REG_WRITE(dsppos_reg, 0);
+
+ if (psb_intel_output)
+ drm_connector_property_get_value(&psb_intel_output->base,
+ dev->mode_config.scaling_mode_property, &scalingType);
+
+ if (scalingType == DRM_MODE_SCALE_NO_SCALE) {
+ /*Moorestown doesn't have register support for centering so we need to
+ mess with the h/vblank and h/vsync start and ends to get centering*/
+ int offsetX = 0, offsetY = 0;
+
+ offsetX = (adjusted_mode->crtc_hdisplay - mode->crtc_hdisplay) / 2;
+ offsetY = (adjusted_mode->crtc_vdisplay - mode->crtc_vdisplay) / 2;
+
+ REG_WRITE(htot_reg, (mode->crtc_hdisplay - 1) |
+ ((adjusted_mode->crtc_htotal - 1) << 16));
+ REG_WRITE(vtot_reg, (mode->crtc_vdisplay - 1) |
+ ((adjusted_mode->crtc_vtotal - 1) << 16));
+ REG_WRITE(hblank_reg, (adjusted_mode->crtc_hblank_start - offsetX - 1) |
+ ((adjusted_mode->crtc_hblank_end - offsetX - 1) << 16));
+ REG_WRITE(hsync_reg, (adjusted_mode->crtc_hsync_start - offsetX - 1) |
+ ((adjusted_mode->crtc_hsync_end - offsetX - 1) << 16));
+ REG_WRITE(vblank_reg, (adjusted_mode->crtc_vblank_start - offsetY - 1) |
+ ((adjusted_mode->crtc_vblank_end - offsetY - 1) << 16));
+ REG_WRITE(vsync_reg, (adjusted_mode->crtc_vsync_start - offsetY - 1) |
+ ((adjusted_mode->crtc_vsync_end - offsetY - 1) << 16));
+ } else {
+ REG_WRITE(htot_reg, (adjusted_mode->crtc_hdisplay - 1) |
+ ((adjusted_mode->crtc_htotal - 1) << 16));
+ REG_WRITE(vtot_reg, (adjusted_mode->crtc_vdisplay - 1) |
+ ((adjusted_mode->crtc_vtotal - 1) << 16));
+ REG_WRITE(hblank_reg, (adjusted_mode->crtc_hblank_start - 1) |
+ ((adjusted_mode->crtc_hblank_end - 1) << 16));
+ REG_WRITE(hsync_reg, (adjusted_mode->crtc_hsync_start - 1) |
+ ((adjusted_mode->crtc_hsync_end - 1) << 16));
+ REG_WRITE(vblank_reg, (adjusted_mode->crtc_vblank_start - 1) |
+ ((adjusted_mode->crtc_vblank_end - 1) << 16));
+ REG_WRITE(vsync_reg, (adjusted_mode->crtc_vsync_start - 1) |
+ ((adjusted_mode->crtc_vsync_end - 1) << 16));
+ }
+
+ /* Flush the plane changes */
+ {


+ struct drm_crtc_helper_funcs *crtc_funcs =

+ crtc->helper_private;


+ crtc_funcs->mode_set_base(crtc, x, y, old_fb);
+ }

+
+ /* setup pipeconf */
+ *pipeconf = PIPEACONF_ENABLE; /* FIXME_JLIU7 REG_READ(pipeconf_reg); */
+
+ /* Set up the display plane register */
+ *dspcntr = REG_READ(dspcntr_reg);
+ *dspcntr |= pipe << DISPPLANE_SEL_PIPE_POS;
+ *dspcntr |= DISPLAY_PLANE_ENABLE;
+/* MDFLD_PO_JLIU7 dspcntr |= DISPPLANE_BOTTOM; */
+/* MDFLD_PO_JLIU7 dspcntr |= DISPPLANE_GAMMA_ENABLE; */
+
+ if (is_mipi2)
+ {
+ goto mrst_crtc_mode_set_exit;
+ }
+/* FIXME JLIU7 Add MDFLD HDMI supports */
+/* FIXME_MDFLD JLIU7 DSIPLL clock *= 8? */
+/* FIXME_MDFLD JLIU7 need to revist for dual MIPI supports */
+ clk = adjusted_mode->clock;
+
+ if (is_hdmi) {
+ if ((ksel == KSEL_CRYSTAL_19) || (ksel == KSEL_BYPASS_19))
+ {
+ refclk = 19200;
+
+ if (is_mipi || is_mipi2)
+ {
+ clk_n = 1, clk_p2 = 8;
+ } else if (is_hdmi) {
+ clk_n = 1, clk_p2 = 10;
+ }
+ } else if (ksel == KSEL_BYPASS_25) {
+ refclk = 25000;
+
+ if (is_mipi || is_mipi2)
+ {
+ clk_n = 1, clk_p2 = 8;
+ } else if (is_hdmi) {
+ clk_n = 1, clk_p2 = 10;
+ }
+ } else if ((ksel == KSEL_BYPASS_83_100) && (dev_priv->core_freq == 166)) {
+ refclk = 83000;
+
+ if (is_mipi || is_mipi2)
+ {
+ clk_n = 4, clk_p2 = 8;
+ } else if (is_hdmi) {
+ clk_n = 4, clk_p2 = 10;
+ }
+ } else if ((ksel == KSEL_BYPASS_83_100) &&
+ (dev_priv->core_freq == 100 || dev_priv->core_freq == 200)) {
+ refclk = 100000;
+ if (is_mipi || is_mipi2)
+ {
+ clk_n = 4, clk_p2 = 8;
+ } else if (is_hdmi) {
+ clk_n = 4, clk_p2 = 10;
+ }
+ }
+
+ if (is_mipi)
+ clk_byte = dev_priv->bpp / 8;
+ else if (is_mipi2)
+ clk_byte = dev_priv->bpp2 / 8;
+
+ clk_tmp = clk * clk_n * clk_p2 * clk_byte;
+
+ dev_dbg(dev->dev, "clk = %d, clk_n = %d, clk_p2 = %d. \n", clk, clk_n, clk_p2);
+ dev_dbg(dev->dev, "adjusted_mode->clock = %d, clk_tmp = %d. \n", adjusted_mode->clock, clk_tmp);
+
+ ok = mdfldFindBestPLL(crtc, clk_tmp, refclk, &clock);
+
+ if (!ok) {
+ dev_err(dev->dev,
+ "mdfldFindBestPLL fail in mdfld_crtc_mode_set. \n");
+ } else {
+ m_conv = mdfld_m_converts[(clock.m - MDFLD_M_MIN)];
+
+ dev_dbg(dev->dev, "dot clock = %d,"
+ "m = %d, p1 = %d, m_conv = %d. \n", clock.dot, clock.m,
+ clock.p1, m_conv);
+ }
+
+ dpll = REG_READ(dpll_reg);
+
+ if (dpll & DPLL_VCO_ENABLE) {
+ dpll &= ~DPLL_VCO_ENABLE;
+ REG_WRITE(dpll_reg, dpll);
+ REG_READ(dpll_reg);
+
+ /* FIXME jliu7 check the DPLL lock bit PIPEACONF[29] */
+ /* FIXME_MDFLD PO - change 500 to 1 after PO */
+ udelay(500);
+
+ /* reset M1, N1 & P1 */
+ REG_WRITE(fp_reg, 0);
+ dpll &= ~MDFLD_P1_MASK;
+ REG_WRITE(dpll_reg, dpll);
+ /* FIXME_MDFLD PO - change 500 to 1 after PO */
+ udelay(500);
+ }
+
+ /* When ungating power of DPLL, needs to wait 0.5us before enable the VCO */
+ if (dpll & MDFLD_PWR_GATE_EN) {
+ dpll &= ~MDFLD_PWR_GATE_EN;
+ REG_WRITE(dpll_reg, dpll);
+ /* FIXME_MDFLD PO - change 500 to 1 after PO */
+ udelay(500);
+ }
+
+ dpll = 0;
+
+#if 0 /* FIXME revisit later */
+ if ((ksel == KSEL_CRYSTAL_19) || (ksel == KSEL_BYPASS_19) || (ksel == KSEL_BYPASS_25)) {
+ dpll &= ~MDFLD_INPUT_REF_SEL;
+ } else if (ksel == KSEL_BYPASS_83_100) {
+ dpll |= MDFLD_INPUT_REF_SEL;
+ }
+#endif /* FIXME revisit later */
+
+ if (is_hdmi)
+ dpll |= MDFLD_VCO_SEL;
+
+ fp = (clk_n / 2) << 16;
+ fp |= m_conv;
+
+ /* compute bitmask from p1 value */
+ dpll |= (1 << (clock.p1 - 2)) << 17;
+
+#if 0 /* 1080p30 & 720p */
+ dpll = 0x00050000;
+ fp = 0x000001be;
+#endif
+#if 0 /* 480p */
+ dpll = 0x02010000;
+ fp = 0x000000d2;
+#endif
+ } else {
+#if 0 /*DBI_TPO_480x864*/
+ dpll = 0x00020000;
+ fp = 0x00000156;
+#endif /* DBI_TPO_480x864 */ /* get from spec. */
+
+ dpll = 0x00800000;
+ fp = 0x000000c1;
+}
+
+ REG_WRITE(fp_reg, fp);
+ REG_WRITE(dpll_reg, dpll);
+ /* FIXME_MDFLD PO - change 500 to 1 after PO */
+ udelay(500);
+
+ dpll |= DPLL_VCO_ENABLE;
+ REG_WRITE(dpll_reg, dpll);
+ REG_READ(dpll_reg);
+
+ /* wait for DSI PLL to lock */
+ while ((timeout < 20000) && !(REG_READ(pipeconf_reg) & PIPECONF_DSIPLL_LOCK)) {
+ udelay(150);
+ timeout ++;
+ }
+
+ if (is_mipi)
+ goto mrst_crtc_mode_set_exit;
+
+ dev_dbg(dev->dev, "is_mipi = 0x%x \n", is_mipi);
+
+ REG_WRITE(pipeconf_reg, *pipeconf);
+ REG_READ(pipeconf_reg);
+
+ /* Wait for for the pipe enable to take effect. */
+//FIXME_JLIU7 HDMI mrstWaitForPipeEnable(dev);
+
+ REG_WRITE(dspcntr_reg, *dspcntr);
+ psb_intel_wait_for_vblank(dev);
+
+mrst_crtc_mode_set_exit:
+
+ gma_power_end(dev);


+
+ return 0;
+}

diff --git a/drivers/staging/gma500/mdfld_msic.h b/drivers/staging/gma500/mdfld_msic.h
new file mode 100644
index 0000000..a7ad6547
--- /dev/null
+++ b/drivers/staging/gma500/mdfld_msic.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright © 2010 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ * Jim Liu <jim...@intel.com>
+ */
+
+#define MSIC_PCI_DEVICE_ID 0x831
+
+int msic_regsiter_driver(void);
+int msic_unregister_driver(void);
+extern void hpd_notify_um(void);
diff --git a/drivers/staging/gma500/mdfld_output.c b/drivers/staging/gma500/mdfld_output.c
new file mode 100644
index 0000000..b1fc765
--- /dev/null
+++ b/drivers/staging/gma500/mdfld_output.c
@@ -0,0 +1,135 @@
+/*
+ * Copyright (c) 2010 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicensen
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ * Thomas Eaton <thomas....@intel.com>
+ * Scott Rowe <scott....@intel.com>
+*/
+
+#include <linux/init.h>
+#include "mdfld_dsi_dbi.h"
+#include "mdfld_dsi_dpi.h"
+#include "mdfld_dsi_output.h"
+#include "mdfld_output.h"
+
+#include "displays/tpo_cmd.h"
+#include "displays/tpo_vid.h"
+#include "displays/tmd_cmd.h"
+#include "displays/tmd_vid.h"
+#include "displays/pyr_cmd.h"
+#include "displays/pyr_vid.h"
+/* #include "displays/hdmi.h" */
+
+/* For now a single type per device is all we cope with */
+int mdfld_get_panel_type(struct drm_device *dev, int pipe)
+{
+ struct drm_psb_private *dev_priv = dev->dev_private;
+ return dev_priv->panel_id;
+}
+
+int mdfld_panel_dpi(struct drm_device *dev)
+{
+ struct drm_psb_private *dev_priv = dev->dev_private;
+
+ switch (dev_priv->panel_id) {
+ case TMD_VID:
+ case TPO_VID:
+ case PYR_VID:
+ return true;
+ case TMD_CMD:
+ case TPO_CMD:
+ case PYR_CMD:
+ default:
+ return false;
+ }
+}
+
+static void init_panel(struct drm_device *dev, int mipi_pipe, int p_type)
+{
+ struct panel_funcs *p_cmd_funcs;
+ struct panel_funcs *p_vid_funcs;
+
+ /* Oh boy ... FIXME */
+ p_cmd_funcs = kzalloc(sizeof(struct panel_funcs), GFP_KERNEL);
+ p_vid_funcs = kzalloc(sizeof(struct panel_funcs), GFP_KERNEL);
+
+ switch (p_type) {
+ case TPO_CMD:
+ tpo_cmd_init(dev, p_cmd_funcs);
+ mdfld_dsi_output_init(dev, mipi_pipe, NULL, p_cmd_funcs, NULL);
+ break;
+ case TPO_VID:
+ tpo_vid_init(dev, p_vid_funcs);
+ mdfld_dsi_output_init(dev, mipi_pipe, NULL, NULL, p_vid_funcs);
+ break;
+ case TMD_CMD:
+ /*tmd_cmd_init(dev, p_cmd_funcs); */
+ mdfld_dsi_output_init(dev, mipi_pipe, NULL, p_cmd_funcs, NULL);
+ break;
+ case TMD_VID:
+ tmd_vid_init(dev, p_vid_funcs);
+ mdfld_dsi_output_init(dev, mipi_pipe, NULL, NULL, p_vid_funcs);
+ break;
+ case PYR_CMD:
+ pyr_cmd_init(dev, p_cmd_funcs);
+ mdfld_dsi_output_init(dev, mipi_pipe, NULL, p_cmd_funcs, NULL);
+ break;
+ case PYR_VID:
+ /*pyr_vid_init(dev, p_vid_funcs); */
+ mdfld_dsi_output_init(dev, mipi_pipe, NULL, NULL, p_vid_funcs);
+ break;
+ case TPO: /* TPO panel supports both cmd & vid interfaces */
+ tpo_cmd_init(dev, p_cmd_funcs);
+ tpo_vid_init(dev, p_vid_funcs);
+ mdfld_dsi_output_init(dev, mipi_pipe, NULL, p_cmd_funcs,
+ p_vid_funcs);
+ break;
+ case TMD:
+ break;
+ case PYR:
+ break;
+#if 0
+ case HDMI:
+ dev_dbg(dev->dev, "Initializing HDMI");
+ mdfld_hdmi_init(dev, &dev_priv->mode_dev);
+ break;
+#endif
+ default:
+ dev_err(dev->dev, "Unsupported interface %d", p_type);
+ break;
+ }
+}
+
+void mdfld_output_init(struct drm_device *dev)
+{
+ int type;
+
+ /* MIPI panel 1 */
+ type = mdfld_get_panel_type(dev, 0);
+ dev_info(dev->dev, "panel 1: type is %d\n", type);
+ init_panel(dev, 0, type);
+
+ /* MIPI panel 2 */
+ type = mdfld_get_panel_type(dev, 2);
+ dev_info(dev->dev, "panel 2: type is %d\n", type);
+ init_panel(dev, 2, type);
+}
diff --git a/drivers/staging/gma500/mdfld_output.h b/drivers/staging/gma500/mdfld_output.h
new file mode 100644
index 0000000..36f43e1
--- /dev/null
+++ b/drivers/staging/gma500/mdfld_output.h
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2010 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicensen
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ * Thomas Eaton <thomas....@intel.com>
+ * Scott Rowe <scott....@intel.com>
+*/
+
+#ifndef MDFLD_OUTPUT_H
+#define MDFLD_OUTPUT_H
+
+#include "psb_drv.h"
+
+/* Panel types */
+enum {
+ TPO_CMD,
+ TPO_VID,
+ TMD_CMD,
+ TMD_VID,
+ PYR_CMD,
+ PYR_VID,
+ TPO,
+ TMD,
+ PYR,
+ HDMI,
+ GCT_DETECT
+};
+
+/* Junk that belongs elsewhere */
+#define TPO_PANEL_WIDTH 84
+#define TPO_PANEL_HEIGHT 46
+#define TMD_PANEL_WIDTH 39
+#define TMD_PANEL_HEIGHT 71
+#define PYR_PANEL_WIDTH 53
+#define PYR_PANEL_HEIGHT 95
+
+/* Panel interface */
+struct panel_info {
+ u32 width_mm;
+ u32 height_mm;
+};
+
+struct mdfld_dsi_dbi_output;
+
+struct panel_funcs {
+ const struct drm_encoder_funcs *encoder_funcs;
+ const struct drm_encoder_helper_funcs *encoder_helper_funcs;
+ struct drm_display_mode *(*get_config_mode) (struct drm_device *);
+ void (*update_fb) (struct mdfld_dsi_dbi_output *, int);
+ int (*get_panel_info) (struct drm_device *, int, struct panel_info *);
+};
+
+void mdfld_output_init(struct drm_device *dev);
+int mdfld_panel_dpi(struct drm_device *dev);
+int mdfld_get_panel_type(struct drm_device *dev, int pipe);
+void mdfld_disable_crtc (struct drm_device *dev, int pipe);
+
+#endif
diff --git a/drivers/staging/gma500/mdfld_pyr_cmd.c b/drivers/staging/gma500/mdfld_pyr_cmd.c
new file mode 100644
index 0000000..0d89384
--- /dev/null
+++ b/drivers/staging/gma500/mdfld_pyr_cmd.c
@@ -0,0 +1,575 @@
+/*
+ * Copyright (c) 2010 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicensen
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ * Thomas Eaton <thomas....@intel.com>
+ * Scott Rowe <scott....@intel.com>
+*/
+
+#include "mdfld_dsi_dbi.h"
+#include "mdfld_dsi_dpi.h"
+#include "mdfld_dsi_output.h"
+#include "mdfld_output.h"
+
+#include "mdfld_dsi_pkg_sender.h"
+
+#include "displays/pyr_cmd.h"
+
+static struct drm_display_mode *pyr_cmd_get_config_mode(struct drm_device *dev)
+{
+ struct drm_display_mode *mode;
+
+ mode = kzalloc(sizeof(*mode), GFP_KERNEL);
+ if (!mode) {
+ dev_err(dev->dev, "Out of memory\n");
+ return NULL;
+ }
+
+ dev_dbg(dev->dev, "hdisplay is %d\n", mode->hdisplay);
+ dev_dbg(dev->dev, "vdisplay is %d\n", mode->vdisplay);
+ dev_dbg(dev->dev, "HSS is %d\n", mode->hsync_start);
+ dev_dbg(dev->dev, "HSE is %d\n", mode->hsync_end);
+ dev_dbg(dev->dev, "htotal is %d\n", mode->htotal);
+ dev_dbg(dev->dev, "VSS is %d\n", mode->vsync_start);
+ dev_dbg(dev->dev, "VSE is %d\n", mode->vsync_end);
+ dev_dbg(dev->dev, "vtotal is %d\n", mode->vtotal);
+ dev_dbg(dev->dev, "clock is %d\n", mode->clock);
+
+ mode->hdisplay = 480;
+ mode->vdisplay = 864;
+ mode->hsync_start = 487;
+ mode->hsync_end = 490;
+ mode->htotal = 499;
+ mode->vsync_start = 874;
+ mode->vsync_end = 878;
+ mode->vtotal = 886;
+ mode->clock = 25777;
+
+ drm_mode_set_name(mode);
+ drm_mode_set_crtcinfo(mode, 0);
+
+ mode->type |= DRM_MODE_TYPE_PREFERRED;
+
+ return mode;
+}
+
+static bool pyr_dsi_dbi_mode_fixup(struct drm_encoder *encoder,
+ struct drm_display_mode *mode,
+ struct drm_display_mode *adjusted_mode)
+{
+ struct drm_device *dev = encoder->dev;
+ struct drm_display_mode *fixed_mode = pyr_cmd_get_config_mode(dev);
+
+ if (fixed_mode) {
+ adjusted_mode->hdisplay = fixed_mode->hdisplay;
+ adjusted_mode->hsync_start = fixed_mode->hsync_start;
+ adjusted_mode->hsync_end = fixed_mode->hsync_end;
+ adjusted_mode->htotal = fixed_mode->htotal;
+ adjusted_mode->vdisplay = fixed_mode->vdisplay;
+ adjusted_mode->vsync_start = fixed_mode->vsync_start;
+ adjusted_mode->vsync_end = fixed_mode->vsync_end;
+ adjusted_mode->vtotal = fixed_mode->vtotal;
+ adjusted_mode->clock = fixed_mode->clock;
+ drm_mode_set_crtcinfo(adjusted_mode, CRTC_INTERLACE_HALVE_V);
+ kfree(fixed_mode);
+ }
+ return true;
+}
+
+static void pyr_dsi_dbi_set_power(struct drm_encoder *encoder, bool on)
+{


+ int ret = 0;

+ struct mdfld_dsi_encoder *dsi_encoder = MDFLD_DSI_ENCODER(encoder);
+ struct mdfld_dsi_dbi_output *dbi_output =
+ MDFLD_DSI_DBI_OUTPUT(dsi_encoder);
+ struct drm_device *dev = encoder->dev;
+ struct drm_psb_private *dev_priv = dev->dev_private;
+ u32 reg_offset = 0;
+ int pipe = (dbi_output->channel_num == 0) ? 0 : 2;
+
+ dev_dbg(dev->dev, "pipe %d : %s, panel on: %s\n", pipe,
+ on ? "On" : "Off",
+ dbi_output->dbi_panel_on ? "True" : "False");
+
+ if (pipe == 2) {
+ if (on)
+ dev_priv->dual_mipi = true;
+ else
+ dev_priv->dual_mipi = false;
+
+ reg_offset = MIPIC_REG_OFFSET;
+ } else {
+ if (!on)
+ dev_priv->dual_mipi = false;
+ }
+
+ if (!gma_power_begin(dev, true)) {
+ dev_err(dev->dev, "hw begin failed\n");
+ return;
+ }
+
+
+ if (on) {
+ if (dbi_output->dbi_panel_on)
+ goto out_err;
+
+ ret = mdfld_dsi_dbi_update_power(dbi_output, DRM_MODE_DPMS_ON);
+ if (ret) {
+ dev_err(dev->dev, "power on error\n");
+ goto out_err;
+ }
+
+ dbi_output->dbi_panel_on = true;
+
+ if (pipe == 2) {
+ dev_priv->dbi_panel_on2 = true;
+ } else {
+ dev_priv->dbi_panel_on = true;
+ mdfld_enable_te(dev, 0);
+ }
+ } else {
+ if (!dbi_output->dbi_panel_on && !dbi_output->first_boot)
+ goto out_err;
+
+ dbi_output->dbi_panel_on = false;
+ dbi_output->first_boot = false;
+
+ if (pipe == 2) {
+ dev_priv->dbi_panel_on2 = false;
+ mdfld_disable_te(dev, 2);
+ } else {
+ dev_priv->dbi_panel_on = false;
+ mdfld_disable_te(dev, 0);
+
+ if (dev_priv->dbi_panel_on2)
+ mdfld_enable_te(dev, 2);
+ }
+
+ ret = mdfld_dsi_dbi_update_power(dbi_output, DRM_MODE_DPMS_OFF);
+ if (ret) {
+ dev_err(dev->dev, "power on error\n");
+ goto out_err;
+ }
+ }
+
+out_err:
+ gma_power_end(dev);
+
+ if (ret)
+ dev_err(dev->dev, "failed\n");
+}
+
+static void pyr_dsi_controller_dbi_init(struct mdfld_dsi_config *dsi_config,
+ int pipe)
+{
+ struct drm_device *dev = dsi_config->dev;
+ u32 reg_offset = pipe ? MIPIC_REG_OFFSET : 0;
+ int lane_count = dsi_config->lane_count;
+ u32 val = 0;
+
+ dev_dbg(dev->dev, "Init DBI interface on pipe %d...\n", pipe);
+
+ /* In-ready device */
+ REG_WRITE((MIPIA_DEVICE_READY_REG + reg_offset), 0x00000000);
+
+ /* Init dsi adapter before kicking off */
+ REG_WRITE((MIPIA_CONTROL_REG + reg_offset), 0x00000018);
+
+ /* TODO: figure out how to setup these registers */
+ REG_WRITE((MIPIA_DPHY_PARAM_REG + reg_offset), 0x150c600F);
+ REG_WRITE((MIPIA_CLK_LANE_SWITCH_TIME_CNT_REG + reg_offset),
+ 0x000a0014);
+ REG_WRITE((MIPIA_DBI_BW_CTRL_REG + reg_offset), 0x00000400);
+ REG_WRITE((MIPIA_HS_LS_DBI_ENABLE_REG + reg_offset), 0x00000000);
+
+ /* Enable all interrupts */
+ REG_WRITE((MIPIA_INTR_EN_REG + reg_offset), 0xffffffff);
+ /* Max value: 20 clock cycles of txclkesc */
+ REG_WRITE((MIPIA_TURN_AROUND_TIMEOUT_REG + reg_offset), 0x0000001f);
+ /* Min 21 txclkesc, max: ffffh */
+ REG_WRITE((MIPIA_DEVICE_RESET_TIMER_REG + reg_offset), 0x0000ffff);
+ /* Min: 7d0 max: 4e20 */
+ REG_WRITE((MIPIA_INIT_COUNT_REG + reg_offset), 0x00000fa0);
+
+ /* Set up func_prg */
+ val |= lane_count;
+ val |= (dsi_config->channel_num << DSI_DBI_VIRT_CHANNEL_OFFSET);
+ val |= DSI_DBI_COLOR_FORMAT_OPTION2;
+ REG_WRITE((MIPIA_DSI_FUNC_PRG_REG + reg_offset), val);
+
+ REG_WRITE((MIPIA_HS_TX_TIMEOUT_REG + reg_offset), 0x3fffff);
+ REG_WRITE((MIPIA_LP_RX_TIMEOUT_REG + reg_offset), 0xffff);
+
+ /* De-assert dbi_stall when half of DBI FIFO is empty */
+ /* REG_WRITE((MIPIA_DBI_FIFO_THROTTLE_REG + reg_offset), 0x00000000); */
+
+ REG_WRITE((MIPIA_HIGH_LOW_SWITCH_COUNT_REG + reg_offset), 0x46);
+ REG_WRITE((MIPIA_EOT_DISABLE_REG + reg_offset), 0x00000002);
+ REG_WRITE((MIPIA_LP_BYTECLK_REG + reg_offset), 0x00000004);
+ REG_WRITE((MIPIA_DEVICE_READY_REG + reg_offset), 0x00000001);
+}
+
+static void pyr_dsi_dbi_mode_set(struct drm_encoder *encoder,
+ struct drm_display_mode *mode,
+ struct drm_display_mode *adjusted_mode)
+{


+ int ret = 0;

+ struct drm_device *dev = encoder->dev;
+ struct drm_psb_private *dev_priv = dev->dev_private;
+ struct mdfld_dsi_encoder *dsi_encoder = MDFLD_DSI_ENCODER(encoder);
+ struct mdfld_dsi_dbi_output *dsi_output =
+ MDFLD_DSI_DBI_OUTPUT(dsi_encoder);
+ struct mdfld_dsi_config *dsi_config =
+ mdfld_dsi_encoder_get_config(dsi_encoder);
+ struct mdfld_dsi_connector *dsi_connector = dsi_config->connector;
+ int pipe = dsi_connector->pipe;
+ u8 param = 0;
+
+ /* Regs */
+ u32 mipi_reg = MIPI;
+ u32 dspcntr_reg = DSPACNTR;
+ u32 pipeconf_reg = PIPEACONF;
+ u32 reg_offset = 0;
+
+ /* Values */
+ u32 dspcntr_val = dev_priv->dspcntr;
+ u32 pipeconf_val = dev_priv->pipeconf;
+ u32 h_active_area = mode->hdisplay;
+ u32 v_active_area = mode->vdisplay;
+ u32 mipi_val = (PASS_FROM_SPHY_TO_AFE | SEL_FLOPPED_HSTX |
+ TE_TRIGGER_GPIO_PIN);
+
+ dev_dbg(dev->dev, "mipi_val =0x%x\n", mipi_val);
+
+ dev_dbg(dev->dev, "type %s\n", (pipe == 2) ? "MIPI2" : "MIPI");
+ dev_dbg(dev->dev, "h %d v %d\n", mode->hdisplay, mode->vdisplay);
+
+ if (pipe == 2) {
+ mipi_reg = MIPI_C;
+ dspcntr_reg = DSPCCNTR;
+ pipeconf_reg = PIPECCONF;
+
+ reg_offset = MIPIC_REG_OFFSET;
+
+ dspcntr_val = dev_priv->dspcntr2;
+ pipeconf_val = dev_priv->pipeconf2;
+ } else {
+ mipi_val |= 0x2; /* Two lanes for port A and C respectively */
+ }
+
+ if (!gma_power_begin(dev, true)) {
+ dev_err(dev->dev, "hw begin failed\n");
+ return;
+ }
+
+ /* Set up pipe related registers */
+ REG_WRITE(mipi_reg, mipi_val);
+ REG_READ(mipi_reg);
+
+ pyr_dsi_controller_dbi_init(dsi_config, pipe);
+
+ msleep(20);
+
+ REG_WRITE(dspcntr_reg, dspcntr_val);
+ REG_READ(dspcntr_reg);
+
+ /* 20ms delay before sending exit_sleep_mode */
+ msleep(20);
+
+ /* Send exit_sleep_mode DCS */
+ ret = mdfld_dsi_dbi_send_dcs(dsi_output, exit_sleep_mode, NULL,
+ 0, CMD_DATA_SRC_SYSTEM_MEM);
+ if (ret) {
+ dev_err(dev->dev, "sent exit_sleep_mode faild\n");
+ goto out_err;
+ }
+
+ /*send set_tear_on DCS*/
+ ret = mdfld_dsi_dbi_send_dcs(dsi_output, set_tear_on,
+ &param, 1, CMD_DATA_SRC_SYSTEM_MEM);
+ if (ret) {
+ dev_err(dev->dev, "%s - sent set_tear_on faild\n", __func__);
+ goto out_err;
+ }
+
+ /* Do some init stuff */
+ mdfld_dsi_brightness_init(dsi_config, pipe);
+ mdfld_dsi_gen_fifo_ready(dev, (MIPIA_GEN_FIFO_STAT_REG + reg_offset),
+ HS_CTRL_FIFO_EMPTY | HS_DATA_FIFO_EMPTY);
+
+ REG_WRITE(pipeconf_reg, pipeconf_val | PIPEACONF_DSR);
+ REG_READ(pipeconf_reg);
+
+ /* TODO: this looks ugly, try to move it to CRTC mode setting */
+ if (pipe == 2)
+ dev_priv->pipeconf2 |= PIPEACONF_DSR;
+ else
+ dev_priv->pipeconf |= PIPEACONF_DSR;
+
+ dev_dbg(dev->dev, "pipeconf %x\n", REG_READ(pipeconf_reg));
+
+ ret = mdfld_dsi_dbi_update_area(dsi_output, 0, 0,
+ h_active_area - 1, v_active_area - 1);
+ if (ret) {
+ dev_err(dev->dev, "update area failed\n");
+ goto out_err;
+ }
+
+out_err:
+ gma_power_end(dev);
+
+ if (ret)
+ dev_err(dev->dev, "mode set failed\n");
+ else
+ dev_dbg(dev->dev, "mode set done successfully\n");
+}
+
+static void pyr_dsi_dbi_prepare(struct drm_encoder *encoder)
+{
+ struct mdfld_dsi_encoder *dsi_encoder = MDFLD_DSI_ENCODER(encoder);
+ struct mdfld_dsi_dbi_output *dbi_output =
+ MDFLD_DSI_DBI_OUTPUT(dsi_encoder);
+
+ dbi_output->mode_flags |= MODE_SETTING_IN_ENCODER;
+ dbi_output->mode_flags &= ~MODE_SETTING_ENCODER_DONE;
+
+ pyr_dsi_dbi_set_power(encoder, false);
+}
+
+static void pyr_dsi_dbi_commit(struct drm_encoder *encoder)
+{
+ struct mdfld_dsi_encoder *dsi_encoder = MDFLD_DSI_ENCODER(encoder);
+ struct mdfld_dsi_dbi_output *dbi_output =
+ MDFLD_DSI_DBI_OUTPUT(dsi_encoder);
+ struct drm_device *dev = dbi_output->dev;
+ struct drm_psb_private *dev_priv = dev->dev_private;
+ struct psb_drm_dpu_rect rect;
+
+ pyr_dsi_dbi_set_power(encoder, true);
+
+ dbi_output->mode_flags &= ~MODE_SETTING_IN_ENCODER;
+
+ rect.x = rect.y = 0;
+ rect.width = 864;
+ rect.height = 480;
+
+ if (dbi_output->channel_num == 1) {
+ dev_priv->dsr_fb_update |= MDFLD_DSR_2D_3D_2;
+#ifdef CONFIG_MDFLD_DSI_DPU
+ /* If DPU enabled report a fullscreen damage */
+ mdfld_dbi_dpu_report_damage(dev, MDFLD_PLANEC, &rect);
+#endif
+ } else {
+ dev_priv->dsr_fb_update |= MDFLD_DSR_2D_3D_0;
+
+#ifdef CONFIG_MDFLD_DSI_DPU
+ mdfld_dbi_dpu_report_damage(dev, MDFLD_PLANEA, &rect);
+#endif
+ }
+ dbi_output->mode_flags |= MODE_SETTING_ENCODER_DONE;
+}
+
+static void pyr_dsi_dbi_dpms(struct drm_encoder *encoder, int mode)
+{
+ struct mdfld_dsi_encoder *dsi_encoder = MDFLD_DSI_ENCODER(encoder);
+ struct mdfld_dsi_dbi_output *dbi_output =
+ MDFLD_DSI_DBI_OUTPUT(dsi_encoder);
+ struct drm_device *dev = dbi_output->dev;
+ struct drm_psb_private *dev_priv = dev->dev_private;
+ static bool bdispoff;
+
+ dev_dbg(dev->dev, "%s\n", (mode == DRM_MODE_DPMS_ON ? "on" : "off"));
+
+ if (mode == DRM_MODE_DPMS_ON) {
+ if (/*gbgfxsuspended && */bdispoff) {
+ bdispoff = false;
+ dev_priv->dispstatus = true;
+ /*gbgfxsuspended = false;
+ */
+ mdfld_dsi_dbi_exit_dsr(dev, MDFLD_DSR_2D_3D, 0, 0);
+ }
+ pyr_dsi_dbi_set_power(encoder, true);
+ } else {
+ bdispoff = true;
+ dev_priv->dispstatus = false;
+ pyr_dsi_dbi_set_power(encoder, false);
+ }
+}
+
+/*
+ * Update the DBI MIPI Panel Frame Buffer.
+ */
+static void pyr_dsi_dbi_update_fb(struct mdfld_dsi_dbi_output *dbi_output,
+ int pipe)
+{
+ struct mdfld_dsi_pkg_sender *sender =
+ mdfld_dsi_encoder_get_pkg_sender(&dbi_output->base);
+ struct drm_device *dev = dbi_output->dev;
+ struct drm_crtc *crtc = dbi_output->base.base.crtc;
+ struct psb_intel_crtc *psb_crtc = (crtc) ?
+ to_psb_intel_crtc(crtc) : NULL;
+
+ u32 dpll_reg = MRST_DPLL_A;
+ u32 dspcntr_reg = DSPACNTR;
+ u32 pipeconf_reg = PIPEACONF;
+ u32 dsplinoff_reg = DSPALINOFF;
+ u32 dspsurf_reg = DSPASURF;
+ u32 hs_gen_ctrl_reg = HS_GEN_CTRL_REG;
+ u32 gen_fifo_stat_reg = GEN_FIFO_STAT_REG;
+ u32 reg_offset = 0;
+
+ u32 intr_status;
+ u32 fifo_stat_reg_val;
+ u32 dpll_reg_val;
+ u32 dspcntr_reg_val;
+ u32 pipeconf_reg_val;
+
+ /* If mode setting on-going, back off */
+ if ((dbi_output->mode_flags & MODE_SETTING_ON_GOING) ||
+ (psb_crtc && psb_crtc->mode_flags & MODE_SETTING_ON_GOING) ||
+ !(dbi_output->mode_flags & MODE_SETTING_ENCODER_DONE))
+ return;
+
+ /*
+ * Look for errors here. In particular we're checking for whatever
+ * error status might have appeared during the last frame transmit
+ * (memory write).
+ *
+ * Normally, the bits we're testing here would be set infrequently,
+ * if at all. However, one panel (at least) returns at least one
+ * error bit on most frames. So we've disabled the kernel message
+ * for now.
+ *
+ * Still clear whatever error bits are set, except don't clear the
+ * ones that would make the Penwell DSI controller reset if we
+ * cleared them.
+ */
+ intr_status = REG_READ(INTR_STAT_REG);
+ if ((intr_status & 0x26FFFFFF) != 0) {
+ /* dev_err(dev->dev, "DSI status: 0x%08X\n", intr_status); */
+ intr_status &= 0x26F3FFFF;
+ REG_WRITE(INTR_STAT_REG, intr_status);
+ }
+
+ if (pipe == 2) {
+ dspcntr_reg = DSPCCNTR;
+ pipeconf_reg = PIPECCONF;
+ dsplinoff_reg = DSPCLINOFF;
+ dspsurf_reg = DSPCSURF;
+
+ hs_gen_ctrl_reg = HS_GEN_CTRL_REG + MIPIC_REG_OFFSET;
+ gen_fifo_stat_reg = GEN_FIFO_STAT_REG + MIPIC_REG_OFFSET,
+
+ reg_offset = MIPIC_REG_OFFSET;
+ }
+
+ if (!gma_power_begin(dev, true)) {
+ dev_err(dev->dev, "hw begin failed\n");
+ return;
+ }
+
+ fifo_stat_reg_val = REG_READ(MIPIA_GEN_FIFO_STAT_REG + reg_offset);
+ dpll_reg_val = REG_READ(dpll_reg);
+ dspcntr_reg_val = REG_READ(dspcntr_reg);
+ pipeconf_reg_val = REG_READ(pipeconf_reg);
+
+ if (!(fifo_stat_reg_val & (1 << 27)) ||
+ (dpll_reg_val & DPLL_VCO_ENABLE) ||
+ !(dspcntr_reg_val & DISPLAY_PLANE_ENABLE) ||
+ !(pipeconf_reg_val & DISPLAY_PLANE_ENABLE)) {
+ goto update_fb_out0;
+ }
+
+ /* Refresh plane changes */
+ REG_WRITE(dsplinoff_reg, REG_READ(dsplinoff_reg));
+ REG_WRITE(dspsurf_reg, REG_READ(dspsurf_reg));
+ REG_READ(dspsurf_reg);
+
+ mdfld_dsi_send_dcs(sender,
+ write_mem_start,
+ NULL,
+ 0,
+ CMD_DATA_SRC_PIPE,
+ MDFLD_DSI_SEND_PACKAGE);
+
+ /*
+ * The idea here is to transmit a Generic Read command after the
+ * Write Memory Start/Continue commands finish. This asks for
+ * the panel to return an "ACK No Errors," or (if it has errors
+ * to report) an Error Report. This allows us to monitor the
+ * panel's perception of the health of the DSI.
+ */
+ mdfld_dsi_gen_fifo_ready(dev, gen_fifo_stat_reg,
+ HS_CTRL_FIFO_EMPTY | HS_DATA_FIFO_EMPTY);
+ REG_WRITE(hs_gen_ctrl_reg, (1 << WORD_COUNTS_POS) | GEN_READ_0);
+
+ dbi_output->dsr_fb_update_done = true;
+update_fb_out0:
+ gma_power_end(dev);
+}
+
+/*
+ * TODO: will be removed later, should work out display interfaces for power
+ */
+void pyr_dsi_adapter_init(struct mdfld_dsi_config *dsi_config, int pipe)
+{
+ if (!dsi_config || (pipe != 0 && pipe != 2)) {
+ WARN_ON(1);
+ return;
+ }
+ pyr_dsi_controller_dbi_init(dsi_config, pipe);
+}
+
+static int pyr_cmd_get_panel_info(struct drm_device *dev, int pipe,
+ struct panel_info *pi)
+{
+ if (!dev || !pi)
+ return -EINVAL;
+
+ pi->width_mm = PYR_PANEL_WIDTH;
+ pi->height_mm = PYR_PANEL_HEIGHT;


+
+ return 0;
+}
+

+/* PYR DBI encoder helper funcs */
+static const struct drm_encoder_helper_funcs pyr_dsi_dbi_helper_funcs = {
+ .dpms = pyr_dsi_dbi_dpms,
+ .mode_fixup = pyr_dsi_dbi_mode_fixup,
+ .prepare = pyr_dsi_dbi_prepare,
+ .mode_set = pyr_dsi_dbi_mode_set,
+ .commit = pyr_dsi_dbi_commit,
+};
+
+/* PYR DBI encoder funcs */
+static const struct drm_encoder_funcs mdfld_dsi_dbi_encoder_funcs = {
+ .destroy = drm_encoder_cleanup,
+};
+
+void pyr_cmd_init(struct drm_device *dev, struct panel_funcs *p_funcs)
+{
+ p_funcs->encoder_funcs = &mdfld_dsi_dbi_encoder_funcs;
+ p_funcs->encoder_helper_funcs = &pyr_dsi_dbi_helper_funcs;
+ p_funcs->get_config_mode = &pyr_cmd_get_config_mode;
+ p_funcs->update_fb = pyr_dsi_dbi_update_fb;
+ p_funcs->get_panel_info = pyr_cmd_get_panel_info;
+}
diff --git a/drivers/staging/gma500/mdfld_tmd_vid.c b/drivers/staging/gma500/mdfld_tmd_vid.c
new file mode 100644
index 0000000..b29c905
--- /dev/null
+++ b/drivers/staging/gma500/mdfld_tmd_vid.c
@@ -0,0 +1,144 @@
+/*
+ * Copyright © 2010 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ * Jim Liu <jim...@intel.com>
+ * Jackie Li<yaodo...@intel.com>
+ * Gideon Eaton <eaton.
+ * Scott Rowe <scott....@intel.com>
+ */
+
+#include "mdfld_dsi_dbi.h"
+#include "mdfld_dsi_dpi.h"
+#include "mdfld_dsi_output.h"
+#include "mdfld_output.h"
+
+#include "mdfld_dsi_pkg_sender.h"
+
+#include "displays/tmd_vid.h"
+
+/* FIXME: static ? */
+struct drm_display_mode *tmd_vid_get_config_mode(struct drm_device *dev)
+{
+ struct drm_display_mode *mode;
+ struct drm_psb_private *dev_priv = dev->dev_private;
+ struct mrst_timing_info *ti = &dev_priv->gct_data.DTD;
+ bool use_gct = false; /*Disable GCT for now*/
+
+ mode = kzalloc(sizeof(*mode), GFP_KERNEL);
+ if (!mode) {
+ dev_err(dev->dev, "Out of memory\n");
+ return NULL;
+ }
+
+ if (use_gct) {
+ dev_dbg(dev->dev, "gct find MIPI panel.\n");
+
+ mode->hdisplay = (ti->hactive_hi << 8) | ti->hactive_lo;
+ mode->vdisplay = (ti->vactive_hi << 8) | ti->vactive_lo;
+ mode->hsync_start = mode->hdisplay +
+ ((ti->hsync_offset_hi << 8) |
+ ti->hsync_offset_lo);
+ mode->hsync_end = mode->hsync_start +
+ ((ti->hsync_pulse_width_hi << 8) |
+ ti->hsync_pulse_width_lo);
+ mode->htotal = mode->hdisplay + ((ti->hblank_hi << 8) |
+ ti->hblank_lo);
+ mode->vsync_start = \
+ mode->vdisplay + ((ti->vsync_offset_hi << 8) |
+ ti->vsync_offset_lo);
+ mode->vsync_end = \
+ mode->vsync_start + ((ti->vsync_pulse_width_hi << 8) | \
+ ti->vsync_pulse_width_lo);
+ mode->vtotal = mode->vdisplay +
+ ((ti->vblank_hi << 8) | ti->vblank_lo);
+ mode->clock = ti->pixel_clock * 10;
+
+ dev_dbg(dev->dev, "hdisplay is %d\n", mode->hdisplay);
+ dev_dbg(dev->dev, "vdisplay is %d\n", mode->vdisplay);
+ dev_dbg(dev->dev, "HSS is %d\n", mode->hsync_start);
+ dev_dbg(dev->dev, "HSE is %d\n", mode->hsync_end);
+ dev_dbg(dev->dev, "htotal is %d\n", mode->htotal);
+ dev_dbg(dev->dev, "VSS is %d\n", mode->vsync_start);
+ dev_dbg(dev->dev, "VSE is %d\n", mode->vsync_end);
+ dev_dbg(dev->dev, "vtotal is %d\n", mode->vtotal);
+ dev_dbg(dev->dev, "clock is %d\n", mode->clock);
+ } else {
+ mode->hdisplay = 480;
+ mode->vdisplay = 854;
+ mode->hsync_start = 487;
+ mode->hsync_end = 490;
+ mode->htotal = 499;
+ mode->vsync_start = 861;
+ mode->vsync_end = 865;
+ mode->vtotal = 873;
+ mode->clock = 33264;
+ }
+ drm_mode_set_name(mode);
+ drm_mode_set_crtcinfo(mode, 0);
+
+ mode->type |= DRM_MODE_TYPE_PREFERRED;
+
+ return mode;
+}
+
+static int tmd_vid_get_panel_info(struct drm_device *dev,
+ int pipe,
+ struct panel_info *pi)
+{
+ if (!dev || !pi)
+ return -EINVAL;
+
+ pi->width_mm = TMD_PANEL_WIDTH;
+ pi->height_mm = TMD_PANEL_HEIGHT;


+
+ return 0;
+}
+

+/* TMD DPI encoder helper funcs */
+static const struct drm_encoder_helper_funcs
+ mdfld_tpo_dpi_encoder_helper_funcs = {
+ .dpms = mdfld_dsi_dpi_dpms,
+ .mode_fixup = mdfld_dsi_dpi_mode_fixup,
+ .prepare = mdfld_dsi_dpi_prepare,
+ .mode_set = mdfld_dsi_dpi_mode_set,
+ .commit = mdfld_dsi_dpi_commit,
+};
+
+/* TMD DPI encoder funcs */
+static const struct drm_encoder_funcs mdfld_tpo_dpi_encoder_funcs = {
+ .destroy = drm_encoder_cleanup,
+};
+
+void tmd_vid_init(struct drm_device *dev, struct panel_funcs *p_funcs)
+{
+ if (!dev || !p_funcs) {
+ dev_err(dev->dev, "Invalid parameters\n");
+ return;
+ }
+
+ p_funcs->encoder_funcs = &mdfld_tpo_dpi_encoder_funcs;
+ p_funcs->encoder_helper_funcs = &mdfld_tpo_dpi_encoder_helper_funcs;
+ p_funcs->get_config_mode = &tmd_vid_get_config_mode;
+ p_funcs->update_fb = NULL;
+ p_funcs->get_panel_info = tmd_vid_get_panel_info;
+}
diff --git a/drivers/staging/gma500/mdfld_tpo_cmd.c b/drivers/staging/gma500/mdfld_tpo_cmd.c
new file mode 100644
index 0000000..d2e1818
--- /dev/null
+++ b/drivers/staging/gma500/mdfld_tpo_cmd.c
@@ -0,0 +1,495 @@
+/*
+ * Copyright (c) 2010 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicensen
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ * Thomas Eaton <thomas....@intel.com>
+ * Scott Rowe <scott....@intel.com>
+ */
+
+#include "mdfld_dsi_dbi.h"
+#include "mdfld_dsi_dpi.h"
+#include "mdfld_dsi_output.h"
+#include "mdfld_output.h"
+
+#include "mdfld_dsi_pkg_sender.h"
+
+#include "displays/tpo_cmd.h"
+
+static struct drm_display_mode *tpo_cmd_get_config_mode(struct drm_device *dev)
+{
+ struct drm_display_mode *mode;
+ struct drm_psb_private *dev_priv = dev->dev_private;
+ struct mrst_timing_info *ti = &dev_priv->gct_data.DTD;
+ bool use_gct = false;
+
+ mode = kzalloc(sizeof(*mode), GFP_KERNEL);
+ if (!mode)
+ return NULL;
+
+ if (use_gct) {
+ dev_dbg(dev->dev, "gct find MIPI panel.\n");
+
+ mode->hdisplay = (ti->hactive_hi << 8) | ti->hactive_lo;
+ mode->vdisplay = (ti->vactive_hi << 8) | ti->vactive_lo;
+ mode->hsync_start = mode->hdisplay + \
+ ((ti->hsync_offset_hi << 8) | \
+ ti->hsync_offset_lo);
+ mode->hsync_end = mode->hsync_start + \
+ ((ti->hsync_pulse_width_hi << 8) | \
+ ti->hsync_pulse_width_lo);
+ mode->htotal = mode->hdisplay + ((ti->hblank_hi << 8) | \
+ ti->hblank_lo);
+ mode->vsync_start = \
+ mode->vdisplay + ((ti->vsync_offset_hi << 8) | \
+ ti->vsync_offset_lo);
+ mode->vsync_end = \
+ mode->vsync_start + ((ti->vsync_pulse_width_hi << 8) | \
+ ti->vsync_pulse_width_lo);
+ mode->vtotal = mode->vdisplay + \
+ ((ti->vblank_hi << 8) | ti->vblank_lo);
+ mode->clock = ti->pixel_clock * 10;
+
+ dev_dbg(dev->dev, "hdisplay is %d\n", mode->hdisplay);
+ dev_dbg(dev->dev, "vdisplay is %d\n", mode->vdisplay);
+ dev_dbg(dev->dev, "HSS is %d\n", mode->hsync_start);
+ dev_dbg(dev->dev, "HSE is %d\n", mode->hsync_end);
+ dev_dbg(dev->dev, "htotal is %d\n", mode->htotal);
+ dev_dbg(dev->dev, "VSS is %d\n", mode->vsync_start);
+ dev_dbg(dev->dev, "VSE is %d\n", mode->vsync_end);
+ dev_dbg(dev->dev, "vtotal is %d\n", mode->vtotal);
+ dev_dbg(dev->dev, "clock is %d\n", mode->clock);
+ } else {
+ mode->hdisplay = 864;
+ mode->vdisplay = 480;
+ mode->hsync_start = 872;
+ mode->hsync_end = 876;
+ mode->htotal = 884;
+ mode->vsync_start = 482;
+ mode->vsync_end = 494;
+ mode->vtotal = 486;
+ mode->clock = 25777;
+ }
+
+ drm_mode_set_name(mode);
+ drm_mode_set_crtcinfo(mode, 0);
+
+ mode->type |= DRM_MODE_TYPE_PREFERRED;
+
+ return mode;
+}
+
+static bool mdfld_dsi_dbi_mode_fixup(struct drm_encoder *encoder,
+ struct drm_display_mode *mode,
+ struct drm_display_mode *adjusted_mode)
+{
+ struct drm_device *dev = encoder->dev;
+ struct drm_display_mode *fixed_mode = tpo_cmd_get_config_mode(dev);
+
+ if (fixed_mode) {
+ adjusted_mode->hdisplay = fixed_mode->hdisplay;
+ adjusted_mode->hsync_start = fixed_mode->hsync_start;
+ adjusted_mode->hsync_end = fixed_mode->hsync_end;
+ adjusted_mode->htotal = fixed_mode->htotal;
+ adjusted_mode->vdisplay = fixed_mode->vdisplay;
+ adjusted_mode->vsync_start = fixed_mode->vsync_start;
+ adjusted_mode->vsync_end = fixed_mode->vsync_end;
+ adjusted_mode->vtotal = fixed_mode->vtotal;
+ adjusted_mode->clock = fixed_mode->clock;
+ drm_mode_set_crtcinfo(adjusted_mode, CRTC_INTERLACE_HALVE_V);
+ kfree(fixed_mode);
+ }
+ return true;
+}
+
+static void mdfld_dsi_dbi_set_power(struct drm_encoder *encoder, bool on)
+{


+ int ret = 0;

+ struct mdfld_dsi_encoder *dsi_encoder = MDFLD_DSI_ENCODER(encoder);
+ struct mdfld_dsi_dbi_output *dbi_output =
+ MDFLD_DSI_DBI_OUTPUT(dsi_encoder);
+ /*struct drm_device *dev = dbi_output->dev;*/
+ struct drm_device *dev = encoder->dev;
+ struct drm_psb_private *dev_priv = dev->dev_private;
+ u32 reg_offset = 0;
+ int pipe = (dbi_output->channel_num == 0) ? 0 : 2;
+
+ dev_dbg(dev->dev, "pipe %d : %s, panel on: %s\n",
+ pipe, on ? "On" : "Off",
+ dbi_output->dbi_panel_on ? "True" : "False");
+
+ if (pipe == 2) {
+ if (on)
+ dev_priv->dual_mipi = true;
+ else
+ dev_priv->dual_mipi = false;
+ reg_offset = MIPIC_REG_OFFSET;
+ } else {
+ if (!on)
+ dev_priv->dual_mipi = false;
+ }
+
+ if (!gma_power_begin(dev, true)) {
+ dev_err(dev->dev, "hw begin failed\n");
+ return;
+ }
+
+ if (on) {
+ if (dbi_output->dbi_panel_on)
+ goto out_err;
+
+ ret = mdfld_dsi_dbi_update_power(dbi_output, DRM_MODE_DPMS_ON);
+ if (ret) {
+ dev_err(dev->dev, "power on error\n");
+ goto out_err;
+ }
+
+ dbi_output->dbi_panel_on = true;
+
+ if (pipe == 2)
+ dev_priv->dbi_panel_on2 = true;
+ else
+ dev_priv->dbi_panel_on = true;
+ mdfld_enable_te(dev, pipe);
+ } else {
+ if (!dbi_output->dbi_panel_on && !dbi_output->first_boot)
+ goto out_err;
+
+ dbi_output->dbi_panel_on = false;
+ dbi_output->first_boot = false;
+
+ if (pipe == 2)
+ dev_priv->dbi_panel_on2 = false;
+ else
+ dev_priv->dbi_panel_on = false;
+
+ mdfld_disable_te(dev, pipe);
+
+ ret = mdfld_dsi_dbi_update_power(dbi_output, DRM_MODE_DPMS_OFF);
+ if (ret) {
+ dev_err(dev->dev, "power on error\n");
+ goto out_err;
+ }
+ }
+
+out_err:
+ gma_power_end(dev);
+
+ if (ret)
+ dev_err(dev->dev, "failed\n");
+}
+
+
+static void mdfld_dsi_dbi_mode_set(struct drm_encoder *encoder,
+ struct drm_display_mode *mode,
+ struct drm_display_mode *adjusted_mode)
+{


+ int ret = 0;

+ struct drm_device *dev = encoder->dev;
+ struct drm_psb_private *dev_priv = dev->dev_private;
+ struct mdfld_dsi_encoder *dsi_encoder = MDFLD_DSI_ENCODER(encoder);
+ struct mdfld_dsi_dbi_output *dsi_output =
+ MDFLD_DSI_DBI_OUTPUT(dsi_encoder);
+ struct mdfld_dsi_config *dsi_config =
+ mdfld_dsi_encoder_get_config(dsi_encoder);
+ struct mdfld_dsi_connector *dsi_connector = dsi_config->connector;
+ int pipe = dsi_connector->pipe;
+ u8 param = 0;
+
+ /* Regs */
+ u32 mipi_reg = MIPI;
+ u32 dspcntr_reg = DSPACNTR;
+ u32 pipeconf_reg = PIPEACONF;
+ u32 reg_offset = 0;
+
+ /* Values */
+ u32 dspcntr_val = dev_priv->dspcntr;
+ u32 pipeconf_val = dev_priv->pipeconf;
+ u32 h_active_area = mode->hdisplay;
+ u32 v_active_area = mode->vdisplay;
+ u32 mipi_val;
+
+ mipi_val = (PASS_FROM_SPHY_TO_AFE | SEL_FLOPPED_HSTX |
+ TE_TRIGGER_GPIO_PIN);
+
+ dev_dbg(dev->dev, "mipi_val =0x%x\n", mipi_val);
+
+ dev_dbg(dev->dev, "type %s\n", (pipe == 2) ? "MIPI2" : "MIPI");
+ dev_dbg(dev->dev, "h %d v %d\n", mode->hdisplay, mode->vdisplay);
+
+ if (pipe == 2) {
+ mipi_reg = MIPI_C;
+ dspcntr_reg = DSPCCNTR;
+ pipeconf_reg = PIPECCONF;
+
+ reg_offset = MIPIC_REG_OFFSET;
+
+ dspcntr_val = dev_priv->dspcntr2;
+ pipeconf_val = dev_priv->pipeconf2;
+ } else {
+ mipi_val |= 0x2; /*two lanes for port A and C respectively*/
+ }
+
+ if (!gma_power_begin(dev, true)) {
+ dev_err(dev->dev, "hw begin failed\n");
+ return;
+ }
+
+ /* Set up pipe related registers */
+ REG_WRITE(mipi_reg, mipi_val);
+ REG_READ(mipi_reg);
+
+ mdfld_dsi_controller_dbi_init(dsi_config, pipe);
+
+ msleep(20);
+
+ REG_WRITE(dspcntr_reg, dspcntr_val);
+ REG_READ(dspcntr_reg);
+
+ /* 20ms delay before sending exit_sleep_mode */
+ msleep(20);
+
+ /* Send exit_sleep_mode DCS */
+ ret = mdfld_dsi_dbi_send_dcs(dsi_output, exit_sleep_mode,
+ NULL, 0, CMD_DATA_SRC_SYSTEM_MEM);
+ if (ret) {
+ dev_err(dev->dev, "sent exit_sleep_mode faild\n");
+ goto out_err;
+ }
+
+ /* Send set_tear_on DCS */
+ ret = mdfld_dsi_dbi_send_dcs(dsi_output, set_tear_on,
+ &param, 1, CMD_DATA_SRC_SYSTEM_MEM);
+ if (ret) {
+ dev_err(dev->dev, "%s - sent set_tear_on faild\n", __func__);
+ goto out_err;
+ }
+
+ /* Do some init stuff */
+ mdfld_dsi_brightness_init(dsi_config, pipe);
+
+ mdfld_dsi_gen_fifo_ready(dev, (MIPIA_GEN_FIFO_STAT_REG + reg_offset),
+ HS_CTRL_FIFO_EMPTY | HS_DATA_FIFO_EMPTY);
+
+ REG_WRITE(pipeconf_reg, pipeconf_val | PIPEACONF_DSR);
+ REG_READ(pipeconf_reg);
+
+ /* TODO: this looks ugly, try to move it to CRTC mode setting*/
+ if (pipe == 2)
+ dev_priv->pipeconf2 |= PIPEACONF_DSR;
+ else
+ dev_priv->pipeconf |= PIPEACONF_DSR;
+
+ dev_dbg(dev->dev, "pipeconf %x\n", REG_READ(pipeconf_reg));
+
+ ret = mdfld_dsi_dbi_update_area(dsi_output, 0, 0,
+ h_active_area - 1, v_active_area - 1);
+ if (ret) {
+ dev_err(dev->dev, "update area failed\n");
+ goto out_err;
+ }
+
+out_err:
+ gma_power_end(dev);
+
+ if (ret)
+ dev_err(dev->dev, "mode set failed\n");
+}
+
+static void mdfld_dsi_dbi_prepare(struct drm_encoder *encoder)
+{
+ struct mdfld_dsi_encoder *dsi_encoder = MDFLD_DSI_ENCODER(encoder);
+ struct mdfld_dsi_dbi_output *dbi_output
+ = MDFLD_DSI_DBI_OUTPUT(dsi_encoder);
+
+ dbi_output->mode_flags |= MODE_SETTING_IN_ENCODER;
+ dbi_output->mode_flags &= ~MODE_SETTING_ENCODER_DONE;
+
+ mdfld_dsi_dbi_set_power(encoder, false);
+}
+
+static void mdfld_dsi_dbi_commit(struct drm_encoder *encoder)
+{
+ struct mdfld_dsi_encoder *dsi_encoder = MDFLD_DSI_ENCODER(encoder);
+ struct mdfld_dsi_dbi_output *dbi_output =
+ MDFLD_DSI_DBI_OUTPUT(dsi_encoder);
+ struct drm_device *dev = dbi_output->dev;
+ struct drm_psb_private *dev_priv = dev->dev_private;
+ struct psb_drm_dpu_rect rect;
+
+ mdfld_dsi_dbi_set_power(encoder, true);
+ dbi_output->mode_flags &= ~MODE_SETTING_IN_ENCODER;
+
+ rect.x = rect.y = 0;
+ rect.width = 864;
+ rect.height = 480;
+
+ if (dbi_output->channel_num == 1) {
+ dev_priv->dsr_fb_update |= MDFLD_DSR_2D_3D_2;
+#ifdef CONFIG_MDFLD_DSI_DPU
+ /*if dpu enabled report a fullscreen damage*/
+ mdfld_dbi_dpu_report_damage(dev, MDFLD_PLANEC, &rect);
+#endif
+ } else {
+ dev_priv->dsr_fb_update |= MDFLD_DSR_2D_3D_0;
+#ifdef CONFIG_MDFLD_DSI_DPU
+ mdfld_dbi_dpu_report_damage(dev, MDFLD_PLANEA, &rect);
+#endif
+ }
+ dbi_output->mode_flags |= MODE_SETTING_ENCODER_DONE;
+}
+
+static void mdfld_dsi_dbi_dpms(struct drm_encoder *encoder, int mode)
+{
+ struct mdfld_dsi_encoder *dsi_encoder = MDFLD_DSI_ENCODER(encoder);
+ struct mdfld_dsi_dbi_output *dbi_output
+ = MDFLD_DSI_DBI_OUTPUT(dsi_encoder);
+ struct drm_device *dev = dbi_output->dev;
+ struct drm_psb_private *dev_priv = dev->dev_private;
+ static bool bdispoff;
+
+ dev_dbg(dev->dev, "%s\n", (mode == DRM_MODE_DPMS_ON ? "on" : "off"));
+
+ if (mode == DRM_MODE_DPMS_ON) {
+ /*
+ * FIXME: in case I am wrong!
+ * we don't need to exit dsr here to wake up plane/pipe/pll
+ * if everything goes right, hw_begin will resume them all
+ * during set_power.
+ */
+ if (bdispoff)
+ mdfld_dsi_dbi_exit_dsr(dev, MDFLD_DSR_2D_3D, 0, 0);
+
+ mdfld_dsi_dbi_set_power(encoder, true);
+ /* FIXME if (gbgfxsuspended)
+ gbgfxsuspended = false; */
+ bdispoff = false;
+ dev_priv->dispstatus = true;
+ } else {
+ /*
+ * I am not sure whether this is the perfect place to
+ * turn rpm on since we still have a lot of CRTC turnning
+ * on work to do.
+ */
+ mdfld_dsi_dbi_set_power(encoder, false);
+ bdispoff = true;
+ dev_priv->dispstatus = false;
+ }
+}
+
+
+/*
+ * Update the DBI MIPI Panel Frame Buffer.
+ */
+static void mdfld_dsi_dbi_update_fb(struct mdfld_dsi_dbi_output *dbi_output,
+ int pipe)
+{
+ struct mdfld_dsi_pkg_sender *sender =
+ mdfld_dsi_encoder_get_pkg_sender(&dbi_output->base);
+ struct drm_device *dev = dbi_output->dev;
+ struct drm_crtc *crtc = dbi_output->base.base.crtc;
+ struct psb_intel_crtc *psb_crtc = (crtc) ?
+ to_psb_intel_crtc(crtc) : NULL;
+ u32 dpll_reg = MRST_DPLL_A;
+ u32 dspcntr_reg = DSPACNTR;
+ u32 pipeconf_reg = PIPEACONF;
+ u32 dsplinoff_reg = DSPALINOFF;
+ u32 dspsurf_reg = DSPASURF;
+ u32 reg_offset = 0;
+
+ /* If mode setting on-going, back off */
+ if ((dbi_output->mode_flags & MODE_SETTING_ON_GOING) ||
+ (psb_crtc && psb_crtc->mode_flags & MODE_SETTING_ON_GOING) ||
+ !(dbi_output->mode_flags & MODE_SETTING_ENCODER_DONE))
+ return;
+
+ if (pipe == 2) {
+ dspcntr_reg = DSPCCNTR;
+ pipeconf_reg = PIPECCONF;
+ dsplinoff_reg = DSPCLINOFF;
+ dspsurf_reg = DSPCSURF;
+ reg_offset = MIPIC_REG_OFFSET;
+ }
+
+ if (!gma_power_begin(dev, true)) {
+ dev_err(dev->dev, "hw begin failed\n");
+ return;
+ }
+
+ /* Check DBI FIFO status */
+ if (!(REG_READ(dpll_reg) & DPLL_VCO_ENABLE) ||
+ !(REG_READ(dspcntr_reg) & DISPLAY_PLANE_ENABLE) ||
+ !(REG_READ(pipeconf_reg) & DISPLAY_PLANE_ENABLE))
+ goto update_fb_out0;
+
+ /* Refresh plane changes */
+ REG_WRITE(dsplinoff_reg, REG_READ(dsplinoff_reg));
+ REG_WRITE(dspsurf_reg, REG_READ(dspsurf_reg));
+ REG_READ(dspsurf_reg);
+
+ mdfld_dsi_send_dcs(sender,
+ write_mem_start,
+ NULL,
+ 0,
+ CMD_DATA_SRC_PIPE,
+ MDFLD_DSI_SEND_PACKAGE);
+
+ dbi_output->dsr_fb_update_done = true;
+update_fb_out0:
+ gma_power_end(dev);
+}
+
+static int tpo_cmd_get_panel_info(struct drm_device *dev,
+ int pipe,
+ struct panel_info *pi)
+{
+ if (!dev || !pi)
+ return -EINVAL;
+
+ pi->width_mm = TPO_PANEL_WIDTH;
+ pi->height_mm = TPO_PANEL_HEIGHT;


+
+ return 0;
+}
+
+

+/* TPO DBI encoder helper funcs */
+static const struct drm_encoder_helper_funcs mdfld_dsi_dbi_helper_funcs = {
+ .dpms = mdfld_dsi_dbi_dpms,
+ .mode_fixup = mdfld_dsi_dbi_mode_fixup,
+ .prepare = mdfld_dsi_dbi_prepare,
+ .mode_set = mdfld_dsi_dbi_mode_set,
+ .commit = mdfld_dsi_dbi_commit,
+};
+
+/* TPO DBI encoder funcs */
+static const struct drm_encoder_funcs mdfld_dsi_dbi_encoder_funcs = {
+ .destroy = drm_encoder_cleanup,
+};
+
+void tpo_cmd_init(struct drm_device *dev, struct panel_funcs *p_funcs)
+{
+ p_funcs->encoder_funcs = &mdfld_dsi_dbi_encoder_funcs;
+ p_funcs->encoder_helper_funcs = &mdfld_dsi_dbi_helper_funcs;
+ p_funcs->get_config_mode = &tpo_cmd_get_config_mode;
+ p_funcs->update_fb = mdfld_dsi_dbi_update_fb;
+ p_funcs->get_panel_info = tpo_cmd_get_panel_info;
+}
diff --git a/drivers/staging/gma500/mdfld_tpo_vid.c b/drivers/staging/gma500/mdfld_tpo_vid.c
new file mode 100644
index 0000000..9549017
--- /dev/null
+++ b/drivers/staging/gma500/mdfld_tpo_vid.c
@@ -0,0 +1,140 @@
+/*
+ * Copyright © 2010 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ * jim liu <jim...@intel.com>
+ * Jackie Li<yaodo...@intel.com>
+ */
+
+#include "mdfld_dsi_dbi.h"
+#include "mdfld_dsi_dpi.h"
+#include "mdfld_dsi_output.h"
+#include "mdfld_output.h"
+
+#include "mdfld_dsi_pkg_sender.h"
+
+#include "displays/tpo_vid.h"
+
+static struct drm_display_mode *tpo_vid_get_config_mode(struct drm_device *dev)
+{
+ struct drm_display_mode *mode;
+ struct drm_psb_private *dev_priv = dev->dev_private;
+ struct mrst_timing_info *ti = &dev_priv->gct_data.DTD;
+ bool use_gct = false;
+
+ mode = kzalloc(sizeof(*mode), GFP_KERNEL);
+ if (!mode) {
+ dev_err(dev->dev, "out of memory\n");
+ return NULL;
+ }
+
+ if (use_gct) {
+ mode->hdisplay = (ti->hactive_hi << 8) | ti->hactive_lo;
+ mode->vdisplay = (ti->vactive_hi << 8) | ti->vactive_lo;
+ mode->hsync_start = mode->hdisplay + \
+ ((ti->hsync_offset_hi << 8) | \
+ ti->hsync_offset_lo);
+ mode->hsync_end = mode->hsync_start + \
+ ((ti->hsync_pulse_width_hi << 8) | \
+ ti->hsync_pulse_width_lo);
+ mode->htotal = mode->hdisplay + ((ti->hblank_hi << 8) | \
+ ti->hblank_lo);
+ mode->vsync_start = \
+ mode->vdisplay + ((ti->vsync_offset_hi << 8) | \
+ ti->vsync_offset_lo);
+ mode->vsync_end = \
+ mode->vsync_start + ((ti->vsync_pulse_width_hi << 8) | \
+ ti->vsync_pulse_width_lo);
+ mode->vtotal = mode->vdisplay + \
+ ((ti->vblank_hi << 8) | ti->vblank_lo);
+ mode->clock = ti->pixel_clock * 10;
+
+ dev_dbg(dev->dev, "hdisplay is %d\n", mode->hdisplay);
+ dev_dbg(dev->dev, "vdisplay is %d\n", mode->vdisplay);
+ dev_dbg(dev->dev, "HSS is %d\n", mode->hsync_start);
+ dev_dbg(dev->dev, "HSE is %d\n", mode->hsync_end);
+ dev_dbg(dev->dev, "htotal is %d\n", mode->htotal);
+ dev_dbg(dev->dev, "VSS is %d\n", mode->vsync_start);
+ dev_dbg(dev->dev, "VSE is %d\n", mode->vsync_end);
+ dev_dbg(dev->dev, "vtotal is %d\n", mode->vtotal);
+ dev_dbg(dev->dev, "clock is %d\n", mode->clock);
+ } else {
+ mode->hdisplay = 864;
+ mode->vdisplay = 480;
+ mode->hsync_start = 873;
+ mode->hsync_end = 876;
+ mode->htotal = 887;
+ mode->vsync_start = 487;
+ mode->vsync_end = 490;
+ mode->vtotal = 499;
+ mode->clock = 33264;
+ }
+
+ drm_mode_set_name(mode);
+ drm_mode_set_crtcinfo(mode, 0);
+
+ mode->type |= DRM_MODE_TYPE_PREFERRED;
+
+ return mode;
+}
+
+static int tpo_vid_get_panel_info(struct drm_device *dev,
+ int pipe,
+ struct panel_info *pi)
+{
+ if (!dev || !pi)
+ return -EINVAL;
+
+ pi->width_mm = TPO_PANEL_WIDTH;
+ pi->height_mm = TPO_PANEL_HEIGHT;


+
+ return 0;
+}
+

+/*TPO DPI encoder helper funcs*/
+static const struct drm_encoder_helper_funcs
+ mdfld_tpo_dpi_encoder_helper_funcs = {
+ .dpms = mdfld_dsi_dpi_dpms,
+ .mode_fixup = mdfld_dsi_dpi_mode_fixup,
+ .prepare = mdfld_dsi_dpi_prepare,
+ .mode_set = mdfld_dsi_dpi_mode_set,
+ .commit = mdfld_dsi_dpi_commit,
+};
+
+/*TPO DPI encoder funcs*/
+static const struct drm_encoder_funcs mdfld_tpo_dpi_encoder_funcs = {
+ .destroy = drm_encoder_cleanup,
+};
+
+void tpo_vid_init(struct drm_device *dev, struct panel_funcs *p_funcs)
+{
+ if (!dev || !p_funcs) {
+ dev_err(dev->dev, "tpo_vid_init: Invalid parameters\n");
+ return;
+ }
+
+ p_funcs->encoder_funcs = &mdfld_tpo_dpi_encoder_funcs;
+ p_funcs->encoder_helper_funcs = &mdfld_tpo_dpi_encoder_helper_funcs;
+ p_funcs->get_config_mode = &tpo_vid_get_config_mode;
+ p_funcs->update_fb = NULL;
+ p_funcs->get_panel_info = tpo_vid_get_panel_info;
+}
diff --git a/drivers/staging/gma500/psb_bl.c b/drivers/staging/gma500/psb_bl.c
index 4a00047..c84d261 100644
--- a/drivers/staging/gma500/psb_bl.c
+++ b/drivers/staging/gma500/psb_bl.c
@@ -105,6 +105,46 @@ int mrst_set_brightness(struct backlight_device *bd)
return 0;
}

+int mfld_set_brightness(struct backlight_device *bd)
+{
+ struct drm_device *dev = bl_get_data(psb_backlight_device);
+ struct drm_psb_private *dev_priv = dev->dev_private;
+ int level = bd->props.brightness;
+
+ DRM_DEBUG_DRIVER("backlight level set to %d\n", level);
+
+ /* Percentage 1-100% being valid */
+ if (level < 1)
+ level = 1;
+
+ if (gma_power_begin(dev, 0)) {
+ /* Calculate and set the brightness value */
+ u32 adjusted_level;
+
+ /* Adjust the backlight level with the percent in
+ * dev_priv->blc_adj2;
+ */
+ adjusted_level = level * dev_priv->blc_adj2;
+ adjusted_level = adjusted_level / BLC_ADJUSTMENT_MAX;
+#if 0
+#ifndef CONFIG_MDFLD_DSI_DPU
+ if(!(dev_priv->dsr_fb_update & MDFLD_DSR_MIPI_CONTROL) &&
+ (dev_priv->dbi_panel_on || dev_priv->dbi_panel_on2)){
+ mdfld_dsi_dbi_exit_dsr(dev,MDFLD_DSR_MIPI_CONTROL, 0, 0);
+ dev_dbg(dev->dev, "Out of DSR before set brightness to %d.\n",adjusted_level);
+ }
+#endif
+ mdfld_dsi_brightness_control(dev, 0, adjusted_level);
+
+ if ((dev_priv->dbi_panel_on2) || (dev_priv->dpi_panel_on2))
+ mdfld_dsi_brightness_control(dev, 2, adjusted_level);
+#endif
+ gma_power_end(dev);
+ }
+ psb_brightness = level;


+ return 0;
+}
+

int psb_get_brightness(struct backlight_device *bd)
{


/* return locally cached var instead of HW read (due to DPST etc.) */

@@ -118,6 +158,16 @@ static const struct backlight_ops psb_ops = {
.update_status = psb_set_brightness,
};

+static const struct backlight_ops mrst_ops = {
+ .get_brightness = psb_get_brightness,
+ .update_status = mrst_set_brightness,
+};
+
+static const struct backlight_ops mfld_ops = {
+ .get_brightness = psb_get_brightness,
+ .update_status = mfld_set_brightness,
+};
+


static int device_backlight_init(struct drm_device *dev)

{


struct drm_psb_private *dev_priv = dev->dev_private;

@@ -128,7 +178,11 @@ static int device_backlight_init(struct drm_device *dev)
uint32_t value;
uint32_t blc_pwm_precision_factor;

- if (IS_MRST(dev)) {
+ if (IS_MFLD(dev)) {
+ dev_priv->blc_adj1 = BLC_ADJUSTMENT_MAX;
+ dev_priv->blc_adj2 = BLC_ADJUSTMENT_MAX;
+ return 0;
+ } else if (IS_MRST(dev)) {
dev_priv->blc_adj1 = BLC_ADJUSTMENT_MAX;
dev_priv->blc_adj2 = BLC_ADJUSTMENT_MAX;
bl_max_freq = 256;
@@ -190,8 +244,16 @@ int psb_backlight_init(struct drm_device *dev)
props.max_brightness = 100;
props.type = BACKLIGHT_PLATFORM;

- psb_backlight_device = backlight_device_register("psb-bl", NULL,
- (void *)dev, &psb_ops, &props);
+ if (IS_MFLD(dev))
+ psb_backlight_device = backlight_device_register("mfld-bl",
+ NULL, (void *)dev, &mfld_ops, &props);
+ else if (IS_MRST(dev))
+ psb_backlight_device = backlight_device_register("mrst-bl",
+ NULL, (void *)dev, &psb_ops, &props);
+ else
+ psb_backlight_device = backlight_device_register("psb-bl",
+ NULL, (void *)dev, &psb_ops, &props);
+
if (IS_ERR(psb_backlight_device))
return PTR_ERR(psb_backlight_device);

diff --git a/drivers/staging/gma500/psb_drm.h b/drivers/staging/gma500/psb_drm.h
index 8c259b8..c541137 100644
--- a/drivers/staging/gma500/psb_drm.h
+++ b/drivers/staging/gma500/psb_drm.h
@@ -186,4 +186,11 @@ struct drm_psb_get_pipe_from_crtc_id_arg {
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;
+};
+
#endif
diff --git a/drivers/staging/gma500/psb_drv.c b/drivers/staging/gma500/psb_drv.c
index 3c2363a..8df9c58 100644
--- a/drivers/staging/gma500/psb_drv.c
+++ b/drivers/staging/gma500/psb_drv.c
@@ -58,6 +58,14 @@ static DEFINE_PCI_DEVICE_TABLE(pciidlist) = {
{ 0x8086, 0x4105, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_MRST_4100},
{ 0x8086, 0x4106, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_MRST_4100},
{ 0x8086, 0x4107, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_MRST_4100},
+ { 0x8086, 0x0130, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_MFLD_0130},
+ { 0x8086, 0x0131, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_MFLD_0130},
+ { 0x8086, 0x0132, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_MFLD_0130},
+ { 0x8086, 0x0133, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_MFLD_0130},
+ { 0x8086, 0x0134, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_MFLD_0130},
+ { 0x8086, 0x0135, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_MFLD_0130},
+ { 0x8086, 0x0136, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_MFLD_0130},
+ { 0x8086, 0x0137, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_MFLD_0130},
{ 0, 0, 0}
};
MODULE_DEVICE_TABLE(pci, pciidlist);
@@ -176,7 +184,9 @@ void mrst_get_fuse_settings(struct drm_device *dev)
pci_write_config_dword(pci_root, 0xD0, FB_REG06);
pci_read_config_dword(pci_root, 0xD4, &fuse_value);

- dev_priv->iLVDS_enable = fuse_value & FB_MIPI_DISABLE;
+ /* FB_MIPI_DISABLE doesn't mean LVDS on with Medfield */
+ if (IS_MRST(dev))
+ dev_priv->iLVDS_enable = fuse_value & FB_MIPI_DISABLE;

DRM_INFO("internal display is %s\n",
dev_priv->iLVDS_enable ? "LVDS display" : "MIPI display");
@@ -360,6 +370,7 @@ void mrst_get_vbt_data(struct drm_psb_private *dev_priv)
printk(KERN_ERR "Unknown revision of GCT!\n");
vbt->size = 0;
}
+ /* FIXME: Need to sort out Medfield panel identifiers in future */
}

static void psb_get_core_freq(struct drm_device *dev)
@@ -539,6 +550,8 @@ static int psb_driver_load(struct drm_device *dev, unsigned long chipset)

if (IS_MRST(dev))
dev_priv->num_pipe = 1;
+ else if (IS_MFLD(dev))
+ dev_priv->num_pipe = 3;
else
dev_priv->num_pipe = 2;

@@ -554,7 +567,7 @@ static int psb_driver_load(struct drm_device *dev, unsigned long chipset)
if (!dev_priv->vdc_reg)
goto out_err;

- if (IS_MRST(dev))
+ if (IS_MRST(dev) || IS_MFLD(dev))
dev_priv->sgx_reg = ioremap(resource_start + MRST_SGX_OFFSET,
PSB_SGX_SIZE);
else
@@ -564,7 +577,7 @@ static int psb_driver_load(struct drm_device *dev, unsigned long chipset)
if (!dev_priv->sgx_reg)
goto out_err;

- if (IS_MRST(dev)) {
+ if (IS_MRST(dev) || IS_MFLD(dev)) {
mrst_get_fuse_settings(dev);
mrst_get_vbt_data(dev_priv);
mid_get_pci_revID(dev_priv);
@@ -706,6 +719,11 @@ static int psb_dc_state_ioctl(struct drm_device *dev, void * data,
struct drm_psb_dc_state_arg *arg =
(struct drm_psb_dc_state_arg *)data;

+
+ /* Double check MRST case */
+ if (IS_MRST(dev) || IS_MFLD(dev))
+ return -EOPNOTSUPP;
+
flags = arg->flags;
obj_id = arg->obj_id;

@@ -954,6 +972,7 @@ 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)
{
diff --git a/drivers/staging/gma500/psb_drv.h b/drivers/staging/gma500/psb_drv.h
index cafbfcd..86abf26 100644
--- a/drivers/staging/gma500/psb_drv.h
+++ b/drivers/staging/gma500/psb_drv.h
@@ -34,15 +34,18 @@
#include "mrst.h"



/* Append new drm mode definition here, align with libdrm definition */

-#define DRM_MODE_SCALE_NO_SCALE 2
+#define DRM_MODE_SCALE_NO_SCALE 2
+#define DRM_MODE_CONNECTOR_MIPI 15

enum {


CHIP_PSB_8108 = 0, /* Poulsbo */

CHIP_PSB_8109 = 1, /* Poulsbo */

CHIP_MRST_4100 = 2, /* Moorestown/Oaktrail */

+ CHIP_MFLD_0130 = 3, /* Medfield */


};

#define IS_MRST(dev) (((dev)->pci_device & 0xfffc) == 0x4100)

+#define IS_MFLD(dev) (((dev)->pci_device & 0xfff8) == 0x0130)

/*
* Driver definitions
@@ -204,10 +207,25 @@ enum {
#define PSB_WATCHDOG_DELAY (DRM_HZ * 2)
#define PSB_LID_DELAY (DRM_HZ / 10)

-#define MDFLD_PNW_A0 0x00
#define MDFLD_PNW_B0 0x04
#define MDFLD_PNW_C0 0x08

+#define MDFLD_DSR_2D_3D_0 (1 << 0)
+#define MDFLD_DSR_2D_3D_2 (1 << 1)
+#define MDFLD_DSR_CURSOR_0 (1 << 2)
+#define MDFLD_DSR_CURSOR_2 (1 << 3)
+#define MDFLD_DSR_OVERLAY_0 (1 << 4)
+#define MDFLD_DSR_OVERLAY_2 (1 << 5)
+#define MDFLD_DSR_MIPI_CONTROL (1 << 6)
+#define MDFLD_DSR_DAMAGE_MASK_0 (1 << 0) | (1 << 2) | (1 << 4)
+#define MDFLD_DSR_DAMAGE_MASK_2 (1 << 1) | (1 << 3) | (1 << 5)
+#define MDFLD_DSR_2D_3D (MDFLD_DSR_2D_3D_0 | MDFLD_DSR_2D_3D_2)
+
+#define MDFLD_DSR_RR 45
+#define MDFLD_DPU_ENABLE (1 << 31)
+#define MDFLD_DSR_FULLSCREEN (1 << 30)
+#define MDFLD_DSR_DELAY (DRM_HZ / MDFLD_DSR_RR)
+
#define PSB_PWR_STATE_ON 1
#define PSB_PWR_STATE_OFF 2

@@ -221,6 +239,12 @@ enum {
#define PSB_PCIx_MSI_ADDR_LOC 0x94
#define PSB_PCIx_MSI_DATA_LOC 0x98

+/* Medfield crystal settings */
+#define KSEL_CRYSTAL_19 1
+#define KSEL_BYPASS_19 5
+#define KSEL_BYPASS_25 6
+#define KSEL_BYPASS_83_100 7
+
struct opregion_header;
struct opregion_acpi;
struct opregion_swsci;
@@ -331,6 +355,7 @@ struct drm_psb_private {
int lvds_ssc_freq;
bool is_lvds_on;
bool is_mipi_on;
+ u32 mipi_ctrl_display;



unsigned int core_freq;
uint32_t iLVDS_enable;

@@ -338,10 +363,19 @@ struct drm_psb_private {


/* Runtime PM state */
int rpm_enabled;

- /* Moorestown specific */
+ /* MID specific */
struct mrst_vbt vbt_data;
struct mrst_gct_data gct_data;

+ /* MIPI Panel type etc */
+ int panel_id;
+ bool dual_mipi; /* dual display - DPI & DBI */
+ bool dpi_panel_on; /* The DPI panel power is on */
+ bool dpi_panel_on2; /* The DPI panel power is on */
+ bool dbi_panel_on; /* The DBI panel power is on */
+ bool dbi_panel_on2; /* The DBI panel power is on */
+ u32 dsr_fb_update; /* DSR FB update counter */
+
/* Moorestown pipe config register value cache */
uint32_t pipeconf;
uint32_t pipeconf1;
@@ -376,6 +410,7 @@ struct drm_psb_private {
uint32_t saveDSPAPOS;
uint32_t saveDSPABASE;
uint32_t saveDSPASURF;
+ uint32_t saveDSPASTATUS;
uint32_t saveFPB0;
uint32_t saveFPB1;
uint32_t saveDPLL_B;
@@ -391,6 +426,7 @@ struct drm_psb_private {
uint32_t saveDSPBPOS;
uint32_t saveDSPBBASE;
uint32_t saveDSPBSURF;
+ uint32_t saveDSPBSTATUS;
uint32_t saveVCLK_DIVISOR_VGA0;
uint32_t saveVCLK_DIVISOR_VGA1;
uint32_t saveVCLK_POST_DIV;
@@ -461,6 +497,77 @@ struct drm_psb_private {
uint32_t msi_addr;
uint32_t msi_data;

+ /* Medfield specific register save state */
+ uint32_t saveHDMIPHYMISCCTL;
+ uint32_t saveHDMIB_CONTROL;
+ uint32_t saveDSPCCNTR;
+ uint32_t savePIPECCONF;
+ uint32_t savePIPECSRC;
+ uint32_t saveHTOTAL_C;
+ uint32_t saveHBLANK_C;
+ uint32_t saveHSYNC_C;
+ uint32_t saveVTOTAL_C;
+ uint32_t saveVBLANK_C;
+ uint32_t saveVSYNC_C;
+ uint32_t saveDSPCSTRIDE;
+ uint32_t saveDSPCSIZE;
+ uint32_t saveDSPCPOS;
+ uint32_t saveDSPCSURF;
+ uint32_t saveDSPCSTATUS;
+ uint32_t saveDSPCLINOFF;
+ uint32_t saveDSPCTILEOFF;
+ uint32_t saveDSPCCURSOR_CTRL;
+ uint32_t saveDSPCCURSOR_BASE;
+ uint32_t saveDSPCCURSOR_POS;
+ uint32_t save_palette_c[256];
+ uint32_t saveOV_OVADD_C;
+ uint32_t saveOV_OGAMC0_C;
+ uint32_t saveOV_OGAMC1_C;
+ uint32_t saveOV_OGAMC2_C;
+ uint32_t saveOV_OGAMC3_C;
+ uint32_t saveOV_OGAMC4_C;
+ uint32_t saveOV_OGAMC5_C;
+
+ /* DSI register save */
+ uint32_t saveDEVICE_READY_REG;
+ uint32_t saveINTR_EN_REG;
+ uint32_t saveDSI_FUNC_PRG_REG;
+ uint32_t saveHS_TX_TIMEOUT_REG;
+ uint32_t saveLP_RX_TIMEOUT_REG;
+ uint32_t saveTURN_AROUND_TIMEOUT_REG;
+ uint32_t saveDEVICE_RESET_REG;
+ uint32_t saveDPI_RESOLUTION_REG;
+ uint32_t saveHORIZ_SYNC_PAD_COUNT_REG;
+ uint32_t saveHORIZ_BACK_PORCH_COUNT_REG;
+ uint32_t saveHORIZ_FRONT_PORCH_COUNT_REG;
+ uint32_t saveHORIZ_ACTIVE_AREA_COUNT_REG;
+ uint32_t saveVERT_SYNC_PAD_COUNT_REG;
+ uint32_t saveVERT_BACK_PORCH_COUNT_REG;
+ uint32_t saveVERT_FRONT_PORCH_COUNT_REG;
+ uint32_t saveHIGH_LOW_SWITCH_COUNT_REG;
+ uint32_t saveINIT_COUNT_REG;
+ uint32_t saveMAX_RET_PAK_REG;
+ uint32_t saveVIDEO_FMT_REG;
+ uint32_t saveEOT_DISABLE_REG;
+ uint32_t saveLP_BYTECLK_REG;
+ uint32_t saveHS_LS_DBI_ENABLE_REG;
+ uint32_t saveTXCLKESC_REG;
+ uint32_t saveDPHY_PARAM_REG;
+ uint32_t saveMIPI_CONTROL_REG;
+ uint32_t saveMIPI;
+ uint32_t saveMIPI_C;
+
+ /* DPST register save */
+ uint32_t saveHISTOGRAM_INT_CONTROL_REG;
+ uint32_t saveHISTOGRAM_LOGIC_CONTROL_REG;
+ uint32_t savePWM_CONTROL_LOGIC;
+
+ /*
+ * DSI info.
+ */
+ void * dbi_dsr_info;
+ void * dbi_dpu_info;
+ void * dsi_configs[2];
/*
* LID-Switch
*/
@@ -486,6 +593,22 @@ struct drm_psb_private {
uint32_t blc_adj2;

void *fbdev;
+
+ /* DPST state */
+ uint32_t dsr_idle_count;
+ bool is_in_idle;
+ bool dsr_enable;
+ void (*exit_idle)(struct drm_device *dev, u32 update_src, void *p_surfaceAddr, bool check_hw_on_only);
+
+ /* FIXME: Arrays anyone ? */
+ struct mdfld_dsi_encoder *encoder0;
+ struct mdfld_dsi_encoder *encoder2;
+ struct mdfld_dsi_dbi_output * dbi_output;
+ struct mdfld_dsi_dbi_output * dbi_output2;
+ u32 bpp;
+ u32 bpp2;
+
+ bool dispstatus;
};


@@ -567,6 +690,9 @@ psb_disable_pipestat(struct drm_psb_private *dev_priv, int pipe, u32 mask);

extern u32 psb_get_vblank_counter(struct drm_device *dev, int crtc);

+extern int mdfld_enable_te(struct drm_device *dev, int pipe);
+extern void mdfld_disable_te(struct drm_device *dev, int pipe);
+
/*
* psb_opregion.c
*/
diff --git a/drivers/staging/gma500/psb_fb.c b/drivers/staging/gma500/psb_fb.c
index c2d4b23..8377a99 100644
--- a/drivers/staging/gma500/psb_fb.c
+++ b/drivers/staging/gma500/psb_fb.c
@@ -38,6 +38,8 @@
#include "psb_intel_drv.h"
#include "psb_fb.h"

+#include "mdfld_output.h"
+
static void psb_user_framebuffer_destroy(struct drm_framebuffer *fb);


static int psb_user_framebuffer_create_handle(struct drm_framebuffer *fb,
struct drm_file *file_priv,

@@ -270,6 +272,8 @@ static int psbfb_ioctl(struct fb_info *info, unsigned int cmd,
case 0x12345678:
if (!capable(CAP_SYS_RAWIO))
return -EPERM;
+ if (IS_MFLD(dev))
+ return -EOPNOTSUPP;
if (get_user(l, p))
return -EFAULT;
if (l > 32)
@@ -297,6 +301,19 @@ static struct fb_ops psbfb_ops = {
.fb_ioctl = psbfb_ioctl,
};

+static struct fb_ops psbfb_mfld_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_mmap = psbfb_mmap,
+ .fb_ioctl = psbfb_ioctl,
+};
+
/**


* psb_framebuffer_init - initialize a framebuffer

* @dev: our DRM device

@@ -346,6 +363,7 @@ static int psb_framebuffer_init(struct drm_device *dev,
*


* TODO: review object references

*/
+
static struct drm_framebuffer *psb_framebuffer_create
(struct drm_device *dev,
struct drm_mode_fb_cmd *mode_cmd,
@@ -468,7 +486,11 @@ static int psbfb_create(struct psb_fbdev *fbdev,


strcpy(info->fix.id, "psbfb");

info->flags = FBINFO_DEFAULT;

- info->fbops = &psbfb_ops;
+ /* No 2D engine */
+ if (IS_MFLD(dev))
+ info->fbops = &psbfb_mfld_ops;
+ else
+ info->fbops = &psbfb_ops;



ret = fb_alloc_cmap(&info->cmap, 256, 0);

if (ret) {
@@ -781,7 +803,9 @@ static void psb_setup_outputs(struct drm_device *dev)
mrst_lvds_init(dev, &dev_priv->mode_dev);
else


dev_err(dev->dev, "DSI is not supported\n");

- } else {
+ } else if (IS_MFLD(dev)) {
+ mdfld_output_init(dev);
+ } else {


psb_intel_lvds_init(dev, &dev_priv->mode_dev);
psb_intel_sdvo_init(dev, SDVOB);
}

diff --git a/drivers/staging/gma500/psb_intel_display.c b/drivers/staging/gma500/psb_intel_display.c
index 1bb2144..ac0d9da 100644
--- a/drivers/staging/gma500/psb_intel_display.c
+++ b/drivers/staging/gma500/psb_intel_display.c


@@ -1,5 +1,5 @@
/*

- * Copyright © 2006-2007 Intel Corporation
+ * Copyright © 2006-2011 Intel Corporation
*


* This program is free software; you can redistribute it and/or modify it

* under the terms and conditions of the GNU General Public License,

@@ -1080,7 +1080,7 @@ static int psb_intel_crtc_cursor_move(struct drm_crtc *crtc, int x, int y)
return 0;
}

-static void psb_intel_crtc_gamma_set(struct drm_crtc *crtc, u16 *red,
+void psb_intel_crtc_gamma_set(struct drm_crtc *crtc, u16 *red,
u16 *green, u16 *blue, uint32_t type, uint32_t size)
{


struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc);

@@ -1241,7 +1241,7 @@ struct drm_display_mode *psb_intel_crtc_mode_get(struct drm_device *dev,
return mode;
}

-static void psb_intel_crtc_destroy(struct drm_crtc *crtc)
+void psb_intel_crtc_destroy(struct drm_crtc *crtc)
{


struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc);

struct gtt_range *gt;
@@ -1303,7 +1303,14 @@ void psb_intel_crtc_init(struct drm_device *dev, int pipe,
return;
}

- drm_crtc_init(dev, &psb_intel_crtc->base, &psb_intel_crtc_funcs);
+#if 0 /* FIXME */
+ if (IS_MFLD(dev))
+ drm_crtc_init(dev, &psb_intel_crtc->base,
+ &mfld_intel_crtc_funcs);
+ else
+#endif
+ drm_crtc_init(dev, &psb_intel_crtc->base,
+ &psb_intel_crtc_funcs);

drm_mode_crtc_set_gamma_size(&psb_intel_crtc->base, 256);
psb_intel_crtc->pipe = pipe;
@@ -1329,6 +1336,9 @@ void psb_intel_crtc_init(struct drm_device *dev, int pipe,
if (IS_MRST(dev))
drm_crtc_helper_add(&psb_intel_crtc->base,
&mrst_helper_funcs);
+/* else if (IS_MDFLD(dev))
+ drm_crtc_helper_add(&psb_intel_crtc->base,
+ &mfld_helper_funcs); */
else
drm_crtc_helper_add(&psb_intel_crtc->base,
&psb_intel_helper_funcs);
diff --git a/drivers/staging/gma500/psb_intel_display.h b/drivers/staging/gma500/psb_intel_display.h
index 3724b97..535b49a 100644
--- a/drivers/staging/gma500/psb_intel_display.h
+++ b/drivers/staging/gma500/psb_intel_display.h
@@ -21,5 +21,8 @@
#define _INTEL_DISPLAY_H_

bool psb_intel_pipe_has_type(struct drm_crtc *crtc, int type);
+void psb_intel_crtc_gamma_set(struct drm_crtc *crtc, u16 *red,
+ u16 *green, u16 *blue, uint32_t type, uint32_t size);
+void psb_intel_crtc_destroy(struct drm_crtc *crtc);

#endif
diff --git a/drivers/staging/gma500/psb_intel_drv.h b/drivers/staging/gma500/psb_intel_drv.h
index 75a95f7..9d7151a 100644
--- a/drivers/staging/gma500/psb_intel_drv.h
+++ b/drivers/staging/gma500/psb_intel_drv.h
@@ -224,4 +224,7 @@ extern int psb_intel_lvds_set_property(struct drm_connector *connector,
extern void psb_intel_lvds_destroy(struct drm_connector *connector);
extern const struct drm_encoder_funcs psb_intel_lvds_enc_funcs;

+extern void mdfldWaitForPipeDisable(struct drm_device *dev, int pipe);
+extern void mdfldWaitForPipeEnable(struct drm_device *dev, int pipe);
+
#endif /* __INTEL_DRV_H__ */
diff --git a/drivers/staging/gma500/psb_intel_lvds.c b/drivers/staging/gma500/psb_intel_lvds.c
index 1cbc9bc..850d07d 100644
--- a/drivers/staging/gma500/psb_intel_lvds.c
+++ b/drivers/staging/gma500/psb_intel_lvds.c
@@ -388,6 +388,7 @@ 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");
diff --git a/drivers/staging/gma500/psb_irq.c b/drivers/staging/gma500/psb_irq.c
index 1cbfeb6..3768cf1 100644
--- a/drivers/staging/gma500/psb_irq.c
+++ b/drivers/staging/gma500/psb_irq.c
@@ -27,7 +27,7 @@
#include "psb_reg.h"
#include "psb_intel_reg.h"
#include "psb_powermgmt.h"
-
+#include "mdfld_output.h"

/*
* inline functions
@@ -455,6 +455,11 @@ int psb_enable_vblank(struct drm_device *dev, int pipe)


uint32_t reg_val = 0;
uint32_t pipeconf_reg = mid_pipeconf(pipe);

+ /* Medfield is different - we should perhaps extract out vblank
+ and blacklight etc ops */
+ if (IS_MFLD(dev) && !mdfld_panel_dpi(dev))
+ return mdfld_enable_te(dev, pipe);
+


if (gma_power_begin(dev, false)) {
reg_val = REG_READ(pipeconf_reg);
gma_power_end(dev);

@@ -481,6 +486,8 @@ void psb_disable_vblank(struct drm_device *dev, int pipe)


struct drm_psb_private *dev_priv = dev->dev_private;

unsigned long irqflags;

+ if (IS_MFLD(dev) && !mdfld_panel_dpi(dev))
+ mdfld_disable_te(dev, pipe);


spin_lock_irqsave(&dev_priv->irqmask_lock, irqflags);

mid_disable_pipe_event(dev_priv, pipe);

@@ -489,6 +496,58 @@ void psb_disable_vblank(struct drm_device *dev, int pipe)
spin_unlock_irqrestore(&dev_priv->irqmask_lock, irqflags);
}

+/**
+ * mdfld_enable_te - enable TE events
+ * @dev: our DRM device
+ * @pipe: which pipe to work on
+ *
+ * Enable TE events on a Medfield display pipe. Medfield specific.
+ */
+int mdfld_enable_te(struct drm_device *dev, int pipe)
+{
+ struct drm_psb_private *dev_priv = dev->dev_private;
+ unsigned long flags;
+ uint32_t reg_val = 0;
+ uint32_t pipeconf_reg = mid_pipeconf(pipe);
+
+ if (gma_power_begin(dev, false)) {
+ reg_val = REG_READ(pipeconf_reg);
+ gma_power_end(dev);
+ }
+
+ if (!(reg_val & PIPEACONF_ENABLE))
+ return -EINVAL;
+
+ spin_lock_irqsave(&dev_priv->irqmask_lock, flags);
+
+ mid_enable_pipe_event(dev_priv, pipe);
+ psb_enable_pipestat(dev_priv, pipe, PIPE_TE_ENABLE);
+
+ spin_unlock_irqrestore(&dev_priv->irqmask_lock, flags);


+
+ return 0;
+}
+

+/**
+ * mdfld_disable_te - disable TE events
+ * @dev: our DRM device
+ * @pipe: which pipe to work on
+ *
+ * Disable TE events on a Medfield display pipe. Medfield specific.
+ */
+void mdfld_disable_te(struct drm_device *dev, int pipe)
+{
+ struct drm_psb_private *dev_priv = dev->dev_private;
+ unsigned long flags;
+
+ spin_lock_irqsave(&dev_priv->irqmask_lock, flags);
+
+ mid_disable_pipe_event(dev_priv, pipe);
+ psb_disable_pipestat(dev_priv, pipe, PIPE_TE_ENABLE);
+
+ spin_unlock_irqrestore(&dev_priv->irqmask_lock, flags);
+}
+
/* Called from drm generic code, passed a 'crtc', which
* we use as a pipe index


*/
diff --git a/drivers/staging/gma500/psb_powermgmt.c b/drivers/staging/gma500/psb_powermgmt.c

index 50f2234..f837ab0 100644
--- a/drivers/staging/gma500/psb_powermgmt.c
+++ b/drivers/staging/gma500/psb_powermgmt.c
@@ -31,8 +31,16 @@
#include "psb_drv.h"
#include "psb_reg.h"
#include "psb_intel_reg.h"
+#include "mdfld_output.h"
+#include "mdfld_dsi_output.h"
#include <linux/mutex.h>
#include <linux/pm_runtime.h>
+#include <asm/intel_scu_ipc.h>
+
+/* IPC message and command defines used to enable/disable mipi panel voltages */
+#define IPC_MSG_PANEL_ON_OFF 0xE9
+#define IPC_CMD_PANEL_ON 1
+#define IPC_CMD_PANEL_OFF 0

static struct mutex power_mutex;

@@ -46,6 +54,8 @@ void gma_power_init(struct drm_device *dev)
{


struct drm_psb_private *dev_priv = dev->dev_private;

+ /* FIXME: need to sort out fetching apm_reg for both platforms ?? */
+
dev_priv->apm_base = dev_priv->apm_reg & 0xffff;
dev_priv->ospm_base &= 0xffff;

@@ -154,6 +164,521 @@ static int restore_display_registers(struct drm_device *dev)
}

/**
+ * mdfld_save_display_registers - save registers for pipe
+ * @dev: our device
+ * @pipe: pipe to save
+ *
+ * Save the pipe state of the device before we power it off. Keep everything
+ * we need to put it back again
+ */
+static int mdfld_save_display_registers(struct drm_device *dev, int pipe)
+{
+ struct drm_psb_private *dev_priv = dev->dev_private;
+ int i;
+
+ /* register */
+ u32 dpll_reg = MRST_DPLL_A;
+ u32 fp_reg = MRST_FPA0;
+ u32 pipeconf_reg = PIPEACONF;
+ u32 htot_reg = HTOTAL_A;
+ u32 hblank_reg = HBLANK_A;
+ u32 hsync_reg = HSYNC_A;
+ u32 vtot_reg = VTOTAL_A;
+ u32 vblank_reg = VBLANK_A;
+ u32 vsync_reg = VSYNC_A;
+ u32 pipesrc_reg = PIPEASRC;
+ u32 dspstride_reg = DSPASTRIDE;
+ u32 dsplinoff_reg = DSPALINOFF;
+ u32 dsptileoff_reg = DSPATILEOFF;
+ u32 dspsize_reg = DSPASIZE;
+ u32 dsppos_reg = DSPAPOS;
+ u32 dspsurf_reg = DSPASURF;
+ u32 mipi_reg = MIPI;
+ u32 dspcntr_reg = DSPACNTR;
+ u32 dspstatus_reg = PIPEASTAT;
+ u32 palette_reg = PALETTE_A;
+
+ /* pointer to values */
+ u32 *dpll_val = &dev_priv->saveDPLL_A;
+ u32 *fp_val = &dev_priv->saveFPA0;
+ u32 *pipeconf_val = &dev_priv->savePIPEACONF;
+ u32 *htot_val = &dev_priv->saveHTOTAL_A;
+ u32 *hblank_val = &dev_priv->saveHBLANK_A;
+ u32 *hsync_val = &dev_priv->saveHSYNC_A;
+ u32 *vtot_val = &dev_priv->saveVTOTAL_A;
+ u32 *vblank_val = &dev_priv->saveVBLANK_A;
+ u32 *vsync_val = &dev_priv->saveVSYNC_A;
+ u32 *pipesrc_val = &dev_priv->savePIPEASRC;
+ u32 *dspstride_val = &dev_priv->saveDSPASTRIDE;
+ u32 *dsplinoff_val = &dev_priv->saveDSPALINOFF;
+ u32 *dsptileoff_val = &dev_priv->saveDSPATILEOFF;
+ u32 *dspsize_val = &dev_priv->saveDSPASIZE;
+ u32 *dsppos_val = &dev_priv->saveDSPAPOS;
+ u32 *dspsurf_val = &dev_priv->saveDSPASURF;
+ u32 *mipi_val = &dev_priv->saveMIPI;
+ u32 *dspcntr_val = &dev_priv->saveDSPACNTR;
+ u32 *dspstatus_val = &dev_priv->saveDSPASTATUS;
+ u32 *palette_val = dev_priv->save_palette_a;
+
+ switch (pipe) {
+ case 0:
+ break;
+ case 1:
+ /* register */
+ dpll_reg = MDFLD_DPLL_B;
+ fp_reg = MDFLD_DPLL_DIV0;
+ pipeconf_reg = PIPEBCONF;
+ htot_reg = HTOTAL_B;
+ hblank_reg = HBLANK_B;
+ hsync_reg = HSYNC_B;
+ vtot_reg = VTOTAL_B;
+ vblank_reg = VBLANK_B;
+ vsync_reg = VSYNC_B;
+ pipesrc_reg = PIPEBSRC;
+ dspstride_reg = DSPBSTRIDE;
+ dsplinoff_reg = DSPBLINOFF;
+ dsptileoff_reg = DSPBTILEOFF;
+ dspsize_reg = DSPBSIZE;
+ dsppos_reg = DSPBPOS;
+ dspsurf_reg = DSPBSURF;
+ dspcntr_reg = DSPBCNTR;
+ dspstatus_reg = PIPEBSTAT;
+ palette_reg = PALETTE_B;
+
+ /* values */
+ dpll_val = &dev_priv->saveDPLL_B;
+ fp_val = &dev_priv->saveFPB0;
+ pipeconf_val = &dev_priv->savePIPEBCONF;
+ htot_val = &dev_priv->saveHTOTAL_B;
+ hblank_val = &dev_priv->saveHBLANK_B;
+ hsync_val = &dev_priv->saveHSYNC_B;
+ vtot_val = &dev_priv->saveVTOTAL_B;
+ vblank_val = &dev_priv->saveVBLANK_B;
+ vsync_val = &dev_priv->saveVSYNC_B;
+ pipesrc_val = &dev_priv->savePIPEBSRC;
+ dspstride_val = &dev_priv->saveDSPBSTRIDE;
+ dsplinoff_val = &dev_priv->saveDSPBLINOFF;
+ dsptileoff_val = &dev_priv->saveDSPBTILEOFF;
+ dspsize_val = &dev_priv->saveDSPBSIZE;
+ dsppos_val = &dev_priv->saveDSPBPOS;
+ dspsurf_val = &dev_priv->saveDSPBSURF;
+ dspcntr_val = &dev_priv->saveDSPBCNTR;
+ dspstatus_val = &dev_priv->saveDSPBSTATUS;
+ palette_val = dev_priv->save_palette_b;
+ break;
+ case 2:
+ /* register */
+ pipeconf_reg = PIPECCONF;
+ htot_reg = HTOTAL_C;
+ hblank_reg = HBLANK_C;
+ hsync_reg = HSYNC_C;
+ vtot_reg = VTOTAL_C;
+ vblank_reg = VBLANK_C;
+ vsync_reg = VSYNC_C;
+ pipesrc_reg = PIPECSRC;
+ dspstride_reg = DSPCSTRIDE;
+ dsplinoff_reg = DSPCLINOFF;
+ dsptileoff_reg = DSPCTILEOFF;
+ dspsize_reg = DSPCSIZE;
+ dsppos_reg = DSPCPOS;
+ dspsurf_reg = DSPCSURF;
+ mipi_reg = MIPI_C;
+ dspcntr_reg = DSPCCNTR;
+ dspstatus_reg = PIPECSTAT;
+ palette_reg = PALETTE_C;
+
+ /* pointer to values */
+ pipeconf_val = &dev_priv->savePIPECCONF;
+ htot_val = &dev_priv->saveHTOTAL_C;
+ hblank_val = &dev_priv->saveHBLANK_C;
+ hsync_val = &dev_priv->saveHSYNC_C;
+ vtot_val = &dev_priv->saveVTOTAL_C;
+ vblank_val = &dev_priv->saveVBLANK_C;
+ vsync_val = &dev_priv->saveVSYNC_C;
+ pipesrc_val = &dev_priv->savePIPECSRC;
+ dspstride_val = &dev_priv->saveDSPCSTRIDE;
+ dsplinoff_val = &dev_priv->saveDSPCLINOFF;
+ dsptileoff_val = &dev_priv->saveDSPCTILEOFF;
+ dspsize_val = &dev_priv->saveDSPCSIZE;
+ dsppos_val = &dev_priv->saveDSPCPOS;
+ dspsurf_val = &dev_priv->saveDSPCSURF;
+ mipi_val = &dev_priv->saveMIPI_C;
+ dspcntr_val = &dev_priv->saveDSPCCNTR;
+ dspstatus_val = &dev_priv->saveDSPCSTATUS;
+ palette_val = dev_priv->save_palette_c;
+ break;
+ default:
+ DRM_ERROR("%s, invalid pipe number.\n", __func__);


+ return -EINVAL;
+ }
+

+ /* Pipe & plane A info */
+ *dpll_val = PSB_RVDC32(dpll_reg);
+ *fp_val = PSB_RVDC32(fp_reg);
+ *pipeconf_val = PSB_RVDC32(pipeconf_reg);
+ *htot_val = PSB_RVDC32(htot_reg);
+ *hblank_val = PSB_RVDC32(hblank_reg);
+ *hsync_val = PSB_RVDC32(hsync_reg);
+ *vtot_val = PSB_RVDC32(vtot_reg);
+ *vblank_val = PSB_RVDC32(vblank_reg);
+ *vsync_val = PSB_RVDC32(vsync_reg);
+ *pipesrc_val = PSB_RVDC32(pipesrc_reg);
+ *dspstride_val = PSB_RVDC32(dspstride_reg);
+ *dsplinoff_val = PSB_RVDC32(dsplinoff_reg);
+ *dsptileoff_val = PSB_RVDC32(dsptileoff_reg);
+ *dspsize_val = PSB_RVDC32(dspsize_reg);
+ *dsppos_val = PSB_RVDC32(dsppos_reg);
+ *dspsurf_val = PSB_RVDC32(dspsurf_reg);
+ *dspcntr_val = PSB_RVDC32(dspcntr_reg);
+ *dspstatus_val = PSB_RVDC32(dspstatus_reg);
+
+ /*save palette (gamma) */
+ for (i = 0; i < 256; i++)
+ palette_val[i] = PSB_RVDC32(palette_reg + (i<<2));
+


+ if (pipe == 1) {

+ dev_priv->savePFIT_CONTROL = PSB_RVDC32(PFIT_CONTROL);
+ dev_priv->savePFIT_PGM_RATIOS = PSB_RVDC32(PFIT_PGM_RATIOS);
+ dev_priv->saveHDMIPHYMISCCTL = PSB_RVDC32(HDMIPHYMISCCTL);
+ dev_priv->saveHDMIB_CONTROL = PSB_RVDC32(HDMIB_CONTROL);
+ return 0;
+ }
+ *mipi_val = PSB_RVDC32(mipi_reg);


+ return 0;
+}
+

+/**
+ * mdfld_save_cursor_overlay_registers - save cursor overlay info
+ * @dev: our device
+ *
+ * Save the cursor and overlay register state
+ */
+static int mdfld_save_cursor_overlay_registers(struct drm_device *dev)
+{
+ struct drm_psb_private *dev_priv = dev->dev_private;
+
+ /* Save cursor regs */
+ dev_priv->saveDSPACURSOR_CTRL = PSB_RVDC32(CURACNTR);
+ dev_priv->saveDSPACURSOR_BASE = PSB_RVDC32(CURABASE);
+ dev_priv->saveDSPACURSOR_POS = PSB_RVDC32(CURAPOS);
+
+ dev_priv->saveDSPBCURSOR_CTRL = PSB_RVDC32(CURBCNTR);
+ dev_priv->saveDSPBCURSOR_BASE = PSB_RVDC32(CURBBASE);
+ dev_priv->saveDSPBCURSOR_POS = PSB_RVDC32(CURBPOS);
+
+ dev_priv->saveDSPCCURSOR_CTRL = PSB_RVDC32(CURCCNTR);
+ dev_priv->saveDSPCCURSOR_BASE = PSB_RVDC32(CURCBASE);
+ dev_priv->saveDSPCCURSOR_POS = PSB_RVDC32(CURCPOS);
+
+ /* HW overlay */
+ dev_priv->saveOV_OVADD = PSB_RVDC32(OV_OVADD);
+ dev_priv->saveOV_OGAMC0 = PSB_RVDC32(OV_OGAMC0);
+ dev_priv->saveOV_OGAMC1 = PSB_RVDC32(OV_OGAMC1);
+ dev_priv->saveOV_OGAMC2 = PSB_RVDC32(OV_OGAMC2);
+ dev_priv->saveOV_OGAMC3 = PSB_RVDC32(OV_OGAMC3);
+ dev_priv->saveOV_OGAMC4 = PSB_RVDC32(OV_OGAMC4);
+ dev_priv->saveOV_OGAMC5 = PSB_RVDC32(OV_OGAMC5);
+
+ dev_priv->saveOV_OVADD_C = PSB_RVDC32(OV_OVADD + OV_C_OFFSET);
+ dev_priv->saveOV_OGAMC0_C = PSB_RVDC32(OV_OGAMC0 + OV_C_OFFSET);
+ dev_priv->saveOV_OGAMC1_C = PSB_RVDC32(OV_OGAMC1 + OV_C_OFFSET);
+ dev_priv->saveOV_OGAMC2_C = PSB_RVDC32(OV_OGAMC2 + OV_C_OFFSET);
+ dev_priv->saveOV_OGAMC3_C = PSB_RVDC32(OV_OGAMC3 + OV_C_OFFSET);
+ dev_priv->saveOV_OGAMC4_C = PSB_RVDC32(OV_OGAMC4 + OV_C_OFFSET);
+ dev_priv->saveOV_OGAMC5_C = PSB_RVDC32(OV_OGAMC5 + OV_C_OFFSET);


+
+ return 0;
+}

+/*
+ * mdfld_restore_display_registers - restore the state of a pipe
+ * @dev: our device
+ * @pipe: the pipe to restore
+ *
+ * Restore the state of a pipe to that which was saved by the register save
+ * functions.
+ */
+static int mdfld_restore_display_registers(struct drm_device *dev, int pipe)
+{
+ /* To get panel out of ULPS mode */
+ struct drm_psb_private *dev_priv = dev->dev_private;
+ struct mdfld_dsi_config *dsi_config = NULL;
+ u32 i = 0;
+ u32 dpll = 0;
+ u32 timeout = 0;
+ u32 reg_offset = 0;
+
+ /* register */
+ u32 dpll_reg = MRST_DPLL_A;
+ u32 fp_reg = MRST_FPA0;
+ u32 pipeconf_reg = PIPEACONF;
+ u32 htot_reg = HTOTAL_A;
+ u32 hblank_reg = HBLANK_A;
+ u32 hsync_reg = HSYNC_A;
+ u32 vtot_reg = VTOTAL_A;
+ u32 vblank_reg = VBLANK_A;
+ u32 vsync_reg = VSYNC_A;
+ u32 pipesrc_reg = PIPEASRC;
+ u32 dspstride_reg = DSPASTRIDE;
+ u32 dsplinoff_reg = DSPALINOFF;
+ u32 dsptileoff_reg = DSPATILEOFF;
+ u32 dspsize_reg = DSPASIZE;
+ u32 dsppos_reg = DSPAPOS;
+ u32 dspsurf_reg = DSPASURF;
+ u32 dspstatus_reg = PIPEASTAT;
+ u32 mipi_reg = MIPI;
+ u32 dspcntr_reg = DSPACNTR;
+ u32 palette_reg = PALETTE_A;
+
+ /* values */
+ u32 dpll_val = dev_priv->saveDPLL_A & ~DPLL_VCO_ENABLE;
+ u32 fp_val = dev_priv->saveFPA0;
+ u32 pipeconf_val = dev_priv->savePIPEACONF;
+ u32 htot_val = dev_priv->saveHTOTAL_A;
+ u32 hblank_val = dev_priv->saveHBLANK_A;
+ u32 hsync_val = dev_priv->saveHSYNC_A;
+ u32 vtot_val = dev_priv->saveVTOTAL_A;
+ u32 vblank_val = dev_priv->saveVBLANK_A;
+ u32 vsync_val = dev_priv->saveVSYNC_A;
+ u32 pipesrc_val = dev_priv->savePIPEASRC;
+ u32 dspstride_val = dev_priv->saveDSPASTRIDE;
+ u32 dsplinoff_val = dev_priv->saveDSPALINOFF;
+ u32 dsptileoff_val = dev_priv->saveDSPATILEOFF;
+ u32 dspsize_val = dev_priv->saveDSPASIZE;
+ u32 dsppos_val = dev_priv->saveDSPAPOS;
+ u32 dspsurf_val = dev_priv->saveDSPASURF;
+ u32 dspstatus_val = dev_priv->saveDSPASTATUS;
+ u32 mipi_val = dev_priv->saveMIPI;
+ u32 dspcntr_val = dev_priv->saveDSPACNTR;
+ u32 *palette_val = dev_priv->save_palette_a;
+
+ switch (pipe) {
+ case 0:
+ dsi_config = dev_priv->dsi_configs[0];
+ break;
+ case 1:
+ /* register */
+ dpll_reg = MDFLD_DPLL_B;
+ fp_reg = MDFLD_DPLL_DIV0;
+ pipeconf_reg = PIPEBCONF;
+ htot_reg = HTOTAL_B;
+ hblank_reg = HBLANK_B;
+ hsync_reg = HSYNC_B;
+ vtot_reg = VTOTAL_B;
+ vblank_reg = VBLANK_B;
+ vsync_reg = VSYNC_B;
+ pipesrc_reg = PIPEBSRC;
+ dspstride_reg = DSPBSTRIDE;
+ dsplinoff_reg = DSPBLINOFF;
+ dsptileoff_reg = DSPBTILEOFF;
+ dspsize_reg = DSPBSIZE;
+ dsppos_reg = DSPBPOS;
+ dspsurf_reg = DSPBSURF;
+ dspcntr_reg = DSPBCNTR;
+ palette_reg = PALETTE_B;
+ dspstatus_reg = PIPEBSTAT;
+
+ /* values */
+ dpll_val = dev_priv->saveDPLL_B & ~DPLL_VCO_ENABLE;
+ fp_val = dev_priv->saveFPB0;
+ pipeconf_val = dev_priv->savePIPEBCONF;
+ htot_val = dev_priv->saveHTOTAL_B;
+ hblank_val = dev_priv->saveHBLANK_B;
+ hsync_val = dev_priv->saveHSYNC_B;
+ vtot_val = dev_priv->saveVTOTAL_B;
+ vblank_val = dev_priv->saveVBLANK_B;
+ vsync_val = dev_priv->saveVSYNC_B;
+ pipesrc_val = dev_priv->savePIPEBSRC;
+ dspstride_val = dev_priv->saveDSPBSTRIDE;
+ dsplinoff_val = dev_priv->saveDSPBLINOFF;
+ dsptileoff_val = dev_priv->saveDSPBTILEOFF;
+ dspsize_val = dev_priv->saveDSPBSIZE;
+ dsppos_val = dev_priv->saveDSPBPOS;
+ dspsurf_val = dev_priv->saveDSPBSURF;
+ dspcntr_val = dev_priv->saveDSPBCNTR;
+ dspstatus_val = dev_priv->saveDSPBSTATUS;
+ palette_val = dev_priv->save_palette_b;
+ break;
+ case 2:
+ reg_offset = MIPIC_REG_OFFSET;
+
+ /* register */
+ pipeconf_reg = PIPECCONF;
+ htot_reg = HTOTAL_C;
+ hblank_reg = HBLANK_C;
+ hsync_reg = HSYNC_C;
+ vtot_reg = VTOTAL_C;
+ vblank_reg = VBLANK_C;
+ vsync_reg = VSYNC_C;
+ pipesrc_reg = PIPECSRC;
+ dspstride_reg = DSPCSTRIDE;
+ dsplinoff_reg = DSPCLINOFF;
+ dsptileoff_reg = DSPCTILEOFF;
+ dspsize_reg = DSPCSIZE;
+ dsppos_reg = DSPCPOS;
+ dspsurf_reg = DSPCSURF;
+ mipi_reg = MIPI_C;
+ dspcntr_reg = DSPCCNTR;
+ palette_reg = PALETTE_C;
+ dspstatus_reg = PIPECSTAT;
+
+ /* values */
+ pipeconf_val = dev_priv->savePIPECCONF;
+ htot_val = dev_priv->saveHTOTAL_C;
+ hblank_val = dev_priv->saveHBLANK_C;
+ hsync_val = dev_priv->saveHSYNC_C;
+ vtot_val = dev_priv->saveVTOTAL_C;
+ vblank_val = dev_priv->saveVBLANK_C;
+ vsync_val = dev_priv->saveVSYNC_C;
+ pipesrc_val = dev_priv->savePIPECSRC;
+ dspstride_val = dev_priv->saveDSPCSTRIDE;
+ dsplinoff_val = dev_priv->saveDSPCLINOFF;
+ dsptileoff_val = dev_priv->saveDSPCTILEOFF;
+ dspsize_val = dev_priv->saveDSPCSIZE;
+ dsppos_val = dev_priv->saveDSPCPOS;
+ dspsurf_val = dev_priv->saveDSPCSURF;
+ dspstatus_val = dev_priv->saveDSPCSTATUS;
+ mipi_val = dev_priv->saveMIPI_C;
+ dspcntr_val = dev_priv->saveDSPCCNTR;
+ palette_val = dev_priv->save_palette_c;
+
+ dsi_config = dev_priv->dsi_configs[1];
+ break;
+ default:
+ DRM_ERROR("%s, invalid pipe number.\n", __func__);


+ return -EINVAL;
+ }
+

+ /* Make sure VGA plane is off. it initializes to on after reset!*/
+ PSB_WVDC32(0x80000000, VGACNTRL);


+ if (pipe == 1) {

+ PSB_WVDC32(dpll_val & ~DPLL_VCO_ENABLE, dpll_reg);
+ PSB_RVDC32(dpll_reg);
+
+ PSB_WVDC32(fp_val, fp_reg);
+ } else {
+ dpll = PSB_RVDC32(dpll_reg);
+
+ if (!(dpll & DPLL_VCO_ENABLE)) {
+
+ /* When ungating power of DPLL, needs to wait 0.5us before enable the VCO */
+ if (dpll & MDFLD_PWR_GATE_EN) {
+ dpll &= ~MDFLD_PWR_GATE_EN;
+ PSB_WVDC32(dpll, dpll_reg);
+ udelay(500); /* FIXME: 1 ? */
+ }
+
+ PSB_WVDC32(fp_val, fp_reg);
+ PSB_WVDC32(dpll_val, dpll_reg);
+ /* FIXME_MDFLD PO - change 500 to 1 after PO */
+ udelay(500);
+
+ dpll_val |= DPLL_VCO_ENABLE;
+ PSB_WVDC32(dpll_val, dpll_reg);
+ PSB_RVDC32(dpll_reg);
+
+ /* wait for DSI PLL to lock */
+ while ((timeout < 20000) && !(PSB_RVDC32(pipeconf_reg) & PIPECONF_DSIPLL_LOCK)) {
+ udelay(150);
+ timeout++;
+ }
+
+ if (timeout == 20000) {
+ DRM_ERROR("%s, can't lock DSIPLL.\n",
+ __func__);


+ return -EINVAL;
+ }
+ }

+ }
+ /* Restore mode */
+ PSB_WVDC32(htot_val, htot_reg);
+ PSB_WVDC32(hblank_val, hblank_reg);
+ PSB_WVDC32(hsync_val, hsync_reg);
+ PSB_WVDC32(vtot_val, vtot_reg);
+ PSB_WVDC32(vblank_val, vblank_reg);
+ PSB_WVDC32(vsync_val, vsync_reg);
+ PSB_WVDC32(pipesrc_val, pipesrc_reg);
+ PSB_WVDC32(dspstatus_val, dspstatus_reg);
+
+ /* Set up the plane */
+ PSB_WVDC32(dspstride_val, dspstride_reg);
+ PSB_WVDC32(dsplinoff_val, dsplinoff_reg);
+ PSB_WVDC32(dsptileoff_val, dsptileoff_reg);
+ PSB_WVDC32(dspsize_val, dspsize_reg);
+ PSB_WVDC32(dsppos_val, dsppos_reg);
+ PSB_WVDC32(dspsurf_val, dspsurf_reg);
+


+ if (pipe == 1) {

+ PSB_WVDC32(dev_priv->savePFIT_CONTROL, PFIT_CONTROL);
+ PSB_WVDC32(dev_priv->savePFIT_PGM_RATIOS, PFIT_PGM_RATIOS);
+ PSB_WVDC32(dev_priv->saveHDMIPHYMISCCTL, HDMIPHYMISCCTL);
+ PSB_WVDC32(dev_priv->saveHDMIB_CONTROL, HDMIB_CONTROL);
+
+ } else {
+ /* Set up pipe related registers */
+ PSB_WVDC32(mipi_val, mipi_reg);
+ /* Setup MIPI adapter + MIPI IP registers */
+ mdfld_dsi_controller_init(dsi_config, pipe);
+ msleep(20);
+ }
+ /* Enable the plane */
+ PSB_WVDC32(dspcntr_val, dspcntr_reg);
+ msleep(20);
+ /* Enable the pipe */
+ PSB_WVDC32(pipeconf_val, pipeconf_reg);
+
+ for (i = 0; i < 256; i++)
+ PSB_WVDC32(palette_val[i], palette_reg + (i<<2));


+ if (pipe == 1)

+ return 0;
+ if (IS_MFLD(dev) && !mdfld_panel_dpi(dev))
+ mdfld_enable_te(dev, pipe);


+ return 0;
+}
+

+/**
+ * mdfld_restore_cursor_overlay_registers - restore cursor
+ * @dev: our device
+ *
+ * Restore the cursor and overlay state that was saved earlier
+ */
+static int mdfld_restore_cursor_overlay_registers(struct drm_device *dev)
+{
+ struct drm_psb_private *dev_priv = dev->dev_private;
+
+ /* Enable Cursor A */
+ PSB_WVDC32(dev_priv->saveDSPACURSOR_CTRL, CURACNTR);
+ PSB_WVDC32(dev_priv->saveDSPACURSOR_POS, CURAPOS);
+ PSB_WVDC32(dev_priv->saveDSPACURSOR_BASE, CURABASE);
+
+ PSB_WVDC32(dev_priv->saveDSPBCURSOR_CTRL, CURBCNTR);
+ PSB_WVDC32(dev_priv->saveDSPBCURSOR_POS, CURBPOS);
+ PSB_WVDC32(dev_priv->saveDSPBCURSOR_BASE, CURBBASE);
+
+ PSB_WVDC32(dev_priv->saveDSPCCURSOR_CTRL, CURCCNTR);
+ PSB_WVDC32(dev_priv->saveDSPCCURSOR_POS, CURCPOS);
+ PSB_WVDC32(dev_priv->saveDSPCCURSOR_BASE, CURCBASE);
+
+ /* Restore HW overlay */
+ PSB_WVDC32(dev_priv->saveOV_OVADD, OV_OVADD);
+ PSB_WVDC32(dev_priv->saveOV_OGAMC0, OV_OGAMC0);
+ PSB_WVDC32(dev_priv->saveOV_OGAMC1, OV_OGAMC1);
+ PSB_WVDC32(dev_priv->saveOV_OGAMC2, OV_OGAMC2);
+ PSB_WVDC32(dev_priv->saveOV_OGAMC3, OV_OGAMC3);
+ PSB_WVDC32(dev_priv->saveOV_OGAMC4, OV_OGAMC4);
+ PSB_WVDC32(dev_priv->saveOV_OGAMC5, OV_OGAMC5);
+
+ PSB_WVDC32(dev_priv->saveOV_OVADD_C, OV_OVADD + OV_C_OFFSET);
+ PSB_WVDC32(dev_priv->saveOV_OGAMC0_C, OV_OGAMC0 + OV_C_OFFSET);
+ PSB_WVDC32(dev_priv->saveOV_OGAMC1_C, OV_OGAMC1 + OV_C_OFFSET);
+ PSB_WVDC32(dev_priv->saveOV_OGAMC2_C, OV_OGAMC2 + OV_C_OFFSET);
+ PSB_WVDC32(dev_priv->saveOV_OGAMC3_C, OV_OGAMC3 + OV_C_OFFSET);
+ PSB_WVDC32(dev_priv->saveOV_OGAMC4_C, OV_OGAMC4 + OV_C_OFFSET);
+ PSB_WVDC32(dev_priv->saveOV_OGAMC5_C, OV_OGAMC5 + OV_C_OFFSET);


+
+ return 0;
+}
+

+/**
* power_down - power down the display island


* @dev: our DRM device
*

@@ -186,6 +711,10 @@ static void power_down(struct drm_device *dev)


* @dev: our DRM device
*

* Suspend the display logic of the graphics interface
+ *
+ * FIXME: This ought to be replaced by a dev_priv-> ops interface
+ * where the various platforms register their save/restore methods
+ * and keep them in their own support files.
*/
static void gma_suspend_display(struct drm_device *dev)
{
@@ -195,38 +724,57 @@ static void gma_suspend_display(struct drm_device *dev)
if (dev_priv->suspended)
return;

- save_display_registers(dev);
-
- 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);
+ if (IS_MFLD(dev)) {
+ /* FIXME: We need to shut down panels here if using them
+ and once the right bits are merged */
+ mdfld_save_cursor_overlay_registers(dev);
+ mdfld_save_display_registers(dev, 0);
+ mdfld_save_display_registers(dev, 0);
+ mdfld_save_display_registers(dev, 2);
+ mdfld_save_display_registers(dev, 1);
+ mdfld_disable_crtc(dev, 0);
+ mdfld_disable_crtc(dev, 2);
+ mdfld_disable_crtc(dev, 1);
} else {
- PSB_WVDC32(DPI_SHUT_DOWN, DPI_CONTROL_REG);
- PSB_WVDC32(0x0, PIPEACONF);
- PSB_WVDC32(0x2faf0000, BLC_PWM_CTL);
- while (REG_READ(0x70008) & 0x40000000);
- while ((PSB_RVDC32(GEN_FIFO_STAT_REG) & DPI_FIFO_EMPTY)
- != DPI_FIFO_EMPTY);
- PSB_WVDC32(0, DEVICE_READY_REG);
- /* turn off panel power */
+ save_display_registers(dev);
+
+ 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);
+ /* Turn off panel power */
+#ifdef CONFIG_X86_MRST
+ intel_scu_ipc_simple_command(IPC_MSG_PANEL_ON_OFF,
+ IPC_CMD_PANEL_OFF);
+#endif
+ }
}
power_down(dev);
}
@@ -286,7 +834,21 @@ static void gma_resume_display(struct pci_dev *pdev)
* above.
*/
/*psb_gtt_init(dev_priv->pg, 1);*/
-
+ if (IS_MFLD(dev)) {
+ mdfld_restore_display_registers(dev, 1);
+ mdfld_restore_display_registers(dev, 0);
+ mdfld_restore_display_registers(dev, 2);
+ mdfld_restore_cursor_overlay_registers(dev);
+ } else if (IS_MRST(dev)) {
+ if (!dev_priv->iLVDS_enable) {
+#ifdef CONFIG_X86_MRST
+ intel_scu_ipc_simple_command(IPC_MSG_PANEL_ON_OFF,
+ IPC_CMD_PANEL_ON);
+ /* FIXME: can we avoid this delay ? */
+ msleep(2000); /* wait 2 seconds */
+#endif
+ }
+ }
restore_display_registers(dev);

Alan Cox

unread,
Jun 16, 2011, 12:40:46 PM6/16/11
to gr...@kroah.com, linux-...@vger.kernel.org
From: Alan Cox <al...@linux.intel.com>

Signed-off-by: Alan Cox <al...@linux.intel.com>
---

drivers/staging/gma500/gem_glue.c | 54 ++++++++++++++++++++++++++++++++++++
drivers/staging/gma500/gem_glue.h | 2 +
drivers/staging/gma500/psb_gem.c | 56 +------------------------------------
3 files changed, 56 insertions(+), 56 deletions(-)

diff --git a/drivers/staging/gma500/gem_glue.c b/drivers/staging/gma500/gem_glue.c
index 0817497..0e7364b 100644
--- a/drivers/staging/gma500/gem_glue.c
+++ b/drivers/staging/gma500/gem_glue.c
@@ -45,3 +45,57 @@ void drm_gem_object_release_wrap(struct drm_gem_object *obj)
if (obj->filp)
drm_gem_object_release(obj);
}
+
+/**
+ * gem_create_mmap_offset - invent an mmap offset
+ * @obj: our object
+ *
+ * Standard implementation of offset generation for mmap as is
+ * duplicated in several drivers. This belongs in GEM.
+ */
+int gem_create_mmap_offset(struct drm_gem_object *obj)
+{
+ struct drm_device *dev = obj->dev;
+ struct drm_gem_mm *mm = dev->mm_private;
+ struct drm_map_list *list;
+ struct drm_local_map *map;
+ int ret;
+
+ list = &obj->map_list;
+ list->map = kzalloc(sizeof(struct drm_map_list), GFP_KERNEL);
+ if (list->map == NULL)
+ return -ENOMEM;
+ map = list->map;
+ map->type = _DRM_GEM;
+ map->size = obj->size;


+ map->handle = obj;

+
+ list->file_offset_node = drm_mm_search_free(&mm->offset_manager,
+ obj->size / PAGE_SIZE, 0, 0);
+ if (!list->file_offset_node) {


+ dev_err(dev->dev, "failed to allocate offset for bo %d\n",
+ obj->name);

+ ret = -ENOSPC;
+ goto free_it;
+ }
+ list->file_offset_node = drm_mm_get_block(list->file_offset_node,
+ obj->size / PAGE_SIZE, 0);
+ if (!list->file_offset_node) {
+ ret = -ENOMEM;
+ goto free_it;
+ }
+ list->hash.key = list->file_offset_node->start;
+ ret = drm_ht_insert_item(&mm->offset_hash, &list->hash);
+ if (ret) {
+ dev_err(dev->dev, "failed to add to map hash\n");
+ goto free_mm;


+ }
+ return 0;
+

+free_mm:
+ drm_mm_put_block(list->file_offset_node);
+free_it:
+ kfree(list->map);
+ list->map = NULL;
+ return ret;
+}
diff --git a/drivers/staging/gma500/gem_glue.h b/drivers/staging/gma500/gem_glue.h
index c38285b..a0f2bc4 100644
--- a/drivers/staging/gma500/gem_glue.h
+++ b/drivers/staging/gma500/gem_glue.h
@@ -1,4 +1,4 @@
extern void drm_gem_object_release_wrap(struct drm_gem_object *obj);
extern int drm_gem_private_object_init(struct drm_device *dev,
struct drm_gem_object *obj, size_t size);
-
+extern int gem_create_mmap_offset(struct drm_gem_object *obj);
diff --git a/drivers/staging/gma500/psb_gem.c b/drivers/staging/gma500/psb_gem.c
index 3f658e4..1e7faae 100644
--- a/drivers/staging/gma500/psb_gem.c
+++ b/drivers/staging/gma500/psb_gem.c
@@ -61,60 +61,6 @@ int psb_gem_get_aperture(struct drm_device *dev, void *data,
}

/**
- * psb_gem_create_mmap_offset - invent an mmap offset
- * @obj: our object
- *
- * This is basically doing by hand a pile of ugly crap which should
- * be done automatically by the GEM library code but isn't
- */
-static int psb_gem_create_mmap_offset(struct drm_gem_object *obj)
-{
- struct drm_device *dev = obj->dev;
- struct drm_gem_mm *mm = dev->mm_private;
- struct drm_map_list *list;
- struct drm_local_map *map;
- int ret;
-
- list = &obj->map_list;
- list->map = kzalloc(sizeof(struct drm_map_list), GFP_KERNEL);
- if (list->map == NULL)
- return -ENOMEM;
- map = list->map;
- map->type = _DRM_GEM;
- map->size = obj->size;


- map->handle = obj;

-
- list->file_offset_node = drm_mm_search_free(&mm->offset_manager,
- obj->size / PAGE_SIZE, 0, 0);
- if (!list->file_offset_node) {


- dev_err(dev->dev, "failed to allocate offset for bo %d\n",

- obj->name);
- ret = -ENOSPC;
- goto free_it;
- }
- list->file_offset_node = drm_mm_get_block(list->file_offset_node,
- obj->size / PAGE_SIZE, 0);
- if (!list->file_offset_node) {
- ret = -ENOMEM;
- goto free_it;
- }
- list->hash.key = list->file_offset_node->start;
- ret = drm_ht_insert_item(&mm->offset_hash, &list->hash);
- if (ret) {
- dev_err(dev->dev, "failed to add to map hash\n");
- goto free_mm;
- }
- return 0;
-
-free_mm:
- drm_mm_put_block(list->file_offset_node);
-free_it:
- kfree(list->map);
- list->map = NULL;


- return ret;
-}
-

-/**
* psb_gem_dumb_map_gtt - buffer mapping for dumb interface
* @file: our drm client file
* @dev: drm device
@@ -144,7 +90,7 @@ int psb_gem_dumb_map_gtt(struct drm_file *file, struct drm_device *dev,



/* Make it mmapable */
if (!obj->map_list.map) {

- ret = psb_gem_create_mmap_offset(obj);
+ ret = gem_create_mmap_offset(obj);
if (ret)
goto out;

Alan Cox

unread,
Jun 16, 2011, 12:41:32 PM6/16/11
to gr...@kroah.com, linux-...@vger.kernel.org
From: Alan Cox <al...@linux.intel.com>

We also pull out the undo side of the mmap offset processing so we can later
push it into GEM where it belongs

Signed-off-by: Alan Cox <al...@linux.intel.com>
---

drivers/staging/gma500/gem_glue.c | 9 +++++++++
drivers/staging/gma500/psb_gem.c | 15 +--------------
2 files changed, 10 insertions(+), 14 deletions(-)

diff --git a/drivers/staging/gma500/gem_glue.c b/drivers/staging/gma500/gem_glue.c
index 0e7364b..779ac1a 100644
--- a/drivers/staging/gma500/gem_glue.c
+++ b/drivers/staging/gma500/gem_glue.c
@@ -42,6 +42,15 @@ int drm_gem_private_object_init(struct drm_device *dev,

void drm_gem_object_release_wrap(struct drm_gem_object *obj)
{
+ /* Remove the list map if one is present */
+ if (obj->map_list.map) {
+ struct drm_gem_mm *mm = obj->dev->mm_private;
+ struct drm_map_list *list = &obj->map_list;
+ drm_ht_remove_item(&mm->offset_hash, &list->hash);
+ drm_mm_put_block(list->file_offset_node);


+ kfree(list->map);
+ list->map = NULL;
+ }

if (obj->filp)
drm_gem_object_release(obj);
}
diff --git a/drivers/staging/gma500/psb_gem.c b/drivers/staging/gma500/psb_gem.c
index 1e7faae..a63ad9e 100644
--- a/drivers/staging/gma500/psb_gem.c
+++ b/drivers/staging/gma500/psb_gem.c
@@ -19,12 +19,8 @@
* Authors: Alan Cox
*
* TODO:
- * - we don't actually put GEM objects into the GART yet
- * - we need to work out if the MMU is relevant as well (eg for
+ * - we need to work out if the MMU is relevant (eg for
* accelerated operations on a GEM object)
- * - cache coherency
- *
- * ie this is just an initial framework to get us going.
*/

#include <drm/drmP.h>
@@ -40,15 +36,6 @@ int psb_gem_init_object(struct drm_gem_object *obj)
void psb_gem_free_object(struct drm_gem_object *obj)
{
struct gtt_range *gtt = container_of(obj, struct gtt_range, gem);
- if (obj->map_list.map) {
- /* Do things GEM should do for us */
- struct drm_gem_mm *mm = obj->dev->mm_private;
- struct drm_map_list *list = &obj->map_list;
- drm_ht_remove_item(&mm->offset_hash, &list->hash);
- drm_mm_put_block(list->file_offset_node);


- kfree(list->map);
- list->map = NULL;
- }

drm_gem_object_release_wrap(obj);
/* This must occur last as it frees up the memory of the GEM object */
psb_gtt_free_range(obj->dev, gtt);

--

Alan Cox

unread,
Jun 16, 2011, 12:41:51 PM6/16/11
to gr...@kroah.com, linux-...@vger.kernel.org
From: Alan Cox <al...@linux.intel.com>

Signed-off-by: Alan Cox <al...@linux.intel.com>
---

drivers/staging/gma500/psb_powermgmt.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/staging/gma500/psb_powermgmt.c b/drivers/staging/gma500/psb_powermgmt.c
index f837ab0..2253ecb 100644
--- a/drivers/staging/gma500/psb_powermgmt.c
+++ b/drivers/staging/gma500/psb_powermgmt.c
@@ -64,7 +64,7 @@ void gma_power_init(struct drm_device *dev)
dev_priv->suspended = false; /* And not suspended */
mutex_init(&power_mutex);

- if (!IS_MRST(dev)) {
+ if (!IS_MRST(dev) && !IS_MFLD(dev)) {
/* FIXME: wants further review */
u32 gating = PSB_RSGX32(PSB_CR_CLKGATECTL);
/* Disable 2D clock gating */

Alan Cox

unread,
Jun 16, 2011, 12:42:07 PM6/16/11
to gr...@kroah.com, linux-...@vger.kernel.org
From: Alan Cox <al...@linux.intel.com>

We really want to move towards a completely abstracted interface rather
than having tons of per chip junk in the same files.

Begin with the power code which is probably the worst offender. Add a set
of methods, initialise a dev_priv->ops pointer and rip the chip specifics
out of the power code. While we are it pick up the display init bits.

So we know it's now chip specifics clean remove the psb_ naming from it.

Signed-off-by: Alan Cox <al...@linux.intel.com>
---

drivers/staging/gma500/Makefile | 5
drivers/staging/gma500/mdfld_device.c | 610 +++++++++++++++++++
drivers/staging/gma500/mdfld_output.c | 15
drivers/staging/gma500/mdfld_output.h | 2
drivers/staging/gma500/mrst_device.c | 230 +++++++
drivers/staging/gma500/power.c | 320 ++++++++++
drivers/staging/gma500/psb_device.c | 174 +++++
drivers/staging/gma500/psb_drv.c | 47 +
drivers/staging/gma500/psb_drv.h | 29 +
drivers/staging/gma500/psb_fb.c | 12
drivers/staging/gma500/psb_powermgmt.c | 1051 --------------------------------
11 files changed, 1402 insertions(+), 1093 deletions(-)
create mode 100644 drivers/staging/gma500/mdfld_device.c


create mode 100644 drivers/staging/gma500/mrst_device.c
create mode 100644 drivers/staging/gma500/power.c

create mode 100644 drivers/staging/gma500/psb_device.c
delete mode 100644 drivers/staging/gma500/psb_powermgmt.c

diff --git a/drivers/staging/gma500/Makefile b/drivers/staging/gma500/Makefile
index fdaac63..e93cbe3 100644
--- a/drivers/staging/gma500/Makefile
+++ b/drivers/staging/gma500/Makefile
@@ -4,6 +4,7 @@
ccflags-y += -Iinclude/drm

psb_gfx-y += gem_glue.o \
+ power.o \
psb_bl.o \
psb_drv.o \
psb_gem.o \
@@ -19,11 +20,13 @@ psb_gfx-y += gem_glue.o \
psb_intel_sdvo.o \
psb_lid.o \
psb_mmu.o \
- psb_powermgmt.o \
psb_irq.o \
+ psb_device.o \
+ mrst_device.o \
mrst_crtc.o \
mrst_lvds.o \
mrst_bios.o \
+ mdfld_device.o \
mdfld_output.o \
mdfld_pyr_cmd.o \
mdfld_tmd_vid.o \
diff --git a/drivers/staging/gma500/mdfld_device.c b/drivers/staging/gma500/mdfld_device.c
new file mode 100644
index 0000000..7caa7cd
--- /dev/null
+++ b/drivers/staging/gma500/mdfld_device.c
@@ -0,0 +1,610 @@


+/**************************************************************************
+ * Copyright (c) 2011, Intel Corporation.
+ * 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.
+ *
+ **************************************************************************/
+

+#include <drm/drmP.h>
+#include <drm/drm.h>
+#include "psb_reg.h"
+#include "psb_intel_reg.h"
+#include "psb_drm.h"
+#include "psb_drv.h"
+#include "mdfld_output.h"
+#include "mdfld_dsi_output.h"
+
+/*
+ * Provide the Medfield specific chip logic and low level methods
+ */
+
+static void mdfld_init_pm(struct drm_device *dev)
+{
+ /* No work needed here yet */
+}
+
+/**

+
+ return 0;
+}

+
+ return 0;
+}
+

+/**
+ * mdfld_save_display_registers - save registers lost on suspend


+ * @dev: our DRM device
+ *

+ * Save the state we need in order to be able to restore the interface
+ * upon resume from suspend
+ */
+static int mdfld_save_registers(struct drm_device *dev)
+{


+ /* FIXME: We need to shut down panels here if using them
+ and once the right bits are merged */
+ mdfld_save_cursor_overlay_registers(dev);
+ mdfld_save_display_registers(dev, 0);
+ mdfld_save_display_registers(dev, 0);
+ mdfld_save_display_registers(dev, 2);
+ mdfld_save_display_registers(dev, 1);
+ mdfld_disable_crtc(dev, 0);
+ mdfld_disable_crtc(dev, 2);
+ mdfld_disable_crtc(dev, 1);

+ return 0;
+}
+
+/**

+ * mdfld_restore_display_registers - restore lost register state


+ * @dev: our DRM device
+ *

+ * Restore register state that was lost during suspend and resume.
+ */
+static int mdfld_restore_registers(struct drm_device *dev)
+{


+ mdfld_restore_display_registers(dev, 1);
+ mdfld_restore_display_registers(dev, 0);
+ mdfld_restore_display_registers(dev, 2);
+ mdfld_restore_cursor_overlay_registers(dev);

+ return 0;
+}
+

+static int mdfld_power_down(struct drm_device *dev)
+{
+ /* FIXME */


+ return 0;
+}
+

+static int mdfld_power_up(struct drm_device *dev)
+{
+ /* FIXME */


+ return 0;
+}
+

+const struct psb_ops mdfld_chip_ops = {
+ .output_init = mdfld_output_init,
+ .init_pm = mdfld_init_pm,
+ .save_regs = mdfld_save_registers,
+ .restore_regs = mdfld_restore_registers,
+ .power_down = mdfld_power_down,
+ .power_up = mdfld_power_up,
+};
+
diff --git a/drivers/staging/gma500/mdfld_output.c b/drivers/staging/gma500/mdfld_output.c
index b1fc765..7e11401 100644
--- a/drivers/staging/gma500/mdfld_output.c
+++ b/drivers/staging/gma500/mdfld_output.c
@@ -63,14 +63,20 @@ int mdfld_panel_dpi(struct drm_device *dev)
}
}

-static void init_panel(struct drm_device *dev, int mipi_pipe, int p_type)
+static int init_panel(struct drm_device *dev, int mipi_pipe, int p_type)
{
struct panel_funcs *p_cmd_funcs;
struct panel_funcs *p_vid_funcs;



/* Oh boy ... FIXME */

p_cmd_funcs = kzalloc(sizeof(struct panel_funcs), GFP_KERNEL);

+ if (p_cmd_funcs == NULL)
+ return -ENODEV;


p_vid_funcs = kzalloc(sizeof(struct panel_funcs), GFP_KERNEL);

+ if (p_vid_funcs == NULL) {
+ kfree(p_cmd_funcs);
+ return -ENODEV;
+ }

switch (p_type) {
case TPO_CMD:
@@ -115,11 +121,12 @@ static void init_panel(struct drm_device *dev, int mipi_pipe, int p_type)
#endif
default:


dev_err(dev->dev, "Unsupported interface %d", p_type);

- break;
+ return -ENODEV;
}
+ return 0;
}

-void mdfld_output_init(struct drm_device *dev)
+int mdfld_output_init(struct drm_device *dev)
{
int type;

@@ -132,4 +139,6 @@ void mdfld_output_init(struct drm_device *dev)
type = mdfld_get_panel_type(dev, 2);


dev_info(dev->dev, "panel 2: type is %d\n", type);

init_panel(dev, 2, type);
+
+ return 0;
}
diff --git a/drivers/staging/gma500/mdfld_output.h b/drivers/staging/gma500/mdfld_output.h
index 36f43e1..53b57db 100644
--- a/drivers/staging/gma500/mdfld_output.h
+++ b/drivers/staging/gma500/mdfld_output.h
@@ -69,7 +69,7 @@ struct panel_funcs {


int (*get_panel_info) (struct drm_device *, int, struct panel_info *);

};

-void mdfld_output_init(struct drm_device *dev);
+int mdfld_output_init(struct drm_device *dev);
int mdfld_panel_dpi(struct drm_device *dev);
int mdfld_get_panel_type(struct drm_device *dev, int pipe);
void mdfld_disable_crtc (struct drm_device *dev, int pipe);
diff --git a/drivers/staging/gma500/mrst_device.c b/drivers/staging/gma500/mrst_device.c
new file mode 100644
index 0000000..5cd8283
--- /dev/null
+++ b/drivers/staging/gma500/mrst_device.c
@@ -0,0 +1,230 @@


+/**************************************************************************
+ * Copyright (c) 2011, Intel Corporation.
+ * 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.
+ *
+ **************************************************************************/
+

+#include <drm/drmP.h>
+#include <drm/drm.h>
+#include "psb_drm.h"
+#include "psb_drv.h"
+#include "psb_reg.h"
+#include "psb_intel_reg.h"


+#include <asm/intel_scu_ipc.h>
+
+/* IPC message and command defines used to enable/disable mipi panel voltages */
+#define IPC_MSG_PANEL_ON_OFF 0xE9
+#define IPC_CMD_PANEL_ON 1
+#define IPC_CMD_PANEL_OFF 0

+
+static int mrst_output_init(struct drm_device *dev)


+{
+ struct drm_psb_private *dev_priv = dev->dev_private;

+ if (dev_priv->iLVDS_enable) {
+ mrst_lvds_init(dev, &dev_priv->mode_dev);
+ return 0;
+ }
+ dev_err(dev->dev, "DSI is not supported\n");
+ return -ENODEV;
+}
+
+/*
+ * Provide the Moorestown specific chip logic and low level methods
+ */
+
+static void mrst_init_pm(struct drm_device *dev)
+{
+}
+
+/**
+ * mrst_save_display_registers - save registers lost on suspend


+ * @dev: our DRM device
+ *

+ * Save the state we need in order to be able to restore the interface
+ * upon resume from suspend
+ */
+static int mrst_save_display_registers(struct drm_device *dev)


+{
+ struct drm_psb_private *dev_priv = dev->dev_private;

+ struct drm_crtc *crtc;


+ struct drm_connector *connector;
+

+ /* Display arbitration control + watermarks */
+ dev_priv->saveDSPARB = PSB_RVDC32(DSPARB);
+ dev_priv->saveDSPFW1 = PSB_RVDC32(DSPFW1);
+ dev_priv->saveDSPFW2 = PSB_RVDC32(DSPFW2);
+ dev_priv->saveDSPFW3 = PSB_RVDC32(DSPFW3);
+ dev_priv->saveDSPFW4 = PSB_RVDC32(DSPFW4);
+ dev_priv->saveDSPFW5 = PSB_RVDC32(DSPFW5);
+ dev_priv->saveDSPFW6 = PSB_RVDC32(DSPFW6);
+ dev_priv->saveCHICKENBIT = PSB_RVDC32(DSPCHICKENBIT);
+
+ /* Save crtc and output state */
+ mutex_lock(&dev->mode_config.mutex);


+ list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {

+ if (drm_helper_crtc_in_use(crtc))
+ crtc->funcs->save(crtc);
+ }
+
+ list_for_each_entry(connector, &dev->mode_config.connector_list, head)
+ connector->funcs->save(connector);
+
+ mutex_unlock(&dev->mode_config.mutex);


+ return 0;
+}
+
+/**

+ * mrst_restore_display_registers - restore lost register state


+ * @dev: our DRM device
+ *

+ * Restore register state that was lost during suspend and resume.
+ */
+static int mrst_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;
+


+ if (!dev_priv->iLVDS_enable) {
+#ifdef CONFIG_X86_MRST
+ intel_scu_ipc_simple_command(IPC_MSG_PANEL_ON_OFF,
+ IPC_CMD_PANEL_ON);
+ /* FIXME: can we avoid this delay ? */
+ msleep(2000); /* wait 2 seconds */
+#endif
+ }
+

+ /* Display arbitration + watermarks */
+ PSB_WVDC32(dev_priv->saveDSPARB, DSPARB);
+ PSB_WVDC32(dev_priv->saveDSPFW1, DSPFW1);
+ PSB_WVDC32(dev_priv->saveDSPFW2, DSPFW2);
+ PSB_WVDC32(dev_priv->saveDSPFW3, DSPFW3);
+ PSB_WVDC32(dev_priv->saveDSPFW4, DSPFW4);
+ PSB_WVDC32(dev_priv->saveDSPFW5, DSPFW5);
+ PSB_WVDC32(dev_priv->saveDSPFW6, DSPFW6);
+ PSB_WVDC32(dev_priv->saveCHICKENBIT, DSPCHICKENBIT);
+
+ /*make sure VGA plane is off. it initializes to on after reset!*/
+ PSB_WVDC32(0x80000000, VGACNTRL);
+
+ mutex_lock(&dev->mode_config.mutex);


+ list_for_each_entry(crtc, &dev->mode_config.crtc_list, head)

+ if (drm_helper_crtc_in_use(crtc))
+ crtc->funcs->restore(crtc);
+
+ list_for_each_entry(connector, &dev->mode_config.connector_list, head)
+ connector->funcs->restore(connector);
+
+ mutex_unlock(&dev->mode_config.mutex);

+#ifdef CONFIG_X86_MRST /* FIXME: kill define once modular */


+ intel_scu_ipc_simple_command(IPC_MSG_PANEL_ON_OFF,
+ IPC_CMD_PANEL_OFF);
+#endif

+ }
+ return 0;
+}
+

+/**
+ * mrst_power_down - power down the display island


+ * @dev: our DRM device
+ *

+ * Power down the display interface of our device
+ */
+static int mrst_power_down(struct drm_device *dev)


+{
+ struct drm_psb_private *dev_priv = dev->dev_private;

+ u32 pwr_mask ;
+ u32 pwr_sts;
+
+ pwr_mask = PSB_PWRGT_DISPLAY_MASK;
+ outl(pwr_mask, dev_priv->ospm_base + PSB_PM_SSC);
+
+ while (true) {
+ pwr_sts = inl(dev_priv->ospm_base + PSB_PM_SSS);
+ if ((pwr_sts & pwr_mask) == pwr_mask)
+ break;
+ else
+ udelay(10);


+ }
+ return 0;
+}
+

+/*
+ * mrst_power_up
+ *
+ * Restore power to the specified island(s) (powergating)
+ */
+static int mrst_power_up(struct drm_device *dev)


+{
+ struct drm_psb_private *dev_priv = dev->dev_private;

+ u32 pwr_mask = PSB_PWRGT_DISPLAY_MASK;
+ u32 pwr_sts, pwr_cnt;
+
+ pwr_cnt = inl(dev_priv->ospm_base + PSB_PM_SSC);
+ pwr_cnt &= ~pwr_mask;
+ outl(pwr_cnt, (dev_priv->ospm_base + PSB_PM_SSC));
+
+ while (true) {
+ pwr_sts = inl(dev_priv->ospm_base + PSB_PM_SSS);
+ if ((pwr_sts & pwr_mask) == 0)
+ break;
+ else
+ udelay(10);


+ }
+ return 0;
+}
+

+const struct psb_ops mrst_chip_ops = {
+ .output_init = mrst_output_init,
+ .init_pm = mrst_init_pm,
+ .save_regs = mrst_save_display_registers,
+ .restore_regs = mrst_restore_display_registers,
+ .power_down = mrst_power_down,
+ .power_up = mrst_power_up,
+};
+
diff --git a/drivers/staging/gma500/power.c b/drivers/staging/gma500/power.c
new file mode 100644
index 0000000..fc2324e
--- /dev/null
+++ b/drivers/staging/gma500/power.c
@@ -0,0 +1,320 @@
+/**************************************************************************
+ * Copyright (c) 2009-2011, Intel Corporation.


+ * All Rights Reserved.

+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER

+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.


+ *
+ * Authors:

+ * Benjamin Defnet <benjamin...@intel.com>
+ * Rajesh Poornachandran <rajesh.poo...@intel.com>
+ * Massively reworked
+ * Alan Cox <al...@linux.intel.com>
+ */
+#include "psb_powermgmt.h"
+#include "psb_drv.h"
+#include "psb_reg.h"
+#include "psb_intel_reg.h"
+#include <linux/mutex.h>
+#include <linux/pm_runtime.h>
+
+static struct mutex power_mutex;
+
+/**
+ * gma_power_init - initialise power manager


+ * @dev: our device
+ *

+ * Set up for power management tracking of our hardware.
+ */
+void gma_power_init(struct drm_device *dev)


+{
+ struct drm_psb_private *dev_priv = dev->dev_private;
+

+ /* FIXME: need to sort out fetching apm_reg for both platforms ?? */
+
+ dev_priv->apm_base = dev_priv->apm_reg & 0xffff;

+ dev_priv->ospm_base &= 0xffff;
+
+ dev_priv->display_power = true; /* We start active */
+ dev_priv->display_count = 0; /* Currently no users */
+ dev_priv->suspended = false; /* And not suspended */
+ mutex_init(&power_mutex);
+
+ dev_priv->ops->init_pm(dev);
+}
+
+/**
+ * gma_power_uninit - end power manager
+ * @dev: device to end for
+ *
+ * Undo the effects of gma_power_init
+ */
+void gma_power_uninit(struct drm_device *dev)
+{
+ mutex_destroy(&power_mutex);
+ pm_runtime_disable(&dev->pdev->dev);
+ pm_runtime_set_suspended(&dev->pdev->dev);


+}
+
+
+
+
+/**

+ * gma_suspend_display - suspend the display logic


+ * @dev: our DRM device
+ *

+ * Suspend the display logic of the graphics interface


+ *
+ * FIXME: This ought to be replaced by a dev_priv-> ops interface
+ * where the various platforms register their save/restore methods
+ * and keep them in their own support files.

+ */
+static void gma_suspend_display(struct drm_device *dev)


+{
+ struct drm_psb_private *dev_priv = dev->dev_private;
+

+ if (dev_priv->suspended)
+ return;
+ dev_priv->ops->save_regs(dev);
+ dev_priv->ops->power_down(dev);
+ dev_priv->display_power = false;
+}
+
+/**
+ * gma_resume_display - resume display side logic
+ *
+ * Resume the display hardware restoring state and enabling
+ * as necessary.
+ */
+static void gma_resume_display(struct pci_dev *pdev)
+{
+ struct drm_device *dev = pci_get_drvdata(pdev);


+ struct drm_psb_private *dev_priv = dev->dev_private;
+

+ if (dev_priv->suspended == false)
+ return;
+
+ /* turn on the display power island */
+ dev_priv->ops->power_up(dev);
+ dev_priv->suspended = false;
+ dev_priv->display_power = true;
+
+ PSB_WVDC32(dev_priv->pge_ctl | _PSB_PGETBL_ENABLED, PSB_PGETBL_CTL);
+ pci_write_config_word(pdev, PSB_GMCH_CTRL,
+ dev_priv->gmch_ctrl | _PSB_GMCH_ENABLED);
+ dev_priv->ops->restore_regs(dev);
+}
+
+/**
+ * gma_suspend_pci - suspend PCI side
+ * @pdev: PCI device
+ *
+ * Perform the suspend processing on our PCI device state
+ */
+static void gma_suspend_pci(struct pci_dev *pdev)
+{
+ struct drm_device *dev = pci_get_drvdata(pdev);


+ struct drm_psb_private *dev_priv = dev->dev_private;

+ int bsm, vbt;
+
+ if (dev_priv->suspended)
+ return;
+
+ pci_save_state(pdev);
+ pci_read_config_dword(pdev, 0x5C, &bsm);
+ dev_priv->saveBSM = bsm;
+ pci_read_config_dword(pdev, 0xFC, &vbt);
+ dev_priv->saveVBT = vbt;
+ pci_read_config_dword(pdev, PSB_PCIx_MSI_ADDR_LOC, &dev_priv->msi_addr);
+ pci_read_config_dword(pdev, PSB_PCIx_MSI_DATA_LOC, &dev_priv->msi_data);
+
+ pci_disable_device(pdev);
+ pci_set_power_state(pdev, PCI_D3hot);
+
+ dev_priv->suspended = true;
+}
+
+/**
+ * gma_resume_pci - resume helper
+ * @dev: our PCI device
+ *
+ * Perform the resume processing on our PCI device state - rewrite
+ * register state and re-enable the PCI device
+ */
+static bool gma_resume_pci(struct pci_dev *pdev)
+{
+ struct drm_device *dev = pci_get_drvdata(pdev);


+ struct drm_psb_private *dev_priv = dev->dev_private;

+ int ret;
+
+ if (!dev_priv->suspended)
+ return true;
+
+ pci_set_power_state(pdev, PCI_D0);
+ pci_restore_state(pdev);
+ pci_write_config_dword(pdev, 0x5c, dev_priv->saveBSM);
+ pci_write_config_dword(pdev, 0xFC, dev_priv->saveVBT);
+ /* restoring MSI address and data in PCIx space */
+ pci_write_config_dword(pdev, PSB_PCIx_MSI_ADDR_LOC, dev_priv->msi_addr);
+ pci_write_config_dword(pdev, PSB_PCIx_MSI_DATA_LOC, dev_priv->msi_data);
+ ret = pci_enable_device(pdev);
+
+ if (ret != 0)
+ dev_err(&pdev->dev, "pci_enable failed: %d\n", ret);
+ else
+ dev_priv->suspended = false;
+ return !dev_priv->suspended;
+}
+
+/**
+ * gma_power_suspend - bus callback for suspend
+ * @pdev: our PCI device
+ * @state: suspend type
+ *
+ * Called back by the PCI layer during a suspend of the system. We
+ * perform the necessary shut down steps and save enough state that
+ * we can undo this when resume is called.
+ */
+int gma_power_suspend(struct pci_dev *pdev, pm_message_t state)
+{
+ struct drm_device *dev = pci_get_drvdata(pdev);


+ struct drm_psb_private *dev_priv = dev->dev_private;
+

+ mutex_lock(&power_mutex);
+ if (!dev_priv->suspended) {
+ if (dev_priv->display_count) {
+ mutex_unlock(&power_mutex);
+ return -EBUSY;
+ }
+ psb_irq_uninstall(dev);
+ gma_suspend_display(dev);
+ gma_suspend_pci(pdev);
+ }
+ mutex_unlock(&power_mutex);


+ return 0;
+}
+
+

+/**
+ * gma_power_resume - resume power
+ * @pdev: PCI device
+ *
+ * Resume the PCI side of the graphics and then the displays
+ */
+int gma_power_resume(struct pci_dev *pdev)
+{
+ struct drm_device *dev = pci_get_drvdata(pdev);
+
+ mutex_lock(&power_mutex);
+ gma_resume_pci(pdev);
+ gma_resume_display(pdev);
+ psb_irq_preinstall(dev);
+ psb_irq_postinstall(dev);
+ mutex_unlock(&power_mutex);


+ return 0;
+}
+
+

+
+/**
+ * gma_power_is_on - returne true if power is on


+ * @dev: our DRM device
+ *

+ * Returns true if the display island power is on at this moment
+ */
+bool gma_power_is_on(struct drm_device *dev)


+{
+ struct drm_psb_private *dev_priv = dev->dev_private;

+ return dev_priv->display_power;
+}
+
+
+/**
+ * gma_power_begin - begin requiring power


+ * @dev: our DRM device

+ * @force_on: true to force power on
+ *
+ * Begin an action that requires the display power island is enabled.
+ * We refcount the islands.
+ *
+ * FIXME: locking
+ */
+bool gma_power_begin(struct drm_device *dev, bool force_on)


+{
+ struct drm_psb_private *dev_priv = dev->dev_private;

+ int ret;
+
+ /* Power already on ? */
+ if (dev_priv->display_power) {
+ dev_priv->display_count++;
+ pm_runtime_get(&dev->pdev->dev);
+ return true;
+ }
+ if (force_on == false)
+ return false;
+
+ /* Ok power up needed */
+ ret = gma_resume_pci(dev->pdev);
+ if (ret == 0) {
+ psb_irq_preinstall(dev);
+ psb_irq_postinstall(dev);
+ pm_runtime_get(&dev->pdev->dev);
+ dev_priv->display_count++;
+ return true;
+ }


+ return false;
+}
+
+

+/**
+ * gma_power_end - end use of power
+ * @dev: Our DRM device
+ *
+ * Indicate that one of our gma_power_begin() requested periods when
+ * the diplay island power is needed has completed.
+ */
+void gma_power_end(struct drm_device *dev)


+{
+ struct drm_psb_private *dev_priv = dev->dev_private;

+ dev_priv->display_count--;
+ WARN_ON(dev_priv->display_count < 0);
+ pm_runtime_put(&dev->pdev->dev);
+}
+
+int psb_runtime_suspend(struct device *dev)
+{
+ static pm_message_t dummy;
+ return gma_power_suspend(to_pci_dev(dev), dummy);
+}
+
+int psb_runtime_resume(struct device *dev)


+{
+ return 0;
+}
+

+int psb_runtime_idle(struct device *dev)
+{
+ struct drm_device *drmdev = pci_get_drvdata(to_pci_dev(dev));
+ struct drm_psb_private *dev_priv = drmdev->dev_private;
+ if (dev_priv->display_count)


+ return 0;
+ else

+ return 1;
+}
+

diff --git a/drivers/staging/gma500/psb_device.c b/drivers/staging/gma500/psb_device.c
new file mode 100644
index 0000000..97e25ab
--- /dev/null
+++ b/drivers/staging/gma500/psb_device.c
@@ -0,0 +1,174 @@


+/**************************************************************************
+ * Copyright (c) 2011, Intel Corporation.
+ * 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.
+ *
+ **************************************************************************/
+

+#include <drm/drmP.h>
+#include <drm/drm.h>
+#include "psb_drm.h"
+#include "psb_drv.h"
+#include "psb_reg.h"
+#include "psb_intel_reg.h"
+
+static int psb_output_init(struct drm_device *dev)


+{
+ struct drm_psb_private *dev_priv = dev->dev_private;

+ psb_intel_lvds_init(dev, &dev_priv->mode_dev);
+ psb_intel_sdvo_init(dev, SDVOB);


+ return 0;
+}
+
+/*

+ * Provide the Poulsbo specific chip logic and low level methods
+ */
+
+static void psb_init_pm(struct drm_device *dev)


+{
+ struct drm_psb_private *dev_priv = dev->dev_private;
+

+ u32 gating = PSB_RSGX32(PSB_CR_CLKGATECTL);
+ gating &= ~3; /* Disable 2D clock gating */
+ gating |= 1;
+ PSB_WSGX32(gating, PSB_CR_CLKGATECTL);
+ PSB_RSGX32(PSB_CR_CLKGATECTL);
+}
+
+/**
+ * psb_save_display_registers - save registers lost on suspend


+ * @dev: our DRM device
+ *

+ * Save the state we need in order to be able to restore the interface
+ * upon resume from suspend
+ */
+static int psb_save_display_registers(struct drm_device *dev)


+{
+ struct drm_psb_private *dev_priv = dev->dev_private;

+ struct drm_crtc *crtc;


+ struct drm_connector *connector;
+

+ /* Display arbitration control + watermarks */
+ dev_priv->saveDSPARB = PSB_RVDC32(DSPARB);
+ dev_priv->saveDSPFW1 = PSB_RVDC32(DSPFW1);
+ dev_priv->saveDSPFW2 = PSB_RVDC32(DSPFW2);
+ dev_priv->saveDSPFW3 = PSB_RVDC32(DSPFW3);
+ dev_priv->saveDSPFW4 = PSB_RVDC32(DSPFW4);
+ dev_priv->saveDSPFW5 = PSB_RVDC32(DSPFW5);
+ dev_priv->saveDSPFW6 = PSB_RVDC32(DSPFW6);
+ dev_priv->saveCHICKENBIT = PSB_RVDC32(DSPCHICKENBIT);
+
+ /* Save crtc and output state */
+ mutex_lock(&dev->mode_config.mutex);


+ list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {

+ if (drm_helper_crtc_in_use(crtc))
+ crtc->funcs->save(crtc);
+ }
+
+ list_for_each_entry(connector, &dev->mode_config.connector_list, head)
+ connector->funcs->save(connector);
+
+ mutex_unlock(&dev->mode_config.mutex);


+ return 0;
+}
+
+/**

+ * psb_restore_display_registers - restore lost register state


+ * @dev: our DRM device
+ *

+ * Restore register state that was lost during suspend and resume.
+ */
+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);
+ PSB_WVDC32(dev_priv->saveDSPFW1, DSPFW1);
+ PSB_WVDC32(dev_priv->saveDSPFW2, DSPFW2);
+ PSB_WVDC32(dev_priv->saveDSPFW3, DSPFW3);
+ PSB_WVDC32(dev_priv->saveDSPFW4, DSPFW4);
+ PSB_WVDC32(dev_priv->saveDSPFW5, DSPFW5);
+ PSB_WVDC32(dev_priv->saveDSPFW6, DSPFW6);
+ PSB_WVDC32(dev_priv->saveCHICKENBIT, DSPCHICKENBIT);
+
+ /*make sure VGA plane is off. it initializes to on after reset!*/
+ PSB_WVDC32(0x80000000, VGACNTRL);
+
+ mutex_lock(&dev->mode_config.mutex);


+ list_for_each_entry(crtc, &dev->mode_config.crtc_list, head)

+ if (drm_helper_crtc_in_use(crtc))
+ crtc->funcs->restore(crtc);
+
+ list_for_each_entry(connector, &dev->mode_config.connector_list, head)
+ connector->funcs->restore(connector);
+
+ mutex_unlock(&dev->mode_config.mutex);

+ }
+ return 0;
+}
+

+int psb_power_down(struct drm_device *dev)


+{
+ return 0;
+}
+

+int psb_power_up(struct drm_device *dev)


+{
+ return 0;
+}
+

+const struct psb_ops psb_chip_ops = {
+ .output_init = psb_output_init,
+ .init_pm = psb_init_pm,
+ .save_regs = psb_save_display_registers,
+ .restore_regs = psb_restore_display_registers,
+ .power_down = psb_power_down,
+ .power_up = psb_power_up,
+};
+
diff --git a/drivers/staging/gma500/psb_drv.c b/drivers/staging/gma500/psb_drv.c
index 0d65f75..6c57234 100644
--- a/drivers/staging/gma500/psb_drv.c
+++ b/drivers/staging/gma500/psb_drv.c
@@ -49,24 +49,24 @@ module_param_named(trap_pagefaults, drm_psb_trap_pagefaults, int, 0600);


static DEFINE_PCI_DEVICE_TABLE(pciidlist) = {
- { 0x8086, 0x8108, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_PSB_8108 },
- { 0x8086, 0x8109, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_PSB_8109 },
- { 0x8086, 0x4100, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_MRST_4100},
- { 0x8086, 0x4101, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_MRST_4100},
- { 0x8086, 0x4102, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_MRST_4100},
- { 0x8086, 0x4103, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_MRST_4100},
- { 0x8086, 0x4104, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_MRST_4100},
- { 0x8086, 0x4105, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_MRST_4100},
- { 0x8086, 0x4106, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_MRST_4100},
- { 0x8086, 0x4107, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_MRST_4100},
- { 0x8086, 0x0130, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_MFLD_0130},
- { 0x8086, 0x0131, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_MFLD_0130},
- { 0x8086, 0x0132, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_MFLD_0130},
- { 0x8086, 0x0133, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_MFLD_0130},
- { 0x8086, 0x0134, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_MFLD_0130},
- { 0x8086, 0x0135, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_MFLD_0130},
- { 0x8086, 0x0136, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_MFLD_0130},
- { 0x8086, 0x0137, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_MFLD_0130},
+ { 0x8086, 0x8108, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (long) &psb_chip_ops },
+ { 0x8086, 0x8109, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (long) &psb_chip_ops },
+ { 0x8086, 0x4100, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (long) &mrst_chip_ops},
+ { 0x8086, 0x4101, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (long) &mrst_chip_ops},
+ { 0x8086, 0x4102, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (long) &mrst_chip_ops},
+ { 0x8086, 0x4103, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (long) &mrst_chip_ops},
+ { 0x8086, 0x4104, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (long) &mrst_chip_ops},
+ { 0x8086, 0x4105, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (long) &mrst_chip_ops},
+ { 0x8086, 0x4106, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (long) &mrst_chip_ops},
+ { 0x8086, 0x4107, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (long) &mrst_chip_ops},
+ { 0x8086, 0x0130, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (long) &mdfld_chip_ops},
+ { 0x8086, 0x0131, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (long) &mdfld_chip_ops},
+ { 0x8086, 0x0132, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (long) &mdfld_chip_ops},
+ { 0x8086, 0x0133, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (long) &mdfld_chip_ops},
+ { 0x8086, 0x0134, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (long) &mdfld_chip_ops},
+ { 0x8086, 0x0135, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (long) &mdfld_chip_ops},
+ { 0x8086, 0x0136, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (long) &mdfld_chip_ops},
+ { 0x8086, 0x0137, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (long) &mdfld_chip_ops},


{ 0, 0, 0}
};
MODULE_DEVICE_TABLE(pci, pciidlist);

@@ -257,8 +257,7 @@ out_err:

static int psb_driver_unload(struct drm_device *dev)
{


- struct drm_psb_private *dev_priv =

- (struct drm_psb_private *) dev->dev_private;


+ struct drm_psb_private *dev_priv = dev->dev_private;

/* Kill vblank etc here */

@@ -332,6 +331,10 @@ static int psb_driver_load(struct drm_device *dev, unsigned long chipset)
if (dev_priv == NULL)
return -ENOMEM;

+ dev_priv->ops = (struct psb_ops *)chipset;
+ dev_priv->dev = dev;
+ dev->dev_private = (void *) dev_priv;
+


if (IS_MRST(dev))
dev_priv->num_pipe = 1;

else if (IS_MFLD(dev))
@@ -339,10 +342,6 @@ static int psb_driver_load(struct drm_device *dev, unsigned long chipset)


else
dev_priv->num_pipe = 2;

- dev_priv->dev = dev;
-
- dev->dev_private = (void *) dev_priv;
- dev_priv->chipset = chipset;



resource_start = pci_resource_start(dev->pdev, PSB_MMIO_RESOURCE);

diff --git a/drivers/staging/gma500/psb_drv.h b/drivers/staging/gma500/psb_drv.h
index 3b2ee08..d1c49e7 100644
--- a/drivers/staging/gma500/psb_drv.h
+++ b/drivers/staging/gma500/psb_drv.h
@@ -258,11 +258,11 @@ struct psb_intel_opregion {
int enabled;
};

+struct psb_ops;

struct drm_psb_private {
struct drm_device *dev;
-
- unsigned long chipset;
+ const struct psb_ops *ops;

struct psb_gtt *pg;

@@ -612,6 +612,23 @@ struct drm_psb_private {
};


+/*
+ * Operations for each board type
+ */
+
+struct psb_ops {
+ /* Display management hooks */
+ int (*output_init)(struct drm_device *dev);
+ /* Power management hooks */
+ void (*init_pm)(struct drm_device *dev);
+ int (*save_regs)(struct drm_device *dev);
+ int (*restore_regs)(struct drm_device *dev);
+ int (*power_up)(struct drm_device *dev);
+ int (*power_down)(struct drm_device *dev);
+};
+
+
+
struct psb_mmu_driver;

extern int drm_crtc_probe_output_modes(struct drm_device *dev, int, int);
@@ -761,6 +778,14 @@ extern int psb_gem_dumb_map_gtt(struct drm_file *file, struct drm_device *dev,
uint32_t handle, uint64_t *offset);


extern int psb_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf);

+/* psb_device.c */
+extern const struct psb_ops psb_chip_ops;
+
+/* mrst_device.c */
+extern const struct psb_ops mrst_chip_ops;
+
+/* mdfld_device.c */
+extern const struct psb_ops mdfld_chip_ops;

/*
* Debug print bits setting
diff --git a/drivers/staging/gma500/psb_fb.c b/drivers/staging/gma500/psb_fb.c
index 83095fc..32d9016 100644
--- a/drivers/staging/gma500/psb_fb.c
+++ b/drivers/staging/gma500/psb_fb.c
@@ -725,17 +725,7 @@ static void psb_setup_outputs(struct drm_device *dev)
drm_mode_create_scaling_mode_property(dev);
psb_create_backlight_property(dev);

- if (IS_MRST(dev)) {
- if (dev_priv->iLVDS_enable)
- mrst_lvds_init(dev, &dev_priv->mode_dev);
- else
- dev_err(dev->dev, "DSI is not supported\n");
- } else if (IS_MFLD(dev)) {
- mdfld_output_init(dev);
- } else {
- psb_intel_lvds_init(dev, &dev_priv->mode_dev);
- psb_intel_sdvo_init(dev, SDVOB);
- }
+ dev_priv->ops->output_init(dev);

list_for_each_entry(connector, &dev->mode_config.connector_list,
head) {
diff --git a/drivers/staging/gma500/psb_powermgmt.c b/drivers/staging/gma500/psb_powermgmt.c
deleted file mode 100644
index 2253ecb..0000000
--- a/drivers/staging/gma500/psb_powermgmt.c
+++ /dev/null
@@ -1,1051 +0,0 @@
-/**************************************************************************
- * Copyright (c) 2009-2011, Intel Corporation.
- * All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- *
- * Authors:
- * Benjamin Defnet <benjamin...@intel.com>
- * Rajesh Poornachandran <rajesh.poo...@intel.com>
- * Massively reworked
- * Alan Cox <al...@linux.intel.com>
- */
-#include "psb_powermgmt.h"
-#include "psb_drv.h"
-#include "psb_reg.h"
-#include "psb_intel_reg.h"
-#include "mdfld_output.h"
-#include "mdfld_dsi_output.h"
-#include <linux/mutex.h>
-#include <linux/pm_runtime.h>
-#include <asm/intel_scu_ipc.h>
-
-/* IPC message and command defines used to enable/disable mipi panel voltages */
-#define IPC_MSG_PANEL_ON_OFF 0xE9
-#define IPC_CMD_PANEL_ON 1
-#define IPC_CMD_PANEL_OFF 0
-
-static struct mutex power_mutex;
-
-/**
- * gma_power_init - initialise power manager
- * @dev: our device
- *
- * Set up for power management tracking of our hardware.
- */
-void gma_power_init(struct drm_device *dev)
-{
- struct drm_psb_private *dev_priv = dev->dev_private;
-
- /* FIXME: need to sort out fetching apm_reg for both platforms ?? */
-
- dev_priv->apm_base = dev_priv->apm_reg & 0xffff;
- dev_priv->ospm_base &= 0xffff;
-
- dev_priv->display_power = true; /* We start active */
- dev_priv->display_count = 0; /* Currently no users */
- dev_priv->suspended = false; /* And not suspended */
- mutex_init(&power_mutex);
-
- if (!IS_MRST(dev) && !IS_MFLD(dev)) {
- /* FIXME: wants further review */
- u32 gating = PSB_RSGX32(PSB_CR_CLKGATECTL);
- /* Disable 2D clock gating */
- gating &= ~3;
- gating |= 1;
- PSB_WSGX32(gating, PSB_CR_CLKGATECTL);
- PSB_RSGX32(PSB_CR_CLKGATECTL);
- }
-}
-
-/**
- * gma_power_uninit - end power manager
- * @dev: device to end for
- *
- * Undo the effects of gma_power_init
- */
-void gma_power_uninit(struct drm_device *dev)
-{
- mutex_destroy(&power_mutex);
- pm_runtime_disable(&dev->pdev->dev);
- pm_runtime_set_suspended(&dev->pdev->dev);
-}
-
-
-/**
- * save_display_registers - save registers lost on suspend
- * @dev: our DRM device
- *
- * Save the state we need in order to be able to restore the interface
- * upon resume from suspend
- */
-static int save_display_registers(struct drm_device *dev)
-{
- struct drm_psb_private *dev_priv = dev->dev_private;
- struct drm_crtc *crtc;
- struct drm_connector *connector;
-
- /* Display arbitration control + watermarks */
- dev_priv->saveDSPARB = PSB_RVDC32(DSPARB);
- dev_priv->saveDSPFW1 = PSB_RVDC32(DSPFW1);
- dev_priv->saveDSPFW2 = PSB_RVDC32(DSPFW2);
- dev_priv->saveDSPFW3 = PSB_RVDC32(DSPFW3);
- dev_priv->saveDSPFW4 = PSB_RVDC32(DSPFW4);
- dev_priv->saveDSPFW5 = PSB_RVDC32(DSPFW5);
- dev_priv->saveDSPFW6 = PSB_RVDC32(DSPFW6);
- dev_priv->saveCHICKENBIT = PSB_RVDC32(DSPCHICKENBIT);
-
- /* Save crtc and output state */
- mutex_lock(&dev->mode_config.mutex);
- list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
- if (drm_helper_crtc_in_use(crtc))
- crtc->funcs->save(crtc);
- }
-
- list_for_each_entry(connector, &dev->mode_config.connector_list, head)
- connector->funcs->save(connector);
-
- mutex_unlock(&dev->mode_config.mutex);
- return 0;
-}
-
-/**
- * restore_display_registers - restore lost register state
- * @dev: our DRM device
- *
- * Restore register state that was lost during suspend and resume.
- */
-static int restore_display_registers(struct drm_device *dev)
-{
- struct drm_psb_private *dev_priv = dev->dev_private;
- struct drm_crtc *crtc;
- struct drm_connector *connector;
-
- /* Display arbitration + watermarks */
- PSB_WVDC32(dev_priv->saveDSPARB, DSPARB);
- PSB_WVDC32(dev_priv->saveDSPFW1, DSPFW1);
- PSB_WVDC32(dev_priv->saveDSPFW2, DSPFW2);
- PSB_WVDC32(dev_priv->saveDSPFW3, DSPFW3);
- PSB_WVDC32(dev_priv->saveDSPFW4, DSPFW4);
- PSB_WVDC32(dev_priv->saveDSPFW5, DSPFW5);
- PSB_WVDC32(dev_priv->saveDSPFW6, DSPFW6);
- PSB_WVDC32(dev_priv->saveCHICKENBIT, DSPCHICKENBIT);
-
- /*make sure VGA plane is off. it initializes to on after reset!*/
- PSB_WVDC32(0x80000000, VGACNTRL);
-
- mutex_lock(&dev->mode_config.mutex);
- list_for_each_entry(crtc, &dev->mode_config.crtc_list, head)
- if (drm_helper_crtc_in_use(crtc))
- crtc->funcs->restore(crtc);
-
- list_for_each_entry(connector, &dev->mode_config.connector_list, head)
- connector->funcs->restore(connector);
-
- mutex_unlock(&dev->mode_config.mutex);


- return 0;
-}
-

-/**
- * mdfld_save_display_registers - save registers for pipe
- * @dev: our device
- * @pipe: pipe to save
- *
- * Save the pipe state of the device before we power it off. Keep everything
- * we need to put it back again
- */
-static int mdfld_save_display_registers(struct drm_device *dev, int pipe)
-{
- struct drm_psb_private *dev_priv = dev->dev_private;
- int i;
-
- /* register */
- u32 dpll_reg = MRST_DPLL_A;
- u32 fp_reg = MRST_FPA0;
- u32 pipeconf_reg = PIPEACONF;
- u32 htot_reg = HTOTAL_A;
- u32 hblank_reg = HBLANK_A;
- u32 hsync_reg = HSYNC_A;
- u32 vtot_reg = VTOTAL_A;
- u32 vblank_reg = VBLANK_A;
- u32 vsync_reg = VSYNC_A;
- u32 pipesrc_reg = PIPEASRC;
- u32 dspstride_reg = DSPASTRIDE;
- u32 dsplinoff_reg = DSPALINOFF;
- u32 dsptileoff_reg = DSPATILEOFF;
- u32 dspsize_reg = DSPASIZE;
- u32 dsppos_reg = DSPAPOS;
- u32 dspsurf_reg = DSPASURF;
- u32 mipi_reg = MIPI;
- u32 dspcntr_reg = DSPACNTR;
- u32 dspstatus_reg = PIPEASTAT;
- u32 palette_reg = PALETTE_A;
-
- /* pointer to values */
- u32 *dpll_val = &dev_priv->saveDPLL_A;
- u32 *fp_val = &dev_priv->saveFPA0;
- u32 *pipeconf_val = &dev_priv->savePIPEACONF;
- u32 *htot_val = &dev_priv->saveHTOTAL_A;
- u32 *hblank_val = &dev_priv->saveHBLANK_A;
- u32 *hsync_val = &dev_priv->saveHSYNC_A;
- u32 *vtot_val = &dev_priv->saveVTOTAL_A;
- u32 *vblank_val = &dev_priv->saveVBLANK_A;
- u32 *vsync_val = &dev_priv->saveVSYNC_A;
- u32 *pipesrc_val = &dev_priv->savePIPEASRC;
- u32 *dspstride_val = &dev_priv->saveDSPASTRIDE;
- u32 *dsplinoff_val = &dev_priv->saveDSPALINOFF;
- u32 *dsptileoff_val = &dev_priv->saveDSPATILEOFF;
- u32 *dspsize_val = &dev_priv->saveDSPASIZE;
- u32 *dsppos_val = &dev_priv->saveDSPAPOS;
- u32 *dspsurf_val = &dev_priv->saveDSPASURF;
- u32 *mipi_val = &dev_priv->saveMIPI;
- u32 *dspcntr_val = &dev_priv->saveDSPACNTR;
- u32 *dspstatus_val = &dev_priv->saveDSPASTATUS;
- u32 *palette_val = dev_priv->save_palette_a;
-
- switch (pipe) {
- case 0:
- break;
- case 1:
- /* register */
- dpll_reg = MDFLD_DPLL_B;
- fp_reg = MDFLD_DPLL_DIV0;
- pipeconf_reg = PIPEBCONF;
- htot_reg = HTOTAL_B;
- hblank_reg = HBLANK_B;
- hsync_reg = HSYNC_B;
- vtot_reg = VTOTAL_B;
- vblank_reg = VBLANK_B;
- vsync_reg = VSYNC_B;
- pipesrc_reg = PIPEBSRC;
- dspstride_reg = DSPBSTRIDE;
- dsplinoff_reg = DSPBLINOFF;
- dsptileoff_reg = DSPBTILEOFF;
- dspsize_reg = DSPBSIZE;
- dsppos_reg = DSPBPOS;
- dspsurf_reg = DSPBSURF;
- dspcntr_reg = DSPBCNTR;
- dspstatus_reg = PIPEBSTAT;
- palette_reg = PALETTE_B;
-
- /* values */
- dpll_val = &dev_priv->saveDPLL_B;
- fp_val = &dev_priv->saveFPB0;
- pipeconf_val = &dev_priv->savePIPEBCONF;
- htot_val = &dev_priv->saveHTOTAL_B;
- hblank_val = &dev_priv->saveHBLANK_B;
- hsync_val = &dev_priv->saveHSYNC_B;
- vtot_val = &dev_priv->saveVTOTAL_B;
- vblank_val = &dev_priv->saveVBLANK_B;
- vsync_val = &dev_priv->saveVSYNC_B;
- pipesrc_val = &dev_priv->savePIPEBSRC;
- dspstride_val = &dev_priv->saveDSPBSTRIDE;
- dsplinoff_val = &dev_priv->saveDSPBLINOFF;
- dsptileoff_val = &dev_priv->saveDSPBTILEOFF;
- dspsize_val = &dev_priv->saveDSPBSIZE;
- dsppos_val = &dev_priv->saveDSPBPOS;
- dspsurf_val = &dev_priv->saveDSPBSURF;
- dspcntr_val = &dev_priv->saveDSPBCNTR;
- dspstatus_val = &dev_priv->saveDSPBSTATUS;
- palette_val = dev_priv->save_palette_b;
- break;
- case 2:
- /* register */
- pipeconf_reg = PIPECCONF;
- htot_reg = HTOTAL_C;
- hblank_reg = HBLANK_C;
- hsync_reg = HSYNC_C;
- vtot_reg = VTOTAL_C;
- vblank_reg = VBLANK_C;
- vsync_reg = VSYNC_C;
- pipesrc_reg = PIPECSRC;
- dspstride_reg = DSPCSTRIDE;
- dsplinoff_reg = DSPCLINOFF;
- dsptileoff_reg = DSPCTILEOFF;
- dspsize_reg = DSPCSIZE;
- dsppos_reg = DSPCPOS;
- dspsurf_reg = DSPCSURF;
- mipi_reg = MIPI_C;
- dspcntr_reg = DSPCCNTR;
- dspstatus_reg = PIPECSTAT;
- palette_reg = PALETTE_C;
-
- /* pointer to values */
- pipeconf_val = &dev_priv->savePIPECCONF;
- htot_val = &dev_priv->saveHTOTAL_C;
- hblank_val = &dev_priv->saveHBLANK_C;
- hsync_val = &dev_priv->saveHSYNC_C;
- vtot_val = &dev_priv->saveVTOTAL_C;
- vblank_val = &dev_priv->saveVBLANK_C;
- vsync_val = &dev_priv->saveVSYNC_C;
- pipesrc_val = &dev_priv->savePIPECSRC;
- dspstride_val = &dev_priv->saveDSPCSTRIDE;
- dsplinoff_val = &dev_priv->saveDSPCLINOFF;
- dsptileoff_val = &dev_priv->saveDSPCTILEOFF;
- dspsize_val = &dev_priv->saveDSPCSIZE;
- dsppos_val = &dev_priv->saveDSPCPOS;
- dspsurf_val = &dev_priv->saveDSPCSURF;
- mipi_val = &dev_priv->saveMIPI_C;
- dspcntr_val = &dev_priv->saveDSPCCNTR;
- dspstatus_val = &dev_priv->saveDSPCSTATUS;
- palette_val = dev_priv->save_palette_c;
- break;
- default:
- DRM_ERROR("%s, invalid pipe number.\n", __func__);


- return -EINVAL;
- }
-

- /* Pipe & plane A info */
- *dpll_val = PSB_RVDC32(dpll_reg);
- *fp_val = PSB_RVDC32(fp_reg);
- *pipeconf_val = PSB_RVDC32(pipeconf_reg);
- *htot_val = PSB_RVDC32(htot_reg);
- *hblank_val = PSB_RVDC32(hblank_reg);
- *hsync_val = PSB_RVDC32(hsync_reg);
- *vtot_val = PSB_RVDC32(vtot_reg);
- *vblank_val = PSB_RVDC32(vblank_reg);
- *vsync_val = PSB_RVDC32(vsync_reg);
- *pipesrc_val = PSB_RVDC32(pipesrc_reg);
- *dspstride_val = PSB_RVDC32(dspstride_reg);
- *dsplinoff_val = PSB_RVDC32(dsplinoff_reg);
- *dsptileoff_val = PSB_RVDC32(dsptileoff_reg);
- *dspsize_val = PSB_RVDC32(dspsize_reg);
- *dsppos_val = PSB_RVDC32(dsppos_reg);
- *dspsurf_val = PSB_RVDC32(dspsurf_reg);
- *dspcntr_val = PSB_RVDC32(dspcntr_reg);
- *dspstatus_val = PSB_RVDC32(dspstatus_reg);
-
- /*save palette (gamma) */
- for (i = 0; i < 256; i++)
- palette_val[i] = PSB_RVDC32(palette_reg + (i<<2));
-


- if (pipe == 1) {

- dev_priv->savePFIT_CONTROL = PSB_RVDC32(PFIT_CONTROL);
- dev_priv->savePFIT_PGM_RATIOS = PSB_RVDC32(PFIT_PGM_RATIOS);
- dev_priv->saveHDMIPHYMISCCTL = PSB_RVDC32(HDMIPHYMISCCTL);
- dev_priv->saveHDMIB_CONTROL = PSB_RVDC32(HDMIB_CONTROL);
- return 0;
- }
- *mipi_val = PSB_RVDC32(mipi_reg);


- return 0;
-}
-

-/**
- * mdfld_save_cursor_overlay_registers - save cursor overlay info
- * @dev: our device
- *
- * Save the cursor and overlay register state
- */
-static int mdfld_save_cursor_overlay_registers(struct drm_device *dev)
-{
- struct drm_psb_private *dev_priv = dev->dev_private;
-
- /* Save cursor regs */
- dev_priv->saveDSPACURSOR_CTRL = PSB_RVDC32(CURACNTR);
- dev_priv->saveDSPACURSOR_BASE = PSB_RVDC32(CURABASE);
- dev_priv->saveDSPACURSOR_POS = PSB_RVDC32(CURAPOS);
-
- dev_priv->saveDSPBCURSOR_CTRL = PSB_RVDC32(CURBCNTR);
- dev_priv->saveDSPBCURSOR_BASE = PSB_RVDC32(CURBBASE);
- dev_priv->saveDSPBCURSOR_POS = PSB_RVDC32(CURBPOS);
-
- dev_priv->saveDSPCCURSOR_CTRL = PSB_RVDC32(CURCCNTR);
- dev_priv->saveDSPCCURSOR_BASE = PSB_RVDC32(CURCBASE);
- dev_priv->saveDSPCCURSOR_POS = PSB_RVDC32(CURCPOS);
-
- /* HW overlay */
- dev_priv->saveOV_OVADD = PSB_RVDC32(OV_OVADD);
- dev_priv->saveOV_OGAMC0 = PSB_RVDC32(OV_OGAMC0);
- dev_priv->saveOV_OGAMC1 = PSB_RVDC32(OV_OGAMC1);
- dev_priv->saveOV_OGAMC2 = PSB_RVDC32(OV_OGAMC2);
- dev_priv->saveOV_OGAMC3 = PSB_RVDC32(OV_OGAMC3);
- dev_priv->saveOV_OGAMC4 = PSB_RVDC32(OV_OGAMC4);
- dev_priv->saveOV_OGAMC5 = PSB_RVDC32(OV_OGAMC5);
-
- dev_priv->saveOV_OVADD_C = PSB_RVDC32(OV_OVADD + OV_C_OFFSET);
- dev_priv->saveOV_OGAMC0_C = PSB_RVDC32(OV_OGAMC0 + OV_C_OFFSET);
- dev_priv->saveOV_OGAMC1_C = PSB_RVDC32(OV_OGAMC1 + OV_C_OFFSET);
- dev_priv->saveOV_OGAMC2_C = PSB_RVDC32(OV_OGAMC2 + OV_C_OFFSET);
- dev_priv->saveOV_OGAMC3_C = PSB_RVDC32(OV_OGAMC3 + OV_C_OFFSET);
- dev_priv->saveOV_OGAMC4_C = PSB_RVDC32(OV_OGAMC4 + OV_C_OFFSET);
- dev_priv->saveOV_OGAMC5_C = PSB_RVDC32(OV_OGAMC5 + OV_C_OFFSET);


-
- return 0;
-}

-/*
- * mdfld_restore_display_registers - restore the state of a pipe
- * @dev: our device
- * @pipe: the pipe to restore
- *
- * Restore the state of a pipe to that which was saved by the register save
- * functions.
- */
-static int mdfld_restore_display_registers(struct drm_device *dev, int pipe)
-{
- /* To get panel out of ULPS mode */
- struct drm_psb_private *dev_priv = dev->dev_private;
- struct mdfld_dsi_config *dsi_config = NULL;
- u32 i = 0;
- u32 dpll = 0;
- u32 timeout = 0;
- u32 reg_offset = 0;
-
- /* register */
- u32 dpll_reg = MRST_DPLL_A;
- u32 fp_reg = MRST_FPA0;
- u32 pipeconf_reg = PIPEACONF;
- u32 htot_reg = HTOTAL_A;
- u32 hblank_reg = HBLANK_A;
- u32 hsync_reg = HSYNC_A;
- u32 vtot_reg = VTOTAL_A;
- u32 vblank_reg = VBLANK_A;
- u32 vsync_reg = VSYNC_A;
- u32 pipesrc_reg = PIPEASRC;
- u32 dspstride_reg = DSPASTRIDE;
- u32 dsplinoff_reg = DSPALINOFF;
- u32 dsptileoff_reg = DSPATILEOFF;
- u32 dspsize_reg = DSPASIZE;
- u32 dsppos_reg = DSPAPOS;
- u32 dspsurf_reg = DSPASURF;
- u32 dspstatus_reg = PIPEASTAT;
- u32 mipi_reg = MIPI;
- u32 dspcntr_reg = DSPACNTR;
- u32 palette_reg = PALETTE_A;
-
- /* values */
- u32 dpll_val = dev_priv->saveDPLL_A & ~DPLL_VCO_ENABLE;
- u32 fp_val = dev_priv->saveFPA0;
- u32 pipeconf_val = dev_priv->savePIPEACONF;
- u32 htot_val = dev_priv->saveHTOTAL_A;
- u32 hblank_val = dev_priv->saveHBLANK_A;
- u32 hsync_val = dev_priv->saveHSYNC_A;
- u32 vtot_val = dev_priv->saveVTOTAL_A;
- u32 vblank_val = dev_priv->saveVBLANK_A;
- u32 vsync_val = dev_priv->saveVSYNC_A;
- u32 pipesrc_val = dev_priv->savePIPEASRC;
- u32 dspstride_val = dev_priv->saveDSPASTRIDE;
- u32 dsplinoff_val = dev_priv->saveDSPALINOFF;
- u32 dsptileoff_val = dev_priv->saveDSPATILEOFF;
- u32 dspsize_val = dev_priv->saveDSPASIZE;
- u32 dsppos_val = dev_priv->saveDSPAPOS;
- u32 dspsurf_val = dev_priv->saveDSPASURF;
- u32 dspstatus_val = dev_priv->saveDSPASTATUS;
- u32 mipi_val = dev_priv->saveMIPI;
- u32 dspcntr_val = dev_priv->saveDSPACNTR;
- u32 *palette_val = dev_priv->save_palette_a;
-
- switch (pipe) {
- case 0:
- dsi_config = dev_priv->dsi_configs[0];
- break;
- case 1:
- /* register */
- dpll_reg = MDFLD_DPLL_B;
- fp_reg = MDFLD_DPLL_DIV0;
- pipeconf_reg = PIPEBCONF;
- htot_reg = HTOTAL_B;
- hblank_reg = HBLANK_B;
- hsync_reg = HSYNC_B;
- vtot_reg = VTOTAL_B;
- vblank_reg = VBLANK_B;
- vsync_reg = VSYNC_B;
- pipesrc_reg = PIPEBSRC;
- dspstride_reg = DSPBSTRIDE;
- dsplinoff_reg = DSPBLINOFF;
- dsptileoff_reg = DSPBTILEOFF;
- dspsize_reg = DSPBSIZE;
- dsppos_reg = DSPBPOS;
- dspsurf_reg = DSPBSURF;
- dspcntr_reg = DSPBCNTR;
- palette_reg = PALETTE_B;
- dspstatus_reg = PIPEBSTAT;
-
- /* values */
- dpll_val = dev_priv->saveDPLL_B & ~DPLL_VCO_ENABLE;
- fp_val = dev_priv->saveFPB0;
- pipeconf_val = dev_priv->savePIPEBCONF;
- htot_val = dev_priv->saveHTOTAL_B;
- hblank_val = dev_priv->saveHBLANK_B;
- hsync_val = dev_priv->saveHSYNC_B;
- vtot_val = dev_priv->saveVTOTAL_B;
- vblank_val = dev_priv->saveVBLANK_B;
- vsync_val = dev_priv->saveVSYNC_B;
- pipesrc_val = dev_priv->savePIPEBSRC;
- dspstride_val = dev_priv->saveDSPBSTRIDE;
- dsplinoff_val = dev_priv->saveDSPBLINOFF;
- dsptileoff_val = dev_priv->saveDSPBTILEOFF;
- dspsize_val = dev_priv->saveDSPBSIZE;
- dsppos_val = dev_priv->saveDSPBPOS;
- dspsurf_val = dev_priv->saveDSPBSURF;
- dspcntr_val = dev_priv->saveDSPBCNTR;
- dspstatus_val = dev_priv->saveDSPBSTATUS;
- palette_val = dev_priv->save_palette_b;
- break;
- case 2:
- reg_offset = MIPIC_REG_OFFSET;
-
- /* register */
- pipeconf_reg = PIPECCONF;
- htot_reg = HTOTAL_C;
- hblank_reg = HBLANK_C;
- hsync_reg = HSYNC_C;
- vtot_reg = VTOTAL_C;
- vblank_reg = VBLANK_C;
- vsync_reg = VSYNC_C;
- pipesrc_reg = PIPECSRC;
- dspstride_reg = DSPCSTRIDE;
- dsplinoff_reg = DSPCLINOFF;
- dsptileoff_reg = DSPCTILEOFF;
- dspsize_reg = DSPCSIZE;
- dsppos_reg = DSPCPOS;
- dspsurf_reg = DSPCSURF;
- mipi_reg = MIPI_C;
- dspcntr_reg = DSPCCNTR;
- palette_reg = PALETTE_C;
- dspstatus_reg = PIPECSTAT;
-
- /* values */
- pipeconf_val = dev_priv->savePIPECCONF;
- htot_val = dev_priv->saveHTOTAL_C;
- hblank_val = dev_priv->saveHBLANK_C;
- hsync_val = dev_priv->saveHSYNC_C;
- vtot_val = dev_priv->saveVTOTAL_C;
- vblank_val = dev_priv->saveVBLANK_C;
- vsync_val = dev_priv->saveVSYNC_C;
- pipesrc_val = dev_priv->savePIPECSRC;
- dspstride_val = dev_priv->saveDSPCSTRIDE;
- dsplinoff_val = dev_priv->saveDSPCLINOFF;
- dsptileoff_val = dev_priv->saveDSPCTILEOFF;
- dspsize_val = dev_priv->saveDSPCSIZE;
- dsppos_val = dev_priv->saveDSPCPOS;
- dspsurf_val = dev_priv->saveDSPCSURF;
- dspstatus_val = dev_priv->saveDSPCSTATUS;
- mipi_val = dev_priv->saveMIPI_C;
- dspcntr_val = dev_priv->saveDSPCCNTR;
- palette_val = dev_priv->save_palette_c;
-
- dsi_config = dev_priv->dsi_configs[1];
- break;
- default:
- DRM_ERROR("%s, invalid pipe number.\n", __func__);


- return -EINVAL;
- }
-

- /* Make sure VGA plane is off. it initializes to on after reset!*/
- PSB_WVDC32(0x80000000, VGACNTRL);


- if (pipe == 1) {

- PSB_WVDC32(dpll_val & ~DPLL_VCO_ENABLE, dpll_reg);
- PSB_RVDC32(dpll_reg);
-
- PSB_WVDC32(fp_val, fp_reg);
- } else {
- dpll = PSB_RVDC32(dpll_reg);
-
- if (!(dpll & DPLL_VCO_ENABLE)) {
-
- /* When ungating power of DPLL, needs to wait 0.5us before enable the VCO */
- if (dpll & MDFLD_PWR_GATE_EN) {
- dpll &= ~MDFLD_PWR_GATE_EN;
- PSB_WVDC32(dpll, dpll_reg);
- udelay(500); /* FIXME: 1 ? */
- }
-
- PSB_WVDC32(fp_val, fp_reg);
- PSB_WVDC32(dpll_val, dpll_reg);
- /* FIXME_MDFLD PO - change 500 to 1 after PO */
- udelay(500);
-
- dpll_val |= DPLL_VCO_ENABLE;
- PSB_WVDC32(dpll_val, dpll_reg);
- PSB_RVDC32(dpll_reg);
-
- /* wait for DSI PLL to lock */
- while ((timeout < 20000) && !(PSB_RVDC32(pipeconf_reg) & PIPECONF_DSIPLL_LOCK)) {
- udelay(150);
- timeout++;
- }
-
- if (timeout == 20000) {
- DRM_ERROR("%s, can't lock DSIPLL.\n",
- __func__);


- return -EINVAL;
- }
- }

- }
- /* Restore mode */
- PSB_WVDC32(htot_val, htot_reg);
- PSB_WVDC32(hblank_val, hblank_reg);
- PSB_WVDC32(hsync_val, hsync_reg);
- PSB_WVDC32(vtot_val, vtot_reg);
- PSB_WVDC32(vblank_val, vblank_reg);
- PSB_WVDC32(vsync_val, vsync_reg);
- PSB_WVDC32(pipesrc_val, pipesrc_reg);
- PSB_WVDC32(dspstatus_val, dspstatus_reg);
-
- /* Set up the plane */
- PSB_WVDC32(dspstride_val, dspstride_reg);
- PSB_WVDC32(dsplinoff_val, dsplinoff_reg);
- PSB_WVDC32(dsptileoff_val, dsptileoff_reg);
- PSB_WVDC32(dspsize_val, dspsize_reg);
- PSB_WVDC32(dsppos_val, dsppos_reg);
- PSB_WVDC32(dspsurf_val, dspsurf_reg);
-


- if (pipe == 1) {

- PSB_WVDC32(dev_priv->savePFIT_CONTROL, PFIT_CONTROL);
- PSB_WVDC32(dev_priv->savePFIT_PGM_RATIOS, PFIT_PGM_RATIOS);
- PSB_WVDC32(dev_priv->saveHDMIPHYMISCCTL, HDMIPHYMISCCTL);
- PSB_WVDC32(dev_priv->saveHDMIB_CONTROL, HDMIB_CONTROL);
-
- } else {
- /* Set up pipe related registers */
- PSB_WVDC32(mipi_val, mipi_reg);
- /* Setup MIPI adapter + MIPI IP registers */
- mdfld_dsi_controller_init(dsi_config, pipe);
- msleep(20);
- }
- /* Enable the plane */
- PSB_WVDC32(dspcntr_val, dspcntr_reg);
- msleep(20);
- /* Enable the pipe */
- PSB_WVDC32(pipeconf_val, pipeconf_reg);
-
- for (i = 0; i < 256; i++)
- PSB_WVDC32(palette_val[i], palette_reg + (i<<2));


- if (pipe == 1)

- return 0;
- if (IS_MFLD(dev) && !mdfld_panel_dpi(dev))
- mdfld_enable_te(dev, pipe);


- return 0;
-}
-

-/**
- * mdfld_restore_cursor_overlay_registers - restore cursor
- * @dev: our device
- *
- * Restore the cursor and overlay state that was saved earlier
- */
-static int mdfld_restore_cursor_overlay_registers(struct drm_device *dev)
-{
- struct drm_psb_private *dev_priv = dev->dev_private;
-
- /* Enable Cursor A */
- PSB_WVDC32(dev_priv->saveDSPACURSOR_CTRL, CURACNTR);
- PSB_WVDC32(dev_priv->saveDSPACURSOR_POS, CURAPOS);
- PSB_WVDC32(dev_priv->saveDSPACURSOR_BASE, CURABASE);
-
- PSB_WVDC32(dev_priv->saveDSPBCURSOR_CTRL, CURBCNTR);
- PSB_WVDC32(dev_priv->saveDSPBCURSOR_POS, CURBPOS);
- PSB_WVDC32(dev_priv->saveDSPBCURSOR_BASE, CURBBASE);
-
- PSB_WVDC32(dev_priv->saveDSPCCURSOR_CTRL, CURCCNTR);
- PSB_WVDC32(dev_priv->saveDSPCCURSOR_POS, CURCPOS);
- PSB_WVDC32(dev_priv->saveDSPCCURSOR_BASE, CURCBASE);
-
- /* Restore HW overlay */
- PSB_WVDC32(dev_priv->saveOV_OVADD, OV_OVADD);
- PSB_WVDC32(dev_priv->saveOV_OGAMC0, OV_OGAMC0);
- PSB_WVDC32(dev_priv->saveOV_OGAMC1, OV_OGAMC1);
- PSB_WVDC32(dev_priv->saveOV_OGAMC2, OV_OGAMC2);
- PSB_WVDC32(dev_priv->saveOV_OGAMC3, OV_OGAMC3);
- PSB_WVDC32(dev_priv->saveOV_OGAMC4, OV_OGAMC4);
- PSB_WVDC32(dev_priv->saveOV_OGAMC5, OV_OGAMC5);
-
- PSB_WVDC32(dev_priv->saveOV_OVADD_C, OV_OVADD + OV_C_OFFSET);
- PSB_WVDC32(dev_priv->saveOV_OGAMC0_C, OV_OGAMC0 + OV_C_OFFSET);
- PSB_WVDC32(dev_priv->saveOV_OGAMC1_C, OV_OGAMC1 + OV_C_OFFSET);
- PSB_WVDC32(dev_priv->saveOV_OGAMC2_C, OV_OGAMC2 + OV_C_OFFSET);
- PSB_WVDC32(dev_priv->saveOV_OGAMC3_C, OV_OGAMC3 + OV_C_OFFSET);
- PSB_WVDC32(dev_priv->saveOV_OGAMC4_C, OV_OGAMC4 + OV_C_OFFSET);
- PSB_WVDC32(dev_priv->saveOV_OGAMC5_C, OV_OGAMC5 + OV_C_OFFSET);


-
- return 0;
-}
-

-/**
- * power_down - power down the display island
- * @dev: our DRM device
- *
- * Power down the display interface of our device
- */
-static void power_down(struct drm_device *dev)
-{
- struct drm_psb_private *dev_priv = dev->dev_private;
- u32 pwr_mask ;
- u32 pwr_sts;
-
- if (IS_MRST(dev)) {
- pwr_mask = PSB_PWRGT_DISPLAY_MASK;
- outl(pwr_mask, dev_priv->ospm_base + PSB_PM_SSC);
-
- while (true) {
- pwr_sts = inl(dev_priv->ospm_base + PSB_PM_SSS);
- if ((pwr_sts & pwr_mask) == pwr_mask)
- break;
- else
- udelay(10);
- }
- dev_priv->display_power = false;
- }
-}
-
-
-/**
- * gma_suspend_display - suspend the display logic
- * @dev: our DRM device
- *
- * Suspend the display logic of the graphics interface
- *
- * FIXME: This ought to be replaced by a dev_priv-> ops interface
- * where the various platforms register their save/restore methods
- * and keep them in their own support files.
- */
-static void gma_suspend_display(struct drm_device *dev)
-{
- struct drm_psb_private *dev_priv = dev->dev_private;
- int pp_stat;
-
- if (dev_priv->suspended)
- return;
-
- if (IS_MFLD(dev)) {
- /* FIXME: We need to shut down panels here if using them
- and once the right bits are merged */
- mdfld_save_cursor_overlay_registers(dev);
- mdfld_save_display_registers(dev, 0);
- mdfld_save_display_registers(dev, 0);
- mdfld_save_display_registers(dev, 2);
- mdfld_save_display_registers(dev, 1);
- mdfld_disable_crtc(dev, 0);
- mdfld_disable_crtc(dev, 2);
- mdfld_disable_crtc(dev, 1);
- } else {


- save_display_registers(dev);
-
- 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);
- /* Turn off panel power */
-#ifdef CONFIG_X86_MRST
- intel_scu_ipc_simple_command(IPC_MSG_PANEL_ON_OFF,
- IPC_CMD_PANEL_OFF);
-#endif
- }
- }
- power_down(dev);
-}
-
-/*
- * power_up
- *
- * Description: Restore power to the specified island(s) (powergating)
- */
-static void power_up(struct drm_device *dev)
-{
- struct drm_psb_private *dev_priv = dev->dev_private;
- u32 pwr_mask = PSB_PWRGT_DISPLAY_MASK;
- u32 pwr_sts, pwr_cnt;
-
- if (IS_MRST(dev)) {
- pwr_cnt = inl(dev_priv->ospm_base + PSB_PM_SSC);
- pwr_cnt &= ~pwr_mask;
- outl(pwr_cnt, (dev_priv->ospm_base + PSB_PM_SSC));
-
- while (true) {
- pwr_sts = inl(dev_priv->ospm_base + PSB_PM_SSS);
- if ((pwr_sts & pwr_mask) == 0)
- break;
- else
- udelay(10);
- }
- }
- dev_priv->suspended = false;
- dev_priv->display_power = true;
-}
-
-/**
- * gma_resume_display - resume display side logic
- *
- * Resume the display hardware restoring state and enabling
- * as necessary.
- */
-static void gma_resume_display(struct pci_dev *pdev)
-{
- struct drm_device *dev = pci_get_drvdata(pdev);
- struct drm_psb_private *dev_priv = dev->dev_private;
-
- if (dev_priv->suspended == false)
- return;
-
- /* turn on the display power island */
- power_up(dev);
-
- PSB_WVDC32(dev_priv->pge_ctl | _PSB_PGETBL_ENABLED, PSB_PGETBL_CTL);
- pci_write_config_word(pdev, PSB_GMCH_CTRL,
- dev_priv->gmch_ctrl | _PSB_GMCH_ENABLED);
-
- /* Don't reinitialize the GTT as it is unnecessary. The gtt is
- * stored in memory so it will automatically be restored. All
- * we need to do is restore the PGETBL_CTL which we already do
- * above.
- */
- /*psb_gtt_init(dev_priv->pg, 1);*/
- if (IS_MFLD(dev)) {
- mdfld_restore_display_registers(dev, 1);
- mdfld_restore_display_registers(dev, 0);
- mdfld_restore_display_registers(dev, 2);
- mdfld_restore_cursor_overlay_registers(dev);
- } else if (IS_MRST(dev)) {
- if (!dev_priv->iLVDS_enable) {
-#ifdef CONFIG_X86_MRST
- intel_scu_ipc_simple_command(IPC_MSG_PANEL_ON_OFF,
- IPC_CMD_PANEL_ON);
- /* FIXME: can we avoid this delay ? */
- msleep(2000); /* wait 2 seconds */
-#endif
- }
- }
- restore_display_registers(dev);
-}
-
-/**
- * gma_suspend_pci - suspend PCI side
- * @pdev: PCI device
- *
- * Perform the suspend processing on our PCI device state
- */
-static void gma_suspend_pci(struct pci_dev *pdev)
-{
- struct drm_device *dev = pci_get_drvdata(pdev);
- struct drm_psb_private *dev_priv = dev->dev_private;
- int bsm, vbt;
-
- if (dev_priv->suspended)
- return;
-
- pci_save_state(pdev);
- pci_read_config_dword(pdev, 0x5C, &bsm);
- dev_priv->saveBSM = bsm;
- pci_read_config_dword(pdev, 0xFC, &vbt);
- dev_priv->saveVBT = vbt;
- pci_read_config_dword(pdev, PSB_PCIx_MSI_ADDR_LOC, &dev_priv->msi_addr);
- pci_read_config_dword(pdev, PSB_PCIx_MSI_DATA_LOC, &dev_priv->msi_data);
-
- pci_disable_device(pdev);
- pci_set_power_state(pdev, PCI_D3hot);
-
- dev_priv->suspended = true;
-}
-
-/**
- * gma_resume_pci - resume helper
- * @dev: our PCI device
- *
- * Perform the resume processing on our PCI device state - rewrite
- * register state and re-enable the PCI device
- */
-static bool gma_resume_pci(struct pci_dev *pdev)
-{
- struct drm_device *dev = pci_get_drvdata(pdev);
- struct drm_psb_private *dev_priv = dev->dev_private;
- int ret;
-
- if (!dev_priv->suspended)
- return true;
-
- pci_set_power_state(pdev, PCI_D0);
- pci_restore_state(pdev);
- pci_write_config_dword(pdev, 0x5c, dev_priv->saveBSM);
- pci_write_config_dword(pdev, 0xFC, dev_priv->saveVBT);
- /* retoring MSI address and data in PCIx space */
- pci_write_config_dword(pdev, PSB_PCIx_MSI_ADDR_LOC, dev_priv->msi_addr);
- pci_write_config_dword(pdev, PSB_PCIx_MSI_DATA_LOC, dev_priv->msi_data);
- ret = pci_enable_device(pdev);
-
- if (ret != 0)
- dev_err(&pdev->dev, "pci_enable failed: %d\n", ret);
- else
- dev_priv->suspended = false;
- return !dev_priv->suspended;
-}
-
-/**
- * gma_power_suspend - bus callback for suspend
- * @pdev: our PCI device
- * @state: suspend type
- *
- * Called back by the PCI layer during a suspend of the system. We
- * perform the necessary shut down steps and save enough state that
- * we can undo this when resume is called.
- */
-int gma_power_suspend(struct pci_dev *pdev, pm_message_t state)
-{
- struct drm_device *dev = pci_get_drvdata(pdev);
- struct drm_psb_private *dev_priv = dev->dev_private;
-
- mutex_lock(&power_mutex);
- if (!dev_priv->suspended) {
- if (dev_priv->display_count) {
- mutex_unlock(&power_mutex);
- return -EBUSY;
- }
- psb_irq_uninstall(dev);
- gma_suspend_display(dev);
- gma_suspend_pci(pdev);
- }
- mutex_unlock(&power_mutex);
- return 0;
-}
-
-
-/**
- * gma_power_resume - resume power
- * @pdev: PCI device
- *
- * Resume the PCI side of the graphics and then the displays
- */
-int gma_power_resume(struct pci_dev *pdev)
-{
- struct drm_device *dev = pci_get_drvdata(pdev);
-
- mutex_lock(&power_mutex);
- gma_resume_pci(pdev);
- gma_resume_display(pdev);
- psb_irq_preinstall(dev);
- psb_irq_postinstall(dev);
- mutex_unlock(&power_mutex);


- return 0;
-}
-

-
-
-/**
- * gma_power_is_on - returne true if power is on
- * @dev: our DRM device
- *
- * Returns true if the display island power is on at this moment
- */
-bool gma_power_is_on(struct drm_device *dev)
-{
- struct drm_psb_private *dev_priv = dev->dev_private;
- return dev_priv->display_power;
-}
-
-
-/**
- * gma_power_begin - begin requiring power
- * @dev: our DRM device
- * @force_on: true to force power on
- *
- * Begin an action that requires the display power island is enabled.
- * We refcount the islands.
- *
- * FIXME: locking
- */
-bool gma_power_begin(struct drm_device *dev, bool force_on)
-{
- struct drm_psb_private *dev_priv = dev->dev_private;
- int ret;
-
- /* Power already on ? */
- if (dev_priv->display_power) {
- dev_priv->display_count++;
- pm_runtime_get(&dev->pdev->dev);
- return true;
- }
- if (force_on == false)
- return false;
-
- /* Ok power up needed */
- ret = gma_resume_pci(dev->pdev);
- if (ret == 0) {
- psb_irq_preinstall(dev);
- psb_irq_postinstall(dev);
- pm_runtime_get(&dev->pdev->dev);
- dev_priv->display_count++;
- return true;
- }
- return false;
-}
-
-
-/**
- * gma_power_end - end use of power
- * @dev: Our DRM device
- *
- * Indicate that one of our gma_power_begin() requested periods when
- * the diplay island power is needed has completed.
- */
-void gma_power_end(struct drm_device *dev)
-{
- struct drm_psb_private *dev_priv = dev->dev_private;
- dev_priv->display_count--;
- WARN_ON(dev_priv->display_count < 0);
- pm_runtime_put(&dev->pdev->dev);
-}
-
-int psb_runtime_suspend(struct device *dev)
-{
- static pm_message_t dummy;
- return gma_power_suspend(to_pci_dev(dev), dummy);
-}
-
-int psb_runtime_resume(struct device *dev)


-{
- return 0;
-}
-

-int psb_runtime_idle(struct device *dev)
-{
- struct drm_device *drmdev = pci_get_drvdata(to_pci_dev(dev));
- struct drm_psb_private *dev_priv = drmdev->dev_private;
- if (dev_priv->display_count)
- return 0;
- else
- return 1;
-}
-

Alan Cox

unread,
Jun 16, 2011, 12:42:31 PM6/16/11
to gr...@kroah.com, linux-...@vger.kernel.org
From: Alan Cox <al...@linux.intel.com>

We need to initialise the DBI interface and the code for it got missed in
the original merge as it's in a daft place. This will need moving but lets
get it added first.

Signed-off-by: Alan Cox <al...@linux.intel.com>
---

drivers/staging/gma500/psb_drv.c | 12 ++++++++++++
1 files changed, 12 insertions(+), 0 deletions(-)

diff --git a/drivers/staging/gma500/psb_drv.c b/drivers/staging/gma500/psb_drv.c
index bb6b68f..dfb3f3a 100644
--- a/drivers/staging/gma500/psb_drv.c
+++ b/drivers/staging/gma500/psb_drv.c
@@ -28,6 +28,7 @@
#include "psb_intel_reg.h"
#include "psb_intel_bios.h"
#include "mrst_bios.h"
+#include "mdfld_dsi_dbi.h"
#include <drm/drm_pciids.h>
#include "psb_powermgmt.h"
#include <linux/cpu.h>
@@ -442,6 +443,17 @@ static int psb_driver_load(struct drm_device *dev, unsigned long chipset)

dev->driver->get_vblank_counter = psb_get_vblank_counter;

+ /* FIXME: this is not the right place for this stuff ! */
+ if (IS_MFLD(dev)) {
+#ifdef CONFIG_MDFLD_DSI_DPU
+ /*init dpu info*/
+ mdfld_dbi_dpu_init(dev);
+#else
+ mdfld_dbi_dsr_init(dev);
+#endif /*CONFIG_MDFLD_DSI_DPU*/
+ /* INIT_WORK(&dev_priv->te_work, mdfld_te_handler_work);*/
+ }
+
if (drm_psb_no_fb == 0) {
psb_modeset_init(dev);
psb_fbdev_init(dev);

Alan Cox

unread,
Jun 16, 2011, 12:42:19 PM6/16/11
to gr...@kroah.com, linux-...@vger.kernel.org
From: Alan Cox <al...@linux.intel.com>

Next obvious target - backlight support

Signed-off-by: Alan Cox <al...@linux.intel.com>
---

drivers/staging/gma500/Makefile | 2
drivers/staging/gma500/backlight.c | 46 +++++
drivers/staging/gma500/mdfld_device.c | 94 ++++++++++
drivers/staging/gma500/mdfld_dsi_output.c | 11 +
drivers/staging/gma500/mrst_device.c | 137 ++++++++++++++
drivers/staging/gma500/psb_bl.c | 283 -----------------------------
drivers/staging/gma500/psb_device.c | 125 +++++++++++++
drivers/staging/gma500/psb_drv.c | 20 +-
drivers/staging/gma500/psb_drv.h | 15 +-
drivers/staging/gma500/psb_intel_lvds.c | 31 ++-
10 files changed, 445 insertions(+), 319 deletions(-)
create mode 100644 drivers/staging/gma500/backlight.c
delete mode 100644 drivers/staging/gma500/psb_bl.c

diff --git a/drivers/staging/gma500/Makefile b/drivers/staging/gma500/Makefile
index e93cbe3..dc02b2f 100644
--- a/drivers/staging/gma500/Makefile
+++ b/drivers/staging/gma500/Makefile
@@ -4,8 +4,8 @@


ccflags-y += -Iinclude/drm

psb_gfx-y += gem_glue.o \

+ backlight.o \
power.o \
- psb_bl.o \
psb_drv.o \
psb_gem.o \
psb_fb.o \
diff --git a/drivers/staging/gma500/backlight.c b/drivers/staging/gma500/backlight.c
new file mode 100644
index 0000000..47681c9
--- /dev/null
+++ b/drivers/staging/gma500/backlight.c
@@ -0,0 +1,46 @@
+/*


+ * GMA500 Backlight Interface

+ *


+ * Copyright (c) 2009-2011, Intel Corporation.
+ *

+ * 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.
+ *

+ * Authors: Eric Knopp
+ *
+ */
+
+#include "psb_drv.h"
+#include "psb_intel_reg.h"
+#include "psb_intel_drv.h"
+#include "psb_intel_bios.h"
+#include "psb_powermgmt.h"
+
+int gma_backlight_init(struct drm_device *dev)
+{
+#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE


+ struct drm_psb_private *dev_priv = dev->dev_private;

+ return dev_priv->ops->backlight_init(dev);
+#endif
+}
+
+void gma_backlight_exit(struct drm_device *dev)
+{
+#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE


+ struct drm_psb_private *dev_priv = dev->dev_private;

+ dev_priv->backlight_device->props.brightness = 0;
+ backlight_update_status(dev_priv->backlight_device);
+ if (dev_priv->backlight_device)
+ backlight_device_unregister(dev_priv->backlight_device);
+#endif
+}
diff --git a/drivers/staging/gma500/mdfld_device.c b/drivers/staging/gma500/mdfld_device.c
index 7caa7cd..e86e476 100644
--- a/drivers/staging/gma500/mdfld_device.c
+++ b/drivers/staging/gma500/mdfld_device.c
@@ -17,6 +17,7 @@
*
**************************************************************************/

+#include <linux/backlight.h>
#include <drm/drmP.h>
#include <drm/drm.h>
#include "psb_reg.h"
@@ -27,7 +28,93 @@
#include "mdfld_dsi_output.h"

/*
- * Provide the Medfield specific chip logic and low level methods
+ * Provide the Medfield specific backlight management
+ */
+
+#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE
+
+static int mdfld_brightness;
+struct backlight_device *mdfld_backlight_device;
+
+static int mfld_set_brightness(struct backlight_device *bd)
+{
+ struct drm_device *dev = bl_get_data(mdfld_backlight_device);


+ struct drm_psb_private *dev_priv = dev->dev_private;

+ int level = bd->props.brightness;
+

+ /* Percentage 1-100% being valid */
+ if (level < 1)
+ level = 1;
+
+ if (gma_power_begin(dev, 0)) {
+ /* Calculate and set the brightness value */
+ u32 adjusted_level;
+
+ /* Adjust the backlight level with the percent in
+ * dev_priv->blc_adj2;
+ */
+ adjusted_level = level * dev_priv->blc_adj2;

+ adjusted_level = adjusted_level / 100;


+#if 0
+#ifndef CONFIG_MDFLD_DSI_DPU
+ if(!(dev_priv->dsr_fb_update & MDFLD_DSR_MIPI_CONTROL) &&
+ (dev_priv->dbi_panel_on || dev_priv->dbi_panel_on2)){
+ mdfld_dsi_dbi_exit_dsr(dev,MDFLD_DSR_MIPI_CONTROL, 0, 0);
+ dev_dbg(dev->dev, "Out of DSR before set brightness to %d.\n",adjusted_level);
+ }
+#endif
+ mdfld_dsi_brightness_control(dev, 0, adjusted_level);
+
+ if ((dev_priv->dbi_panel_on2) || (dev_priv->dpi_panel_on2))
+ mdfld_dsi_brightness_control(dev, 2, adjusted_level);
+#endif
+ gma_power_end(dev);
+ }

+ mdfld_brightness = level;


+ return 0;
+}
+

+int psb_get_brightness(struct backlight_device *bd)
+{
+ /* return locally cached var instead of HW read (due to DPST etc.) */
+ /* FIXME: ideally return actual value in case firmware fiddled with
+ it */
+ return mdfld_brightness;


+}
+
+static const struct backlight_ops mfld_ops = {
+ .get_brightness = psb_get_brightness,
+ .update_status = mfld_set_brightness,
+};
+

+static int mdfld_backlight_init(struct drm_device *dev)


+{
+ struct drm_psb_private *dev_priv = dev->dev_private;

+ struct backlight_properties props;
+ memset(&props, 0, sizeof(struct backlight_properties));
+ props.max_brightness = 100;
+ props.type = BACKLIGHT_PLATFORM;
+
+ mdfld_backlight_device = backlight_device_register("mfld-bl",


+ NULL, (void *)dev, &mfld_ops, &props);
+

+ if (IS_ERR(mdfld_backlight_device))
+ return PTR_ERR(mdfld_backlight_device);
+
+ dev_priv->blc_adj1 = 100;
+ dev_priv->blc_adj2 = 100;
+ mdfld_backlight_device->props.brightness = 100;
+ mdfld_backlight_device->props.max_brightness = 100;
+ backlight_update_status(mdfld_backlight_device);
+ dev_priv->backlight_device = mdfld_backlight_device;


+ return 0;
+}
+

+#endif
+
+/*
+ * Provide the Medfield specific chip logic and low level methods for
+ * power management.
*/

static void mdfld_init_pm(struct drm_device *dev)
@@ -601,6 +688,11 @@ static int mdfld_power_up(struct drm_device *dev)

const struct psb_ops mdfld_chip_ops = {
.output_init = mdfld_output_init,
+
+#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE
+ .backlight_init = mdfld_backlight_init,
+#endif
+
.init_pm = mdfld_init_pm,
.save_regs = mdfld_save_registers,
.restore_regs = mdfld_restore_registers,
diff --git a/drivers/staging/gma500/mdfld_dsi_output.c b/drivers/staging/gma500/mdfld_dsi_output.c
index 44ee3f6..b88dfc2 100644
--- a/drivers/staging/gma500/mdfld_dsi_output.c
+++ b/drivers/staging/gma500/mdfld_dsi_output.c
@@ -468,6 +468,7 @@ static int mdfld_dsi_connector_set_property(struct drm_connector * connector,
{


struct drm_encoder * encoder = connector->encoder;

struct backlight_device * psb_bd;
+ struct drm_psb_private * dev_priv = encoder->dev->dev_private;



if (!strcmp(property->name, "scaling mode") && encoder) {

struct psb_intel_crtc * psb_crtc = to_psb_intel_crtc(encoder->crtc);

@@ -512,6 +513,7 @@ static int mdfld_dsi_connector_set_property(struct drm_connector * connector,
&psb_crtc->saved_adjusted_mode);
}
}
+#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE


} else if (!strcmp(property->name, "backlight") && encoder) {

dev_dbg(encoder->dev->dev, "backlight level = %d\n", (int)value);

if (drm_connector_property_set_value(connector, property, value))
@@ -519,20 +521,21 @@ static int mdfld_dsi_connector_set_property(struct drm_connector * connector,
else {
dev_dbg(encoder->dev->dev,


"set brightness to %d", (int)value);

- psb_bd = psb_get_backlight_device();
- if(psb_bd) {
+ psb_bd = dev_priv->backlight_device;
+ if (psb_bd) {
psb_bd->props.brightness = value;
- psb_set_brightness(psb_bd);
+ backlight_update_status(psb_bd);
}
}
}
+#endif
set_prop_done:
return 0;
set_prop_error:
return -1;
}

-static void mdfld_dsi_connector_destroy(struct drm_connector * connector)
+static void mdfld_dsi_connector_destroy(struct drm_connector *connector)
{


struct psb_intel_output * psb_output = to_psb_intel_output(connector);

struct mdfld_dsi_connector * dsi_connector = MDFLD_DSI_CONNECTOR(psb_output);

diff --git a/drivers/staging/gma500/mrst_device.c b/drivers/staging/gma500/mrst_device.c
index 5cd8283..daeeb18 100644
--- a/drivers/staging/gma500/mrst_device.c
+++ b/drivers/staging/gma500/mrst_device.c
@@ -17,6 +17,7 @@
*
**************************************************************************/

+#include <linux/backlight.h>
#include <drm/drmP.h>
#include <drm/drm.h>
#include "psb_drm.h"
@@ -42,7 +43,138 @@ static int mrst_output_init(struct drm_device *dev)
}

/*
+ * Provide the low level interfaces for the Moorestown backlight
+ */
+
+#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE
+
+#define MRST_BLC_MAX_PWM_REG_FREQ 0xFFFF
+#define BLC_PWM_PRECISION_FACTOR 100 /* 10000000 */
+#define BLC_PWM_FREQ_CALC_CONSTANT 32
+#define MHz 1000000
+#define BLC_ADJUSTMENT_MAX 100
+
+static struct backlight_device *mrst_backlight_device;
+static int mrst_brightness;
+
+static int mrst_set_brightness(struct backlight_device *bd)
+{
+ struct drm_device *dev = bl_get_data(mrst_backlight_device);


+ struct drm_psb_private *dev_priv = dev->dev_private;

+ int level = bd->props.brightness;

+ u32 blc_pwm_ctl;
+ u32 max_pwm_blc;


+
+ /* Percentage 1-100% being valid */
+ if (level < 1)
+ level = 1;
+
+ if (gma_power_begin(dev, 0)) {
+ /* Calculate and set the brightness value */

+ max_pwm_blc = REG_READ(BLC_PWM_CTL) >> 16;
+ blc_pwm_ctl = level * max_pwm_blc / 100;


+
+ /* Adjust the backlight level with the percent in

+ * dev_priv->blc_adj1;
+ */
+ blc_pwm_ctl = blc_pwm_ctl * dev_priv->blc_adj1;
+ blc_pwm_ctl = blc_pwm_ctl / 100;


+
+ /* Adjust the backlight level with the percent in
+ * dev_priv->blc_adj2;
+ */

+ blc_pwm_ctl = blc_pwm_ctl * dev_priv->blc_adj2;
+ blc_pwm_ctl = blc_pwm_ctl / 100;
+
+ /* force PWM bit on */
+ REG_WRITE(BLC_PWM_CTL2, (0x80000000 | REG_READ(BLC_PWM_CTL2)));
+ REG_WRITE(BLC_PWM_CTL, (max_pwm_blc << 16) | blc_pwm_ctl);
+ gma_power_end(dev);
+ }
+ mrst_brightness = level;


+ return 0;
+}
+

+static int mrst_get_brightness(struct backlight_device *bd)
+{
+ /* return locally cached var instead of HW read (due to DPST etc.) */
+ /* FIXME: ideally return actual value in case firmware fiddled with
+ it */
+ return mrst_brightness;
+}
+
+static int device_backlight_init(struct drm_device *dev)


+{
+ struct drm_psb_private *dev_priv = dev->dev_private;

+ unsigned long core_clock;
+ u16 bl_max_freq;
+ uint32_t value;
+ uint32_t blc_pwm_precision_factor;
+


+ dev_priv->blc_adj1 = BLC_ADJUSTMENT_MAX;
+ dev_priv->blc_adj2 = BLC_ADJUSTMENT_MAX;

+ bl_max_freq = 256;
+ /* this needs to be set elsewhere */
+ blc_pwm_precision_factor = BLC_PWM_PRECISION_FACTOR;
+
+ core_clock = dev_priv->core_freq;
+
+ value = (core_clock * MHz) / BLC_PWM_FREQ_CALC_CONSTANT;
+ value *= blc_pwm_precision_factor;
+ value /= bl_max_freq;
+ value /= blc_pwm_precision_factor;


+
+ if (gma_power_begin(dev, false)) {

+ if (value > (unsigned long long)MRST_BLC_MAX_PWM_REG_FREQ)
+ return -ERANGE;
+ else {
+ REG_WRITE(BLC_PWM_CTL2,
+ (0x80000000 | REG_READ(BLC_PWM_CTL2)));
+ REG_WRITE(BLC_PWM_CTL, value | (value << 16));
+ }
+ gma_power_end(dev);


+ }
+ return 0;
+}
+

+static const struct backlight_ops mrst_ops = {

+ .get_brightness = mrst_get_brightness,


+ .update_status = mrst_set_brightness,
+};
+

+int mrst_backlight_init(struct drm_device *dev)


+{
+ struct drm_psb_private *dev_priv = dev->dev_private;

+ int ret;
+ struct backlight_properties props;
+
+ memset(&props, 0, sizeof(struct backlight_properties));
+ props.max_brightness = 100;
+ props.type = BACKLIGHT_PLATFORM;
+
+ mrst_backlight_device = backlight_device_register("mrst-bl",
+ NULL, (void *)dev, &mrst_ops, &props);
+
+ if (IS_ERR(mrst_backlight_device))
+ return PTR_ERR(mrst_backlight_device);
+
+ ret = device_backlight_init(dev);
+ if (ret < 0) {
+ backlight_device_unregister(mrst_backlight_device);
+ return ret;
+ }
+ mrst_backlight_device->props.brightness = 100;
+ mrst_backlight_device->props.max_brightness = 100;
+ backlight_update_status(mrst_backlight_device);
+ dev_priv->backlight_device = mrst_backlight_device;


+ return 0;
+}
+

+#endif
+
+/*


* Provide the Moorestown specific chip logic and low level methods

+ * for power management
*/

static void mrst_init_pm(struct drm_device *dev)
@@ -221,6 +353,11 @@ static int mrst_power_up(struct drm_device *dev)

const struct psb_ops mrst_chip_ops = {
.output_init = mrst_output_init,
+
+#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE
+ .backlight_init = mrst_backlight_init,
+#endif
+
.init_pm = mrst_init_pm,
.save_regs = mrst_save_display_registers,
.restore_regs = mrst_restore_display_registers,
diff --git a/drivers/staging/gma500/psb_bl.c b/drivers/staging/gma500/psb_bl.c
deleted file mode 100644
index c84d261..0000000
--- a/drivers/staging/gma500/psb_bl.c
+++ /dev/null
@@ -1,283 +0,0 @@
-/*
- * GMA500 Backlight Interface
- *


- * Copyright (c) 2009-2011, Intel Corporation.
- *

- * 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.
- *
- * Authors: Eric Knopp
- *
- */
-
-#include <linux/backlight.h>
-#include <linux/version.h>
-#include "psb_drv.h"
-#include "psb_intel_reg.h"
-#include "psb_intel_drv.h"
-#include "psb_intel_bios.h"
-#include "psb_powermgmt.h"
-
-#define MRST_BLC_MAX_PWM_REG_FREQ 0xFFFF
-#define BLC_PWM_PRECISION_FACTOR 100 /* 10000000 */
-#define BLC_PWM_FREQ_CALC_CONSTANT 32
-#define MHz 1000000
-#define BRIGHTNESS_MIN_LEVEL 1
-#define BRIGHTNESS_MASK 0xFF
-#define BLC_POLARITY_NORMAL 0
-#define BLC_POLARITY_INVERSE 1
-#define BLC_ADJUSTMENT_MAX 100
-
-#define PSB_BLC_PWM_PRECISION_FACTOR 10
-#define PSB_BLC_MAX_PWM_REG_FREQ 0xFFFE
-#define PSB_BLC_MIN_PWM_REG_FREQ 0x2
-
-#define PSB_BACKLIGHT_PWM_POLARITY_BIT_CLEAR (0xFFFE)
-#define PSB_BACKLIGHT_PWM_CTL_SHIFT (16)
-
-static int psb_brightness;
-static struct backlight_device *psb_backlight_device;
-static u8 blc_brightnesscmd;
-static u8 blc_pol;
-static u8 blc_type;
-
-int psb_set_brightness(struct backlight_device *bd)
-{
- struct drm_device *dev = bl_get_data(psb_backlight_device);
- int level = bd->props.brightness;
-
- /* Percentage 1-100% being valid */
- if (level < 1)
- level = 1;
-
- psb_intel_lvds_set_brightness(dev, level);
- psb_brightness = level;


- return 0;
-}
-

-int mrst_set_brightness(struct backlight_device *bd)
-{
- struct drm_device *dev = bl_get_data(psb_backlight_device);


- struct drm_psb_private *dev_priv = dev->dev_private;

- int level = bd->props.brightness;
- u32 blc_pwm_ctl;
- u32 max_pwm_blc;
-
- /* Percentage 1-100% being valid */
- if (level < 1)
- level = 1;
-
- if (gma_power_begin(dev, 0)) {
- /* Calculate and set the brightness value */
- max_pwm_blc = REG_READ(BLC_PWM_CTL) >> 16;
- blc_pwm_ctl = level * max_pwm_blc / 100;
-
- /* Adjust the backlight level with the percent in
- * dev_priv->blc_adj1;
- */
- blc_pwm_ctl = blc_pwm_ctl * dev_priv->blc_adj1;
- blc_pwm_ctl = blc_pwm_ctl / 100;
-
- /* Adjust the backlight level with the percent in
- * dev_priv->blc_adj2;
- */
- blc_pwm_ctl = blc_pwm_ctl * dev_priv->blc_adj2;
- blc_pwm_ctl = blc_pwm_ctl / 100;
-
- if (blc_pol == BLC_POLARITY_INVERSE)
- blc_pwm_ctl = max_pwm_blc - blc_pwm_ctl;
- /* force PWM bit on */
- REG_WRITE(BLC_PWM_CTL2, (0x80000000 | REG_READ(BLC_PWM_CTL2)));
- REG_WRITE(BLC_PWM_CTL, (max_pwm_blc << 16) | blc_pwm_ctl);
- gma_power_end(dev);
- }
- psb_brightness = level;


- return 0;
-}
-

-int mfld_set_brightness(struct backlight_device *bd)
-{
- struct drm_device *dev = bl_get_data(psb_backlight_device);


- struct drm_psb_private *dev_priv = dev->dev_private;

- int level = bd->props.brightness;
-
- DRM_DEBUG_DRIVER("backlight level set to %d\n", level);
-
- /* Percentage 1-100% being valid */
- if (level < 1)
- level = 1;
-
- if (gma_power_begin(dev, 0)) {
- /* Calculate and set the brightness value */
- u32 adjusted_level;
-
- /* Adjust the backlight level with the percent in
- * dev_priv->blc_adj2;
- */
- adjusted_level = level * dev_priv->blc_adj2;
- adjusted_level = adjusted_level / BLC_ADJUSTMENT_MAX;
-#if 0
-#ifndef CONFIG_MDFLD_DSI_DPU
- if(!(dev_priv->dsr_fb_update & MDFLD_DSR_MIPI_CONTROL) &&
- (dev_priv->dbi_panel_on || dev_priv->dbi_panel_on2)){
- mdfld_dsi_dbi_exit_dsr(dev,MDFLD_DSR_MIPI_CONTROL, 0, 0);
- dev_dbg(dev->dev, "Out of DSR before set brightness to %d.\n",adjusted_level);
- }
-#endif
- mdfld_dsi_brightness_control(dev, 0, adjusted_level);
-
- if ((dev_priv->dbi_panel_on2) || (dev_priv->dpi_panel_on2))
- mdfld_dsi_brightness_control(dev, 2, adjusted_level);
-#endif
- gma_power_end(dev);
- }
- psb_brightness = level;


- return 0;
-}
-

-int psb_get_brightness(struct backlight_device *bd)
-{
- /* return locally cached var instead of HW read (due to DPST etc.) */
- /* FIXME: ideally return actual value in case firmware fiddled with
- it */
- return psb_brightness;
-}
-
-static const struct backlight_ops psb_ops = {
- .get_brightness = psb_get_brightness,
- .update_status = psb_set_brightness,
-};
-
-static const struct backlight_ops mrst_ops = {
- .get_brightness = psb_get_brightness,
- .update_status = mrst_set_brightness,
-};
-
-static const struct backlight_ops mfld_ops = {
- .get_brightness = psb_get_brightness,
- .update_status = mfld_set_brightness,
-};
-
-static int device_backlight_init(struct drm_device *dev)


-{
- struct drm_psb_private *dev_priv = dev->dev_private;

- unsigned long core_clock;
- /* u32 bl_max_freq; */
- /* unsigned long value; */
- u16 bl_max_freq;
- uint32_t value;
- uint32_t blc_pwm_precision_factor;
-
- if (IS_MFLD(dev)) {
- dev_priv->blc_adj1 = BLC_ADJUSTMENT_MAX;
- dev_priv->blc_adj2 = BLC_ADJUSTMENT_MAX;
- return 0;
- } else if (IS_MRST(dev)) {
- dev_priv->blc_adj1 = BLC_ADJUSTMENT_MAX;
- dev_priv->blc_adj2 = BLC_ADJUSTMENT_MAX;
- bl_max_freq = 256;
- /* this needs to be set elsewhere */
- blc_pol = BLC_POLARITY_NORMAL;
- blc_pwm_precision_factor = BLC_PWM_PRECISION_FACTOR;
- } else {
- /* get bl_max_freq and pol from dev_priv*/
- if (!dev_priv->lvds_bl) {
- dev_err(dev->dev, "Has no valid LVDS backlight info\n");
- return 1;
- }
- bl_max_freq = dev_priv->lvds_bl->freq;
- blc_pol = dev_priv->lvds_bl->pol;
- blc_pwm_precision_factor = PSB_BLC_PWM_PRECISION_FACTOR;
- blc_brightnesscmd = dev_priv->lvds_bl->brightnesscmd;
- blc_type = dev_priv->lvds_bl->type;
- }
-
- core_clock = dev_priv->core_freq;
-
- value = (core_clock * MHz) / BLC_PWM_FREQ_CALC_CONSTANT;
- value *= blc_pwm_precision_factor;
- value /= bl_max_freq;
- value /= blc_pwm_precision_factor;
-
- if (gma_power_begin(dev, false)) {
- if (IS_MRST(dev)) {
- if (value > (unsigned long long)MRST_BLC_MAX_PWM_REG_FREQ)
- return 2;
- else {
- REG_WRITE(BLC_PWM_CTL2,
- (0x80000000 | REG_READ(BLC_PWM_CTL2)));
- REG_WRITE(BLC_PWM_CTL, value | (value << 16));
- }
- } else {
- if (value > (unsigned long long)PSB_BLC_MAX_PWM_REG_FREQ ||
- value < (unsigned long long)PSB_BLC_MIN_PWM_REG_FREQ)
- return 2;
- else {
- value &= PSB_BACKLIGHT_PWM_POLARITY_BIT_CLEAR;
- REG_WRITE(BLC_PWM_CTL,
- (value << PSB_BACKLIGHT_PWM_CTL_SHIFT) |
- (value));
- }
- }
- gma_power_end(dev);


- }
- return 0;
-}
-

-int psb_backlight_init(struct drm_device *dev)
-{
-#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE
- int ret = 0;
-
- struct backlight_properties props;
- memset(&props, 0, sizeof(struct backlight_properties));
- props.max_brightness = 100;
- props.type = BACKLIGHT_PLATFORM;
-
- if (IS_MFLD(dev))
- psb_backlight_device = backlight_device_register("mfld-bl",
- NULL, (void *)dev, &mfld_ops, &props);
- else if (IS_MRST(dev))
- psb_backlight_device = backlight_device_register("mrst-bl",
- NULL, (void *)dev, &psb_ops, &props);
- else


- psb_backlight_device = backlight_device_register("psb-bl",

- NULL, (void *)dev, &psb_ops, &props);
-
- if (IS_ERR(psb_backlight_device))
- return PTR_ERR(psb_backlight_device);
-
- ret = device_backlight_init(dev);
- if (ret < 0)
- return ret;
-
- psb_backlight_device->props.brightness = 100;
- psb_backlight_device->props.max_brightness = 100;
- backlight_update_status(psb_backlight_device);
-#endif


- return 0;
-}
-

-void psb_backlight_exit(void)
-{
-#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE
- psb_backlight_device->props.brightness = 0;
- backlight_update_status(psb_backlight_device);
- backlight_device_unregister(psb_backlight_device);
-#endif
-}
-
-struct backlight_device *psb_get_backlight_device(void)
-{
- return psb_backlight_device;
-}
diff --git a/drivers/staging/gma500/psb_device.c b/drivers/staging/gma500/psb_device.c
index 97e25ab..4a3c516 100644
--- a/drivers/staging/gma500/psb_device.c
+++ b/drivers/staging/gma500/psb_device.c
@@ -17,12 +17,15 @@
*
**************************************************************************/

+#include <linux/backlight.h>
#include <drm/drmP.h>
#include <drm/drm.h>
#include "psb_drm.h"


#include "psb_drv.h"
#include "psb_reg.h"
#include "psb_intel_reg.h"

+#include "psb_intel_bios.h"
+

static int psb_output_init(struct drm_device *dev)
{
@@ -32,8 +35,123 @@ static int psb_output_init(struct drm_device *dev)
return 0;
}

+#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE
+
+/*
+ * Poulsbo Backlight Interfaces
+ */
+
+#define BLC_PWM_PRECISION_FACTOR 100 /* 10000000 */
+#define BLC_PWM_FREQ_CALC_CONSTANT 32
+#define MHz 1000000
+
+#define PSB_BLC_PWM_PRECISION_FACTOR 10
+#define PSB_BLC_MAX_PWM_REG_FREQ 0xFFFE
+#define PSB_BLC_MIN_PWM_REG_FREQ 0x2
+
+#define PSB_BACKLIGHT_PWM_POLARITY_BIT_CLEAR (0xFFFE)
+#define PSB_BACKLIGHT_PWM_CTL_SHIFT (16)
+
+static int psb_brightness;
+static struct backlight_device *psb_backlight_device;
+
+static int psb_get_brightness(struct backlight_device *bd)
+{
+ /* return locally cached var instead of HW read (due to DPST etc.) */
+ /* FIXME: ideally return actual value in case firmware fiddled with
+ it */
+ return psb_brightness;
+}
+
+
+static int psb_backlight_setup(struct drm_device *dev)


+{
+ struct drm_psb_private *dev_priv = dev->dev_private;

+ unsigned long core_clock;
+ /* u32 bl_max_freq; */
+ /* unsigned long value; */
+ u16 bl_max_freq;
+ uint32_t value;
+ uint32_t blc_pwm_precision_factor;
+
+ /* get bl_max_freq and pol from dev_priv*/
+ if (!dev_priv->lvds_bl) {


+ dev_err(dev->dev, "Has no valid LVDS backlight info\n");

+ return -ENOENT;
+ }
+ bl_max_freq = dev_priv->lvds_bl->freq;
+ blc_pwm_precision_factor = PSB_BLC_PWM_PRECISION_FACTOR;
+
+ core_clock = dev_priv->core_freq;
+
+ value = (core_clock * MHz) / BLC_PWM_FREQ_CALC_CONSTANT;
+ value *= blc_pwm_precision_factor;
+ value /= bl_max_freq;
+ value /= blc_pwm_precision_factor;
+
+ if (value > (unsigned long long)PSB_BLC_MAX_PWM_REG_FREQ ||
+ value < (unsigned long long)PSB_BLC_MIN_PWM_REG_FREQ)
+ return -ERANGE;
+ else {
+ value &= PSB_BACKLIGHT_PWM_POLARITY_BIT_CLEAR;
+ REG_WRITE(BLC_PWM_CTL,
+ (value << PSB_BACKLIGHT_PWM_CTL_SHIFT) | (value));


+ }
+ return 0;
+}
+

+static int psb_set_brightness(struct backlight_device *bd)
+{
+ struct drm_device *dev = bl_get_data(psb_backlight_device);


+ int level = bd->props.brightness;
+

+ /* Percentage 1-100% being valid */
+ if (level < 1)
+ level = 1;
+

+ psb_intel_lvds_set_brightness(dev, level);
+ psb_brightness = level;


+ return 0;
+}
+

+static const struct backlight_ops psb_ops = {
+ .get_brightness = psb_get_brightness,
+ .update_status = psb_set_brightness,
+};
+
+static int psb_backlight_init(struct drm_device *dev)


+{
+ struct drm_psb_private *dev_priv = dev->dev_private;

+ int ret;
+ struct backlight_properties props;
+
+ memset(&props, 0, sizeof(struct backlight_properties));
+ props.max_brightness = 100;
+ props.type = BACKLIGHT_PLATFORM;
+


+ psb_backlight_device = backlight_device_register("psb-bl",
+ NULL, (void *)dev, &psb_ops, &props);
+ if (IS_ERR(psb_backlight_device))

+ return PTR_ERR(psb_backlight_device);
+
+ ret = psb_backlight_setup(dev);
+ if (ret < 0) {
+ backlight_device_unregister(psb_backlight_device);
+ psb_backlight_device = NULL;
+ return ret;
+ }
+ psb_backlight_device->props.brightness = 100;
+ psb_backlight_device->props.max_brightness = 100;
+ backlight_update_status(psb_backlight_device);
+ dev_priv->backlight_device = psb_backlight_device;


+ return 0;
+}
+

+#endif
+
/*


* Provide the Poulsbo specific chip logic and low level methods

+ * for power management
*/

static void psb_init_pm(struct drm_device *dev)
@@ -165,10 +283,15 @@ int psb_power_up(struct drm_device *dev)

const struct psb_ops psb_chip_ops = {
.output_init = psb_output_init,
+
+#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE
+ .backlight_init = psb_backlight_init,
+#endif
+
.init_pm = psb_init_pm,
.save_regs = psb_save_display_registers,
.restore_regs = psb_restore_display_registers,
.power_down = psb_power_down,
- .power_up = psb_power_up,
+ .power_up = psb_power_up,
};

diff --git a/drivers/staging/gma500/psb_drv.c b/drivers/staging/gma500/psb_drv.c
index 6c57234..bb6b68f 100644
--- a/drivers/staging/gma500/psb_drv.c
+++ b/drivers/staging/gma500/psb_drv.c
@@ -261,7 +261,7 @@ static int psb_driver_unload(struct drm_device *dev)



/* Kill vblank etc here */

- psb_backlight_exit(); /*writes minimum value to backlight HW reg */
+ gma_backlight_exit(dev);

if (drm_psb_no_fb == 0)
psb_modeset_cleanup(dev);
@@ -455,7 +455,7 @@ static int psb_driver_load(struct drm_device *dev, unsigned long chipset)

switch (psb_intel_output->type) {
case INTEL_OUTPUT_LVDS:
- ret = psb_backlight_init(dev);
+ ret = gma_backlight_init(dev);
break;
}
}
@@ -554,12 +554,14 @@ static int psb_dpst_bl_ioctl(struct drm_device *dev, void *data,
{
struct drm_psb_private *dev_priv = psb_priv(dev);
uint32_t *arg = data;
- struct backlight_device bd;
+ struct backlight_device *bd = dev_priv->backlight_device;
dev_priv->blc_adj2 = *arg;

#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE
- bd.props.brightness = psb_get_brightness(&bd);
- psb_set_brightness(&bd);
+ if (bd) {
+ bd->props.brightness = bd->ops->get_brightness(bd);
+ backlight_update_status(bd);
+ }
#endif
return 0;
}
@@ -569,12 +571,14 @@ static int psb_adb_ioctl(struct drm_device *dev, void *data,
{
struct drm_psb_private *dev_priv = psb_priv(dev);
uint32_t *arg = data;
- struct backlight_device bd;
+ struct backlight_device *bd = dev_priv->backlight_device;
dev_priv->blc_adj1 = *arg;

#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE
- bd.props.brightness = psb_get_brightness(&bd);
- psb_set_brightness(&bd);
+ if (bd) {
+ bd->props.brightness = bd->ops->get_brightness(bd);
+ backlight_update_status(bd);
+ }
#endif
return 0;
}
diff --git a/drivers/staging/gma500/psb_drv.h b/drivers/staging/gma500/psb_drv.h
index d1c49e7..b0908f2 100644
--- a/drivers/staging/gma500/psb_drv.h
+++ b/drivers/staging/gma500/psb_drv.h
@@ -588,12 +588,12 @@ struct drm_psb_private {
* Used for modifying backlight from
* xrandr -- consider removing and using HAL instead
*/
+ struct backlight_device *backlight_device;
struct drm_property *backlight_property;
uint32_t blc_adj1;
uint32_t blc_adj2;

void *fbdev;
-
/* DPST state */
uint32_t dsr_idle_count;
bool is_in_idle;
@@ -625,6 +625,10 @@ struct psb_ops {
int (*restore_regs)(struct drm_device *dev);
int (*power_up)(struct drm_device *dev);
int (*power_down)(struct drm_device *dev);
+#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE
+ /* Backlight */
+ int (*backlight_init)(struct drm_device *dev);
+#endif
};


@@ -744,12 +748,9 @@ extern void psb_modeset_init(struct drm_device *dev);


extern void psb_modeset_cleanup(struct drm_device *dev);

extern int psb_fbdev_init(struct drm_device *dev);

-/* psb_bl.c */
-int psb_backlight_init(struct drm_device *dev);
-void psb_backlight_exit(void);
-int psb_set_brightness(struct backlight_device *bd);
-int psb_get_brightness(struct backlight_device *bd);
-struct backlight_device *psb_get_backlight_device(void);
+/* backlight.c */
+int gma_backlight_init(struct drm_device *dev);
+void gma_backlight_exit(struct drm_device *dev);



/* mrst_crtc.c */
extern const struct drm_crtc_helper_funcs mrst_helper_funcs;

diff --git a/drivers/staging/gma500/psb_intel_lvds.c b/drivers/staging/gma500/psb_intel_lvds.c
index 850d07d..41b96d2 100644
--- a/drivers/staging/gma500/psb_intel_lvds.c
+++ b/drivers/staging/gma500/psb_intel_lvds.c
@@ -575,11 +575,12 @@ int psb_intel_lvds_set_property(struct drm_connector *connector,
struct drm_property *property,
uint64_t value)
{
- struct drm_encoder *pEncoder = connector->encoder;
+ struct drm_encoder *encoder = connector->encoder;
+ struct drm_psb_private *dev_priv = encoder->dev->dev_private;

- if (!strcmp(property->name, "scaling mode") && pEncoder) {


+ if (!strcmp(property->name, "scaling mode") && encoder) {

struct psb_intel_crtc *pPsbCrtc =
- to_psb_intel_crtc(pEncoder->crtc);
+ to_psb_intel_crtc(encoder->crtc);
uint64_t curValue;

if (!pPsbCrtc)
@@ -611,29 +612,31 @@ int psb_intel_lvds_set_property(struct drm_connector *connector,

if (pPsbCrtc->saved_mode.hdisplay != 0 &&
pPsbCrtc->saved_mode.vdisplay != 0) {
- if (!drm_crtc_helper_set_mode(pEncoder->crtc,
+ if (!drm_crtc_helper_set_mode(encoder->crtc,
&pPsbCrtc->saved_mode,
- pEncoder->crtc->x,
- pEncoder->crtc->y,
- pEncoder->crtc->fb))
+ encoder->crtc->x,
+ encoder->crtc->y,
+ encoder->crtc->fb))
goto set_prop_error;
}
- } else if (!strcmp(property->name, "backlight") && pEncoder) {


+ } else if (!strcmp(property->name, "backlight") && encoder) {

if (drm_connector_property_set_value(connector,
property,
value))
goto set_prop_error;
else {
#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE
- struct backlight_device bd;
- bd.props.brightness = value;
- psb_set_brightness(&bd);
+ struct backlight_device *bd = dev_priv->backlight_device;
+ if (bd) {
+ bd->props.brightness = value;
+ backlight_update_status(bd);
+ }
#endif
}
- } else if (!strcmp(property->name, "DPMS") && pEncoder) {
+ } else if (!strcmp(property->name, "DPMS") && encoder) {
struct drm_encoder_helper_funcs *pEncHFuncs
- = pEncoder->helper_private;
- pEncHFuncs->dpms(pEncoder, value);
+ = encoder->helper_private;
+ pEncHFuncs->dpms(encoder, value);
}

set_prop_done:

Alan Cox

unread,
Jun 16, 2011, 12:41:18 PM6/16/11
to gr...@kroah.com, linux-...@vger.kernel.org
From: Alan Cox <al...@linux.intel.com>

Eliminate unused stuff and clean up the code ordering.

Signed-off-by: Alan Cox <al...@linux.intel.com>
---

drivers/staging/gma500/psb_drm.h | 4 -
drivers/staging/gma500/psb_drv.c | 9 ---
drivers/staging/gma500/psb_drv.h | 6 --
drivers/staging/gma500/psb_fb.c | 135 ++++++++------------------------------
4 files changed, 29 insertions(+), 125 deletions(-)

diff --git a/drivers/staging/gma500/psb_drm.h b/drivers/staging/gma500/psb_drm.h
index c541137..5dcf045 100644
--- a/drivers/staging/gma500/psb_drm.h
+++ b/drivers/staging/gma500/psb_drm.h
@@ -145,8 +145,6 @@ struct drm_psb_register_rw_arg {

/* Controlling the kernel modesetting buffers */

-#define DRM_PSB_KMS_OFF 0x00
-#define DRM_PSB_KMS_ON 0x01


#define DRM_PSB_SIZES 0x07
#define DRM_PSB_FUSE_REG 0x08

#define DRM_PSB_DC_STATE 0x0A
@@ -155,7 +153,7 @@ struct drm_psb_register_rw_arg {


#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
diff --git a/drivers/staging/gma500/psb_drv.c b/drivers/staging/gma500/psb_drv.c
index cbdc02c..0d65f75 100644
--- a/drivers/staging/gma500/psb_drv.c
+++ b/drivers/staging/gma500/psb_drv.c
@@ -75,10 +75,6 @@ MODULE_DEVICE_TABLE(pci, pciidlist);
* Standard IOCTLs.
*/

-#define DRM_IOCTL_PSB_KMS_OFF \
- DRM_IO(DRM_PSB_KMS_OFF + DRM_COMMAND_BASE)
-#define DRM_IOCTL_PSB_KMS_ON \
- DRM_IO(DRM_PSB_KMS_ON + DRM_COMMAND_BASE)
#define DRM_IOCTL_PSB_SIZES \
DRM_IOR(DRM_PSB_SIZES + DRM_COMMAND_BASE, \
struct drm_psb_sizes_arg)
@@ -134,11 +130,6 @@ 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_KMS_OFF, psbfb_kms_off_ioctl,
- DRM_ROOT_ONLY),
- PSB_IOCTL_DEF(DRM_IOCTL_PSB_KMS_ON,
- psbfb_kms_on_ioctl,
- DRM_ROOT_ONLY),
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),
diff --git a/drivers/staging/gma500/psb_drv.h b/drivers/staging/gma500/psb_drv.h
index 86abf26..3b2ee08 100644
--- a/drivers/staging/gma500/psb_drv.h
+++ b/drivers/staging/gma500/psb_drv.h
@@ -704,12 +704,6 @@ extern int psb_intel_opregion_init(struct drm_device *dev);
extern int psbfb_probed(struct drm_device *dev);
extern int psbfb_remove(struct drm_device *dev,
struct drm_framebuffer *fb);
-extern int psbfb_kms_off_ioctl(struct drm_device *dev, void *data,
- struct drm_file *file_priv);
-extern int psbfb_kms_on_ioctl(struct drm_device *dev, void *data,
- struct drm_file *file_priv);
-extern void *psbfb_vdc_reg(struct drm_device* dev);
-
/*
* psb_2d.c
*/
diff --git a/drivers/staging/gma500/psb_fb.c b/drivers/staging/gma500/psb_fb.c
index 8377a99..83095fc 100644
--- a/drivers/staging/gma500/psb_fb.c
+++ b/drivers/staging/gma500/psb_fb.c
@@ -52,13 +52,6 @@ static const struct drm_framebuffer_funcs psb_fb_funcs = {

#define CMAP_TOHW(_val, _width) ((((_val) << (_width)) + 0x7FFF - (_val)) >> 16)

-void *psbfb_vdc_reg(struct drm_device *dev)
-{
- struct drm_psb_private *dev_priv;
- dev_priv = (struct drm_psb_private *) dev->dev_private;
- return dev_priv->vdc_reg;
-}
-


static int psbfb_setcolreg(unsigned regno, unsigned red, unsigned green,
unsigned blue, unsigned transp,

struct fb_info *info)
@@ -98,108 +91,60 @@ static int psbfb_setcolreg(unsigned regno, unsigned red, unsigned green,
return 0;
}

-static int psbfb_kms_off(struct drm_device *dev, int suspend)
+
+void psbfb_suspend(struct drm_device *dev)


{
struct drm_framebuffer *fb = 0;

struct psb_framebuffer *psbfb = to_psb_fb(fb);

+ console_lock();
mutex_lock(&dev->mode_config.mutex);
list_for_each_entry(fb, &dev->mode_config.fb_list, head) {
struct fb_info *info = psbfb->fbdev;
-
- if (suspend) {
- fb_set_suspend(info, 1);
- drm_fb_helper_blank(FB_BLANK_POWERDOWN, info);
- }
+ fb_set_suspend(info, 1);
+ drm_fb_helper_blank(FB_BLANK_POWERDOWN, info);
}
mutex_unlock(&dev->mode_config.mutex);


- return 0;
-}
-

-int psbfb_kms_off_ioctl(struct drm_device *dev, void *data,
- struct drm_file *file_priv)
-{
- int ret;
-


- if (drm_psb_no_fb)
- return 0;

- console_lock();
- ret = psbfb_kms_off(dev, 0);
console_unlock();
-
- return ret;
}

-static int psbfb_kms_on(struct drm_device *dev, int resume)
+void psbfb_resume(struct drm_device *dev)


{
struct drm_framebuffer *fb = 0;

struct psb_framebuffer *psbfb = to_psb_fb(fb);

+ console_lock();
mutex_lock(&dev->mode_config.mutex);
list_for_each_entry(fb, &dev->mode_config.fb_list, head) {
struct fb_info *info = psbfb->fbdev;
-
- if (resume) {
- fb_set_suspend(info, 0);
- drm_fb_helper_blank(FB_BLANK_UNBLANK, info);
- }
+ fb_set_suspend(info, 0);
+ drm_fb_helper_blank(FB_BLANK_UNBLANK, info);
}
mutex_unlock(&dev->mode_config.mutex);


-
- return 0;
-}
-

-int psbfb_kms_on_ioctl(struct drm_device *dev, void *data,
- struct drm_file *file_priv)
-{
- int ret;
-


- if (drm_psb_no_fb)
- return 0;

- console_lock();
- ret = psbfb_kms_on(dev, 0);
- console_unlock();
- drm_helper_disable_unused_functions(dev);


- return ret;
-}
-

-void psbfb_suspend(struct drm_device *dev)
-{
- console_lock();
- psbfb_kms_off(dev, 1);
- console_unlock();
-}
-
-void psbfb_resume(struct drm_device *dev)
-{
- console_lock();
- psbfb_kms_on(dev, 1);
console_unlock();
drm_helper_disable_unused_functions(dev);
}

static int psbfb_vm_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
{
- int page_num = 0;
- int i;
- unsigned long address = 0;
- int ret;
- unsigned long pfn;


struct psb_framebuffer *psbfb = vma->vm_private_data;

struct drm_device *dev = psbfb->base.dev;

struct drm_psb_private *dev_priv = dev->dev_private;
-

+ int page_num;
+ int i;
+ unsigned long address;
+ int ret;
+ unsigned long pfn;


/* FIXME: assumes fb at stolen base which may not be true */
unsigned long phys_addr = (unsigned long)dev_priv->stolen_base;

page_num = (vma->vm_end - vma->vm_start) >> PAGE_SHIFT;

-
address = (unsigned long)vmf->virtual_address;

vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);

for (i = 0; i < page_num; i++) {
- pfn = (phys_addr >> PAGE_SHIFT); /* phys_to_pfn(phys_addr); */
+ pfn = (phys_addr >> PAGE_SHIFT);

ret = vm_insert_mixed(vma, address, pfn);
if (unlikely((ret == -EBUSY) || (ret != 0 && i > 0)))
@@ -208,11 +153,9 @@ static int psbfb_vm_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
ret = (ret == -ENOMEM) ? VM_FAULT_OOM : VM_FAULT_SIGBUS;
return ret;
}
-
address += PAGE_SIZE;
phys_addr += PAGE_SIZE;
}
-
return VM_FAULT_NOPAGE;
}

@@ -234,7 +177,6 @@ static int psbfb_mmap(struct fb_info *info, struct vm_area_struct *vma)


{
struct psb_fbdev *fbdev = info->par;
struct psb_framebuffer *psbfb = &fbdev->pfb;

- char *fb_screen_base = NULL;



if (vma->vm_pgoff != 0)
return -EINVAL;

@@ -243,9 +185,6 @@ static int psbfb_mmap(struct fb_info *info, struct vm_area_struct *vma)

if (!psbfb->addr_space)
psbfb->addr_space = vma->vm_file->f_mapping;
-
- fb_screen_base = (char *)info->screen_base;
-
/*


* If this is a GEM object then info->screen_base is the virtual

* kernel remapping of the object. FIXME: Review if this is

@@ -272,8 +211,8 @@ static int psbfb_ioctl(struct fb_info *info, unsigned int cmd,


case 0x12345678:
if (!capable(CAP_SYS_RAWIO))
return -EPERM;

- if (IS_MFLD(dev))
- return -EOPNOTSUPP;


+ if (IS_MFLD(dev))
+ return -EOPNOTSUPP;
if (get_user(l, p))
return -EFAULT;
if (l > 32)

@@ -488,9 +427,9 @@ static int psbfb_create(struct psb_fbdev *fbdev,
info->flags = FBINFO_DEFAULT;


/* No 2D engine */

if (IS_MFLD(dev))
- info->fbops = &psbfb_mfld_ops;
- else


- info->fbops = &psbfb_ops;

+ info->fbops = &psbfb_mfld_ops;
+ else
+ info->fbops = &psbfb_ops;

ret = fb_alloc_cmap(&info->cmap, 256, 0);
if (ret) {

@@ -518,7 +457,6 @@ static int psbfb_create(struct psb_fbdev *fbdev,


psbfb->vm_map = 1;
}
info->screen_size = size;

-/* memset(info->screen_base, 0, size); */



if (dev_priv->pg->stolen_size) {
info->apertures = alloc_apertures(1);

@@ -644,15 +582,8 @@ int psb_fbdev_destroy(struct drm_device *dev, struct psb_fbdev *fbdev)
drm_fb_helper_fini(&fbdev->psb_fb_helper);
drm_framebuffer_cleanup(&psbfb->base);

- if (psbfb->gtt) {
- /* FIXME: this is a bit more inside knowledge than I'd like
- but I don't see how to make a fake GEM object of the
- stolen space nicely */
- if (psbfb->gtt->stolen)
- psb_gtt_free_range(dev, psbfb->gtt);
- else
- drm_gem_object_unreference(&psbfb->gtt->gem);
- }
+ if (psbfb->gtt)
+ drm_gem_object_unreference(&psbfb->gtt->gem);
return 0;
}

@@ -671,6 +602,7 @@ int psb_fbdev_init(struct drm_device *dev)
dev_priv->fbdev = fbdev;
fbdev->psb_fb_helper.funcs = &psb_fb_helper_funcs;

+ /* FIXME: check Medfield */
num_crtc = 2;

drm_fb_helper_init(dev, &fbdev->psb_fb_helper, num_crtc,
@@ -769,17 +701,14 @@ static const struct drm_mode_config_funcs psb_mode_funcs = {

static int psb_create_backlight_property(struct drm_device *dev)
{
- struct drm_psb_private *dev_priv
- = (struct drm_psb_private *) dev->dev_private;


+ struct drm_psb_private *dev_priv = dev->dev_private;

struct drm_property *backlight;

if (dev_priv->backlight_property)
return 0;

- backlight = drm_property_create(dev,
- DRM_MODE_PROP_RANGE,
- "backlight",
- 2);
+ backlight = drm_property_create(dev, DRM_MODE_PROP_RANGE,
+ "backlight", 2);
backlight->values[0] = 0;
backlight->values[1] = 100;

@@ -790,12 +719,10 @@ static int psb_create_backlight_property(struct drm_device *dev)



static void psb_setup_outputs(struct drm_device *dev)

{


- struct drm_psb_private *dev_priv =

- (struct drm_psb_private *) dev->dev_private;

+ struct drm_psb_private *dev_priv = dev->dev_private;

struct drm_connector *connector;

drm_mode_create_scaling_mode_property(dev);
-
psb_create_backlight_property(dev);

if (IS_MRST(dev)) {
@@ -805,7 +732,7 @@ static void psb_setup_outputs(struct drm_device *dev)


dev_err(dev->dev, "DSI is not supported\n");

} else if (IS_MFLD(dev)) {
mdfld_output_init(dev);
- } else {


+ } else {
psb_intel_lvds_init(dev, &dev_priv->mode_dev);
psb_intel_sdvo_init(dev, SDVOB);
}

@@ -843,11 +770,9 @@ static void psb_setup_outputs(struct drm_device *dev)


clone_mask = (1 << INTEL_OUTPUT_HDMI);
break;
}

-
encoder->possible_crtcs = crtc_mask;
encoder->possible_clones =
psb_intel_connector_clones(dev, clone_mask);
-
}
}

@@ -878,9 +803,6 @@ void psb_modeset_init(struct drm_device *dev)
dev->mode_config.max_height = 2048;

psb_setup_outputs(dev);
-
- /* setup fbs */
- /* drm_initial_config(dev); */
}

void psb_modeset_cleanup(struct drm_device *dev)
@@ -889,7 +811,6 @@ void psb_modeset_cleanup(struct drm_device *dev)

drm_kms_helper_poll_fini(dev);
psb_fbdev_fini(dev);
-
drm_mode_config_cleanup(dev);

mutex_unlock(&dev->struct_mutex);

Alan Cox

unread,
Jun 16, 2011, 12:40:58 PM6/16/11
to gr...@kroah.com, linux-...@vger.kernel.org
From: Alan Cox <al...@linux.intel.com>

This is too big already so lets rip out more of the device specific crud. It
also means we pull the ugly stuff that needs work out of our main line of
cleanup.

Signed-off-by: Alan Cox <al...@linux.intel.com>
---

drivers/staging/gma500/Makefile | 1
drivers/staging/gma500/mrst_bios.c | 236 ++++++++++++++++++++++++++++++++++++
drivers/staging/gma500/mrst_bios.h | 22 +++
drivers/staging/gma500/psb_drv.c | 209 --------------------------------
4 files changed, 260 insertions(+), 208 deletions(-)


create mode 100644 drivers/staging/gma500/mrst_bios.c
create mode 100644 drivers/staging/gma500/mrst_bios.h

diff --git a/drivers/staging/gma500/Makefile b/drivers/staging/gma500/Makefile
index 4c9c475..fdaac63 100644
--- a/drivers/staging/gma500/Makefile
+++ b/drivers/staging/gma500/Makefile
@@ -23,6 +23,7 @@ psb_gfx-y += gem_glue.o \
psb_irq.o \
mrst_crtc.o \
mrst_lvds.o \
+ mrst_bios.o \
mdfld_output.o \
mdfld_pyr_cmd.o \
mdfld_tmd_vid.o \
diff --git a/drivers/staging/gma500/mrst_bios.c b/drivers/staging/gma500/mrst_bios.c
new file mode 100644
index 0000000..0d944c4
--- /dev/null
+++ b/drivers/staging/gma500/mrst_bios.c
@@ -0,0 +1,236 @@


+/**************************************************************************
+ * Copyright (c) 2011, Intel Corporation.
+ * 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.
+ *

+ **************************************************************************/
+
+/* TODO
+ * - Split functions by vbt type
+ * - Make them all take drm_device
+ * - Check ioremap failures
+ */


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

+#include "mrst_bios.h"
+
+void mrst_get_fuse_settings(struct drm_device *dev)
+{


+ struct drm_psb_private *dev_priv = dev->dev_private;

+ struct pci_dev *pci_root = pci_get_bus_and_slot(0, 0);

+ uint32_t fuse_value = 0;
+ uint32_t fuse_value_tmp = 0;
+
+#define FB_REG06 0xD0810600
+#define FB_MIPI_DISABLE (1 << 11)
+#define FB_REG09 0xD0810900
+#define FB_REG09 0xD0810900
+#define FB_SKU_MASK 0x7000
+#define FB_SKU_SHIFT 12
+#define FB_SKU_100 0
+#define FB_SKU_100L 1
+#define FB_SKU_83 2
+ pci_write_config_dword(pci_root, 0xD0, FB_REG06);
+ pci_read_config_dword(pci_root, 0xD4, &fuse_value);
+


+ /* FB_MIPI_DISABLE doesn't mean LVDS on with Medfield */
+ if (IS_MRST(dev))
+ dev_priv->iLVDS_enable = fuse_value & FB_MIPI_DISABLE;

+
+ DRM_INFO("internal display is %s\n",
+ dev_priv->iLVDS_enable ? "LVDS display" : "MIPI display");
+
+ /* Prevent runtime suspend at start*/
+ if (dev_priv->iLVDS_enable) {
+ dev_priv->is_lvds_on = true;
+ dev_priv->is_mipi_on = false;
+ } else {
+ dev_priv->is_mipi_on = true;
+ dev_priv->is_lvds_on = false;
+ }
+
+ dev_priv->video_device_fuse = fuse_value;
+
+ pci_write_config_dword(pci_root, 0xD0, FB_REG09);
+ pci_read_config_dword(pci_root, 0xD4, &fuse_value);
+
+ dev_dbg(dev->dev, "SKU values is 0x%x.\n", fuse_value);
+ fuse_value_tmp = (fuse_value & FB_SKU_MASK) >> FB_SKU_SHIFT;
+
+ dev_priv->fuse_reg_value = fuse_value;
+
+ switch (fuse_value_tmp) {
+ case FB_SKU_100:
+ dev_priv->core_freq = 200;
+ break;
+ case FB_SKU_100L:
+ dev_priv->core_freq = 100;
+ break;
+ case FB_SKU_83:
+ dev_priv->core_freq = 166;
+ break;
+ default:


+ dev_warn(dev->dev, "Invalid SKU values, SKU value = 0x%08x\n",
+ fuse_value_tmp);

+ dev_priv->core_freq = 0;
+ }
+ dev_dbg(dev->dev, "LNC core clk is %dMHz.\n", dev_priv->core_freq);
+ pci_dev_put(pci_root);
+}
+
+/*
+ * Get the revison ID, B0:D2:F0;0x08
+ */
+void mid_get_pci_revID(struct drm_psb_private *dev_priv)
+{
+ uint32_t platform_rev_id = 0;
+ struct pci_dev *pci_gfx_root = pci_get_bus_and_slot(0, PCI_DEVFN(2, 0));
+
+ pci_read_config_dword(pci_gfx_root, 0x08, &platform_rev_id);
+ dev_priv->platform_rev_id = (uint8_t) platform_rev_id;
+ pci_dev_put(pci_gfx_root);
+ dev_dbg(dev_priv->dev->dev, "platform_rev_id is %x\n",
+ dev_priv->platform_rev_id);
+}
+
+void mrst_get_vbt_data(struct drm_psb_private *dev_priv)
+{
+ struct drm_device *dev = dev_priv->dev;
+ struct mrst_vbt *vbt = &dev_priv->vbt_data;
+ u32 addr;
+ u16 new_size;
+ u8 *vbt_virtual;
+ u8 bpi;
+ u8 number_desc = 0;
+ struct mrst_timing_info *dp_ti = &dev_priv->gct_data.DTD;
+ struct gct_r10_timing_info ti;
+ void *pGCT;
+ struct pci_dev *pci_gfx_root = pci_get_bus_and_slot(0, PCI_DEVFN(2, 0));
+
+ /* Get the address of the platform config vbt, B0:D2:F0;0xFC */
+ pci_read_config_dword(pci_gfx_root, 0xFC, &addr);
+ pci_dev_put(pci_gfx_root);
+
+ dev_dbg(dev->dev, "drm platform config address is %x\n", addr);
+
+ /* check for platform config address == 0. */
+ /* this means fw doesn't support vbt */
+
+ if (addr == 0) {
+ vbt->size = 0;
+ return;
+ }
+
+ /* get the virtual address of the vbt */
+ vbt_virtual = ioremap(addr, sizeof(*vbt));
+
+ memcpy(vbt, vbt_virtual, sizeof(*vbt));
+ iounmap(vbt_virtual); /* Free virtual address space */
+
+ dev_dbg(dev->dev, "GCT revision is %x\n", vbt->revision);
+
+ switch (vbt->revision) {
+ case 0:
+ vbt->mrst_gct = ioremap(addr + sizeof(*vbt) - 4,
+ vbt->size - sizeof(*vbt) + 4);
+ pGCT = vbt->mrst_gct;
+ bpi = ((struct mrst_gct_v1 *)pGCT)->PD.BootPanelIndex;
+ dev_priv->gct_data.bpi = bpi;
+ dev_priv->gct_data.pt =
+ ((struct mrst_gct_v1 *)pGCT)->PD.PanelType;
+ memcpy(&dev_priv->gct_data.DTD,
+ &((struct mrst_gct_v1 *)pGCT)->panel[bpi].DTD,
+ sizeof(struct mrst_timing_info));
+ dev_priv->gct_data.Panel_Port_Control =
+ ((struct mrst_gct_v1 *)pGCT)->panel[bpi].Panel_Port_Control;
+ dev_priv->gct_data.Panel_MIPI_Display_Descriptor =


+ ((struct mrst_gct_v1 *)pGCT)->panel[bpi].Panel_MIPI_Display_Descriptor;

+ break;
+ case 1:

+ vbt->mrst_gct = ioremap(addr + sizeof(*vbt) - 4,
+ vbt->size - sizeof(*vbt) + 4);
+ pGCT = vbt->mrst_gct;
+ bpi = ((struct mrst_gct_v2 *)pGCT)->PD.BootPanelIndex;
+ dev_priv->gct_data.bpi = bpi;
+ dev_priv->gct_data.pt =
+ ((struct mrst_gct_v2 *)pGCT)->PD.PanelType;
+ memcpy(&dev_priv->gct_data.DTD,
+ &((struct mrst_gct_v2 *)pGCT)->panel[bpi].DTD,
+ sizeof(struct mrst_timing_info));
+ dev_priv->gct_data.Panel_Port_Control =
+ ((struct mrst_gct_v2 *)pGCT)->panel[bpi].Panel_Port_Control;
+ dev_priv->gct_data.Panel_MIPI_Display_Descriptor =


+ ((struct mrst_gct_v2 *)pGCT)->panel[bpi].Panel_MIPI_Display_Descriptor;

+ break;
+ case 0x10:
+ /*header definition changed from rev 01 (v2) to rev 10h. */
+ /*so, some values have changed location*/
+ new_size = vbt->checksum; /*checksum contains lo size byte*/
+ /*LSB of mrst_gct contains hi size byte*/
+ new_size |= ((0xff & (unsigned int)vbt->mrst_gct)) << 8;
+
+ vbt->checksum = vbt->size; /*size contains the checksum*/
+ if (new_size > 0xff)
+ vbt->size = 0xff; /*restrict size to 255*/
+ else
+ vbt->size = new_size;
+
+ /* number of descriptors defined in the GCT */
+ number_desc = ((0xff00 & (unsigned int)vbt->mrst_gct)) >> 8;
+ bpi = ((0xff0000 & (unsigned int)vbt->mrst_gct)) >> 16;
+ vbt->mrst_gct = ioremap(addr + GCT_R10_HEADER_SIZE,
+ GCT_R10_DISPLAY_DESC_SIZE * number_desc);
+ pGCT = vbt->mrst_gct;
+ pGCT = (u8 *)pGCT + (bpi*GCT_R10_DISPLAY_DESC_SIZE);
+ dev_priv->gct_data.bpi = bpi; /*save boot panel id*/
+
+ /*copy the GCT display timings into a temp structure*/
+ memcpy(&ti, pGCT, sizeof(struct gct_r10_timing_info));
+
+ /*now copy the temp struct into the dev_priv->gct_data*/
+ dp_ti->pixel_clock = ti.pixel_clock;
+ dp_ti->hactive_hi = ti.hactive_hi;
+ dp_ti->hactive_lo = ti.hactive_lo;
+ dp_ti->hblank_hi = ti.hblank_hi;
+ dp_ti->hblank_lo = ti.hblank_lo;
+ dp_ti->hsync_offset_hi = ti.hsync_offset_hi;
+ dp_ti->hsync_offset_lo = ti.hsync_offset_lo;
+ dp_ti->hsync_pulse_width_hi = ti.hsync_pulse_width_hi;
+ dp_ti->hsync_pulse_width_lo = ti.hsync_pulse_width_lo;
+ dp_ti->vactive_hi = ti.vactive_hi;
+ dp_ti->vactive_lo = ti.vactive_lo;
+ dp_ti->vblank_hi = ti.vblank_hi;
+ dp_ti->vblank_lo = ti.vblank_lo;
+ dp_ti->vsync_offset_hi = ti.vsync_offset_hi;
+ dp_ti->vsync_offset_lo = ti.vsync_offset_lo;
+ dp_ti->vsync_pulse_width_hi = ti.vsync_pulse_width_hi;
+ dp_ti->vsync_pulse_width_lo = ti.vsync_pulse_width_lo;
+
+ /* Move the MIPI_Display_Descriptor data from GCT to dev priv */
+ dev_priv->gct_data.Panel_MIPI_Display_Descriptor =
+ *((u8 *)pGCT + 0x0d);
+ dev_priv->gct_data.Panel_MIPI_Display_Descriptor |=
+ (*((u8 *)pGCT + 0x0e)) << 8;
+ break;
+ default:
+ dev_err(dev->dev, "Unknown revision of GCT!\n");
+ vbt->size = 0;
+ }


+ /* FIXME: Need to sort out Medfield panel identifiers in future */

+}
+
diff --git a/drivers/staging/gma500/mrst_bios.h b/drivers/staging/gma500/mrst_bios.h
new file mode 100644
index 0000000..a257306
--- /dev/null
+++ b/drivers/staging/gma500/mrst_bios.h
@@ -0,0 +1,22 @@


+/**************************************************************************
+ * Copyright (c) 2011, Intel Corporation.
+ * 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.
+ *

+ **************************************************************************/
+
+extern void mrst_get_fuse_settings(struct drm_device *dev);
+extern void mid_get_pci_revID(struct drm_psb_private *dev_priv);
+extern void mrst_get_vbt_data(struct drm_psb_private *dev_priv);
diff --git a/drivers/staging/gma500/psb_drv.c b/drivers/staging/gma500/psb_drv.c
index 8df9c58..cbdc02c 100644
--- a/drivers/staging/gma500/psb_drv.c
+++ b/drivers/staging/gma500/psb_drv.c
@@ -27,6 +27,7 @@
#include "psb_reg.h"
#include "psb_intel_reg.h"
#include "psb_intel_bios.h"
+#include "mrst_bios.h"


#include <drm/drm_pciids.h>
#include "psb_powermgmt.h"
#include <linux/cpu.h>

@@ -165,214 +166,6 @@ static void psb_do_takedown(struct drm_device *dev)
/* FIXME: do we need to clean up the gtt here ? */
}

-void mrst_get_fuse_settings(struct drm_device *dev)
-{


- struct drm_psb_private *dev_priv = dev->dev_private;

- struct pci_dev *pci_root = pci_get_bus_and_slot(0, 0);
- uint32_t fuse_value = 0;
- uint32_t fuse_value_tmp = 0;
-
-#define FB_REG06 0xD0810600
-#define FB_MIPI_DISABLE (1 << 11)
-#define FB_REG09 0xD0810900
-#define FB_REG09 0xD0810900
-#define FB_SKU_MASK 0x7000
-#define FB_SKU_SHIFT 12
-#define FB_SKU_100 0
-#define FB_SKU_100L 1
-#define FB_SKU_83 2
- pci_write_config_dword(pci_root, 0xD0, FB_REG06);
- pci_read_config_dword(pci_root, 0xD4, &fuse_value);
-
- /* FB_MIPI_DISABLE doesn't mean LVDS on with Medfield */
- if (IS_MRST(dev))


- dev_priv->iLVDS_enable = fuse_value & FB_MIPI_DISABLE;

-
- DRM_INFO("internal display is %s\n",
- dev_priv->iLVDS_enable ? "LVDS display" : "MIPI display");
-
- /*prevent Runtime suspend at start*/
- if (dev_priv->iLVDS_enable) {
- dev_priv->is_lvds_on = true;
- dev_priv->is_mipi_on = false;
- } else {
- dev_priv->is_mipi_on = true;
- dev_priv->is_lvds_on = false;
- }
-
- dev_priv->video_device_fuse = fuse_value;
-
- pci_write_config_dword(pci_root, 0xD0, FB_REG09);
- pci_read_config_dword(pci_root, 0xD4, &fuse_value);
-


- DRM_INFO("SKU values is 0x%x.\n", fuse_value);

- fuse_value_tmp = (fuse_value & FB_SKU_MASK) >> FB_SKU_SHIFT;
-
- dev_priv->fuse_reg_value = fuse_value;
-
- switch (fuse_value_tmp) {
- case FB_SKU_100:
- dev_priv->core_freq = 200;
- break;
- case FB_SKU_100L:
- dev_priv->core_freq = 100;
- break;
- case FB_SKU_83:
- dev_priv->core_freq = 166;
- break;
- default:
- dev_warn(dev->dev, "Invalid SKU values, SKU value = 0x%08x\n",
- fuse_value_tmp);
- dev_priv->core_freq = 0;
- }
- DRM_INFO("LNC core clk is %dMHz.\n", dev_priv->core_freq);
- pci_dev_put(pci_root);
-}
-
-void mid_get_pci_revID(struct drm_psb_private *dev_priv)
-{
- uint32_t platform_rev_id = 0;
- struct pci_dev *pci_gfx_root = pci_get_bus_and_slot(0, PCI_DEVFN(2, 0));
-
- /*get the revison ID, B0:D2:F0;0x08 */
- pci_read_config_dword(pci_gfx_root, 0x08, &platform_rev_id);
- dev_priv->platform_rev_id = (uint8_t) platform_rev_id;
- pci_dev_put(pci_gfx_root);
- dev_info(dev_priv->dev->dev, "platform_rev_id is %x\n",
- dev_priv->platform_rev_id);
-}
-
-void mrst_get_vbt_data(struct drm_psb_private *dev_priv)
-{
- struct mrst_vbt *vbt = &dev_priv->vbt_data;
- u32 platform_config_address;
- u16 new_size;
- u8 *vbt_virtual;
- u8 bpi;
- u8 number_desc = 0;
- struct mrst_timing_info *dp_ti = &dev_priv->gct_data.DTD;
- struct gct_r10_timing_info ti;
- void *pGCT;
- struct pci_dev *pci_gfx_root = pci_get_bus_and_slot(0, PCI_DEVFN(2, 0));
-
- /*get the address of the platform config vbt, B0:D2:F0;0xFC */
- pci_read_config_dword(pci_gfx_root, 0xFC, &platform_config_address);
- pci_dev_put(pci_gfx_root);
- DRM_INFO("drm platform config address is %x\n",
- platform_config_address);
-
- /* check for platform config address == 0. */
- /* this means fw doesn't support vbt */
-
- if (platform_config_address == 0) {
- vbt->size = 0;
- return;
- }
-
- /* get the virtual address of the vbt */
- vbt_virtual = ioremap(platform_config_address, sizeof(*vbt));
-
- memcpy(vbt, vbt_virtual, sizeof(*vbt));
- iounmap(vbt_virtual); /* Free virtual address space */
-
- printk(KERN_ALERT "GCT revision is %x\n", vbt->revision);
-
- switch (vbt->revision) {
- case 0:
- vbt->mrst_gct = NULL;
- vbt->mrst_gct = \
- ioremap(platform_config_address + sizeof(*vbt) - 4,
- vbt->size - sizeof(*vbt) + 4);
- pGCT = vbt->mrst_gct;
- bpi = ((struct mrst_gct_v1 *)pGCT)->PD.BootPanelIndex;
- dev_priv->gct_data.bpi = bpi;
- dev_priv->gct_data.pt =
- ((struct mrst_gct_v1 *)pGCT)->PD.PanelType;
- memcpy(&dev_priv->gct_data.DTD,
- &((struct mrst_gct_v1 *)pGCT)->panel[bpi].DTD,
- sizeof(struct mrst_timing_info));
- dev_priv->gct_data.Panel_Port_Control =
- ((struct mrst_gct_v1 *)pGCT)->panel[bpi].Panel_Port_Control;
- dev_priv->gct_data.Panel_MIPI_Display_Descriptor =


- ((struct mrst_gct_v1 *)pGCT)->panel[bpi].Panel_MIPI_Display_Descriptor;

- break;
- case 1:

- vbt->mrst_gct = NULL;
- vbt->mrst_gct = \
- ioremap(platform_config_address + sizeof(*vbt) - 4,
- vbt->size - sizeof(*vbt) + 4);
- pGCT = vbt->mrst_gct;
- bpi = ((struct mrst_gct_v2 *)pGCT)->PD.BootPanelIndex;
- dev_priv->gct_data.bpi = bpi;
- dev_priv->gct_data.pt =
- ((struct mrst_gct_v2 *)pGCT)->PD.PanelType;
- memcpy(&dev_priv->gct_data.DTD,
- &((struct mrst_gct_v2 *)pGCT)->panel[bpi].DTD,
- sizeof(struct mrst_timing_info));
- dev_priv->gct_data.Panel_Port_Control =
- ((struct mrst_gct_v2 *)pGCT)->panel[bpi].Panel_Port_Control;
- dev_priv->gct_data.Panel_MIPI_Display_Descriptor =


- ((struct mrst_gct_v2 *)pGCT)->panel[bpi].Panel_MIPI_Display_Descriptor;

- break;
- case 0x10:
- /*header definition changed from rev 01 (v2) to rev 10h. */
- /*so, some values have changed location*/
- new_size = vbt->checksum; /*checksum contains lo size byte*/
- /*LSB of mrst_gct contains hi size byte*/
- new_size |= ((0xff & (unsigned int)vbt->mrst_gct)) << 8;
-
- vbt->checksum = vbt->size; /*size contains the checksum*/
- if (new_size > 0xff)
- vbt->size = 0xff; /*restrict size to 255*/
- else
- vbt->size = new_size;
-
- /* number of descriptors defined in the GCT */
- number_desc = ((0xff00 & (unsigned int)vbt->mrst_gct)) >> 8;
- bpi = ((0xff0000 & (unsigned int)vbt->mrst_gct)) >> 16;
- vbt->mrst_gct = NULL;
- vbt->mrst_gct = \
- ioremap(platform_config_address + GCT_R10_HEADER_SIZE,
- GCT_R10_DISPLAY_DESC_SIZE * number_desc);
- pGCT = vbt->mrst_gct;
- pGCT = (u8 *)pGCT + (bpi*GCT_R10_DISPLAY_DESC_SIZE);
- dev_priv->gct_data.bpi = bpi; /*save boot panel id*/
-
- /*copy the GCT display timings into a temp structure*/
- memcpy(&ti, pGCT, sizeof(struct gct_r10_timing_info));
-
- /*now copy the temp struct into the dev_priv->gct_data*/
- dp_ti->pixel_clock = ti.pixel_clock;
- dp_ti->hactive_hi = ti.hactive_hi;
- dp_ti->hactive_lo = ti.hactive_lo;
- dp_ti->hblank_hi = ti.hblank_hi;
- dp_ti->hblank_lo = ti.hblank_lo;
- dp_ti->hsync_offset_hi = ti.hsync_offset_hi;
- dp_ti->hsync_offset_lo = ti.hsync_offset_lo;
- dp_ti->hsync_pulse_width_hi = ti.hsync_pulse_width_hi;
- dp_ti->hsync_pulse_width_lo = ti.hsync_pulse_width_lo;
- dp_ti->vactive_hi = ti.vactive_hi;
- dp_ti->vactive_lo = ti.vactive_lo;
- dp_ti->vblank_hi = ti.vblank_hi;
- dp_ti->vblank_lo = ti.vblank_lo;
- dp_ti->vsync_offset_hi = ti.vsync_offset_hi;
- dp_ti->vsync_offset_lo = ti.vsync_offset_lo;
- dp_ti->vsync_pulse_width_hi = ti.vsync_pulse_width_hi;
- dp_ti->vsync_pulse_width_lo = ti.vsync_pulse_width_lo;
-
- /*mov the MIPI_Display_Descriptor data from GCT to dev priv*/
- dev_priv->gct_data.Panel_MIPI_Display_Descriptor =
- *((u8 *)pGCT + 0x0d);
- dev_priv->gct_data.Panel_MIPI_Display_Descriptor |=
- (*((u8 *)pGCT + 0x0e)) << 8;
- break;
- default:
- printk(KERN_ERR "Unknown revision of GCT!\n");
- vbt->size = 0;
- }
- /* FIXME: Need to sort out Medfield panel identifiers in future */
-}
-


static void psb_get_core_freq(struct drm_device *dev)

{
uint32_t clock;

Alan Cox

unread,
Jun 16, 2011, 12:43:19 PM6/16/11
to gr...@kroah.com, linux-...@vger.kernel.org
From: Alan Cox <al...@linux.intel.com>

Signed-off-by: Alan Cox <al...@linux.intel.com>
---

drivers/staging/gma500/mdfld_intel_display.c | 33 ++++++++++++++++++++++++--
drivers/staging/gma500/mdfld_output.h | 3 ++
drivers/staging/gma500/mrst_bios.c | 4 ++-
drivers/staging/gma500/psb_intel_display.c | 9 +++----
4 files changed, 39 insertions(+), 10 deletions(-)

diff --git a/drivers/staging/gma500/mdfld_intel_display.c b/drivers/staging/gma500/mdfld_intel_display.c
index 26d7f80..0b619b6 100644
--- a/drivers/staging/gma500/mdfld_intel_display.c
+++ b/drivers/staging/gma500/mdfld_intel_display.c
@@ -44,7 +44,6 @@
/* Hardcoded currently */
static int ksel = KSEL_CRYSTAL_19;

-extern struct drm_device *gpDrmDevice;
extern void mdfld_save_display(struct drm_device *dev);
extern bool gbgfxsuspended;

@@ -561,10 +560,10 @@ static void mdfld_crtc_dpms(struct drm_crtc *crtc, int mode)
return;



/* Ignore if system is already in DSR and in suspended state. */

- if(gbgfxsuspended && dev_priv->dispstatus == false && mode == 3){
+ if(/*gbgfxsuspended */0 && dev_priv->dispstatus == false && mode == 3){


if(dev_priv->rpm_enabled && pipe == 1){

// dev_priv->is_mipi_on = false;
- pm_request_idle(&gpDrmDevice->pdev->dev);
+ pm_request_idle(&dev->pdev->dev);
}
return;
}else if(mode == 0) {
@@ -1386,3 +1385,31 @@ mrst_crtc_mode_set_exit:

return 0;
}
+
+static void mdfld_crtc_prepare(struct drm_crtc *crtc)
+{
+ struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
+ crtc_funcs->dpms(crtc, DRM_MODE_DPMS_OFF);
+}
+
+static void mdfld_crtc_commit(struct drm_crtc *crtc)
+{
+ struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
+ crtc_funcs->dpms(crtc, DRM_MODE_DPMS_ON);
+}
+
+static bool mdfld_crtc_mode_fixup(struct drm_crtc *crtc,
+ struct drm_display_mode *mode,
+ struct drm_display_mode *adjusted_mode)
+{


+ return true;
+}
+

+const struct drm_crtc_helper_funcs mdfld_helper_funcs = {
+ .dpms = mdfld_crtc_dpms,
+ .mode_fixup = mdfld_crtc_mode_fixup,
+ .mode_set = mdfld_crtc_mode_set,
+ .mode_set_base = mdfld__intel_pipe_set_base,
+ .prepare = mdfld_crtc_prepare,
+ .commit = mdfld_crtc_commit,
+};
diff --git a/drivers/staging/gma500/mdfld_output.h b/drivers/staging/gma500/mdfld_output.h
index 53b57db..70f2302a 100644
--- a/drivers/staging/gma500/mdfld_output.h
+++ b/drivers/staging/gma500/mdfld_output.h
@@ -74,4 +74,7 @@ int mdfld_panel_dpi(struct drm_device *dev);


int mdfld_get_panel_type(struct drm_device *dev, int pipe);
void mdfld_disable_crtc (struct drm_device *dev, int pipe);

+extern const struct drm_crtc_helper_funcs mdfld_helper_funcs;
+extern const struct drm_crtc_funcs mdfld_intel_crtc_funcs;
+
#endif
diff --git a/drivers/staging/gma500/mrst_bios.c b/drivers/staging/gma500/mrst_bios.c
index 103777b..c3707f4 100644
--- a/drivers/staging/gma500/mrst_bios.c
+++ b/drivers/staging/gma500/mrst_bios.c
@@ -30,7 +30,7 @@
#include "mrst_bios.h"
#include "mdfld_output.h"

-static int panel_id;
+static int panel_id = GCT_DETECT;
module_param_named(panel_id, panel_id, int, 0600);
MODULE_PARM_DESC(panel_id, "Panel Identifier");

@@ -237,7 +237,7 @@ void mrst_get_vbt_data(struct drm_psb_private *dev_priv)


dev_err(dev->dev, "Unknown revision of GCT!\n");

vbt->size = 0;
}
- if (IS_MDFLD(dev_priv->dev)){
+ if (IS_MFLD(dev_priv->dev)){
if (panel_id == GCT_DETECT) {
if (dev_priv->gct_data.bpi == 2) {
dev_info(dev->dev, "[GFX] PYR Panel Detected\n");
diff --git a/drivers/staging/gma500/psb_intel_display.c b/drivers/staging/gma500/psb_intel_display.c
index ac0d9da..907c68e 100644
--- a/drivers/staging/gma500/psb_intel_display.c
+++ b/drivers/staging/gma500/psb_intel_display.c
@@ -29,6 +29,7 @@
#include "psb_intel_display.h"
#include "psb_powermgmt.h"

+#include "mdfld_output.h"

struct psb_intel_clock_t {
/* given values */
@@ -1303,12 +1304,10 @@ void psb_intel_crtc_init(struct drm_device *dev, int pipe,
return;
}

-#if 0 /* FIXME */
if (IS_MFLD(dev))
drm_crtc_init(dev, &psb_intel_crtc->base,
- &mfld_intel_crtc_funcs);
+ &mdfld_intel_crtc_funcs);
else
-#endif
drm_crtc_init(dev, &psb_intel_crtc->base,
&psb_intel_crtc_funcs);

@@ -1336,9 +1335,9 @@ void psb_intel_crtc_init(struct drm_device *dev, int pipe,


if (IS_MRST(dev))
drm_crtc_helper_add(&psb_intel_crtc->base,
&mrst_helper_funcs);

-/* else if (IS_MDFLD(dev))
+ else if (IS_MFLD(dev))
drm_crtc_helper_add(&psb_intel_crtc->base,
- &mfld_helper_funcs); */
+ &mdfld_helper_funcs);
else
drm_crtc_helper_add(&psb_intel_crtc->base,
&psb_intel_helper_funcs);

Alan Cox

unread,
Jun 16, 2011, 12:43:35 PM6/16/11
to gr...@kroah.com, linux-...@vger.kernel.org
From: Andrew Morton <ak...@linux-foundation.org>

x86_64 allmodconfig:

ERROR: "__bad_udelay" [drivers/staging/gma500/psb_gfx.ko] undefined!

Signed-off-by: Andrew Morton <ak...@linux-foundation.org>


Signed-off-by: Alan Cox <al...@linux.intel.com>
---

drivers/staging/gma500/psb_intel_display.c | 2 +-


1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/staging/gma500/psb_intel_display.c b/drivers/staging/gma500/psb_intel_display.c
index 907c68e..0e9758a 100644
--- a/drivers/staging/gma500/psb_intel_display.c
+++ b/drivers/staging/gma500/psb_intel_display.c
@@ -332,7 +332,7 @@ static bool psb_intel_find_best_PLL(struct drm_crtc *crtc, int target,
void psb_intel_wait_for_vblank(struct drm_device *dev)
{
/* Wait for 20ms, i.e. one cycle at 50hz. */
- udelay(20000);
+ mdelay(20);
}

int psb_intel_pipe_set_base(struct drm_crtc *crtc,

Alan Cox

unread,
Jun 16, 2011, 12:43:01 PM6/16/11
to gr...@kroah.com, linux-...@vger.kernel.org
From: Alan Cox <al...@linux.intel.com>

Missed in the original merge work

Signed-off-by: Alan Cox <al...@linux.intel.com>
---

drivers/staging/gma500/mrst_bios.c | 29 ++++++++++++++++++++++++++++-
1 files changed, 28 insertions(+), 1 deletions(-)

diff --git a/drivers/staging/gma500/mrst_bios.c b/drivers/staging/gma500/mrst_bios.c
index 0d944c4..103777b 100644
--- a/drivers/staging/gma500/mrst_bios.c
+++ b/drivers/staging/gma500/mrst_bios.c
@@ -28,6 +28,12 @@
#include "psb_drm.h"
#include "psb_drv.h"
#include "mrst_bios.h"
+#include "mdfld_output.h"
+
+static int panel_id;
+module_param_named(panel_id, panel_id, int, 0600);
+MODULE_PARM_DESC(panel_id, "Panel Identifier");
+

void mrst_get_fuse_settings(struct drm_device *dev)
{
@@ -231,6 +237,27 @@ void mrst_get_vbt_data(struct drm_psb_private *dev_priv)


dev_err(dev->dev, "Unknown revision of GCT!\n");
vbt->size = 0;
}

- /* FIXME: Need to sort out Medfield panel identifiers in future */
+ if (IS_MDFLD(dev_priv->dev)){
+ if (panel_id == GCT_DETECT) {
+ if (dev_priv->gct_data.bpi == 2) {
+ dev_info(dev->dev, "[GFX] PYR Panel Detected\n");
+ dev_priv->panel_id = PYR_CMD;
+ panel_id = PYR_CMD;
+ }
+ else if(dev_priv->gct_data.bpi == 0) {
+ dev_info(dev->dev, "[GFX] TMD Panel Detected.\n");
+ dev_priv->panel_id = TMD_VID;
+ panel_id = TMD_VID;
+ }
+ else {
+ dev_info(dev->dev, "[GFX] Default Panel (TPO)\n");
+ dev_priv->panel_id = TPO_CMD;
+ panel_id = TPO_CMD;
+ }
+ } else {
+ dev_info(dev->dev, "[GFX] Panel Parameter Passed in through cmd line\n");
+ dev_priv->panel_id = panel_id;
+ }
+ }

Greg KH

unread,
Jun 28, 2011, 5:18:59 PM6/28/11
to Alan Cox, linux-...@vger.kernel.org
On Thu, Jun 16, 2011 at 05:07:01PM +0100, Alan Cox wrote:
> From: Alan Cox <al...@linux.intel.com>
>
> We need this for the framebuffer in order to ensure that the kernel
> framebuffer layer can handle it when using KMS. Except for the base
> framebuffer this isn't a concern.
>
> Add an npage field to the gtt as too many copies of the page calculation
> are getting spread around the code.

>
> Signed-off-by: Alan Cox <al...@linux.intel.com>
> ---
>
> drivers/staging/gma500/psb_fb.c | 47 ++++++++++++++++++++++++--------------
> drivers/staging/gma500/psb_fb.h | 1 +
> drivers/staging/gma500/psb_gtt.c | 18 ++++++---------
> drivers/staging/gma500/psb_gtt.h | 5 ++--
> 4 files changed, 42 insertions(+), 29 deletions(-)

This doesn't apply:

patching file drivers/staging/gma500/psb_fb.c
patching file drivers/staging/gma500/psb_fb.h
patching file drivers/staging/gma500/psb_gtt.c
Hunk #1 FAILED at 79.
Hunk #3 FAILED at 120.
Hunk #5 FAILED at 149.
Hunk #7 FAILED at 193.
4 out of 7 hunks FAILED -- saving rejects to file drivers/staging/gma500/psb_gtt.c.rej
patching file drivers/staging/gma500/psb_gtt.h

Any ideas?

Is there drm changes in linux-next for this driver that I don't have?

If so, maybe we need to just start sending these patches through that tree?

greg k-h

Greg KH

unread,
Jun 28, 2011, 5:20:16 PM6/28/11
to Alan Cox, linux-...@vger.kernel.org
On Thu, Jun 16, 2011 at 05:08:00PM +0100, Alan Cox wrote:
> From: Alan Cox <al...@linux.intel.com>
>
> Restructure this to work the same way as the i915 frame buffer does. That
> cleans up various chunks of code.
>
> We can now set a mode in modetest but mode restore is a bit iffy
>
> Signed-off-by: Alan Cox <al...@linux.intel.com>

As other patches didn't apply, I'll have to stop here in the series :(

Alan Cox

unread,
Jun 28, 2011, 6:02:45 PM6/28/11
to Greg KH, linux-...@vger.kernel.org, Jiri Kosina
> Any ideas?
>
> Is there drm changes in linux-next for this driver that I don't have?
>
> If so, maybe we need to just start sending these patches through that tree?

Not DRM - looks like more sem-random treewide damage in -next tht has yet
again not gone via the maintainers of subsystems.

e44ba033c5654dbfda53461c9b1f7dd9bd1d198f

28f65c11f2ffb3957259dece647a24f8ad2e241b

Can you drop the bits you have merged and I'll send you a new set (which
will instead break the stuff Jiri has in his tree and he can fix it up)

Really though this sort of treewide trivial has to stop, its costing tons
of time and delays in real work. It should all be going via maintainers
of subsystems but clearly Jiri is letting stuff through that isn't
trivial but is in fact nuisance.

Alan

Jiri Kosina

unread,
Jun 28, 2011, 6:09:55 PM6/28/11
to Alan Cox, Greg KH, linux-...@vger.kernel.org
On Tue, 28 Jun 2011, Alan Cox wrote:

> > Is there drm changes in linux-next for this driver that I don't have?
> >
> > If so, maybe we need to just start sending these patches through that tree?
>
> Not DRM - looks like more sem-random treewide damage in -next tht has yet
> again not gone via the maintainers of subsystems.
>
> e44ba033c5654dbfda53461c9b1f7dd9bd1d198f
>
> 28f65c11f2ffb3957259dece647a24f8ad2e241b
>
> Can you drop the bits you have merged and I'll send you a new set (which
> will instead break the stuff Jiri has in his tree and he can fix it up)
>
> Really though this sort of treewide trivial has to stop, its costing tons
> of time and delays in real work. It should all be going via maintainers
> of subsystems but clearly Jiri is letting stuff through that isn't
> trivial but is in fact nuisance.

So, what I am normally doing:

- I usually wait several weeks (!) before I pick up patches to trivial
tree that have been also sent to maintainers. Exactly to avoid this kind
of situation.
With treewide patches, the situation is of course a little bit
different in principle.
- I reject to apply any drivers/staging bits on a regular basis. I
consider drivers/staging a moving target, and I usually re-route
anything touching drivers/staging to Greg immediately. Admittedly, I
have failed to do so in this case, sorry about that.
- I consider the trivial tree to be really the 'tail' of the whole
development process, so whenever there is any merge conflict in
linux-next caused by anything in trivial tree, I always take the
responsibility to resolve the conflict so that subsystem maintainers are
not bothered

I will drop the staging bits, sorry again for missing those in the bulk.

I am still wondering how come that this is causing trouble to anyone
though -- is anyone really developing real code on top of linux-next
(which should be there to cross-check merge problems between subsystems
and test functionality) instead of particular subsystem tree?

Thanks,

--
Jiri Kosina
SUSE Labs

Jiri Kosina

unread,
Jun 28, 2011, 6:15:29 PM6/28/11
to Alan Cox, Greg KH, linux-...@vger.kernel.org
On Wed, 29 Jun 2011, Jiri Kosina wrote:

> > Can you drop the bits you have merged and I'll send you a new set (which
> > will instead break the stuff Jiri has in his tree and he can fix it up)

[ ... snip ... ]


> I will drop the staging bits, sorry again for missing those in the bulk.

Or just let me know whatever you prefer (both now and in the longer
term as well).

I can either drop the gma500 bits I have queued now (and stop applying
anything touching it, hard rule), or you rebasing on top of Greg's staging
tree instead of linux-next (and I sorting out the merge conflict later).

> I am still wondering how come that this is causing trouble to anyone
> though -- is anyone really developing real code on top of linux-next
> (which should be there to cross-check merge problems between subsystems
> and test functionality) instead of particular subsystem tree?

--

Joe Perches

unread,
Jun 28, 2011, 6:18:06 PM6/28/11
to Alan Cox, Greg KH, linux-...@vger.kernel.org, Jiri Kosina
On Tue, 2011-06-28 at 23:02 +0100, Alan Cox wrote:
> Really though this sort of treewide trivial has to stop, its costing tons
> of time and delays in real work. It should all be going via maintainers
> of subsystems but clearly Jiri is letting stuff through that isn't
> trivial but is in fact nuisance.

Because standardizing APIs is too hard?

Another option is for you to develop with -next.

Alan Cox

unread,
Jun 28, 2011, 6:41:52 PM6/28/11
to Jiri Kosina, Greg KH, linux-...@vger.kernel.org
> I am still wondering how come that this is causing trouble to anyone
> though -- is anyone really developing real code on top of linux-next
> (which should be there to cross-check merge problems between subsystems
> and test functionality) instead of particular subsystem tree?

I run -next on a regular basis. I'm actually doing a lot of Linux mid
development on it because I need bits going via various trees from x86 to
staging to input together.

I'm not btw saying your approach is wrong - in fact I imagine its the
only way to make it managable for some things but in the gma500 case at
least and I suspect much of staging it tends to cause merge problems. It
would be helpful if you route any gma500 bits via me because of the
amount of change in that subtree.

Alan

Alan Cox

unread,
Jun 28, 2011, 6:42:35 PM6/28/11
to Jiri Kosina, Greg KH, linux-...@vger.kernel.org
> I can either drop the gma500 bits I have queued now (and stop applying
> anything touching it, hard rule), or you rebasing on top of Greg's staging
> tree instead of linux-next (and I sorting out the merge conflict later).

If you can drop the gma500 bits and send them my way I'll merge them via
the gma500 pile.

Jiri Kosina

unread,
Jun 28, 2011, 6:54:41 PM6/28/11
to Alan Cox, Greg KH, linux-...@vger.kernel.org
On Tue, 28 Jun 2011, Alan Cox wrote:

> > I am still wondering how come that this is causing trouble to anyone
> > though -- is anyone really developing real code on top of linux-next
> > (which should be there to cross-check merge problems between subsystems
> > and test functionality) instead of particular subsystem tree?
>

> I run -next on a regular basis. I'm actually doing a lot of Linux mid
> development on it because I need bits going via various trees from x86 to
> staging to input together.

Yes, cross-tree development is definitely a mode in which I can imagine
linux-next could be used as a base for actual code development (and
probably the only one which is justifiable).

> I'm not btw saying your approach is wrong - in fact I imagine its the
> only way to make it managable for some things but in the gma500 case at
> least and I suspect much of staging it tends to cause merge problems. It
> would be helpful if you route any gma500 bits via me because of the
> amount of change in that subtree.

Yeah, thanks.

As said already -- normally I don't accept staging bits at all (for a
reason), that was a mistake. Sorry for that.

On Tue, 28 Jun 2011, Alan Cox wrote:

> > I can either drop the gma500 bits I have queued now (and stop applying
> > anything touching it, hard rule), or you rebasing on top of Greg's staging
> > tree instead of linux-next (and I sorting out the merge conflict later).
>
> If you can drop the gma500 bits and send them my way I'll merge them via
> the gma500 pile.

Sure. I have already pushed out a tree with those reverted and will be
sending you the patches separately in a second.

--
Jiri Kosina
SUSE Labs

Reply all
Reply to author
Forward
0 new messages