diff options
Diffstat (limited to 'drivers/gpu/drm/nouveau/nouveau_state.c')
-rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_state.c | 270 |
1 files changed, 100 insertions, 170 deletions
diff --git a/drivers/gpu/drm/nouveau/nouveau_state.c b/drivers/gpu/drm/nouveau/nouveau_state.c index c2a8511e855..19706f0532e 100644 --- a/drivers/gpu/drm/nouveau/nouveau_state.c +++ b/drivers/gpu/drm/nouveau/nouveau_state.c @@ -39,6 +39,9 @@ #include "nouveau_gpio.h" #include "nouveau_pm.h" #include "nv50_display.h" +#include "nouveau_fifo.h" +#include "nouveau_fence.h" +#include "nouveau_software.h" static void nouveau_stub_takedown(struct drm_device *dev) {} static int nouveau_stub_init(struct drm_device *dev) { return 0; } @@ -66,18 +69,6 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev) engine->timer.takedown = nv04_timer_takedown; engine->fb.init = nv04_fb_init; engine->fb.takedown = nv04_fb_takedown; - engine->fifo.channels = 16; - engine->fifo.init = nv04_fifo_init; - engine->fifo.takedown = nv04_fifo_fini; - engine->fifo.disable = nv04_fifo_disable; - engine->fifo.enable = nv04_fifo_enable; - engine->fifo.reassign = nv04_fifo_reassign; - engine->fifo.cache_pull = nv04_fifo_cache_pull; - engine->fifo.channel_id = nv04_fifo_channel_id; - engine->fifo.create_context = nv04_fifo_create_context; - 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; @@ -111,18 +102,6 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev) engine->fb.init_tile_region = nv10_fb_init_tile_region; engine->fb.set_tile_region = nv10_fb_set_tile_region; engine->fb.free_tile_region = nv10_fb_free_tile_region; - engine->fifo.channels = 32; - engine->fifo.init = nv10_fifo_init; - engine->fifo.takedown = nv04_fifo_fini; - engine->fifo.disable = nv04_fifo_disable; - engine->fifo.enable = nv04_fifo_enable; - engine->fifo.reassign = nv04_fifo_reassign; - engine->fifo.cache_pull = nv04_fifo_cache_pull; - engine->fifo.channel_id = nv10_fifo_channel_id; - engine->fifo.create_context = nv10_fifo_create_context; - engine->fifo.destroy_context = nv04_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; @@ -162,18 +141,6 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev) engine->fb.init_tile_region = nv20_fb_init_tile_region; engine->fb.set_tile_region = nv20_fb_set_tile_region; engine->fb.free_tile_region = nv20_fb_free_tile_region; - engine->fifo.channels = 32; - engine->fifo.init = nv10_fifo_init; - engine->fifo.takedown = nv04_fifo_fini; - engine->fifo.disable = nv04_fifo_disable; - engine->fifo.enable = nv04_fifo_enable; - engine->fifo.reassign = nv04_fifo_reassign; - engine->fifo.cache_pull = nv04_fifo_cache_pull; - engine->fifo.channel_id = nv10_fifo_channel_id; - engine->fifo.create_context = nv10_fifo_create_context; - engine->fifo.destroy_context = nv04_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; @@ -209,18 +176,6 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev) engine->fb.init_tile_region = nv30_fb_init_tile_region; engine->fb.set_tile_region = nv10_fb_set_tile_region; engine->fb.free_tile_region = nv30_fb_free_tile_region; - engine->fifo.channels = 32; - engine->fifo.init = nv10_fifo_init; - engine->fifo.takedown = nv04_fifo_fini; - engine->fifo.disable = nv04_fifo_disable; - engine->fifo.enable = nv04_fifo_enable; - engine->fifo.reassign = nv04_fifo_reassign; - engine->fifo.cache_pull = nv04_fifo_cache_pull; - engine->fifo.channel_id = nv10_fifo_channel_id; - engine->fifo.create_context = nv10_fifo_create_context; - engine->fifo.destroy_context = nv04_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; @@ -259,18 +214,6 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev) engine->fb.init_tile_region = nv30_fb_init_tile_region; engine->fb.set_tile_region = nv40_fb_set_tile_region; engine->fb.free_tile_region = nv30_fb_free_tile_region; - engine->fifo.channels = 32; - engine->fifo.init = nv40_fifo_init; - engine->fifo.takedown = nv04_fifo_fini; - engine->fifo.disable = nv04_fifo_disable; - engine->fifo.enable = nv04_fifo_enable; - engine->fifo.reassign = nv04_fifo_reassign; - engine->fifo.cache_pull = nv04_fifo_cache_pull; - engine->fifo.channel_id = nv10_fifo_channel_id; - engine->fifo.create_context = nv40_fifo_create_context; - engine->fifo.destroy_context = nv04_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; @@ -317,18 +260,6 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev) engine->timer.takedown = nv04_timer_takedown; engine->fb.init = nv50_fb_init; engine->fb.takedown = nv50_fb_takedown; - engine->fifo.channels = 128; - engine->fifo.init = nv50_fifo_init; - engine->fifo.takedown = nv50_fifo_takedown; - engine->fifo.disable = nv04_fifo_disable; - engine->fifo.enable = nv04_fifo_enable; - engine->fifo.reassign = nv04_fifo_reassign; - engine->fifo.channel_id = nv50_fifo_channel_id; - engine->fifo.create_context = nv50_fifo_create_context; - 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->fifo.tlb_flush = nv50_fifo_tlb_flush; engine->display.early_init = nv50_display_early_init; engine->display.late_takedown = nv50_display_late_takedown; engine->display.create = nv50_display_create; @@ -392,17 +323,6 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev) engine->timer.takedown = nv04_timer_takedown; engine->fb.init = nvc0_fb_init; engine->fb.takedown = nvc0_fb_takedown; - engine->fifo.channels = 128; - engine->fifo.init = nvc0_fifo_init; - engine->fifo.takedown = nvc0_fifo_takedown; - engine->fifo.disable = nvc0_fifo_disable; - engine->fifo.enable = nvc0_fifo_enable; - engine->fifo.reassign = nvc0_fifo_reassign; - engine->fifo.channel_id = nvc0_fifo_channel_id; - engine->fifo.create_context = nvc0_fifo_create_context; - engine->fifo.destroy_context = nvc0_fifo_destroy_context; - engine->fifo.load_context = nvc0_fifo_load_context; - engine->fifo.unload_context = nvc0_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; @@ -445,17 +365,6 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev) engine->timer.takedown = nv04_timer_takedown; engine->fb.init = nvc0_fb_init; engine->fb.takedown = nvc0_fb_takedown; - engine->fifo.channels = 128; - engine->fifo.init = nvc0_fifo_init; - engine->fifo.takedown = nvc0_fifo_takedown; - engine->fifo.disable = nvc0_fifo_disable; - engine->fifo.enable = nvc0_fifo_enable; - engine->fifo.reassign = nvc0_fifo_reassign; - engine->fifo.channel_id = nvc0_fifo_channel_id; - engine->fifo.create_context = nvc0_fifo_create_context; - engine->fifo.destroy_context = nvc0_fifo_destroy_context; - engine->fifo.load_context = nvc0_fifo_load_context; - engine->fifo.unload_context = nvc0_fifo_unload_context; engine->display.early_init = nouveau_stub_init; engine->display.late_takedown = nouveau_stub_takedown; engine->display.create = nvd0_display_create; @@ -496,13 +405,6 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev) engine->timer.takedown = nv04_timer_takedown; engine->fb.init = nvc0_fb_init; engine->fb.takedown = nvc0_fb_takedown; - engine->fifo.channels = 0; - engine->fifo.init = nouveau_stub_init; - engine->fifo.takedown = nouveau_stub_takedown; - engine->fifo.disable = nvc0_fifo_disable; - engine->fifo.enable = nvc0_fifo_enable; - engine->fifo.reassign = nvc0_fifo_reassign; - engine->fifo.unload_context = nouveau_stub_init; engine->display.early_init = nouveau_stub_init; engine->display.late_takedown = nouveau_stub_takedown; engine->display.create = nvd0_display_create; @@ -607,61 +509,24 @@ nouveau_card_channel_init(struct drm_device *dev) { struct drm_nouveau_private *dev_priv = dev->dev_private; struct nouveau_channel *chan; - int ret, oclass; + int ret; ret = nouveau_channel_alloc(dev, &chan, NULL, NvDmaFB, NvDmaTT); dev_priv->channel = chan; if (ret) return ret; - mutex_unlock(&dev_priv->channel->mutex); - if (dev_priv->card_type <= NV_50) { - if (dev_priv->card_type < NV_50) - oclass = 0x0039; - else - oclass = 0x5039; - - ret = nouveau_gpuobj_gr_new(chan, NvM2MF, oclass); - if (ret) - goto error; - - ret = nouveau_notifier_alloc(chan, NvNotify0, 32, 0xfe0, 0x1000, - &chan->m2mf_ntfy); - if (ret) - goto error; - - ret = RING_SPACE(chan, 6); - if (ret) - goto error; - - BEGIN_RING(chan, NvSubM2MF, NV_MEMORY_TO_MEMORY_FORMAT_NAME, 1); - OUT_RING (chan, NvM2MF); - BEGIN_RING(chan, NvSubM2MF, NV_MEMORY_TO_MEMORY_FORMAT_DMA_NOTIFY, 3); - OUT_RING (chan, NvNotify0); - OUT_RING (chan, chan->vram_handle); - OUT_RING (chan, chan->gart_handle); - } else - if (dev_priv->card_type <= NV_D0) { - ret = nouveau_gpuobj_gr_new(chan, 0x9039, 0x9039); - if (ret) - goto error; - - ret = RING_SPACE(chan, 2); - if (ret) - goto error; - - BEGIN_NVC0(chan, 2, NvSubM2MF, 0x0000, 1); - OUT_RING (chan, 0x00009039); - } - - FIRE_RING (chan); -error: - if (ret) - nouveau_card_channel_fini(dev); - return ret; + nouveau_bo_move_init(chan); + return 0; } +static const struct vga_switcheroo_client_ops nouveau_switcheroo_ops = { + .set_gpu_state = nouveau_switcheroo_set_state, + .reprobe = nouveau_switcheroo_reprobe, + .can_switch = nouveau_switcheroo_can_switch, +}; + int nouveau_card_init(struct drm_device *dev) { @@ -670,9 +535,7 @@ nouveau_card_init(struct drm_device *dev) int ret, e = 0; vga_client_register(dev->pdev, dev, NULL, nouveau_vga_set_decode); - vga_switcheroo_register_client(dev->pdev, nouveau_switcheroo_set_state, - nouveau_switcheroo_reprobe, - nouveau_switcheroo_can_switch); + vga_switcheroo_register_client(dev->pdev, &nouveau_switcheroo_ops); /* Initialise internal driver API hooks */ ret = nouveau_init_engine_ptrs(dev); @@ -745,6 +608,81 @@ nouveau_card_init(struct drm_device *dev) if (!dev_priv->noaccel) { switch (dev_priv->card_type) { case NV_04: + nv04_fifo_create(dev); + break; + case NV_10: + case NV_20: + case NV_30: + if (dev_priv->chipset < 0x17) + nv10_fifo_create(dev); + else + nv17_fifo_create(dev); + break; + case NV_40: + nv40_fifo_create(dev); + break; + case NV_50: + if (dev_priv->chipset == 0x50) + nv50_fifo_create(dev); + else + nv84_fifo_create(dev); + break; + case NV_C0: + case NV_D0: + nvc0_fifo_create(dev); + break; + case NV_E0: + nve0_fifo_create(dev); + break; + default: + break; + } + + switch (dev_priv->card_type) { + case NV_04: + nv04_fence_create(dev); + break; + case NV_10: + case NV_20: + case NV_30: + case NV_40: + case NV_50: + if (dev_priv->chipset < 0x84) + nv10_fence_create(dev); + else + nv84_fence_create(dev); + break; + case NV_C0: + case NV_D0: + case NV_E0: + nvc0_fence_create(dev); + break; + default: + break; + } + + switch (dev_priv->card_type) { + case NV_04: + case NV_10: + case NV_20: + case NV_30: + case NV_40: + nv04_software_create(dev); + break; + case NV_50: + nv50_software_create(dev); + break; + case NV_C0: + case NV_D0: + case NV_E0: + nvc0_software_create(dev); + break; + default: + break; + } + + switch (dev_priv->card_type) { + case NV_04: nv04_graph_create(dev); break; case NV_10: @@ -764,6 +702,9 @@ nouveau_card_init(struct drm_device *dev) case NV_D0: nvc0_graph_create(dev); break; + case NV_E0: + nve0_graph_create(dev); + break; default: break; } @@ -796,8 +737,9 @@ nouveau_card_init(struct drm_device *dev) } break; case NV_C0: - nvc0_copy_create(dev, 0); nvc0_copy_create(dev, 1); + case NV_D0: + nvc0_copy_create(dev, 0); break; default: break; @@ -830,16 +772,11 @@ nouveau_card_init(struct drm_device *dev) goto out_engine; } } - - /* PFIFO */ - ret = engine->fifo.init(dev); - if (ret) - goto out_engine; } ret = nouveau_irq_init(dev); if (ret) - goto out_fifo; + goto out_engine; ret = nouveau_display_create(dev); if (ret) @@ -848,14 +785,10 @@ nouveau_card_init(struct drm_device *dev) nouveau_backlight_init(dev); nouveau_pm_init(dev); - ret = nouveau_fence_init(dev); - if (ret) - goto out_pm; - if (dev_priv->eng[NVOBJ_ENGINE_GR]) { ret = nouveau_card_channel_init(dev); if (ret) - goto out_fence; + goto out_pm; } if (dev->mode_config.num_crtc) { @@ -870,17 +803,12 @@ nouveau_card_init(struct drm_device *dev) out_chan: nouveau_card_channel_fini(dev); -out_fence: - nouveau_fence_fini(dev); out_pm: nouveau_pm_fini(dev); nouveau_backlight_exit(dev); nouveau_display_destroy(dev); out_irq: nouveau_irq_fini(dev); -out_fifo: - if (!dev_priv->noaccel) - engine->fifo.takedown(dev); out_engine: if (!dev_priv->noaccel) { for (e = e - 1; e >= 0; e--) { @@ -912,6 +840,7 @@ out_bios: out_display_early: engine->display.late_takedown(dev); out: + vga_switcheroo_unregister_client(dev->pdev); vga_client_register(dev->pdev, NULL, NULL, NULL); return ret; } @@ -928,13 +857,11 @@ static void nouveau_card_takedown(struct drm_device *dev) } nouveau_card_channel_fini(dev); - nouveau_fence_fini(dev); nouveau_pm_fini(dev); nouveau_backlight_exit(dev); nouveau_display_destroy(dev); if (!dev_priv->noaccel) { - engine->fifo.takedown(dev); for (e = NVOBJ_ENGINE_NR - 1; e >= 0; e--) { if (dev_priv->eng[e]) { dev_priv->eng[e]->fini(dev, e, false); @@ -969,6 +896,7 @@ static void nouveau_card_takedown(struct drm_device *dev) nouveau_irq_fini(dev); + vga_switcheroo_unregister_client(dev->pdev); vga_client_register(dev->pdev, NULL, NULL, NULL); } @@ -1176,7 +1104,7 @@ int nouveau_load(struct drm_device *dev, unsigned long flags) goto err_priv; } - NV_INFO(dev, "Detected an NV%2x generation card (0x%08x)\n", + NV_INFO(dev, "Detected an NV%02x generation card (0x%08x)\n", dev_priv->card_type, reg0); /* map the mmio regs, limiting the amount to preserve vmap space */ @@ -1219,6 +1147,8 @@ int nouveau_load(struct drm_device *dev, unsigned long flags) if (nouveau_noaccel == -1) { switch (dev_priv->chipset) { case 0xd9: /* known broken */ + case 0xe4: /* needs binary driver firmware */ + case 0xe7: /* needs binary driver firmware */ NV_INFO(dev, "acceleration disabled by default, pass " "noaccel=0 to force enable\n"); dev_priv->noaccel = true; |