diff options
Diffstat (limited to 'drivers/gpu/drm/gma500')
28 files changed, 509 insertions, 467 deletions
diff --git a/drivers/gpu/drm/gma500/cdv_device.c b/drivers/gpu/drm/gma500/cdv_device.c index d7c6cca23e94..dd32b484dd82 100644 --- a/drivers/gpu/drm/gma500/cdv_device.c +++ b/drivers/gpu/drm/gma500/cdv_device.c @@ -262,6 +262,7 @@ static int cdv_save_display_registers(struct drm_device *dev) struct drm_psb_private *dev_priv = to_drm_psb_private(dev); struct pci_dev *pdev = to_pci_dev(dev->dev); struct psb_save_area *regs = &dev_priv->regs; + struct drm_connector_list_iter conn_iter; struct drm_connector *connector; dev_dbg(dev->dev, "Saving GPU registers.\n"); @@ -298,8 +299,10 @@ static int cdv_save_display_registers(struct drm_device *dev) regs->cdv.saveIER = REG_READ(PSB_INT_ENABLE_R); regs->cdv.saveIMR = REG_READ(PSB_INT_MASK_R); - list_for_each_entry(connector, &dev->mode_config.connector_list, head) + drm_connector_list_iter_begin(dev, &conn_iter); + drm_for_each_connector_iter(connector, &conn_iter) connector->funcs->dpms(connector, DRM_MODE_DPMS_OFF); + drm_connector_list_iter_end(&conn_iter); return 0; } @@ -317,6 +320,7 @@ static int cdv_restore_display_registers(struct drm_device *dev) struct drm_psb_private *dev_priv = to_drm_psb_private(dev); struct pci_dev *pdev = to_pci_dev(dev->dev); struct psb_save_area *regs = &dev_priv->regs; + struct drm_connector_list_iter conn_iter; struct drm_connector *connector; u32 temp; @@ -373,8 +377,10 @@ static int cdv_restore_display_registers(struct drm_device *dev) drm_mode_config_reset(dev); - list_for_each_entry(connector, &dev->mode_config.connector_list, head) + drm_connector_list_iter_begin(dev, &conn_iter); + drm_for_each_connector_iter(connector, &conn_iter) connector->funcs->dpms(connector, DRM_MODE_DPMS_ON); + drm_connector_list_iter_end(&conn_iter); /* Resume the modeset for every activated CRTC */ drm_helper_resume_force_mode(dev); @@ -603,7 +609,6 @@ const struct psb_ops cdv_chip_ops = { .errata = cdv_errata, .crtc_helper = &cdv_intel_helper_funcs, - .crtc_funcs = &gma_intel_crtc_funcs, .clock_funcs = &cdv_clock_funcs, .output_init = cdv_output_init, diff --git a/drivers/gpu/drm/gma500/cdv_intel_crt.c b/drivers/gpu/drm/gma500/cdv_intel_crt.c index 4a9bb4994a26..6bcd18c63c31 100644 --- a/drivers/gpu/drm/gma500/cdv_intel_crt.c +++ b/drivers/gpu/drm/gma500/cdv_intel_crt.c @@ -191,12 +191,12 @@ static enum drm_connector_status cdv_intel_crt_detect( static void cdv_intel_crt_destroy(struct drm_connector *connector) { + struct gma_connector *gma_connector = to_gma_connector(connector); struct gma_encoder *gma_encoder = gma_attached_encoder(connector); psb_intel_i2c_destroy(gma_encoder->ddc_bus); - drm_connector_unregister(connector); drm_connector_cleanup(connector); - kfree(connector); + kfree(gma_connector); } static int cdv_intel_crt_get_modes(struct drm_connector *connector) @@ -281,8 +281,6 @@ void cdv_intel_crt_init(struct drm_device *dev, drm_connector_helper_add(connector, &cdv_intel_crt_connector_helper_funcs); - drm_connector_register(connector); - return; failed_ddc: drm_encoder_cleanup(&gma_encoder->base); diff --git a/drivers/gpu/drm/gma500/cdv_intel_display.c b/drivers/gpu/drm/gma500/cdv_intel_display.c index 94ebc48a4349..0c3ddcdc29dc 100644 --- a/drivers/gpu/drm/gma500/cdv_intel_display.c +++ b/drivers/gpu/drm/gma500/cdv_intel_display.c @@ -584,13 +584,14 @@ static int cdv_intel_crtc_mode_set(struct drm_crtc *crtc, bool ok; bool is_lvds = false; bool is_dp = false; - struct drm_mode_config *mode_config = &dev->mode_config; + struct drm_connector_list_iter conn_iter; struct drm_connector *connector; const struct gma_limit_t *limit; u32 ddi_select = 0; bool is_edp = false; - list_for_each_entry(connector, &mode_config->connector_list, head) { + drm_connector_list_iter_begin(dev, &conn_iter); + drm_for_each_connector_iter(connector, &conn_iter) { struct gma_encoder *gma_encoder = gma_attached_encoder(connector); @@ -613,10 +614,14 @@ static int cdv_intel_crtc_mode_set(struct drm_crtc *crtc, is_edp = true; break; default: + drm_connector_list_iter_end(&conn_iter); DRM_ERROR("invalid output type.\n"); return 0; } + + break; } + drm_connector_list_iter_end(&conn_iter); if (dev_priv->dplla_96mhz) /* low-end sku, 96/100 mhz */ diff --git a/drivers/gpu/drm/gma500/cdv_intel_dp.c b/drivers/gpu/drm/gma500/cdv_intel_dp.c index f562e91337c7..9ee99a7d4fbe 100644 --- a/drivers/gpu/drm/gma500/cdv_intel_dp.c +++ b/drivers/gpu/drm/gma500/cdv_intel_dp.c @@ -29,9 +29,9 @@ #include <linux/module.h> #include <linux/slab.h> +#include <drm/display/drm_dp_helper.h> #include <drm/drm_crtc.h> #include <drm/drm_crtc_helper.h> -#include <drm/dp/drm_dp_helper.h> #include <drm/drm_simple_kms_helper.h> #include "gma_display.h" @@ -1857,6 +1857,7 @@ done: static void cdv_intel_dp_destroy(struct drm_connector *connector) { + struct gma_connector *gma_connector = to_gma_connector(connector); struct gma_encoder *gma_encoder = gma_attached_encoder(connector); struct cdv_intel_dp *intel_dp = gma_encoder->dev_priv; @@ -1866,9 +1867,8 @@ cdv_intel_dp_destroy(struct drm_connector *connector) intel_dp->panel_fixed_mode = NULL; } i2c_del_adapter(&intel_dp->adapter); - drm_connector_unregister(connector); drm_connector_cleanup(connector); - kfree(connector); + kfree(gma_connector); } static const struct drm_encoder_helper_funcs cdv_intel_dp_helper_funcs = { @@ -1990,8 +1990,6 @@ cdv_intel_dp_init(struct drm_device *dev, struct psb_intel_mode_device *mode_dev connector->interlace_allowed = false; connector->doublescan_allowed = false; - drm_connector_register(connector); - /* Set up the DDC bus. */ switch (output_reg) { case DP_B: diff --git a/drivers/gpu/drm/gma500/cdv_intel_hdmi.c b/drivers/gpu/drm/gma500/cdv_intel_hdmi.c index e525689f84f0..8987e555e113 100644 --- a/drivers/gpu/drm/gma500/cdv_intel_hdmi.c +++ b/drivers/gpu/drm/gma500/cdv_intel_hdmi.c @@ -242,12 +242,12 @@ static enum drm_mode_status cdv_hdmi_mode_valid(struct drm_connector *connector, static void cdv_hdmi_destroy(struct drm_connector *connector) { + struct gma_connector *gma_connector = to_gma_connector(connector); struct gma_encoder *gma_encoder = gma_attached_encoder(connector); psb_intel_i2c_destroy(gma_encoder->i2c_bus); - drm_connector_unregister(connector); drm_connector_cleanup(connector); - kfree(connector); + kfree(gma_connector); } static const struct drm_encoder_helper_funcs cdv_hdmi_helper_funcs = { @@ -352,7 +352,6 @@ void cdv_hdmi_init(struct drm_device *dev, hdmi_priv->hdmi_i2c_adapter = &(gma_encoder->i2c_bus->adapter); hdmi_priv->dev = dev; - drm_connector_register(connector); return; failed_ddc: diff --git a/drivers/gpu/drm/gma500/cdv_intel_lvds.c b/drivers/gpu/drm/gma500/cdv_intel_lvds.c index 9e1cdb11023c..98d9f5483a7c 100644 --- a/drivers/gpu/drm/gma500/cdv_intel_lvds.c +++ b/drivers/gpu/drm/gma500/cdv_intel_lvds.c @@ -326,12 +326,12 @@ static int cdv_intel_lvds_get_modes(struct drm_connector *connector) */ static void cdv_intel_lvds_destroy(struct drm_connector *connector) { + struct gma_connector *gma_connector = to_gma_connector(connector); struct gma_encoder *gma_encoder = gma_attached_encoder(connector); psb_intel_i2c_destroy(gma_encoder->i2c_bus); - drm_connector_unregister(connector); drm_connector_cleanup(connector); - kfree(connector); + kfree(gma_connector); } static int cdv_intel_lvds_set_property(struct drm_connector *connector, @@ -647,7 +647,6 @@ void cdv_intel_lvds_init(struct drm_device *dev, out: mutex_unlock(&dev->mode_config.mutex); - drm_connector_register(connector); return; failed_find: diff --git a/drivers/gpu/drm/gma500/framebuffer.c b/drivers/gpu/drm/gma500/framebuffer.c index 45df9de22007..0ac6ea5fd3a1 100644 --- a/drivers/gpu/drm/gma500/framebuffer.c +++ b/drivers/gpu/drm/gma500/framebuffer.c @@ -451,6 +451,7 @@ static const struct drm_mode_config_funcs psb_mode_funcs = { static void psb_setup_outputs(struct drm_device *dev) { struct drm_psb_private *dev_priv = to_drm_psb_private(dev); + struct drm_connector_list_iter conn_iter; struct drm_connector *connector; drm_mode_create_scaling_mode_property(dev); @@ -461,8 +462,8 @@ static void psb_setup_outputs(struct drm_device *dev) "backlight", 0, 100); dev_priv->ops->output_init(dev); - list_for_each_entry(connector, &dev->mode_config.connector_list, - head) { + drm_connector_list_iter_begin(dev, &conn_iter); + drm_for_each_connector_iter(connector, &conn_iter) { struct gma_encoder *gma_encoder = gma_attached_encoder(connector); struct drm_encoder *encoder = &gma_encoder->base; int crtc_mask = 0, clone_mask = 0; @@ -505,6 +506,7 @@ static void psb_setup_outputs(struct drm_device *dev) encoder->possible_clones = gma_connector_clones(dev, clone_mask); } + drm_connector_list_iter_end(&conn_iter); } void psb_modeset_init(struct drm_device *dev) @@ -514,7 +516,8 @@ void psb_modeset_init(struct drm_device *dev) struct pci_dev *pdev = to_pci_dev(dev->dev); int i; - drm_mode_config_init(dev); + if (drmm_mode_config_init(dev)) + return; dev->mode_config.min_width = 0; dev->mode_config.min_height = 0; @@ -546,6 +549,5 @@ void psb_modeset_cleanup(struct drm_device *dev) if (dev_priv->modeset) { drm_kms_helper_poll_fini(dev); psb_fbdev_fini(dev); - drm_mode_config_cleanup(dev); } } diff --git a/drivers/gpu/drm/gma500/gem.c b/drivers/gpu/drm/gma500/gem.c index 8d65af80bb08..dffe37490206 100644 --- a/drivers/gpu/drm/gma500/gem.c +++ b/drivers/gpu/drm/gma500/gem.c @@ -21,6 +21,10 @@ #include "gem.h" #include "psb_drv.h" +/* + * PSB GEM object + */ + int psb_gem_pin(struct psb_gem_object *pobj) { struct drm_gem_object *obj = &pobj->base; @@ -31,7 +35,9 @@ int psb_gem_pin(struct psb_gem_object *pobj) unsigned int npages; int ret; - mutex_lock(&dev_priv->gtt_mutex); + ret = dma_resv_lock(obj->resv, NULL); + if (drm_WARN_ONCE(dev, ret, "dma_resv_lock() failed, ret=%d\n", ret)) + return ret; if (pobj->in_gart || pobj->stolen) goto out; /* already mapped */ @@ -39,7 +45,7 @@ int psb_gem_pin(struct psb_gem_object *pobj) pages = drm_gem_get_pages(obj); if (IS_ERR(pages)) { ret = PTR_ERR(pages); - goto err_mutex_unlock; + goto err_dma_resv_unlock; } npages = obj->size / PAGE_SIZE; @@ -51,17 +57,16 @@ int psb_gem_pin(struct psb_gem_object *pobj) (gpu_base + pobj->offset), npages, 0, 0, PSB_MMU_CACHED_MEMORY); - pobj->npage = npages; pobj->pages = pages; out: ++pobj->in_gart; - mutex_unlock(&dev_priv->gtt_mutex); + dma_resv_unlock(obj->resv); return 0; -err_mutex_unlock: - mutex_unlock(&dev_priv->gtt_mutex); +err_dma_resv_unlock: + dma_resv_unlock(obj->resv); return ret; } @@ -71,8 +76,12 @@ void psb_gem_unpin(struct psb_gem_object *pobj) struct drm_device *dev = obj->dev; struct drm_psb_private *dev_priv = to_drm_psb_private(dev); u32 gpu_base = dev_priv->gtt.gatt_start; + unsigned long npages; + int ret; - mutex_lock(&dev_priv->gtt_mutex); + ret = dma_resv_lock(obj->resv, NULL); + if (drm_WARN_ONCE(dev, ret, "dma_resv_lock() failed, ret=%d\n", ret)) + return; WARN_ON(!pobj->in_gart); @@ -81,19 +90,20 @@ void psb_gem_unpin(struct psb_gem_object *pobj) if (pobj->in_gart || pobj->stolen) goto out; + npages = obj->size / PAGE_SIZE; + psb_mmu_remove_pages(psb_mmu_get_default_pd(dev_priv->mmu), - (gpu_base + pobj->offset), pobj->npage, 0, 0); + (gpu_base + pobj->offset), npages, 0, 0); psb_gtt_remove_pages(dev_priv, &pobj->resource); /* Reset caching flags */ - set_pages_array_wb(pobj->pages, pobj->npage); + set_pages_array_wb(pobj->pages, npages); drm_gem_put_pages(obj, pobj->pages, true, false); pobj->pages = NULL; - pobj->npage = 0; out: - mutex_unlock(&dev_priv->gtt_mutex); + dma_resv_unlock(obj->resv); } static vm_fault_t psb_gem_fault(struct vm_fault *vmf); @@ -290,3 +300,132 @@ fail: return ret; } + +/* + * Memory management + */ + +/* Insert vram stolen pages into the GTT. */ +static void psb_gem_mm_populate_stolen(struct drm_psb_private *pdev) +{ + struct drm_device *dev = &pdev->dev; + unsigned int pfn_base; + unsigned int i, num_pages; + uint32_t pte; + + pfn_base = pdev->stolen_base >> PAGE_SHIFT; + num_pages = pdev->vram_stolen_size >> PAGE_SHIFT; + + drm_dbg(dev, "Set up %u stolen pages starting at 0x%08x, GTT offset %dK\n", + num_pages, pfn_base << PAGE_SHIFT, 0); + + for (i = 0; i < num_pages; ++i) { + pte = psb_gtt_mask_pte(pfn_base + i, PSB_MMU_CACHED_MEMORY); + iowrite32(pte, pdev->gtt_map + i); + } + + (void)ioread32(pdev->gtt_map + i - 1); +} + +int psb_gem_mm_init(struct drm_device *dev) +{ + struct drm_psb_private *dev_priv = to_drm_psb_private(dev); + struct pci_dev *pdev = to_pci_dev(dev->dev); + unsigned long stolen_size, vram_stolen_size; + struct psb_gtt *pg; + int ret; + + mutex_init(&dev_priv->mmap_mutex); + + pg = &dev_priv->gtt; + + pci_read_config_dword(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; + + dev_dbg(dev->dev, "Stolen memory base 0x%x, size %luK\n", + dev_priv->stolen_base, vram_stolen_size / 1024); + + pg->stolen_size = stolen_size; + dev_priv->vram_stolen_size = vram_stolen_size; + + dev_priv->vram_addr = ioremap_wc(dev_priv->stolen_base, stolen_size); + if (!dev_priv->vram_addr) { + dev_err(dev->dev, "Failure to map stolen base.\n"); + ret = -ENOMEM; + goto err_mutex_destroy; + } + + psb_gem_mm_populate_stolen(dev_priv); + + return 0; + +err_mutex_destroy: + mutex_destroy(&dev_priv->mmap_mutex); + return ret; +} + +void psb_gem_mm_fini(struct drm_device *dev) +{ + struct drm_psb_private *dev_priv = to_drm_psb_private(dev); + + iounmap(dev_priv->vram_addr); + + mutex_destroy(&dev_priv->mmap_mutex); +} + +/* Re-insert all pinned GEM objects into GTT. */ +static void psb_gem_mm_populate_resources(struct drm_psb_private *pdev) +{ + unsigned int restored = 0, total = 0, size = 0; + struct resource *r = pdev->gtt_mem->child; + struct drm_device *dev = &pdev->dev; + struct psb_gem_object *pobj; + + while (r) { + /* + * TODO: GTT restoration needs a refactoring, so that we don't have to touch + * struct psb_gem_object here. The type represents a GEM object and is + * not related to the GTT itself. + */ + pobj = container_of(r, struct psb_gem_object, resource); + if (pobj->pages) { + psb_gtt_insert_pages(pdev, &pobj->resource, pobj->pages); + size += resource_size(&pobj->resource); + ++restored; + } + r = r->sibling; + ++total; + } + + drm_dbg(dev, "Restored %u of %u gtt ranges (%u KB)", restored, total, (size / 1024)); +} + +int psb_gem_mm_resume(struct drm_device *dev) +{ + struct drm_psb_private *dev_priv = to_drm_psb_private(dev); + struct pci_dev *pdev = to_pci_dev(dev->dev); + unsigned long stolen_size, vram_stolen_size; + struct psb_gtt *pg; + + pg = &dev_priv->gtt; + + pci_read_config_dword(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; + + dev_dbg(dev->dev, "Stolen memory base 0x%x, size %luK\n", dev_priv->stolen_base, + vram_stolen_size / 1024); + + if (stolen_size != pg->stolen_size) { + dev_err(dev->dev, "GTT resume error.\n"); + return -EINVAL; + } + + psb_gem_mm_populate_stolen(dev_priv); + psb_gem_mm_populate_resources(dev_priv); + + return 0; +} diff --git a/drivers/gpu/drm/gma500/gem.h b/drivers/gpu/drm/gma500/gem.h index 79cced40c87f..27df6ff4ed37 100644 --- a/drivers/gpu/drm/gma500/gem.h +++ b/drivers/gpu/drm/gma500/gem.h @@ -14,6 +14,10 @@ struct drm_device; +/* + * PSB GEM object + */ + struct psb_gem_object { struct drm_gem_object base; @@ -23,7 +27,6 @@ struct psb_gem_object { bool stolen; /* Backed from stolen RAM */ bool mmapping; /* Is mmappable */ struct page **pages; /* Backing pages if present */ - int npage; /* Number of backing pages */ }; static inline struct psb_gem_object *to_psb_gem_object(struct drm_gem_object *obj) @@ -37,4 +40,12 @@ psb_gem_create(struct drm_device *dev, u64 size, const char *name, bool stolen, int psb_gem_pin(struct psb_gem_object *pobj); void psb_gem_unpin(struct psb_gem_object *pobj); +/* + * Memory management + */ + +int psb_gem_mm_init(struct drm_device *dev); +void psb_gem_mm_fini(struct drm_device *dev); +int psb_gem_mm_resume(struct drm_device *dev); + #endif diff --git a/drivers/gpu/drm/gma500/gma_display.c b/drivers/gpu/drm/gma500/gma_display.c index 60ba7de59139..34ec3fca09ba 100644 --- a/drivers/gpu/drm/gma500/gma_display.c +++ b/drivers/gpu/drm/gma500/gma_display.c @@ -17,7 +17,7 @@ #include "framebuffer.h" #include "gem.h" #include "gma_display.h" -#include "psb_drv.h" +#include "psb_irq.h" #include "psb_intel_drv.h" #include "psb_intel_reg.h" @@ -27,17 +27,21 @@ bool gma_pipe_has_type(struct drm_crtc *crtc, int type) { struct drm_device *dev = crtc->dev; - struct drm_mode_config *mode_config = &dev->mode_config; - struct drm_connector *l_entry; + struct drm_connector_list_iter conn_iter; + struct drm_connector *connector; - list_for_each_entry(l_entry, &mode_config->connector_list, head) { - if (l_entry->encoder && l_entry->encoder->crtc == crtc) { + drm_connector_list_iter_begin(dev, &conn_iter); + drm_for_each_connector_iter(connector, &conn_iter) { + if (connector->encoder && connector->encoder->crtc == crtc) { struct gma_encoder *gma_encoder = - gma_attached_encoder(l_entry); - if (gma_encoder->type == type) + gma_attached_encoder(connector); + if (gma_encoder->type == type) { + drm_connector_list_iter_end(&conn_iter); return true; + } } } + drm_connector_list_iter_end(&conn_iter); return false; } @@ -172,9 +176,9 @@ void gma_crtc_load_lut(struct drm_crtc *crtc) } } -int gma_crtc_gamma_set(struct drm_crtc *crtc, u16 *red, u16 *green, u16 *blue, - u32 size, - struct drm_modeset_acquire_ctx *ctx) +static int gma_crtc_gamma_set(struct drm_crtc *crtc, u16 *red, u16 *green, + u16 *blue, u32 size, + struct drm_modeset_acquire_ctx *ctx) { gma_crtc_load_lut(crtc); @@ -319,10 +323,9 @@ void gma_crtc_dpms(struct drm_crtc *crtc, int mode) REG_WRITE(DSPARB, 0x3F3E); } -int gma_crtc_cursor_set(struct drm_crtc *crtc, - struct drm_file *file_priv, - uint32_t handle, - uint32_t width, uint32_t height) +static int gma_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 = to_drm_psb_private(dev); @@ -391,11 +394,9 @@ int gma_crtc_cursor_set(struct drm_crtc *crtc, goto unref_cursor; } - /* Prevent overflow */ - if (pobj->npage > 4) - cursor_pages = 4; - else - cursor_pages = pobj->npage; + cursor_pages = obj->size / PAGE_SIZE; + if (cursor_pages > 4) + cursor_pages = 4; /* Prevent overflow */ /* Copy the cursor to cursor mem */ tmp_dst = dev_priv->vram_addr + cursor_pobj->offset; @@ -437,7 +438,7 @@ unref_cursor: return ret; } -int gma_crtc_cursor_move(struct drm_crtc *crtc, int x, int y) +static int gma_crtc_cursor_move(struct drm_crtc *crtc, int x, int y) { struct drm_device *dev = crtc->dev; struct gma_crtc *gma_crtc = to_gma_crtc(crtc); @@ -567,6 +568,18 @@ int gma_crtc_set_config(struct drm_mode_set *set, return ret; } +const struct drm_crtc_funcs gma_crtc_funcs = { + .cursor_set = gma_crtc_cursor_set, + .cursor_move = gma_crtc_cursor_move, + .gamma_set = gma_crtc_gamma_set, + .set_config = gma_crtc_set_config, + .destroy = gma_crtc_destroy, + .page_flip = gma_crtc_page_flip, + .enable_vblank = gma_crtc_enable_vblank, + .disable_vblank = gma_crtc_disable_vblank, + .get_vblank_counter = gma_crtc_get_vblank_counter, +}; + /* * Save HW states of given crtc */ diff --git a/drivers/gpu/drm/gma500/gma_display.h b/drivers/gpu/drm/gma500/gma_display.h index 7bd6c1ee8b21..113cf048105e 100644 --- a/drivers/gpu/drm/gma500/gma_display.h +++ b/drivers/gpu/drm/gma500/gma_display.h @@ -58,15 +58,7 @@ extern bool gma_pipe_has_type(struct drm_crtc *crtc, int type); extern void gma_wait_for_vblank(struct drm_device *dev); extern int gma_pipe_set_base(struct drm_crtc *crtc, int x, int y, struct drm_framebuffer *old_fb); -extern int gma_crtc_cursor_set(struct drm_crtc *crtc, - struct drm_file *file_priv, - uint32_t handle, - uint32_t width, uint32_t height); -extern int gma_crtc_cursor_move(struct drm_crtc *crtc, int x, int y); extern void gma_crtc_load_lut(struct drm_crtc *crtc); -extern int gma_crtc_gamma_set(struct drm_crtc *crtc, u16 *red, u16 *green, - u16 *blue, u32 size, - struct drm_modeset_acquire_ctx *ctx); extern void gma_crtc_dpms(struct drm_crtc *crtc, int mode); extern void gma_crtc_prepare(struct drm_crtc *crtc); extern void gma_crtc_commit(struct drm_crtc *crtc); @@ -83,6 +75,8 @@ extern int gma_crtc_set_config(struct drm_mode_set *set, extern void gma_crtc_save(struct drm_crtc *crtc); extern void gma_crtc_restore(struct drm_crtc *crtc); +extern const struct drm_crtc_funcs gma_crtc_funcs; + extern void gma_encoder_prepare(struct drm_encoder *encoder); extern void gma_encoder_commit(struct drm_encoder *encoder); extern void gma_encoder_destroy(struct drm_encoder *encoder); diff --git a/drivers/gpu/drm/gma500/gtt.c b/drivers/gpu/drm/gma500/gtt.c index 309ffe921bfd..379bc218aa6b 100644 --- a/drivers/gpu/drm/gma500/gtt.c +++ b/drivers/gpu/drm/gma500/gtt.c @@ -49,7 +49,7 @@ int psb_gtt_allocate_resource(struct drm_psb_private *pdev, struct resource *res * * Set the GTT entry for the appropriate memory type. */ -static inline uint32_t psb_gtt_mask_pte(uint32_t pfn, int type) +uint32_t psb_gtt_mask_pte(uint32_t pfn, int type) { uint32_t mask = PSB_PTE_VALID; @@ -74,11 +74,7 @@ static u32 __iomem *psb_gtt_entry(struct drm_psb_private *pdev, const struct res return pdev->gtt_map + (offset >> PAGE_SHIFT); } -/* - * Take our preallocated GTT range and insert the GEM object into - * the GTT. This is protected via the gtt mutex which the caller - * must hold. - */ +/* Acquires GTT mutex internally. */ void psb_gtt_insert_pages(struct drm_psb_private *pdev, const struct resource *res, struct page **pages) { @@ -86,6 +82,8 @@ void psb_gtt_insert_pages(struct drm_psb_private *pdev, const struct resource *r u32 __iomem *gtt_slot; u32 pte; + mutex_lock(&pdev->gtt_mutex); + /* Write our page entries into the GTT itself */ npages = resource_size(res) >> PAGE_SHIFT; @@ -98,19 +96,19 @@ void psb_gtt_insert_pages(struct drm_psb_private *pdev, const struct resource *r /* Make sure all the entries are set before we return */ ioread32(gtt_slot - 1); + + mutex_unlock(&pdev->gtt_mutex); } -/* - * Remove a preallocated GTT range from the GTT. Overwrite all the - * page table entries with the dummy page. This is protected via the gtt - * mutex which the caller must hold. - */ +/* Acquires GTT mutex internally. */ void psb_gtt_remove_pages(struct drm_psb_private *pdev, const struct resource *res) { resource_size_t npages, i; u32 __iomem *gtt_slot; u32 pte; + mutex_lock(&pdev->gtt_mutex); + /* Install scratch page for the resource */ pte = psb_gtt_mask_pte(page_to_pfn(pdev->scratch_page), PSB_MMU_CACHED_MEMORY); @@ -123,211 +121,192 @@ void psb_gtt_remove_pages(struct drm_psb_private *pdev, const struct resource *r /* Make sure all the entries are set before we return */ ioread32(gtt_slot - 1); + + mutex_unlock(&pdev->gtt_mutex); } -static void psb_gtt_alloc(struct drm_device *dev) +static int psb_gtt_enable(struct drm_psb_private *dev_priv) { - struct drm_psb_private *dev_priv = to_drm_psb_private(dev); - init_rwsem(&dev_priv->gtt.sem); + struct drm_device *dev = &dev_priv->dev; + struct pci_dev *pdev = to_pci_dev(dev->dev); + int ret; + + ret = pci_read_config_word(pdev, PSB_GMCH_CTRL, &dev_priv->gmch_ctrl); + if (ret) + return pcibios_err_to_errno(ret); + ret = pci_write_config_word(pdev, PSB_GMCH_CTRL, dev_priv->gmch_ctrl | _PSB_GMCH_ENABLED); + if (ret) + return pcibios_err_to_errno(ret); + + dev_priv->pge_ctl = PSB_RVDC32(PSB_PGETBL_CTL); + PSB_WVDC32(dev_priv->pge_ctl | _PSB_PGETBL_ENABLED, PSB_PGETBL_CTL); + + (void)PSB_RVDC32(PSB_PGETBL_CTL); + + return 0; } -void psb_gtt_takedown(struct drm_device *dev) +static void psb_gtt_disable(struct drm_psb_private *dev_priv) { - struct drm_psb_private *dev_priv = to_drm_psb_private(dev); + struct drm_device *dev = &dev_priv->dev; struct pci_dev *pdev = to_pci_dev(dev->dev); - if (dev_priv->gtt_map) { - iounmap(dev_priv->gtt_map); - dev_priv->gtt_map = NULL; - } - if (dev_priv->gtt_initialized) { - pci_write_config_word(pdev, PSB_GMCH_CTRL, - dev_priv->gmch_ctrl); - 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); + pci_write_config_word(pdev, PSB_GMCH_CTRL, dev_priv->gmch_ctrl); + PSB_WVDC32(dev_priv->pge_ctl, PSB_PGETBL_CTL); + + (void)PSB_RVDC32(PSB_PGETBL_CTL); } -int psb_gtt_init(struct drm_device *dev, int resume) +void psb_gtt_fini(struct drm_device *dev) { struct drm_psb_private *dev_priv = to_drm_psb_private(dev); - struct pci_dev *pdev = to_pci_dev(dev->dev); - unsigned gtt_pages; - unsigned long stolen_size, vram_stolen_size; - unsigned i, num_pages; - unsigned pfn_base; - struct psb_gtt *pg; - int ret = 0; + iounmap(dev_priv->gtt_map); + psb_gtt_disable(dev_priv); + mutex_destroy(&dev_priv->gtt_mutex); +} + +/* Clear GTT. Use a scratch page to avoid accidents or scribbles. */ +static void psb_gtt_clear(struct drm_psb_private *pdev) +{ + resource_size_t pfn_base; + unsigned long i; uint32_t pte; - if (!resume) { - mutex_init(&dev_priv->gtt_mutex); - mutex_init(&dev_priv->mmap_mutex); - psb_gtt_alloc(dev); - } + pfn_base = page_to_pfn(pdev->scratch_page); + pte = psb_gtt_mask_pte(pfn_base, PSB_MMU_CACHED_MEMORY); - pg = &dev_priv->gtt; + for (i = 0; i < pdev->gtt.gtt_pages; ++i) + iowrite32(pte, pdev->gtt_map + i); - /* Enable the GTT */ - pci_read_config_word(pdev, PSB_GMCH_CTRL, &dev_priv->gmch_ctrl); - pci_write_config_word(pdev, PSB_GMCH_CTRL, - dev_priv->gmch_ctrl | _PSB_GMCH_ENABLED); + (void)ioread32(pdev->gtt_map + i - 1); +} - dev_priv->pge_ctl = PSB_RVDC32(PSB_PGETBL_CTL); - PSB_WVDC32(dev_priv->pge_ctl | _PSB_PGETBL_ENABLED, PSB_PGETBL_CTL); - (void) PSB_RVDC32(PSB_PGETBL_CTL); +static void psb_gtt_init_ranges(struct drm_psb_private *dev_priv) +{ + struct drm_device *dev = &dev_priv->dev; + struct pci_dev *pdev = to_pci_dev(dev->dev); + struct psb_gtt *pg = &dev_priv->gtt; + resource_size_t gtt_phys_start, mmu_gatt_start, gtt_start, gtt_pages, + gatt_start, gatt_pages; + struct resource *gtt_mem; /* The root resource we allocate address space from */ - dev_priv->gtt_initialized = 1; - - pg->gtt_phys_start = dev_priv->pge_ctl & PAGE_MASK; + gtt_phys_start = dev_priv->pge_ctl & PAGE_MASK; /* - * 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. + * The video MMU has a HW bug when accessing 0x0d0000000. Make + * GATT start at 0x0e0000000. This doesn't actually matter for + * us now, but maybe will if the video acceleration ever gets + * opened up. */ - pg->mmu_gatt_start = 0xE0000000; + mmu_gatt_start = 0xe0000000; + + gtt_start = pci_resource_start(pdev, PSB_GTT_RESOURCE); + gtt_pages = pci_resource_len(pdev, PSB_GTT_RESOURCE) >> PAGE_SHIFT; - pg->gtt_start = pci_resource_start(pdev, PSB_GTT_RESOURCE); - gtt_pages = pci_resource_len(pdev, PSB_GTT_RESOURCE) - >> PAGE_SHIFT; /* CDV doesn't report this. In which case the system has 64 gtt pages */ - if (pg->gtt_start == 0 || gtt_pages == 0) { + if (!gtt_start || !gtt_pages) { dev_dbg(dev->dev, "GTT PCI BAR not initialized.\n"); gtt_pages = 64; - pg->gtt_start = dev_priv->pge_ctl; + gtt_start = dev_priv->pge_ctl; } - pg->gatt_start = pci_resource_start(pdev, PSB_GATT_RESOURCE); - pg->gatt_pages = pci_resource_len(pdev, PSB_GATT_RESOURCE) - >> PAGE_SHIFT; - dev_priv->gtt_mem = &pdev->resource[PSB_GATT_RESOURCE]; + gatt_start = pci_resource_start(pdev, PSB_GATT_RESOURCE); + gatt_pages = pci_resource_len(pdev, PSB_GATT_RESOURCE) >> PAGE_SHIFT; - if (pg->gatt_pages == 0 || pg->gatt_start == 0) { + if (!gatt_pages || !gatt_start) { static struct resource fudge; /* Preferably peppermint */ - /* This can occur on CDV systems. Fudge it in this case. - We really don't care what imaginary space is being allocated - at this point */ + + /* + * This can occur on CDV systems. Fudge it in this case. We + * really don't care what imaginary space is being allocated + * at this point. + */ dev_dbg(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 */ + gatt_start = 0x40000000; + 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"; fudge.flags = IORESOURCE_MEM; - dev_priv->gtt_mem = &fudge; + + gtt_mem = &fudge; + } else { + gtt_mem = &pdev->resource[PSB_GATT_RESOURCE]; } - pci_read_config_dword(pdev, PSB_BSM, &dev_priv->stolen_base); - vram_stolen_size = pg->gtt_phys_start - dev_priv->stolen_base - - PAGE_SIZE; + pg->gtt_phys_start = gtt_phys_start; + pg->mmu_gatt_start = mmu_gatt_start; + pg->gtt_start = gtt_start; + pg->gtt_pages = gtt_pages; + pg->gatt_start = gatt_start; + pg->gatt_pages = gatt_pages; + dev_priv->gtt_mem = gtt_mem; +} - stolen_size = vram_stolen_size; +int psb_gtt_init(struct drm_device *dev) +{ + struct drm_psb_private *dev_priv = to_drm_psb_private(dev); + struct psb_gtt *pg = &dev_priv->gtt; + int ret; - dev_dbg(dev->dev, "Stolen memory base 0x%x, size %luK\n", - dev_priv->stolen_base, vram_stolen_size / 1024); + mutex_init(&dev_priv->gtt_mutex); - if (resume && (gtt_pages != pg->gtt_pages) && - (stolen_size != pg->stolen_size)) { - dev_err(dev->dev, "GTT resume error.\n"); - ret = -EINVAL; - goto out_err; - } + ret = psb_gtt_enable(dev_priv); + if (ret) + goto err_mutex_destroy; - pg->gtt_pages = gtt_pages; - pg->stolen_size = stolen_size; - dev_priv->vram_stolen_size = vram_stolen_size; + psb_gtt_init_ranges(dev_priv); - /* - * Map the GTT and the stolen memory area - */ - if (!resume) - dev_priv->gtt_map = ioremap(pg->gtt_phys_start, - gtt_pages << PAGE_SHIFT); + dev_priv->gtt_map = ioremap(pg->gtt_phys_start, pg->gtt_pages << PAGE_SHIFT); if (!dev_priv->gtt_map) { dev_err(dev->dev, "Failure to map gtt.\n"); ret = -ENOMEM; - goto out_err; - } - - if (!resume) - dev_priv->vram_addr = ioremap_wc(dev_priv->stolen_base, - stolen_size); - - if (!dev_priv->vram_addr) { - dev_err(dev->dev, "Failure to map stolen base.\n"); - ret = -ENOMEM; - goto out_err; + goto err_psb_gtt_disable; } - /* - * Insert vram stolen pages into the GTT - */ - - pfn_base = dev_priv->stolen_base >> PAGE_SHIFT; - num_pages = vram_stolen_size >> PAGE_SHIFT; - dev_dbg(dev->dev, "Set up %d stolen pages starting at 0x%08x, GTT offset %dK\n", - num_pages, pfn_base << PAGE_SHIFT, 0); - for (i = 0; i < num_pages; ++i) { - pte = psb_gtt_mask_pte(pfn_base + i, PSB_MMU_CACHED_MEMORY); - iowrite32(pte, dev_priv->gtt_map + i); - } - - /* - * Init rest of GTT to the scratch page to avoid accidents or scribbles - */ + psb_gtt_clear(dev_priv); - pfn_base = page_to_pfn(dev_priv->scratch_page); - pte = psb_gtt_mask_pte(pfn_base, PSB_MMU_CACHED_MEMORY); - for (; i < gtt_pages; ++i) - iowrite32(pte, dev_priv->gtt_map + i); - - (void) ioread32(dev_priv->gtt_map + i - 1); return 0; -out_err: - psb_gtt_takedown(dev); +err_psb_gtt_disable: + psb_gtt_disable(dev_priv); +err_mutex_destroy: + mutex_destroy(&dev_priv->gtt_mutex); return ret; } -int psb_gtt_restore(struct drm_device *dev) +int psb_gtt_resume(struct drm_device *dev) { struct drm_psb_private *dev_priv = to_drm_psb_private(dev); - struct resource *r = dev_priv->gtt_mem->child; - struct psb_gem_object *pobj; - unsigned int restored = 0, total = 0, size = 0; + struct psb_gtt *pg = &dev_priv->gtt; + unsigned int old_gtt_pages = pg->gtt_pages; + int ret; - /* On resume, the gtt_mutex is already initialized */ - mutex_lock(&dev_priv->gtt_mutex); - psb_gtt_init(dev, 1); + /* Enable the GTT */ + ret = psb_gtt_enable(dev_priv); + if (ret) + return ret; - while (r != NULL) { - /* - * TODO: GTT restoration needs a refactoring, so that we don't have to touch - * struct psb_gem_object here. The type represents a GEM object and is - * not related to the GTT itself. - */ - pobj = container_of(r, struct psb_gem_object, resource); - if (pobj->pages) { - psb_gtt_insert_pages(dev_priv, &pobj->resource, pobj->pages); - size += pobj->resource.end - pobj->resource.start; - restored++; - } - r = r->sibling; - total++; + psb_gtt_init_ranges(dev_priv); + + if (old_gtt_pages != pg->gtt_pages) { + dev_err(dev->dev, "GTT resume error.\n"); + ret = -ENODEV; + goto err_psb_gtt_disable; } - mutex_unlock(&dev_priv->gtt_mutex); - DRM_DEBUG_DRIVER("Restored %u of %u gtt ranges (%u KB)", restored, - total, (size / 1024)); - return 0; + psb_gtt_clear(dev_priv); + +err_psb_gtt_disable: + psb_gtt_disable(dev_priv); + return ret; } diff --git a/drivers/gpu/drm/gma500/gtt.h b/drivers/gpu/drm/gma500/gtt.h index ff1dcdd1ff52..d5a5fd4466c1 100644 --- a/drivers/gpu/drm/gma500/gtt.h +++ b/drivers/gpu/drm/gma500/gtt.h @@ -22,18 +22,18 @@ struct psb_gtt { unsigned gatt_pages; unsigned long stolen_size; unsigned long vram_stolen_size; - struct rw_semaphore sem; }; /* Exported functions */ -extern int psb_gtt_init(struct drm_device *dev, int resume); -extern void psb_gtt_takedown(struct drm_device *dev); -extern int psb_gtt_restore(struct drm_device *dev); +int psb_gtt_init(struct drm_device *dev); +void psb_gtt_fini(struct drm_device *dev); +int psb_gtt_resume(struct drm_device *dev); int psb_gtt_allocate_resource(struct drm_psb_private *pdev, struct resource *res, const char *name, resource_size_t size, resource_size_t align, bool stolen, u32 *offset); +uint32_t psb_gtt_mask_pte(uint32_t pfn, int type); void psb_gtt_insert_pages(struct drm_psb_private *pdev, const struct resource *res, struct page **pages); void psb_gtt_remove_pages(struct drm_psb_private *pdev, const struct resource *res); diff --git a/drivers/gpu/drm/gma500/intel_bios.c b/drivers/gpu/drm/gma500/intel_bios.c index ea7c16f33a0e..8245b5603d2c 100644 --- a/drivers/gpu/drm/gma500/intel_bios.c +++ b/drivers/gpu/drm/gma500/intel_bios.c @@ -5,8 +5,9 @@ * Authors: * Eric Anholt <eric@anholt.net> */ + +#include <drm/display/drm_dp_helper.h> #include <drm/drm.h> -#include <drm/dp/drm_dp_helper.h> #include "intel_bios.h" #include "psb_drv.h" diff --git a/drivers/gpu/drm/gma500/oaktrail_crtc.c b/drivers/gpu/drm/gma500/oaktrail_crtc.c index 36c7c2686c90..22398d34853a 100644 --- a/drivers/gpu/drm/gma500/oaktrail_crtc.c +++ b/drivers/gpu/drm/gma500/oaktrail_crtc.c @@ -372,9 +372,9 @@ static int oaktrail_crtc_mode_set(struct drm_crtc *crtc, bool ok, is_sdvo = false; bool is_lvds = false; bool is_mipi = false; - struct drm_mode_config *mode_config = &dev->mode_config; struct gma_encoder *gma_encoder = NULL; uint64_t scalingType = DRM_MODE_SCALE_FULLSCREEN; + struct drm_connector_list_iter conn_iter; struct drm_connector *connector; int i; int need_aux = gma_pipe_has_type(crtc, INTEL_OUTPUT_SDVO) ? 1 : 0; @@ -385,14 +385,11 @@ static int oaktrail_crtc_mode_set(struct drm_crtc *crtc, if (!gma_power_begin(dev, true)) return 0; - memcpy(&gma_crtc->saved_mode, - mode, - sizeof(struct drm_display_mode)); - memcpy(&gma_crtc->saved_adjusted_mode, - adjusted_mode, - sizeof(struct drm_display_mode)); + drm_mode_copy(&gma_crtc->saved_mode, mode); + drm_mode_copy(&gma_crtc->saved_adjusted_mode, adjusted_mode); - list_for_each_entry(connector, &mode_config->connector_list, head) { + drm_connector_list_iter_begin(dev, &conn_iter); + drm_for_each_connector_iter(connector, &conn_iter) { if (!connector->encoder || connector->encoder->crtc != crtc) continue; @@ -409,8 +406,16 @@ static int oaktrail_crtc_mode_set(struct drm_crtc *crtc, is_mipi = true; break; } + + break; } + if (gma_encoder) + drm_object_property_get_value(&connector->base, + dev->mode_config.scaling_mode_property, &scalingType); + + drm_connector_list_iter_end(&conn_iter); + /* Disable the VGA plane that we never use */ for (i = 0; i <= need_aux; i++) REG_WRITE_WITH_AUX(VGACNTRL, VGA_DISP_DISABLE, i); @@ -424,10 +429,6 @@ static int oaktrail_crtc_mode_set(struct drm_crtc *crtc, (mode->crtc_vdisplay - 1), i); } - if (gma_encoder) - drm_object_property_get_value(&connector->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 diff --git a/drivers/gpu/drm/gma500/oaktrail_device.c b/drivers/gpu/drm/gma500/oaktrail_device.c index 5c75eae630b5..5923a9c89312 100644 --- a/drivers/gpu/drm/gma500/oaktrail_device.c +++ b/drivers/gpu/drm/gma500/oaktrail_device.c @@ -545,7 +545,6 @@ const struct psb_ops oaktrail_chip_ops = { .chip_setup = oaktrail_chip_setup, .chip_teardown = oaktrail_teardown, .crtc_helper = &oaktrail_helper_funcs, - .crtc_funcs = &gma_intel_crtc_funcs, .output_init = oaktrail_output_init, diff --git a/drivers/gpu/drm/gma500/oaktrail_hdmi.c b/drivers/gpu/drm/gma500/oaktrail_hdmi.c index 6eef60a5ac27..b5946a1cdcd5 100644 --- a/drivers/gpu/drm/gma500/oaktrail_hdmi.c +++ b/drivers/gpu/drm/gma500/oaktrail_hdmi.c @@ -654,7 +654,6 @@ void oaktrail_hdmi_init(struct drm_device *dev, connector->display_info.subpixel_order = SubPixelHorizontalRGB; connector->interlace_allowed = false; connector->doublescan_allowed = false; - drm_connector_register(connector); dev_info(dev->dev, "HDMI initialised.\n"); return; diff --git a/drivers/gpu/drm/gma500/oaktrail_lvds.c b/drivers/gpu/drm/gma500/oaktrail_lvds.c index 28b995ef2844..aed5de8f8245 100644 --- a/drivers/gpu/drm/gma500/oaktrail_lvds.c +++ b/drivers/gpu/drm/gma500/oaktrail_lvds.c @@ -85,7 +85,7 @@ static void oaktrail_lvds_mode_set(struct drm_encoder *encoder, struct drm_device *dev = encoder->dev; struct drm_psb_private *dev_priv = to_drm_psb_private(dev); struct psb_intel_mode_device *mode_dev = &dev_priv->mode_dev; - struct drm_mode_config *mode_config = &dev->mode_config; + struct drm_connector_list_iter conn_iter; struct drm_connector *connector = NULL; struct drm_crtc *crtc = encoder->crtc; u32 lvds_port; @@ -112,21 +112,22 @@ static void oaktrail_lvds_mode_set(struct drm_encoder *encoder, REG_WRITE(LVDS, lvds_port); /* Find the connector we're trying to set up */ - list_for_each_entry(connector, &mode_config->connector_list, head) { + drm_connector_list_iter_begin(dev, &conn_iter); + drm_for_each_connector_iter(connector, &conn_iter) { if (connector->encoder && connector->encoder->crtc == crtc) break; } - if (list_entry_is_head(connector, &mode_config->connector_list, head)) { + if (!connector) { + drm_connector_list_iter_end(&conn_iter); DRM_ERROR("Couldn't find connector when setting mode"); gma_power_end(dev); return; } - drm_object_property_get_value( - &connector->base, - dev->mode_config.scaling_mode_property, - &v); + drm_object_property_get_value( &connector->base, + dev->mode_config.scaling_mode_property, &v); + drm_connector_list_iter_end(&conn_iter); if (v == DRM_MODE_SCALE_NO_SCALE) REG_WRITE(PFIT_CONTROL, 0); @@ -400,7 +401,6 @@ void oaktrail_lvds_init(struct drm_device *dev, out: mutex_unlock(&dev->mode_config.mutex); - drm_connector_register(connector); return; failed_find: diff --git a/drivers/gpu/drm/gma500/opregion.c b/drivers/gpu/drm/gma500/opregion.c index fef04ff8c3a9..dc494df71a48 100644 --- a/drivers/gpu/drm/gma500/opregion.c +++ b/drivers/gpu/drm/gma500/opregion.c @@ -23,6 +23,7 @@ */ #include <linux/acpi.h> #include "psb_drv.h" +#include "psb_irq.h" #include "psb_intel_reg.h" #define PCI_ASLE 0xe4 @@ -217,8 +218,8 @@ void psb_intel_opregion_enable_asle(struct drm_device *dev) if (asle && system_opregion ) { /* Don't do this on Medfield or other non PC like devices, they use the bit for something different altogether */ - psb_enable_pipestat(dev_priv, 0, PIPE_LEGACY_BLC_EVENT_ENABLE); - psb_enable_pipestat(dev_priv, 1, PIPE_LEGACY_BLC_EVENT_ENABLE); + gma_enable_pipestat(dev_priv, 0, PIPE_LEGACY_BLC_EVENT_ENABLE); + gma_enable_pipestat(dev_priv, 1, PIPE_LEGACY_BLC_EVENT_ENABLE); asle->tche = ASLE_ALS_EN | ASLE_BLC_EN | ASLE_PFIT_EN | ASLE_PFMB_EN; diff --git a/drivers/gpu/drm/gma500/power.c b/drivers/gpu/drm/gma500/power.c index d2a46d96e746..b91de6d36e41 100644 --- a/drivers/gpu/drm/gma500/power.c +++ b/drivers/gpu/drm/gma500/power.c @@ -28,6 +28,7 @@ * Alan Cox <alan@linux.intel.com> */ +#include "gem.h" #include "power.h" #include "psb_drv.h" #include "psb_reg.h" @@ -112,7 +113,9 @@ static void gma_resume_display(struct pci_dev *pdev) pci_write_config_word(pdev, PSB_GMCH_CTRL, dev_priv->gmch_ctrl | _PSB_GMCH_ENABLED); - psb_gtt_restore(dev); /* Rebuild our GTT mappings */ + /* Rebuild our GTT mappings */ + psb_gtt_resume(dev); + psb_gem_mm_resume(dev); dev_priv->ops->restore_regs(dev); } @@ -198,7 +201,7 @@ int gma_power_suspend(struct device *_dev) dev_err(dev->dev, "GPU hardware busy, cannot suspend\n"); return -EBUSY; } - psb_irq_uninstall(dev); + gma_irq_uninstall(dev); gma_suspend_display(dev); gma_suspend_pci(pdev); } @@ -220,8 +223,8 @@ int gma_power_resume(struct device *_dev) mutex_lock(&power_mutex); gma_resume_pci(pdev); gma_resume_display(pdev); - psb_irq_preinstall(dev); - psb_irq_postinstall(dev); + gma_irq_preinstall(dev); + gma_irq_postinstall(dev); mutex_unlock(&power_mutex); return 0; } @@ -267,8 +270,8 @@ bool gma_power_begin(struct drm_device *dev, bool force_on) /* Ok power up needed */ ret = gma_resume_pci(pdev); if (ret == 0) { - psb_irq_preinstall(dev); - psb_irq_postinstall(dev); + gma_irq_preinstall(dev); + gma_irq_postinstall(dev); pm_runtime_get(dev->dev); dev_priv->display_count++; spin_unlock_irqrestore(&power_ctrl_lock, flags); diff --git a/drivers/gpu/drm/gma500/psb_device.c b/drivers/gpu/drm/gma500/psb_device.c index 3030f18ba022..71534f4ca834 100644 --- a/drivers/gpu/drm/gma500/psb_device.c +++ b/drivers/gpu/drm/gma500/psb_device.c @@ -168,8 +168,10 @@ static void psb_init_pm(struct drm_device *dev) static int psb_save_display_registers(struct drm_device *dev) { struct drm_psb_private *dev_priv = to_drm_psb_private(dev); + struct gma_connector *gma_connector; struct drm_crtc *crtc; - struct gma_connector *connector; + struct drm_connector_list_iter conn_iter; + struct drm_connector *connector; struct psb_state *regs = &dev_priv->regs.psb; /* Display arbitration control + watermarks */ @@ -189,9 +191,13 @@ static int psb_save_display_registers(struct drm_device *dev) dev_priv->ops->save_crtc(crtc); } - list_for_each_entry(connector, &dev->mode_config.connector_list, base.head) - if (connector->save) - connector->save(&connector->base); + drm_connector_list_iter_begin(dev, &conn_iter); + drm_for_each_connector_iter(connector, &conn_iter) { + gma_connector = to_gma_connector(connector); + if (gma_connector->save) + gma_connector->save(connector); + } + drm_connector_list_iter_end(&conn_iter); drm_modeset_unlock_all(dev); return 0; @@ -206,8 +212,10 @@ static int psb_save_display_registers(struct drm_device *dev) static int psb_restore_display_registers(struct drm_device *dev) { struct drm_psb_private *dev_priv = to_drm_psb_private(dev); + struct gma_connector *gma_connector; struct drm_crtc *crtc; - struct gma_connector *connector; + struct drm_connector_list_iter conn_iter; + struct drm_connector *connector; struct psb_state *regs = &dev_priv->regs.psb; /* Display arbitration + watermarks */ @@ -228,9 +236,13 @@ static int psb_restore_display_registers(struct drm_device *dev) if (drm_helper_crtc_in_use(crtc)) dev_priv->ops->restore_crtc(crtc); - list_for_each_entry(connector, &dev->mode_config.connector_list, base.head) - if (connector->restore) - connector->restore(&connector->base); + drm_connector_list_iter_begin(dev, &conn_iter); + drm_for_each_connector_iter(connector, &conn_iter) { + gma_connector = to_gma_connector(connector); + if (gma_connector->restore) + gma_connector->restore(connector); + } + drm_connector_list_iter_end(&conn_iter); drm_modeset_unlock_all(dev); return 0; @@ -329,7 +341,6 @@ const struct psb_ops psb_chip_ops = { .chip_teardown = psb_chip_teardown, .crtc_helper = &psb_intel_helper_funcs, - .crtc_funcs = &gma_intel_crtc_funcs, .clock_funcs = &psb_clock_funcs, .output_init = psb_output_init, diff --git a/drivers/gpu/drm/gma500/psb_drv.c b/drivers/gpu/drm/gma500/psb_drv.c index eeb681be9c95..1d8744f3e702 100644 --- a/drivers/gpu/drm/gma500/psb_drv.c +++ b/drivers/gpu/drm/gma500/psb_drv.c @@ -28,6 +28,7 @@ #include <drm/drm_vblank.h> #include "framebuffer.h" +#include "gem.h" #include "intel_bios.h" #include "mid_bios.h" #include "power.h" @@ -99,7 +100,7 @@ static const struct drm_ioctl_desc psb_ioctls[] = { * * Soft reset the graphics engine and then reload the necessary registers. */ -void psb_spank(struct drm_psb_private *dev_priv) +static void psb_spank(struct drm_psb_private *dev_priv) { PSB_WSGX32(_PSB_CS_RESET_BIF_RESET | _PSB_CS_RESET_DPM_RESET | _PSB_CS_RESET_TA_RESET | _PSB_CS_RESET_USE_RESET | @@ -172,6 +173,8 @@ static void psb_driver_unload(struct drm_device *dev) gma_backlight_exit(dev); psb_modeset_cleanup(dev); + gma_irq_uninstall(dev); + if (dev_priv->ops->chip_teardown) dev_priv->ops->chip_teardown(dev); @@ -184,17 +187,16 @@ static void psb_driver_unload(struct drm_device *dev) if (dev_priv->mmu) { struct psb_gtt *pg = &dev_priv->gtt; - down_read(&pg->sem); psb_mmu_remove_pfn_sequence( psb_mmu_get_default_pd (dev_priv->mmu), pg->mmu_gatt_start, dev_priv->vram_stolen_size >> PAGE_SHIFT); - up_read(&pg->sem); psb_mmu_driver_takedown(dev_priv->mmu); dev_priv->mmu = NULL; } - psb_gtt_takedown(dev); + psb_gem_mm_fini(dev); + psb_gtt_fini(dev); if (dev_priv->scratch_page) { set_pages_wb(dev_priv->scratch_page, 1); __free_page(dev_priv->scratch_page); @@ -234,10 +236,11 @@ static int psb_driver_load(struct drm_device *dev, unsigned long flags) struct drm_psb_private *dev_priv = to_drm_psb_private(dev); unsigned long resource_start, resource_len; unsigned long irqflags; - int ret = -ENOMEM; + struct drm_connector_list_iter conn_iter; struct drm_connector *connector; struct gma_encoder *gma_encoder; struct psb_gtt *pg; + int ret = -ENOMEM; /* initializing driver private data */ @@ -326,7 +329,10 @@ static int psb_driver_load(struct drm_device *dev, unsigned long flags) set_pages_uc(dev_priv->scratch_page, 1); - ret = psb_gtt_init(dev, 0); + ret = psb_gtt_init(dev); + if (ret) + goto out_err; + ret = psb_gem_mm_init(dev); if (ret) goto out_err; @@ -345,12 +351,10 @@ static int psb_driver_load(struct drm_device *dev, unsigned long flags) return ret; /* Add stolen memory to SGX MMU */ - down_read(&pg->sem); ret = psb_mmu_insert_pfn_sequence(psb_mmu_get_default_pd(dev_priv->mmu), dev_priv->stolen_base >> PAGE_SHIFT, pg->gatt_start, pg->stolen_size >> PAGE_SHIFT, 0); - up_read(&pg->sem); psb_mmu_set_pd_context(psb_mmu_get_default_pd(dev_priv->mmu), 0); psb_mmu_set_pd_context(dev_priv->pf_pd, 1); @@ -379,7 +383,7 @@ static int psb_driver_load(struct drm_device *dev, unsigned long flags) PSB_WVDC32(0xFFFFFFFF, PSB_INT_MASK_R); spin_unlock_irqrestore(&dev_priv->irqmask_lock, irqflags); - psb_irq_install(dev, pdev->irq); + gma_irq_install(dev, pdev->irq); dev->max_vblank_count = 0xffffff; /* only 24 bits of frame count */ @@ -387,18 +391,18 @@ static int psb_driver_load(struct drm_device *dev, unsigned long flags) psb_fbdev_init(dev); drm_kms_helper_poll_init(dev); - /* Only add backlight support if we have LVDS output */ - list_for_each_entry(connector, &dev->mode_config.connector_list, - head) { + /* Only add backlight support if we have LVDS or MIPI output */ + drm_connector_list_iter_begin(dev, &conn_iter); + drm_for_each_connector_iter(connector, &conn_iter) { gma_encoder = gma_attached_encoder(connector); - switch (gma_encoder->type) { - case INTEL_OUTPUT_LVDS: - case INTEL_OUTPUT_MIPI: + if (gma_encoder->type == INTEL_OUTPUT_LVDS || + gma_encoder->type == INTEL_OUTPUT_MIPI) { ret = gma_backlight_init(dev); break; } } + drm_connector_list_iter_end(&conn_iter); if (ret) return ret; diff --git a/drivers/gpu/drm/gma500/psb_drv.h b/drivers/gpu/drm/gma500/psb_drv.h index 0439b10d3db5..0ddfec1a0851 100644 --- a/drivers/gpu/drm/gma500/psb_drv.h +++ b/drivers/gpu/drm/gma500/psb_drv.h @@ -13,7 +13,6 @@ #include <drm/drm_device.h> -#include "gma_display.h" #include "gtt.h" #include "intel_bios.h" #include "mmu.h" @@ -36,12 +35,6 @@ /* Append new drm mode definition here, align with libdrm definition */ #define DRM_MODE_SCALE_NO_SCALE 2 -enum { - CHIP_PSB_8108 = 0, /* Poulsbo */ - CHIP_PSB_8109 = 1, /* Poulsbo */ - CHIP_MRST_4100 = 2, /* Moorestown/Oaktrail */ -}; - #define IS_PSB(drm) ((to_pci_dev((drm)->dev)->device & 0xfffe) == 0x8108) #define IS_MRST(drm) ((to_pci_dev((drm)->dev)->device & 0xfff0) == 0x4100) #define IS_CDV(drm) ((to_pci_dev((drm)->dev)->device & 0xfff0) == 0x0be0) @@ -408,7 +401,6 @@ struct drm_psb_private { uint32_t stolen_base; u8 __iomem *vram_addr; unsigned long vram_stolen_size; - int gtt_initialized; u16 gmch_ctrl; /* Saved GTT setup */ u32 pge_ctl; @@ -586,7 +578,6 @@ struct psb_ops { /* Sub functions */ struct drm_crtc_helper_funcs const *crtc_helper; - struct drm_crtc_funcs const *crtc_funcs; const struct gma_clock_funcs *clock_funcs; /* Setup hooks */ @@ -618,36 +609,9 @@ struct psb_ops { int i2c_bus; /* I2C bus identifier for Moorestown */ }; - - -extern int drm_crtc_probe_output_modes(struct drm_device *dev, int, int); -extern int drm_pick_crtcs(struct drm_device *dev); - -/* psb_irq.c */ -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_wait(struct drm_device *dev, unsigned int *sequence); -extern int psb_enable_vblank(struct drm_crtc *crtc); -extern void psb_disable_vblank(struct drm_crtc *crtc); -void -psb_enable_pipestat(struct drm_psb_private *dev_priv, int pipe, u32 mask); - -void -psb_disable_pipestat(struct drm_psb_private *dev_priv, int pipe, u32 mask); - -extern u32 psb_get_vblank_counter(struct drm_crtc *crtc); - -/* framebuffer.c */ -extern int psbfb_probed(struct drm_device *dev); -extern int psbfb_remove(struct drm_device *dev, - struct drm_framebuffer *fb); -/* psb_drv.c */ -extern void psb_spank(struct drm_psb_private *dev_priv); - -/* psb_reset.c */ +/* psb_lid.c */ extern void psb_lid_timer_init(struct drm_psb_private *dev_priv); extern void psb_lid_timer_takedown(struct drm_psb_private *dev_priv); -extern void psb_print_pagefault(struct drm_psb_private *dev_priv); /* modesetting */ extern void psb_modeset_init(struct drm_device *dev); @@ -670,7 +634,6 @@ extern void oaktrail_lvds_init(struct drm_device *dev, /* psb_intel_display.c */ extern const struct drm_crtc_helper_funcs psb_intel_helper_funcs; -extern const struct drm_crtc_funcs gma_intel_crtc_funcs; /* psb_intel_lvds.c */ extern const struct drm_connector_helper_funcs @@ -690,43 +653,7 @@ extern const struct psb_ops oaktrail_chip_ops; /* cdv_device.c */ extern const struct psb_ops cdv_chip_ops; -/* Debug print bits setting */ -#define PSB_D_GENERAL (1 << 0) -#define PSB_D_INIT (1 << 1) -#define PSB_D_IRQ (1 << 2) -#define PSB_D_ENTRY (1 << 3) -/* debug the get H/V BP/FP count */ -#define PSB_D_HV (1 << 4) -#define PSB_D_DBI_BF (1 << 5) -#define PSB_D_PM (1 << 6) -#define PSB_D_RENDER (1 << 7) -#define PSB_D_REG (1 << 8) -#define PSB_D_MSVDX (1 << 9) -#define PSB_D_TOPAZ (1 << 10) - -extern int drm_idle_check_interval; - /* Utilities */ -static inline u32 MRST_MSG_READ32(int domain, uint port, uint offset) -{ - int mcr = (0xD0<<24) | (port << 16) | (offset << 8); - uint32_t ret_val = 0; - struct pci_dev *pci_root = pci_get_domain_bus_and_slot(domain, 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(int domain, uint port, uint offset, - u32 value) -{ - int mcr = (0xE0<<24) | (port << 16) | (offset << 8) | 0xF0; - struct pci_dev *pci_root = pci_get_domain_bus_and_slot(domain, 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 uint32_t REGISTER_READ(struct drm_device *dev, uint32_t reg) { struct drm_psb_private *dev_priv = to_drm_psb_private(dev); @@ -807,24 +734,9 @@ static inline void REGISTER_WRITE8(struct drm_device *dev, #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 -#define PSB_RSGX32(_offs) \ -({ \ - if (inl(dev_priv->apm_base + PSB_APM_STS) & 0x3) { \ - pr_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)) -#endif #define PSB_WSGX32(_val, _offs) iowrite32(_val, dev_priv->sgx_reg + (_offs)) -#define MSVDX_REG_DUMP 0 - #define PSB_WMSVDX32(_val, _offs) iowrite32(_val, dev_priv->msvdx_reg + (_offs)) #define PSB_RMSVDX32(_offs) ioread32(dev_priv->msvdx_reg + (_offs)) diff --git a/drivers/gpu/drm/gma500/psb_intel_display.c b/drivers/gpu/drm/gma500/psb_intel_display.c index d5f95212934e..9a5ea06a1a8e 100644 --- a/drivers/gpu/drm/gma500/psb_intel_display.c +++ b/drivers/gpu/drm/gma500/psb_intel_display.c @@ -106,7 +106,7 @@ static int psb_intel_crtc_mode_set(struct drm_crtc *crtc, u32 dpll = 0, fp = 0, dspcntr, pipeconf; bool ok, is_sdvo = false; bool is_lvds = false, is_tv = false; - struct drm_mode_config *mode_config = &dev->mode_config; + struct drm_connector_list_iter conn_iter; struct drm_connector *connector; const struct gma_limit_t *limit; @@ -116,7 +116,8 @@ static int psb_intel_crtc_mode_set(struct drm_crtc *crtc, return 0; } - list_for_each_entry(connector, &mode_config->connector_list, head) { + drm_connector_list_iter_begin(dev, &conn_iter); + drm_for_each_connector_iter(connector, &conn_iter) { struct gma_encoder *gma_encoder = gma_attached_encoder(connector); if (!connector->encoder @@ -134,7 +135,10 @@ static int psb_intel_crtc_mode_set(struct drm_crtc *crtc, is_tv = true; break; } + + break; } + drm_connector_list_iter_end(&conn_iter); refclk = 96000; @@ -427,18 +431,6 @@ const struct drm_crtc_helper_funcs psb_intel_helper_funcs = { .disable = gma_crtc_disable, }; -const struct drm_crtc_funcs gma_intel_crtc_funcs = { - .cursor_set = gma_crtc_cursor_set, - .cursor_move = gma_crtc_cursor_move, - .gamma_set = gma_crtc_gamma_set, - .set_config = gma_crtc_set_config, - .destroy = gma_crtc_destroy, - .page_flip = gma_crtc_page_flip, - .enable_vblank = psb_enable_vblank, - .disable_vblank = psb_disable_vblank, - .get_vblank_counter = psb_get_vblank_counter, -}; - const struct gma_clock_funcs psb_clock_funcs = { .clock = psb_intel_clock, .limit = psb_intel_limit, @@ -500,8 +492,7 @@ void psb_intel_crtc_init(struct drm_device *dev, int pipe, return; } - /* Set the CRTC operations from the chip specific data */ - drm_crtc_init(dev, &gma_crtc->base, dev_priv->ops->crtc_funcs); + drm_crtc_init(dev, &gma_crtc->base, &gma_crtc_funcs); /* Set the CRTC clock functions from chip specific data */ gma_crtc->clock_funcs = dev_priv->ops->clock_funcs; @@ -535,28 +526,32 @@ void psb_intel_crtc_init(struct drm_device *dev, int pipe, struct drm_crtc *psb_intel_get_crtc_from_pipe(struct drm_device *dev, int pipe) { - struct drm_crtc *crtc = NULL; + struct drm_crtc *crtc; list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { struct gma_crtc *gma_crtc = to_gma_crtc(crtc); + if (gma_crtc->pipe == pipe) - break; + return crtc; } - return crtc; + return NULL; } int gma_connector_clones(struct drm_device *dev, int type_mask) { - int index_mask = 0; + struct drm_connector_list_iter conn_iter; struct drm_connector *connector; + int index_mask = 0; int entry = 0; - list_for_each_entry(connector, &dev->mode_config.connector_list, - head) { + drm_connector_list_iter_begin(dev, &conn_iter); + drm_for_each_connector_iter(connector, &conn_iter) { struct gma_encoder *gma_encoder = gma_attached_encoder(connector); if (type_mask & (1 << gma_encoder->type)) index_mask |= (1 << entry); entry++; } + drm_connector_list_iter_end(&conn_iter); + return index_mask; } diff --git a/drivers/gpu/drm/gma500/psb_intel_lvds.c b/drivers/gpu/drm/gma500/psb_intel_lvds.c index ac97e0d3c7dd..cad00380b386 100644 --- a/drivers/gpu/drm/gma500/psb_intel_lvds.c +++ b/drivers/gpu/drm/gma500/psb_intel_lvds.c @@ -521,13 +521,13 @@ static int psb_intel_lvds_get_modes(struct drm_connector *connector) */ void psb_intel_lvds_destroy(struct drm_connector *connector) { + struct gma_connector *gma_connector = to_gma_connector(connector); struct gma_encoder *gma_encoder = gma_attached_encoder(connector); struct psb_intel_lvds_priv *lvds_priv = gma_encoder->dev_priv; psb_intel_i2c_destroy(lvds_priv->ddc_bus); - drm_connector_unregister(connector); drm_connector_cleanup(connector); - kfree(connector); + kfree(gma_connector); } int psb_intel_lvds_set_property(struct drm_connector *connector, @@ -782,7 +782,6 @@ void psb_intel_lvds_init(struct drm_device *dev, */ out: mutex_unlock(&dev->mode_config.mutex); - drm_connector_register(connector); return; failed_find: diff --git a/drivers/gpu/drm/gma500/psb_intel_sdvo.c b/drivers/gpu/drm/gma500/psb_intel_sdvo.c index 042c4392e676..a85aace25548 100644 --- a/drivers/gpu/drm/gma500/psb_intel_sdvo.c +++ b/drivers/gpu/drm/gma500/psb_intel_sdvo.c @@ -1542,9 +1542,10 @@ static int psb_intel_sdvo_get_modes(struct drm_connector *connector) static void psb_intel_sdvo_destroy(struct drm_connector *connector) { - drm_connector_unregister(connector); + struct gma_connector *gma_connector = to_gma_connector(connector); + drm_connector_cleanup(connector); - kfree(connector); + kfree(gma_connector); } static bool psb_intel_sdvo_detect_hdmi_audio(struct drm_connector *connector) @@ -1932,7 +1933,6 @@ psb_intel_sdvo_connector_init(struct psb_intel_sdvo_connector *connector, connector->base.restore = psb_intel_sdvo_restore; gma_connector_attach_encoder(&connector->base, &encoder->base); - drm_connector_register(&connector->base.base); } static void diff --git a/drivers/gpu/drm/gma500/psb_irq.c b/drivers/gpu/drm/gma500/psb_irq.c index ccf402007beb..e6e6d61bbeab 100644 --- a/drivers/gpu/drm/gma500/psb_irq.c +++ b/drivers/gpu/drm/gma500/psb_irq.c @@ -21,8 +21,7 @@ * inline functions */ -static inline u32 -psb_pipestat(int pipe) +static inline u32 gma_pipestat(int pipe) { if (pipe == 0) return PIPEASTAT; @@ -33,8 +32,7 @@ psb_pipestat(int pipe) BUG(); } -static inline u32 -mid_pipe_event(int pipe) +static inline u32 gma_pipe_event(int pipe) { if (pipe == 0) return _PSB_PIPEA_EVENT_FLAG; @@ -45,20 +43,7 @@ mid_pipe_event(int pipe) BUG(); } -static inline u32 -mid_pipe_vsync(int pipe) -{ - if (pipe == 0) - return _PSB_VSYNC_PIPEA_FLAG; - if (pipe == 1) - return _PSB_VSYNC_PIPEB_FLAG; - if (pipe == 2) - return _MDFLD_PIPEC_VBLANK_FLAG; - BUG(); -} - -static inline u32 -mid_pipeconf(int pipe) +static inline u32 gma_pipeconf(int pipe) { if (pipe == 0) return PIPEACONF; @@ -69,11 +54,10 @@ mid_pipeconf(int pipe) BUG(); } -void -psb_enable_pipestat(struct drm_psb_private *dev_priv, int pipe, u32 mask) +void gma_enable_pipestat(struct drm_psb_private *dev_priv, int pipe, u32 mask) { if ((dev_priv->pipestat[pipe] & mask) != mask) { - u32 reg = psb_pipestat(pipe); + u32 reg = gma_pipestat(pipe); dev_priv->pipestat[pipe] |= mask; /* Enable the interrupt, clear any pending status */ if (gma_power_begin(&dev_priv->dev, false)) { @@ -86,11 +70,10 @@ psb_enable_pipestat(struct drm_psb_private *dev_priv, int pipe, u32 mask) } } -void -psb_disable_pipestat(struct drm_psb_private *dev_priv, int pipe, u32 mask) +void gma_disable_pipestat(struct drm_psb_private *dev_priv, int pipe, u32 mask) { if ((dev_priv->pipestat[pipe] & mask) != 0) { - u32 reg = psb_pipestat(pipe); + u32 reg = gma_pipestat(pipe); dev_priv->pipestat[pipe] &= ~mask; if (gma_power_begin(&dev_priv->dev, false)) { u32 writeVal = PSB_RVDC32(reg); @@ -105,12 +88,12 @@ psb_disable_pipestat(struct drm_psb_private *dev_priv, int pipe, u32 mask) /* * Display controller interrupt handler for pipe event. */ -static void mid_pipe_event_handler(struct drm_device *dev, int pipe) +static void gma_pipe_event_handler(struct drm_device *dev, int pipe) { struct drm_psb_private *dev_priv = to_drm_psb_private(dev); uint32_t pipe_stat_val = 0; - uint32_t pipe_stat_reg = psb_pipestat(pipe); + uint32_t pipe_stat_reg = gma_pipestat(pipe); uint32_t pipe_enable = dev_priv->pipestat[pipe]; uint32_t pipe_status = dev_priv->pipestat[pipe] >> 16; uint32_t pipe_clear; @@ -160,22 +143,22 @@ static void mid_pipe_event_handler(struct drm_device *dev, int pipe) /* * Display controller interrupt handler. */ -static void psb_vdc_interrupt(struct drm_device *dev, uint32_t vdc_stat) +static void gma_vdc_interrupt(struct drm_device *dev, uint32_t vdc_stat) { if (vdc_stat & _PSB_IRQ_ASLE) psb_intel_opregion_asle_intr(dev); if (vdc_stat & _PSB_VSYNC_PIPEA_FLAG) - mid_pipe_event_handler(dev, 0); + gma_pipe_event_handler(dev, 0); if (vdc_stat & _PSB_VSYNC_PIPEB_FLAG) - mid_pipe_event_handler(dev, 1); + gma_pipe_event_handler(dev, 1); } /* * SGX interrupt handler */ -static void psb_sgx_interrupt(struct drm_device *dev, u32 stat_1, u32 stat_2) +static void gma_sgx_interrupt(struct drm_device *dev, u32 stat_1, u32 stat_2) { struct drm_psb_private *dev_priv = to_drm_psb_private(dev); u32 val, addr; @@ -222,7 +205,7 @@ static void psb_sgx_interrupt(struct drm_device *dev, u32 stat_1, u32 stat_2) PSB_RSGX32(PSB_CR_EVENT_HOST_CLEAR2); } -static irqreturn_t psb_irq_handler(int irq, void *arg) +static irqreturn_t gma_irq_handler(int irq, void *arg) { struct drm_device *dev = arg; struct drm_psb_private *dev_priv = to_drm_psb_private(dev); @@ -246,14 +229,14 @@ static irqreturn_t psb_irq_handler(int irq, void *arg) spin_unlock(&dev_priv->irqmask_lock); if (dsp_int && gma_power_is_on(dev)) { - psb_vdc_interrupt(dev, vdc_stat); + gma_vdc_interrupt(dev, vdc_stat); handled = 1; } if (sgx_int) { sgx_stat_1 = PSB_RSGX32(PSB_CR_EVENT_STATUS); sgx_stat_2 = PSB_RSGX32(PSB_CR_EVENT_STATUS2); - psb_sgx_interrupt(dev, sgx_stat_1, sgx_stat_2); + gma_sgx_interrupt(dev, sgx_stat_1, sgx_stat_2); handled = 1; } @@ -274,7 +257,7 @@ static irqreturn_t psb_irq_handler(int irq, void *arg) return IRQ_HANDLED; } -void psb_irq_preinstall(struct drm_device *dev) +void gma_irq_preinstall(struct drm_device *dev) { struct drm_psb_private *dev_priv = to_drm_psb_private(dev); unsigned long irqflags; @@ -303,7 +286,7 @@ void psb_irq_preinstall(struct drm_device *dev) spin_unlock_irqrestore(&dev_priv->irqmask_lock, irqflags); } -void psb_irq_postinstall(struct drm_device *dev) +void gma_irq_postinstall(struct drm_device *dev) { struct drm_psb_private *dev_priv = to_drm_psb_private(dev); unsigned long irqflags; @@ -322,9 +305,9 @@ void psb_irq_postinstall(struct drm_device *dev) for (i = 0; i < dev->num_crtcs; ++i) { if (dev->vblank[i].enabled) - psb_enable_pipestat(dev_priv, i, PIPE_VBLANK_INTERRUPT_ENABLE); + gma_enable_pipestat(dev_priv, i, PIPE_VBLANK_INTERRUPT_ENABLE); else - psb_disable_pipestat(dev_priv, i, PIPE_VBLANK_INTERRUPT_ENABLE); + gma_disable_pipestat(dev_priv, i, PIPE_VBLANK_INTERRUPT_ENABLE); } if (dev_priv->ops->hotplug_enable) @@ -333,26 +316,26 @@ void psb_irq_postinstall(struct drm_device *dev) spin_unlock_irqrestore(&dev_priv->irqmask_lock, irqflags); } -int psb_irq_install(struct drm_device *dev, unsigned int irq) +int gma_irq_install(struct drm_device *dev, unsigned int irq) { int ret; if (irq == IRQ_NOTCONNECTED) return -ENOTCONN; - psb_irq_preinstall(dev); + gma_irq_preinstall(dev); /* PCI devices require shared interrupts. */ - ret = request_irq(irq, psb_irq_handler, IRQF_SHARED, dev->driver->name, dev); + ret = request_irq(irq, gma_irq_handler, IRQF_SHARED, dev->driver->name, dev); if (ret) return ret; - psb_irq_postinstall(dev); + gma_irq_postinstall(dev); return 0; } -void psb_irq_uninstall(struct drm_device *dev) +void gma_irq_uninstall(struct drm_device *dev) { struct drm_psb_private *dev_priv = to_drm_psb_private(dev); struct pci_dev *pdev = to_pci_dev(dev->dev); @@ -368,7 +351,7 @@ void psb_irq_uninstall(struct drm_device *dev) for (i = 0; i < dev->num_crtcs; ++i) { if (dev->vblank[i].enabled) - psb_disable_pipestat(dev_priv, i, PIPE_VBLANK_INTERRUPT_ENABLE); + gma_disable_pipestat(dev_priv, i, PIPE_VBLANK_INTERRUPT_ENABLE); } dev_priv->vdc_irq_mask &= _PSB_IRQ_SGX_FLAG | @@ -388,17 +371,14 @@ void psb_irq_uninstall(struct drm_device *dev) free_irq(pdev->irq, dev); } -/* - * It is used to enable VBLANK interrupt - */ -int psb_enable_vblank(struct drm_crtc *crtc) +int gma_crtc_enable_vblank(struct drm_crtc *crtc) { struct drm_device *dev = crtc->dev; unsigned int pipe = crtc->index; struct drm_psb_private *dev_priv = to_drm_psb_private(dev); unsigned long irqflags; uint32_t reg_val = 0; - uint32_t pipeconf_reg = mid_pipeconf(pipe); + uint32_t pipeconf_reg = gma_pipeconf(pipe); if (gma_power_begin(dev, false)) { reg_val = REG_READ(pipeconf_reg); @@ -417,17 +397,14 @@ int psb_enable_vblank(struct drm_crtc *crtc) 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); + gma_enable_pipestat(dev_priv, pipe, PIPE_VBLANK_INTERRUPT_ENABLE); spin_unlock_irqrestore(&dev_priv->irqmask_lock, irqflags); return 0; } -/* - * It is used to disable VBLANK interrupt - */ -void psb_disable_vblank(struct drm_crtc *crtc) +void gma_crtc_disable_vblank(struct drm_crtc *crtc) { struct drm_device *dev = crtc->dev; unsigned int pipe = crtc->index; @@ -443,7 +420,7 @@ void psb_disable_vblank(struct drm_crtc *crtc) 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); + gma_disable_pipestat(dev_priv, pipe, PIPE_VBLANK_INTERRUPT_ENABLE); spin_unlock_irqrestore(&dev_priv->irqmask_lock, irqflags); } @@ -451,7 +428,7 @@ void psb_disable_vblank(struct drm_crtc *crtc) /* Called from drm generic code, passed a 'crtc', which * we use as a pipe index */ -u32 psb_get_vblank_counter(struct drm_crtc *crtc) +u32 gma_crtc_get_vblank_counter(struct drm_crtc *crtc) { struct drm_device *dev = crtc->dev; unsigned int pipe = crtc->index; @@ -486,8 +463,8 @@ u32 psb_get_vblank_counter(struct drm_crtc *crtc) if (!(reg_val & PIPEACONF_ENABLE)) { dev_err(dev->dev, "trying to get vblank count for disabled pipe %u\n", - pipe); - goto psb_get_vblank_counter_exit; + pipe); + goto err_gma_power_end; } /* @@ -506,8 +483,7 @@ u32 psb_get_vblank_counter(struct drm_crtc *crtc) count = (high1 << 8) | low; -psb_get_vblank_counter_exit: - +err_gma_power_end: gma_power_end(dev); return count; diff --git a/drivers/gpu/drm/gma500/psb_irq.h b/drivers/gpu/drm/gma500/psb_irq.h index a97cb49393d8..b51e395194ff 100644 --- a/drivers/gpu/drm/gma500/psb_irq.h +++ b/drivers/gpu/drm/gma500/psb_irq.h @@ -15,16 +15,15 @@ struct drm_crtc; struct drm_device; -bool sysirq_init(struct drm_device *dev); -void sysirq_uninit(struct drm_device *dev); +void gma_irq_preinstall(struct drm_device *dev); +void gma_irq_postinstall(struct drm_device *dev); +int gma_irq_install(struct drm_device *dev, unsigned int irq); +void gma_irq_uninstall(struct drm_device *dev); -void psb_irq_preinstall(struct drm_device *dev); -void psb_irq_postinstall(struct drm_device *dev); -int psb_irq_install(struct drm_device *dev, unsigned int irq); -void psb_irq_uninstall(struct drm_device *dev); - -int psb_enable_vblank(struct drm_crtc *crtc); -void psb_disable_vblank(struct drm_crtc *crtc); -u32 psb_get_vblank_counter(struct drm_crtc *crtc); +int gma_crtc_enable_vblank(struct drm_crtc *crtc); +void gma_crtc_disable_vblank(struct drm_crtc *crtc); +u32 gma_crtc_get_vblank_counter(struct drm_crtc *crtc); +void gma_enable_pipestat(struct drm_psb_private *dev_priv, int pipe, u32 mask); +void gma_disable_pipestat(struct drm_psb_private *dev_priv, int pipe, u32 mask); #endif /* _PSB_IRQ_H_ */ |