diff options
Diffstat (limited to 'drivers/gpu/drm')
41 files changed, 317 insertions, 164 deletions
diff --git a/drivers/gpu/drm/exynos/exynos_drm_connector.c b/drivers/gpu/drm/exynos/exynos_drm_connector.c index d620b078425..618bd4d87d2 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_connector.c +++ b/drivers/gpu/drm/exynos/exynos_drm_connector.c @@ -28,6 +28,7 @@ #include "drmP.h" #include "drm_crtc_helper.h" +#include <drm/exynos_drm.h> #include "exynos_drm_drv.h" #include "exynos_drm_encoder.h" @@ -44,8 +45,9 @@ struct exynos_drm_connector { /* convert exynos_video_timings to drm_display_mode */ static inline void convert_to_display_mode(struct drm_display_mode *mode, - struct fb_videomode *timing) + struct exynos_drm_panel_info *panel) { + struct fb_videomode *timing = &panel->timing; DRM_DEBUG_KMS("%s\n", __FILE__); mode->clock = timing->pixclock / 1000; @@ -60,6 +62,8 @@ convert_to_display_mode(struct drm_display_mode *mode, mode->vsync_start = mode->vdisplay + timing->upper_margin; mode->vsync_end = mode->vsync_start + timing->vsync_len; mode->vtotal = mode->vsync_end + timing->lower_margin; + mode->width_mm = panel->width_mm; + mode->height_mm = panel->height_mm; if (timing->vmode & FB_VMODE_INTERLACED) mode->flags |= DRM_MODE_FLAG_INTERLACE; @@ -148,16 +152,18 @@ static int exynos_drm_connector_get_modes(struct drm_connector *connector) connector->display_info.raw_edid = edid; } else { struct drm_display_mode *mode = drm_mode_create(connector->dev); - struct fb_videomode *timing; + struct exynos_drm_panel_info *panel; - if (display_ops->get_timing) - timing = display_ops->get_timing(manager->dev); + if (display_ops->get_panel) + panel = display_ops->get_panel(manager->dev); else { drm_mode_destroy(connector->dev, mode); return 0; } - convert_to_display_mode(mode, timing); + convert_to_display_mode(mode, panel); + connector->display_info.width_mm = mode->width_mm; + connector->display_info.height_mm = mode->height_mm; mode->type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED; drm_mode_set_name(mode); diff --git a/drivers/gpu/drm/exynos/exynos_drm_core.c b/drivers/gpu/drm/exynos/exynos_drm_core.c index 661a03571d0..d08a55896d5 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_core.c +++ b/drivers/gpu/drm/exynos/exynos_drm_core.c @@ -193,6 +193,9 @@ int exynos_drm_subdrv_register(struct exynos_drm_subdrv *subdrv) return err; } + /* setup possible_clones. */ + exynos_drm_encoder_setup(drm_dev); + /* * if any specific driver such as fimd or hdmi driver called * exynos_drm_subdrv_register() later than drm_load(), diff --git a/drivers/gpu/drm/exynos/exynos_drm_crtc.c b/drivers/gpu/drm/exynos/exynos_drm_crtc.c index e3861ac4929..de818831a51 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_crtc.c +++ b/drivers/gpu/drm/exynos/exynos_drm_crtc.c @@ -307,9 +307,6 @@ static int exynos_drm_crtc_page_flip(struct drm_crtc *crtc, */ event->pipe = exynos_crtc->pipe; - list_add_tail(&event->base.link, - &dev_priv->pageflip_event_list); - ret = drm_vblank_get(dev, exynos_crtc->pipe); if (ret) { DRM_DEBUG("failed to acquire vblank counter\n"); @@ -318,6 +315,9 @@ static int exynos_drm_crtc_page_flip(struct drm_crtc *crtc, goto out; } + list_add_tail(&event->base.link, + &dev_priv->pageflip_event_list); + crtc->fb = fb; ret = exynos_drm_crtc_update(crtc); if (ret) { diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.c b/drivers/gpu/drm/exynos/exynos_drm_drv.c index 35889ca255e..58820ebd355 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_drv.c +++ b/drivers/gpu/drm/exynos/exynos_drm_drv.c @@ -33,6 +33,7 @@ #include "exynos_drm_drv.h" #include "exynos_drm_crtc.h" +#include "exynos_drm_encoder.h" #include "exynos_drm_fbdev.h" #include "exynos_drm_fb.h" #include "exynos_drm_gem.h" @@ -99,6 +100,9 @@ static int exynos_drm_load(struct drm_device *dev, unsigned long flags) if (ret) goto err_vblank; + /* setup possible_clones. */ + exynos_drm_encoder_setup(dev); + /* * create and configure fb helper and also exynos specific * fbdev object. @@ -141,16 +145,21 @@ static int exynos_drm_unload(struct drm_device *dev) } static void exynos_drm_preclose(struct drm_device *dev, - struct drm_file *file_priv) + struct drm_file *file) { - struct exynos_drm_private *dev_priv = dev->dev_private; + DRM_DEBUG_DRIVER("%s\n", __FILE__); - /* - * drm framework frees all events at release time, - * so private event list should be cleared. - */ - if (!list_empty(&dev_priv->pageflip_event_list)) - INIT_LIST_HEAD(&dev_priv->pageflip_event_list); +} + +static void exynos_drm_postclose(struct drm_device *dev, struct drm_file *file) +{ + DRM_DEBUG_DRIVER("%s\n", __FILE__); + + if (!file->driver_priv) + return; + + kfree(file->driver_priv); + file->driver_priv = NULL; } static void exynos_drm_lastclose(struct drm_device *dev) @@ -195,6 +204,7 @@ static struct drm_driver exynos_drm_driver = { .unload = exynos_drm_unload, .preclose = exynos_drm_preclose, .lastclose = exynos_drm_lastclose, + .postclose = exynos_drm_postclose, .get_vblank_counter = drm_vblank_count, .enable_vblank = exynos_drm_crtc_enable_vblank, .disable_vblank = exynos_drm_crtc_disable_vblank, diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.h b/drivers/gpu/drm/exynos/exynos_drm_drv.h index e685e1e3305..13540de90bf 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_drv.h +++ b/drivers/gpu/drm/exynos/exynos_drm_drv.h @@ -136,7 +136,7 @@ struct exynos_drm_overlay { * @type: one of EXYNOS_DISPLAY_TYPE_LCD and HDMI. * @is_connected: check for that display is connected or not. * @get_edid: get edid modes from display driver. - * @get_timing: get timing object from display driver. + * @get_panel: get panel object from display driver. * @check_timing: check if timing is valid or not. * @power_on: display device on or off. */ @@ -145,7 +145,7 @@ struct exynos_drm_display_ops { bool (*is_connected)(struct device *dev); int (*get_edid)(struct device *dev, struct drm_connector *connector, u8 *edid, int len); - void *(*get_timing)(struct device *dev); + void *(*get_panel)(struct device *dev); int (*check_timing)(struct device *dev, void *timing); int (*power_on)(struct device *dev, int mode); }; diff --git a/drivers/gpu/drm/exynos/exynos_drm_encoder.c b/drivers/gpu/drm/exynos/exynos_drm_encoder.c index 86b93dde219..ef4754f1519 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_encoder.c +++ b/drivers/gpu/drm/exynos/exynos_drm_encoder.c @@ -195,6 +195,40 @@ static struct drm_encoder_funcs exynos_encoder_funcs = { .destroy = exynos_drm_encoder_destroy, }; +static unsigned int exynos_drm_encoder_clones(struct drm_encoder *encoder) +{ + struct drm_encoder *clone; + struct drm_device *dev = encoder->dev; + struct exynos_drm_encoder *exynos_encoder = to_exynos_encoder(encoder); + struct exynos_drm_display_ops *display_ops = + exynos_encoder->manager->display_ops; + unsigned int clone_mask = 0; + int cnt = 0; + + list_for_each_entry(clone, &dev->mode_config.encoder_list, head) { + switch (display_ops->type) { + case EXYNOS_DISPLAY_TYPE_LCD: + case EXYNOS_DISPLAY_TYPE_HDMI: + clone_mask |= (1 << (cnt++)); + break; + default: + continue; + } + } + + return clone_mask; +} + +void exynos_drm_encoder_setup(struct drm_device *dev) +{ + struct drm_encoder *encoder; + + DRM_DEBUG_KMS("%s\n", __FILE__); + + list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) + encoder->possible_clones = exynos_drm_encoder_clones(encoder); +} + struct drm_encoder * exynos_drm_encoder_create(struct drm_device *dev, struct exynos_drm_manager *manager, diff --git a/drivers/gpu/drm/exynos/exynos_drm_encoder.h b/drivers/gpu/drm/exynos/exynos_drm_encoder.h index 97b087a51cb..eb7d2316847 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_encoder.h +++ b/drivers/gpu/drm/exynos/exynos_drm_encoder.h @@ -30,6 +30,7 @@ struct exynos_drm_manager; +void exynos_drm_encoder_setup(struct drm_device *dev); struct drm_encoder *exynos_drm_encoder_create(struct drm_device *dev, struct exynos_drm_manager *mgr, unsigned int possible_crtcs); diff --git a/drivers/gpu/drm/exynos/exynos_drm_fbdev.c b/drivers/gpu/drm/exynos/exynos_drm_fbdev.c index 5737bc5e6ed..54f8f074822 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_fbdev.c +++ b/drivers/gpu/drm/exynos/exynos_drm_fbdev.c @@ -169,66 +169,6 @@ out: return ret; } -static bool -exynos_drm_fbdev_is_samefb(struct drm_framebuffer *fb, - struct drm_fb_helper_surface_size *sizes) -{ - if (fb->width != sizes->surface_width) - return false; - if (fb->height != sizes->surface_height) - return false; - if (fb->bits_per_pixel != sizes->surface_bpp) - return false; - if (fb->depth != sizes->surface_depth) - return false; - - return true; -} - -static int exynos_drm_fbdev_recreate(struct drm_fb_helper *helper, - struct drm_fb_helper_surface_size *sizes) -{ - struct drm_device *dev = helper->dev; - struct exynos_drm_fbdev *exynos_fbdev = to_exynos_fbdev(helper); - struct exynos_drm_gem_obj *exynos_gem_obj; - struct drm_framebuffer *fb = helper->fb; - struct drm_mode_fb_cmd2 mode_cmd = { 0 }; - unsigned long size; - - DRM_DEBUG_KMS("%s\n", __FILE__); - - if (exynos_drm_fbdev_is_samefb(fb, sizes)) - return 0; - - mode_cmd.width = sizes->surface_width; - mode_cmd.height = sizes->surface_height; - mode_cmd.pitches[0] = sizes->surface_width * (sizes->surface_bpp >> 3); - mode_cmd.pixel_format = drm_mode_legacy_fb_format(sizes->surface_bpp, - sizes->surface_depth); - - if (exynos_fbdev->exynos_gem_obj) - exynos_drm_gem_destroy(exynos_fbdev->exynos_gem_obj); - - if (fb->funcs->destroy) - fb->funcs->destroy(fb); - - size = mode_cmd.pitches[0] * mode_cmd.height; - exynos_gem_obj = exynos_drm_gem_create(dev, size); - if (IS_ERR(exynos_gem_obj)) - return PTR_ERR(exynos_gem_obj); - - exynos_fbdev->exynos_gem_obj = exynos_gem_obj; - - helper->fb = exynos_drm_framebuffer_init(dev, &mode_cmd, - &exynos_gem_obj->base); - if (IS_ERR_OR_NULL(helper->fb)) { - DRM_ERROR("failed to create drm framebuffer.\n"); - return PTR_ERR(helper->fb); - } - - return exynos_drm_fbdev_update(helper, helper->fb); -} - static int exynos_drm_fbdev_probe(struct drm_fb_helper *helper, struct drm_fb_helper_surface_size *sizes) { @@ -236,6 +176,10 @@ static int exynos_drm_fbdev_probe(struct drm_fb_helper *helper, DRM_DEBUG_KMS("%s\n", __FILE__); + /* + * with !helper->fb, it means that this funcion is called first time + * and after that, the helper->fb would be used as clone mode. + */ if (!helper->fb) { ret = exynos_drm_fbdev_create(helper, sizes); if (ret < 0) { @@ -248,12 +192,6 @@ static int exynos_drm_fbdev_probe(struct drm_fb_helper *helper, * because register_framebuffer() should be called. */ ret = 1; - } else { - ret = exynos_drm_fbdev_recreate(helper, sizes); - if (ret < 0) { - DRM_ERROR("failed to reconfigure fbdev\n"); - return ret; - } } return ret; diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimd.c b/drivers/gpu/drm/exynos/exynos_drm_fimd.c index b6a737d196a..360adf2bba0 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_fimd.c +++ b/drivers/gpu/drm/exynos/exynos_drm_fimd.c @@ -89,7 +89,7 @@ struct fimd_context { bool suspended; struct mutex lock; - struct fb_videomode *timing; + struct exynos_drm_panel_info *panel; }; static bool fimd_display_is_connected(struct device *dev) @@ -101,13 +101,13 @@ static bool fimd_display_is_connected(struct device *dev) return true; } -static void *fimd_get_timing(struct device *dev) +static void *fimd_get_panel(struct device *dev) { struct fimd_context *ctx = get_fimd_context(dev); DRM_DEBUG_KMS("%s\n", __FILE__); - return ctx->timing; + return ctx->panel; } static int fimd_check_timing(struct device *dev, void *timing) @@ -131,7 +131,7 @@ static int fimd_display_power_on(struct device *dev, int mode) static struct exynos_drm_display_ops fimd_display_ops = { .type = EXYNOS_DISPLAY_TYPE_LCD, .is_connected = fimd_display_is_connected, - .get_timing = fimd_get_timing, + .get_panel = fimd_get_panel, .check_timing = fimd_check_timing, .power_on = fimd_display_power_on, }; @@ -193,7 +193,8 @@ static void fimd_apply(struct device *subdrv_dev) static void fimd_commit(struct device *dev) { struct fimd_context *ctx = get_fimd_context(dev); - struct fb_videomode *timing = ctx->timing; + struct exynos_drm_panel_info *panel = ctx->panel; + struct fb_videomode *timing = &panel->timing; u32 val; if (ctx->suspended) @@ -604,7 +605,12 @@ static void fimd_finish_pageflip(struct drm_device *drm_dev, int crtc) } if (is_checked) { - drm_vblank_put(drm_dev, crtc); + /* + * call drm_vblank_put only in case that drm_vblank_get was + * called. + */ + if (atomic_read(&drm_dev->vblank_refcount[crtc]) > 0) + drm_vblank_put(drm_dev, crtc); /* * don't off vblank if vblank_disable_allowed is 1, @@ -781,7 +787,7 @@ static int __devinit fimd_probe(struct platform_device *pdev) struct fimd_context *ctx; struct exynos_drm_subdrv *subdrv; struct exynos_drm_fimd_pdata *pdata; - struct fb_videomode *timing; + struct exynos_drm_panel_info *panel; struct resource *res; int win; int ret = -EINVAL; @@ -794,9 +800,9 @@ static int __devinit fimd_probe(struct platform_device *pdev) return -EINVAL; } - timing = &pdata->timing; - if (!timing) { - dev_err(dev, "timing is null.\n"); + panel = &pdata->panel; + if (!panel) { + dev_err(dev, "panel is null.\n"); return -EINVAL; } @@ -858,16 +864,16 @@ static int __devinit fimd_probe(struct platform_device *pdev) goto err_req_irq; } - ctx->clkdiv = fimd_calc_clkdiv(ctx, timing); + ctx->clkdiv = fimd_calc_clkdiv(ctx, &panel->timing); ctx->vidcon0 = pdata->vidcon0; ctx->vidcon1 = pdata->vidcon1; ctx->default_win = pdata->default_win; - ctx->timing = timing; + ctx->panel = panel; - timing->pixclock = clk_get_rate(ctx->lcd_clk) / ctx->clkdiv; + panel->timing.pixclock = clk_get_rate(ctx->lcd_clk) / ctx->clkdiv; DRM_DEBUG_KMS("pixel clock = %d, clkdiv = %d\n", - timing->pixclock, ctx->clkdiv); + panel->timing.pixclock, ctx->clkdiv); subdrv = &ctx->subdrv; diff --git a/drivers/gpu/drm/exynos/exynos_mixer.c b/drivers/gpu/drm/exynos/exynos_mixer.c index ac24cff3977..93846e810e3 100644 --- a/drivers/gpu/drm/exynos/exynos_mixer.c +++ b/drivers/gpu/drm/exynos/exynos_mixer.c @@ -712,7 +712,12 @@ static void mixer_finish_pageflip(struct drm_device *drm_dev, int crtc) } if (is_checked) - drm_vblank_put(drm_dev, crtc); + /* + * call drm_vblank_put only in case that drm_vblank_get was + * called. + */ + if (atomic_read(&drm_dev->vblank_refcount[crtc]) > 0) + drm_vblank_put(drm_dev, crtc); spin_unlock_irqrestore(&drm_dev->event_lock, flags); } @@ -779,15 +784,15 @@ static void mixer_win_reset(struct mixer_context *ctx) mixer_reg_writemask(res, MXR_STATUS, MXR_STATUS_16_BURST, MXR_STATUS_BURST_MASK); - /* setting default layer priority: layer1 > video > layer0 + /* setting default layer priority: layer1 > layer0 > video * because typical usage scenario would be + * layer1 - OSD * layer0 - framebuffer * video - video overlay - * layer1 - OSD */ - val = MXR_LAYER_CFG_GRP0_VAL(1); - val |= MXR_LAYER_CFG_VP_VAL(2); - val |= MXR_LAYER_CFG_GRP1_VAL(3); + val = MXR_LAYER_CFG_GRP1_VAL(3); + val |= MXR_LAYER_CFG_GRP0_VAL(2); + val |= MXR_LAYER_CFG_VP_VAL(1); mixer_reg_write(res, MXR_LAYER_CFG, val); /* setting background color */ @@ -1044,7 +1049,7 @@ static int mixer_remove(struct platform_device *pdev) platform_get_drvdata(pdev); struct mixer_context *ctx = (struct mixer_context *)drm_hdmi_ctx->ctx; - dev_info(dev, "remove sucessful\n"); + dev_info(dev, "remove successful\n"); mixer_resource_poweroff(ctx); mixer_resources_cleanup(ctx); diff --git a/drivers/gpu/drm/gma500/cdv_device.c b/drivers/gpu/drm/gma500/cdv_device.c index eefcef6fa32..a54cc738926 100644 --- a/drivers/gpu/drm/gma500/cdv_device.c +++ b/drivers/gpu/drm/gma500/cdv_device.c @@ -452,6 +452,8 @@ static int cdv_chip_setup(struct drm_device *dev) cdv_get_core_freq(dev); gma_intel_opregion_init(dev); psb_intel_init_bios(dev); + REG_WRITE(PORT_HOTPLUG_EN, 0); + REG_WRITE(PORT_HOTPLUG_STAT, REG_READ(PORT_HOTPLUG_STAT)); return 0; } diff --git a/drivers/gpu/drm/gma500/framebuffer.c b/drivers/gpu/drm/gma500/framebuffer.c index 98006308bab..153f9cf2446 100644 --- a/drivers/gpu/drm/gma500/framebuffer.c +++ b/drivers/gpu/drm/gma500/framebuffer.c @@ -214,7 +214,6 @@ static struct fb_ops psbfb_roll_ops = { .fb_imageblit = cfb_imageblit, .fb_pan_display = psbfb_pan, .fb_mmap = psbfb_mmap, - .fb_sync = psbfb_sync, .fb_ioctl = psbfb_ioctl, }; diff --git a/drivers/gpu/drm/gma500/gtt.c b/drivers/gpu/drm/gma500/gtt.c index 574bc9794a0..c6465b40090 100644 --- a/drivers/gpu/drm/gma500/gtt.c +++ b/drivers/gpu/drm/gma500/gtt.c @@ -446,10 +446,9 @@ int psb_gtt_init(struct drm_device *dev, int resume) pg->gtt_start = pci_resource_start(dev->pdev, PSB_GTT_RESOURCE); gtt_pages = pci_resource_len(dev->pdev, PSB_GTT_RESOURCE) >> PAGE_SHIFT; - /* Some CDV firmware doesn't report this currently. In which case the - system has 64 gtt pages */ + /* CDV doesn't report this. 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"); + dev_dbg(dev->dev, "GTT PCI BAR not initialized.\n"); gtt_pages = 64; pg->gtt_start = dev_priv->pge_ctl; } @@ -461,10 +460,10 @@ 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. + /* 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_err(dev->dev, "GATT PCI BAR not initialized.\n"); + 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 diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 52a06be1d98..f59cd3a1f4c 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -3111,6 +3111,20 @@ #define DISP_TILE_SURFACE_SWIZZLING (1<<13) #define DISP_FBC_WM_DIS (1<<15) +/* GEN7 chicken */ +#define GEN7_COMMON_SLICE_CHICKEN1 0x7010 +# define GEN7_CSC1_RHWO_OPT_DISABLE_IN_RCC ((1<<10) | (1<<26)) + +#define GEN7_L3CNTLREG1 0xB01C +#define GEN7_WA_FOR_GEN7_L3_CONTROL 0x3C4FFF8C + +#define GEN7_L3_CHICKEN_MODE_REGISTER 0xB030 +#define GEN7_WA_L3_CHICKEN_MODE 0x20000000 + +/* WaCatErrorRejectionIssue */ +#define GEN7_SQ_CHICKEN_MBCUNIT_CONFIG 0x9030 +#define GEN7_SQ_CHICKEN_MBCUNIT_SQINTMOB (1<<11) + /* PCH */ /* south display engine interrupt */ @@ -3714,6 +3728,7 @@ #define GT_FIFO_NUM_RESERVED_ENTRIES 20 #define GEN6_UCGCTL2 0x9404 +# define GEN6_RCZUNIT_CLOCK_GATE_DISABLE (1 << 13) # define GEN6_RCPBUNIT_CLOCK_GATE_DISABLE (1 << 12) # define GEN6_RCCUNIT_CLOCK_GATE_DISABLE (1 << 11) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index b65dc04f128..0da4753e9a2 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -4737,8 +4737,17 @@ sandybridge_compute_sprite_srwm(struct drm_device *dev, int plane, crtc = intel_get_crtc_for_plane(dev, plane); clock = crtc->mode.clock; + if (!clock) { + *sprite_wm = 0; + return false; + } line_time_us = (sprite_width * 1000) / clock; + if (!line_time_us) { + *sprite_wm = 0; + return false; + } + line_count = (latency_ns / line_time_us + 1000) / 1000; line_size = sprite_width * pixel_size; @@ -6268,7 +6277,7 @@ void intel_crtc_load_lut(struct drm_crtc *crtc) int i; /* The clocks have to be on to load the palette. */ - if (!crtc->enabled) + if (!crtc->enabled || !intel_crtc->active) return; /* use legacy palette for Ironlake */ @@ -6654,7 +6663,7 @@ intel_framebuffer_create_for_mode(struct drm_device *dev, mode_cmd.height = mode->vdisplay; mode_cmd.pitches[0] = intel_framebuffer_pitch_for_width(mode_cmd.width, bpp); - mode_cmd.pixel_format = 0; + mode_cmd.pixel_format = drm_mode_legacy_fb_format(bpp, depth); return intel_framebuffer_create(dev, &mode_cmd, obj); } @@ -8275,8 +8284,8 @@ void gen6_enable_rps(struct drm_i915_private *dev_priv) I915_WRITE(GEN6_RC6pp_THRESHOLD, 64000); /* unused */ if (intel_enable_rc6(dev_priv->dev)) - rc6_mask = GEN6_RC_CTL_RC6p_ENABLE | - GEN6_RC_CTL_RC6_ENABLE; + rc6_mask = GEN6_RC_CTL_RC6_ENABLE | + ((IS_GEN7(dev_priv->dev)) ? GEN6_RC_CTL_RC6p_ENABLE : 0); I915_WRITE(GEN6_RC_CONTROL, rc6_mask | @@ -8554,12 +8563,32 @@ static void ivybridge_init_clock_gating(struct drm_device *dev) I915_WRITE(WM2_LP_ILK, 0); I915_WRITE(WM1_LP_ILK, 0); + /* According to the spec, bit 13 (RCZUNIT) must be set on IVB. + * This implements the WaDisableRCZUnitClockGating workaround. + */ + I915_WRITE(GEN6_UCGCTL2, GEN6_RCZUNIT_CLOCK_GATE_DISABLE); + I915_WRITE(ILK_DSPCLK_GATE, IVB_VRHUNIT_CLK_GATE); I915_WRITE(IVB_CHICKEN3, CHICKEN3_DGMG_REQ_OUT_FIX_DISABLE | CHICKEN3_DGMG_DONE_FIX_DISABLE); + /* Apply the WaDisableRHWOOptimizationForRenderHang workaround. */ + I915_WRITE(GEN7_COMMON_SLICE_CHICKEN1, + GEN7_CSC1_RHWO_OPT_DISABLE_IN_RCC); + + /* WaApplyL3ControlAndL3ChickenMode requires those two on Ivy Bridge */ + I915_WRITE(GEN7_L3CNTLREG1, + GEN7_WA_FOR_GEN7_L3_CONTROL); + I915_WRITE(GEN7_L3_CHICKEN_MODE_REGISTER, + GEN7_WA_L3_CHICKEN_MODE); + + /* This is required by WaCatErrorRejectionIssue */ + I915_WRITE(GEN7_SQ_CHICKEN_MBCUNIT_CONFIG, + I915_READ(GEN7_SQ_CHICKEN_MBCUNIT_CONFIG) | + GEN7_SQ_CHICKEN_MBCUNIT_SQINTMOB); + for_each_pipe(pipe) { I915_WRITE(DSPCNTR(pipe), I915_READ(DSPCNTR(pipe)) | diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index ca3972f2c6f..fc66af6a944 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -287,7 +287,7 @@ static int init_ring_common(struct intel_ring_buffer *ring) I915_WRITE_CTL(ring, ((ring->size - PAGE_SIZE) & RING_NR_PAGES) - | RING_REPORT_64K | RING_VALID); + | RING_VALID); /* If the head is still not zero, the ring is dead */ if ((I915_READ_CTL(ring) & RING_VALID) == 0 || @@ -1191,18 +1191,6 @@ int intel_wait_ring_buffer(struct intel_ring_buffer *ring, int n) struct drm_i915_private *dev_priv = dev->dev_private; unsigned long end; int ret; - u32 head; - - /* If the reported head position has wrapped or hasn't advanced, - * fallback to the slow and accurate path. - */ - head = intel_read_status_page(ring, 4); - if (head > ring->head) { - ring->head = head; - ring->space = ring_space(ring); - if (ring->space >= n) - return 0; - } ret = intel_ring_wait_request(ring, n); if (ret != -ENOSPC) diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c index 450b01d915e..466db4115cd 100644 --- a/drivers/gpu/drm/radeon/evergreen.c +++ b/drivers/gpu/drm/radeon/evergreen.c @@ -3273,6 +3273,7 @@ int evergreen_resume(struct radeon_device *rdev) r = evergreen_startup(rdev); if (r) { DRM_ERROR("evergreen startup failed on resume\n"); + rdev->accel_working = false; return r; } diff --git a/drivers/gpu/drm/radeon/ni.c b/drivers/gpu/drm/radeon/ni.c index 8ce7f9973a5..160799c14b9 100644 --- a/drivers/gpu/drm/radeon/ni.c +++ b/drivers/gpu/drm/radeon/ni.c @@ -1547,6 +1547,7 @@ int cayman_resume(struct radeon_device *rdev) r = cayman_startup(rdev); if (r) { DRM_ERROR("cayman startup failed on resume\n"); + rdev->accel_working = false; return r; } return r; diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c index cee3c8a28db..81801c176aa 100644 --- a/drivers/gpu/drm/radeon/r100.c +++ b/drivers/gpu/drm/radeon/r100.c @@ -827,9 +827,7 @@ int r100_irq_process(struct radeon_device *rdev) WREG32(RADEON_AIC_CNTL, msi_rearm | RS400_MSI_REARM); break; default: - msi_rearm = RREG32(RADEON_MSI_REARM_EN) & ~RV370_MSI_REARM_EN; - WREG32(RADEON_MSI_REARM_EN, msi_rearm); - WREG32(RADEON_MSI_REARM_EN, msi_rearm | RV370_MSI_REARM_EN); + WREG32(RADEON_MSI_REARM_EN, RV370_MSI_REARM_EN); break; } } @@ -3979,6 +3977,8 @@ static int r100_startup(struct radeon_device *rdev) int r100_resume(struct radeon_device *rdev) { + int r; + /* Make sur GART are not working */ if (rdev->flags & RADEON_IS_PCI) r100_pci_gart_disable(rdev); @@ -3998,7 +3998,11 @@ int r100_resume(struct radeon_device *rdev) radeon_surface_init(rdev); rdev->accel_working = true; - return r100_startup(rdev); + r = r100_startup(rdev); + if (r) { + rdev->accel_working = false; + } + return r; } int r100_suspend(struct radeon_device *rdev) diff --git a/drivers/gpu/drm/radeon/r300.c b/drivers/gpu/drm/radeon/r300.c index 9b36e581b18..fa14383f9ca 100644 --- a/drivers/gpu/drm/radeon/r300.c +++ b/drivers/gpu/drm/radeon/r300.c @@ -1430,6 +1430,8 @@ static int r300_startup(struct radeon_device *rdev) int r300_resume(struct radeon_device *rdev) { + int r; + /* Make sur GART are not working */ if (rdev->flags & RADEON_IS_PCIE) rv370_pcie_gart_disable(rdev); @@ -1451,7 +1453,11 @@ int r300_resume(struct radeon_device *rdev) radeon_surface_init(rdev); rdev->accel_working = true; - return r300_startup(rdev); + r = r300_startup(rdev); + if (r) { + rdev->accel_working = false; + } + return r; } int r300_suspend(struct radeon_device *rdev) diff --git a/drivers/gpu/drm/radeon/r420.c b/drivers/gpu/drm/radeon/r420.c index d0f2c0363c2..f3fcaacfea0 100644 --- a/drivers/gpu/drm/radeon/r420.c +++ b/drivers/gpu/drm/radeon/r420.c @@ -291,6 +291,8 @@ static int r420_startup(struct radeon_device *rdev) int r420_resume(struct radeon_device *rdev) { + int r; + /* Make sur GART are not working */ if (rdev->flags & RADEON_IS_PCIE) rv370_pcie_gart_disable(rdev); @@ -316,7 +318,11 @@ int r420_resume(struct radeon_device *rdev) radeon_surface_init(rdev); rdev->accel_working = true; - return r420_startup(rdev); + r = r420_startup(rdev); + if (r) { + rdev->accel_working = false; + } + return r; } int r420_suspend(struct radeon_device *rdev) diff --git a/drivers/gpu/drm/radeon/r520.c b/drivers/gpu/drm/radeon/r520.c index 422923ce70b..ebcc15b03c9 100644 --- a/drivers/gpu/drm/radeon/r520.c +++ b/drivers/gpu/drm/radeon/r520.c @@ -218,6 +218,8 @@ static int r520_startup(struct radeon_device *rdev) int r520_resume(struct radeon_device *rdev) { + int r; + /* Make sur GART are not working */ if (rdev->flags & RADEON_IS_PCIE) rv370_pcie_gart_disable(rdev); @@ -237,7 +239,11 @@ int r520_resume(struct radeon_device *rdev) radeon_surface_init(rdev); rdev->accel_working = true; - return r520_startup(rdev); + r = r520_startup(rdev); + if (r) { + rdev->accel_working = false; + } + return r; } int r520_init(struct radeon_device *rdev) diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c index 8a6d68c028d..5eb23829353 100644 --- a/drivers/gpu/drm/radeon/r600.c +++ b/drivers/gpu/drm/radeon/r600.c @@ -2362,6 +2362,9 @@ void r600_semaphore_ring_emit(struct radeon_device *rdev, uint64_t addr = semaphore->gpu_addr; unsigned sel = emit_wait ? PACKET3_SEM_SEL_WAIT : PACKET3_SEM_SEL_SIGNAL; + if (rdev->family < CHIP_CAYMAN) + sel |= PACKET3_SEM_WAIT_ON_SIGNAL; + radeon_ring_write(ring, PACKET3(PACKET3_MEM_SEMAPHORE, 1)); radeon_ring_write(ring, addr & 0xffffffff); radeon_ring_write(ring, (upper_32_bits(addr) & 0xff) | sel); @@ -2529,6 +2532,7 @@ int r600_resume(struct radeon_device *rdev) r = r600_startup(rdev); if (r) { DRM_ERROR("r600 startup failed on resume\n"); + rdev->accel_working = false; return r; } diff --git a/drivers/gpu/drm/radeon/r600_blit_shaders.c b/drivers/gpu/drm/radeon/r600_blit_shaders.c index 2d1f6c5ee2a..73e2c7c6edb 100644 --- a/drivers/gpu/drm/radeon/r600_blit_shaders.c +++ b/drivers/gpu/drm/radeon/r600_blit_shaders.c @@ -314,6 +314,10 @@ const u32 r6xx_default_state[] = 0x00000000, /* VGT_VTX_CNT_EN */ 0xc0016900, + 0x000000d4, + 0x00000000, /* SX_MISC */ + + 0xc0016900, 0x000002c8, 0x00000000, /* VGT_STRMOUT_BUFFER_EN */ @@ -626,6 +630,10 @@ const u32 r7xx_default_state[] = 0x00000000, /* VGT_VTX_CNT_EN */ 0xc0016900, + 0x000000d4, + 0x00000000, /* SX_MISC */ + + 0xc0016900, 0x000002c8, 0x00000000, /* VGT_STRMOUT_BUFFER_EN */ diff --git a/drivers/gpu/drm/radeon/r600_cs.c b/drivers/gpu/drm/radeon/r600_cs.c index 5cbe948ef16..2e465a7089b 100644 --- a/drivers/gpu/drm/radeon/r600_cs.c +++ b/drivers/gpu/drm/radeon/r600_cs.c @@ -1392,6 +1392,7 @@ static int r600_check_texture_resource(struct radeon_cs_parser *p, u32 idx, h0 = G_038004_TEX_HEIGHT(word1) + 1; d0 = G_038004_TEX_DEPTH(word1); nfaces = 1; + array = 0; switch (G_038000_DIM(word0)) { case V_038000_SQ_TEX_DIM_1D: case V_038000_SQ_TEX_DIM_2D: diff --git a/drivers/gpu/drm/radeon/r600d.h b/drivers/gpu/drm/radeon/r600d.h index 2ba460b5b62..8ae328ff5fd 100644 --- a/drivers/gpu/drm/radeon/r600d.h +++ b/drivers/gpu/drm/radeon/r600d.h @@ -850,6 +850,7 @@ #define PACKET3_STRMOUT_BUFFER_UPDATE 0x34 #define PACKET3_INDIRECT_BUFFER_MP 0x38 #define PACKET3_MEM_SEMAPHORE 0x39 +# define PACKET3_SEM_WAIT_ON_SIGNAL (0x1 << 12) # define PACKET3_SEM_SEL_SIGNAL (0x6 << 29) # define PACKET3_SEM_SEL_WAIT (0x7 << 29) #define PACKET3_MPEG_INDEX 0x3A diff --git a/drivers/gpu/drm/radeon/radeon_atombios.c b/drivers/gpu/drm/radeon/radeon_atombios.c index 5082d17d14d..1f53ae74ada 100644 --- a/drivers/gpu/drm/radeon/radeon_atombios.c +++ b/drivers/gpu/drm/radeon/radeon_atombios.c @@ -2931,6 +2931,20 @@ radeon_atombios_connected_scratch_regs(struct drm_connector *connector, bios_6_scratch &= ~ATOM_S6_ACC_REQ_DFP5; } } + if ((radeon_encoder->devices & ATOM_DEVICE_DFP6_SUPPORT) && + (radeon_connector->devices & ATOM_DEVICE_DFP6_SUPPORT)) { + if (connected) { + DRM_DEBUG_KMS("DFP6 connected\n"); + bios_0_scratch |= ATOM_S0_DFP6; + bios_3_scratch |= ATOM_S3_DFP6_ACTIVE; + bios_6_scratch |= ATOM_S6_ACC_REQ_DFP6; + } else { + DRM_DEBUG_KMS("DFP6 disconnected\n"); + bios_0_scratch &= ~ATOM_S0_DFP6; + bios_3_scratch &= ~ATOM_S3_DFP6_ACTIVE; + bios_6_scratch &= ~ATOM_S6_ACC_REQ_DFP6; + } + } if (rdev->family >= CHIP_R600) { WREG32(R600_BIOS_0_SCRATCH, bios_0_scratch); @@ -2951,6 +2965,9 @@ radeon_atombios_encoder_crtc_scratch_regs(struct drm_encoder *encoder, int crtc) struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); uint32_t bios_3_scratch; + if (ASIC_IS_DCE4(rdev)) + return; + if (rdev->family >= CHIP_R600) bios_3_scratch = RREG32(R600_BIOS_3_SCRATCH); else @@ -3003,6 +3020,9 @@ radeon_atombios_encoder_dpms_scratch_regs(struct drm_encoder *encoder, bool on) struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); uint32_t bios_2_scratch; + if (ASIC_IS_DCE4(rdev)) + return; + if (rdev->family >= CHIP_R600) bios_2_scratch = RREG32(R600_BIOS_2_SCRATCH); else diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c b/drivers/gpu/drm/radeon/radeon_connectors.c index e7cb3ab0924..8c9a8115b63 100644 --- a/drivers/gpu/drm/radeon/radeon_connectors.c +++ b/drivers/gpu/drm/radeon/radeon_connectors.c @@ -1057,7 +1057,7 @@ static int radeon_dvi_mode_valid(struct drm_connector *connector, (radeon_connector->connector_object_id == CONNECTOR_OBJECT_ID_HDMI_TYPE_B)) return MODE_OK; else if (radeon_connector->connector_object_id == CONNECTOR_OBJECT_ID_HDMI_TYPE_A) { - if (ASIC_IS_DCE3(rdev)) { + if (0) { /* HDMI 1.3+ supports max clock of 340 Mhz */ if (mode->clock > 340000) return MODE_CLOCK_HIGH; @@ -1117,13 +1117,23 @@ static int radeon_dp_get_modes(struct drm_connector *connector) (connector->connector_type == DRM_MODE_CONNECTOR_LVDS)) { struct drm_display_mode *mode; - if (!radeon_dig_connector->edp_on) - atombios_set_edp_panel_power(connector, - ATOM_TRANSMITTER_ACTION_POWER_ON); - ret = radeon_ddc_get_modes(radeon_connector); - if (!radeon_dig_connector->edp_on) - atombios_set_edp_panel_power(connector, - ATOM_TRANSMITTER_ACTION_POWER_OFF); + if (connector->connector_type == DRM_MODE_CONNECTOR_eDP) { + if (!radeon_dig_connector->edp_on) + atombios_set_edp_panel_power(connector, + ATOM_TRANSMITTER_ACTION_POWER_ON); + ret = radeon_ddc_get_modes(radeon_connector); + if (!radeon_dig_connector->edp_on) + atombios_set_edp_panel_power(connector, + ATOM_TRANSMITTER_ACTION_POWER_OFF); + } else { + /* need to setup ddc on the bridge */ + if (radeon_connector_encoder_get_dp_bridge_encoder_id(connector) != + ENCODER_OBJECT_ID_NONE) { + if (encoder) + radeon_atom_ext_encoder_setup_ddc(encoder); + } + ret = radeon_ddc_get_modes(radeon_connector); + } if (ret > 0) { if (encoder) { @@ -1134,7 +1144,6 @@ static int radeon_dp_get_modes(struct drm_connector *connector) return ret; } - encoder = radeon_best_single_encoder(connector); if (!encoder) return 0; diff --git a/drivers/gpu/drm/radeon/radeon_cs.c b/drivers/gpu/drm/radeon/radeon_cs.c index dc79d08c1f9..9b4124ee17f 100644 --- a/drivers/gpu/drm/radeon/radeon_cs.c +++ b/drivers/gpu/drm/radeon/radeon_cs.c @@ -460,6 +460,10 @@ int radeon_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) int r; radeon_mutex_lock(&rdev->cs_mutex); + if (!rdev->accel_working) { + radeon_mutex_unlock(&rdev->cs_mutex); + return -EBUSY; + } /* initialize parser */ memset(&parser, 0, sizeof(struct radeon_cs_parser)); parser.filp = filp; diff --git a/drivers/gpu/drm/radeon/radeon_display.c b/drivers/gpu/drm/radeon/radeon_display.c index 1f98e5fbc73..b25bb2a5581 100644 --- a/drivers/gpu/drm/radeon/radeon_display.c +++ b/drivers/gpu/drm/radeon/radeon_display.c @@ -1087,15 +1087,21 @@ static const struct drm_framebuffer_funcs radeon_fb_funcs = { .create_handle = radeon_user_framebuffer_create_handle, }; -void +int radeon_framebuffer_init(struct drm_device *dev, struct radeon_framebuffer *rfb, struct drm_mode_fb_cmd2 *mode_cmd, struct drm_gem_object *obj) { + int ret; rfb->obj = obj; - drm_framebuffer_init(dev, &rfb->base, &radeon_fb_funcs); + ret = drm_framebuffer_init(dev, &rfb->base, &radeon_fb_funcs); + if (ret) { + rfb->obj = NULL; + return ret; + } drm_helper_mode_fill_fb_struct(&rfb->base, mode_cmd); + return 0; } static struct drm_framebuffer * @@ -1105,6 +1111,7 @@ radeon_user_framebuffer_create(struct drm_device *dev, { struct drm_gem_object *obj; struct radeon_framebuffer *radeon_fb; + int ret; obj = drm_gem_object_lookup(dev, file_priv, mode_cmd->handles[0]); if (obj == NULL) { @@ -1117,7 +1124,12 @@ radeon_user_framebuffer_create(struct drm_device *dev, if (radeon_fb == NULL) return ERR_PTR(-ENOMEM); - radeon_framebuffer_init(dev, radeon_fb, mode_cmd, obj); + ret = radeon_framebuffer_init(dev, radeon_fb, mode_cmd, obj); + if (ret) { + kfree(radeon_fb); + drm_gem_object_unreference_unlocked(obj); + return NULL; + } return &radeon_fb->base; } diff --git a/drivers/gpu/drm/radeon/radeon_encoders.c b/drivers/gpu/drm/radeon/radeon_encoders.c index 9419c51bcf5..26e92708d11 100644 --- a/drivers/gpu/drm/radeon/radeon_encoders.c +++ b/drivers/gpu/drm/radeon/radeon_encoders.c @@ -307,8 +307,6 @@ void radeon_panel_mode_fixup(struct drm_encoder *encoder, bool radeon_dig_monitor_is_duallink(struct drm_encoder *encoder, u32 pixel_clock) { - struct drm_device *dev = encoder->dev; - struct radeon_device *rdev = dev->dev_private; struct drm_connector *connector; struct radeon_connector *radeon_connector; struct radeon_connector_atom_dig *dig_connector; @@ -326,7 +324,7 @@ bool radeon_dig_monitor_is_duallink(struct drm_encoder *encoder, case DRM_MODE_CONNECTOR_HDMIB: if (radeon_connector->use_digital) { /* HDMI 1.3 supports up to 340 Mhz over single link */ - if (ASIC_IS_DCE3(rdev) && drm_detect_hdmi_monitor(radeon_connector->edid)) { + if (0 && drm_detect_hdmi_monitor(radeon_connector->edid)) { if (pixel_clock > 340000) return true; else @@ -348,7 +346,7 @@ bool radeon_dig_monitor_is_duallink(struct drm_encoder *encoder, return false; else { /* HDMI 1.3 supports up to 340 Mhz over single link */ - if (ASIC_IS_DCE3(rdev) && drm_detect_hdmi_monitor(radeon_connector->edid)) { + if (0 && drm_detect_hdmi_monitor(radeon_connector->edid)) { if (pixel_clock > 340000) return true; else diff --git a/drivers/gpu/drm/radeon/radeon_fb.c b/drivers/gpu/drm/radeon/radeon_fb.c index a5692d5f415..60b97ab1d19 100644 --- a/drivers/gpu/drm/radeon/radeon_fb.c +++ b/drivers/gpu/drm/radeon/radeon_fb.c @@ -209,6 +209,11 @@ static int radeonfb_create(struct radeon_fbdev *rfbdev, sizes->surface_depth); ret = radeonfb_create_pinned_object(rfbdev, &mode_cmd, &gobj); + if (ret) { + DRM_ERROR("failed to create fbcon object %d\n", ret); + return ret; + } + rbo = gem_to_radeon_bo(gobj); /* okay we have an object now allocate the framebuffer */ @@ -220,7 +225,11 @@ static int radeonfb_create(struct radeon_fbdev *rfbdev, info->par = rfbdev; - radeon_framebuffer_init(rdev->ddev, &rfbdev->rfb, &mode_cmd, gobj); + ret = radeon_framebuffer_init(rdev->ddev, &rfbdev->rfb, &mode_cmd, gobj); + if (ret) { + DRM_ERROR("failed to initalise framebuffer %d\n", ret); + goto out_unref; + } fb = &rfbdev->rfb.base; diff --git a/drivers/gpu/drm/radeon/radeon_fence.c b/drivers/gpu/drm/radeon/radeon_fence.c index 64ea3dd9e6f..4bd36a354fb 100644 --- a/drivers/gpu/drm/radeon/radeon_fence.c +++ b/drivers/gpu/drm/radeon/radeon_fence.c @@ -364,8 +364,10 @@ int radeon_fence_count_emitted(struct radeon_device *rdev, int ring) int not_processed = 0; read_lock_irqsave(&rdev->fence_lock, irq_flags); - if (!rdev->fence_drv[ring].initialized) + if (!rdev->fence_drv[ring].initialized) { + read_unlock_irqrestore(&rdev->fence_lock, irq_flags); return 0; + } if (!list_empty(&rdev->fence_drv[ring].emitted)) { struct list_head *ptr; diff --git a/drivers/gpu/drm/radeon/radeon_gart.c b/drivers/gpu/drm/radeon/radeon_gart.c index 010dad8b66a..c58a036233f 100644 --- a/drivers/gpu/drm/radeon/radeon_gart.c +++ b/drivers/gpu/drm/radeon/radeon_gart.c @@ -597,13 +597,13 @@ int radeon_vm_bo_rmv(struct radeon_device *rdev, if (bo_va == NULL) return 0; - list_del(&bo_va->bo_list); mutex_lock(&vm->mutex); radeon_mutex_lock(&rdev->cs_mutex); radeon_vm_bo_update_pte(rdev, vm, bo, NULL); radeon_mutex_unlock(&rdev->cs_mutex); list_del(&bo_va->vm_list); mutex_unlock(&vm->mutex); + list_del(&bo_va->bo_list); kfree(bo_va); return 0; diff --git a/drivers/gpu/drm/radeon/radeon_mode.h b/drivers/gpu/drm/radeon/radeon_mode.h index 4330e325357..8a85598fb24 100644 --- a/drivers/gpu/drm/radeon/radeon_mode.h +++ b/drivers/gpu/drm/radeon/radeon_mode.h @@ -649,7 +649,7 @@ extern void radeon_crtc_fb_gamma_set(struct drm_crtc *crtc, u16 red, u16 green, u16 blue, int regno); extern void radeon_crtc_fb_gamma_get(struct drm_crtc *crtc, u16 *red, u16 *green, u16 *blue, int regno); -void radeon_framebuffer_init(struct drm_device *dev, +int radeon_framebuffer_init(struct drm_device *dev, struct radeon_framebuffer *rfb, struct drm_mode_fb_cmd2 *mode_cmd, struct drm_gem_object *obj); diff --git a/drivers/gpu/drm/radeon/radeon_ring.c b/drivers/gpu/drm/radeon/radeon_ring.c index 32c83d8bad3..30566201dff 100644 --- a/drivers/gpu/drm/radeon/radeon_ring.c +++ b/drivers/gpu/drm/radeon/radeon_ring.c @@ -503,8 +503,11 @@ static unsigned radeon_debugfs_ib_idx[RADEON_IB_POOL_SIZE]; int radeon_debugfs_ring_init(struct radeon_device *rdev) { #if defined(CONFIG_DEBUG_FS) - return radeon_debugfs_add_files(rdev, radeon_debugfs_ring_info_list, - ARRAY_SIZE(radeon_debugfs_ring_info_list)); + if (rdev->family >= CHIP_CAYMAN) + return radeon_debugfs_add_files(rdev, radeon_debugfs_ring_info_list, + ARRAY_SIZE(radeon_debugfs_ring_info_list)); + else + return radeon_debugfs_add_files(rdev, radeon_debugfs_ring_info_list, 1); #else return 0; #endif diff --git a/drivers/gpu/drm/radeon/rs400.c b/drivers/gpu/drm/radeon/rs400.c index 5280c87d595..4cf381b3a6d 100644 --- a/drivers/gpu/drm/radeon/rs400.c +++ b/drivers/gpu/drm/radeon/rs400.c @@ -442,6 +442,8 @@ static int rs400_startup(struct radeon_device *rdev) int rs400_resume(struct radeon_device *rdev) { + int r; + /* Make sur GART are not working */ rs400_gart_disable(rdev); /* Resume clock before doing reset */ @@ -462,7 +464,11 @@ int rs400_resume(struct radeon_device *rdev) radeon_surface_init(rdev); rdev->accel_working = true; - return rs400_startup(rdev); + r = rs400_startup(rdev); + if (r) { + rdev->accel_working = false; + } + return r; } int rs400_suspend(struct radeon_device *rdev) diff --git a/drivers/gpu/drm/radeon/rs600.c b/drivers/gpu/drm/radeon/rs600.c index 8c2a3d4d638..d25cf869d08 100644 --- a/drivers/gpu/drm/radeon/rs600.c +++ b/drivers/gpu/drm/radeon/rs600.c @@ -703,9 +703,7 @@ int rs600_irq_process(struct radeon_device *rdev) WREG32(RADEON_BUS_CNTL, msi_rearm | RS600_MSI_REARM); break; default: - msi_rearm = RREG32(RADEON_MSI_REARM_EN) & ~RV370_MSI_REARM_EN; - WREG32(RADEON_MSI_REARM_EN, msi_rearm); - WREG32(RADEON_MSI_REARM_EN, msi_rearm | RV370_MSI_REARM_EN); + WREG32(RADEON_MSI_REARM_EN, RV370_MSI_REARM_EN); break; } } @@ -897,6 +895,8 @@ static int rs600_startup(struct radeon_device *rdev) int rs600_resume(struct radeon_device *rdev) { + int r; + /* Make sur GART are not working */ rs600_gart_disable(rdev); /* Resume clock before doing reset */ @@ -915,7 +915,11 @@ int rs600_resume(struct radeon_device *rdev) radeon_surface_init(rdev); rdev->accel_working = true; - return rs600_startup(rdev); + r = rs600_startup(rdev); + if (r) { + rdev->accel_working = false; + } + return r; } int rs600_suspend(struct radeon_device *rdev) diff --git a/drivers/gpu/drm/radeon/rs690.c b/drivers/gpu/drm/radeon/rs690.c index 6aa65032d3c..f2c3b9d75f1 100644 --- a/drivers/gpu/drm/radeon/rs690.c +++ b/drivers/gpu/drm/radeon/rs690.c @@ -659,6 +659,8 @@ static int rs690_startup(struct radeon_device *rdev) int rs690_resume(struct radeon_device *rdev) { + int r; + /* Make sur GART are not working */ rs400_gart_disable(rdev); /* Resume clock before doing reset */ @@ -677,7 +679,11 @@ int rs690_resume(struct radeon_device *rdev) radeon_surface_init(rdev); rdev->accel_working = true; - return rs690_startup(rdev); + r = rs690_startup(rdev); + if (r) { + rdev->accel_working = false; + } + return r; } int rs690_suspend(struct radeon_device *rdev) diff --git a/drivers/gpu/drm/radeon/rv515.c b/drivers/gpu/drm/radeon/rv515.c index 9e1b159bbb7..c0549b146ba 100644 --- a/drivers/gpu/drm/radeon/rv515.c +++ b/drivers/gpu/drm/radeon/rv515.c @@ -423,6 +423,8 @@ static int rv515_startup(struct radeon_device *rdev) int rv515_resume(struct radeon_device *rdev) { + int r; + /* Make sur GART are not working */ if (rdev->flags & RADEON_IS_PCIE) rv370_pcie_gart_disable(rdev); @@ -442,7 +444,11 @@ int rv515_resume(struct radeon_device *rdev) radeon_surface_init(rdev); rdev->accel_working = true; - return rv515_startup(rdev); + r = rv515_startup(rdev); + if (r) { + rdev->accel_working = false; + } + return r; } int rv515_suspend(struct radeon_device *rdev) diff --git a/drivers/gpu/drm/radeon/rv770.c b/drivers/gpu/drm/radeon/rv770.c index 6f2cbfb1829..c62ae4be384 100644 --- a/drivers/gpu/drm/radeon/rv770.c +++ b/drivers/gpu/drm/radeon/rv770.c @@ -1139,6 +1139,7 @@ int rv770_resume(struct radeon_device *rdev) r = rv770_startup(rdev); if (r) { DRM_ERROR("r600 startup failed on resume\n"); + rdev->accel_working = false; return r; } |