Ben Skeggs | 6ee7386 | 2009-12-11 19:24:15 +1000 | [diff] [blame] | 1 | #include "drmP.h" |
| 2 | #include "drm.h" |
| 3 | #include "nouveau_drv.h" |
| 4 | #include "nouveau_drm.h" |
| 5 | |
Ben Skeggs | d81c19e | 2011-12-12 22:51:33 +1000 | [diff] [blame] | 6 | void |
| 7 | nv10_fb_init_tile_region(struct drm_device *dev, int i, uint32_t addr, |
| 8 | uint32_t size, uint32_t pitch, uint32_t flags) |
| 9 | { |
| 10 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
| 11 | struct nouveau_tile_reg *tile = &dev_priv->tile.reg[i]; |
| 12 | |
| 13 | tile->addr = 0x80000000 | addr; |
| 14 | tile->limit = max(1u, addr + size) - 1; |
| 15 | tile->pitch = pitch; |
| 16 | } |
| 17 | |
| 18 | void |
| 19 | nv10_fb_free_tile_region(struct drm_device *dev, int i) |
| 20 | { |
| 21 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
| 22 | struct nouveau_tile_reg *tile = &dev_priv->tile.reg[i]; |
| 23 | |
| 24 | tile->addr = tile->limit = tile->pitch = tile->zcomp = 0; |
| 25 | } |
| 26 | |
| 27 | void |
| 28 | nv10_fb_set_tile_region(struct drm_device *dev, int i) |
| 29 | { |
| 30 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
| 31 | struct nouveau_tile_reg *tile = &dev_priv->tile.reg[i]; |
| 32 | |
| 33 | nv_wr32(dev, NV10_PFB_TLIMIT(i), tile->limit); |
| 34 | nv_wr32(dev, NV10_PFB_TSIZE(i), tile->pitch); |
| 35 | nv_wr32(dev, NV10_PFB_TILE(i), tile->addr); |
| 36 | } |
| 37 | |
Ben Skeggs | 7ad2d31 | 2011-12-11 00:30:05 +1000 | [diff] [blame] | 38 | int |
| 39 | nv1a_fb_vram_init(struct drm_device *dev) |
| 40 | { |
| 41 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
| 42 | struct pci_dev *bridge; |
| 43 | uint32_t mem, mib; |
| 44 | |
| 45 | bridge = pci_get_bus_and_slot(0, PCI_DEVFN(0, 1)); |
| 46 | if (!bridge) { |
| 47 | NV_ERROR(dev, "no bridge device\n"); |
| 48 | return 0; |
| 49 | } |
| 50 | |
| 51 | if (dev_priv->chipset == 0x1a) { |
| 52 | pci_read_config_dword(bridge, 0x7c, &mem); |
| 53 | mib = ((mem >> 6) & 31) + 1; |
| 54 | } else { |
| 55 | pci_read_config_dword(bridge, 0x84, &mem); |
| 56 | mib = ((mem >> 4) & 127) + 1; |
| 57 | } |
| 58 | |
| 59 | dev_priv->vram_size = mib * 1024 * 1024; |
| 60 | return 0; |
| 61 | } |
| 62 | |
| 63 | int |
| 64 | nv10_fb_vram_init(struct drm_device *dev) |
| 65 | { |
| 66 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
| 67 | u32 fifo_data = nv_rd32(dev, NV04_PFB_FIFO_DATA); |
Ben Skeggs | d81c19e | 2011-12-12 22:51:33 +1000 | [diff] [blame] | 68 | u32 cfg0 = nv_rd32(dev, 0x100200); |
Ben Skeggs | 7ad2d31 | 2011-12-11 00:30:05 +1000 | [diff] [blame] | 69 | |
| 70 | dev_priv->vram_size = fifo_data & NV10_PFB_FIFO_DATA_RAM_AMOUNT_MB_MASK; |
Ben Skeggs | d81c19e | 2011-12-12 22:51:33 +1000 | [diff] [blame] | 71 | |
| 72 | if (cfg0 & 0x00000001) |
| 73 | dev_priv->vram_type = NV_MEM_TYPE_DDR1; |
| 74 | else |
| 75 | dev_priv->vram_type = NV_MEM_TYPE_SDRAM; |
Ben Skeggs | ddfd2da | 2011-12-11 01:31:17 +1000 | [diff] [blame] | 76 | |
Ben Skeggs | 7ad2d31 | 2011-12-11 00:30:05 +1000 | [diff] [blame] | 77 | return 0; |
| 78 | } |
| 79 | |
Ben Skeggs | 6ee7386 | 2009-12-11 19:24:15 +1000 | [diff] [blame] | 80 | int |
| 81 | nv10_fb_init(struct drm_device *dev) |
| 82 | { |
Francisco Jerez | 0d87c10 | 2009-12-16 12:12:27 +0100 | [diff] [blame] | 83 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
| 84 | struct nouveau_fb_engine *pfb = &dev_priv->engine.fb; |
Ben Skeggs | 6ee7386 | 2009-12-11 19:24:15 +1000 | [diff] [blame] | 85 | int i; |
| 86 | |
Francisco Jerez | 0d87c10 | 2009-12-16 12:12:27 +0100 | [diff] [blame] | 87 | /* Turn all the tiling regions off. */ |
Ben Skeggs | d81c19e | 2011-12-12 22:51:33 +1000 | [diff] [blame] | 88 | pfb->num_tiles = NV10_PFB_TILE__SIZE; |
Francisco Jerez | 0d87c10 | 2009-12-16 12:12:27 +0100 | [diff] [blame] | 89 | for (i = 0; i < pfb->num_tiles; i++) |
Francisco Jerez | a5cf68b | 2010-10-24 16:14:41 +0200 | [diff] [blame] | 90 | pfb->set_tile_region(dev, i); |
Ben Skeggs | 6ee7386 | 2009-12-11 19:24:15 +1000 | [diff] [blame] | 91 | |
| 92 | return 0; |
| 93 | } |
| 94 | |
| 95 | void |
| 96 | nv10_fb_takedown(struct drm_device *dev) |
| 97 | { |
Francisco Jerez | 87a326a | 2010-10-24 16:36:12 +0200 | [diff] [blame] | 98 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
| 99 | struct nouveau_fb_engine *pfb = &dev_priv->engine.fb; |
| 100 | int i; |
| 101 | |
| 102 | for (i = 0; i < pfb->num_tiles; i++) |
| 103 | pfb->free_tile_region(dev, i); |
Ben Skeggs | 6ee7386 | 2009-12-11 19:24:15 +1000 | [diff] [blame] | 104 | } |