drm/nvc0/pm: initial engine reclocking
[firefly-linux-kernel-4.4.55.git] / drivers / gpu / drm / nouveau / nouveau_state.c
index d8831ab42bb90344a28b8a146624aa4aca69d8c5..f5e98910d17faf6b80bcd64f49d9c8909896b6a7 100644 (file)
@@ -36,6 +36,7 @@
 #include "nouveau_drm.h"
 #include "nouveau_fbcon.h"
 #include "nouveau_ramht.h"
+#include "nouveau_gpio.h"
 #include "nouveau_pm.h"
 #include "nv50_display.h"
 
@@ -80,16 +81,12 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev)
                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;
-               engine->pm.clock_get            = nv04_pm_clock_get;
-               engine->pm.clock_pre            = nv04_pm_clock_pre;
-               engine->pm.clock_set            = nv04_pm_clock_set;
+               engine->display.init            = nv04_display_init;
+               engine->display.fini            = nv04_display_fini;
+               engine->pm.clocks_get           = nv04_pm_clocks_get;
+               engine->pm.clocks_pre           = nv04_pm_clocks_pre;
+               engine->pm.clocks_set           = nv04_pm_clocks_set;
                engine->vram.init               = nouveau_mem_detect;
                engine->vram.takedown           = nouveau_stub_takedown;
                engine->vram.flags_valid        = nouveau_mem_flags_valid;
@@ -129,16 +126,14 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev)
                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;
-               engine->pm.clock_get            = nv04_pm_clock_get;
-               engine->pm.clock_pre            = nv04_pm_clock_pre;
-               engine->pm.clock_set            = nv04_pm_clock_set;
+               engine->display.init            = nv04_display_init;
+               engine->display.fini            = nv04_display_fini;
+               engine->gpio.drive              = nv10_gpio_drive;
+               engine->gpio.sense              = nv10_gpio_sense;
+               engine->pm.clocks_get           = nv04_pm_clocks_get;
+               engine->pm.clocks_pre           = nv04_pm_clocks_pre;
+               engine->pm.clocks_set           = nv04_pm_clocks_set;
                engine->vram.init               = nouveau_mem_detect;
                engine->vram.takedown           = nouveau_stub_takedown;
                engine->vram.flags_valid        = nouveau_mem_flags_valid;
@@ -178,16 +173,14 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev)
                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;
-               engine->pm.clock_get            = nv04_pm_clock_get;
-               engine->pm.clock_pre            = nv04_pm_clock_pre;
-               engine->pm.clock_set            = nv04_pm_clock_set;
+               engine->display.init            = nv04_display_init;
+               engine->display.fini            = nv04_display_fini;
+               engine->gpio.drive              = nv10_gpio_drive;
+               engine->gpio.sense              = nv10_gpio_sense;
+               engine->pm.clocks_get           = nv04_pm_clocks_get;
+               engine->pm.clocks_pre           = nv04_pm_clocks_pre;
+               engine->pm.clocks_set           = nv04_pm_clocks_set;
                engine->vram.init               = nouveau_mem_detect;
                engine->vram.takedown           = nouveau_stub_takedown;
                engine->vram.flags_valid        = nouveau_mem_flags_valid;
@@ -227,16 +220,14 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev)
                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;
-               engine->pm.clock_get            = nv04_pm_clock_get;
-               engine->pm.clock_pre            = nv04_pm_clock_pre;
-               engine->pm.clock_set            = nv04_pm_clock_set;
+               engine->display.init            = nv04_display_init;
+               engine->display.fini            = nv04_display_fini;
+               engine->gpio.drive              = nv10_gpio_drive;
+               engine->gpio.sense              = nv10_gpio_sense;
+               engine->pm.clocks_get           = nv04_pm_clocks_get;
+               engine->pm.clocks_pre           = nv04_pm_clocks_pre;
+               engine->pm.clocks_set           = nv04_pm_clocks_set;
                engine->pm.voltage_get          = nouveau_voltage_gpio_get;
                engine->pm.voltage_set          = nouveau_voltage_gpio_set;
                engine->vram.init               = nouveau_mem_detect;
@@ -279,19 +270,22 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev)
                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;
+               engine->display.init            = nv04_display_init;
+               engine->display.fini            = nv04_display_fini;
+               engine->gpio.init               = nv10_gpio_init;
+               engine->gpio.fini               = nv10_gpio_fini;
+               engine->gpio.drive              = nv10_gpio_drive;
+               engine->gpio.sense              = nv10_gpio_sense;
+               engine->gpio.irq_enable         = nv10_gpio_irq_enable;
                engine->pm.clocks_get           = nv40_pm_clocks_get;
                engine->pm.clocks_pre           = nv40_pm_clocks_pre;
                engine->pm.clocks_set           = nv40_pm_clocks_set;
                engine->pm.voltage_get          = nouveau_voltage_gpio_get;
                engine->pm.voltage_set          = nouveau_voltage_gpio_set;
                engine->pm.temp_get             = nv40_temp_get;
+               engine->pm.pwm_get              = nv40_pm_pwm_get;
+               engine->pm.pwm_set              = nv40_pm_pwm_set;
                engine->vram.init               = nouveau_mem_detect;
                engine->vram.takedown           = nouveau_stub_takedown;
                engine->vram.flags_valid        = nouveau_mem_flags_valid;
@@ -334,14 +328,13 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev)
                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->display.init            = nv50_display_init;
+               engine->display.fini            = nv50_display_fini;
                engine->gpio.init               = nv50_gpio_init;
-               engine->gpio.takedown           = nv50_gpio_fini;
-               engine->gpio.get                = nv50_gpio_get;
-               engine->gpio.set                = nv50_gpio_set;
-               engine->gpio.irq_register       = nv50_gpio_irq_register;
-               engine->gpio.irq_unregister     = nv50_gpio_irq_unregister;
+               engine->gpio.fini               = nv50_gpio_fini;
+               engine->gpio.drive              = nv50_gpio_drive;
+               engine->gpio.sense              = nv50_gpio_sense;
                engine->gpio.irq_enable         = nv50_gpio_irq_enable;
                switch (dev_priv->chipset) {
                case 0x84:
@@ -354,9 +347,9 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev)
                case 0xaa:
                case 0xac:
                case 0x50:
-                       engine->pm.clock_get    = nv50_pm_clock_get;
-                       engine->pm.clock_pre    = nv50_pm_clock_pre;
-                       engine->pm.clock_set    = nv50_pm_clock_set;
+                       engine->pm.clocks_get   = nv50_pm_clocks_get;
+                       engine->pm.clocks_pre   = nv50_pm_clocks_pre;
+                       engine->pm.clocks_set   = nv50_pm_clocks_set;
                        break;
                default:
                        engine->pm.clocks_get   = nva3_pm_clocks_get;
@@ -370,6 +363,8 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev)
                        engine->pm.temp_get     = nv84_temp_get;
                else
                        engine->pm.temp_get     = nv40_temp_get;
+               engine->pm.pwm_get              = nv50_pm_pwm_get;
+               engine->pm.pwm_set              = nv50_pm_pwm_set;
                engine->vram.init               = nv50_vram_init;
                engine->vram.takedown           = nv50_vram_fini;
                engine->vram.get                = nv50_vram_new;
@@ -407,14 +402,13 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev)
                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->display.init            = nv50_display_init;
+               engine->display.fini            = nv50_display_fini;
                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_register       = nv50_gpio_irq_register;
-               engine->gpio.irq_unregister     = nv50_gpio_irq_unregister;
+               engine->gpio.fini               = nv50_gpio_fini;
+               engine->gpio.drive              = nv50_gpio_drive;
+               engine->gpio.sense              = nv50_gpio_sense;
                engine->gpio.irq_enable         = nv50_gpio_irq_enable;
                engine->vram.init               = nvc0_vram_init;
                engine->vram.takedown           = nv50_vram_fini;
@@ -423,8 +417,12 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev)
                engine->vram.flags_valid        = nvc0_vram_flags_valid;
                engine->pm.temp_get             = nv84_temp_get;
                engine->pm.clocks_get           = nvc0_pm_clocks_get;
+               engine->pm.clocks_pre           = nvc0_pm_clocks_pre;
+               engine->pm.clocks_set           = nvc0_pm_clocks_set;
                engine->pm.voltage_get          = nouveau_voltage_gpio_get;
                engine->pm.voltage_set          = nouveau_voltage_gpio_set;
+               engine->pm.pwm_get              = nv50_pm_pwm_get;
+               engine->pm.pwm_set              = nv50_pm_pwm_set;
                break;
        case 0xd0:
                engine->instmem.init            = nvc0_instmem_init;
@@ -457,21 +455,23 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev)
                engine->display.early_init      = nouveau_stub_init;
                engine->display.late_takedown   = nouveau_stub_takedown;
                engine->display.create          = nvd0_display_create;
-               engine->display.init            = nvd0_display_init;
                engine->display.destroy         = nvd0_display_destroy;
+               engine->display.init            = nvd0_display_init;
+               engine->display.fini            = nvd0_display_fini;
                engine->gpio.init               = nv50_gpio_init;
-               engine->gpio.takedown           = nouveau_stub_takedown;
-               engine->gpio.get                = nvd0_gpio_get;
-               engine->gpio.set                = nvd0_gpio_set;
-               engine->gpio.irq_register       = nv50_gpio_irq_register;
-               engine->gpio.irq_unregister     = nv50_gpio_irq_unregister;
+               engine->gpio.fini               = nv50_gpio_fini;
+               engine->gpio.drive              = nvd0_gpio_drive;
+               engine->gpio.sense              = nvd0_gpio_sense;
                engine->gpio.irq_enable         = nv50_gpio_irq_enable;
                engine->vram.init               = nvc0_vram_init;
                engine->vram.takedown           = nv50_vram_fini;
                engine->vram.get                = nvc0_vram_new;
                engine->vram.put                = nv50_vram_del;
                engine->vram.flags_valid        = nvc0_vram_flags_valid;
+               engine->pm.temp_get             = nv84_temp_get;
                engine->pm.clocks_get           = nvc0_pm_clocks_get;
+               engine->pm.clocks_pre           = nvc0_pm_clocks_pre;
+               engine->pm.clocks_set           = nvc0_pm_clocks_set;
                engine->pm.voltage_get          = nouveau_voltage_gpio_get;
                engine->pm.voltage_set          = nouveau_voltage_gpio_set;
                break;
@@ -615,7 +615,7 @@ nouveau_card_init(struct drm_device *dev)
                goto out_gart;
 
        /* PGPIO */
-       ret = engine->gpio.init(dev);
+       ret = nouveau_gpio_create(dev);
        if (ret)
                goto out_mc;
 
@@ -648,6 +648,7 @@ nouveau_card_init(struct drm_device *dev)
                        nv50_graph_create(dev);
                        break;
                case NV_C0:
+               case NV_D0:
                        nvc0_graph_create(dev);
                        break;
                default:
@@ -663,6 +664,11 @@ nouveau_card_init(struct drm_device *dev)
                case 0xa0:
                        nv84_crypt_create(dev);
                        break;
+               case 0x98:
+               case 0xaa:
+               case 0xac:
+                       nv98_crypt_create(dev);
+                       break;
                }
 
                switch (dev_priv->card_type) {
@@ -684,15 +690,25 @@ nouveau_card_init(struct drm_device *dev)
                        break;
                }
 
+               if (dev_priv->chipset >= 0xa3 || dev_priv->chipset == 0x98) {
+                       nv84_bsp_create(dev);
+                       nv84_vp_create(dev);
+                       nv98_ppp_create(dev);
+               } else
+               if (dev_priv->chipset >= 0x84) {
+                       nv50_mpeg_create(dev);
+                       nv84_bsp_create(dev);
+                       nv84_vp_create(dev);
+               } else
+               if (dev_priv->chipset >= 0x50) {
+                       nv50_mpeg_create(dev);
+               } else
                if (dev_priv->card_type == NV_40 ||
                    dev_priv->chipset == 0x31 ||
                    dev_priv->chipset == 0x34 ||
-                   dev_priv->chipset == 0x36)
+                   dev_priv->chipset == 0x36) {
                        nv31_mpeg_create(dev);
-               else
-               if (dev_priv->card_type == NV_50 &&
-                   (dev_priv->chipset < 0x98 || dev_priv->chipset == 0xa0))
-                       nv50_mpeg_create(dev);
+               }
 
                for (e = 0; e < NVOBJ_ENGINE_NR; e++) {
                        if (dev_priv->eng[e]) {
@@ -712,27 +728,7 @@ nouveau_card_init(struct drm_device *dev)
        if (ret)
                goto out_fifo;
 
-       /* initialise general modesetting */
-       drm_mode_config_init(dev);
-       drm_mode_create_scaling_mode_property(dev);
-       drm_mode_create_dithering_property(dev);
-       dev->mode_config.funcs = (void *)&nouveau_mode_config_funcs;
-       dev->mode_config.fb_base = pci_resource_start(dev->pdev, 1);
-       dev->mode_config.min_width = 0;
-       dev->mode_config.min_height = 0;
-       if (dev_priv->card_type < NV_10) {
-               dev->mode_config.max_width = 2048;
-               dev->mode_config.max_height = 2048;
-       } else
-       if (dev_priv->card_type < NV_50) {
-               dev->mode_config.max_width = 4096;
-               dev->mode_config.max_height = 4096;
-       } else {
-               dev->mode_config.max_width = 8192;
-               dev->mode_config.max_height = 8192;
-       }
-
-       ret = engine->display.create(dev);
+       ret = nouveau_display_create(dev);
        if (ret)
                goto out_irq;
 
@@ -752,12 +748,11 @@ nouveau_card_init(struct drm_device *dev)
        }
 
        if (dev->mode_config.num_crtc) {
-               ret = drm_vblank_init(dev, dev->mode_config.num_crtc);
+               ret = nouveau_display_init(dev);
                if (ret)
                        goto out_chan;
 
                nouveau_fbcon_init(dev);
-               drm_kms_helper_poll_init(dev);
        }
 
        return 0;
@@ -768,7 +763,7 @@ out_fence:
        nouveau_fence_fini(dev);
 out_disp:
        nouveau_backlight_exit(dev);
-       engine->display.destroy(dev);
+       nouveau_display_destroy(dev);
 out_irq:
        nouveau_irq_fini(dev);
 out_fifo:
@@ -788,7 +783,7 @@ out_engine:
 out_timer:
        engine->timer.takedown(dev);
 out_gpio:
-       engine->gpio.takedown(dev);
+       nouveau_gpio_destroy(dev);
 out_mc:
        engine->mc.takedown(dev);
 out_gart:
@@ -818,9 +813,8 @@ static void nouveau_card_takedown(struct drm_device *dev)
        int e;
 
        if (dev->mode_config.num_crtc) {
-               drm_kms_helper_poll_fini(dev);
                nouveau_fbcon_fini(dev);
-               drm_vblank_cleanup(dev);
+               nouveau_display_fini(dev);
        }
 
        if (dev_priv->channel) {
@@ -829,8 +823,7 @@ static void nouveau_card_takedown(struct drm_device *dev)
        }
 
        nouveau_backlight_exit(dev);
-       engine->display.destroy(dev);
-       drm_mode_config_cleanup(dev);
+       nouveau_display_destroy(dev);
 
        if (!dev_priv->noaccel) {
                engine->fifo.takedown(dev);
@@ -843,7 +836,7 @@ static void nouveau_card_takedown(struct drm_device *dev)
        }
        engine->fb.takedown(dev);
        engine->timer.takedown(dev);
-       engine->gpio.takedown(dev);
+       nouveau_gpio_destroy(dev);
        engine->mc.takedown(dev);
        engine->display.late_takedown(dev);
 
@@ -1110,13 +1103,11 @@ int nouveau_load(struct drm_device *dev, unsigned long flags)
        dev_priv->noaccel = !!nouveau_noaccel;
        if (nouveau_noaccel == -1) {
                switch (dev_priv->chipset) {
-#if 0
-               case 0xXX: /* known broken */
+               case 0xd9: /* known broken */
                        NV_INFO(dev, "acceleration disabled by default, pass "
                                     "noaccel=0 to force enable\n");
                        dev_priv->noaccel = true;
                        break;
-#endif
                default:
                        dev_priv->noaccel = false;
                        break;
@@ -1238,7 +1229,7 @@ int nouveau_ioctl_getparam(struct drm_device *dev, void *data,
                getparam->value = 1;
                break;
        case NOUVEAU_GETPARAM_HAS_PAGEFLIP:
-               getparam->value = dev_priv->card_type < NV_D0;
+               getparam->value = 1;
                break;
        case NOUVEAU_GETPARAM_GRAPH_UNITS:
                /* NV40 and NV50 versions are quite different, but register