Commit | Line | Data |
---|---|---|
760285e7 | 1 | #include <drm/drmP.h> |
6ee73861 | 2 | #include "nouveau_drv.h" |
760285e7 | 3 | #include <drm/nouveau_drm.h> |
6ee73861 | 4 | |
0d87c100 | 5 | void |
a5cf68b0 | 6 | nv40_fb_set_tile_region(struct drm_device *dev, int i) |
0d87c100 FJ |
7 | { |
8 | struct drm_nouveau_private *dev_priv = dev->dev_private; | |
a5cf68b0 | 9 | struct nouveau_tile_reg *tile = &dev_priv->tile.reg[i]; |
0d87c100 FJ |
10 | |
11 | switch (dev_priv->chipset) { | |
12 | case 0x40: | |
a5cf68b0 FJ |
13 | nv_wr32(dev, NV10_PFB_TLIMIT(i), tile->limit); |
14 | nv_wr32(dev, NV10_PFB_TSIZE(i), tile->pitch); | |
15 | nv_wr32(dev, NV10_PFB_TILE(i), tile->addr); | |
0d87c100 FJ |
16 | break; |
17 | ||
18 | default: | |
a5cf68b0 FJ |
19 | nv_wr32(dev, NV40_PFB_TLIMIT(i), tile->limit); |
20 | nv_wr32(dev, NV40_PFB_TSIZE(i), tile->pitch); | |
21 | nv_wr32(dev, NV40_PFB_TILE(i), tile->addr); | |
0d87c100 FJ |
22 | break; |
23 | } | |
24 | } | |
25 | ||
7948758d BS |
26 | static void |
27 | nv40_fb_init_gart(struct drm_device *dev) | |
28 | { | |
29 | struct drm_nouveau_private *dev_priv = dev->dev_private; | |
30 | struct nouveau_gpuobj *gart = dev_priv->gart_info.sg_ctxdma; | |
31 | ||
32 | if (dev_priv->gart_info.type != NOUVEAU_GART_HW) { | |
33 | nv_wr32(dev, 0x100800, 0x00000001); | |
34 | return; | |
35 | } | |
36 | ||
37 | nv_wr32(dev, 0x100800, gart->pinst | 0x00000002); | |
38 | nv_mask(dev, 0x10008c, 0x00000100, 0x00000100); | |
39 | nv_wr32(dev, 0x100820, 0x00000000); | |
40 | } | |
41 | ||
42 | static void | |
43 | nv44_fb_init_gart(struct drm_device *dev) | |
44 | { | |
45 | struct drm_nouveau_private *dev_priv = dev->dev_private; | |
46 | struct nouveau_gpuobj *gart = dev_priv->gart_info.sg_ctxdma; | |
47 | u32 vinst; | |
48 | ||
49 | if (dev_priv->gart_info.type != NOUVEAU_GART_HW) { | |
50 | nv_wr32(dev, 0x100850, 0x80000000); | |
51 | nv_wr32(dev, 0x100800, 0x00000001); | |
52 | return; | |
53 | } | |
54 | ||
55 | /* calculate vram address of this PRAMIN block, object | |
56 | * must be allocated on 512KiB alignment, and not exceed | |
57 | * a total size of 512KiB for this to work correctly | |
58 | */ | |
59 | vinst = nv_rd32(dev, 0x10020c); | |
60 | vinst -= ((gart->pinst >> 19) + 1) << 19; | |
61 | ||
62 | nv_wr32(dev, 0x100850, 0x80000000); | |
63 | nv_wr32(dev, 0x100818, dev_priv->gart_info.dummy.addr); | |
64 | ||
65 | nv_wr32(dev, 0x100804, dev_priv->gart_info.aper_size); | |
66 | nv_wr32(dev, 0x100850, 0x00008000); | |
67 | nv_mask(dev, 0x10008c, 0x00000200, 0x00000200); | |
68 | nv_wr32(dev, 0x100820, 0x00000000); | |
69 | nv_wr32(dev, 0x10082c, 0x00000001); | |
70 | nv_wr32(dev, 0x100800, vinst | 0x00000010); | |
71 | } | |
72 | ||
ff92a6cd BS |
73 | int |
74 | nv40_fb_vram_init(struct drm_device *dev) | |
75 | { | |
76 | struct drm_nouveau_private *dev_priv = dev->dev_private; | |
77 | ||
78 | /* 0x001218 is actually present on a few other NV4X I looked at, | |
79 | * and even contains sane values matching 0x100474. From looking | |
80 | * at various vbios images however, this isn't the case everywhere. | |
81 | * So, I chose to use the same regs I've seen NVIDIA reading around | |
82 | * the memory detection, hopefully that'll get us the right numbers | |
83 | */ | |
84 | if (dev_priv->chipset == 0x40) { | |
85 | u32 pbus1218 = nv_rd32(dev, 0x001218); | |
86 | switch (pbus1218 & 0x00000300) { | |
87 | case 0x00000000: dev_priv->vram_type = NV_MEM_TYPE_SDRAM; break; | |
88 | case 0x00000100: dev_priv->vram_type = NV_MEM_TYPE_DDR1; break; | |
89 | case 0x00000200: dev_priv->vram_type = NV_MEM_TYPE_GDDR3; break; | |
90 | case 0x00000300: dev_priv->vram_type = NV_MEM_TYPE_DDR2; break; | |
91 | } | |
92 | } else | |
93 | if (dev_priv->chipset == 0x49 || dev_priv->chipset == 0x4b) { | |
94 | u32 pfb914 = nv_rd32(dev, 0x100914); | |
95 | switch (pfb914 & 0x00000003) { | |
96 | case 0x00000000: dev_priv->vram_type = NV_MEM_TYPE_DDR1; break; | |
97 | case 0x00000001: dev_priv->vram_type = NV_MEM_TYPE_DDR2; break; | |
98 | case 0x00000002: dev_priv->vram_type = NV_MEM_TYPE_GDDR3; break; | |
99 | case 0x00000003: break; | |
100 | } | |
101 | } else | |
102 | if (dev_priv->chipset != 0x4e) { | |
103 | u32 pfb474 = nv_rd32(dev, 0x100474); | |
104 | if (pfb474 & 0x00000004) | |
105 | dev_priv->vram_type = NV_MEM_TYPE_GDDR3; | |
106 | if (pfb474 & 0x00000002) | |
107 | dev_priv->vram_type = NV_MEM_TYPE_DDR2; | |
108 | if (pfb474 & 0x00000001) | |
109 | dev_priv->vram_type = NV_MEM_TYPE_DDR1; | |
110 | } else { | |
111 | dev_priv->vram_type = NV_MEM_TYPE_STOLEN; | |
112 | } | |
113 | ||
114 | dev_priv->vram_size = nv_rd32(dev, 0x10020c) & 0xff000000; | |
115 | return 0; | |
116 | } | |
117 | ||
6ee73861 BS |
118 | int |
119 | nv40_fb_init(struct drm_device *dev) | |
120 | { | |
121 | struct drm_nouveau_private *dev_priv = dev->dev_private; | |
0d87c100 FJ |
122 | struct nouveau_fb_engine *pfb = &dev_priv->engine.fb; |
123 | uint32_t tmp; | |
6ee73861 BS |
124 | int i; |
125 | ||
7948758d BS |
126 | if (dev_priv->chipset != 0x40 && dev_priv->chipset != 0x45) { |
127 | if (nv44_graph_class(dev)) | |
128 | nv44_fb_init_gart(dev); | |
129 | else | |
130 | nv40_fb_init_gart(dev); | |
131 | } | |
6ee73861 BS |
132 | |
133 | switch (dev_priv->chipset) { | |
134 | case 0x40: | |
135 | case 0x45: | |
136 | tmp = nv_rd32(dev, NV10_PFB_CLOSE_PAGE2); | |
137 | nv_wr32(dev, NV10_PFB_CLOSE_PAGE2, tmp & ~(1 << 15)); | |
0d87c100 | 138 | pfb->num_tiles = NV10_PFB_TILE__SIZE; |
6ee73861 BS |
139 | break; |
140 | case 0x46: /* G72 */ | |
141 | case 0x47: /* G70 */ | |
142 | case 0x49: /* G71 */ | |
143 | case 0x4b: /* G73 */ | |
144 | case 0x4c: /* C51 (G7X version) */ | |
0d87c100 | 145 | pfb->num_tiles = NV40_PFB_TILE__SIZE_1; |
6ee73861 BS |
146 | break; |
147 | default: | |
0d87c100 | 148 | pfb->num_tiles = NV40_PFB_TILE__SIZE_0; |
6ee73861 BS |
149 | break; |
150 | } | |
151 | ||
0d87c100 FJ |
152 | /* Turn all the tiling regions off. */ |
153 | for (i = 0; i < pfb->num_tiles; i++) | |
a5cf68b0 | 154 | pfb->set_tile_region(dev, i); |
6ee73861 BS |
155 | |
156 | return 0; | |
157 | } | |
158 | ||
159 | void | |
160 | nv40_fb_takedown(struct drm_device *dev) | |
161 | { | |
162 | } |