diff options
Diffstat (limited to 'drivers/gpu/drm/radeon/radeon_cp.c')
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_cp.c | 522 |
1 files changed, 441 insertions, 81 deletions
diff --git a/drivers/gpu/drm/radeon/radeon_cp.c b/drivers/gpu/drm/radeon/radeon_cp.c index 92965dbb3c14..77a7a4d84650 100644 --- a/drivers/gpu/drm/radeon/radeon_cp.c +++ b/drivers/gpu/drm/radeon/radeon_cp.c | |||
@@ -43,6 +43,78 @@ | |||
43 | static int radeon_do_cleanup_cp(struct drm_device * dev); | 43 | static int radeon_do_cleanup_cp(struct drm_device * dev); |
44 | static void radeon_do_cp_start(drm_radeon_private_t * dev_priv); | 44 | static void radeon_do_cp_start(drm_radeon_private_t * dev_priv); |
45 | 45 | ||
46 | u32 radeon_read_ring_rptr(drm_radeon_private_t *dev_priv, u32 off) | ||
47 | { | ||
48 | u32 val; | ||
49 | |||
50 | if (dev_priv->flags & RADEON_IS_AGP) { | ||
51 | val = DRM_READ32(dev_priv->ring_rptr, off); | ||
52 | } else { | ||
53 | val = *(((volatile u32 *) | ||
54 | dev_priv->ring_rptr->handle) + | ||
55 | (off / sizeof(u32))); | ||
56 | val = le32_to_cpu(val); | ||
57 | } | ||
58 | return val; | ||
59 | } | ||
60 | |||
61 | u32 radeon_get_ring_head(drm_radeon_private_t *dev_priv) | ||
62 | { | ||
63 | if (dev_priv->writeback_works) | ||
64 | return radeon_read_ring_rptr(dev_priv, 0); | ||
65 | else { | ||
66 | if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) | ||
67 | return RADEON_READ(R600_CP_RB_RPTR); | ||
68 | else | ||
69 | return RADEON_READ(RADEON_CP_RB_RPTR); | ||
70 | } | ||
71 | } | ||
72 | |||
73 | void radeon_write_ring_rptr(drm_radeon_private_t *dev_priv, u32 off, u32 val) | ||
74 | { | ||
75 | if (dev_priv->flags & RADEON_IS_AGP) | ||
76 | DRM_WRITE32(dev_priv->ring_rptr, off, val); | ||
77 | else | ||
78 | *(((volatile u32 *) dev_priv->ring_rptr->handle) + | ||
79 | (off / sizeof(u32))) = cpu_to_le32(val); | ||
80 | } | ||
81 | |||
82 | void radeon_set_ring_head(drm_radeon_private_t *dev_priv, u32 val) | ||
83 | { | ||
84 | radeon_write_ring_rptr(dev_priv, 0, val); | ||
85 | } | ||
86 | |||
87 | u32 radeon_get_scratch(drm_radeon_private_t *dev_priv, int index) | ||
88 | { | ||
89 | if (dev_priv->writeback_works) { | ||
90 | if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) | ||
91 | return radeon_read_ring_rptr(dev_priv, | ||
92 | R600_SCRATCHOFF(index)); | ||
93 | else | ||
94 | return radeon_read_ring_rptr(dev_priv, | ||
95 | RADEON_SCRATCHOFF(index)); | ||
96 | } else { | ||
97 | if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) | ||
98 | return RADEON_READ(R600_SCRATCH_REG0 + 4*index); | ||
99 | else | ||
100 | return RADEON_READ(RADEON_SCRATCH_REG0 + 4*index); | ||
101 | } | ||
102 | } | ||
103 | |||
104 | u32 RADEON_READ_MM(drm_radeon_private_t *dev_priv, int addr) | ||
105 | { | ||
106 | u32 ret; | ||
107 | |||
108 | if (addr < 0x10000) | ||
109 | ret = DRM_READ32(dev_priv->mmio, addr); | ||
110 | else { | ||
111 | DRM_WRITE32(dev_priv->mmio, RADEON_MM_INDEX, addr); | ||
112 | ret = DRM_READ32(dev_priv->mmio, RADEON_MM_DATA); | ||
113 | } | ||
114 | |||
115 | return ret; | ||
116 | } | ||
117 | |||
46 | static u32 R500_READ_MCIND(drm_radeon_private_t *dev_priv, int addr) | 118 | static u32 R500_READ_MCIND(drm_radeon_private_t *dev_priv, int addr) |
47 | { | 119 | { |
48 | u32 ret; | 120 | u32 ret; |
@@ -70,11 +142,22 @@ static u32 RS690_READ_MCIND(drm_radeon_private_t *dev_priv, int addr) | |||
70 | return ret; | 142 | return ret; |
71 | } | 143 | } |
72 | 144 | ||
145 | static u32 RS600_READ_MCIND(drm_radeon_private_t *dev_priv, int addr) | ||
146 | { | ||
147 | u32 ret; | ||
148 | RADEON_WRITE(RS600_MC_INDEX, ((addr & RS600_MC_ADDR_MASK) | | ||
149 | RS600_MC_IND_CITF_ARB0)); | ||
150 | ret = RADEON_READ(RS600_MC_DATA); | ||
151 | return ret; | ||
152 | } | ||
153 | |||
73 | static u32 IGP_READ_MCIND(drm_radeon_private_t *dev_priv, int addr) | 154 | static u32 IGP_READ_MCIND(drm_radeon_private_t *dev_priv, int addr) |
74 | { | 155 | { |
75 | if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) || | 156 | if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) || |
76 | ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS740)) | 157 | ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS740)) |
77 | return RS690_READ_MCIND(dev_priv, addr); | 158 | return RS690_READ_MCIND(dev_priv, addr); |
159 | else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS600) | ||
160 | return RS600_READ_MCIND(dev_priv, addr); | ||
78 | else | 161 | else |
79 | return RS480_READ_MCIND(dev_priv, addr); | 162 | return RS480_READ_MCIND(dev_priv, addr); |
80 | } | 163 | } |
@@ -82,11 +165,17 @@ static u32 IGP_READ_MCIND(drm_radeon_private_t *dev_priv, int addr) | |||
82 | u32 radeon_read_fb_location(drm_radeon_private_t *dev_priv) | 165 | u32 radeon_read_fb_location(drm_radeon_private_t *dev_priv) |
83 | { | 166 | { |
84 | 167 | ||
85 | if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV515) | 168 | if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RV770) |
169 | return RADEON_READ(R700_MC_VM_FB_LOCATION); | ||
170 | else if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) | ||
171 | return RADEON_READ(R600_MC_VM_FB_LOCATION); | ||
172 | else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV515) | ||
86 | return R500_READ_MCIND(dev_priv, RV515_MC_FB_LOCATION); | 173 | return R500_READ_MCIND(dev_priv, RV515_MC_FB_LOCATION); |
87 | else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) || | 174 | else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) || |
88 | ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS740)) | 175 | ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS740)) |
89 | return RS690_READ_MCIND(dev_priv, RS690_MC_FB_LOCATION); | 176 | return RS690_READ_MCIND(dev_priv, RS690_MC_FB_LOCATION); |
177 | else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS600) | ||
178 | return RS600_READ_MCIND(dev_priv, RS600_MC_FB_LOCATION); | ||
90 | else if ((dev_priv->flags & RADEON_FAMILY_MASK) > CHIP_RV515) | 179 | else if ((dev_priv->flags & RADEON_FAMILY_MASK) > CHIP_RV515) |
91 | return R500_READ_MCIND(dev_priv, R520_MC_FB_LOCATION); | 180 | return R500_READ_MCIND(dev_priv, R520_MC_FB_LOCATION); |
92 | else | 181 | else |
@@ -95,42 +184,66 @@ u32 radeon_read_fb_location(drm_radeon_private_t *dev_priv) | |||
95 | 184 | ||
96 | static void radeon_write_fb_location(drm_radeon_private_t *dev_priv, u32 fb_loc) | 185 | static void radeon_write_fb_location(drm_radeon_private_t *dev_priv, u32 fb_loc) |
97 | { | 186 | { |
98 | if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV515) | 187 | if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RV770) |
188 | RADEON_WRITE(R700_MC_VM_FB_LOCATION, fb_loc); | ||
189 | else if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) | ||
190 | RADEON_WRITE(R600_MC_VM_FB_LOCATION, fb_loc); | ||
191 | else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV515) | ||
99 | R500_WRITE_MCIND(RV515_MC_FB_LOCATION, fb_loc); | 192 | R500_WRITE_MCIND(RV515_MC_FB_LOCATION, fb_loc); |
100 | else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) || | 193 | else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) || |
101 | ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS740)) | 194 | ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS740)) |
102 | RS690_WRITE_MCIND(RS690_MC_FB_LOCATION, fb_loc); | 195 | RS690_WRITE_MCIND(RS690_MC_FB_LOCATION, fb_loc); |
196 | else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS600) | ||
197 | RS600_WRITE_MCIND(RS600_MC_FB_LOCATION, fb_loc); | ||
103 | else if ((dev_priv->flags & RADEON_FAMILY_MASK) > CHIP_RV515) | 198 | else if ((dev_priv->flags & RADEON_FAMILY_MASK) > CHIP_RV515) |
104 | R500_WRITE_MCIND(R520_MC_FB_LOCATION, fb_loc); | 199 | R500_WRITE_MCIND(R520_MC_FB_LOCATION, fb_loc); |
105 | else | 200 | else |
106 | RADEON_WRITE(RADEON_MC_FB_LOCATION, fb_loc); | 201 | RADEON_WRITE(RADEON_MC_FB_LOCATION, fb_loc); |
107 | } | 202 | } |
108 | 203 | ||
109 | static void radeon_write_agp_location(drm_radeon_private_t *dev_priv, u32 agp_loc) | 204 | void radeon_write_agp_location(drm_radeon_private_t *dev_priv, u32 agp_loc) |
110 | { | 205 | { |
111 | if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV515) | 206 | /*R6xx/R7xx: AGP_TOP and BOT are actually 18 bits each */ |
207 | if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RV770) { | ||
208 | RADEON_WRITE(R700_MC_VM_AGP_BOT, agp_loc & 0xffff); /* FIX ME */ | ||
209 | RADEON_WRITE(R700_MC_VM_AGP_TOP, (agp_loc >> 16) & 0xffff); | ||
210 | } else if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) { | ||
211 | RADEON_WRITE(R600_MC_VM_AGP_BOT, agp_loc & 0xffff); /* FIX ME */ | ||
212 | RADEON_WRITE(R600_MC_VM_AGP_TOP, (agp_loc >> 16) & 0xffff); | ||
213 | } else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV515) | ||
112 | R500_WRITE_MCIND(RV515_MC_AGP_LOCATION, agp_loc); | 214 | R500_WRITE_MCIND(RV515_MC_AGP_LOCATION, agp_loc); |
113 | else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) || | 215 | else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) || |
114 | ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS740)) | 216 | ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS740)) |
115 | RS690_WRITE_MCIND(RS690_MC_AGP_LOCATION, agp_loc); | 217 | RS690_WRITE_MCIND(RS690_MC_AGP_LOCATION, agp_loc); |
218 | else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS600) | ||
219 | RS600_WRITE_MCIND(RS600_MC_AGP_LOCATION, agp_loc); | ||
116 | else if ((dev_priv->flags & RADEON_FAMILY_MASK) > CHIP_RV515) | 220 | else if ((dev_priv->flags & RADEON_FAMILY_MASK) > CHIP_RV515) |
117 | R500_WRITE_MCIND(R520_MC_AGP_LOCATION, agp_loc); | 221 | R500_WRITE_MCIND(R520_MC_AGP_LOCATION, agp_loc); |
118 | else | 222 | else |
119 | RADEON_WRITE(RADEON_MC_AGP_LOCATION, agp_loc); | 223 | RADEON_WRITE(RADEON_MC_AGP_LOCATION, agp_loc); |
120 | } | 224 | } |
121 | 225 | ||
122 | static void radeon_write_agp_base(drm_radeon_private_t *dev_priv, u64 agp_base) | 226 | void radeon_write_agp_base(drm_radeon_private_t *dev_priv, u64 agp_base) |
123 | { | 227 | { |
124 | u32 agp_base_hi = upper_32_bits(agp_base); | 228 | u32 agp_base_hi = upper_32_bits(agp_base); |
125 | u32 agp_base_lo = agp_base & 0xffffffff; | 229 | u32 agp_base_lo = agp_base & 0xffffffff; |
126 | 230 | u32 r6xx_agp_base = (agp_base >> 22) & 0x3ffff; | |
127 | if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV515) { | 231 | |
232 | /* R6xx/R7xx must be aligned to a 4MB boundry */ | ||
233 | if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RV770) | ||
234 | RADEON_WRITE(R700_MC_VM_AGP_BASE, r6xx_agp_base); | ||
235 | else if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) | ||
236 | RADEON_WRITE(R600_MC_VM_AGP_BASE, r6xx_agp_base); | ||
237 | else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV515) { | ||
128 | R500_WRITE_MCIND(RV515_MC_AGP_BASE, agp_base_lo); | 238 | R500_WRITE_MCIND(RV515_MC_AGP_BASE, agp_base_lo); |
129 | R500_WRITE_MCIND(RV515_MC_AGP_BASE_2, agp_base_hi); | 239 | R500_WRITE_MCIND(RV515_MC_AGP_BASE_2, agp_base_hi); |
130 | } else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) || | 240 | } else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) || |
131 | ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS740)) { | 241 | ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS740)) { |
132 | RS690_WRITE_MCIND(RS690_MC_AGP_BASE, agp_base_lo); | 242 | RS690_WRITE_MCIND(RS690_MC_AGP_BASE, agp_base_lo); |
133 | RS690_WRITE_MCIND(RS690_MC_AGP_BASE_2, agp_base_hi); | 243 | RS690_WRITE_MCIND(RS690_MC_AGP_BASE_2, agp_base_hi); |
244 | } else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS600) { | ||
245 | RS600_WRITE_MCIND(RS600_AGP_BASE, agp_base_lo); | ||
246 | RS600_WRITE_MCIND(RS600_AGP_BASE_2, agp_base_hi); | ||
134 | } else if ((dev_priv->flags & RADEON_FAMILY_MASK) > CHIP_RV515) { | 247 | } else if ((dev_priv->flags & RADEON_FAMILY_MASK) > CHIP_RV515) { |
135 | R500_WRITE_MCIND(R520_MC_AGP_BASE, agp_base_lo); | 248 | R500_WRITE_MCIND(R520_MC_AGP_BASE, agp_base_lo); |
136 | R500_WRITE_MCIND(R520_MC_AGP_BASE_2, agp_base_hi); | 249 | R500_WRITE_MCIND(R520_MC_AGP_BASE_2, agp_base_hi); |
@@ -145,6 +258,25 @@ static void radeon_write_agp_base(drm_radeon_private_t *dev_priv, u64 agp_base) | |||
145 | } | 258 | } |
146 | } | 259 | } |
147 | 260 | ||
261 | void radeon_enable_bm(struct drm_radeon_private *dev_priv) | ||
262 | { | ||
263 | u32 tmp; | ||
264 | /* Turn on bus mastering */ | ||
265 | if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) || | ||
266 | ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS740)) { | ||
267 | /* rs600/rs690/rs740 */ | ||
268 | tmp = RADEON_READ(RADEON_BUS_CNTL) & ~RS600_BUS_MASTER_DIS; | ||
269 | RADEON_WRITE(RADEON_BUS_CNTL, tmp); | ||
270 | } else if (((dev_priv->flags & RADEON_FAMILY_MASK) <= CHIP_RV350) || | ||
271 | ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R420) || | ||
272 | ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS400) || | ||
273 | ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS480)) { | ||
274 | /* r1xx, r2xx, r300, r(v)350, r420/r481, rs400/rs480 */ | ||
275 | tmp = RADEON_READ(RADEON_BUS_CNTL) & ~RADEON_BUS_MASTER_DIS; | ||
276 | RADEON_WRITE(RADEON_BUS_CNTL, tmp); | ||
277 | } /* PCIE cards appears to not need this */ | ||
278 | } | ||
279 | |||
148 | static int RADEON_READ_PLL(struct drm_device * dev, int addr) | 280 | static int RADEON_READ_PLL(struct drm_device * dev, int addr) |
149 | { | 281 | { |
150 | drm_radeon_private_t *dev_priv = dev->dev_private; | 282 | drm_radeon_private_t *dev_priv = dev->dev_private; |
@@ -302,7 +434,7 @@ static void radeon_init_pipes(drm_radeon_private_t *dev_priv) | |||
302 | 434 | ||
303 | if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RV515) { | 435 | if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RV515) { |
304 | RADEON_WRITE_PLL(R500_DYN_SCLK_PWMEM_PIPE, (1 | ((gb_pipe_sel >> 8) & 0xf) << 4)); | 436 | RADEON_WRITE_PLL(R500_DYN_SCLK_PWMEM_PIPE, (1 | ((gb_pipe_sel >> 8) & 0xf) << 4)); |
305 | RADEON_WRITE(R500_SU_REG_DEST, ((1 << dev_priv->num_gb_pipes) - 1)); | 437 | RADEON_WRITE(R300_SU_REG_DEST, ((1 << dev_priv->num_gb_pipes) - 1)); |
306 | } | 438 | } |
307 | RADEON_WRITE(R300_GB_TILE_CONFIG, gb_tile_config); | 439 | RADEON_WRITE(R300_GB_TILE_CONFIG, gb_tile_config); |
308 | radeon_do_wait_for_idle(dev_priv); | 440 | radeon_do_wait_for_idle(dev_priv); |
@@ -382,6 +514,14 @@ static void radeon_cp_load_microcode(drm_radeon_private_t * dev_priv) | |||
382 | RADEON_WRITE(RADEON_CP_ME_RAM_DATAL, | 514 | RADEON_WRITE(RADEON_CP_ME_RAM_DATAL, |
383 | RS690_cp_microcode[i][0]); | 515 | RS690_cp_microcode[i][0]); |
384 | } | 516 | } |
517 | } else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS600) { | ||
518 | DRM_INFO("Loading RS600 Microcode\n"); | ||
519 | for (i = 0; i < 256; i++) { | ||
520 | RADEON_WRITE(RADEON_CP_ME_RAM_DATAH, | ||
521 | RS600_cp_microcode[i][1]); | ||
522 | RADEON_WRITE(RADEON_CP_ME_RAM_DATAL, | ||
523 | RS600_cp_microcode[i][0]); | ||
524 | } | ||
385 | } else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV515) || | 525 | } else if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV515) || |
386 | ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R520) || | 526 | ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R520) || |
387 | ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV530) || | 527 | ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV530) || |
@@ -562,7 +702,6 @@ static void radeon_cp_init_ring_buffer(struct drm_device * dev, | |||
562 | { | 702 | { |
563 | struct drm_radeon_master_private *master_priv; | 703 | struct drm_radeon_master_private *master_priv; |
564 | u32 ring_start, cur_read_ptr; | 704 | u32 ring_start, cur_read_ptr; |
565 | u32 tmp; | ||
566 | 705 | ||
567 | /* Initialize the memory controller. With new memory map, the fb location | 706 | /* Initialize the memory controller. With new memory map, the fb location |
568 | * is not changed, it should have been properly initialized already. Part | 707 | * is not changed, it should have been properly initialized already. Part |
@@ -611,17 +750,10 @@ static void radeon_cp_init_ring_buffer(struct drm_device * dev, | |||
611 | } else | 750 | } else |
612 | #endif | 751 | #endif |
613 | { | 752 | { |
614 | struct drm_sg_mem *entry = dev->sg; | 753 | RADEON_WRITE(RADEON_CP_RB_RPTR_ADDR, |
615 | unsigned long tmp_ofs, page_ofs; | 754 | dev_priv->ring_rptr->offset |
616 | 755 | - ((unsigned long) dev->sg->virtual) | |
617 | tmp_ofs = dev_priv->ring_rptr->offset - | 756 | + dev_priv->gart_vm_start); |
618 | (unsigned long)dev->sg->virtual; | ||
619 | page_ofs = tmp_ofs >> PAGE_SHIFT; | ||
620 | |||
621 | RADEON_WRITE(RADEON_CP_RB_RPTR_ADDR, entry->busaddr[page_ofs]); | ||
622 | DRM_DEBUG("ring rptr: offset=0x%08lx handle=0x%08lx\n", | ||
623 | (unsigned long)entry->busaddr[page_ofs], | ||
624 | entry->handle + tmp_ofs); | ||
625 | } | 757 | } |
626 | 758 | ||
627 | /* Set ring buffer size */ | 759 | /* Set ring buffer size */ |
@@ -649,34 +781,17 @@ static void radeon_cp_init_ring_buffer(struct drm_device * dev, | |||
649 | RADEON_WRITE(RADEON_SCRATCH_ADDR, RADEON_READ(RADEON_CP_RB_RPTR_ADDR) | 781 | RADEON_WRITE(RADEON_SCRATCH_ADDR, RADEON_READ(RADEON_CP_RB_RPTR_ADDR) |
650 | + RADEON_SCRATCH_REG_OFFSET); | 782 | + RADEON_SCRATCH_REG_OFFSET); |
651 | 783 | ||
652 | dev_priv->scratch = ((__volatile__ u32 *) | ||
653 | dev_priv->ring_rptr->handle + | ||
654 | (RADEON_SCRATCH_REG_OFFSET / sizeof(u32))); | ||
655 | |||
656 | RADEON_WRITE(RADEON_SCRATCH_UMSK, 0x7); | 784 | RADEON_WRITE(RADEON_SCRATCH_UMSK, 0x7); |
657 | 785 | ||
658 | /* Turn on bus mastering */ | 786 | radeon_enable_bm(dev_priv); |
659 | if (((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) || | ||
660 | ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS740)) { | ||
661 | /* rs600/rs690/rs740 */ | ||
662 | tmp = RADEON_READ(RADEON_BUS_CNTL) & ~RS600_BUS_MASTER_DIS; | ||
663 | RADEON_WRITE(RADEON_BUS_CNTL, tmp); | ||
664 | } else if (((dev_priv->flags & RADEON_FAMILY_MASK) <= CHIP_RV350) || | ||
665 | ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_R420) || | ||
666 | ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS400) || | ||
667 | ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS480)) { | ||
668 | /* r1xx, r2xx, r300, r(v)350, r420/r481, rs400/rs480 */ | ||
669 | tmp = RADEON_READ(RADEON_BUS_CNTL) & ~RADEON_BUS_MASTER_DIS; | ||
670 | RADEON_WRITE(RADEON_BUS_CNTL, tmp); | ||
671 | } /* PCIE cards appears to not need this */ | ||
672 | 787 | ||
673 | dev_priv->scratch[0] = 0; | 788 | radeon_write_ring_rptr(dev_priv, RADEON_SCRATCHOFF(0), 0); |
674 | RADEON_WRITE(RADEON_LAST_FRAME_REG, 0); | 789 | RADEON_WRITE(RADEON_LAST_FRAME_REG, 0); |
675 | 790 | ||
676 | dev_priv->scratch[1] = 0; | 791 | radeon_write_ring_rptr(dev_priv, RADEON_SCRATCHOFF(1), 0); |
677 | RADEON_WRITE(RADEON_LAST_DISPATCH_REG, 0); | 792 | RADEON_WRITE(RADEON_LAST_DISPATCH_REG, 0); |
678 | 793 | ||
679 | dev_priv->scratch[2] = 0; | 794 | radeon_write_ring_rptr(dev_priv, RADEON_SCRATCHOFF(2), 0); |
680 | RADEON_WRITE(RADEON_LAST_CLEAR_REG, 0); | 795 | RADEON_WRITE(RADEON_LAST_CLEAR_REG, 0); |
681 | 796 | ||
682 | /* reset sarea copies of these */ | 797 | /* reset sarea copies of these */ |
@@ -708,12 +823,15 @@ static void radeon_test_writeback(drm_radeon_private_t * dev_priv) | |||
708 | /* Writeback doesn't seem to work everywhere, test it here and possibly | 823 | /* Writeback doesn't seem to work everywhere, test it here and possibly |
709 | * enable it if it appears to work | 824 | * enable it if it appears to work |
710 | */ | 825 | */ |
711 | DRM_WRITE32(dev_priv->ring_rptr, RADEON_SCRATCHOFF(1), 0); | 826 | radeon_write_ring_rptr(dev_priv, RADEON_SCRATCHOFF(1), 0); |
827 | |||
712 | RADEON_WRITE(RADEON_SCRATCH_REG1, 0xdeadbeef); | 828 | RADEON_WRITE(RADEON_SCRATCH_REG1, 0xdeadbeef); |
713 | 829 | ||
714 | for (tmp = 0; tmp < dev_priv->usec_timeout; tmp++) { | 830 | for (tmp = 0; tmp < dev_priv->usec_timeout; tmp++) { |
715 | if (DRM_READ32(dev_priv->ring_rptr, RADEON_SCRATCHOFF(1)) == | 831 | u32 val; |
716 | 0xdeadbeef) | 832 | |
833 | val = radeon_read_ring_rptr(dev_priv, RADEON_SCRATCHOFF(1)); | ||
834 | if (val == 0xdeadbeef) | ||
717 | break; | 835 | break; |
718 | DRM_UDELAY(1); | 836 | DRM_UDELAY(1); |
719 | } | 837 | } |
@@ -809,6 +927,82 @@ static void radeon_set_igpgart(drm_radeon_private_t * dev_priv, int on) | |||
809 | } | 927 | } |
810 | } | 928 | } |
811 | 929 | ||
930 | /* Enable or disable IGP GART on the chip */ | ||
931 | static void rs600_set_igpgart(drm_radeon_private_t *dev_priv, int on) | ||
932 | { | ||
933 | u32 temp; | ||
934 | int i; | ||
935 | |||
936 | if (on) { | ||
937 | DRM_DEBUG("programming igp gart %08X %08lX %08X\n", | ||
938 | dev_priv->gart_vm_start, | ||
939 | (long)dev_priv->gart_info.bus_addr, | ||
940 | dev_priv->gart_size); | ||
941 | |||
942 | IGP_WRITE_MCIND(RS600_MC_PT0_CNTL, (RS600_EFFECTIVE_L2_CACHE_SIZE(6) | | ||
943 | RS600_EFFECTIVE_L2_QUEUE_SIZE(6))); | ||
944 | |||
945 | for (i = 0; i < 19; i++) | ||
946 | IGP_WRITE_MCIND(RS600_MC_PT0_CLIENT0_CNTL + i, | ||
947 | (RS600_ENABLE_TRANSLATION_MODE_OVERRIDE | | ||
948 | RS600_SYSTEM_ACCESS_MODE_IN_SYS | | ||
949 | RS600_SYSTEM_APERTURE_UNMAPPED_ACCESS_PASSTHROUGH | | ||
950 | RS600_EFFECTIVE_L1_CACHE_SIZE(3) | | ||
951 | RS600_ENABLE_FRAGMENT_PROCESSING | | ||
952 | RS600_EFFECTIVE_L1_QUEUE_SIZE(3))); | ||
953 | |||
954 | IGP_WRITE_MCIND(RS600_MC_PT0_CONTEXT0_CNTL, (RS600_ENABLE_PAGE_TABLE | | ||
955 | RS600_PAGE_TABLE_TYPE_FLAT)); | ||
956 | |||
957 | /* disable all other contexts */ | ||
958 | for (i = 1; i < 8; i++) | ||
959 | IGP_WRITE_MCIND(RS600_MC_PT0_CONTEXT0_CNTL + i, 0); | ||
960 | |||
961 | /* setup the page table aperture */ | ||
962 | IGP_WRITE_MCIND(RS600_MC_PT0_CONTEXT0_FLAT_BASE_ADDR, | ||
963 | dev_priv->gart_info.bus_addr); | ||
964 | IGP_WRITE_MCIND(RS600_MC_PT0_CONTEXT0_FLAT_START_ADDR, | ||
965 | dev_priv->gart_vm_start); | ||
966 | IGP_WRITE_MCIND(RS600_MC_PT0_CONTEXT0_FLAT_END_ADDR, | ||
967 | (dev_priv->gart_vm_start + dev_priv->gart_size - 1)); | ||
968 | IGP_WRITE_MCIND(RS600_MC_PT0_CONTEXT0_DEFAULT_READ_ADDR, 0); | ||
969 | |||
970 | /* setup the system aperture */ | ||
971 | IGP_WRITE_MCIND(RS600_MC_PT0_SYSTEM_APERTURE_LOW_ADDR, | ||
972 | dev_priv->gart_vm_start); | ||
973 | IGP_WRITE_MCIND(RS600_MC_PT0_SYSTEM_APERTURE_HIGH_ADDR, | ||
974 | (dev_priv->gart_vm_start + dev_priv->gart_size - 1)); | ||
975 | |||
976 | /* enable page tables */ | ||
977 | temp = IGP_READ_MCIND(dev_priv, RS600_MC_PT0_CNTL); | ||
978 | IGP_WRITE_MCIND(RS600_MC_PT0_CNTL, (temp | RS600_ENABLE_PT)); | ||
979 | |||
980 | temp = IGP_READ_MCIND(dev_priv, RS600_MC_CNTL1); | ||
981 | IGP_WRITE_MCIND(RS600_MC_CNTL1, (temp | RS600_ENABLE_PAGE_TABLES)); | ||
982 | |||
983 | /* invalidate the cache */ | ||
984 | temp = IGP_READ_MCIND(dev_priv, RS600_MC_PT0_CNTL); | ||
985 | |||
986 | temp &= ~(RS600_INVALIDATE_ALL_L1_TLBS | RS600_INVALIDATE_L2_CACHE); | ||
987 | IGP_WRITE_MCIND(RS600_MC_PT0_CNTL, temp); | ||
988 | temp = IGP_READ_MCIND(dev_priv, RS600_MC_PT0_CNTL); | ||
989 | |||
990 | temp |= RS600_INVALIDATE_ALL_L1_TLBS | RS600_INVALIDATE_L2_CACHE; | ||
991 | IGP_WRITE_MCIND(RS600_MC_PT0_CNTL, temp); | ||
992 | temp = IGP_READ_MCIND(dev_priv, RS600_MC_PT0_CNTL); | ||
993 | |||
994 | temp &= ~(RS600_INVALIDATE_ALL_L1_TLBS | RS600_INVALIDATE_L2_CACHE); | ||
995 | IGP_WRITE_MCIND(RS600_MC_PT0_CNTL, temp); | ||
996 | temp = IGP_READ_MCIND(dev_priv, RS600_MC_PT0_CNTL); | ||
997 | |||
998 | } else { | ||
999 | IGP_WRITE_MCIND(RS600_MC_PT0_CNTL, 0); | ||
1000 | temp = IGP_READ_MCIND(dev_priv, RS600_MC_CNTL1); | ||
1001 | temp &= ~RS600_ENABLE_PAGE_TABLES; | ||
1002 | IGP_WRITE_MCIND(RS600_MC_CNTL1, temp); | ||
1003 | } | ||
1004 | } | ||
1005 | |||
812 | static void radeon_set_pciegart(drm_radeon_private_t * dev_priv, int on) | 1006 | static void radeon_set_pciegart(drm_radeon_private_t * dev_priv, int on) |
813 | { | 1007 | { |
814 | u32 tmp = RADEON_READ_PCIE(dev_priv, RADEON_PCIE_TX_GART_CNTL); | 1008 | u32 tmp = RADEON_READ_PCIE(dev_priv, RADEON_PCIE_TX_GART_CNTL); |
@@ -850,6 +1044,11 @@ static void radeon_set_pcigart(drm_radeon_private_t * dev_priv, int on) | |||
850 | return; | 1044 | return; |
851 | } | 1045 | } |
852 | 1046 | ||
1047 | if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS600) { | ||
1048 | rs600_set_igpgart(dev_priv, on); | ||
1049 | return; | ||
1050 | } | ||
1051 | |||
853 | if (dev_priv->flags & RADEON_IS_PCIE) { | 1052 | if (dev_priv->flags & RADEON_IS_PCIE) { |
854 | radeon_set_pciegart(dev_priv, on); | 1053 | radeon_set_pciegart(dev_priv, on); |
855 | return; | 1054 | return; |
@@ -881,6 +1080,46 @@ static void radeon_set_pcigart(drm_radeon_private_t * dev_priv, int on) | |||
881 | } | 1080 | } |
882 | } | 1081 | } |
883 | 1082 | ||
1083 | static int radeon_setup_pcigart_surface(drm_radeon_private_t *dev_priv) | ||
1084 | { | ||
1085 | struct drm_ati_pcigart_info *gart_info = &dev_priv->gart_info; | ||
1086 | struct radeon_virt_surface *vp; | ||
1087 | int i; | ||
1088 | |||
1089 | for (i = 0; i < RADEON_MAX_SURFACES * 2; i++) { | ||
1090 | if (!dev_priv->virt_surfaces[i].file_priv || | ||
1091 | dev_priv->virt_surfaces[i].file_priv == PCIGART_FILE_PRIV) | ||
1092 | break; | ||
1093 | } | ||
1094 | if (i >= 2 * RADEON_MAX_SURFACES) | ||
1095 | return -ENOMEM; | ||
1096 | vp = &dev_priv->virt_surfaces[i]; | ||
1097 | |||
1098 | for (i = 0; i < RADEON_MAX_SURFACES; i++) { | ||
1099 | struct radeon_surface *sp = &dev_priv->surfaces[i]; | ||
1100 | if (sp->refcount) | ||
1101 | continue; | ||
1102 | |||
1103 | vp->surface_index = i; | ||
1104 | vp->lower = gart_info->bus_addr; | ||
1105 | vp->upper = vp->lower + gart_info->table_size; | ||
1106 | vp->flags = 0; | ||
1107 | vp->file_priv = PCIGART_FILE_PRIV; | ||
1108 | |||
1109 | sp->refcount = 1; | ||
1110 | sp->lower = vp->lower; | ||
1111 | sp->upper = vp->upper; | ||
1112 | sp->flags = 0; | ||
1113 | |||
1114 | RADEON_WRITE(RADEON_SURFACE0_INFO + 16 * i, sp->flags); | ||
1115 | RADEON_WRITE(RADEON_SURFACE0_LOWER_BOUND + 16 * i, sp->lower); | ||
1116 | RADEON_WRITE(RADEON_SURFACE0_UPPER_BOUND + 16 * i, sp->upper); | ||
1117 | return 0; | ||
1118 | } | ||
1119 | |||
1120 | return -ENOMEM; | ||
1121 | } | ||
1122 | |||
884 | static int radeon_do_init_cp(struct drm_device *dev, drm_radeon_init_t *init, | 1123 | static int radeon_do_init_cp(struct drm_device *dev, drm_radeon_init_t *init, |
885 | struct drm_file *file_priv) | 1124 | struct drm_file *file_priv) |
886 | { | 1125 | { |
@@ -1062,11 +1301,12 @@ static int radeon_do_init_cp(struct drm_device *dev, drm_radeon_init_t *init, | |||
1062 | } else | 1301 | } else |
1063 | #endif | 1302 | #endif |
1064 | { | 1303 | { |
1065 | dev_priv->cp_ring->handle = (void *)dev_priv->cp_ring->offset; | 1304 | dev_priv->cp_ring->handle = |
1305 | (void *)(unsigned long)dev_priv->cp_ring->offset; | ||
1066 | dev_priv->ring_rptr->handle = | 1306 | dev_priv->ring_rptr->handle = |
1067 | (void *)dev_priv->ring_rptr->offset; | 1307 | (void *)(unsigned long)dev_priv->ring_rptr->offset; |
1068 | dev->agp_buffer_map->handle = | 1308 | dev->agp_buffer_map->handle = |
1069 | (void *)dev->agp_buffer_map->offset; | 1309 | (void *)(unsigned long)dev->agp_buffer_map->offset; |
1070 | 1310 | ||
1071 | DRM_DEBUG("dev_priv->cp_ring->handle %p\n", | 1311 | DRM_DEBUG("dev_priv->cp_ring->handle %p\n", |
1072 | dev_priv->cp_ring->handle); | 1312 | dev_priv->cp_ring->handle); |
@@ -1173,11 +1413,14 @@ static int radeon_do_init_cp(struct drm_device *dev, drm_radeon_init_t *init, | |||
1173 | } else | 1413 | } else |
1174 | #endif | 1414 | #endif |
1175 | { | 1415 | { |
1416 | u32 sctrl; | ||
1417 | int ret; | ||
1418 | |||
1176 | dev_priv->gart_info.table_mask = DMA_BIT_MASK(32); | 1419 | dev_priv->gart_info.table_mask = DMA_BIT_MASK(32); |
1177 | /* if we have an offset set from userspace */ | 1420 | /* if we have an offset set from userspace */ |
1178 | if (dev_priv->pcigart_offset_set) { | 1421 | if (dev_priv->pcigart_offset_set) { |
1179 | dev_priv->gart_info.bus_addr = | 1422 | dev_priv->gart_info.bus_addr = |
1180 | dev_priv->pcigart_offset + dev_priv->fb_location; | 1423 | (resource_size_t)dev_priv->pcigart_offset + dev_priv->fb_location; |
1181 | dev_priv->gart_info.mapping.offset = | 1424 | dev_priv->gart_info.mapping.offset = |
1182 | dev_priv->pcigart_offset + dev_priv->fb_aper_offset; | 1425 | dev_priv->pcigart_offset + dev_priv->fb_aper_offset; |
1183 | dev_priv->gart_info.mapping.size = | 1426 | dev_priv->gart_info.mapping.size = |
@@ -1214,12 +1457,31 @@ static int radeon_do_init_cp(struct drm_device *dev, drm_radeon_init_t *init, | |||
1214 | } | 1457 | } |
1215 | } | 1458 | } |
1216 | 1459 | ||
1217 | if (!drm_ati_pcigart_init(dev, &dev_priv->gart_info)) { | 1460 | sctrl = RADEON_READ(RADEON_SURFACE_CNTL); |
1461 | RADEON_WRITE(RADEON_SURFACE_CNTL, 0); | ||
1462 | if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS600) | ||
1463 | ret = r600_page_table_init(dev); | ||
1464 | else | ||
1465 | ret = drm_ati_pcigart_init(dev, &dev_priv->gart_info); | ||
1466 | RADEON_WRITE(RADEON_SURFACE_CNTL, sctrl); | ||
1467 | |||
1468 | if (!ret) { | ||
1218 | DRM_ERROR("failed to init PCI GART!\n"); | 1469 | DRM_ERROR("failed to init PCI GART!\n"); |
1219 | radeon_do_cleanup_cp(dev); | 1470 | radeon_do_cleanup_cp(dev); |
1220 | return -ENOMEM; | 1471 | return -ENOMEM; |
1221 | } | 1472 | } |
1222 | 1473 | ||
1474 | ret = radeon_setup_pcigart_surface(dev_priv); | ||
1475 | if (ret) { | ||
1476 | DRM_ERROR("failed to setup GART surface!\n"); | ||
1477 | if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS600) | ||
1478 | r600_page_table_cleanup(dev, &dev_priv->gart_info); | ||
1479 | else | ||
1480 | drm_ati_pcigart_cleanup(dev, &dev_priv->gart_info); | ||
1481 | radeon_do_cleanup_cp(dev); | ||
1482 | return ret; | ||
1483 | } | ||
1484 | |||
1223 | /* Turn on PCI GART */ | 1485 | /* Turn on PCI GART */ |
1224 | radeon_set_pcigart(dev_priv, 1); | 1486 | radeon_set_pcigart(dev_priv, 1); |
1225 | } | 1487 | } |
@@ -1268,14 +1530,18 @@ static int radeon_do_cleanup_cp(struct drm_device * dev) | |||
1268 | if (dev_priv->gart_info.bus_addr) { | 1530 | if (dev_priv->gart_info.bus_addr) { |
1269 | /* Turn off PCI GART */ | 1531 | /* Turn off PCI GART */ |
1270 | radeon_set_pcigart(dev_priv, 0); | 1532 | radeon_set_pcigart(dev_priv, 0); |
1271 | if (!drm_ati_pcigart_cleanup(dev, &dev_priv->gart_info)) | 1533 | if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS600) |
1272 | DRM_ERROR("failed to cleanup PCI GART!\n"); | 1534 | r600_page_table_cleanup(dev, &dev_priv->gart_info); |
1535 | else { | ||
1536 | if (!drm_ati_pcigart_cleanup(dev, &dev_priv->gart_info)) | ||
1537 | DRM_ERROR("failed to cleanup PCI GART!\n"); | ||
1538 | } | ||
1273 | } | 1539 | } |
1274 | 1540 | ||
1275 | if (dev_priv->gart_info.gart_table_location == DRM_ATI_GART_FB) | 1541 | if (dev_priv->gart_info.gart_table_location == DRM_ATI_GART_FB) |
1276 | { | 1542 | { |
1277 | drm_core_ioremapfree(&dev_priv->gart_info.mapping, dev); | 1543 | drm_core_ioremapfree(&dev_priv->gart_info.mapping, dev); |
1278 | dev_priv->gart_info.addr = 0; | 1544 | dev_priv->gart_info.addr = NULL; |
1279 | } | 1545 | } |
1280 | } | 1546 | } |
1281 | /* only clear to the start of flags */ | 1547 | /* only clear to the start of flags */ |
@@ -1326,6 +1592,7 @@ static int radeon_do_resume_cp(struct drm_device *dev, struct drm_file *file_pri | |||
1326 | 1592 | ||
1327 | int radeon_cp_init(struct drm_device *dev, void *data, struct drm_file *file_priv) | 1593 | int radeon_cp_init(struct drm_device *dev, void *data, struct drm_file *file_priv) |
1328 | { | 1594 | { |
1595 | drm_radeon_private_t *dev_priv = dev->dev_private; | ||
1329 | drm_radeon_init_t *init = data; | 1596 | drm_radeon_init_t *init = data; |
1330 | 1597 | ||
1331 | LOCK_TEST_WITH_RETURN(dev, file_priv); | 1598 | LOCK_TEST_WITH_RETURN(dev, file_priv); |
@@ -1338,8 +1605,13 @@ int radeon_cp_init(struct drm_device *dev, void *data, struct drm_file *file_pri | |||
1338 | case RADEON_INIT_R200_CP: | 1605 | case RADEON_INIT_R200_CP: |
1339 | case RADEON_INIT_R300_CP: | 1606 | case RADEON_INIT_R300_CP: |
1340 | return radeon_do_init_cp(dev, init, file_priv); | 1607 | return radeon_do_init_cp(dev, init, file_priv); |
1608 | case RADEON_INIT_R600_CP: | ||
1609 | return r600_do_init_cp(dev, init, file_priv); | ||
1341 | case RADEON_CLEANUP_CP: | 1610 | case RADEON_CLEANUP_CP: |
1342 | return radeon_do_cleanup_cp(dev); | 1611 | if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) |
1612 | return r600_do_cleanup_cp(dev); | ||
1613 | else | ||
1614 | return radeon_do_cleanup_cp(dev); | ||
1343 | } | 1615 | } |
1344 | 1616 | ||
1345 | return -EINVAL; | 1617 | return -EINVAL; |
@@ -1362,7 +1634,10 @@ int radeon_cp_start(struct drm_device *dev, void *data, struct drm_file *file_pr | |||
1362 | return 0; | 1634 | return 0; |
1363 | } | 1635 | } |
1364 | 1636 | ||
1365 | radeon_do_cp_start(dev_priv); | 1637 | if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) |
1638 | r600_do_cp_start(dev_priv); | ||
1639 | else | ||
1640 | radeon_do_cp_start(dev_priv); | ||
1366 | 1641 | ||
1367 | return 0; | 1642 | return 0; |
1368 | } | 1643 | } |
@@ -1393,7 +1668,10 @@ int radeon_cp_stop(struct drm_device *dev, void *data, struct drm_file *file_pri | |||
1393 | * code so that the DRM ioctl wrapper can try again. | 1668 | * code so that the DRM ioctl wrapper can try again. |
1394 | */ | 1669 | */ |
1395 | if (stop->idle) { | 1670 | if (stop->idle) { |
1396 | ret = radeon_do_cp_idle(dev_priv); | 1671 | if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) |
1672 | ret = r600_do_cp_idle(dev_priv); | ||
1673 | else | ||
1674 | ret = radeon_do_cp_idle(dev_priv); | ||
1397 | if (ret) | 1675 | if (ret) |
1398 | return ret; | 1676 | return ret; |
1399 | } | 1677 | } |
@@ -1402,10 +1680,16 @@ int radeon_cp_stop(struct drm_device *dev, void *data, struct drm_file *file_pri | |||
1402 | * we will get some dropped triangles as they won't be fully | 1680 | * we will get some dropped triangles as they won't be fully |
1403 | * rendered before the CP is shut down. | 1681 | * rendered before the CP is shut down. |
1404 | */ | 1682 | */ |
1405 | radeon_do_cp_stop(dev_priv); | 1683 | if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) |
1684 | r600_do_cp_stop(dev_priv); | ||
1685 | else | ||
1686 | radeon_do_cp_stop(dev_priv); | ||
1406 | 1687 | ||
1407 | /* Reset the engine */ | 1688 | /* Reset the engine */ |
1408 | radeon_do_engine_reset(dev); | 1689 | if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) |
1690 | r600_do_engine_reset(dev); | ||
1691 | else | ||
1692 | radeon_do_engine_reset(dev); | ||
1409 | 1693 | ||
1410 | return 0; | 1694 | return 0; |
1411 | } | 1695 | } |
@@ -1418,29 +1702,47 @@ void radeon_do_release(struct drm_device * dev) | |||
1418 | if (dev_priv) { | 1702 | if (dev_priv) { |
1419 | if (dev_priv->cp_running) { | 1703 | if (dev_priv->cp_running) { |
1420 | /* Stop the cp */ | 1704 | /* Stop the cp */ |
1421 | while ((ret = radeon_do_cp_idle(dev_priv)) != 0) { | 1705 | if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) { |
1422 | DRM_DEBUG("radeon_do_cp_idle %d\n", ret); | 1706 | while ((ret = r600_do_cp_idle(dev_priv)) != 0) { |
1707 | DRM_DEBUG("radeon_do_cp_idle %d\n", ret); | ||
1708 | #ifdef __linux__ | ||
1709 | schedule(); | ||
1710 | #else | ||
1711 | tsleep(&ret, PZERO, "rdnrel", 1); | ||
1712 | #endif | ||
1713 | } | ||
1714 | } else { | ||
1715 | while ((ret = radeon_do_cp_idle(dev_priv)) != 0) { | ||
1716 | DRM_DEBUG("radeon_do_cp_idle %d\n", ret); | ||
1423 | #ifdef __linux__ | 1717 | #ifdef __linux__ |
1424 | schedule(); | 1718 | schedule(); |
1425 | #else | 1719 | #else |
1426 | tsleep(&ret, PZERO, "rdnrel", 1); | 1720 | tsleep(&ret, PZERO, "rdnrel", 1); |
1427 | #endif | 1721 | #endif |
1722 | } | ||
1723 | } | ||
1724 | if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) { | ||
1725 | r600_do_cp_stop(dev_priv); | ||
1726 | r600_do_engine_reset(dev); | ||
1727 | } else { | ||
1728 | radeon_do_cp_stop(dev_priv); | ||
1729 | radeon_do_engine_reset(dev); | ||
1428 | } | 1730 | } |
1429 | radeon_do_cp_stop(dev_priv); | ||
1430 | radeon_do_engine_reset(dev); | ||
1431 | } | 1731 | } |
1432 | 1732 | ||
1433 | /* Disable *all* interrupts */ | 1733 | if ((dev_priv->flags & RADEON_FAMILY_MASK) < CHIP_R600) { |
1434 | if (dev_priv->mmio) /* remove this after permanent addmaps */ | 1734 | /* Disable *all* interrupts */ |
1435 | RADEON_WRITE(RADEON_GEN_INT_CNTL, 0); | 1735 | if (dev_priv->mmio) /* remove this after permanent addmaps */ |
1436 | 1736 | RADEON_WRITE(RADEON_GEN_INT_CNTL, 0); | |
1437 | if (dev_priv->mmio) { /* remove all surfaces */ | 1737 | |
1438 | for (i = 0; i < RADEON_MAX_SURFACES; i++) { | 1738 | if (dev_priv->mmio) { /* remove all surfaces */ |
1439 | RADEON_WRITE(RADEON_SURFACE0_INFO + 16 * i, 0); | 1739 | for (i = 0; i < RADEON_MAX_SURFACES; i++) { |
1440 | RADEON_WRITE(RADEON_SURFACE0_LOWER_BOUND + | 1740 | RADEON_WRITE(RADEON_SURFACE0_INFO + 16 * i, 0); |
1441 | 16 * i, 0); | 1741 | RADEON_WRITE(RADEON_SURFACE0_LOWER_BOUND + |
1442 | RADEON_WRITE(RADEON_SURFACE0_UPPER_BOUND + | 1742 | 16 * i, 0); |
1443 | 16 * i, 0); | 1743 | RADEON_WRITE(RADEON_SURFACE0_UPPER_BOUND + |
1744 | 16 * i, 0); | ||
1745 | } | ||
1444 | } | 1746 | } |
1445 | } | 1747 | } |
1446 | 1748 | ||
@@ -1449,7 +1751,10 @@ void radeon_do_release(struct drm_device * dev) | |||
1449 | radeon_mem_takedown(&(dev_priv->fb_heap)); | 1751 | radeon_mem_takedown(&(dev_priv->fb_heap)); |
1450 | 1752 | ||
1451 | /* deallocate kernel resources */ | 1753 | /* deallocate kernel resources */ |
1452 | radeon_do_cleanup_cp(dev); | 1754 | if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) |
1755 | r600_do_cleanup_cp(dev); | ||
1756 | else | ||
1757 | radeon_do_cleanup_cp(dev); | ||
1453 | } | 1758 | } |
1454 | } | 1759 | } |
1455 | 1760 | ||
@@ -1467,7 +1772,10 @@ int radeon_cp_reset(struct drm_device *dev, void *data, struct drm_file *file_pr | |||
1467 | return -EINVAL; | 1772 | return -EINVAL; |
1468 | } | 1773 | } |
1469 | 1774 | ||
1470 | radeon_do_cp_reset(dev_priv); | 1775 | if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) |
1776 | r600_do_cp_reset(dev_priv); | ||
1777 | else | ||
1778 | radeon_do_cp_reset(dev_priv); | ||
1471 | 1779 | ||
1472 | /* The CP is no longer running after an engine reset */ | 1780 | /* The CP is no longer running after an engine reset */ |
1473 | dev_priv->cp_running = 0; | 1781 | dev_priv->cp_running = 0; |
@@ -1482,23 +1790,36 @@ int radeon_cp_idle(struct drm_device *dev, void *data, struct drm_file *file_pri | |||
1482 | 1790 | ||
1483 | LOCK_TEST_WITH_RETURN(dev, file_priv); | 1791 | LOCK_TEST_WITH_RETURN(dev, file_priv); |
1484 | 1792 | ||
1485 | return radeon_do_cp_idle(dev_priv); | 1793 | if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) |
1794 | return r600_do_cp_idle(dev_priv); | ||
1795 | else | ||
1796 | return radeon_do_cp_idle(dev_priv); | ||
1486 | } | 1797 | } |
1487 | 1798 | ||
1488 | /* Added by Charl P. Botha to call radeon_do_resume_cp(). | 1799 | /* Added by Charl P. Botha to call radeon_do_resume_cp(). |
1489 | */ | 1800 | */ |
1490 | int radeon_cp_resume(struct drm_device *dev, void *data, struct drm_file *file_priv) | 1801 | int radeon_cp_resume(struct drm_device *dev, void *data, struct drm_file *file_priv) |
1491 | { | 1802 | { |
1492 | return radeon_do_resume_cp(dev, file_priv); | 1803 | drm_radeon_private_t *dev_priv = dev->dev_private; |
1804 | DRM_DEBUG("\n"); | ||
1805 | |||
1806 | if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) | ||
1807 | return r600_do_resume_cp(dev, file_priv); | ||
1808 | else | ||
1809 | return radeon_do_resume_cp(dev, file_priv); | ||
1493 | } | 1810 | } |
1494 | 1811 | ||
1495 | int radeon_engine_reset(struct drm_device *dev, void *data, struct drm_file *file_priv) | 1812 | int radeon_engine_reset(struct drm_device *dev, void *data, struct drm_file *file_priv) |
1496 | { | 1813 | { |
1814 | drm_radeon_private_t *dev_priv = dev->dev_private; | ||
1497 | DRM_DEBUG("\n"); | 1815 | DRM_DEBUG("\n"); |
1498 | 1816 | ||
1499 | LOCK_TEST_WITH_RETURN(dev, file_priv); | 1817 | LOCK_TEST_WITH_RETURN(dev, file_priv); |
1500 | 1818 | ||
1501 | return radeon_do_engine_reset(dev); | 1819 | if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) |
1820 | return r600_do_engine_reset(dev); | ||
1821 | else | ||
1822 | return radeon_do_engine_reset(dev); | ||
1502 | } | 1823 | } |
1503 | 1824 | ||
1504 | /* ================================================================ | 1825 | /* ================================================================ |
@@ -1548,7 +1869,7 @@ struct drm_buf *radeon_freelist_get(struct drm_device * dev) | |||
1548 | start = dev_priv->last_buf; | 1869 | start = dev_priv->last_buf; |
1549 | 1870 | ||
1550 | for (t = 0; t < dev_priv->usec_timeout; t++) { | 1871 | for (t = 0; t < dev_priv->usec_timeout; t++) { |
1551 | u32 done_age = GET_SCRATCH(1); | 1872 | u32 done_age = GET_SCRATCH(dev_priv, 1); |
1552 | DRM_DEBUG("done_age = %d\n", done_age); | 1873 | DRM_DEBUG("done_age = %d\n", done_age); |
1553 | for (i = start; i < dma->buf_count; i++) { | 1874 | for (i = start; i < dma->buf_count; i++) { |
1554 | buf = dma->buflist[i]; | 1875 | buf = dma->buflist[i]; |
@@ -1582,8 +1903,9 @@ struct drm_buf *radeon_freelist_get(struct drm_device * dev) | |||
1582 | struct drm_buf *buf; | 1903 | struct drm_buf *buf; |
1583 | int i, t; | 1904 | int i, t; |
1584 | int start; | 1905 | int start; |
1585 | u32 done_age = DRM_READ32(dev_priv->ring_rptr, RADEON_SCRATCHOFF(1)); | 1906 | u32 done_age; |
1586 | 1907 | ||
1908 | done_age = radeon_read_ring_rptr(dev_priv, RADEON_SCRATCHOFF(1)); | ||
1587 | if (++dev_priv->last_buf >= dma->buf_count) | 1909 | if (++dev_priv->last_buf >= dma->buf_count) |
1588 | dev_priv->last_buf = 0; | 1910 | dev_priv->last_buf = 0; |
1589 | 1911 | ||
@@ -1854,3 +2176,41 @@ int radeon_driver_unload(struct drm_device *dev) | |||
1854 | dev->dev_private = NULL; | 2176 | dev->dev_private = NULL; |
1855 | return 0; | 2177 | return 0; |
1856 | } | 2178 | } |
2179 | |||
2180 | void radeon_commit_ring(drm_radeon_private_t *dev_priv) | ||
2181 | { | ||
2182 | int i; | ||
2183 | u32 *ring; | ||
2184 | int tail_aligned; | ||
2185 | |||
2186 | /* check if the ring is padded out to 16-dword alignment */ | ||
2187 | |||
2188 | tail_aligned = dev_priv->ring.tail & 0xf; | ||
2189 | if (tail_aligned) { | ||
2190 | int num_p2 = 16 - tail_aligned; | ||
2191 | |||
2192 | ring = dev_priv->ring.start; | ||
2193 | /* pad with some CP_PACKET2 */ | ||
2194 | for (i = 0; i < num_p2; i++) | ||
2195 | ring[dev_priv->ring.tail + i] = CP_PACKET2(); | ||
2196 | |||
2197 | dev_priv->ring.tail += i; | ||
2198 | |||
2199 | dev_priv->ring.space -= num_p2 * sizeof(u32); | ||
2200 | } | ||
2201 | |||
2202 | dev_priv->ring.tail &= dev_priv->ring.tail_mask; | ||
2203 | |||
2204 | DRM_MEMORYBARRIER(); | ||
2205 | GET_RING_HEAD( dev_priv ); | ||
2206 | |||
2207 | if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) { | ||
2208 | RADEON_WRITE(R600_CP_RB_WPTR, dev_priv->ring.tail); | ||
2209 | /* read from PCI bus to ensure correct posting */ | ||
2210 | RADEON_READ(R600_CP_RB_RPTR); | ||
2211 | } else { | ||
2212 | RADEON_WRITE(RADEON_CP_RB_WPTR, dev_priv->ring.tail); | ||
2213 | /* read from PCI bus to ensure correct posting */ | ||
2214 | RADEON_READ(RADEON_CP_RB_RPTR); | ||
2215 | } | ||
2216 | } | ||