diff options
Diffstat (limited to 'drivers/gpu/drm/nouveau/nv50_graph.c')
| -rw-r--r-- | drivers/gpu/drm/nouveau/nv50_graph.c | 118 |
1 files changed, 37 insertions, 81 deletions
diff --git a/drivers/gpu/drm/nouveau/nv50_graph.c b/drivers/gpu/drm/nouveau/nv50_graph.c index d43c46caa76e..ac601f7c4e1a 100644 --- a/drivers/gpu/drm/nouveau/nv50_graph.c +++ b/drivers/gpu/drm/nouveau/nv50_graph.c | |||
| @@ -120,70 +120,62 @@ nv50_graph_unload_context(struct drm_device *dev) | |||
| 120 | return 0; | 120 | return 0; |
| 121 | } | 121 | } |
| 122 | 122 | ||
| 123 | static void | 123 | static int |
| 124 | nv50_graph_init_reset(struct drm_device *dev) | 124 | nv50_graph_init(struct drm_device *dev, int engine) |
| 125 | { | ||
| 126 | uint32_t pmc_e = NV_PMC_ENABLE_PGRAPH | (1 << 21); | ||
| 127 | NV_DEBUG(dev, "\n"); | ||
| 128 | |||
| 129 | nv_wr32(dev, NV03_PMC_ENABLE, nv_rd32(dev, NV03_PMC_ENABLE) & ~pmc_e); | ||
| 130 | nv_wr32(dev, NV03_PMC_ENABLE, nv_rd32(dev, NV03_PMC_ENABLE) | pmc_e); | ||
| 131 | } | ||
| 132 | |||
| 133 | static void | ||
| 134 | nv50_graph_init_intr(struct drm_device *dev) | ||
| 135 | { | ||
| 136 | NV_DEBUG(dev, "\n"); | ||
| 137 | |||
| 138 | nv_wr32(dev, NV03_PGRAPH_INTR, 0xffffffff); | ||
| 139 | nv_wr32(dev, 0x400138, 0xffffffff); | ||
| 140 | nv_wr32(dev, NV40_PGRAPH_INTR_EN, 0xffffffff); | ||
| 141 | } | ||
| 142 | |||
| 143 | static void | ||
| 144 | nv50_graph_init_regs__nv(struct drm_device *dev) | ||
| 145 | { | 125 | { |
| 146 | struct drm_nouveau_private *dev_priv = dev->dev_private; | 126 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
| 147 | uint32_t units = nv_rd32(dev, 0x1540); | 127 | struct nv50_graph_engine *pgraph = nv_engine(dev, engine); |
| 128 | u32 units = nv_rd32(dev, 0x001540); | ||
| 148 | int i; | 129 | int i; |
| 149 | 130 | ||
| 150 | NV_DEBUG(dev, "\n"); | 131 | NV_DEBUG(dev, "\n"); |
| 151 | 132 | ||
| 133 | /* master reset */ | ||
| 134 | nv_mask(dev, 0x000200, 0x00201000, 0x00000000); | ||
| 135 | nv_mask(dev, 0x000200, 0x00201000, 0x00201000); | ||
| 136 | nv_wr32(dev, 0x40008c, 0x00000004); /* HW_CTX_SWITCH_ENABLED */ | ||
| 137 | |||
| 138 | /* reset/enable traps and interrupts */ | ||
| 152 | nv_wr32(dev, 0x400804, 0xc0000000); | 139 | nv_wr32(dev, 0x400804, 0xc0000000); |
| 153 | nv_wr32(dev, 0x406800, 0xc0000000); | 140 | nv_wr32(dev, 0x406800, 0xc0000000); |
| 154 | nv_wr32(dev, 0x400c04, 0xc0000000); | 141 | nv_wr32(dev, 0x400c04, 0xc0000000); |
| 155 | nv_wr32(dev, 0x401800, 0xc0000000); | 142 | nv_wr32(dev, 0x401800, 0xc0000000); |
| 156 | nv_wr32(dev, 0x405018, 0xc0000000); | 143 | nv_wr32(dev, 0x405018, 0xc0000000); |
| 157 | nv_wr32(dev, 0x402000, 0xc0000000); | 144 | nv_wr32(dev, 0x402000, 0xc0000000); |
| 158 | |||
| 159 | for (i = 0; i < 16; i++) { | 145 | for (i = 0; i < 16; i++) { |
| 160 | if (units & 1 << i) { | 146 | if (!(units & (1 << i))) |
| 161 | if (dev_priv->chipset < 0xa0) { | 147 | continue; |
| 162 | nv_wr32(dev, 0x408900 + (i << 12), 0xc0000000); | 148 | |
| 163 | nv_wr32(dev, 0x408e08 + (i << 12), 0xc0000000); | 149 | if (dev_priv->chipset < 0xa0) { |
| 164 | nv_wr32(dev, 0x408314 + (i << 12), 0xc0000000); | 150 | nv_wr32(dev, 0x408900 + (i << 12), 0xc0000000); |
| 165 | } else { | 151 | nv_wr32(dev, 0x408e08 + (i << 12), 0xc0000000); |
| 166 | nv_wr32(dev, 0x408600 + (i << 11), 0xc0000000); | 152 | nv_wr32(dev, 0x408314 + (i << 12), 0xc0000000); |
| 167 | nv_wr32(dev, 0x408708 + (i << 11), 0xc0000000); | 153 | } else { |
| 168 | nv_wr32(dev, 0x40831c + (i << 11), 0xc0000000); | 154 | nv_wr32(dev, 0x408600 + (i << 11), 0xc0000000); |
| 169 | } | 155 | nv_wr32(dev, 0x408708 + (i << 11), 0xc0000000); |
| 156 | nv_wr32(dev, 0x40831c + (i << 11), 0xc0000000); | ||
| 170 | } | 157 | } |
| 171 | } | 158 | } |
| 172 | 159 | ||
| 173 | nv_wr32(dev, 0x400108, 0xffffffff); | 160 | nv_wr32(dev, 0x400108, 0xffffffff); |
| 174 | 161 | nv_wr32(dev, 0x400138, 0xffffffff); | |
| 175 | nv_wr32(dev, 0x400824, 0x00004000); | 162 | nv_wr32(dev, 0x400100, 0xffffffff); |
| 163 | nv_wr32(dev, 0x40013c, 0xffffffff); | ||
| 176 | nv_wr32(dev, 0x400500, 0x00010001); | 164 | nv_wr32(dev, 0x400500, 0x00010001); |
| 177 | } | ||
| 178 | |||
| 179 | static void | ||
| 180 | nv50_graph_init_zcull(struct drm_device *dev) | ||
| 181 | { | ||
| 182 | struct drm_nouveau_private *dev_priv = dev->dev_private; | ||
| 183 | int i; | ||
| 184 | |||
| 185 | NV_DEBUG(dev, "\n"); | ||
| 186 | 165 | ||
| 166 | /* upload context program, initialise ctxctl defaults */ | ||
| 167 | nv_wr32(dev, 0x400324, 0x00000000); | ||
| 168 | for (i = 0; i < pgraph->ctxprog_size; i++) | ||
| 169 | nv_wr32(dev, 0x400328, pgraph->ctxprog[i]); | ||
| 170 | nv_wr32(dev, 0x400824, 0x00000000); | ||
| 171 | nv_wr32(dev, 0x400828, 0x00000000); | ||
| 172 | nv_wr32(dev, 0x40082c, 0x00000000); | ||
| 173 | nv_wr32(dev, 0x400830, 0x00000000); | ||
| 174 | nv_wr32(dev, 0x400724, 0x00000000); | ||
| 175 | nv_wr32(dev, 0x40032c, 0x00000000); | ||
| 176 | nv_wr32(dev, 0x400320, 4); /* CTXCTL_CMD = NEWCTXDMA */ | ||
| 177 | |||
| 178 | /* some unknown zcull magic */ | ||
| 187 | switch (dev_priv->chipset & 0xf0) { | 179 | switch (dev_priv->chipset & 0xf0) { |
| 188 | case 0x50: | 180 | case 0x50: |
| 189 | case 0x80: | 181 | case 0x80: |
| @@ -212,43 +204,7 @@ nv50_graph_init_zcull(struct drm_device *dev) | |||
| 212 | nv_wr32(dev, 0x402c28 + (i * 8), 0x00000000); | 204 | nv_wr32(dev, 0x402c28 + (i * 8), 0x00000000); |
| 213 | nv_wr32(dev, 0x402c2c + (i * 8), 0x00000000); | 205 | nv_wr32(dev, 0x402c2c + (i * 8), 0x00000000); |
| 214 | } | 206 | } |
| 215 | } | ||
| 216 | |||
| 217 | static int | ||
| 218 | nv50_graph_init_ctxctl(struct drm_device *dev) | ||
| 219 | { | ||
| 220 | struct nv50_graph_engine *pgraph = nv_engine(dev, NVOBJ_ENGINE_GR); | ||
| 221 | int i; | ||
| 222 | |||
| 223 | NV_DEBUG(dev, "\n"); | ||
| 224 | |||
| 225 | nv_wr32(dev, NV40_PGRAPH_CTXCTL_UCODE_INDEX, 0); | ||
| 226 | for (i = 0; i < pgraph->ctxprog_size; i++) | ||
| 227 | nv_wr32(dev, NV40_PGRAPH_CTXCTL_UCODE_DATA, pgraph->ctxprog[i]); | ||
| 228 | |||
| 229 | nv_wr32(dev, 0x40008c, 0x00000004); /* HW_CTX_SWITCH_ENABLED */ | ||
| 230 | nv_wr32(dev, 0x400320, 4); | ||
| 231 | nv_wr32(dev, NV40_PGRAPH_CTXCTL_CUR, 0); | ||
| 232 | nv_wr32(dev, NV20_PGRAPH_CHANNEL_CTX_POINTER, 0); | ||
| 233 | return 0; | ||
| 234 | } | ||
| 235 | |||
| 236 | static int | ||
| 237 | nv50_graph_init(struct drm_device *dev, int engine) | ||
| 238 | { | ||
| 239 | int ret; | ||
| 240 | |||
| 241 | NV_DEBUG(dev, "\n"); | ||
| 242 | |||
| 243 | nv50_graph_init_reset(dev); | ||
| 244 | nv50_graph_init_regs__nv(dev); | ||
| 245 | nv50_graph_init_zcull(dev); | ||
| 246 | |||
| 247 | ret = nv50_graph_init_ctxctl(dev); | ||
| 248 | if (ret) | ||
| 249 | return ret; | ||
| 250 | 207 | ||
| 251 | nv50_graph_init_intr(dev); | ||
| 252 | return 0; | 208 | return 0; |
| 253 | } | 209 | } |
| 254 | 210 | ||
