Commit 2d1f4c8e authored by Linus Torvalds's avatar Linus Torvalds

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

Pull drm fixes from Dave Airlie:
 "Fixes for intel and nouveau mainly.

   - intel: disable HSW by default, sdvo fixes, link train regression
     fix
   - nouveau: acpi rom loading regression fix, with a few other fixes
     from the rework
   -core: just other minor fixes and race fixes for ttm."

* 'drm-fixes' of git://people.freedesktop.org/~airlied/linux: (24 commits)
  drm/ttm: Fix a theoretical race in ttm_bo_cleanup_refs()
  drm/ttm: Fix a theoretical race
  drm: platform: Don't initialize driver-private data
  drm/debugfs: remove redundant info from gem_names
  drm: fb: cma: Fail gracefully on allocation failure
  drm: fb: cma: Fix typo in debug message
  drm/nouveau/clock: fix missing pll type/addr when matching default entry
  drm/nouveau/fb: fix reporting of memory type on GF8+ IGPs
  drm/nv41/vm: don't init hw pciegart on boards with agp bridge
  drm/nouveau/bios: fetch full 4KiB block to determine ACPI ROM image size
  drm/nouveau: validate vbios size
  drm/nouveau: warn when trying to free mm which is still in use
  drm/nouveau: fix nouveau_mm/nouveau_mm_node leak
  drm/nouveau/bios: improve error handling when reading the vbios from ACPI
  drm/nouveau: handle same-fb page flips
  drm/i915: Initialize obj->pages before use by i915_gem_object_do_bit17_swizzle()
  drm/i915: Add no-lvds quirk for Supermicro X7SPA-H
  drm/i915: Insert i915_preliminary_hw_support variable.
  drm/i915: shut up spurious WARN in the gtt fault handler
  Revert "drm/i915: Try harder to complete DP training pattern 1"
  ...
parents d888af96 b8e902f2
...@@ -206,7 +206,7 @@ static int drm_fbdev_cma_create(struct drm_fb_helper *helper, ...@@ -206,7 +206,7 @@ static int drm_fbdev_cma_create(struct drm_fb_helper *helper,
size_t size; size_t size;
int ret; int ret;
DRM_DEBUG_KMS("surface width(%d), height(%d) and bpp(%d\n", DRM_DEBUG_KMS("surface width(%d), height(%d) and bpp(%d)\n",
sizes->surface_width, sizes->surface_height, sizes->surface_width, sizes->surface_height,
sizes->surface_bpp); sizes->surface_bpp);
...@@ -220,7 +220,7 @@ static int drm_fbdev_cma_create(struct drm_fb_helper *helper, ...@@ -220,7 +220,7 @@ static int drm_fbdev_cma_create(struct drm_fb_helper *helper,
size = mode_cmd.pitches[0] * mode_cmd.height; size = mode_cmd.pitches[0] * mode_cmd.height;
obj = drm_gem_cma_create(dev, size); obj = drm_gem_cma_create(dev, size);
if (!obj) if (IS_ERR(obj))
return -ENOMEM; return -ENOMEM;
fbi = framebuffer_alloc(0, dev->dev); fbi = framebuffer_alloc(0, dev->dev);
......
...@@ -205,8 +205,6 @@ static int drm_gem_one_name_info(int id, void *ptr, void *data) ...@@ -205,8 +205,6 @@ static int drm_gem_one_name_info(int id, void *ptr, void *data)
struct drm_gem_object *obj = ptr; struct drm_gem_object *obj = ptr;
struct seq_file *m = data; struct seq_file *m = data;
seq_printf(m, "name %d size %zd\n", obj->name, obj->size);
seq_printf(m, "%6d %8zd %7d %8d\n", seq_printf(m, "%6d %8zd %7d %8d\n",
obj->name, obj->size, obj->name, obj->size,
atomic_read(&obj->handle_count), atomic_read(&obj->handle_count),
......
...@@ -64,7 +64,6 @@ int drm_get_platform_dev(struct platform_device *platdev, ...@@ -64,7 +64,6 @@ int drm_get_platform_dev(struct platform_device *platdev,
} }
if (drm_core_check_feature(dev, DRIVER_MODESET)) { if (drm_core_check_feature(dev, DRIVER_MODESET)) {
dev_set_drvdata(&platdev->dev, dev);
ret = drm_get_minor(dev, &dev->control, DRM_MINOR_CONTROL); ret = drm_get_minor(dev, &dev->control, DRM_MINOR_CONTROL);
if (ret) if (ret)
goto err_g1; goto err_g1;
......
...@@ -118,6 +118,13 @@ module_param_named(i915_enable_ppgtt, i915_enable_ppgtt, int, 0600); ...@@ -118,6 +118,13 @@ module_param_named(i915_enable_ppgtt, i915_enable_ppgtt, int, 0600);
MODULE_PARM_DESC(i915_enable_ppgtt, MODULE_PARM_DESC(i915_enable_ppgtt,
"Enable PPGTT (default: true)"); "Enable PPGTT (default: true)");
unsigned int i915_preliminary_hw_support __read_mostly = 0;
module_param_named(preliminary_hw_support, i915_preliminary_hw_support, int, 0600);
MODULE_PARM_DESC(preliminary_hw_support,
"Enable preliminary hardware support. "
"Enable Haswell and ValleyView Support. "
"(default: false)");
static struct drm_driver driver; static struct drm_driver driver;
extern int intel_agp_enabled; extern int intel_agp_enabled;
...@@ -826,6 +833,12 @@ i915_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) ...@@ -826,6 +833,12 @@ i915_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
struct intel_device_info *intel_info = struct intel_device_info *intel_info =
(struct intel_device_info *) ent->driver_data; (struct intel_device_info *) ent->driver_data;
if (intel_info->is_haswell || intel_info->is_valleyview)
if(!i915_preliminary_hw_support) {
DRM_ERROR("Preliminary hardware support disabled\n");
return -ENODEV;
}
/* Only bind to function 0 of the device. Early generations /* Only bind to function 0 of the device. Early generations
* used function 1 as a placeholder for multi-head. This causes * used function 1 as a placeholder for multi-head. This causes
* us confusion instead, especially on the systems where both * us confusion instead, especially on the systems where both
......
...@@ -1217,6 +1217,7 @@ extern int i915_enable_rc6 __read_mostly; ...@@ -1217,6 +1217,7 @@ extern int i915_enable_rc6 __read_mostly;
extern int i915_enable_fbc __read_mostly; extern int i915_enable_fbc __read_mostly;
extern bool i915_enable_hangcheck __read_mostly; extern bool i915_enable_hangcheck __read_mostly;
extern int i915_enable_ppgtt __read_mostly; extern int i915_enable_ppgtt __read_mostly;
extern unsigned int i915_preliminary_hw_support __read_mostly;
extern int i915_suspend(struct drm_device *dev, pm_message_t state); extern int i915_suspend(struct drm_device *dev, pm_message_t state);
extern int i915_resume(struct drm_device *dev); extern int i915_resume(struct drm_device *dev);
......
...@@ -1407,8 +1407,10 @@ int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf) ...@@ -1407,8 +1407,10 @@ int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
return VM_FAULT_NOPAGE; return VM_FAULT_NOPAGE;
case -ENOMEM: case -ENOMEM:
return VM_FAULT_OOM; return VM_FAULT_OOM;
case -ENOSPC:
return VM_FAULT_SIGBUS;
default: default:
WARN_ON_ONCE(ret); WARN_ONCE(ret, "unhandled error in i915_gem_fault: %i\n", ret);
return VM_FAULT_SIGBUS; return VM_FAULT_SIGBUS;
} }
} }
...@@ -1822,10 +1824,11 @@ i915_gem_object_get_pages_gtt(struct drm_i915_gem_object *obj) ...@@ -1822,10 +1824,11 @@ i915_gem_object_get_pages_gtt(struct drm_i915_gem_object *obj)
sg_set_page(sg, page, PAGE_SIZE, 0); sg_set_page(sg, page, PAGE_SIZE, 0);
} }
obj->pages = st;
if (i915_gem_object_needs_bit17_swizzle(obj)) if (i915_gem_object_needs_bit17_swizzle(obj))
i915_gem_object_do_bit_17_swizzle(obj); i915_gem_object_do_bit_17_swizzle(obj);
obj->pages = st;
return 0; return 0;
err_pages: err_pages:
......
...@@ -219,20 +219,7 @@ static void intel_crt_mode_set(struct drm_encoder *encoder, ...@@ -219,20 +219,7 @@ static void intel_crt_mode_set(struct drm_encoder *encoder,
intel_encoder_to_crt(to_intel_encoder(encoder)); intel_encoder_to_crt(to_intel_encoder(encoder));
struct intel_crtc *intel_crtc = to_intel_crtc(crtc); struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
struct drm_i915_private *dev_priv = dev->dev_private; struct drm_i915_private *dev_priv = dev->dev_private;
int dpll_md_reg; u32 adpa;
u32 adpa, dpll_md;
dpll_md_reg = DPLL_MD(intel_crtc->pipe);
/*
* Disable separate mode multiplier used when cloning SDVO to CRT
* XXX this needs to be adjusted when we really are cloning
*/
if (INTEL_INFO(dev)->gen >= 4 && !HAS_PCH_SPLIT(dev)) {
dpll_md = I915_READ(dpll_md_reg);
I915_WRITE(dpll_md_reg,
dpll_md & ~DPLL_MD_UDI_MULTIPLIER_MASK);
}
adpa = ADPA_HOTPLUG_BITS; adpa = ADPA_HOTPLUG_BITS;
if (adjusted_mode->flags & DRM_MODE_FLAG_PHSYNC) if (adjusted_mode->flags & DRM_MODE_FLAG_PHSYNC)
......
...@@ -7892,6 +7892,34 @@ struct intel_quirk { ...@@ -7892,6 +7892,34 @@ struct intel_quirk {
void (*hook)(struct drm_device *dev); void (*hook)(struct drm_device *dev);
}; };
/* For systems that don't have a meaningful PCI subdevice/subvendor ID */
struct intel_dmi_quirk {
void (*hook)(struct drm_device *dev);
const struct dmi_system_id (*dmi_id_list)[];
};
static int intel_dmi_reverse_brightness(const struct dmi_system_id *id)
{
DRM_INFO("Backlight polarity reversed on %s\n", id->ident);
return 1;
}
static const struct intel_dmi_quirk intel_dmi_quirks[] = {
{
.dmi_id_list = &(const struct dmi_system_id[]) {
{
.callback = intel_dmi_reverse_brightness,
.ident = "NCR Corporation",
.matches = {DMI_MATCH(DMI_SYS_VENDOR, "NCR Corporation"),
DMI_MATCH(DMI_PRODUCT_NAME, ""),
},
},
{ } /* terminating entry */
},
.hook = quirk_invert_brightness,
},
};
static struct intel_quirk intel_quirks[] = { static struct intel_quirk intel_quirks[] = {
/* HP Mini needs pipe A force quirk (LP: #322104) */ /* HP Mini needs pipe A force quirk (LP: #322104) */
{ 0x27ae, 0x103c, 0x361a, quirk_pipea_force }, { 0x27ae, 0x103c, 0x361a, quirk_pipea_force },
...@@ -7931,6 +7959,10 @@ static void intel_init_quirks(struct drm_device *dev) ...@@ -7931,6 +7959,10 @@ static void intel_init_quirks(struct drm_device *dev)
q->subsystem_device == PCI_ANY_ID)) q->subsystem_device == PCI_ANY_ID))
q->hook(dev); q->hook(dev);
} }
for (i = 0; i < ARRAY_SIZE(intel_dmi_quirks); i++) {
if (dmi_check_system(*intel_dmi_quirks[i].dmi_id_list) != 0)
intel_dmi_quirks[i].hook(dev);
}
} }
/* Disable the VGA plane that we never use */ /* Disable the VGA plane that we never use */
......
...@@ -1797,7 +1797,8 @@ intel_dp_start_link_train(struct intel_dp *intel_dp) ...@@ -1797,7 +1797,8 @@ intel_dp_start_link_train(struct intel_dp *intel_dp)
if ((intel_dp->train_set[i] & DP_TRAIN_MAX_SWING_REACHED) == 0) if ((intel_dp->train_set[i] & DP_TRAIN_MAX_SWING_REACHED) == 0)
break; break;
if (i == intel_dp->lane_count && voltage_tries == 5) { if (i == intel_dp->lane_count && voltage_tries == 5) {
if (++loop_tries == 5) { ++loop_tries;
if (loop_tries == 5) {
DRM_DEBUG_KMS("too many full retries, give up\n"); DRM_DEBUG_KMS("too many full retries, give up\n");
break; break;
} }
...@@ -1807,11 +1808,15 @@ intel_dp_start_link_train(struct intel_dp *intel_dp) ...@@ -1807,11 +1808,15 @@ intel_dp_start_link_train(struct intel_dp *intel_dp)
} }
/* Check to see if we've tried the same voltage 5 times */ /* Check to see if we've tried the same voltage 5 times */
if ((intel_dp->train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK) != voltage) { if ((intel_dp->train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK) == voltage) {
voltage = intel_dp->train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK;
voltage_tries = 0;
} else
++voltage_tries; ++voltage_tries;
if (voltage_tries == 5) {
DRM_DEBUG_KMS("too many voltage retries, give up\n");
break;
}
} else
voltage_tries = 0;
voltage = intel_dp->train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK;
/* Compute new intel_dp->train_set as requested by target */ /* Compute new intel_dp->train_set as requested by target */
intel_get_adjust_train(intel_dp, link_status); intel_get_adjust_train(intel_dp, link_status);
......
...@@ -777,6 +777,14 @@ static const struct dmi_system_id intel_no_lvds[] = { ...@@ -777,6 +777,14 @@ static const struct dmi_system_id intel_no_lvds[] = {
DMI_MATCH(DMI_BOARD_NAME, "D525TUD"), DMI_MATCH(DMI_BOARD_NAME, "D525TUD"),
}, },
}, },
{
.callback = intel_no_lvds_dmi_callback,
.ident = "Supermicro X7SPA-H",
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "Supermicro"),
DMI_MATCH(DMI_PRODUCT_NAME, "X7SPA-H"),
},
},
{ } /* terminating entry */ { } /* terminating entry */
}; };
......
...@@ -139,6 +139,11 @@ struct intel_sdvo { ...@@ -139,6 +139,11 @@ struct intel_sdvo {
/* DDC bus used by this SDVO encoder */ /* DDC bus used by this SDVO encoder */
uint8_t ddc_bus; uint8_t ddc_bus;
/*
* the sdvo flag gets lost in round trip: dtd->adjusted_mode->dtd
*/
uint8_t dtd_sdvo_flags;
}; };
struct intel_sdvo_connector { struct intel_sdvo_connector {
...@@ -984,6 +989,7 @@ intel_sdvo_get_preferred_input_mode(struct intel_sdvo *intel_sdvo, ...@@ -984,6 +989,7 @@ intel_sdvo_get_preferred_input_mode(struct intel_sdvo *intel_sdvo,
return false; return false;
intel_sdvo_get_mode_from_dtd(adjusted_mode, &input_dtd); intel_sdvo_get_mode_from_dtd(adjusted_mode, &input_dtd);
intel_sdvo->dtd_sdvo_flags = input_dtd.part2.sdvo_flags;
return true; return true;
} }
...@@ -1092,6 +1098,8 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder, ...@@ -1092,6 +1098,8 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder,
* adjusted_mode. * adjusted_mode.
*/ */
intel_sdvo_get_dtd_from_mode(&input_dtd, adjusted_mode); intel_sdvo_get_dtd_from_mode(&input_dtd, adjusted_mode);
if (intel_sdvo->is_tv || intel_sdvo->is_lvds)
input_dtd.part2.sdvo_flags = intel_sdvo->dtd_sdvo_flags;
if (!intel_sdvo_set_input_timing(intel_sdvo, &input_dtd)) if (!intel_sdvo_set_input_timing(intel_sdvo, &input_dtd))
DRM_INFO("Setting input timings on %s failed\n", DRM_INFO("Setting input timings on %s failed\n",
SDVO_NAME(intel_sdvo)); SDVO_NAME(intel_sdvo));
...@@ -2277,10 +2285,8 @@ intel_sdvo_lvds_init(struct intel_sdvo *intel_sdvo, int device) ...@@ -2277,10 +2285,8 @@ intel_sdvo_lvds_init(struct intel_sdvo *intel_sdvo, int device)
intel_sdvo_connector->output_flag = SDVO_OUTPUT_LVDS1; intel_sdvo_connector->output_flag = SDVO_OUTPUT_LVDS1;
} }
/* SDVO LVDS is cloneable because the SDVO encoder does the upscaling, /* SDVO LVDS is not cloneable because the input mode gets adjusted by the encoder */
* as opposed to native LVDS, where we upscale with the panel-fitter intel_sdvo->base.cloneable = false;
* (and hence only the native LVDS resolution could be cloned). */
intel_sdvo->base.cloneable = true;
intel_sdvo_connector_init(intel_sdvo_connector, intel_sdvo); intel_sdvo_connector_init(intel_sdvo_connector, intel_sdvo);
if (!intel_sdvo_create_enhance_property(intel_sdvo, intel_sdvo_connector)) if (!intel_sdvo_create_enhance_property(intel_sdvo, intel_sdvo_connector))
......
...@@ -39,6 +39,11 @@ nouveau_gpuobj_destroy(struct nouveau_gpuobj *gpuobj) ...@@ -39,6 +39,11 @@ nouveau_gpuobj_destroy(struct nouveau_gpuobj *gpuobj)
nv_wo32(gpuobj, i, 0x00000000); nv_wo32(gpuobj, i, 0x00000000);
} }
if (gpuobj->node) {
nouveau_mm_free(&nv_gpuobj(gpuobj->parent)->heap,
&gpuobj->node);
}
if (gpuobj->heap.block_size) if (gpuobj->heap.block_size)
nouveau_mm_fini(&gpuobj->heap); nouveau_mm_fini(&gpuobj->heap);
......
...@@ -236,7 +236,7 @@ nouveau_mm_fini(struct nouveau_mm *mm) ...@@ -236,7 +236,7 @@ nouveau_mm_fini(struct nouveau_mm *mm)
int nodes = 0; int nodes = 0;
list_for_each_entry(node, &mm->nodes, nl_entry) { list_for_each_entry(node, &mm->nodes, nl_entry) {
if (nodes++ == mm->heap_nodes) if (WARN_ON(nodes++ == mm->heap_nodes))
return -EBUSY; return -EBUSY;
} }
......
...@@ -72,7 +72,7 @@ nouveau_bios_shadow_of(struct nouveau_bios *bios) ...@@ -72,7 +72,7 @@ nouveau_bios_shadow_of(struct nouveau_bios *bios)
} }
data = of_get_property(dn, "NVDA,BMP", &size); data = of_get_property(dn, "NVDA,BMP", &size);
if (data) { if (data && size) {
bios->size = size; bios->size = size;
bios->data = kmalloc(bios->size, GFP_KERNEL); bios->data = kmalloc(bios->size, GFP_KERNEL);
if (bios->data) if (bios->data)
...@@ -104,6 +104,9 @@ nouveau_bios_shadow_pramin(struct nouveau_bios *bios) ...@@ -104,6 +104,9 @@ nouveau_bios_shadow_pramin(struct nouveau_bios *bios)
goto out; goto out;
bios->size = nv_rd08(bios, 0x700002) * 512; bios->size = nv_rd08(bios, 0x700002) * 512;
if (!bios->size)
goto out;
bios->data = kmalloc(bios->size, GFP_KERNEL); bios->data = kmalloc(bios->size, GFP_KERNEL);
if (bios->data) { if (bios->data) {
for (i = 0; i < bios->size; i++) for (i = 0; i < bios->size; i++)
...@@ -155,6 +158,9 @@ nouveau_bios_shadow_prom(struct nouveau_bios *bios) ...@@ -155,6 +158,9 @@ nouveau_bios_shadow_prom(struct nouveau_bios *bios)
/* read entire bios image to system memory */ /* read entire bios image to system memory */
bios->size = nv_rd08(bios, 0x300002) * 512; bios->size = nv_rd08(bios, 0x300002) * 512;
if (!bios->size)
goto out;
bios->data = kmalloc(bios->size, GFP_KERNEL); bios->data = kmalloc(bios->size, GFP_KERNEL);
if (bios->data) { if (bios->data) {
for (i = 0; i < bios->size; i++) for (i = 0; i < bios->size; i++)
...@@ -186,14 +192,22 @@ nouveau_bios_shadow_acpi(struct nouveau_bios *bios) ...@@ -186,14 +192,22 @@ nouveau_bios_shadow_acpi(struct nouveau_bios *bios)
{ {
struct pci_dev *pdev = nv_device(bios)->pdev; struct pci_dev *pdev = nv_device(bios)->pdev;
int ret, cnt, i; int ret, cnt, i;
u8 data[3];
if (!nouveau_acpi_rom_supported(pdev)) if (!nouveau_acpi_rom_supported(pdev)) {
bios->data = NULL;
return; return;
}
bios->size = 0; bios->size = 0;
if (nouveau_acpi_get_bios_chunk(data, 0, 3) == 3) bios->data = kmalloc(4096, GFP_KERNEL);
bios->size = data[2] * 512; if (bios->data) {
if (nouveau_acpi_get_bios_chunk(bios->data, 0, 4096) == 4096)
bios->size = bios->data[2] * 512;
kfree(bios->data);
}
if (!bios->size)
return;
bios->data = kmalloc(bios->size, GFP_KERNEL); bios->data = kmalloc(bios->size, GFP_KERNEL);
for (i = 0; bios->data && i < bios->size; i += cnt) { for (i = 0; bios->data && i < bios->size; i += cnt) {
...@@ -229,12 +243,14 @@ nouveau_bios_shadow_pci(struct nouveau_bios *bios) ...@@ -229,12 +243,14 @@ nouveau_bios_shadow_pci(struct nouveau_bios *bios)
static int static int
nouveau_bios_score(struct nouveau_bios *bios, const bool writeable) nouveau_bios_score(struct nouveau_bios *bios, const bool writeable)
{ {
if (!bios->data || bios->data[0] != 0x55 || bios->data[1] != 0xAA) { if (bios->size < 3 || !bios->data || bios->data[0] != 0x55 ||
bios->data[1] != 0xAA) {
nv_info(bios, "... signature not found\n"); nv_info(bios, "... signature not found\n");
return 0; return 0;
} }
if (nvbios_checksum(bios->data, bios->data[2] * 512)) { if (nvbios_checksum(bios->data,
min_t(u32, bios->data[2] * 512, bios->size))) {
nv_info(bios, "... checksum invalid\n"); nv_info(bios, "... checksum invalid\n");
/* if a ro image is somewhat bad, it's probably all rubbish */ /* if a ro image is somewhat bad, it's probably all rubbish */
return writeable ? 2 : 1; return writeable ? 2 : 1;
......
...@@ -157,11 +157,10 @@ pll_map_reg(struct nouveau_bios *bios, u32 reg, u32 *type, u8 *ver, u8 *len) ...@@ -157,11 +157,10 @@ pll_map_reg(struct nouveau_bios *bios, u32 reg, u32 *type, u8 *ver, u8 *len)
while (map->reg) { while (map->reg) {
if (map->reg == reg && *ver >= 0x20) { if (map->reg == reg && *ver >= 0x20) {
u16 addr = (data += hdr); u16 addr = (data += hdr);
*type = map->type;
while (cnt--) { while (cnt--) {
if (nv_ro32(bios, data) == map->reg) { if (nv_ro32(bios, data) == map->reg)
*type = map->type;
return data; return data;
}
data += *len; data += *len;
} }
return addr; return addr;
...@@ -200,11 +199,10 @@ pll_map_type(struct nouveau_bios *bios, u8 type, u32 *reg, u8 *ver, u8 *len) ...@@ -200,11 +199,10 @@ pll_map_type(struct nouveau_bios *bios, u8 type, u32 *reg, u8 *ver, u8 *len)
while (map->reg) { while (map->reg) {
if (map->type == type && *ver >= 0x20) { if (map->type == type && *ver >= 0x20) {
u16 addr = (data += hdr); u16 addr = (data += hdr);
*reg = map->reg;
while (cnt--) { while (cnt--) {
if (nv_ro32(bios, data) == map->reg) { if (nv_ro32(bios, data) == map->reg)
*reg = map->reg;
return data; return data;
}
data += *len; data += *len;
} }
return addr; return addr;
......
...@@ -237,6 +237,7 @@ nv50_fb_ctor(struct nouveau_object *parent, struct nouveau_object *engine, ...@@ -237,6 +237,7 @@ nv50_fb_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
return ret; return ret;
priv->base.ram.stolen = (u64)nv_rd32(priv, 0x100e10) << 12; priv->base.ram.stolen = (u64)nv_rd32(priv, 0x100e10) << 12;
priv->base.ram.type = NV_MEM_TYPE_STOLEN;
break; break;
default: default:
ret = nouveau_mm_init(&priv->base.vram, rsvd_head, size, ret = nouveau_mm_init(&priv->base.vram, rsvd_head, size,
......
...@@ -92,7 +92,8 @@ nv41_vmmgr_ctor(struct nouveau_object *parent, struct nouveau_object *engine, ...@@ -92,7 +92,8 @@ nv41_vmmgr_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
struct nv04_vmmgr_priv *priv; struct nv04_vmmgr_priv *priv;
int ret; int ret;
if (!nouveau_boolopt(device->cfgopt, "NvPCIE", true)) { if (pci_find_capability(device->pdev, PCI_CAP_ID_AGP) ||
!nouveau_boolopt(device->cfgopt, "NvPCIE", true)) {
return nouveau_object_ctor(parent, engine, &nv04_vmmgr_oclass, return nouveau_object_ctor(parent, engine, &nv04_vmmgr_oclass,
data, size, pobject); data, size, pobject);
} }
......
...@@ -163,7 +163,8 @@ nv44_vmmgr_ctor(struct nouveau_object *parent, struct nouveau_object *engine, ...@@ -163,7 +163,8 @@ nv44_vmmgr_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
struct nv04_vmmgr_priv *priv; struct nv04_vmmgr_priv *priv;
int ret; int ret;
if (!nouveau_boolopt(device->cfgopt, "NvPCIE", true)) { if (pci_find_capability(device->pdev, PCI_CAP_ID_AGP) ||
!nouveau_boolopt(device->cfgopt, "NvPCIE", true)) {
return nouveau_object_ctor(parent, engine, &nv04_vmmgr_oclass, return nouveau_object_ctor(parent, engine, &nv04_vmmgr_oclass,
data, size, pobject); data, size, pobject);
} }
......
...@@ -530,9 +530,11 @@ nouveau_page_flip_reserve(struct nouveau_bo *old_bo, ...@@ -530,9 +530,11 @@ nouveau_page_flip_reserve(struct nouveau_bo *old_bo,
if (ret) if (ret)
goto fail; goto fail;
ret = ttm_bo_reserve(&old_bo->bo, false, false, false, 0); if (likely(old_bo != new_bo)) {
if (ret) ret = ttm_bo_reserve(&old_bo->bo, false, false, false, 0);
goto fail_unreserve; if (ret)
goto fail_unreserve;
}
return 0; return 0;
...@@ -551,8 +553,10 @@ nouveau_page_flip_unreserve(struct nouveau_bo *old_bo, ...@@ -551,8 +553,10 @@ nouveau_page_flip_unreserve(struct nouveau_bo *old_bo,
nouveau_bo_fence(new_bo, fence); nouveau_bo_fence(new_bo, fence);
ttm_bo_unreserve(&new_bo->bo); ttm_bo_unreserve(&new_bo->bo);
nouveau_bo_fence(old_bo, fence); if (likely(old_bo != new_bo)) {
ttm_bo_unreserve(&old_bo->bo); nouveau_bo_fence(old_bo, fence);
ttm_bo_unreserve(&old_bo->bo);
}
nouveau_bo_unpin(old_bo); nouveau_bo_unpin(old_bo);
} }
......
...@@ -201,6 +201,8 @@ static int shmob_drm_load(struct drm_device *dev, unsigned long flags) ...@@ -201,6 +201,8 @@ static int shmob_drm_load(struct drm_device *dev, unsigned long flags)
goto done; goto done;
} }
platform_set_drvdata(pdev, sdev);
done: done:
if (ret) if (ret)
shmob_drm_unload(dev); shmob_drm_unload(dev);
...@@ -299,11 +301,9 @@ static struct drm_driver shmob_drm_driver = { ...@@ -299,11 +301,9 @@ static struct drm_driver shmob_drm_driver = {
#if CONFIG_PM_SLEEP #if CONFIG_PM_SLEEP
static int shmob_drm_pm_suspend(struct device *dev) static int shmob_drm_pm_suspend(struct device *dev)
{ {
struct platform_device *pdev = to_platform_device(dev); struct shmob_drm_device *sdev = dev_get_drvdata(dev);
struct drm_device *ddev = platform_get_drvdata(pdev);
struct shmob_drm_device *sdev = ddev->dev_private;
drm_kms_helper_poll_disable(ddev); drm_kms_helper_poll_disable(sdev->ddev);
shmob_drm_crtc_suspend(&sdev->crtc); shmob_drm_crtc_suspend(&sdev->crtc);
return 0; return 0;
...@@ -311,9 +311,7 @@ static int shmob_drm_pm_suspend(struct device *dev) ...@@ -311,9 +311,7 @@ static int shmob_drm_pm_suspend(struct device *dev)
static int shmob_drm_pm_resume(struct device *dev) static int shmob_drm_pm_resume(struct device *dev)
{ {
struct platform_device *pdev = to_platform_device(dev); struct shmob_drm_device *sdev = dev_get_drvdata(dev);
struct drm_device *ddev = platform_get_drvdata(pdev);
struct shmob_drm_device *sdev = ddev->dev_private;
mutex_lock(&sdev->ddev->mode_config.mutex); mutex_lock(&sdev->ddev->mode_config.mutex);
shmob_drm_crtc_resume(&sdev->crtc); shmob_drm_crtc_resume(&sdev->crtc);
......
...@@ -580,6 +580,7 @@ static int ttm_bo_cleanup_refs(struct ttm_buffer_object *bo, ...@@ -580,6 +580,7 @@ static int ttm_bo_cleanup_refs(struct ttm_buffer_object *bo,
if (unlikely(ret != 0)) if (unlikely(ret != 0))
return ret; return ret;
retry_reserve:
spin_lock(&glob->lru_lock); spin_lock(&glob->lru_lock);
if (unlikely(list_empty(&bo->ddestroy))) { if (unlikely(list_empty(&bo->ddestroy))) {
...@@ -587,14 +588,20 @@ static int ttm_bo_cleanup_refs(struct ttm_buffer_object *bo, ...@@ -587,14 +588,20 @@ static int ttm_bo_cleanup_refs(struct ttm_buffer_object *bo,
return 0; return 0;
} }
ret = ttm_bo_reserve_locked(bo, interruptible, ret = ttm_bo_reserve_locked(bo, false, true, false, 0);
no_wait_reserve, false, 0);
if (unlikely(ret != 0)) { if (unlikely(ret == -EBUSY)) {
spin_unlock(&glob->lru_lock); spin_unlock(&glob->lru_lock);
return ret; if (likely(!no_wait_reserve))
ret = ttm_bo_wait_unreserved(bo, interruptible);
if (unlikely(ret != 0))
return ret;
goto retry_reserve;
} }
BUG_ON(ret != 0);
/** /**
* We can re-check for sync object without taking * We can re-check for sync object without taking
* the bo::lock since setting the sync object requires * the bo::lock since setting the sync object requires
...@@ -811,17 +818,14 @@ static int ttm_mem_evict_first(struct ttm_bo_device *bdev, ...@@ -811,17 +818,14 @@ static int ttm_mem_evict_first(struct ttm_bo_device *bdev,
no_wait_reserve, no_wait_gpu); no_wait_reserve, no_wait_gpu);
kref_put(&bo->list_kref, ttm_bo_release_list); kref_put(&bo->list_kref, ttm_bo_release_list);
if (likely(ret == 0 || ret == -ERESTARTSYS)) return ret;
return ret;
goto retry;
} }
ret = ttm_bo_reserve_locked(bo, false, no_wait_reserve, false, 0); ret = ttm_bo_reserve_locked(bo, false, true, false, 0);
if (unlikely(ret == -EBUSY)) { if (unlikely(ret == -EBUSY)) {
spin_unlock(&glob->lru_lock); spin_unlock(&glob->lru_lock);
if (likely(!no_wait_gpu)) if (likely(!no_wait_reserve))
ret = ttm_bo_wait_unreserved(bo, interruptible); ret = ttm_bo_wait_unreserved(bo, interruptible);
kref_put(&bo->list_kref, ttm_bo_release_list); kref_put(&bo->list_kref, ttm_bo_release_list);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment