mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-25 21:24:08 +08:00
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
This commit is contained in:
commit
cfa5555cab
@ -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);
|
||||
|
@ -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);
|
||||
};
|
||||
|
@ -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)
|
||||
@ -786,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;
|
||||
@ -799,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;
|
||||
}
|
||||
|
||||
@ -863,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;
|
||||
|
||||
|
@ -4680,8 +4680,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;
|
||||
|
||||
@ -6175,7 +6184,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 */
|
||||
@ -6561,7 +6570,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);
|
||||
}
|
||||
@ -8185,7 +8194,7 @@ void gen6_enable_rps(struct drm_i915_private *dev_priv)
|
||||
|
||||
if (intel_enable_rc6(dev_priv->dev))
|
||||
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,
|
||||
rc6_mask |
|
||||
|
@ -301,7 +301,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 ||
|
||||
@ -1132,18 +1132,6 @@ int intel_wait_ring_buffer(struct intel_ring_buffer *ring, int n)
|
||||
struct drm_device *dev = ring->dev;
|
||||
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||
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);
|
||||
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,
|
||||
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:
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
@ -2,6 +2,7 @@ header-y += drm.h
|
||||
header-y += drm_fourcc.h
|
||||
header-y += drm_mode.h
|
||||
header-y += drm_sarea.h
|
||||
header-y += exynos_drm.h
|
||||
header-y += i810_drm.h
|
||||
header-y += i915_drm.h
|
||||
header-y += mga_drm.h
|
||||
|
@ -97,15 +97,30 @@ struct drm_exynos_plane_set_zpos {
|
||||
#define DRM_IOCTL_EXYNOS_PLANE_SET_ZPOS DRM_IOWR(DRM_COMMAND_BASE + \
|
||||
DRM_EXYNOS_PLANE_SET_ZPOS, struct drm_exynos_plane_set_zpos)
|
||||
|
||||
#ifdef __KERNEL__
|
||||
|
||||
/**
|
||||
* A structure for lcd panel information.
|
||||
*
|
||||
* @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.
|
||||
*
|
||||
* @timing: default video mode for initializing
|
||||
* @panel: default panel info for initializing
|
||||
* @default_win: default window layer number to be used for UI.
|
||||
* @bpp: default bit per pixel.
|
||||
*/
|
||||
struct exynos_drm_fimd_pdata {
|
||||
struct fb_videomode timing;
|
||||
struct exynos_drm_panel_info panel;
|
||||
u32 vidcon0;
|
||||
u32 vidcon1;
|
||||
unsigned int default_win;
|
||||
@ -139,4 +154,5 @@ struct exynos_drm_hdmi_pdata {
|
||||
unsigned int bpp;
|
||||
};
|
||||
|
||||
#endif
|
||||
#endif /* __KERNEL__ */
|
||||
#endif /* _EXYNOS_DRM_H_ */
|
||||
|
Loading…
Reference in New Issue
Block a user