Skip to content

Commit

Permalink
Merge branch 'drm-fixes' of git://people.freedesktop.org/~airlied/linux
Browse files Browse the repository at this point in the history
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"
  ...
  • Loading branch information
torvalds committed Oct 23, 2012
2 parents d888af9 + b8e902f commit 2d1f4c8
Show file tree
Hide file tree
Showing 21 changed files with 148 additions and 68 deletions.
4 changes: 2 additions & 2 deletions drivers/gpu/drm/drm_fb_cma_helper.c
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,7 @@ static int drm_fbdev_cma_create(struct drm_fb_helper *helper,
size_t size;
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_bpp);

Expand All @@ -220,7 +220,7 @@ static int drm_fbdev_cma_create(struct drm_fb_helper *helper,

size = mode_cmd.pitches[0] * mode_cmd.height;
obj = drm_gem_cma_create(dev, size);
if (!obj)
if (IS_ERR(obj))
return -ENOMEM;

fbi = framebuffer_alloc(0, dev->dev);
Expand Down
2 changes: 0 additions & 2 deletions drivers/gpu/drm/drm_info.c
Original file line number Diff line number Diff line change
Expand Up @@ -205,8 +205,6 @@ static int drm_gem_one_name_info(int id, void *ptr, void *data)
struct drm_gem_object *obj = ptr;
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",
obj->name, obj->size,
atomic_read(&obj->handle_count),
Expand Down
1 change: 0 additions & 1 deletion drivers/gpu/drm/drm_platform.c
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,6 @@ int drm_get_platform_dev(struct platform_device *platdev,
}

if (drm_core_check_feature(dev, DRIVER_MODESET)) {
dev_set_drvdata(&platdev->dev, dev);
ret = drm_get_minor(dev, &dev->control, DRM_MINOR_CONTROL);
if (ret)
goto err_g1;
Expand Down
13 changes: 13 additions & 0 deletions drivers/gpu/drm/i915/i915_drv.c
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,13 @@ module_param_named(i915_enable_ppgtt, i915_enable_ppgtt, int, 0600);
MODULE_PARM_DESC(i915_enable_ppgtt,
"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;
extern int intel_agp_enabled;

Expand Down Expand Up @@ -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 *) 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
* used function 1 as a placeholder for multi-head. This causes
* us confusion instead, especially on the systems where both
Expand Down
1 change: 1 addition & 0 deletions drivers/gpu/drm/i915/i915_drv.h
Original file line number Diff line number Diff line change
Expand Up @@ -1217,6 +1217,7 @@ extern int i915_enable_rc6 __read_mostly;
extern int i915_enable_fbc __read_mostly;
extern bool i915_enable_hangcheck __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_resume(struct drm_device *dev);
Expand Down
7 changes: 5 additions & 2 deletions drivers/gpu/drm/i915/i915_gem.c
Original file line number Diff line number Diff line change
Expand Up @@ -1407,8 +1407,10 @@ int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
return VM_FAULT_NOPAGE;
case -ENOMEM:
return VM_FAULT_OOM;
case -ENOSPC:
return VM_FAULT_SIGBUS;
default:
WARN_ON_ONCE(ret);
WARN_ONCE(ret, "unhandled error in i915_gem_fault: %i\n", ret);
return VM_FAULT_SIGBUS;
}
}
Expand Down Expand Up @@ -1822,10 +1824,11 @@ i915_gem_object_get_pages_gtt(struct drm_i915_gem_object *obj)
sg_set_page(sg, page, PAGE_SIZE, 0);
}

obj->pages = st;

if (i915_gem_object_needs_bit17_swizzle(obj))
i915_gem_object_do_bit_17_swizzle(obj);

obj->pages = st;
return 0;

err_pages:
Expand Down
15 changes: 1 addition & 14 deletions drivers/gpu/drm/i915/intel_crt.c
Original file line number Diff line number Diff line change
Expand Up @@ -219,20 +219,7 @@ static void intel_crt_mode_set(struct drm_encoder *encoder,
intel_encoder_to_crt(to_intel_encoder(encoder));
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
struct drm_i915_private *dev_priv = dev->dev_private;
int dpll_md_reg;
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);
}
u32 adpa;

adpa = ADPA_HOTPLUG_BITS;
if (adjusted_mode->flags & DRM_MODE_FLAG_PHSYNC)
Expand Down
32 changes: 32 additions & 0 deletions drivers/gpu/drm/i915/intel_display.c
Original file line number Diff line number Diff line change
Expand Up @@ -7892,6 +7892,34 @@ struct intel_quirk {
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[] = {
/* HP Mini needs pipe A force quirk (LP: #322104) */
{ 0x27ae, 0x103c, 0x361a, quirk_pipea_force },
Expand Down Expand Up @@ -7931,6 +7959,10 @@ static void intel_init_quirks(struct drm_device *dev)
q->subsystem_device == PCI_ANY_ID))
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 */
Expand Down
15 changes: 10 additions & 5 deletions drivers/gpu/drm/i915/intel_dp.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
break;
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");
break;
}
Expand All @@ -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 */
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
if ((intel_dp->train_set[0] & DP_TRAIN_VOLTAGE_SWING_MASK) == voltage) {
++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 */
intel_get_adjust_train(intel_dp, link_status);
Expand Down
8 changes: 8 additions & 0 deletions drivers/gpu/drm/i915/intel_lvds.c
Original file line number Diff line number Diff line change
Expand Up @@ -777,6 +777,14 @@ static const struct dmi_system_id intel_no_lvds[] = {
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 */
};
Expand Down
14 changes: 10 additions & 4 deletions drivers/gpu/drm/i915/intel_sdvo.c
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,11 @@ struct intel_sdvo {

/* DDC bus used by this SDVO encoder */
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 {
Expand Down Expand Up @@ -984,6 +989,7 @@ intel_sdvo_get_preferred_input_mode(struct intel_sdvo *intel_sdvo,
return false;

intel_sdvo_get_mode_from_dtd(adjusted_mode, &input_dtd);
intel_sdvo->dtd_sdvo_flags = input_dtd.part2.sdvo_flags;

return true;
}
Expand Down Expand Up @@ -1092,6 +1098,8 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder,
* 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))
DRM_INFO("Setting input timings on %s failed\n",
SDVO_NAME(intel_sdvo));
Expand Down Expand Up @@ -2277,10 +2285,8 @@ intel_sdvo_lvds_init(struct intel_sdvo *intel_sdvo, int device)
intel_sdvo_connector->output_flag = SDVO_OUTPUT_LVDS1;
}

/* SDVO LVDS is cloneable because the SDVO encoder does the upscaling,
* as opposed to native LVDS, where we upscale with the panel-fitter
* (and hence only the native LVDS resolution could be cloned). */
intel_sdvo->base.cloneable = true;
/* SDVO LVDS is not cloneable because the input mode gets adjusted by the encoder */
intel_sdvo->base.cloneable = false;

intel_sdvo_connector_init(intel_sdvo_connector, intel_sdvo);
if (!intel_sdvo_create_enhance_property(intel_sdvo, intel_sdvo_connector))
Expand Down
5 changes: 5 additions & 0 deletions drivers/gpu/drm/nouveau/core/core/gpuobj.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,11 @@ nouveau_gpuobj_destroy(struct nouveau_gpuobj *gpuobj)
nv_wo32(gpuobj, i, 0x00000000);
}

if (gpuobj->node) {
nouveau_mm_free(&nv_gpuobj(gpuobj->parent)->heap,
&gpuobj->node);
}

if (gpuobj->heap.block_size)
nouveau_mm_fini(&gpuobj->heap);

Expand Down
2 changes: 1 addition & 1 deletion drivers/gpu/drm/nouveau/core/core/mm.c
Original file line number Diff line number Diff line change
Expand Up @@ -236,7 +236,7 @@ nouveau_mm_fini(struct nouveau_mm *mm)
int nodes = 0;

list_for_each_entry(node, &mm->nodes, nl_entry) {
if (nodes++ == mm->heap_nodes)
if (WARN_ON(nodes++ == mm->heap_nodes))
return -EBUSY;
}

Expand Down
30 changes: 23 additions & 7 deletions drivers/gpu/drm/nouveau/core/subdev/bios/base.c
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ nouveau_bios_shadow_of(struct nouveau_bios *bios)
}

data = of_get_property(dn, "NVDA,BMP", &size);
if (data) {
if (data && size) {
bios->size = size;
bios->data = kmalloc(bios->size, GFP_KERNEL);
if (bios->data)
Expand Down Expand Up @@ -104,6 +104,9 @@ nouveau_bios_shadow_pramin(struct nouveau_bios *bios)
goto out;

bios->size = nv_rd08(bios, 0x700002) * 512;
if (!bios->size)
goto out;

bios->data = kmalloc(bios->size, GFP_KERNEL);
if (bios->data) {
for (i = 0; i < bios->size; i++)
Expand Down Expand Up @@ -155,6 +158,9 @@ nouveau_bios_shadow_prom(struct nouveau_bios *bios)

/* read entire bios image to system memory */
bios->size = nv_rd08(bios, 0x300002) * 512;
if (!bios->size)
goto out;

bios->data = kmalloc(bios->size, GFP_KERNEL);
if (bios->data) {
for (i = 0; i < bios->size; i++)
Expand Down Expand Up @@ -186,14 +192,22 @@ nouveau_bios_shadow_acpi(struct nouveau_bios *bios)
{
struct pci_dev *pdev = nv_device(bios)->pdev;
int ret, cnt, i;
u8 data[3];

if (!nouveau_acpi_rom_supported(pdev))
if (!nouveau_acpi_rom_supported(pdev)) {
bios->data = NULL;
return;
}

bios->size = 0;
if (nouveau_acpi_get_bios_chunk(data, 0, 3) == 3)
bios->size = data[2] * 512;
bios->data = kmalloc(4096, GFP_KERNEL);
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);
for (i = 0; bios->data && i < bios->size; i += cnt) {
Expand Down Expand Up @@ -229,12 +243,14 @@ nouveau_bios_shadow_pci(struct nouveau_bios *bios)
static int
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");
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");
/* if a ro image is somewhat bad, it's probably all rubbish */
return writeable ? 2 : 1;
Expand Down
10 changes: 4 additions & 6 deletions drivers/gpu/drm/nouveau/core/subdev/bios/pll.c
Original file line number Diff line number Diff line change
Expand Up @@ -157,11 +157,10 @@ pll_map_reg(struct nouveau_bios *bios, u32 reg, u32 *type, u8 *ver, u8 *len)
while (map->reg) {
if (map->reg == reg && *ver >= 0x20) {
u16 addr = (data += hdr);
*type = map->type;
while (cnt--) {
if (nv_ro32(bios, data) == map->reg) {
*type = map->type;
if (nv_ro32(bios, data) == map->reg)
return data;
}
data += *len;
}
return addr;
Expand Down Expand Up @@ -200,11 +199,10 @@ pll_map_type(struct nouveau_bios *bios, u8 type, u32 *reg, u8 *ver, u8 *len)
while (map->reg) {
if (map->type == type && *ver >= 0x20) {
u16 addr = (data += hdr);
*reg = map->reg;
while (cnt--) {
if (nv_ro32(bios, data) == map->reg) {
*reg = map->reg;
if (nv_ro32(bios, data) == map->reg)
return data;
}
data += *len;
}
return addr;
Expand Down
1 change: 1 addition & 0 deletions drivers/gpu/drm/nouveau/core/subdev/fb/nv50.c
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,7 @@ nv50_fb_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
return ret;

priv->base.ram.stolen = (u64)nv_rd32(priv, 0x100e10) << 12;
priv->base.ram.type = NV_MEM_TYPE_STOLEN;
break;
default:
ret = nouveau_mm_init(&priv->base.vram, rsvd_head, size,
Expand Down
3 changes: 2 additions & 1 deletion drivers/gpu/drm/nouveau/core/subdev/vm/nv41.c
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,8 @@ nv41_vmmgr_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
struct nv04_vmmgr_priv *priv;
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,
data, size, pobject);
}
Expand Down
3 changes: 2 additions & 1 deletion drivers/gpu/drm/nouveau/core/subdev/vm/nv44.c
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,8 @@ nv44_vmmgr_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
struct nv04_vmmgr_priv *priv;
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,
data, size, pobject);
}
Expand Down
Loading

0 comments on commit 2d1f4c8

Please sign in to comment.