diff options
Diffstat (limited to 'drivers/gpu/drm/nouveau/nouveau_state.c')
-rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_state.c | 123 |
1 files changed, 79 insertions, 44 deletions
diff --git a/drivers/gpu/drm/nouveau/nouveau_state.c b/drivers/gpu/drm/nouveau/nouveau_state.c index 989322be372..ed7757f1408 100644 --- a/drivers/gpu/drm/nouveau/nouveau_state.c +++ b/drivers/gpu/drm/nouveau/nouveau_state.c @@ -35,6 +35,8 @@ #include "nouveau_drv.h" #include "nouveau_drm.h" #include "nouveau_fbcon.h" +#include "nouveau_ramht.h" +#include "nouveau_pm.h" #include "nv50_display.h" static void nouveau_stub_takedown(struct drm_device *dev) {} @@ -78,7 +80,6 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev) engine->fifo.disable = nv04_fifo_disable; engine->fifo.enable = nv04_fifo_enable; engine->fifo.reassign = nv04_fifo_reassign; - engine->fifo.cache_flush = nv04_fifo_cache_flush; engine->fifo.cache_pull = nv04_fifo_cache_pull; engine->fifo.channel_id = nv04_fifo_channel_id; engine->fifo.create_context = nv04_fifo_create_context; @@ -95,6 +96,9 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev) 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; break; case 0x10: engine->instmem.init = nv04_instmem_init; @@ -130,7 +134,6 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev) engine->fifo.disable = nv04_fifo_disable; engine->fifo.enable = nv04_fifo_enable; engine->fifo.reassign = nv04_fifo_reassign; - engine->fifo.cache_flush = nv04_fifo_cache_flush; engine->fifo.cache_pull = nv04_fifo_cache_pull; engine->fifo.channel_id = nv10_fifo_channel_id; engine->fifo.create_context = nv10_fifo_create_context; @@ -147,6 +150,9 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev) 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; break; case 0x20: engine->instmem.init = nv04_instmem_init; @@ -182,7 +188,6 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev) engine->fifo.disable = nv04_fifo_disable; engine->fifo.enable = nv04_fifo_enable; engine->fifo.reassign = nv04_fifo_reassign; - engine->fifo.cache_flush = nv04_fifo_cache_flush; engine->fifo.cache_pull = nv04_fifo_cache_pull; engine->fifo.channel_id = nv10_fifo_channel_id; engine->fifo.create_context = nv10_fifo_create_context; @@ -199,6 +204,9 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev) 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; break; case 0x30: engine->instmem.init = nv04_instmem_init; @@ -234,7 +242,6 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev) engine->fifo.disable = nv04_fifo_disable; engine->fifo.enable = nv04_fifo_enable; engine->fifo.reassign = nv04_fifo_reassign; - engine->fifo.cache_flush = nv04_fifo_cache_flush; engine->fifo.cache_pull = nv04_fifo_cache_pull; engine->fifo.channel_id = nv10_fifo_channel_id; engine->fifo.create_context = nv10_fifo_create_context; @@ -251,6 +258,11 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev) 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->pm.voltage_get = nouveau_voltage_gpio_get; + engine->pm.voltage_set = nouveau_voltage_gpio_set; break; case 0x40: case 0x60: @@ -287,7 +299,6 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev) engine->fifo.disable = nv04_fifo_disable; engine->fifo.enable = nv04_fifo_enable; engine->fifo.reassign = nv04_fifo_reassign; - engine->fifo.cache_flush = nv04_fifo_cache_flush; engine->fifo.cache_pull = nv04_fifo_cache_pull; engine->fifo.channel_id = nv10_fifo_channel_id; engine->fifo.create_context = nv40_fifo_create_context; @@ -304,6 +315,12 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev) 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->pm.voltage_get = nouveau_voltage_gpio_get; + engine->pm.voltage_set = nouveau_voltage_gpio_set; + engine->pm.temp_get = nv40_temp_get; break; case 0x50: case 0x80: /* gotta love NVIDIA's consistency.. */ @@ -358,6 +375,27 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev) engine->gpio.get = nv50_gpio_get; engine->gpio.set = nv50_gpio_set; engine->gpio.irq_enable = nv50_gpio_irq_enable; + switch (dev_priv->chipset) { + case 0xa3: + case 0xa5: + case 0xa8: + case 0xaf: + engine->pm.clock_get = nva3_pm_clock_get; + engine->pm.clock_pre = nva3_pm_clock_pre; + engine->pm.clock_set = nva3_pm_clock_set; + break; + default: + engine->pm.clock_get = nv50_pm_clock_get; + engine->pm.clock_pre = nv50_pm_clock_pre; + engine->pm.clock_set = nv50_pm_clock_set; + break; + } + engine->pm.voltage_get = nouveau_voltage_gpio_get; + engine->pm.voltage_set = nouveau_voltage_gpio_set; + if (dev_priv->chipset >= 0x84) + engine->pm.temp_get = nv84_temp_get; + else + engine->pm.temp_get = nv40_temp_get; break; case 0xC0: engine->instmem.init = nvc0_instmem_init; @@ -437,16 +475,14 @@ static int nouveau_card_init_channel(struct drm_device *dev) { struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_gpuobj *gpuobj; + struct nouveau_gpuobj *gpuobj = NULL; int ret; ret = nouveau_channel_alloc(dev, &dev_priv->channel, - (struct drm_file *)-2, - NvDmaFB, NvDmaTT); + (struct drm_file *)-2, NvDmaFB, NvDmaTT); if (ret) return ret; - gpuobj = NULL; ret = nouveau_gpuobj_dma_new(dev_priv->channel, NV_CLASS_DMA_IN_MEMORY, 0, dev_priv->vram_size, NV_DMA_ACCESS_RW, NV_DMA_TARGET_VIDMEM, @@ -454,26 +490,25 @@ nouveau_card_init_channel(struct drm_device *dev) if (ret) goto out_err; - ret = nouveau_gpuobj_ref_add(dev, dev_priv->channel, NvDmaVRAM, - gpuobj, NULL); + ret = nouveau_ramht_insert(dev_priv->channel, NvDmaVRAM, gpuobj); + nouveau_gpuobj_ref(NULL, &gpuobj); if (ret) goto out_err; - gpuobj = NULL; ret = nouveau_gpuobj_gart_dma_new(dev_priv->channel, 0, dev_priv->gart_info.aper_size, NV_DMA_ACCESS_RW, &gpuobj, NULL); if (ret) goto out_err; - ret = nouveau_gpuobj_ref_add(dev, dev_priv->channel, NvDmaGART, - gpuobj, NULL); + ret = nouveau_ramht_insert(dev_priv->channel, NvDmaGART, gpuobj); + nouveau_gpuobj_ref(NULL, &gpuobj); if (ret) goto out_err; return 0; + out_err: - nouveau_gpuobj_del(dev, &gpuobj); nouveau_channel_free(dev_priv->channel); dev_priv->channel = NULL; return ret; @@ -534,35 +569,28 @@ nouveau_card_init(struct drm_device *dev) if (ret) goto out_display_early; - ret = nouveau_mem_detect(dev); + nouveau_pm_init(dev); + + ret = nouveau_mem_vram_init(dev); if (ret) goto out_bios; - ret = nouveau_gpuobj_early_init(dev); + ret = nouveau_gpuobj_init(dev); if (ret) - goto out_bios; + goto out_vram; - /* Initialise instance memory, must happen before mem_init so we - * know exactly how much VRAM we're able to use for "normal" - * purposes. - */ ret = engine->instmem.init(dev); if (ret) - goto out_gpuobj_early; + goto out_gpuobj; - /* Setup the memory manager */ - ret = nouveau_mem_init(dev); + ret = nouveau_mem_gart_init(dev); if (ret) goto out_instmem; - ret = nouveau_gpuobj_init(dev); - if (ret) - goto out_mem; - /* PMC */ ret = engine->mc.init(dev); if (ret) - goto out_gpuobj; + goto out_gart; /* PGPIO */ ret = engine->gpio.init(dev); @@ -611,9 +639,13 @@ nouveau_card_init(struct drm_device *dev) /* what about PVIDEO/PCRTC/PRAMDAC etc? */ if (!engine->graph.accel_blocked) { - ret = nouveau_card_init_channel(dev); + ret = nouveau_fence_init(dev); if (ret) goto out_irq; + + ret = nouveau_card_init_channel(dev); + if (ret) + goto out_fence; } ret = nouveau_backlight_init(dev); @@ -624,6 +656,8 @@ nouveau_card_init(struct drm_device *dev) drm_kms_helper_poll_init(dev); return 0; +out_fence: + nouveau_fence_fini(dev); out_irq: drm_irq_uninstall(dev); out_display: @@ -642,16 +676,16 @@ out_gpio: engine->gpio.takedown(dev); out_mc: engine->mc.takedown(dev); -out_gpuobj: - nouveau_gpuobj_takedown(dev); -out_mem: - nouveau_sgdma_takedown(dev); - nouveau_mem_close(dev); +out_gart: + nouveau_mem_gart_fini(dev); out_instmem: engine->instmem.takedown(dev); -out_gpuobj_early: - nouveau_gpuobj_late_takedown(dev); +out_gpuobj: + nouveau_gpuobj_takedown(dev); +out_vram: + nouveau_mem_vram_fini(dev); out_bios: + nouveau_pm_fini(dev); nouveau_bios_takedown(dev); out_display_early: engine->display.late_takedown(dev); @@ -667,7 +701,8 @@ static void nouveau_card_takedown(struct drm_device *dev) nouveau_backlight_exit(dev); - if (dev_priv->channel) { + if (!engine->graph.accel_blocked) { + nouveau_fence_fini(dev); nouveau_channel_free(dev_priv->channel); dev_priv->channel = NULL; } @@ -686,15 +721,15 @@ static void nouveau_card_takedown(struct drm_device *dev) ttm_bo_clean_mm(&dev_priv->ttm.bdev, TTM_PL_VRAM); ttm_bo_clean_mm(&dev_priv->ttm.bdev, TTM_PL_TT); mutex_unlock(&dev->struct_mutex); - nouveau_sgdma_takedown(dev); + nouveau_mem_gart_fini(dev); - nouveau_gpuobj_takedown(dev); - nouveau_mem_close(dev); engine->instmem.takedown(dev); + nouveau_gpuobj_takedown(dev); + nouveau_mem_vram_fini(dev); drm_irq_uninstall(dev); - nouveau_gpuobj_late_takedown(dev); + nouveau_pm_fini(dev); nouveau_bios_takedown(dev); vga_client_register(dev->pdev, NULL, NULL, NULL); @@ -1057,7 +1092,7 @@ bool nouveau_wait_until(struct drm_device *dev, uint64_t timeout, /* Waits for PGRAPH to go completely idle */ bool nouveau_wait_for_idle(struct drm_device *dev) { - if (!nv_wait(NV04_PGRAPH_STATUS, 0xffffffff, 0x00000000)) { + if (!nv_wait(dev, NV04_PGRAPH_STATUS, 0xffffffff, 0x00000000)) { NV_ERROR(dev, "PGRAPH idle timed out with status 0x%08x\n", nv_rd32(dev, NV04_PGRAPH_STATUS)); return false; |