Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/teigland/dlm
[sfrench/cifs-2.6.git] / drivers / gpu / drm / nouveau / nouveau_state.c
index 0bf79bf8e61acace38a13480da73c5b978a7f63c..ee3729e7823ba312001985790e54f4844610416d 100644 (file)
@@ -38,6 +38,7 @@
 #include "nv50_display.h"
 
 static void nouveau_stub_takedown(struct drm_device *dev) {}
+static int nouveau_stub_init(struct drm_device *dev) { return 0; }
 
 static int nouveau_init_engine_ptrs(struct drm_device *dev)
 {
@@ -84,6 +85,16 @@ 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;
+               engine->gpio.init               = nouveau_stub_init;
+               engine->gpio.takedown           = nouveau_stub_takedown;
+               engine->gpio.get                = NULL;
+               engine->gpio.set                = NULL;
+               engine->gpio.irq_enable         = NULL;
                break;
        case 0x10:
                engine->instmem.init            = nv04_instmem_init;
@@ -126,6 +137,16 @@ 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;
+               engine->gpio.init               = nouveau_stub_init;
+               engine->gpio.takedown           = nouveau_stub_takedown;
+               engine->gpio.get                = nv10_gpio_get;
+               engine->gpio.set                = nv10_gpio_set;
+               engine->gpio.irq_enable         = NULL;
                break;
        case 0x20:
                engine->instmem.init            = nv04_instmem_init;
@@ -168,6 +189,16 @@ 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;
+               engine->gpio.init               = nouveau_stub_init;
+               engine->gpio.takedown           = nouveau_stub_takedown;
+               engine->gpio.get                = nv10_gpio_get;
+               engine->gpio.set                = nv10_gpio_set;
+               engine->gpio.irq_enable         = NULL;
                break;
        case 0x30:
                engine->instmem.init            = nv04_instmem_init;
@@ -184,8 +215,8 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev)
                engine->timer.init              = nv04_timer_init;
                engine->timer.read              = nv04_timer_read;
                engine->timer.takedown          = nv04_timer_takedown;
-               engine->fb.init                 = nv10_fb_init;
-               engine->fb.takedown             = nv10_fb_takedown;
+               engine->fb.init                 = nv30_fb_init;
+               engine->fb.takedown             = nv30_fb_takedown;
                engine->fb.set_region_tiling    = nv10_fb_set_region_tiling;
                engine->graph.grclass           = nv30_graph_grclass;
                engine->graph.init              = nv30_graph_init;
@@ -210,6 +241,16 @@ 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;
+               engine->gpio.init               = nouveau_stub_init;
+               engine->gpio.takedown           = nouveau_stub_takedown;
+               engine->gpio.get                = nv10_gpio_get;
+               engine->gpio.set                = nv10_gpio_set;
+               engine->gpio.irq_enable         = NULL;
                break;
        case 0x40:
        case 0x60:
@@ -253,6 +294,16 @@ 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;
+               engine->gpio.init               = nouveau_stub_init;
+               engine->gpio.takedown           = nouveau_stub_takedown;
+               engine->gpio.get                = nv10_gpio_get;
+               engine->gpio.set                = nv10_gpio_set;
+               engine->gpio.irq_enable         = NULL;
                break;
        case 0x50:
        case 0x80: /* gotta love NVIDIA's consistency.. */
@@ -297,6 +348,16 @@ 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;
+               engine->gpio.init               = nv50_gpio_init;
+               engine->gpio.takedown           = nouveau_stub_takedown;
+               engine->gpio.get                = nv50_gpio_get;
+               engine->gpio.set                = nv50_gpio_set;
+               engine->gpio.irq_enable         = nv50_gpio_irq_enable;
                break;
        default:
                NV_ERROR(dev, "NV%02x unsupported\n", dev_priv->chipset);
@@ -415,10 +476,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)
@@ -450,10 +516,15 @@ nouveau_card_init(struct drm_device *dev)
        if (ret)
                goto out_gpuobj;
 
+       /* PGPIO */
+       ret = engine->gpio.init(dev);
+       if (ret)
+               goto out_mc;
+
        /* PTIMER */
        ret = engine->timer.init(dev);
        if (ret)
-               goto out_mc;
+               goto out_gpio;
 
        /* PFB */
        ret = engine->fb.init(dev);
@@ -474,10 +545,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 +579,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);
@@ -525,6 +590,8 @@ out_fb:
        engine->fb.takedown(dev);
 out_timer:
        engine->timer.takedown(dev);
+out_gpio:
+       engine->gpio.takedown(dev);
 out_mc:
        engine->mc.takedown(dev);
 out_gpuobj:
@@ -538,6 +605,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;
@@ -561,7 +630,9 @@ static void nouveau_card_takedown(struct drm_device *dev)
        }
        engine->fb.takedown(dev);
        engine->timer.takedown(dev);
+       engine->gpio.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 +869,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);