Merge branch 'drm-fixes' of git://people.freedesktop.org/~airlied/linux
Pull drm fixes from Dave Airlie: "Just some GMA500 memory leaks and i915 regression fix due to a regression fix" * 'drm-fixes' of git://people.freedesktop.org/~airlied/linux: drm/i915: prefer VBT modes for SVDO-LVDS over EDID drm/i915: Enable hotplug interrupts after querying hw capabilities. drm/i915: Fix hotplug interrupt enabling for SDVOC drm/gma500/cdv: Fix cursor gem obj referencing on cdv drm/gma500/psb: Fix cursor gem obj referencing on psb drm/gma500/cdv: Unpin framebuffer on crtc disable drm/gma500/psb: Unpin framebuffer on crtc disable drm/gma500: Add fb gtt offset to fb base
This commit is contained in:
@@ -1462,7 +1462,7 @@ static int cdv_intel_crtc_cursor_set(struct drm_crtc *crtc,
|
|||||||
size_t addr = 0;
|
size_t addr = 0;
|
||||||
struct gtt_range *gt;
|
struct gtt_range *gt;
|
||||||
struct drm_gem_object *obj;
|
struct drm_gem_object *obj;
|
||||||
int ret;
|
int ret = 0;
|
||||||
|
|
||||||
/* if we want to turn of the cursor ignore width and height */
|
/* if we want to turn of the cursor ignore width and height */
|
||||||
if (!handle) {
|
if (!handle) {
|
||||||
@@ -1499,7 +1499,8 @@ static int cdv_intel_crtc_cursor_set(struct drm_crtc *crtc,
|
|||||||
|
|
||||||
if (obj->size < width * height * 4) {
|
if (obj->size < width * height * 4) {
|
||||||
dev_dbg(dev->dev, "buffer is to small\n");
|
dev_dbg(dev->dev, "buffer is to small\n");
|
||||||
return -ENOMEM;
|
ret = -ENOMEM;
|
||||||
|
goto unref_cursor;
|
||||||
}
|
}
|
||||||
|
|
||||||
gt = container_of(obj, struct gtt_range, gem);
|
gt = container_of(obj, struct gtt_range, gem);
|
||||||
@@ -1508,7 +1509,7 @@ static int cdv_intel_crtc_cursor_set(struct drm_crtc *crtc,
|
|||||||
ret = psb_gtt_pin(gt);
|
ret = psb_gtt_pin(gt);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
dev_err(dev->dev, "Can not pin down handle 0x%x\n", handle);
|
dev_err(dev->dev, "Can not pin down handle 0x%x\n", handle);
|
||||||
return ret;
|
goto unref_cursor;
|
||||||
}
|
}
|
||||||
|
|
||||||
addr = gt->offset; /* Or resource.start ??? */
|
addr = gt->offset; /* Or resource.start ??? */
|
||||||
@@ -1532,9 +1533,14 @@ static int cdv_intel_crtc_cursor_set(struct drm_crtc *crtc,
|
|||||||
struct gtt_range, gem);
|
struct gtt_range, gem);
|
||||||
psb_gtt_unpin(gt);
|
psb_gtt_unpin(gt);
|
||||||
drm_gem_object_unreference(psb_intel_crtc->cursor_obj);
|
drm_gem_object_unreference(psb_intel_crtc->cursor_obj);
|
||||||
psb_intel_crtc->cursor_obj = obj;
|
|
||||||
}
|
}
|
||||||
return 0;
|
|
||||||
|
psb_intel_crtc->cursor_obj = obj;
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
unref_cursor:
|
||||||
|
drm_gem_object_unreference(obj);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int cdv_intel_crtc_cursor_move(struct drm_crtc *crtc, int x, int y)
|
static int cdv_intel_crtc_cursor_move(struct drm_crtc *crtc, int x, int y)
|
||||||
@@ -1750,6 +1756,19 @@ static void cdv_intel_crtc_destroy(struct drm_crtc *crtc)
|
|||||||
kfree(psb_intel_crtc);
|
kfree(psb_intel_crtc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void cdv_intel_crtc_disable(struct drm_crtc *crtc)
|
||||||
|
{
|
||||||
|
struct gtt_range *gt;
|
||||||
|
struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
|
||||||
|
|
||||||
|
crtc_funcs->dpms(crtc, DRM_MODE_DPMS_OFF);
|
||||||
|
|
||||||
|
if (crtc->fb) {
|
||||||
|
gt = to_psb_fb(crtc->fb)->gtt;
|
||||||
|
psb_gtt_unpin(gt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const struct drm_crtc_helper_funcs cdv_intel_helper_funcs = {
|
const struct drm_crtc_helper_funcs cdv_intel_helper_funcs = {
|
||||||
.dpms = cdv_intel_crtc_dpms,
|
.dpms = cdv_intel_crtc_dpms,
|
||||||
.mode_fixup = cdv_intel_crtc_mode_fixup,
|
.mode_fixup = cdv_intel_crtc_mode_fixup,
|
||||||
@@ -1757,6 +1776,7 @@ const struct drm_crtc_helper_funcs cdv_intel_helper_funcs = {
|
|||||||
.mode_set_base = cdv_intel_pipe_set_base,
|
.mode_set_base = cdv_intel_pipe_set_base,
|
||||||
.prepare = cdv_intel_crtc_prepare,
|
.prepare = cdv_intel_crtc_prepare,
|
||||||
.commit = cdv_intel_crtc_commit,
|
.commit = cdv_intel_crtc_commit,
|
||||||
|
.disable = cdv_intel_crtc_disable,
|
||||||
};
|
};
|
||||||
|
|
||||||
const struct drm_crtc_funcs cdv_intel_crtc_funcs = {
|
const struct drm_crtc_funcs cdv_intel_crtc_funcs = {
|
||||||
|
@@ -121,8 +121,8 @@ static int psbfb_vm_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
|
|||||||
unsigned long address;
|
unsigned long address;
|
||||||
int ret;
|
int ret;
|
||||||
unsigned long pfn;
|
unsigned long pfn;
|
||||||
/* FIXME: assumes fb at stolen base which may not be true */
|
unsigned long phys_addr = (unsigned long)dev_priv->stolen_base +
|
||||||
unsigned long phys_addr = (unsigned long)dev_priv->stolen_base;
|
psbfb->gtt->offset;
|
||||||
|
|
||||||
page_num = (vma->vm_end - vma->vm_start) >> PAGE_SHIFT;
|
page_num = (vma->vm_end - vma->vm_start) >> PAGE_SHIFT;
|
||||||
address = (unsigned long)vmf->virtual_address - (vmf->pgoff << PAGE_SHIFT);
|
address = (unsigned long)vmf->virtual_address - (vmf->pgoff << PAGE_SHIFT);
|
||||||
|
@@ -843,7 +843,7 @@ static int psb_intel_crtc_cursor_set(struct drm_crtc *crtc,
|
|||||||
struct gtt_range *cursor_gt = psb_intel_crtc->cursor_gt;
|
struct gtt_range *cursor_gt = psb_intel_crtc->cursor_gt;
|
||||||
struct drm_gem_object *obj;
|
struct drm_gem_object *obj;
|
||||||
void *tmp_dst, *tmp_src;
|
void *tmp_dst, *tmp_src;
|
||||||
int ret, i, cursor_pages;
|
int ret = 0, i, cursor_pages;
|
||||||
|
|
||||||
/* if we want to turn of the cursor ignore width and height */
|
/* if we want to turn of the cursor ignore width and height */
|
||||||
if (!handle) {
|
if (!handle) {
|
||||||
@@ -880,7 +880,8 @@ static int psb_intel_crtc_cursor_set(struct drm_crtc *crtc,
|
|||||||
|
|
||||||
if (obj->size < width * height * 4) {
|
if (obj->size < width * height * 4) {
|
||||||
dev_dbg(dev->dev, "buffer is to small\n");
|
dev_dbg(dev->dev, "buffer is to small\n");
|
||||||
return -ENOMEM;
|
ret = -ENOMEM;
|
||||||
|
goto unref_cursor;
|
||||||
}
|
}
|
||||||
|
|
||||||
gt = container_of(obj, struct gtt_range, gem);
|
gt = container_of(obj, struct gtt_range, gem);
|
||||||
@@ -889,13 +890,14 @@ static int psb_intel_crtc_cursor_set(struct drm_crtc *crtc,
|
|||||||
ret = psb_gtt_pin(gt);
|
ret = psb_gtt_pin(gt);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
dev_err(dev->dev, "Can not pin down handle 0x%x\n", handle);
|
dev_err(dev->dev, "Can not pin down handle 0x%x\n", handle);
|
||||||
return ret;
|
goto unref_cursor;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dev_priv->ops->cursor_needs_phys) {
|
if (dev_priv->ops->cursor_needs_phys) {
|
||||||
if (cursor_gt == NULL) {
|
if (cursor_gt == NULL) {
|
||||||
dev_err(dev->dev, "No hardware cursor mem available");
|
dev_err(dev->dev, "No hardware cursor mem available");
|
||||||
return -ENOMEM;
|
ret = -ENOMEM;
|
||||||
|
goto unref_cursor;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Prevent overflow */
|
/* Prevent overflow */
|
||||||
@@ -936,9 +938,14 @@ static int psb_intel_crtc_cursor_set(struct drm_crtc *crtc,
|
|||||||
struct gtt_range, gem);
|
struct gtt_range, gem);
|
||||||
psb_gtt_unpin(gt);
|
psb_gtt_unpin(gt);
|
||||||
drm_gem_object_unreference(psb_intel_crtc->cursor_obj);
|
drm_gem_object_unreference(psb_intel_crtc->cursor_obj);
|
||||||
psb_intel_crtc->cursor_obj = obj;
|
|
||||||
}
|
}
|
||||||
return 0;
|
|
||||||
|
psb_intel_crtc->cursor_obj = obj;
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
unref_cursor:
|
||||||
|
drm_gem_object_unreference(obj);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int psb_intel_crtc_cursor_move(struct drm_crtc *crtc, int x, int y)
|
static int psb_intel_crtc_cursor_move(struct drm_crtc *crtc, int x, int y)
|
||||||
@@ -1150,6 +1157,19 @@ static void psb_intel_crtc_destroy(struct drm_crtc *crtc)
|
|||||||
kfree(psb_intel_crtc);
|
kfree(psb_intel_crtc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void psb_intel_crtc_disable(struct drm_crtc *crtc)
|
||||||
|
{
|
||||||
|
struct gtt_range *gt;
|
||||||
|
struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
|
||||||
|
|
||||||
|
crtc_funcs->dpms(crtc, DRM_MODE_DPMS_OFF);
|
||||||
|
|
||||||
|
if (crtc->fb) {
|
||||||
|
gt = to_psb_fb(crtc->fb)->gtt;
|
||||||
|
psb_gtt_unpin(gt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const struct drm_crtc_helper_funcs psb_intel_helper_funcs = {
|
const struct drm_crtc_helper_funcs psb_intel_helper_funcs = {
|
||||||
.dpms = psb_intel_crtc_dpms,
|
.dpms = psb_intel_crtc_dpms,
|
||||||
.mode_fixup = psb_intel_crtc_mode_fixup,
|
.mode_fixup = psb_intel_crtc_mode_fixup,
|
||||||
@@ -1157,6 +1177,7 @@ const struct drm_crtc_helper_funcs psb_intel_helper_funcs = {
|
|||||||
.mode_set_base = psb_intel_pipe_set_base,
|
.mode_set_base = psb_intel_pipe_set_base,
|
||||||
.prepare = psb_intel_crtc_prepare,
|
.prepare = psb_intel_crtc_prepare,
|
||||||
.commit = psb_intel_crtc_commit,
|
.commit = psb_intel_crtc_commit,
|
||||||
|
.disable = psb_intel_crtc_disable,
|
||||||
};
|
};
|
||||||
|
|
||||||
const struct drm_crtc_funcs psb_intel_crtc_funcs = {
|
const struct drm_crtc_funcs psb_intel_crtc_funcs = {
|
||||||
|
@@ -1777,10 +1777,13 @@ static void intel_sdvo_get_lvds_modes(struct drm_connector *connector)
|
|||||||
* arranged in priority order.
|
* arranged in priority order.
|
||||||
*/
|
*/
|
||||||
intel_ddc_get_modes(connector, &intel_sdvo->ddc);
|
intel_ddc_get_modes(connector, &intel_sdvo->ddc);
|
||||||
if (list_empty(&connector->probed_modes) == false)
|
|
||||||
goto end;
|
|
||||||
|
|
||||||
/* Fetch modes from VBT */
|
/*
|
||||||
|
* Fetch modes from VBT. For SDVO prefer the VBT mode since some
|
||||||
|
* SDVO->LVDS transcoders can't cope with the EDID mode. Since
|
||||||
|
* drm_mode_probed_add adds the mode at the head of the list we add it
|
||||||
|
* last.
|
||||||
|
*/
|
||||||
if (dev_priv->sdvo_lvds_vbt_mode != NULL) {
|
if (dev_priv->sdvo_lvds_vbt_mode != NULL) {
|
||||||
newmode = drm_mode_duplicate(connector->dev,
|
newmode = drm_mode_duplicate(connector->dev,
|
||||||
dev_priv->sdvo_lvds_vbt_mode);
|
dev_priv->sdvo_lvds_vbt_mode);
|
||||||
@@ -1792,7 +1795,6 @@ static void intel_sdvo_get_lvds_modes(struct drm_connector *connector)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
end:
|
|
||||||
list_for_each_entry(newmode, &connector->probed_modes, head) {
|
list_for_each_entry(newmode, &connector->probed_modes, head) {
|
||||||
if (newmode->type & DRM_MODE_TYPE_PREFERRED) {
|
if (newmode->type & DRM_MODE_TYPE_PREFERRED) {
|
||||||
intel_sdvo->sdvo_lvds_fixed_mode =
|
intel_sdvo->sdvo_lvds_fixed_mode =
|
||||||
@@ -2790,12 +2792,6 @@ bool intel_sdvo_init(struct drm_device *dev, uint32_t sdvo_reg, bool is_sdvob)
|
|||||||
SDVOB_HOTPLUG_INT_STATUS_I915 : SDVOC_HOTPLUG_INT_STATUS_I915;
|
SDVOB_HOTPLUG_INT_STATUS_I915 : SDVOC_HOTPLUG_INT_STATUS_I915;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Only enable the hotplug irq if we need it, to work around noisy
|
|
||||||
* hotplug lines.
|
|
||||||
*/
|
|
||||||
if (intel_sdvo->hotplug_active)
|
|
||||||
intel_encoder->hpd_pin = HPD_SDVO_B ? HPD_SDVO_B : HPD_SDVO_C;
|
|
||||||
|
|
||||||
intel_encoder->compute_config = intel_sdvo_compute_config;
|
intel_encoder->compute_config = intel_sdvo_compute_config;
|
||||||
intel_encoder->disable = intel_disable_sdvo;
|
intel_encoder->disable = intel_disable_sdvo;
|
||||||
intel_encoder->mode_set = intel_sdvo_mode_set;
|
intel_encoder->mode_set = intel_sdvo_mode_set;
|
||||||
@@ -2814,6 +2810,14 @@ bool intel_sdvo_init(struct drm_device *dev, uint32_t sdvo_reg, bool is_sdvob)
|
|||||||
goto err_output;
|
goto err_output;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Only enable the hotplug irq if we need it, to work around noisy
|
||||||
|
* hotplug lines.
|
||||||
|
*/
|
||||||
|
if (intel_sdvo->hotplug_active) {
|
||||||
|
intel_encoder->hpd_pin =
|
||||||
|
intel_sdvo->is_sdvob ? HPD_SDVO_B : HPD_SDVO_C;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Cloning SDVO with anything is often impossible, since the SDVO
|
* Cloning SDVO with anything is often impossible, since the SDVO
|
||||||
* encoder can request a special input timing mode. And even if that's
|
* encoder can request a special input timing mode. And even if that's
|
||||||
|
Reference in New Issue
Block a user