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" ...
This commit is contained in:
commit
2d1f4c8e09
|
@ -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,
|
||||||
|
|
||||||
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)
|
||||||
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,
|
||||||
}
|
}
|
||||||
|
|
||||||
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);
|
||||||
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)
|
||||||
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;
|
||||||
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 @@ out:
|
||||||
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)
|
||||||
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,
|
||||||
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 {
|
||||||
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)
|
||||||
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)
|
||||||
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)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 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[] = {
|
||||||
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 {
|
||||||
|
|
||||||
/* 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,
|
||||||
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,
|
||||||
* 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)
|
||||||
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)
|
||||||
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)
|
||||||
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)
|
||||||
}
|
}
|
||||||
|
|
||||||
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)
|
||||||
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)
|
||||||
|
|
||||||
/* 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)
|
||||||
{
|
{
|
||||||
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)
|
||||||
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)
|
||||||
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)
|
||||||
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,
|
||||||
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,
|
||||||
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,
|
||||||
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,
|
||||||
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,
|
||||||
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)
|
||||||
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 = {
|
||||||
#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)
|
||||||
|
|
||||||
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 @@ retry:
|
||||||
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 @@ retry:
|
||||||
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 @@ retry:
|
||||||
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);
|
||||||
|
|
Loading…
Reference in New Issue