diff options
Diffstat (limited to 'drivers/gpu/drm/nouveau/nouveau_mem.c')
-rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_mem.c | 90 |
1 files changed, 19 insertions, 71 deletions
diff --git a/drivers/gpu/drm/nouveau/nouveau_mem.c b/drivers/gpu/drm/nouveau/nouveau_mem.c index 689d3e708057..4aea1c4c46ef 100644 --- a/drivers/gpu/drm/nouveau/nouveau_mem.c +++ b/drivers/gpu/drm/nouveau/nouveau_mem.c | |||
@@ -48,21 +48,21 @@ | |||
48 | 48 | ||
49 | static void | 49 | static void |
50 | nv10_mem_update_tile_region(struct drm_device *dev, | 50 | nv10_mem_update_tile_region(struct drm_device *dev, |
51 | struct nouveau_tile_reg *tile, uint32_t addr, | 51 | struct nouveau_tile_reg *tilereg, uint32_t addr, |
52 | uint32_t size, uint32_t pitch, uint32_t flags) | 52 | uint32_t size, uint32_t pitch, uint32_t flags) |
53 | { | 53 | { |
54 | struct drm_nouveau_private *dev_priv = dev->dev_private; | 54 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
55 | struct nouveau_fb_engine *pfb = &dev_priv->engine.fb; | 55 | int i = tilereg - dev_priv->tile.reg, j; |
56 | int i = tile - dev_priv->tile.reg, j; | 56 | struct nouveau_fb_tile *tile = nvfb_tile(dev, i); |
57 | unsigned long save; | 57 | unsigned long save; |
58 | 58 | ||
59 | nouveau_fence_unref(&tile->fence); | 59 | nouveau_fence_unref(&tilereg->fence); |
60 | 60 | ||
61 | if (tile->pitch) | 61 | if (tile->pitch) |
62 | pfb->free_tile_region(dev, i); | 62 | nvfb_tile_fini(dev, i); |
63 | 63 | ||
64 | if (pitch) | 64 | if (pitch) |
65 | pfb->init_tile_region(dev, i, addr, size, pitch, flags); | 65 | nvfb_tile_init(dev, i, addr, size, pitch, flags); |
66 | 66 | ||
67 | spin_lock_irqsave(&dev_priv->context_switch_lock, save); | 67 | spin_lock_irqsave(&dev_priv->context_switch_lock, save); |
68 | nv_wr32(dev, NV03_PFIFO_CACHES, 0); | 68 | nv_wr32(dev, NV03_PFIFO_CACHES, 0); |
@@ -70,7 +70,7 @@ nv10_mem_update_tile_region(struct drm_device *dev, | |||
70 | 70 | ||
71 | nouveau_wait_for_idle(dev); | 71 | nouveau_wait_for_idle(dev); |
72 | 72 | ||
73 | pfb->set_tile_region(dev, i); | 73 | nvfb_tile_prog(dev, i); |
74 | for (j = 0; j < NVOBJ_ENGINE_NR; j++) { | 74 | for (j = 0; j < NVOBJ_ENGINE_NR; j++) { |
75 | if (dev_priv->eng[j] && dev_priv->eng[j]->set_tile_region) | 75 | if (dev_priv->eng[j] && dev_priv->eng[j]->set_tile_region) |
76 | dev_priv->eng[j]->set_tile_region(dev, i); | 76 | dev_priv->eng[j]->set_tile_region(dev, i); |
@@ -122,19 +122,17 @@ struct nouveau_tile_reg * | |||
122 | nv10_mem_set_tiling(struct drm_device *dev, uint32_t addr, uint32_t size, | 122 | nv10_mem_set_tiling(struct drm_device *dev, uint32_t addr, uint32_t size, |
123 | uint32_t pitch, uint32_t flags) | 123 | uint32_t pitch, uint32_t flags) |
124 | { | 124 | { |
125 | struct drm_nouveau_private *dev_priv = dev->dev_private; | ||
126 | struct nouveau_fb_engine *pfb = &dev_priv->engine.fb; | ||
127 | struct nouveau_tile_reg *tile, *found = NULL; | 125 | struct nouveau_tile_reg *tile, *found = NULL; |
128 | int i; | 126 | int i; |
129 | 127 | ||
130 | for (i = 0; i < pfb->num_tiles; i++) { | 128 | for (i = 0; i < nvfb_tile_nr(dev); i++) { |
131 | tile = nv10_mem_get_tile_region(dev, i); | 129 | tile = nv10_mem_get_tile_region(dev, i); |
132 | 130 | ||
133 | if (pitch && !found) { | 131 | if (pitch && !found) { |
134 | found = tile; | 132 | found = tile; |
135 | continue; | 133 | continue; |
136 | 134 | ||
137 | } else if (tile && tile->pitch) { | 135 | } else if (tile && nvfb_tile(dev, i)->pitch) { |
138 | /* Kill an unused tile region. */ | 136 | /* Kill an unused tile region. */ |
139 | nv10_mem_update_tile_region(dev, tile, 0, 0, 0, 0); | 137 | nv10_mem_update_tile_region(dev, tile, 0, 0, 0, 0); |
140 | } | 138 | } |
@@ -174,38 +172,11 @@ nouveau_mem_gart_fini(struct drm_device *dev) | |||
174 | nouveau_sgdma_takedown(dev); | 172 | nouveau_sgdma_takedown(dev); |
175 | } | 173 | } |
176 | 174 | ||
177 | bool | ||
178 | nouveau_mem_flags_valid(struct drm_device *dev, u32 tile_flags) | ||
179 | { | ||
180 | if (!(tile_flags & NOUVEAU_GEM_TILE_LAYOUT_MASK)) | ||
181 | return true; | ||
182 | |||
183 | return false; | ||
184 | } | ||
185 | |||
186 | static const struct vram_types { | ||
187 | int value; | ||
188 | const char *name; | ||
189 | } vram_type_map[] = { | ||
190 | { NV_MEM_TYPE_STOLEN , "stolen system memory" }, | ||
191 | { NV_MEM_TYPE_SGRAM , "SGRAM" }, | ||
192 | { NV_MEM_TYPE_SDRAM , "SDRAM" }, | ||
193 | { NV_MEM_TYPE_DDR1 , "DDR1" }, | ||
194 | { NV_MEM_TYPE_DDR2 , "DDR2" }, | ||
195 | { NV_MEM_TYPE_DDR3 , "DDR3" }, | ||
196 | { NV_MEM_TYPE_GDDR2 , "GDDR2" }, | ||
197 | { NV_MEM_TYPE_GDDR3 , "GDDR3" }, | ||
198 | { NV_MEM_TYPE_GDDR4 , "GDDR4" }, | ||
199 | { NV_MEM_TYPE_GDDR5 , "GDDR5" }, | ||
200 | { NV_MEM_TYPE_UNKNOWN, "unknown type" } | ||
201 | }; | ||
202 | |||
203 | int | 175 | int |
204 | nouveau_mem_vram_init(struct drm_device *dev) | 176 | nouveau_mem_vram_init(struct drm_device *dev) |
205 | { | 177 | { |
206 | struct drm_nouveau_private *dev_priv = dev->dev_private; | 178 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
207 | struct ttm_bo_device *bdev = &dev_priv->ttm.bdev; | 179 | struct ttm_bo_device *bdev = &dev_priv->ttm.bdev; |
208 | const struct vram_types *vram_type; | ||
209 | int ret, dma_bits; | 180 | int ret, dma_bits; |
210 | 181 | ||
211 | dma_bits = 32; | 182 | dma_bits = 32; |
@@ -243,27 +214,7 @@ nouveau_mem_vram_init(struct drm_device *dev) | |||
243 | return ret; | 214 | return ret; |
244 | } | 215 | } |
245 | 216 | ||
246 | vram_type = vram_type_map; | 217 | dev_priv->fb_available_size = nvfb_vram_size(dev); |
247 | while (vram_type->value != NV_MEM_TYPE_UNKNOWN) { | ||
248 | if (nouveau_vram_type) { | ||
249 | if (!strcasecmp(nouveau_vram_type, vram_type->name)) | ||
250 | break; | ||
251 | dev_priv->vram_type = vram_type->value; | ||
252 | } else { | ||
253 | if (vram_type->value == dev_priv->vram_type) | ||
254 | break; | ||
255 | } | ||
256 | vram_type++; | ||
257 | } | ||
258 | |||
259 | NV_INFO(dev, "Detected %dMiB VRAM (%s)\n", | ||
260 | (int)(dev_priv->vram_size >> 20), vram_type->name); | ||
261 | if (dev_priv->vram_sys_base) { | ||
262 | NV_INFO(dev, "Stolen system memory at: 0x%010llx\n", | ||
263 | dev_priv->vram_sys_base); | ||
264 | } | ||
265 | |||
266 | dev_priv->fb_available_size = dev_priv->vram_size; | ||
267 | dev_priv->fb_mappable_pages = dev_priv->fb_available_size; | 218 | dev_priv->fb_mappable_pages = dev_priv->fb_available_size; |
268 | if (dev_priv->fb_mappable_pages > pci_resource_len(dev->pdev, 1)) | 219 | if (dev_priv->fb_mappable_pages > pci_resource_len(dev->pdev, 1)) |
269 | dev_priv->fb_mappable_pages = pci_resource_len(dev->pdev, 1); | 220 | dev_priv->fb_mappable_pages = pci_resource_len(dev->pdev, 1); |
@@ -364,7 +315,6 @@ nv50_mem_timing_calc(struct drm_device *dev, u32 freq, | |||
364 | struct nouveau_pm_memtiming *boot, | 315 | struct nouveau_pm_memtiming *boot, |
365 | struct nouveau_pm_memtiming *t) | 316 | struct nouveau_pm_memtiming *t) |
366 | { | 317 | { |
367 | struct drm_nouveau_private *dev_priv = dev->dev_private; | ||
368 | struct bit_entry P; | 318 | struct bit_entry P; |
369 | uint8_t unk18 = 1, unk20 = 0, unk21 = 0, tmp7_3; | 319 | uint8_t unk18 = 1, unk20 = 0, unk21 = 0, tmp7_3; |
370 | 320 | ||
@@ -418,7 +368,7 @@ nv50_mem_timing_calc(struct drm_device *dev, u32 freq, | |||
418 | t->reg[7] = 0x4000202 | (e->tCL - 1) << 16; | 368 | t->reg[7] = 0x4000202 | (e->tCL - 1) << 16; |
419 | 369 | ||
420 | /* XXX: P.version == 1 only has DDR2 and GDDR3? */ | 370 | /* XXX: P.version == 1 only has DDR2 and GDDR3? */ |
421 | if (dev_priv->vram_type == NV_MEM_TYPE_DDR2) { | 371 | if (nvfb_vram_type(dev) == NV_MEM_TYPE_DDR2) { |
422 | t->reg[5] |= (e->tCL + 3) << 8; | 372 | t->reg[5] |= (e->tCL + 3) << 8; |
423 | t->reg[6] |= (t->tCWL - 2) << 8; | 373 | t->reg[6] |= (t->tCWL - 2) << 8; |
424 | t->reg[8] |= (e->tCL - 4); | 374 | t->reg[8] |= (e->tCL - 4); |
@@ -711,7 +661,7 @@ nouveau_mem_timing_calc(struct drm_device *dev, u32 freq, | |||
711 | break; | 661 | break; |
712 | } | 662 | } |
713 | 663 | ||
714 | switch (dev_priv->vram_type * !ret) { | 664 | switch (nvfb_vram_type(dev) * !ret) { |
715 | case NV_MEM_TYPE_GDDR3: | 665 | case NV_MEM_TYPE_GDDR3: |
716 | ret = nouveau_mem_gddr3_mr(dev, freq, e, len, boot, t); | 666 | ret = nouveau_mem_gddr3_mr(dev, freq, e, len, boot, t); |
717 | break; | 667 | break; |
@@ -738,7 +688,7 @@ nouveau_mem_timing_calc(struct drm_device *dev, u32 freq, | |||
738 | else | 688 | else |
739 | dll_off = !!(ramcfg[2] & 0x40); | 689 | dll_off = !!(ramcfg[2] & 0x40); |
740 | 690 | ||
741 | switch (dev_priv->vram_type) { | 691 | switch (nvfb_vram_type(dev)) { |
742 | case NV_MEM_TYPE_GDDR3: | 692 | case NV_MEM_TYPE_GDDR3: |
743 | t->mr[1] &= ~0x00000040; | 693 | t->mr[1] &= ~0x00000040; |
744 | t->mr[1] |= 0x00000040 * dll_off; | 694 | t->mr[1] |= 0x00000040 * dll_off; |
@@ -804,7 +754,7 @@ nouveau_mem_timing_read(struct drm_device *dev, struct nouveau_pm_memtiming *t) | |||
804 | t->odt = 0; | 754 | t->odt = 0; |
805 | t->drive_strength = 0; | 755 | t->drive_strength = 0; |
806 | 756 | ||
807 | switch (dev_priv->vram_type) { | 757 | switch (nvfb_vram_type(dev)) { |
808 | case NV_MEM_TYPE_DDR3: | 758 | case NV_MEM_TYPE_DDR3: |
809 | t->odt |= (t->mr[1] & 0x200) >> 7; | 759 | t->odt |= (t->mr[1] & 0x200) >> 7; |
810 | case NV_MEM_TYPE_DDR2: | 760 | case NV_MEM_TYPE_DDR2: |
@@ -831,7 +781,7 @@ nouveau_mem_exec(struct nouveau_mem_exec_func *exec, | |||
831 | u32 mr[3] = { info->mr[0], info->mr[1], info->mr[2] }; | 781 | u32 mr[3] = { info->mr[0], info->mr[1], info->mr[2] }; |
832 | u32 mr1_dlloff; | 782 | u32 mr1_dlloff; |
833 | 783 | ||
834 | switch (dev_priv->vram_type) { | 784 | switch (nvfb_vram_type(dev_priv->dev)) { |
835 | case NV_MEM_TYPE_DDR2: | 785 | case NV_MEM_TYPE_DDR2: |
836 | tDLLK = 2000; | 786 | tDLLK = 2000; |
837 | mr1_dlloff = 0x00000001; | 787 | mr1_dlloff = 0x00000001; |
@@ -852,7 +802,7 @@ nouveau_mem_exec(struct nouveau_mem_exec_func *exec, | |||
852 | } | 802 | } |
853 | 803 | ||
854 | /* fetch current MRs */ | 804 | /* fetch current MRs */ |
855 | switch (dev_priv->vram_type) { | 805 | switch (nvfb_vram_type(dev_priv->dev)) { |
856 | case NV_MEM_TYPE_GDDR3: | 806 | case NV_MEM_TYPE_GDDR3: |
857 | case NV_MEM_TYPE_DDR3: | 807 | case NV_MEM_TYPE_DDR3: |
858 | mr[2] = exec->mrg(exec, 2); | 808 | mr[2] = exec->mrg(exec, 2); |
@@ -919,7 +869,7 @@ nouveau_mem_exec(struct nouveau_mem_exec_func *exec, | |||
919 | exec->mrs (exec, 0, info->mr[0] | 0x00000000); | 869 | exec->mrs (exec, 0, info->mr[0] | 0x00000000); |
920 | exec->wait(exec, tMRD); | 870 | exec->wait(exec, tMRD); |
921 | exec->wait(exec, tDLLK); | 871 | exec->wait(exec, tDLLK); |
922 | if (dev_priv->vram_type == NV_MEM_TYPE_GDDR3) | 872 | if (nvfb_vram_type(dev_priv->dev) == NV_MEM_TYPE_GDDR3) |
923 | exec->precharge(exec); | 873 | exec->precharge(exec); |
924 | } | 874 | } |
925 | 875 | ||
@@ -982,11 +932,10 @@ nouveau_vram_manager_del(struct ttm_mem_type_manager *man, | |||
982 | struct ttm_mem_reg *mem) | 932 | struct ttm_mem_reg *mem) |
983 | { | 933 | { |
984 | struct drm_nouveau_private *dev_priv = nouveau_bdev(man->bdev); | 934 | struct drm_nouveau_private *dev_priv = nouveau_bdev(man->bdev); |
985 | struct nouveau_vram_engine *vram = &dev_priv->engine.vram; | ||
986 | struct drm_device *dev = dev_priv->dev; | 935 | struct drm_device *dev = dev_priv->dev; |
987 | 936 | ||
988 | nouveau_mem_node_cleanup(mem->mm_node); | 937 | nouveau_mem_node_cleanup(mem->mm_node); |
989 | vram->put(dev, (struct nouveau_mem **)&mem->mm_node); | 938 | nvfb_vram_put(dev, (struct nouveau_mem **)&mem->mm_node); |
990 | } | 939 | } |
991 | 940 | ||
992 | static int | 941 | static int |
@@ -996,7 +945,6 @@ nouveau_vram_manager_new(struct ttm_mem_type_manager *man, | |||
996 | struct ttm_mem_reg *mem) | 945 | struct ttm_mem_reg *mem) |
997 | { | 946 | { |
998 | struct drm_nouveau_private *dev_priv = nouveau_bdev(man->bdev); | 947 | struct drm_nouveau_private *dev_priv = nouveau_bdev(man->bdev); |
999 | struct nouveau_vram_engine *vram = &dev_priv->engine.vram; | ||
1000 | struct drm_device *dev = dev_priv->dev; | 948 | struct drm_device *dev = dev_priv->dev; |
1001 | struct nouveau_bo *nvbo = nouveau_bo(bo); | 949 | struct nouveau_bo *nvbo = nouveau_bo(bo); |
1002 | struct nouveau_mem *node; | 950 | struct nouveau_mem *node; |
@@ -1006,7 +954,7 @@ nouveau_vram_manager_new(struct ttm_mem_type_manager *man, | |||
1006 | if (nvbo->tile_flags & NOUVEAU_GEM_TILE_NONCONTIG) | 954 | if (nvbo->tile_flags & NOUVEAU_GEM_TILE_NONCONTIG) |
1007 | size_nc = 1 << nvbo->page_shift; | 955 | size_nc = 1 << nvbo->page_shift; |
1008 | 956 | ||
1009 | ret = vram->get(dev, mem->num_pages << PAGE_SHIFT, | 957 | ret = nvfb_vram_get(dev, mem->num_pages << PAGE_SHIFT, |
1010 | mem->page_alignment << PAGE_SHIFT, size_nc, | 958 | mem->page_alignment << PAGE_SHIFT, size_nc, |
1011 | (nvbo->tile_flags >> 8) & 0x3ff, &node); | 959 | (nvbo->tile_flags >> 8) & 0x3ff, &node); |
1012 | if (ret) { | 960 | if (ret) { |