Commit c88c2e06 authored by Francisco Jerez's avatar Francisco Jerez Committed by Ben Skeggs

drm/nouveau: Move display init to a new nouveau_engine.

Signed-off-by: default avatarFrancisco Jerez <currojerez@riseup.net>
Signed-off-by: default avatarBen Skeggs <bskeggs@redhat.com>
parent f1feda70
...@@ -263,6 +263,9 @@ nouveau_pci_resume(struct pci_dev *pdev) ...@@ -263,6 +263,9 @@ nouveau_pci_resume(struct pci_dev *pdev)
if (dev_priv->gart_info.type == NOUVEAU_GART_AGP) if (dev_priv->gart_info.type == NOUVEAU_GART_AGP)
nouveau_mem_reset_agp(dev); nouveau_mem_reset_agp(dev);
/* Make the CRTCs accessible */
engine->display.early_init(dev);
NV_INFO(dev, "POSTing device...\n"); NV_INFO(dev, "POSTing device...\n");
ret = nouveau_run_vbios_init(dev); ret = nouveau_run_vbios_init(dev);
if (ret) if (ret)
...@@ -325,10 +328,7 @@ nouveau_pci_resume(struct pci_dev *pdev) ...@@ -325,10 +328,7 @@ nouveau_pci_resume(struct pci_dev *pdev)
NV_ERROR(dev, "Could not pin/map cursor.\n"); NV_ERROR(dev, "Could not pin/map cursor.\n");
} }
if (dev_priv->card_type < NV_50) engine->display.init(dev);
nv04_display_restore(dev);
else
nv50_display_init(dev);
list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
......
...@@ -351,6 +351,14 @@ struct nouveau_pgraph_engine { ...@@ -351,6 +351,14 @@ struct nouveau_pgraph_engine {
uint32_t size, uint32_t pitch); uint32_t size, uint32_t pitch);
}; };
struct nouveau_display_engine {
int (*early_init)(struct drm_device *);
void (*late_takedown)(struct drm_device *);
int (*create)(struct drm_device *);
int (*init)(struct drm_device *);
void (*destroy)(struct drm_device *);
};
struct nouveau_engine { struct nouveau_engine {
struct nouveau_instmem_engine instmem; struct nouveau_instmem_engine instmem;
struct nouveau_mc_engine mc; struct nouveau_mc_engine mc;
...@@ -358,6 +366,7 @@ struct nouveau_engine { ...@@ -358,6 +366,7 @@ struct nouveau_engine {
struct nouveau_fb_engine fb; struct nouveau_fb_engine fb;
struct nouveau_pgraph_engine graph; struct nouveau_pgraph_engine graph;
struct nouveau_fifo_engine fifo; struct nouveau_fifo_engine fifo;
struct nouveau_display_engine display;
}; };
struct nouveau_pll_vals { struct nouveau_pll_vals {
...@@ -1081,9 +1090,11 @@ extern int nv04_tv_create(struct drm_connector *, struct dcb_entry *); ...@@ -1081,9 +1090,11 @@ extern int nv04_tv_create(struct drm_connector *, struct dcb_entry *);
extern int nv17_tv_create(struct drm_connector *, struct dcb_entry *); extern int nv17_tv_create(struct drm_connector *, struct dcb_entry *);
/* nv04_display.c */ /* nv04_display.c */
extern int nv04_display_early_init(struct drm_device *);
extern void nv04_display_late_takedown(struct drm_device *);
extern int nv04_display_create(struct drm_device *); extern int nv04_display_create(struct drm_device *);
extern int nv04_display_init(struct drm_device *);
extern void nv04_display_destroy(struct drm_device *); extern void nv04_display_destroy(struct drm_device *);
extern void nv04_display_restore(struct drm_device *);
/* nv04_crtc.c */ /* nv04_crtc.c */
extern int nv04_crtc_create(struct drm_device *, int index); extern int nv04_crtc_create(struct drm_device *, int index);
......
...@@ -84,6 +84,11 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev) ...@@ -84,6 +84,11 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev)
engine->fifo.destroy_context = nv04_fifo_destroy_context; engine->fifo.destroy_context = nv04_fifo_destroy_context;
engine->fifo.load_context = nv04_fifo_load_context; engine->fifo.load_context = nv04_fifo_load_context;
engine->fifo.unload_context = nv04_fifo_unload_context; engine->fifo.unload_context = nv04_fifo_unload_context;
engine->display.early_init = nv04_display_early_init;
engine->display.late_takedown = nv04_display_late_takedown;
engine->display.create = nv04_display_create;
engine->display.init = nv04_display_init;
engine->display.destroy = nv04_display_destroy;
break; break;
case 0x10: case 0x10:
engine->instmem.init = nv04_instmem_init; engine->instmem.init = nv04_instmem_init;
...@@ -126,6 +131,11 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev) ...@@ -126,6 +131,11 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev)
engine->fifo.destroy_context = nv10_fifo_destroy_context; engine->fifo.destroy_context = nv10_fifo_destroy_context;
engine->fifo.load_context = nv10_fifo_load_context; engine->fifo.load_context = nv10_fifo_load_context;
engine->fifo.unload_context = nv10_fifo_unload_context; engine->fifo.unload_context = nv10_fifo_unload_context;
engine->display.early_init = nv04_display_early_init;
engine->display.late_takedown = nv04_display_late_takedown;
engine->display.create = nv04_display_create;
engine->display.init = nv04_display_init;
engine->display.destroy = nv04_display_destroy;
break; break;
case 0x20: case 0x20:
engine->instmem.init = nv04_instmem_init; engine->instmem.init = nv04_instmem_init;
...@@ -168,6 +178,11 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev) ...@@ -168,6 +178,11 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev)
engine->fifo.destroy_context = nv10_fifo_destroy_context; engine->fifo.destroy_context = nv10_fifo_destroy_context;
engine->fifo.load_context = nv10_fifo_load_context; engine->fifo.load_context = nv10_fifo_load_context;
engine->fifo.unload_context = nv10_fifo_unload_context; engine->fifo.unload_context = nv10_fifo_unload_context;
engine->display.early_init = nv04_display_early_init;
engine->display.late_takedown = nv04_display_late_takedown;
engine->display.create = nv04_display_create;
engine->display.init = nv04_display_init;
engine->display.destroy = nv04_display_destroy;
break; break;
case 0x30: case 0x30:
engine->instmem.init = nv04_instmem_init; engine->instmem.init = nv04_instmem_init;
...@@ -210,6 +225,11 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev) ...@@ -210,6 +225,11 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev)
engine->fifo.destroy_context = nv10_fifo_destroy_context; engine->fifo.destroy_context = nv10_fifo_destroy_context;
engine->fifo.load_context = nv10_fifo_load_context; engine->fifo.load_context = nv10_fifo_load_context;
engine->fifo.unload_context = nv10_fifo_unload_context; engine->fifo.unload_context = nv10_fifo_unload_context;
engine->display.early_init = nv04_display_early_init;
engine->display.late_takedown = nv04_display_late_takedown;
engine->display.create = nv04_display_create;
engine->display.init = nv04_display_init;
engine->display.destroy = nv04_display_destroy;
break; break;
case 0x40: case 0x40:
case 0x60: case 0x60:
...@@ -253,6 +273,11 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev) ...@@ -253,6 +273,11 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev)
engine->fifo.destroy_context = nv40_fifo_destroy_context; engine->fifo.destroy_context = nv40_fifo_destroy_context;
engine->fifo.load_context = nv40_fifo_load_context; engine->fifo.load_context = nv40_fifo_load_context;
engine->fifo.unload_context = nv40_fifo_unload_context; engine->fifo.unload_context = nv40_fifo_unload_context;
engine->display.early_init = nv04_display_early_init;
engine->display.late_takedown = nv04_display_late_takedown;
engine->display.create = nv04_display_create;
engine->display.init = nv04_display_init;
engine->display.destroy = nv04_display_destroy;
break; break;
case 0x50: case 0x50:
case 0x80: /* gotta love NVIDIA's consistency.. */ case 0x80: /* gotta love NVIDIA's consistency.. */
...@@ -297,6 +322,11 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev) ...@@ -297,6 +322,11 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev)
engine->fifo.destroy_context = nv50_fifo_destroy_context; engine->fifo.destroy_context = nv50_fifo_destroy_context;
engine->fifo.load_context = nv50_fifo_load_context; engine->fifo.load_context = nv50_fifo_load_context;
engine->fifo.unload_context = nv50_fifo_unload_context; engine->fifo.unload_context = nv50_fifo_unload_context;
engine->display.early_init = nv50_display_early_init;
engine->display.late_takedown = nv50_display_late_takedown;
engine->display.create = nv50_display_create;
engine->display.init = nv50_display_init;
engine->display.destroy = nv50_display_destroy;
break; break;
default: default:
NV_ERROR(dev, "NV%02x unsupported\n", dev_priv->chipset); NV_ERROR(dev, "NV%02x unsupported\n", dev_priv->chipset);
...@@ -415,10 +445,15 @@ nouveau_card_init(struct drm_device *dev) ...@@ -415,10 +445,15 @@ nouveau_card_init(struct drm_device *dev)
engine = &dev_priv->engine; engine = &dev_priv->engine;
spin_lock_init(&dev_priv->context_switch_lock); spin_lock_init(&dev_priv->context_switch_lock);
/* Make the CRTCs and I2C buses accessible */
ret = engine->display.early_init(dev);
if (ret)
goto out;
/* Parse BIOS tables / Run init tables if card not POSTed */ /* Parse BIOS tables / Run init tables if card not POSTed */
ret = nouveau_bios_init(dev); ret = nouveau_bios_init(dev);
if (ret) if (ret)
goto out; goto out_display_early;
ret = nouveau_mem_detect(dev); ret = nouveau_mem_detect(dev);
if (ret) if (ret)
...@@ -474,10 +509,7 @@ nouveau_card_init(struct drm_device *dev) ...@@ -474,10 +509,7 @@ nouveau_card_init(struct drm_device *dev)
goto out_graph; goto out_graph;
} }
if (dev_priv->card_type >= NV_50) ret = engine->display.create(dev);
ret = nv50_display_create(dev);
else
ret = nv04_display_create(dev);
if (ret) if (ret)
goto out_fifo; goto out_fifo;
...@@ -511,10 +543,7 @@ nouveau_card_init(struct drm_device *dev) ...@@ -511,10 +543,7 @@ nouveau_card_init(struct drm_device *dev)
out_irq: out_irq:
drm_irq_uninstall(dev); drm_irq_uninstall(dev);
out_display: out_display:
if (dev_priv->card_type >= NV_50) engine->display.destroy(dev);
nv50_display_destroy(dev);
else
nv04_display_destroy(dev);
out_fifo: out_fifo:
if (!nouveau_noaccel) if (!nouveau_noaccel)
engine->fifo.takedown(dev); engine->fifo.takedown(dev);
...@@ -538,6 +567,8 @@ nouveau_card_init(struct drm_device *dev) ...@@ -538,6 +567,8 @@ nouveau_card_init(struct drm_device *dev)
nouveau_gpuobj_late_takedown(dev); nouveau_gpuobj_late_takedown(dev);
out_bios: out_bios:
nouveau_bios_takedown(dev); nouveau_bios_takedown(dev);
out_display_early:
engine->display.late_takedown(dev);
out: out:
vga_client_register(dev->pdev, NULL, NULL, NULL); vga_client_register(dev->pdev, NULL, NULL, NULL);
return ret; return ret;
...@@ -562,6 +593,7 @@ static void nouveau_card_takedown(struct drm_device *dev) ...@@ -562,6 +593,7 @@ static void nouveau_card_takedown(struct drm_device *dev)
engine->fb.takedown(dev); engine->fb.takedown(dev);
engine->timer.takedown(dev); engine->timer.takedown(dev);
engine->mc.takedown(dev); engine->mc.takedown(dev);
engine->display.late_takedown(dev);
mutex_lock(&dev->struct_mutex); mutex_lock(&dev->struct_mutex);
ttm_bo_clean_mm(&dev_priv->ttm.bdev, TTM_PL_VRAM); ttm_bo_clean_mm(&dev_priv->ttm.bdev, TTM_PL_VRAM);
...@@ -798,13 +830,11 @@ void nouveau_lastclose(struct drm_device *dev) ...@@ -798,13 +830,11 @@ void nouveau_lastclose(struct drm_device *dev)
int nouveau_unload(struct drm_device *dev) int nouveau_unload(struct drm_device *dev)
{ {
struct drm_nouveau_private *dev_priv = dev->dev_private; struct drm_nouveau_private *dev_priv = dev->dev_private;
struct nouveau_engine *engine = &dev_priv->engine;
drm_kms_helper_poll_fini(dev); drm_kms_helper_poll_fini(dev);
nouveau_fbcon_fini(dev); nouveau_fbcon_fini(dev);
if (dev_priv->card_type >= NV_50) engine->display.destroy(dev);
nv50_display_destroy(dev);
else
nv04_display_destroy(dev);
nouveau_card_takedown(dev); nouveau_card_takedown(dev);
iounmap(dev_priv->mmio); iounmap(dev_priv->mmio);
......
...@@ -75,6 +75,32 @@ nv04_display_store_initial_head_owner(struct drm_device *dev) ...@@ -75,6 +75,32 @@ nv04_display_store_initial_head_owner(struct drm_device *dev)
} }
} }
int
nv04_display_early_init(struct drm_device *dev)
{
/* Unlock the VGA CRTCs. */
NVLockVgaCrtcs(dev, false);
/* Make sure the CRTCs aren't in slaved mode. */
if (nv_two_heads(dev)) {
nv04_display_store_initial_head_owner(dev);
NVSetOwner(dev, 0);
}
return 0;
}
void
nv04_display_late_takedown(struct drm_device *dev)
{
struct drm_nouveau_private *dev_priv = dev->dev_private;
if (nv_two_heads(dev))
NVSetOwner(dev, dev_priv->crtc_owner);
NVLockVgaCrtcs(dev, true);
}
int int
nv04_display_create(struct drm_device *dev) nv04_display_create(struct drm_device *dev)
{ {
...@@ -87,13 +113,6 @@ nv04_display_create(struct drm_device *dev) ...@@ -87,13 +113,6 @@ nv04_display_create(struct drm_device *dev)
NV_DEBUG_KMS(dev, "\n"); NV_DEBUG_KMS(dev, "\n");
NVLockVgaCrtcs(dev, false);
if (nv_two_heads(dev)) {
nv04_display_store_initial_head_owner(dev);
NVSetOwner(dev, 0);
}
nouveau_hw_save_vga_fonts(dev, 1); nouveau_hw_save_vga_fonts(dev, 1);
drm_mode_config_init(dev); drm_mode_config_init(dev);
...@@ -176,7 +195,6 @@ nv04_display_create(struct drm_device *dev) ...@@ -176,7 +195,6 @@ nv04_display_create(struct drm_device *dev)
void void
nv04_display_destroy(struct drm_device *dev) nv04_display_destroy(struct drm_device *dev)
{ {
struct drm_nouveau_private *dev_priv = dev->dev_private;
struct drm_encoder *encoder; struct drm_encoder *encoder;
struct drm_crtc *crtc; struct drm_crtc *crtc;
...@@ -204,20 +222,14 @@ nv04_display_destroy(struct drm_device *dev) ...@@ -204,20 +222,14 @@ nv04_display_destroy(struct drm_device *dev)
drm_mode_config_cleanup(dev); drm_mode_config_cleanup(dev);
nouveau_hw_save_vga_fonts(dev, 0); nouveau_hw_save_vga_fonts(dev, 0);
if (nv_two_heads(dev))
NVSetOwner(dev, dev_priv->crtc_owner);
NVLockVgaCrtcs(dev, true);
} }
void int
nv04_display_restore(struct drm_device *dev) nv04_display_init(struct drm_device *dev)
{ {
struct drm_encoder *encoder; struct drm_encoder *encoder;
struct drm_crtc *crtc; struct drm_crtc *crtc;
NVLockVgaCrtcs(dev, false);
/* meh.. modeset apparently doesn't setup all the regs and depends /* meh.. modeset apparently doesn't setup all the regs and depends
* on pre-existing state, for now load the state of the card *before* * on pre-existing state, for now load the state of the card *before*
* nouveau was loaded, and then do a modeset. * nouveau was loaded, and then do a modeset.
...@@ -234,5 +246,7 @@ nv04_display_restore(struct drm_device *dev) ...@@ -234,5 +246,7 @@ nv04_display_restore(struct drm_device *dev)
list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) list_for_each_entry(crtc, &dev->mode_config.crtc_list, head)
crtc->funcs->restore(crtc); crtc->funcs->restore(crtc);
return 0;
} }
...@@ -177,6 +177,17 @@ nv50_evo_channel_new(struct drm_device *dev, struct nouveau_channel **pchan) ...@@ -177,6 +177,17 @@ nv50_evo_channel_new(struct drm_device *dev, struct nouveau_channel **pchan)
return 0; return 0;
} }
int
nv50_display_early_init(struct drm_device *dev)
{
return 0;
}
void
nv50_display_late_takedown(struct drm_device *dev)
{
}
int int
nv50_display_init(struct drm_device *dev) nv50_display_init(struct drm_device *dev)
{ {
...@@ -528,7 +539,8 @@ int nv50_display_create(struct drm_device *dev) ...@@ -528,7 +539,8 @@ int nv50_display_create(struct drm_device *dev)
return 0; return 0;
} }
int nv50_display_destroy(struct drm_device *dev) void
nv50_display_destroy(struct drm_device *dev)
{ {
struct drm_nouveau_private *dev_priv = dev->dev_private; struct drm_nouveau_private *dev_priv = dev->dev_private;
...@@ -538,8 +550,6 @@ int nv50_display_destroy(struct drm_device *dev) ...@@ -538,8 +550,6 @@ int nv50_display_destroy(struct drm_device *dev)
nv50_display_disable(dev); nv50_display_disable(dev);
nv50_evo_channel_del(&dev_priv->evo); nv50_evo_channel_del(&dev_priv->evo);
return 0;
} }
static u16 static u16
......
...@@ -38,9 +38,11 @@ ...@@ -38,9 +38,11 @@
void nv50_display_irq_handler(struct drm_device *dev); void nv50_display_irq_handler(struct drm_device *dev);
void nv50_display_irq_handler_bh(struct work_struct *work); void nv50_display_irq_handler_bh(struct work_struct *work);
void nv50_display_irq_hotplug_bh(struct work_struct *work); void nv50_display_irq_hotplug_bh(struct work_struct *work);
int nv50_display_init(struct drm_device *dev); int nv50_display_early_init(struct drm_device *dev);
void nv50_display_late_takedown(struct drm_device *dev);
int nv50_display_create(struct drm_device *dev); int nv50_display_create(struct drm_device *dev);
int nv50_display_destroy(struct drm_device *dev); int nv50_display_init(struct drm_device *dev);
void nv50_display_destroy(struct drm_device *dev);
int nv50_crtc_blank(struct nouveau_crtc *, bool blank); int nv50_crtc_blank(struct nouveau_crtc *, bool blank);
int nv50_crtc_set_clock(struct drm_device *, int head, int pclk); int nv50_crtc_set_clock(struct drm_device *, int head, int pclk);
......
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