diff options
Diffstat (limited to 'drivers/staging/gma500')
22 files changed, 288 insertions, 188 deletions
diff --git a/drivers/staging/gma500/accel_2d.c b/drivers/staging/gma500/accel_2d.c index 14400fcfe8a7..114b99a1ce19 100644 --- a/drivers/staging/gma500/accel_2d.c +++ b/drivers/staging/gma500/accel_2d.c @@ -111,14 +111,15 @@ static int psbfb_2d_submit(struct drm_psb_private *dev_priv, uint32_t *cmdbuf, int ret = 0; int i; unsigned submit_size; + unsigned long flags; - mutex_lock(&dev_priv->mutex_2d); + spin_lock_irqsave(&dev_priv->lock_2d, flags); while (size > 0) { submit_size = (size < 0x60) ? size : 0x60; size -= submit_size; ret = psb_2d_wait_available(dev_priv, submit_size); if (ret) - break; + break; submit_size <<= 2; @@ -127,7 +128,7 @@ static int psbfb_2d_submit(struct drm_psb_private *dev_priv, uint32_t *cmdbuf, (void)PSB_RSGX32(PSB_SGX_2D_SLAVE_PORT + i - 4); } - mutex_unlock(&dev_priv->mutex_2d); + spin_unlock_irqrestore(&dev_priv->lock_2d, flags); return ret; } @@ -327,8 +328,9 @@ int psbfb_sync(struct fb_info *info) struct drm_psb_private *dev_priv = dev->dev_private; unsigned long _end = jiffies + DRM_HZ; int busy = 0; + unsigned long flags; - mutex_lock(&dev_priv->mutex_2d); + spin_lock_irqsave(&dev_priv->lock_2d, flags); /* * First idle the 2D engine. */ @@ -357,7 +359,7 @@ int psbfb_sync(struct fb_info *info) _PSB_C2B_STATUS_BUSY) != 0); out: - mutex_unlock(&dev_priv->mutex_2d); + spin_unlock_irqrestore(&dev_priv->lock_2d, flags); return (busy) ? -EBUSY : 0; } @@ -388,19 +390,19 @@ int psb_accel_ioctl(struct drm_device *dev, void *data, struct drm_file *file) for (i = 0; i < op->size; i++, op_ptr++) { u32 r = *op_ptr & 0xF0000000; /* Fill in the GTT offsets for the command buffer */ - if (r == PSB_2D_SRC_SURF_BH || - r == PSB_2D_DST_SURF_BH || + if (r == PSB_2D_SRC_SURF_BH || + r == PSB_2D_DST_SURF_BH || r == PSB_2D_MASK_SURF_BH || r == PSB_2D_PAT_SURF_BH) { i++; op_ptr++; if (i == op->size) goto bad; - if (*op_ptr) + if (*op_ptr) goto bad; - *op_ptr = gtt->offset; - continue; - } + *op_ptr = gtt->offset; + continue; + } } psbfb_2d_submit(dev_priv, op->cmd, op->size); err = 0; diff --git a/drivers/staging/gma500/cdv_device.c b/drivers/staging/gma500/cdv_device.c index 87614e0d396a..8ec10caab13e 100644 --- a/drivers/staging/gma500/cdv_device.c +++ b/drivers/staging/gma500/cdv_device.c @@ -30,7 +30,6 @@ #define VGA_SR_INDEX 0x3c4 #define VGA_SR_DATA 0x3c5 -/* FIXME: should check if we are the active VGA device ?? */ static void cdv_disable_vga(struct drm_device *dev) { u8 sr1; diff --git a/drivers/staging/gma500/framebuffer.c b/drivers/staging/gma500/framebuffer.c index ebfde13ec18f..3f39a37456fc 100644 --- a/drivers/staging/gma500/framebuffer.c +++ b/drivers/staging/gma500/framebuffer.c @@ -37,6 +37,7 @@ #include "psb_intel_reg.h" #include "psb_intel_drv.h" #include "framebuffer.h" +#include "gtt.h" #include "mdfld_output.h" @@ -91,6 +92,21 @@ static int psbfb_setcolreg(unsigned regno, unsigned red, unsigned green, return 0; } +static int psbfb_pan(struct fb_var_screeninfo *var, struct fb_info *info) +{ + struct psb_fbdev *fbdev = info->par; + struct psb_framebuffer *psbfb = &fbdev->pfb; + struct drm_device *dev = psbfb->base.dev; + + /* + * We have to poke our nose in here. The core fb code assumes + * panning is part of the hardware that can be invoked before + * the actual fb is mapped. In our case that isn't quite true. + */ + if (psbfb->gtt->npage) + psb_gtt_roll(dev, psbfb->gtt, var->yoffset); + return 0; +} void psbfb_suspend(struct drm_device *dev) { @@ -217,6 +233,21 @@ static struct fb_ops psbfb_ops = { .fb_ioctl = psbfb_ioctl, }; +static struct fb_ops psbfb_roll_ops = { + .owner = THIS_MODULE, + .fb_check_var = drm_fb_helper_check_var, + .fb_set_par = drm_fb_helper_set_par, + .fb_blank = drm_fb_helper_blank, + .fb_setcolreg = psbfb_setcolreg, + .fb_fillrect = cfb_fillrect, + .fb_copyarea = cfb_copyarea, + .fb_imageblit = cfb_imageblit, + .fb_pan_display = psbfb_pan, + .fb_mmap = psbfb_mmap, + .fb_sync = psbfb_sync, + .fb_ioctl = psbfb_ioctl, +}; + static struct fb_ops psbfb_unaccel_ops = { .owner = THIS_MODULE, .fb_check_var = drm_fb_helper_check_var, @@ -304,6 +335,7 @@ static struct drm_framebuffer *psb_framebuffer_create * psbfb_alloc - allocate frame buffer memory * @dev: the DRM device * @aligned_size: space needed + * @force: fall back to GEM buffers if need be * * Allocate the frame buffer. In the usual case we get a GTT range that * is stolen memory backed and life is simple. If there isn't sufficient @@ -311,11 +343,9 @@ static struct drm_framebuffer *psb_framebuffer_create * 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. */ -static struct gtt_range *psbfb_alloc(struct drm_device *dev, int aligned_size) +static struct gtt_range *psbfb_alloc(struct drm_device *dev, + int aligned_size, int force) { struct gtt_range *backing; /* Begin by trying to use stolen memory backing */ @@ -326,6 +356,9 @@ static struct gtt_range *psbfb_alloc(struct drm_device *dev, int aligned_size) return backing; psb_gtt_free_range(dev, backing); } + if (!force) + return NULL; + /* Next try using GEM host memory */ backing = psb_gtt_alloc_range(dev, aligned_size, "fb(gem)", 0); if (backing == NULL) @@ -359,6 +392,7 @@ static int psbfb_create(struct psb_fbdev *fbdev, int size; int ret; struct gtt_range *backing; + int gtt_roll = 1; mode_cmd.width = sizes->surface_width; mode_cmd.height = sizes->surface_height; @@ -368,17 +402,37 @@ static int psbfb_create(struct psb_fbdev *fbdev, if (mode_cmd.bpp == 24) 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); + /* Acceleration via the GTT requires pitch to be 4096 byte aligned + (ie 1024 or 2048 pixels in normal use) */ + mode_cmd.pitch = ALIGN(mode_cmd.width * ((mode_cmd.bpp + 7) / 8), 4096); mode_cmd.depth = sizes->surface_depth; size = mode_cmd.pitch * mode_cmd.height; size = ALIGN(size, PAGE_SIZE); /* Allocate the framebuffer in the GTT with stolen page backing */ - backing = psbfb_alloc(dev, size); - if (backing == NULL) - return -ENOMEM; + backing = psbfb_alloc(dev, size, 0); + if (backing == NULL) { + /* + * We couldn't get the space we wanted, fall back to the + * display engine requirement instead. The HW requires + * the pitch to be 64 byte aligned + */ + + gtt_roll = 0; /* Don't use GTT accelerated scrolling */ + + 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; + size = ALIGN(size, PAGE_SIZE); + + /* Allocate the framebuffer in the GTT with stolen page + backing when there is room */ + backing = psbfb_alloc(dev, size, 1); + if (backing == NULL) + return -ENOMEM; + } mutex_lock(&dev->struct_mutex); @@ -402,11 +456,14 @@ static int psbfb_create(struct psb_fbdev *fbdev, strcpy(info->fix.id, "psbfb"); info->flags = FBINFO_DEFAULT; - /* No 2D engine */ - if (!dev_priv->ops->accel_2d) - info->fbops = &psbfb_unaccel_ops; - else + if (gtt_roll) { /* GTT rolling seems best */ + info->fbops = &psbfb_roll_ops; + info->flags |= FBINFO_HWACCEL_YPAN; + } + else if (dev_priv->ops->accel_2d) /* 2D engine */ info->fbops = &psbfb_ops; + else /* Software */ + info->fbops = &psbfb_unaccel_ops; ret = fb_alloc_cmap(&info->cmap, 256, 0); if (ret) { @@ -416,6 +473,8 @@ static int psbfb_create(struct psb_fbdev *fbdev, info->fix.smem_start = dev->mode_config.fb_base; info->fix.smem_len = size; + info->fix.ywrapstep = gtt_roll; + info->fix.ypanstep = gtt_roll; if (backing->stolen) { /* Accessed stolen memory directly */ @@ -733,9 +792,12 @@ static void psb_setup_outputs(struct drm_device *dev) clone_mask = (1 << INTEL_OUTPUT_MIPI2); break; case INTEL_OUTPUT_HDMI: - if (IS_MFLD(dev)) + /* HDMI on crtc 1 for SoC devices and crtc 0 for + Cedarview. HDMI on Poulsbo is only via external + logic */ + if (IS_MFLD(dev) || IS_MRST(dev)) crtc_mask = (1 << 1); - else /* FIXME: review Oaktrail */ + else crtc_mask = (1 << 0); /* Cedarview */ clone_mask = (1 << INTEL_OUTPUT_HDMI); break; diff --git a/drivers/staging/gma500/gem.c b/drivers/staging/gma500/gem.c index 65fdd6b8ab16..f6433c037d24 100644 --- a/drivers/staging/gma500/gem.c +++ b/drivers/staging/gma500/gem.c @@ -120,8 +120,7 @@ static int psb_gem_create(struct drm_file *file, /* Initialize the extra goodies GEM needs to do all the hard work */ if (drm_gem_object_init(dev, &r->gem, size) != 0) { psb_gtt_free_range(dev, r); - /* GEM doesn't give an error code and we don't have an - EGEMSUCKS so make something up for now - FIXME */ + /* GEM doesn't give an error code so use -ENOMEM */ dev_err(dev->dev, "GEM init failed for %lld\n", size); return -ENOMEM; } @@ -191,8 +190,6 @@ int psb_gem_dumb_destroy(struct drm_file *file, struct drm_device *dev, * The VMA was set up by GEM. In doing so it also ensured that the * vma->vm_private_data points to the GEM object that is backing this * mapping. - * - * FIXME */ int psb_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf) { diff --git a/drivers/staging/gma500/gtt.c b/drivers/staging/gma500/gtt.c index 461ead251bbd..e770bd190a5c 100644 --- a/drivers/staging/gma500/gtt.c +++ b/drivers/staging/gma500/gtt.c @@ -72,9 +72,8 @@ u32 *psb_gtt_entry(struct drm_device *dev, struct gtt_range *r) * @r: our GTT range * * Take our preallocated GTT range and insert the GEM object into - * the GTT. - * - * FIXME: gtt lock ? + * the GTT. This is protected via the gtt mutex which the caller + * must hold. */ static int psb_gtt_insert(struct drm_device *dev, struct gtt_range *r) { @@ -96,12 +95,17 @@ static int psb_gtt_insert(struct drm_device *dev, struct gtt_range *r) set_pages_array_uc(pages, r->npage); /* Write our page entries into the GTT itself */ - for (i = 0; i < r->npage; i++) { - pte = psb_gtt_mask_pte(page_to_pfn(*pages++), 0/*type*/); + for (i = r->roll; i < r->npage; i++) { + pte = psb_gtt_mask_pte(page_to_pfn(r->pages[i]), 0); + iowrite32(pte, gtt_slot++); + } + for (i = 0; i < r->roll; i++) { + pte = psb_gtt_mask_pte(page_to_pfn(r->pages[i]), 0); iowrite32(pte, gtt_slot++); } /* Make sure all the entries are set before we return */ ioread32(gtt_slot - 1); + return 0; } @@ -111,9 +115,9 @@ static int psb_gtt_insert(struct drm_device *dev, struct gtt_range *r) * @r: our GTT range * * Remove a preallocated GTT range from the GTT. Overwrite all the - * page table entries with the dummy page + * page table entries with the dummy page. This is protected via the gtt + * mutex which the caller must hold. */ - static void psb_gtt_remove(struct drm_device *dev, struct gtt_range *r) { struct drm_psb_private *dev_priv = dev->dev_private; @@ -132,11 +136,52 @@ static void psb_gtt_remove(struct drm_device *dev, struct gtt_range *r) } /** + * psb_gtt_roll - set scrolling position + * @dev: our DRM device + * @r: the gtt mapping we are using + * @roll: roll offset + * + * Roll an existing pinned mapping by moving the pages through the GTT. + * This allows us to implement hardware scrolling on the consoles without + * a 2D engine + */ +void psb_gtt_roll(struct drm_device *dev, struct gtt_range *r, int roll) +{ + u32 *gtt_slot, pte; + int i; + + if (roll >= r->npage) { + WARN_ON(1); + return; + } + + r->roll = roll; + + /* Not currently in the GTT - no worry we will write the mapping at + the right position when it gets pinned */ + if (!r->stolen && !r->in_gart) + return; + + gtt_slot = psb_gtt_entry(dev, r); + + for (i = r->roll; i < r->npage; i++) { + pte = psb_gtt_mask_pte(page_to_pfn(r->pages[i]), 0); + iowrite32(pte, gtt_slot++); + } + for (i = 0; i < r->roll; i++) { + pte = psb_gtt_mask_pte(page_to_pfn(r->pages[i]), 0); + iowrite32(pte, gtt_slot++); + } + ioread32(gtt_slot - 1); +} + +/** * psb_gtt_attach_pages - attach and pin GEM pages * @gt: the gtt range * * Pin and build an in kernel list of the pages that back our GEM object. - * While we hold this the pages cannot be swapped out + * While we hold this the pages cannot be swapped out. This is protected + * via the gtt mutex which the caller must hold. */ static int psb_gtt_attach_pages(struct gtt_range *gt) { @@ -158,7 +203,7 @@ static int psb_gtt_attach_pages(struct gtt_range *gt) gt->npage = pages; for (i = 0; i < pages; i++) { - /* FIXME: review flags later */ + /* FIXME: needs updating as per mail from Hugh Dickins */ p = read_cache_page_gfp(mapping, i, __GFP_COLD | GFP_KERNEL); if (IS_ERR(p)) @@ -181,7 +226,8 @@ err: * * Undo the effect of psb_gtt_attach_pages. At this point the pages * must have been removed from the GTT as they could now be paged out - * and move bus address. + * and move bus address. This is protected via the gtt mutex which the + * caller must hold. */ static void psb_gtt_detach_pages(struct gtt_range *gt) { @@ -300,6 +346,7 @@ struct gtt_range *psb_gtt_alloc_range(struct drm_device *dev, int len, gt->resource.name = name; gt->stolen = backed; gt->in_gart = backed; + gt->roll = 0; /* Ensure this is set for non GEM objects */ gt->gem.dev = dev; ret = allocate_resource(dev_priv->gtt_mem, >->resource, @@ -390,15 +437,18 @@ int psb_gtt_init(struct drm_device *dev, int resume) pg->gtt_phys_start = dev_priv->pge_ctl & PAGE_MASK; /* - * FIXME: video mmu has hw bug to access 0x0D0000000, - * then make gatt start at 0x0e000,0000 + * The video mmu has a hw bug when accessing 0x0D0000000. + * Make gatt start at 0x0e000,0000. This doesn't actually + * matter for us but may do if the video acceleration ever + * gets opened up. */ pg->mmu_gatt_start = 0xE0000000; pg->gtt_start = pci_resource_start(dev->pdev, PSB_GTT_RESOURCE); gtt_pages = pci_resource_len(dev->pdev, PSB_GTT_RESOURCE) >> PAGE_SHIFT; - /* CDV workaround */ + /* Some CDV firmware doesn't report this currently. In which case the + system has 64 gtt pages */ if (pg->gtt_start == 0 || gtt_pages == 0) { dev_err(dev->dev, "GTT PCI BAR not initialized.\n"); gtt_pages = 64; @@ -412,13 +462,16 @@ int psb_gtt_init(struct drm_device *dev, int resume) if (pg->gatt_pages == 0 || pg->gatt_start == 0) { static struct resource fudge; /* Preferably peppermint */ - /* This can occur on CDV SDV systems. Fudge it in this case. We really don't care what imaginary space is being allocated at this point */ dev_err(dev->dev, "GATT PCI BAR not initialized.\n"); pg->gatt_start = 0x40000000; pg->gatt_pages = (128 * 1024 * 1024) >> PAGE_SHIFT; + /* This is a little confusing but in fact the GTT is providing + a view from the GPU into memory and not vice versa. As such + this is really allocating space that is not the same as the + CPU address space on CDV */ fudge.start = 0x40000000; fudge.end = 0x40000000 + 128 * 1024 * 1024 - 1; fudge.name = "fudge"; diff --git a/drivers/staging/gma500/gtt.h b/drivers/staging/gma500/gtt.h index e0e1cb6f9bd6..aa1742387f5a 100644 --- a/drivers/staging/gma500/gtt.h +++ b/drivers/staging/gma500/gtt.h @@ -49,6 +49,7 @@ struct gtt_range { bool mmapping; /* Is mmappable */ struct page **pages; /* Backing pages if present */ int npage; /* Number of backing pages */ + int roll; /* Roll applied to the GTT entries */ }; extern struct gtt_range *psb_gtt_alloc_range(struct drm_device *dev, int len, @@ -57,5 +58,7 @@ extern void psb_gtt_kref_put(struct gtt_range *gt); extern void psb_gtt_free_range(struct drm_device *dev, struct gtt_range *gt); extern int psb_gtt_pin(struct gtt_range *gt); extern void psb_gtt_unpin(struct gtt_range *gt); +extern void psb_gtt_roll(struct drm_device *dev, + struct gtt_range *gt, int roll); #endif diff --git a/drivers/staging/gma500/intel_i2c.c b/drivers/staging/gma500/intel_i2c.c index e33432df510c..51cbf65268e6 100644 --- a/drivers/staging/gma500/intel_i2c.c +++ b/drivers/staging/gma500/intel_i2c.c @@ -20,6 +20,7 @@ #include <linux/i2c.h> #include <linux/i2c-algo-bit.h> +#include <linux/export.h> #include "psb_drv.h" #include "psb_intel_reg.h" diff --git a/drivers/staging/gma500/intel_opregion.c b/drivers/staging/gma500/intel_opregion.c index d2e60376982f..d946bc1b17bf 100644 --- a/drivers/staging/gma500/intel_opregion.c +++ b/drivers/staging/gma500/intel_opregion.c @@ -20,6 +20,7 @@ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. * + * FIXME: resolve with the i915 version */ #include "psb_drv.h" diff --git a/drivers/staging/gma500/mdfld_dsi_output.c b/drivers/staging/gma500/mdfld_dsi_output.c index 9050c0f78b15..3f979db2c3a5 100644 --- a/drivers/staging/gma500/mdfld_dsi_output.c +++ b/drivers/staging/gma500/mdfld_dsi_output.c @@ -32,6 +32,7 @@ #include <asm/intel_scu_ipc.h> #include "mdfld_dsi_pkg_sender.h" #include <linux/pm_runtime.h> +#include <linux/moduleparam.h> #define MDFLD_DSI_BRIGHTNESS_MAX_LEVEL 100 diff --git a/drivers/staging/gma500/mdfld_intel_display.c b/drivers/staging/gma500/mdfld_intel_display.c index aa2ff559383d..8eb827ecc3d3 100644 --- a/drivers/staging/gma500/mdfld_intel_display.c +++ b/drivers/staging/gma500/mdfld_intel_display.c @@ -282,7 +282,7 @@ static int mdfld_intel_crtc_cursor_move(struct drm_crtc *crtc, int x, int y) return -EINVAL; } -#if 1 /* FIXME_JLIU7 can't enalbe cursorB/C HW issue. need to remove after HW fix */ +#if 1 /* FIXME_JLIU7 can't enable cursorB/C HW issue. need to remove after HW fix */ if (pipe != 0) return 0; #endif @@ -484,7 +484,7 @@ void mdfld_disable_crtc (struct drm_device *dev, int pipe) /* FIXME_JLIU7 MDFLD_PO revisit */ /* Wait for vblank for the disable to take effect */ -// MDFLD_PO_JLIU7 psb_intel_wait_for_vblank(dev); +/* MDFLD_PO_JLIU7 psb_intel_wait_for_vblank(dev); */ /* Next, disable display pipes */ temp = REG_READ(pipeconf_reg); @@ -561,7 +561,6 @@ static void mdfld_crtc_dpms(struct drm_crtc *crtc, int mode) //gbdispstatus = true; } - /* FIXME_JLIU7 MDFLD_PO replaced w/ the following function */ /* mdfld_dbi_dpms (struct drm_device *dev, int pipe, bool enabled) */ @@ -1150,8 +1149,11 @@ static int mdfld_crtc_mode_set(struct drm_crtc *crtc, 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*/ + /* + * Medfield doesn't have register support for centering so + * we need to mess with the h/vblank and h/vsync start and + * ends to get central + */ int offsetX = 0, offsetY = 0; offsetX = (adjusted_mode->crtc_hdisplay - mode->crtc_hdisplay) / 2; diff --git a/drivers/staging/gma500/mdfld_output.c b/drivers/staging/gma500/mdfld_output.c index ee55f87ba1fd..eabf53d58f92 100644 --- a/drivers/staging/gma500/mdfld_output.c +++ b/drivers/staging/gma500/mdfld_output.c @@ -26,6 +26,7 @@ */ #include <linux/init.h> +#include <linux/moduleparam.h> #include "mdfld_dsi_dbi.h" #include "mdfld_dsi_dpi.h" #include "mdfld_dsi_output.h" @@ -167,4 +168,4 @@ void mdfld_output_setup(struct drm_device *dev) else mdfld_dbi_dsr_init(dev); } -}
\ No newline at end of file +} diff --git a/drivers/staging/gma500/mid_bios.c b/drivers/staging/gma500/mid_bios.c index 8cfe301f8fb2..ee3c0368e320 100644 --- a/drivers/staging/gma500/mid_bios.c +++ b/drivers/staging/gma500/mid_bios.c @@ -23,6 +23,7 @@ * - Check ioremap failures */ +#include <linux/moduleparam.h> #include <drm/drmP.h> #include <drm/drm.h> #include "psb_drm.h" diff --git a/drivers/staging/gma500/mrst_crtc.c b/drivers/staging/gma500/mrst_crtc.c index 72464dd0f23d..c9311a573c28 100644 --- a/drivers/staging/gma500/mrst_crtc.c +++ b/drivers/staging/gma500/mrst_crtc.c @@ -521,12 +521,11 @@ int mrst_pipe_set_base(struct drm_crtc *crtc, int x, int y, struct drm_framebuffer *old_fb) { struct drm_device *dev = crtc->dev; - /* struct drm_i915_master_private *master_priv; */ struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc); struct psb_framebuffer *psbfb = to_psb_fb(crtc->fb); int pipe = psb_intel_crtc->pipe; unsigned long start, offset; - /* FIXME: check if we need this surely MRST is pipe 0 only */ + int dspbase = (pipe == 0 ? DSPALINOFF : DSPBBASE); int dspsurf = (pipe == 0 ? DSPASURF : DSPBSURF); int dspstride = (pipe == 0) ? DSPASTRIDE : DSPBSTRIDE; @@ -572,15 +571,10 @@ int mrst_pipe_set_base(struct drm_crtc *crtc, } REG_WRITE(dspcntr_reg, dspcntr); - if (0 /* FIXMEAC - check what PSB needs */) { - REG_WRITE(dspbase, offset); - REG_READ(dspbase); - REG_WRITE(dspsurf, start); - REG_READ(dspsurf); - } else { - REG_WRITE(dspbase, start + offset); - REG_READ(dspbase); - } + REG_WRITE(dspbase, offset); + REG_READ(dspbase); + REG_WRITE(dspsurf, start); + REG_READ(dspsurf); pipe_set_base_exit: gma_power_end(dev); diff --git a/drivers/staging/gma500/mrst_hdmi_i2c.c b/drivers/staging/gma500/mrst_hdmi_i2c.c index 351b9d897b9f..36e7edc4d14c 100644 --- a/drivers/staging/gma500/mrst_hdmi_i2c.c +++ b/drivers/staging/gma500/mrst_hdmi_i2c.c @@ -29,6 +29,7 @@ #include <linux/i2c.h> #include <linux/interrupt.h> #include <linux/delay.h> +#include <linux/export.h> #include "psb_drv.h" #define HDMI_READ(reg) readl(hdmi_dev->regs + (reg)) diff --git a/drivers/staging/gma500/power.c b/drivers/staging/gma500/power.c index 972bea7c1af2..436fe9733b16 100644 --- a/drivers/staging/gma500/power.c +++ b/drivers/staging/gma500/power.c @@ -83,7 +83,7 @@ static void gma_suspend_display(struct drm_device *dev) { struct drm_psb_private *dev_priv = dev->dev_private; - if (dev_priv->suspended) + if (!dev_priv->display_power) return; dev_priv->ops->save_regs(dev); dev_priv->ops->power_down(dev); @@ -101,7 +101,7 @@ 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) + if (dev_priv->display_power) return; /* turn on the display power island */ @@ -265,6 +265,8 @@ bool gma_power_begin(struct drm_device *dev, bool force_on) /* Ok power up needed */ ret = gma_resume_pci(dev->pdev); if (ret == 0) { + /* FIXME: we want to defer this for Medfield/Oaktrail */ + gma_resume_display(dev); psb_irq_preinstall(dev); psb_irq_postinstall(dev); pm_runtime_get(&dev->pdev->dev); @@ -302,7 +304,7 @@ int psb_runtime_suspend(struct device *dev) int psb_runtime_resume(struct device *dev) { - return 0; + return gma_power_resume(dev);; } int psb_runtime_idle(struct device *dev) diff --git a/drivers/staging/gma500/psb_device.c b/drivers/staging/gma500/psb_device.c index 46591323595a..b97aa78519f2 100644 --- a/drivers/staging/gma500/psb_device.c +++ b/drivers/staging/gma500/psb_device.c @@ -213,7 +213,6 @@ static int psb_restore_display_registers(struct drm_device *dev) struct drm_psb_private *dev_priv = dev->dev_private; struct drm_crtc *crtc; struct drm_connector *connector; - int pp_stat; /* Display arbitration + watermarks */ PSB_WVDC32(dev_priv->saveDSPARB, DSPARB); @@ -237,37 +236,6 @@ static int psb_restore_display_registers(struct drm_device *dev) connector->funcs->restore(connector); mutex_unlock(&dev->mode_config.mutex); - - if (dev_priv->iLVDS_enable) { - /*shutdown the panel*/ - PSB_WVDC32(0, PP_CONTROL); - do { - pp_stat = PSB_RVDC32(PP_STATUS); - } while (pp_stat & 0x80000000); - - /* Turn off the plane */ - PSB_WVDC32(0x58000000, DSPACNTR); - PSB_WVDC32(0, DSPASURF);/*trigger the plane disable*/ - /* Wait ~4 ticks */ - msleep(4); - /* Turn off pipe */ - PSB_WVDC32(0x0, PIPEACONF); - /* Wait ~8 ticks */ - msleep(8); - - /* Turn off PLLs */ - PSB_WVDC32(0, MRST_DPLL_A); - } else { - PSB_WVDC32(DPI_SHUT_DOWN, DPI_CONTROL_REG); - PSB_WVDC32(0x0, PIPEACONF); - PSB_WVDC32(0x2faf0000, BLC_PWM_CTL); - while (REG_READ(0x70008) & 0x40000000) - cpu_relax(); - while ((PSB_RVDC32(GEN_FIFO_STAT_REG) & DPI_FIFO_EMPTY) - != DPI_FIFO_EMPTY) - cpu_relax(); - PSB_WVDC32(0, DEVICE_READY_REG); - } return 0; } diff --git a/drivers/staging/gma500/psb_drv.c b/drivers/staging/gma500/psb_drv.c index b2cdce7b97ef..986a04d16ba8 100644 --- a/drivers/staging/gma500/psb_drv.c +++ b/drivers/staging/gma500/psb_drv.c @@ -35,6 +35,7 @@ #include <linux/notifier.h> #include <linux/spinlock.h> #include <linux/pm_runtime.h> +#include <linux/module.h> #include <acpi/video.h> static int drm_psb_trap_pagefaults; @@ -183,7 +184,6 @@ static void psb_lastclose(struct drm_device *dev) static void psb_do_takedown(struct drm_device *dev) { - /* FIXME: do we need to clean up the gtt here ? */ } static int psb_do_init(struct drm_device *dev) @@ -229,7 +229,7 @@ static int psb_do_init(struct drm_device *dev) spin_lock_init(&dev_priv->irqmask_lock); - mutex_init(&dev_priv->mutex_2d); + spin_lock_init(&dev_priv->lock_2d); PSB_WSGX32(0x00000000, PSB_CR_BIF_BANK0); PSB_WSGX32(0x00000000, PSB_CR_BIF_BANK1); @@ -329,6 +329,11 @@ static int psb_driver_load(struct drm_device *dev, unsigned long chipset) dev_priv->dev = dev; dev->dev_private = (void *) dev_priv; + if (!IS_PSB(dev)) { + if (pci_enable_msi(dev->pdev)) + dev_warn(dev->dev, "Enabling MSI failed!\n"); + } + dev_priv->num_pipe = dev_priv->ops->pipes; resource_start = pci_resource_start(dev->pdev, PSB_MMIO_RESOURCE); @@ -410,7 +415,7 @@ static int psb_driver_load(struct drm_device *dev, unsigned long chipset) PSB_WVDC32(0x00000000, PSB_INT_ENABLE_R); PSB_WVDC32(0xFFFFFFFF, PSB_INT_MASK_R); spin_unlock_irqrestore(&dev_priv->irqmask_lock, irqflags); - if (drm_core_check_feature(dev, DRIVER_MODESET)) + if (IS_PSB(dev) && drm_core_check_feature(dev, DRIVER_MODESET)) drm_irq_install(dev); dev->vblank_disable_allowed = 1; @@ -444,12 +449,9 @@ static int psb_driver_load(struct drm_device *dev, unsigned long chipset) if (ret) return ret; -#if 0 - /*enable runtime pm at last*/ - pm_runtime_enable(&dev->pdev->dev); + + /* Enable runtime pm at last */ pm_runtime_set_active(&dev->pdev->dev); -#endif - /*Intel drm driver load is done, continue doing pvr load*/ return 0; out_err: psb_driver_unload(dev); @@ -466,14 +468,13 @@ static int psb_sizes_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv) { struct drm_psb_private *dev_priv = psb_priv(dev); - struct drm_psb_sizes_arg *arg = - (struct drm_psb_sizes_arg *) data; + struct drm_psb_sizes_arg *arg = data; *arg = dev_priv->sizes; return 0; } -static int psb_dc_state_ioctl(struct drm_device *dev, void * data, +static int psb_dc_state_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv) { uint32_t flags; @@ -481,8 +482,7 @@ static int psb_dc_state_ioctl(struct drm_device *dev, void * data, struct drm_mode_object *obj; struct drm_connector *connector; struct drm_crtc *crtc; - struct drm_psb_dc_state_arg *arg = - (struct drm_psb_dc_state_arg *)data; + struct drm_psb_dc_state_arg *arg = data; /* Double check MRST case */ @@ -1110,15 +1110,12 @@ static long psb_unlocked_ioctl(struct file *filp, unsigned int cmd, { struct drm_file *file_priv = filp->private_data; struct drm_device *dev = file_priv->minor->dev; - struct drm_psb_private *dev_priv = dev->dev_private; - static unsigned int runtime_allowed; - - if (runtime_allowed == 1 && dev_priv->is_lvds_on) { - runtime_allowed++; - pm_runtime_allow(&dev->pdev->dev); - dev_priv->rpm_enabled = 1; - } - return drm_ioctl(filp, cmd, arg); + int ret; + + pm_runtime_forbid(dev->dev); + ret = drm_ioctl(filp, cmd, arg); + pm_runtime_allow(dev->dev); + return ret; /* FIXME: do we need to wrap the other side of this */ } @@ -1137,8 +1134,12 @@ static void psb_remove(struct pci_dev *pdev) } static const struct dev_pm_ops psb_pm_ops = { - .resume = gma_power_resume, .suspend = gma_power_suspend, + .resume = gma_power_resume, + .freeze = gma_power_suspend, + .thaw = gma_power_resume, + .poweroff = gma_power_suspend, + .restore = gma_power_resume, .runtime_suspend = psb_runtime_suspend, .runtime_resume = psb_runtime_resume, .runtime_idle = psb_runtime_idle, @@ -1207,9 +1208,6 @@ static struct pci_driver psb_pci_driver = { static int psb_probe(struct pci_dev *pdev, const struct pci_device_id *ent) { - /* MLD Added this from Inaky's patch */ - if (pci_enable_msi(pdev)) - dev_warn(&pdev->dev, "Enable MSI failed!\n"); return drm_get_pci_dev(pdev, ent, &driver); } diff --git a/drivers/staging/gma500/psb_drv.h b/drivers/staging/gma500/psb_drv.h index fd4732dd783a..11d963a055be 100644 --- a/drivers/staging/gma500/psb_drv.h +++ b/drivers/staging/gma500/psb_drv.h @@ -43,6 +43,7 @@ enum { CHIP_MFLD_0130 = 3, /* Medfield */ }; +#define IS_PSB(dev) (((dev)->pci_device & 0xfffe) == 0x8108) #define IS_MRST(dev) (((dev)->pci_device & 0xfffc) == 0x4100) #define IS_MFLD(dev) (((dev)->pci_device & 0xfff8) == 0x0130) @@ -134,6 +135,9 @@ enum { #define _PSB_IRQ_MSVDX_FLAG (1<<19) #define _LNC_IRQ_TOPAZ_FLAG (1<<20) +#define _PSB_PIPE_EVENT_FLAG (_PSB_VSYNC_PIPEA_FLAG | \ + _PSB_VSYNC_PIPEB_FLAG) + /* This flag includes all the display IRQ bits excepts the vblank irqs. */ #define _MDFLD_DISP_ALL_IRQ_FLAG (_MDFLD_PIPEC_EVENT_FLAG | \ _MDFLD_PIPEB_EVENT_FLAG | \ @@ -608,7 +612,7 @@ struct drm_psb_private { void (*exit_idle)(struct drm_device *dev, u32 update_src); /* 2D acceleration */ - struct mutex mutex_2d; + spinlock_t lock_2d; /* FIXME: Arrays anyone ? */ struct mdfld_dsi_encoder *encoder0; diff --git a/drivers/staging/gma500/psb_intel_display.c b/drivers/staging/gma500/psb_intel_display.c index 4afa671f9747..caa9d86f26d8 100644 --- a/drivers/staging/gma500/psb_intel_display.c +++ b/drivers/staging/gma500/psb_intel_display.c @@ -1102,10 +1102,6 @@ static int psb_crtc_set_config(struct drm_mode_set *set) { int ret; struct drm_device *dev = set->crtc->dev; - struct drm_psb_private *dev_priv = dev->dev_private; - - if (!dev_priv->rpm_enabled) - return drm_crtc_helper_set_config(set); pm_runtime_forbid(&dev->pdev->dev); ret = drm_crtc_helper_set_config(set); diff --git a/drivers/staging/gma500/psb_intel_lvds.c b/drivers/staging/gma500/psb_intel_lvds.c index c6436da60732..21022e1a977a 100644 --- a/drivers/staging/gma500/psb_intel_lvds.c +++ b/drivers/staging/gma500/psb_intel_lvds.c @@ -68,20 +68,23 @@ struct psb_intel_lvds_priv { static u32 psb_intel_lvds_get_max_backlight(struct drm_device *dev) { struct drm_psb_private *dev_priv = dev->dev_private; - u32 retVal; + u32 ret; if (gma_power_begin(dev, false)) { - retVal = ((REG_READ(BLC_PWM_CTL) & - BACKLIGHT_MODULATION_FREQ_MASK) >> - BACKLIGHT_MODULATION_FREQ_SHIFT) * 2; - + ret = REG_READ(BLC_PWM_CTL); gma_power_end(dev); - } else - retVal = ((dev_priv->saveBLC_PWM_CTL & - BACKLIGHT_MODULATION_FREQ_MASK) >> - BACKLIGHT_MODULATION_FREQ_SHIFT) * 2; - - return retVal; + } else /* Powered off, use the saved value */ + ret = dev_priv->saveBLC_PWM_CTL; + + /* Top 15bits hold the frequency mask */ + ret = (ret & BACKLIGHT_MODULATION_FREQ_MASK) >> + BACKLIGHT_MODULATION_FREQ_SHIFT; + + ret *= 2; /* Return a 16bit range as needed for setting */ + if (ret == 0) + dev_err(dev->dev, "BL bug: Reg %08x save %08X\n", + REG_READ(BLC_PWM_CTL), dev_priv->saveBLC_PWM_CTL); + return ret; } /* @@ -142,7 +145,7 @@ static int psb_lvds_pwm_set_brightness(struct drm_device *dev, int level) max_pwm_blc = psb_intel_lvds_get_max_backlight(dev); /*BLC_PWM_CTL Should be initiated while backlight device init*/ - BUG_ON((max_pwm_blc & PSB_BLC_MAX_PWM_REG_FREQ) == 0); + BUG_ON(max_pwm_blc == 0); blc_pwm_duty_cycle = level * max_pwm_blc / BRIGHTNESS_MAX_LEVEL; @@ -154,6 +157,10 @@ static int psb_lvds_pwm_set_brightness(struct drm_device *dev, int level) (max_pwm_blc << PSB_BACKLIGHT_PWM_CTL_SHIFT) | (blc_pwm_duty_cycle)); + dev_info(dev->dev, "Backlight lvds set brightness %08x\n", + (max_pwm_blc << PSB_BACKLIGHT_PWM_CTL_SHIFT) | + (blc_pwm_duty_cycle)); + return 0; } @@ -162,14 +169,12 @@ static int psb_lvds_pwm_set_brightness(struct drm_device *dev, int level) */ void psb_intel_lvds_set_brightness(struct drm_device *dev, int level) { - /*u32 blc_pwm_ctl;*/ - struct drm_psb_private *dev_priv = - (struct drm_psb_private *)dev->dev_private; + struct drm_psb_private *dev_priv = dev->dev_private; dev_dbg(dev->dev, "backlight level is %d\n", level); if (!dev_priv->lvds_bl) { - dev_err(dev->dev, "NO LVDS Backlight Info\n"); + dev_err(dev->dev, "NO LVDS backlight info\n"); return; } @@ -190,11 +195,13 @@ static void psb_intel_lvds_set_backlight(struct drm_device *dev, int level) u32 blc_pwm_ctl; if (gma_power_begin(dev, false)) { - blc_pwm_ctl = - REG_READ(BLC_PWM_CTL) & ~BACKLIGHT_DUTY_CYCLE_MASK; + blc_pwm_ctl = REG_READ(BLC_PWM_CTL); + blc_pwm_ctl &= ~BACKLIGHT_DUTY_CYCLE_MASK; REG_WRITE(BLC_PWM_CTL, (blc_pwm_ctl | (level << BACKLIGHT_DUTY_CYCLE_SHIFT))); + dev_priv->saveBLC_PWM_CTL = (blc_pwm_ctl | + (level << BACKLIGHT_DUTY_CYCLE_SHIFT)); gma_power_end(dev); } else { blc_pwm_ctl = dev_priv->saveBLC_PWM_CTL & @@ -212,9 +219,11 @@ static void psb_intel_lvds_set_power(struct drm_device *dev, { u32 pp_status; - if (!gma_power_begin(dev, true)) + if (!gma_power_begin(dev, true)) { + dev_err(dev->dev, "set power, chip off!\n"); return; - + } + if (on) { REG_WRITE(PP_CONTROL, REG_READ(PP_CONTROL) | POWER_TARGET_ON); @@ -296,9 +305,6 @@ static void psb_intel_lvds_restore(struct drm_connector *connector) { struct drm_device *dev = connector->dev; u32 pp_status; - - /*struct drm_psb_private *dev_priv = - (struct drm_psb_private *)dev->dev_private;*/ struct psb_intel_output *psb_intel_output = to_psb_intel_output(connector); struct psb_intel_lvds_priv *lvds_priv = @@ -382,7 +388,6 @@ bool psb_intel_lvds_mode_fixup(struct drm_encoder *encoder, if (psb_intel_output->type == INTEL_OUTPUT_MIPI2) panel_fixed_mode = mode_dev->panel_fixed_mode2; - /* FIXME: review for Medfield */ /* PSB requires the LVDS is on pipe B, MRST has only one pipe anyway */ if (!IS_MRST(dev) && psb_intel_crtc->pipe == 0) { printk(KERN_ERR "Can't support LVDS on pipe A\n"); @@ -622,7 +627,8 @@ int psb_intel_lvds_set_property(struct drm_connector *connector, goto set_prop_error; else { #ifdef CONFIG_BACKLIGHT_CLASS_DEVICE - struct drm_psb_private *devp = encoder->dev->dev_private; + struct drm_psb_private *devp = + encoder->dev->dev_private; struct backlight_device *bd = devp->backlight_device; if (bd) { bd->props.brightness = value; @@ -695,8 +701,7 @@ void psb_intel_lvds_init(struct drm_device *dev, struct drm_encoder *encoder; struct drm_display_mode *scan; /* *modes, *bios_mode; */ struct drm_crtc *crtc; - struct drm_psb_private *dev_priv = - (struct drm_psb_private *)dev->dev_private; + struct drm_psb_private *dev_priv = dev->dev_private; u32 lvds; int pipe; @@ -712,8 +717,8 @@ void psb_intel_lvds_init(struct drm_device *dev, } psb_intel_output->dev_priv = lvds_priv; - psb_intel_output->mode_dev = mode_dev; + connector = &psb_intel_output->base; encoder = &psb_intel_output->enc; drm_connector_init(dev, &psb_intel_output->base, diff --git a/drivers/staging/gma500/psb_irq.c b/drivers/staging/gma500/psb_irq.c index 4a0fa42893f9..36dd63044b06 100644 --- a/drivers/staging/gma500/psb_irq.c +++ b/drivers/staging/gma500/psb_irq.c @@ -139,21 +139,10 @@ void mid_disable_pipe_event(struct drm_psb_private *dev_priv, int pipe) } /** - * Display controller interrupt handler for vsync/vblank. - * - */ -static void mid_vblank_handler(struct drm_device *dev, uint32_t pipe) -{ - drm_handle_vblank(dev, pipe); -} - - -/** * Display controller interrupt handler for pipe event. * */ -#define WAIT_STATUS_CLEAR_LOOP_COUNT 0xffff -static void mid_pipe_event_handler(struct drm_device *dev, uint32_t pipe) +static void mid_pipe_event_handler(struct drm_device *dev, int pipe) { struct drm_psb_private *dev_priv = (struct drm_psb_private *) dev->dev_private; @@ -162,6 +151,7 @@ static void mid_pipe_event_handler(struct drm_device *dev, uint32_t pipe) uint32_t pipe_stat_reg = psb_pipestat(pipe); uint32_t pipe_enable = dev_priv->pipestat[pipe]; uint32_t pipe_status = dev_priv->pipestat[pipe] >> 16; + uint32_t pipe_clear; uint32_t i = 0; spin_lock(&dev_priv->irqmask_lock); @@ -172,27 +162,23 @@ static void mid_pipe_event_handler(struct drm_device *dev, uint32_t pipe) spin_unlock(&dev_priv->irqmask_lock); - /* clear the 2nd level interrupt status bits */ - /** - * FIXME: shouldn't use while loop here. However, the interrupt - * status 'sticky' bits cannot be cleared by setting '1' to that - * bit once... - */ - for (i = 0; i < WAIT_STATUS_CLEAR_LOOP_COUNT; i++) { + /* Clear the 2nd level interrupt status bits + * Sometimes the bits are very sticky so we repeat until they unstick */ + for (i = 0; i < 0xffff; i++) { PSB_WVDC32(PSB_RVDC32(pipe_stat_reg), pipe_stat_reg); - (void) PSB_RVDC32(pipe_stat_reg); + pipe_clear = PSB_RVDC32(pipe_stat_reg) & pipe_status; - if ((PSB_RVDC32(pipe_stat_reg) & pipe_status) == 0) + if (pipe_clear == 0) break; } - if (i == WAIT_STATUS_CLEAR_LOOP_COUNT) + if (pipe_clear) dev_err(dev->dev, - "%s, can't clear the status bits in pipe_stat_reg, its value = 0x%x.\n", - __func__, PSB_RVDC32(pipe_stat_reg)); + "%s, can't clear status bits for pipe %d, its value = 0x%x.\n", + __func__, pipe, PSB_RVDC32(pipe_stat_reg)); if (pipe_stat_val & PIPE_VBLANK_STATUS) - mid_vblank_handler(dev, pipe); + drm_handle_vblank(dev, pipe); if (pipe_stat_val & PIPE_TE_STATUS) drm_handle_vblank(dev, pipe); @@ -203,8 +189,11 @@ static void mid_pipe_event_handler(struct drm_device *dev, uint32_t pipe) */ static void psb_vdc_interrupt(struct drm_device *dev, uint32_t vdc_stat) { - if (vdc_stat & _PSB_PIPEA_EVENT_FLAG) + if (vdc_stat & _PSB_VSYNC_PIPEA_FLAG) mid_pipe_event_handler(dev, 0); + + if (vdc_stat & _PSB_VSYNC_PIPEB_FLAG) + mid_pipe_event_handler(dev, 1); } irqreturn_t psb_irq_handler(DRM_IRQ_ARGS) @@ -220,8 +209,13 @@ irqreturn_t psb_irq_handler(DRM_IRQ_ARGS) vdc_stat = PSB_RVDC32(PSB_INT_IDENTITY_R); + if (vdc_stat & _PSB_PIPE_EVENT_FLAG) + dsp_int = 1; + + /* FIXME: Handle Medfield if (vdc_stat & _MDFLD_DISP_ALL_IRQ_FLAG) dsp_int = 1; + */ if (vdc_stat & _PSB_IRQ_SGX_FLAG) sgx_int = 1; @@ -267,13 +261,18 @@ void psb_irq_preinstall(struct drm_device *dev) if (gma_power_is_on(dev)) PSB_WVDC32(0xFFFFFFFF, PSB_HWSTAM); if (dev->vblank_enabled[0]) - dev_priv->vdc_irq_mask |= _PSB_PIPEA_EVENT_FLAG; + dev_priv->vdc_irq_mask |= _PSB_VSYNC_PIPEA_FLAG; + if (dev->vblank_enabled[1]) + dev_priv->vdc_irq_mask |= _PSB_VSYNC_PIPEB_FLAG; + + /* FIXME: Handle Medfield irq mask if (dev->vblank_enabled[1]) dev_priv->vdc_irq_mask |= _MDFLD_PIPEB_EVENT_FLAG; if (dev->vblank_enabled[2]) dev_priv->vdc_irq_mask |= _MDFLD_PIPEC_EVENT_FLAG; + */ - /*This register is safe even if display island is off*/ + /* This register is safe even if display island is off */ PSB_WVDC32(~dev_priv->vdc_irq_mask, PSB_INT_MASK_R); spin_unlock_irqrestore(&dev_priv->irqmask_lock, irqflags); } @@ -471,7 +470,13 @@ int psb_enable_vblank(struct drm_device *dev, int pipe) spin_lock_irqsave(&dev_priv->irqmask_lock, irqflags); - mid_enable_pipe_event(dev_priv, pipe); + if (pipe == 0) + dev_priv->vdc_irq_mask |= _PSB_VSYNC_PIPEA_FLAG; + else if (pipe == 1) + dev_priv->vdc_irq_mask |= _PSB_VSYNC_PIPEB_FLAG; + + PSB_WVDC32(~dev_priv->vdc_irq_mask, PSB_INT_MASK_R); + PSB_WVDC32(dev_priv->vdc_irq_mask, PSB_INT_ENABLE_R); psb_enable_pipestat(dev_priv, pipe, PIPE_VBLANK_INTERRUPT_ENABLE); spin_unlock_irqrestore(&dev_priv->irqmask_lock, irqflags); @@ -493,7 +498,13 @@ void psb_disable_vblank(struct drm_device *dev, int pipe) #endif spin_lock_irqsave(&dev_priv->irqmask_lock, irqflags); - mid_disable_pipe_event(dev_priv, pipe); + if (pipe == 0) + dev_priv->vdc_irq_mask &= ~_PSB_VSYNC_PIPEA_FLAG; + else if (pipe == 1) + dev_priv->vdc_irq_mask &= ~_PSB_VSYNC_PIPEB_FLAG; + + PSB_WVDC32(~dev_priv->vdc_irq_mask, PSB_INT_MASK_R); + PSB_WVDC32(dev_priv->vdc_irq_mask, PSB_INT_ENABLE_R); psb_disable_pipestat(dev_priv, pipe, PIPE_VBLANK_INTERRUPT_ENABLE); spin_unlock_irqrestore(&dev_priv->irqmask_lock, irqflags); diff --git a/drivers/staging/gma500/psb_lid.c b/drivers/staging/gma500/psb_lid.c index af328516561e..b867aabe6bf3 100644 --- a/drivers/staging/gma500/psb_lid.c +++ b/drivers/staging/gma500/psb_lid.c @@ -52,8 +52,6 @@ static void psb_lid_timer_func(unsigned long data) pp_status = REG_READ(PP_STATUS); } while ((pp_status & PP_ON) == 0); } - /* printk(KERN_INFO"%s: lid: closed\n", __FUNCTION__); */ - dev_priv->lid_last_state = readl(lid_state); lid_timer_schedule: |