Kaynağa Gözat

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

Signed-off-by: Francisco Jerez <currojerez@riseup.net>
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Francisco Jerez 15 yıl önce
ebeveyn
işleme
c88c2e0631

+ 4 - 4
drivers/gpu/drm/nouveau/nouveau_drv.c

@@ -263,6 +263,9 @@ nouveau_pci_resume(struct pci_dev *pdev)
 	if (dev_priv->gart_info.type == NOUVEAU_GART_AGP)
 		nouveau_mem_reset_agp(dev);
 
+	/* Make the CRTCs accessible */
+	engine->display.early_init(dev);
+
 	NV_INFO(dev, "POSTing device...\n");
 	ret = nouveau_run_vbios_init(dev);
 	if (ret)
@@ -325,10 +328,7 @@ nouveau_pci_resume(struct pci_dev *pdev)
 			NV_ERROR(dev, "Could not pin/map cursor.\n");
 	}
 
-	if (dev_priv->card_type < NV_50)
-		nv04_display_restore(dev);
-	else
-		nv50_display_init(dev);
+	engine->display.init(dev);
 
 	list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
 		struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);

+ 12 - 1
drivers/gpu/drm/nouveau/nouveau_drv.h

@@ -351,6 +351,14 @@ struct nouveau_pgraph_engine {
 				  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_instmem_engine instmem;
 	struct nouveau_mc_engine      mc;
@@ -358,6 +366,7 @@ struct nouveau_engine {
 	struct nouveau_fb_engine      fb;
 	struct nouveau_pgraph_engine  graph;
 	struct nouveau_fifo_engine    fifo;
+	struct nouveau_display_engine display;
 };
 
 struct nouveau_pll_vals {
@@ -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 *);
 
 /* 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_init(struct drm_device *);
 extern void nv04_display_destroy(struct drm_device *);
-extern void nv04_display_restore(struct drm_device *);
 
 /* nv04_crtc.c */
 extern int nv04_crtc_create(struct drm_device *, int index);

+ 43 - 13
drivers/gpu/drm/nouveau/nouveau_state.c

@@ -84,6 +84,11 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev)
 		engine->fifo.destroy_context	= nv04_fifo_destroy_context;
 		engine->fifo.load_context	= nv04_fifo_load_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;
 	case 0x10:
 		engine->instmem.init		= nv04_instmem_init;
@@ -126,6 +131,11 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev)
 		engine->fifo.destroy_context	= nv10_fifo_destroy_context;
 		engine->fifo.load_context	= nv10_fifo_load_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;
 	case 0x20:
 		engine->instmem.init		= nv04_instmem_init;
@@ -168,6 +178,11 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev)
 		engine->fifo.destroy_context	= nv10_fifo_destroy_context;
 		engine->fifo.load_context	= nv10_fifo_load_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;
 	case 0x30:
 		engine->instmem.init		= nv04_instmem_init;
@@ -210,6 +225,11 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev)
 		engine->fifo.destroy_context	= nv10_fifo_destroy_context;
 		engine->fifo.load_context	= nv10_fifo_load_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;
 	case 0x40:
 	case 0x60:
@@ -253,6 +273,11 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev)
 		engine->fifo.destroy_context	= nv40_fifo_destroy_context;
 		engine->fifo.load_context	= nv40_fifo_load_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;
 	case 0x50:
 	case 0x80: /* gotta love NVIDIA's consistency.. */
@@ -297,6 +322,11 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev)
 		engine->fifo.destroy_context	= nv50_fifo_destroy_context;
 		engine->fifo.load_context	= nv50_fifo_load_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;
 	default:
 		NV_ERROR(dev, "NV%02x unsupported\n", dev_priv->chipset);
@@ -415,10 +445,15 @@ nouveau_card_init(struct drm_device *dev)
 	engine = &dev_priv->engine;
 	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 */
 	ret = nouveau_bios_init(dev);
 	if (ret)
-		goto out;
+		goto out_display_early;
 
 	ret = nouveau_mem_detect(dev);
 	if (ret)
@@ -474,10 +509,7 @@ nouveau_card_init(struct drm_device *dev)
 			goto out_graph;
 	}
 
-	if (dev_priv->card_type >= NV_50)
-		ret = nv50_display_create(dev);
-	else
-		ret = nv04_display_create(dev);
+	ret = engine->display.create(dev);
 	if (ret)
 		goto out_fifo;
 
@@ -511,10 +543,7 @@ nouveau_card_init(struct drm_device *dev)
 out_irq:
 	drm_irq_uninstall(dev);
 out_display:
-	if (dev_priv->card_type >= NV_50)
-		nv50_display_destroy(dev);
-	else
-		nv04_display_destroy(dev);
+	engine->display.destroy(dev);
 out_fifo:
 	if (!nouveau_noaccel)
 		engine->fifo.takedown(dev);
@@ -538,6 +567,8 @@ out_gpuobj_early:
 	nouveau_gpuobj_late_takedown(dev);
 out_bios:
 	nouveau_bios_takedown(dev);
+out_display_early:
+	engine->display.late_takedown(dev);
 out:
 	vga_client_register(dev->pdev, NULL, NULL, NULL);
 	return ret;
@@ -562,6 +593,7 @@ static void nouveau_card_takedown(struct drm_device *dev)
 	engine->fb.takedown(dev);
 	engine->timer.takedown(dev);
 	engine->mc.takedown(dev);
+	engine->display.late_takedown(dev);
 
 	mutex_lock(&dev->struct_mutex);
 	ttm_bo_clean_mm(&dev_priv->ttm.bdev, TTM_PL_VRAM);
@@ -798,13 +830,11 @@ void nouveau_lastclose(struct drm_device *dev)
 int nouveau_unload(struct drm_device *dev)
 {
 	struct drm_nouveau_private *dev_priv = dev->dev_private;
+	struct nouveau_engine *engine = &dev_priv->engine;
 
 	drm_kms_helper_poll_fini(dev);
 	nouveau_fbcon_fini(dev);
-	if (dev_priv->card_type >= NV_50)
-		nv50_display_destroy(dev);
-	else
-		nv04_display_destroy(dev);
+	engine->display.destroy(dev);
 	nouveau_card_takedown(dev);
 
 	iounmap(dev_priv->mmio);

+ 30 - 16
drivers/gpu/drm/nouveau/nv04_display.c

@@ -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
 nv04_display_create(struct drm_device *dev)
 {
@@ -87,13 +113,6 @@ nv04_display_create(struct drm_device *dev)
 
 	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);
 
 	drm_mode_config_init(dev);
@@ -176,7 +195,6 @@ nv04_display_create(struct drm_device *dev)
 void
 nv04_display_destroy(struct drm_device *dev)
 {
-	struct drm_nouveau_private *dev_priv = dev->dev_private;
 	struct drm_encoder *encoder;
 	struct drm_crtc *crtc;
 
@@ -204,20 +222,14 @@ nv04_display_destroy(struct drm_device *dev)
 	drm_mode_config_cleanup(dev);
 
 	nouveau_hw_save_vga_fonts(dev, 0);
-
-	if (nv_two_heads(dev))
-		NVSetOwner(dev, dev_priv->crtc_owner);
-	NVLockVgaCrtcs(dev, true);
 }
 
-void
-nv04_display_restore(struct drm_device *dev)
+int
+nv04_display_init(struct drm_device *dev)
 {
 	struct drm_encoder *encoder;
 	struct drm_crtc *crtc;
 
-	NVLockVgaCrtcs(dev, false);
-
 	/* meh.. modeset apparently doesn't setup all the regs and depends
 	 * on pre-existing state, for now load the state of the card *before*
 	 * nouveau was loaded, and then do a modeset.
@@ -234,5 +246,7 @@ nv04_display_restore(struct drm_device *dev)
 
 	list_for_each_entry(crtc, &dev->mode_config.crtc_list, head)
 		crtc->funcs->restore(crtc);
+
+	return 0;
 }
 

+ 13 - 3
drivers/gpu/drm/nouveau/nv50_display.c

@@ -177,6 +177,17 @@ nv50_evo_channel_new(struct drm_device *dev, struct nouveau_channel **pchan)
 	return 0;
 }
 
+int
+nv50_display_early_init(struct drm_device *dev)
+{
+	return 0;
+}
+
+void
+nv50_display_late_takedown(struct drm_device *dev)
+{
+}
+
 int
 nv50_display_init(struct drm_device *dev)
 {
@@ -528,7 +539,8 @@ int nv50_display_create(struct drm_device *dev)
 	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;
 
@@ -538,8 +550,6 @@ int nv50_display_destroy(struct drm_device *dev)
 
 	nv50_display_disable(dev);
 	nv50_evo_channel_del(&dev_priv->evo);
-
-	return 0;
 }
 
 static u16

+ 4 - 2
drivers/gpu/drm/nouveau/nv50_display.h

@@ -38,9 +38,11 @@
 void nv50_display_irq_handler(struct drm_device *dev);
 void nv50_display_irq_handler_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_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_set_clock(struct drm_device *, int head, int pclk);