提交 cfa5555c 编写于 作者: L Linus Torvalds

Merge branch 'drm-fixes' of git://people.freedesktop.org/~airlied/linux

DRM fixes from Dave Airlie:
  intel: fixes for output regression on 965GM, an oops and a machine
  hang

  radeon: uninitialised var (that gcc didn't warn about for some reason)
  + a couple of correctness fixes.

  exynos: fixes for various things, drop some chunks of unused code.

* 'drm-fixes' of git://people.freedesktop.org/~airlied/linux:
  drm/radeon/kms/vm: fix possible bug in radeon_vm_bo_rmv()
  drm/radeon: fix uninitialized variable
  drm/radeon/kms: fix radeon_dp_get_modes for LVDS bridges (v2)
  drm/i915: Remove use of the autoreported ringbuffer HEAD position
  drm/i915: Prevent a machine hang by checking crtc->active before loading lut
  drm/i915: fix operator precedence when enabling RC6p
  drm/i915: fix a sprite watermark computation to avoid divide by zero if xpos<0
  drm/i915: fix mode set on load pipe. (v2)
  drm/exynos: exynos_drm.h header file fixes
  drm/exynos: added panel physical size.
  drm/exynos: added postclose to release resource.
  drm/exynos: removed exynos_drm_fbdev_recreate function.
  drm/exynos: fixed page flip issue.
  drm/exynos: added possible_clones setup function.
  drm/exynos: removed pageflip_event_list init code when closed.
  drm/exynos: changed priority of mixer layers.
  drm/exynos: Fix typo in exynos_mixer.c
...@@ -28,6 +28,7 @@ ...@@ -28,6 +28,7 @@
#include "drmP.h" #include "drmP.h"
#include "drm_crtc_helper.h" #include "drm_crtc_helper.h"
#include <drm/exynos_drm.h>
#include "exynos_drm_drv.h" #include "exynos_drm_drv.h"
#include "exynos_drm_encoder.h" #include "exynos_drm_encoder.h"
...@@ -44,8 +45,9 @@ struct exynos_drm_connector { ...@@ -44,8 +45,9 @@ struct exynos_drm_connector {
/* convert exynos_video_timings to drm_display_mode */ /* convert exynos_video_timings to drm_display_mode */
static inline void static inline void
convert_to_display_mode(struct drm_display_mode *mode, 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__); DRM_DEBUG_KMS("%s\n", __FILE__);
mode->clock = timing->pixclock / 1000; mode->clock = timing->pixclock / 1000;
...@@ -60,6 +62,8 @@ convert_to_display_mode(struct drm_display_mode *mode, ...@@ -60,6 +62,8 @@ convert_to_display_mode(struct drm_display_mode *mode,
mode->vsync_start = mode->vdisplay + timing->upper_margin; mode->vsync_start = mode->vdisplay + timing->upper_margin;
mode->vsync_end = mode->vsync_start + timing->vsync_len; mode->vsync_end = mode->vsync_start + timing->vsync_len;
mode->vtotal = mode->vsync_end + timing->lower_margin; 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) if (timing->vmode & FB_VMODE_INTERLACED)
mode->flags |= DRM_MODE_FLAG_INTERLACE; mode->flags |= DRM_MODE_FLAG_INTERLACE;
...@@ -148,16 +152,18 @@ static int exynos_drm_connector_get_modes(struct drm_connector *connector) ...@@ -148,16 +152,18 @@ static int exynos_drm_connector_get_modes(struct drm_connector *connector)
connector->display_info.raw_edid = edid; connector->display_info.raw_edid = edid;
} else { } else {
struct drm_display_mode *mode = drm_mode_create(connector->dev); 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) if (display_ops->get_panel)
timing = display_ops->get_timing(manager->dev); panel = display_ops->get_panel(manager->dev);
else { else {
drm_mode_destroy(connector->dev, mode); drm_mode_destroy(connector->dev, mode);
return 0; 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; mode->type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED;
drm_mode_set_name(mode); drm_mode_set_name(mode);
......
...@@ -136,7 +136,7 @@ struct exynos_drm_overlay { ...@@ -136,7 +136,7 @@ struct exynos_drm_overlay {
* @type: one of EXYNOS_DISPLAY_TYPE_LCD and HDMI. * @type: one of EXYNOS_DISPLAY_TYPE_LCD and HDMI.
* @is_connected: check for that display is connected or not. * @is_connected: check for that display is connected or not.
* @get_edid: get edid modes from display driver. * @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. * @check_timing: check if timing is valid or not.
* @power_on: display device on or off. * @power_on: display device on or off.
*/ */
...@@ -145,7 +145,7 @@ struct exynos_drm_display_ops { ...@@ -145,7 +145,7 @@ struct exynos_drm_display_ops {
bool (*is_connected)(struct device *dev); bool (*is_connected)(struct device *dev);
int (*get_edid)(struct device *dev, struct drm_connector *connector, int (*get_edid)(struct device *dev, struct drm_connector *connector,
u8 *edid, int len); 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 (*check_timing)(struct device *dev, void *timing);
int (*power_on)(struct device *dev, int mode); int (*power_on)(struct device *dev, int mode);
}; };
......
...@@ -89,7 +89,7 @@ struct fimd_context { ...@@ -89,7 +89,7 @@ struct fimd_context {
bool suspended; bool suspended;
struct mutex lock; struct mutex lock;
struct fb_videomode *timing; struct exynos_drm_panel_info *panel;
}; };
static bool fimd_display_is_connected(struct device *dev) static bool fimd_display_is_connected(struct device *dev)
...@@ -101,13 +101,13 @@ static bool fimd_display_is_connected(struct device *dev) ...@@ -101,13 +101,13 @@ static bool fimd_display_is_connected(struct device *dev)
return true; 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); struct fimd_context *ctx = get_fimd_context(dev);
DRM_DEBUG_KMS("%s\n", __FILE__); DRM_DEBUG_KMS("%s\n", __FILE__);
return ctx->timing; return ctx->panel;
} }
static int fimd_check_timing(struct device *dev, void *timing) 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) ...@@ -131,7 +131,7 @@ static int fimd_display_power_on(struct device *dev, int mode)
static struct exynos_drm_display_ops fimd_display_ops = { static struct exynos_drm_display_ops fimd_display_ops = {
.type = EXYNOS_DISPLAY_TYPE_LCD, .type = EXYNOS_DISPLAY_TYPE_LCD,
.is_connected = fimd_display_is_connected, .is_connected = fimd_display_is_connected,
.get_timing = fimd_get_timing, .get_panel = fimd_get_panel,
.check_timing = fimd_check_timing, .check_timing = fimd_check_timing,
.power_on = fimd_display_power_on, .power_on = fimd_display_power_on,
}; };
...@@ -193,7 +193,8 @@ static void fimd_apply(struct device *subdrv_dev) ...@@ -193,7 +193,8 @@ static void fimd_apply(struct device *subdrv_dev)
static void fimd_commit(struct device *dev) static void fimd_commit(struct device *dev)
{ {
struct fimd_context *ctx = get_fimd_context(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; u32 val;
if (ctx->suspended) if (ctx->suspended)
...@@ -786,7 +787,7 @@ static int __devinit fimd_probe(struct platform_device *pdev) ...@@ -786,7 +787,7 @@ static int __devinit fimd_probe(struct platform_device *pdev)
struct fimd_context *ctx; struct fimd_context *ctx;
struct exynos_drm_subdrv *subdrv; struct exynos_drm_subdrv *subdrv;
struct exynos_drm_fimd_pdata *pdata; struct exynos_drm_fimd_pdata *pdata;
struct fb_videomode *timing; struct exynos_drm_panel_info *panel;
struct resource *res; struct resource *res;
int win; int win;
int ret = -EINVAL; int ret = -EINVAL;
...@@ -799,9 +800,9 @@ static int __devinit fimd_probe(struct platform_device *pdev) ...@@ -799,9 +800,9 @@ static int __devinit fimd_probe(struct platform_device *pdev)
return -EINVAL; return -EINVAL;
} }
timing = &pdata->timing; panel = &pdata->panel;
if (!timing) { if (!panel) {
dev_err(dev, "timing is null.\n"); dev_err(dev, "panel is null.\n");
return -EINVAL; return -EINVAL;
} }
...@@ -863,16 +864,16 @@ static int __devinit fimd_probe(struct platform_device *pdev) ...@@ -863,16 +864,16 @@ static int __devinit fimd_probe(struct platform_device *pdev)
goto err_req_irq; goto err_req_irq;
} }
ctx->clkdiv = fimd_calc_clkdiv(ctx, timing); ctx->clkdiv = fimd_calc_clkdiv(ctx, &panel->timing);
ctx->vidcon0 = pdata->vidcon0; ctx->vidcon0 = pdata->vidcon0;
ctx->vidcon1 = pdata->vidcon1; ctx->vidcon1 = pdata->vidcon1;
ctx->default_win = pdata->default_win; 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", DRM_DEBUG_KMS("pixel clock = %d, clkdiv = %d\n",
timing->pixclock, ctx->clkdiv); panel->timing.pixclock, ctx->clkdiv);
subdrv = &ctx->subdrv; subdrv = &ctx->subdrv;
......
...@@ -4680,8 +4680,17 @@ sandybridge_compute_sprite_srwm(struct drm_device *dev, int plane, ...@@ -4680,8 +4680,17 @@ sandybridge_compute_sprite_srwm(struct drm_device *dev, int plane,
crtc = intel_get_crtc_for_plane(dev, plane); crtc = intel_get_crtc_for_plane(dev, plane);
clock = crtc->mode.clock; clock = crtc->mode.clock;
if (!clock) {
*sprite_wm = 0;
return false;
}
line_time_us = (sprite_width * 1000) / clock; 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_count = (latency_ns / line_time_us + 1000) / 1000;
line_size = sprite_width * pixel_size; line_size = sprite_width * pixel_size;
...@@ -6175,7 +6184,7 @@ void intel_crtc_load_lut(struct drm_crtc *crtc) ...@@ -6175,7 +6184,7 @@ void intel_crtc_load_lut(struct drm_crtc *crtc)
int i; int i;
/* The clocks have to be on to load the palette. */ /* The clocks have to be on to load the palette. */
if (!crtc->enabled) if (!crtc->enabled || !intel_crtc->active)
return; return;
/* use legacy palette for Ironlake */ /* use legacy palette for Ironlake */
...@@ -6561,7 +6570,7 @@ intel_framebuffer_create_for_mode(struct drm_device *dev, ...@@ -6561,7 +6570,7 @@ intel_framebuffer_create_for_mode(struct drm_device *dev,
mode_cmd.height = mode->vdisplay; mode_cmd.height = mode->vdisplay;
mode_cmd.pitches[0] = intel_framebuffer_pitch_for_width(mode_cmd.width, mode_cmd.pitches[0] = intel_framebuffer_pitch_for_width(mode_cmd.width,
bpp); 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); return intel_framebuffer_create(dev, &mode_cmd, obj);
} }
...@@ -8185,7 +8194,7 @@ void gen6_enable_rps(struct drm_i915_private *dev_priv) ...@@ -8185,7 +8194,7 @@ void gen6_enable_rps(struct drm_i915_private *dev_priv)
if (intel_enable_rc6(dev_priv->dev)) if (intel_enable_rc6(dev_priv->dev))
rc6_mask = GEN6_RC_CTL_RC6_ENABLE | rc6_mask = GEN6_RC_CTL_RC6_ENABLE |
(IS_GEN7(dev_priv->dev)) ? GEN6_RC_CTL_RC6p_ENABLE : 0; ((IS_GEN7(dev_priv->dev)) ? GEN6_RC_CTL_RC6p_ENABLE : 0);
I915_WRITE(GEN6_RC_CONTROL, I915_WRITE(GEN6_RC_CONTROL,
rc6_mask | rc6_mask |
......
...@@ -301,7 +301,7 @@ static int init_ring_common(struct intel_ring_buffer *ring) ...@@ -301,7 +301,7 @@ static int init_ring_common(struct intel_ring_buffer *ring)
I915_WRITE_CTL(ring, I915_WRITE_CTL(ring,
((ring->size - PAGE_SIZE) & RING_NR_PAGES) ((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 the head is still not zero, the ring is dead */
if ((I915_READ_CTL(ring) & RING_VALID) == 0 || if ((I915_READ_CTL(ring) & RING_VALID) == 0 ||
...@@ -1132,18 +1132,6 @@ int intel_wait_ring_buffer(struct intel_ring_buffer *ring, int n) ...@@ -1132,18 +1132,6 @@ int intel_wait_ring_buffer(struct intel_ring_buffer *ring, int n)
struct drm_device *dev = ring->dev; struct drm_device *dev = ring->dev;
struct drm_i915_private *dev_priv = dev->dev_private; struct drm_i915_private *dev_priv = dev->dev_private;
unsigned long end; unsigned long end;
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;
}
trace_i915_ring_wait_begin(ring); trace_i915_ring_wait_begin(ring);
if (drm_core_check_feature(dev, DRIVER_GEM)) if (drm_core_check_feature(dev, DRIVER_GEM))
......
...@@ -1304,6 +1304,7 @@ static int r600_check_texture_resource(struct radeon_cs_parser *p, u32 idx, ...@@ -1304,6 +1304,7 @@ static int r600_check_texture_resource(struct radeon_cs_parser *p, u32 idx,
h0 = G_038004_TEX_HEIGHT(word1) + 1; h0 = G_038004_TEX_HEIGHT(word1) + 1;
d0 = G_038004_TEX_DEPTH(word1); d0 = G_038004_TEX_DEPTH(word1);
nfaces = 1; nfaces = 1;
array = 0;
switch (G_038000_DIM(word0)) { switch (G_038000_DIM(word0)) {
case V_038000_SQ_TEX_DIM_1D: case V_038000_SQ_TEX_DIM_1D:
case V_038000_SQ_TEX_DIM_2D: case V_038000_SQ_TEX_DIM_2D:
......
...@@ -1117,13 +1117,23 @@ static int radeon_dp_get_modes(struct drm_connector *connector) ...@@ -1117,13 +1117,23 @@ static int radeon_dp_get_modes(struct drm_connector *connector)
(connector->connector_type == DRM_MODE_CONNECTOR_LVDS)) { (connector->connector_type == DRM_MODE_CONNECTOR_LVDS)) {
struct drm_display_mode *mode; struct drm_display_mode *mode;
if (!radeon_dig_connector->edp_on) if (connector->connector_type == DRM_MODE_CONNECTOR_eDP) {
atombios_set_edp_panel_power(connector, if (!radeon_dig_connector->edp_on)
ATOM_TRANSMITTER_ACTION_POWER_ON); atombios_set_edp_panel_power(connector,
ret = radeon_ddc_get_modes(radeon_connector); ATOM_TRANSMITTER_ACTION_POWER_ON);
if (!radeon_dig_connector->edp_on) ret = radeon_ddc_get_modes(radeon_connector);
atombios_set_edp_panel_power(connector, if (!radeon_dig_connector->edp_on)
ATOM_TRANSMITTER_ACTION_POWER_OFF); 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 (ret > 0) {
if (encoder) { if (encoder) {
...@@ -1134,7 +1144,6 @@ static int radeon_dp_get_modes(struct drm_connector *connector) ...@@ -1134,7 +1144,6 @@ static int radeon_dp_get_modes(struct drm_connector *connector)
return ret; return ret;
} }
encoder = radeon_best_single_encoder(connector);
if (!encoder) if (!encoder)
return 0; return 0;
......
...@@ -597,13 +597,13 @@ int radeon_vm_bo_rmv(struct radeon_device *rdev, ...@@ -597,13 +597,13 @@ int radeon_vm_bo_rmv(struct radeon_device *rdev,
if (bo_va == NULL) if (bo_va == NULL)
return 0; return 0;
list_del(&bo_va->bo_list);
mutex_lock(&vm->mutex); mutex_lock(&vm->mutex);
radeon_mutex_lock(&rdev->cs_mutex); radeon_mutex_lock(&rdev->cs_mutex);
radeon_vm_bo_update_pte(rdev, vm, bo, NULL); radeon_vm_bo_update_pte(rdev, vm, bo, NULL);
radeon_mutex_unlock(&rdev->cs_mutex); radeon_mutex_unlock(&rdev->cs_mutex);
list_del(&bo_va->vm_list); list_del(&bo_va->vm_list);
mutex_unlock(&vm->mutex); mutex_unlock(&vm->mutex);
list_del(&bo_va->bo_list);
kfree(bo_va); kfree(bo_va);
return 0; return 0;
......
...@@ -2,6 +2,7 @@ header-y += drm.h ...@@ -2,6 +2,7 @@ header-y += drm.h
header-y += drm_fourcc.h header-y += drm_fourcc.h
header-y += drm_mode.h header-y += drm_mode.h
header-y += drm_sarea.h header-y += drm_sarea.h
header-y += exynos_drm.h
header-y += i810_drm.h header-y += i810_drm.h
header-y += i915_drm.h header-y += i915_drm.h
header-y += mga_drm.h header-y += mga_drm.h
......
...@@ -97,15 +97,30 @@ struct drm_exynos_plane_set_zpos { ...@@ -97,15 +97,30 @@ struct drm_exynos_plane_set_zpos {
#define DRM_IOCTL_EXYNOS_PLANE_SET_ZPOS DRM_IOWR(DRM_COMMAND_BASE + \ #define DRM_IOCTL_EXYNOS_PLANE_SET_ZPOS DRM_IOWR(DRM_COMMAND_BASE + \
DRM_EXYNOS_PLANE_SET_ZPOS, struct drm_exynos_plane_set_zpos) DRM_EXYNOS_PLANE_SET_ZPOS, struct drm_exynos_plane_set_zpos)
#ifdef __KERNEL__
/** /**
* Platform Specific Structure for DRM based FIMD. * A structure for lcd panel information.
* *
* @timing: default video mode for initializing * @timing: default video mode for initializing
* @width_mm: physical size of lcd width.
* @height_mm: physical size of lcd height.
*/
struct exynos_drm_panel_info {
struct fb_videomode timing;
u32 width_mm;
u32 height_mm;
};
/**
* Platform Specific Structure for DRM based FIMD.
*
* @panel: default panel info for initializing
* @default_win: default window layer number to be used for UI. * @default_win: default window layer number to be used for UI.
* @bpp: default bit per pixel. * @bpp: default bit per pixel.
*/ */
struct exynos_drm_fimd_pdata { struct exynos_drm_fimd_pdata {
struct fb_videomode timing; struct exynos_drm_panel_info panel;
u32 vidcon0; u32 vidcon0;
u32 vidcon1; u32 vidcon1;
unsigned int default_win; unsigned int default_win;
...@@ -139,4 +154,5 @@ struct exynos_drm_hdmi_pdata { ...@@ -139,4 +154,5 @@ struct exynos_drm_hdmi_pdata {
unsigned int bpp; unsigned int bpp;
}; };
#endif #endif /* __KERNEL__ */
#endif /* _EXYNOS_DRM_H_ */
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册