Commit 4936b172 authored by Dave Airlie's avatar Dave Airlie

Merge branch 'drm-nouveau-fixes' of...

Merge branch 'drm-nouveau-fixes' of git://people.freedesktop.org/git/nouveau/linux-2.6 into drm-fixes

This covers all known nouveau regressions at the moment, along with a fix
to not steal the console on headless GPUs.

* 'drm-nouveau-fixes' of git://people.freedesktop.org/git/nouveau/linux-2.6:
  drm/nouveau: headless mode by default if pci class != vga display
  drm/nouveau: resurrect headless mode since rework
  drm/nv50/fb: prevent oops on chipsets without compression tags
  drm/nouveau: allow creation of zero-sized mm
  drm/nouveau/i2c: fix typo when checking nvio i2c port validity
  drm/nouveau: silence modesetting spam on pre-gf8 chipsets
parents 8f0d8163 e412e95a
......@@ -218,13 +218,16 @@ nouveau_mm_init(struct nouveau_mm *mm, u32 offset, u32 length, u32 block)
node = kzalloc(sizeof(*node), GFP_KERNEL);
if (!node)
return -ENOMEM;
node->offset = roundup(offset, mm->block_size);
node->length = rounddown(offset + length, mm->block_size) - node->offset;
if (length) {
node->offset = roundup(offset, mm->block_size);
node->length = rounddown(offset + length, mm->block_size);
node->length -= node->offset;
}
list_add_tail(&node->nl_entry, &mm->nodes);
list_add_tail(&node->fl_entry, &mm->free);
mm->heap_nodes++;
mm->heap_size += length;
return 0;
}
......
......@@ -19,7 +19,6 @@ struct nouveau_mm {
u32 block_size;
int heap_nodes;
u32 heap_size;
};
int nouveau_mm_init(struct nouveau_mm *, u32 offset, u32 length, u32 block);
......
......@@ -219,13 +219,11 @@ nv50_fb_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
((priv->base.ram.size & 0x000000ff) << 32);
tags = nv_rd32(priv, 0x100320);
if (tags) {
ret = nouveau_mm_init(&priv->base.tags, 0, tags, 1);
if (ret)
return ret;
ret = nouveau_mm_init(&priv->base.tags, 0, tags, 1);
if (ret)
return ret;
nv_debug(priv, "%d compression tags\n", tags);
}
nv_debug(priv, "%d compression tags\n", tags);
size = (priv->base.ram.size >> 12) - rsvd_head - rsvd_tail;
switch (device->chipset) {
......
......@@ -292,7 +292,7 @@ nouveau_i2c_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
case DCB_I2C_NVIO_BIT:
port->drive = info.drive & 0x0f;
if (device->card_type < NV_D0) {
if (info.drive >= ARRAY_SIZE(nv50_i2c_port))
if (port->drive >= ARRAY_SIZE(nv50_i2c_port))
break;
port->drive = nv50_i2c_port[port->drive];
port->sense = port->drive;
......
......@@ -290,6 +290,7 @@ nouveau_display_create(struct drm_device *dev)
struct nouveau_drm *drm = nouveau_drm(dev);
struct nouveau_disp *pdisp = nouveau_disp(drm->device);
struct nouveau_display *disp;
u32 pclass = dev->pdev->class >> 8;
int ret, gen;
disp = drm->display = kzalloc(sizeof(*disp), GFP_KERNEL);
......@@ -360,23 +361,27 @@ nouveau_display_create(struct drm_device *dev)
drm_kms_helper_poll_init(dev);
drm_kms_helper_poll_disable(dev);
if (nv_device(drm->device)->card_type < NV_50)
ret = nv04_display_create(dev);
else
if (nv_device(drm->device)->card_type < NV_D0)
ret = nv50_display_create(dev);
else
ret = nvd0_display_create(dev);
if (ret)
goto disp_create_err;
if (dev->mode_config.num_crtc) {
ret = drm_vblank_init(dev, dev->mode_config.num_crtc);
if (nouveau_modeset == 1 ||
(nouveau_modeset < 0 && pclass == PCI_CLASS_DISPLAY_VGA)) {
if (nv_device(drm->device)->card_type < NV_50)
ret = nv04_display_create(dev);
else
if (nv_device(drm->device)->card_type < NV_D0)
ret = nv50_display_create(dev);
else
ret = nvd0_display_create(dev);
if (ret)
goto vblank_err;
goto disp_create_err;
if (dev->mode_config.num_crtc) {
ret = drm_vblank_init(dev, dev->mode_config.num_crtc);
if (ret)
goto vblank_err;
}
nouveau_backlight_init(dev);
}
nouveau_backlight_init(dev);
return 0;
vblank_err:
......@@ -395,7 +400,8 @@ nouveau_display_destroy(struct drm_device *dev)
nouveau_backlight_exit(dev);
drm_vblank_cleanup(dev);
disp->dtor(dev);
if (disp->dtor)
disp->dtor(dev);
drm_kms_helper_poll_fini(dev);
drm_mode_config_cleanup(dev);
......
......@@ -63,8 +63,9 @@ MODULE_PARM_DESC(noaccel, "disable kernel/abi16 acceleration");
static int nouveau_noaccel = 0;
module_param_named(noaccel, nouveau_noaccel, int, 0400);
MODULE_PARM_DESC(modeset, "enable driver");
static int nouveau_modeset = -1;
MODULE_PARM_DESC(modeset, "enable driver (default: auto, "
"0 = disabled, 1 = enabled, 2 = headless)");
int nouveau_modeset = -1;
module_param_named(modeset, nouveau_modeset, int, 0400);
static struct drm_driver driver;
......@@ -363,7 +364,8 @@ nouveau_drm_unload(struct drm_device *dev)
nouveau_pm_fini(dev);
nouveau_display_fini(dev);
if (dev->mode_config.num_crtc)
nouveau_display_fini(dev);
nouveau_display_destroy(dev);
nouveau_irq_fini(dev);
......@@ -403,13 +405,15 @@ nouveau_drm_suspend(struct pci_dev *pdev, pm_message_t pm_state)
pm_state.event == PM_EVENT_PRETHAW)
return 0;
NV_INFO(drm, "suspending fbcon...\n");
nouveau_fbcon_set_suspend(dev, 1);
if (dev->mode_config.num_crtc) {
NV_INFO(drm, "suspending fbcon...\n");
nouveau_fbcon_set_suspend(dev, 1);
NV_INFO(drm, "suspending display...\n");
ret = nouveau_display_suspend(dev);
if (ret)
return ret;
NV_INFO(drm, "suspending display...\n");
ret = nouveau_display_suspend(dev);
if (ret)
return ret;
}
NV_INFO(drm, "evicting buffers...\n");
ttm_bo_evict_mm(&drm->ttm.bdev, TTM_PL_VRAM);
......@@ -445,8 +449,10 @@ nouveau_drm_suspend(struct pci_dev *pdev, pm_message_t pm_state)
nouveau_client_init(&cli->base);
}
NV_INFO(drm, "resuming display...\n");
nouveau_display_resume(dev);
if (dev->mode_config.num_crtc) {
NV_INFO(drm, "resuming display...\n");
nouveau_display_resume(dev);
}
return ret;
}
......@@ -486,8 +492,10 @@ nouveau_drm_resume(struct pci_dev *pdev)
nouveau_irq_postinstall(dev);
nouveau_pm_resume(dev);
NV_INFO(drm, "resuming display...\n");
nouveau_display_resume(dev);
if (dev->mode_config.num_crtc) {
NV_INFO(drm, "resuming display...\n");
nouveau_display_resume(dev);
}
return 0;
}
......@@ -662,9 +670,7 @@ nouveau_drm_init(void)
#ifdef CONFIG_VGA_CONSOLE
if (vgacon_text_force())
nouveau_modeset = 0;
else
#endif
nouveau_modeset = 1;
}
if (!nouveau_modeset)
......
......@@ -141,4 +141,6 @@ int nouveau_drm_resume(struct pci_dev *);
nv_info((cli), fmt, ##args); \
} while (0)
extern int nouveau_modeset;
#endif
......@@ -61,13 +61,15 @@ nouveau_irq_handler(DRM_IRQ_ARGS)
nv_subdev(pmc)->intr(nv_subdev(pmc));
if (device->card_type >= NV_D0) {
if (nv_rd32(device, 0x000100) & 0x04000000)
nvd0_display_intr(dev);
} else
if (device->card_type >= NV_50) {
if (nv_rd32(device, 0x000100) & 0x04000000)
nv50_display_intr(dev);
if (dev->mode_config.num_crtc) {
if (device->card_type >= NV_D0) {
if (nv_rd32(device, 0x000100) & 0x04000000)
nvd0_display_intr(dev);
} else
if (device->card_type >= NV_50) {
if (nv_rd32(device, 0x000100) & 0x04000000)
nv50_display_intr(dev);
}
}
return IRQ_HANDLED;
......
......@@ -220,7 +220,7 @@ static enum drm_connector_status nv04_dac_detect(struct drm_encoder *encoder,
NVWriteVgaCrtc(dev, 0, NV_CIO_CR_MODE_INDEX, saved_cr_mode);
if (blue == 0x18) {
NV_INFO(drm, "Load detected on head A\n");
NV_DEBUG(drm, "Load detected on head A\n");
return connector_status_connected;
}
......@@ -338,8 +338,8 @@ nv17_dac_detect(struct drm_encoder *encoder, struct drm_connector *connector)
if (nv17_dac_sample_load(encoder) &
NV_PRAMDAC_TEST_CONTROL_SENSEB_ALLHI) {
NV_INFO(drm, "Load detected on output %c\n",
'@' + ffs(dcb->or));
NV_DEBUG(drm, "Load detected on output %c\n",
'@' + ffs(dcb->or));
return connector_status_connected;
} else {
return connector_status_disconnected;
......@@ -413,9 +413,9 @@ static void nv04_dac_commit(struct drm_encoder *encoder)
helper->dpms(encoder, DRM_MODE_DPMS_ON);
NV_INFO(drm, "Output %s is running on CRTC %d using output %c\n",
drm_get_connector_name(&nouveau_encoder_connector_get(nv_encoder)->base),
nv_crtc->index, '@' + ffs(nv_encoder->dcb->or));
NV_DEBUG(drm, "Output %s is running on CRTC %d using output %c\n",
drm_get_connector_name(&nouveau_encoder_connector_get(nv_encoder)->base),
nv_crtc->index, '@' + ffs(nv_encoder->dcb->or));
}
void nv04_dac_update_dacclk(struct drm_encoder *encoder, bool enable)
......@@ -461,8 +461,8 @@ static void nv04_dac_dpms(struct drm_encoder *encoder, int mode)
return;
nv_encoder->last_dpms = mode;
NV_INFO(drm, "Setting dpms mode %d on vga encoder (output %d)\n",
mode, nv_encoder->dcb->index);
NV_DEBUG(drm, "Setting dpms mode %d on vga encoder (output %d)\n",
mode, nv_encoder->dcb->index);
nv04_dac_update_dacclk(encoder, mode == DRM_MODE_DPMS_ON);
}
......
......@@ -476,9 +476,9 @@ static void nv04_dfp_commit(struct drm_encoder *encoder)
helper->dpms(encoder, DRM_MODE_DPMS_ON);
NV_INFO(drm, "Output %s is running on CRTC %d using output %c\n",
drm_get_connector_name(&nouveau_encoder_connector_get(nv_encoder)->base),
nv_crtc->index, '@' + ffs(nv_encoder->dcb->or));
NV_DEBUG(drm, "Output %s is running on CRTC %d using output %c\n",
drm_get_connector_name(&nouveau_encoder_connector_get(nv_encoder)->base),
nv_crtc->index, '@' + ffs(nv_encoder->dcb->or));
}
static void nv04_dfp_update_backlight(struct drm_encoder *encoder, int mode)
......@@ -520,8 +520,8 @@ static void nv04_lvds_dpms(struct drm_encoder *encoder, int mode)
return;
nv_encoder->last_dpms = mode;
NV_INFO(drm, "Setting dpms mode %d on lvds encoder (output %d)\n",
mode, nv_encoder->dcb->index);
NV_DEBUG(drm, "Setting dpms mode %d on lvds encoder (output %d)\n",
mode, nv_encoder->dcb->index);
if (was_powersaving && is_powersaving_dpms(mode))
return;
......@@ -565,8 +565,8 @@ static void nv04_tmds_dpms(struct drm_encoder *encoder, int mode)
return;
nv_encoder->last_dpms = mode;
NV_INFO(drm, "Setting dpms mode %d on tmds encoder (output %d)\n",
mode, nv_encoder->dcb->index);
NV_DEBUG(drm, "Setting dpms mode %d on tmds encoder (output %d)\n",
mode, nv_encoder->dcb->index);
nv04_dfp_update_backlight(encoder, mode);
nv04_dfp_update_fp_control(encoder, mode);
......
......@@ -75,8 +75,8 @@ static void nv04_tv_dpms(struct drm_encoder *encoder, int mode)
struct nv04_mode_state *state = &nv04_display(dev)->mode_reg;
uint8_t crtc1A;
NV_INFO(drm, "Setting dpms mode %d on TV encoder (output %d)\n",
mode, nv_encoder->dcb->index);
NV_DEBUG(drm, "Setting dpms mode %d on TV encoder (output %d)\n",
mode, nv_encoder->dcb->index);
state->pllsel &= ~(PLLSEL_TV_CRTC1_MASK | PLLSEL_TV_CRTC2_MASK);
......@@ -167,9 +167,8 @@ static void nv04_tv_commit(struct drm_encoder *encoder)
helper->dpms(encoder, DRM_MODE_DPMS_ON);
NV_INFO(drm, "Output %s is running on CRTC %d using output %c\n",
drm_get_connector_name(&nouveau_encoder_connector_get(nv_encoder)->base), nv_crtc->index,
'@' + ffs(nv_encoder->dcb->or));
NV_DEBUG(drm, "Output %s is running on CRTC %d using output %c\n",
drm_get_connector_name(&nouveau_encoder_connector_get(nv_encoder)->base), nv_crtc->index, '@' + ffs(nv_encoder->dcb->or));
}
static void nv04_tv_destroy(struct drm_encoder *encoder)
......
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