Rev 1179 | Rev 1268 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 1179 | Rev 1221 | ||
---|---|---|---|
Line 23... | Line 23... | ||
23 | * |
23 | * |
24 | * Authors: Dave Airlie |
24 | * Authors: Dave Airlie |
25 | * Alex Deucher |
25 | * Alex Deucher |
26 | * Jerome Glisse |
26 | * Jerome Glisse |
27 | */ |
27 | */ |
- | 28 | /* RS600 / Radeon X1250/X1270 integrated GPU |
|
- | 29 | * |
|
- | 30 | * This file gather function specific to RS600 which is the IGP of |
|
- | 31 | * the X1250/X1270 family supporting intel CPU (while RS690/RS740 |
|
- | 32 | * is the X1250/X1270 supporting AMD CPU). The display engine are |
|
- | 33 | * the avivo one, bios is an atombios, 3D block are the one of the |
|
- | 34 | * R4XX family. The GART is different from the RS400 one and is very |
|
- | 35 | * close to the one of the R600 family (R600 likely being an evolution |
|
- | 36 | * of the RS600 GART block). |
|
- | 37 | */ |
|
28 | #include "drmP.h" |
38 | #include "drmP.h" |
29 | #include "radeon_reg.h" |
- | |
30 | #include "radeon.h" |
39 | #include "radeon.h" |
31 | #include "avivod.h" |
40 | #include "atom.h" |
- | 41 | #include "rs600d.h" |
|
Line 32... | Line 42... | ||
32 | 42 | ||
Line 33... | Line -... | ||
33 | #include "rs600_reg_safe.h" |
- | |
34 | - | ||
35 | /* rs600 depends on : */ |
- | |
36 | void r100_hdp_reset(struct radeon_device *rdev); |
- | |
37 | int r100_gui_wait_for_idle(struct radeon_device *rdev); |
- | |
38 | int r300_mc_wait_for_idle(struct radeon_device *rdev); |
- | |
39 | void r420_pipes_init(struct radeon_device *rdev); |
- | |
40 | - | ||
41 | /* This files gather functions specifics to : |
- | |
42 | * rs600 |
- | |
43 | * |
- | |
44 | * Some of these functions might be used by newer ASICs. |
43 | #include "rs600_reg_safe.h" |
45 | */ |
44 | |
46 | void rs600_gpu_init(struct radeon_device *rdev); |
- | |
47 | int rs600_mc_wait_for_idle(struct radeon_device *rdev); |
- | |
Line 48... | Line 45... | ||
48 | void rs600_disable_vga(struct radeon_device *rdev); |
45 | void rs600_gpu_init(struct radeon_device *rdev); |
49 | 46 | int rs600_mc_wait_for_idle(struct radeon_device *rdev); |
|
50 | 47 | ||
51 | /* |
48 | /* |
52 | * GART. |
49 | * GART. |
53 | */ |
50 | */ |
Line 54... | Line 51... | ||
54 | void rs600_gart_tlb_flush(struct radeon_device *rdev) |
51 | void rs600_gart_tlb_flush(struct radeon_device *rdev) |
55 | { |
52 | { |
56 | uint32_t tmp; |
53 | uint32_t tmp; |
57 | 54 | ||
58 | tmp = RREG32_MC(RS600_MC_PT0_CNTL); |
55 | tmp = RREG32_MC(R_000100_MC_PT0_CNTL); |
59 | tmp &= ~(RS600_INVALIDATE_ALL_L1_TLBS | RS600_INVALIDATE_L2_CACHE); |
56 | tmp &= C_000100_INVALIDATE_ALL_L1_TLBS & C_000100_INVALIDATE_L2_CACHE; |
60 | WREG32_MC(RS600_MC_PT0_CNTL, tmp); |
57 | WREG32_MC(R_000100_MC_PT0_CNTL, tmp); |
61 | 58 | ||
62 | tmp = RREG32_MC(RS600_MC_PT0_CNTL); |
59 | tmp = RREG32_MC(R_000100_MC_PT0_CNTL); |
63 | tmp |= RS600_INVALIDATE_ALL_L1_TLBS | RS600_INVALIDATE_L2_CACHE; |
60 | tmp |= S_000100_INVALIDATE_ALL_L1_TLBS(1) & S_000100_INVALIDATE_L2_CACHE(1); |
64 | WREG32_MC(RS600_MC_PT0_CNTL, tmp); |
61 | WREG32_MC(R_000100_MC_PT0_CNTL, tmp); |
65 | 62 | ||
66 | tmp = RREG32_MC(RS600_MC_PT0_CNTL); |
63 | tmp = RREG32_MC(R_000100_MC_PT0_CNTL); |
Line 67... | Line 64... | ||
67 | tmp &= ~(RS600_INVALIDATE_ALL_L1_TLBS | RS600_INVALIDATE_L2_CACHE); |
64 | tmp &= C_000100_INVALIDATE_ALL_L1_TLBS & C_000100_INVALIDATE_L2_CACHE; |
68 | WREG32_MC(RS600_MC_PT0_CNTL, tmp); |
65 | WREG32_MC(R_000100_MC_PT0_CNTL, tmp); |
69 | tmp = RREG32_MC(RS600_MC_PT0_CNTL); |
- | |
70 | } |
- | |
71 | 66 | tmp = RREG32_MC(R_000100_MC_PT0_CNTL); |
|
Line -... | Line 67... | ||
- | 67 | } |
|
- | 68 | ||
- | 69 | int rs600_gart_init(struct radeon_device *rdev) |
|
- | 70 | { |
|
72 | int rs600_gart_enable(struct radeon_device *rdev) |
71 | int r; |
73 | { |
72 | |
74 | uint32_t tmp; |
73 | if (rdev->gart.table.vram.robj) { |
75 | int i; |
74 | WARN(1, "RS600 GART already initialized.\n"); |
76 | int r; |
75 | return 0; |
77 | 76 | } |
|
78 | /* Initialize common gart structure */ |
77 | /* Initialize common gart structure */ |
79 | r = radeon_gart_init(rdev); |
- | |
80 | if (r) { |
- | |
81 | return r; |
78 | r = radeon_gart_init(rdev); |
- | 79 | if (r) { |
|
- | 80 | return r; |
|
- | 81 | } |
|
- | 82 | rdev->gart.table_size = rdev->gart.num_gpu_pages * 8; |
|
- | 83 | return radeon_gart_table_vram_alloc(rdev); |
|
- | 84 | } |
|
- | 85 | ||
- | 86 | int rs600_gart_enable(struct radeon_device *rdev) |
|
- | 87 | { |
|
- | 88 | u32 tmp; |
|
- | 89 | int r, i; |
|
- | 90 | ||
- | 91 | if (rdev->gart.table.vram.robj == NULL) { |
|
- | 92 | dev_err(rdev->dev, "No VRAM object for PCIE GART.\n"); |
|
- | 93 | return -EINVAL; |
|
- | 94 | } |
|
82 | } |
95 | r = radeon_gart_table_vram_pin(rdev); |
83 | rdev->gart.table_size = rdev->gart.num_gpu_pages * 8; |
96 | if (r) |
84 | r = radeon_gart_table_vram_alloc(rdev); |
97 | return r; |
85 | if (r) { |
98 | /* Enable bus master */ |
86 | return r; |
99 | tmp = RREG32(R_00004C_BUS_CNTL) & C_00004C_BUS_MASTER_DIS; |
87 | } |
100 | WREG32(R_00004C_BUS_CNTL, tmp); |
88 | /* FIXME: setup default page */ |
101 | /* FIXME: setup default page */ |
- | 102 | WREG32_MC(R_000100_MC_PT0_CNTL, |
|
89 | WREG32_MC(RS600_MC_PT0_CNTL, |
103 | (S_000100_EFFECTIVE_L2_CACHE_SIZE(6) | |
- | 104 | S_000100_EFFECTIVE_L2_QUEUE_SIZE(6))); |
|
90 | (RS600_EFFECTIVE_L2_CACHE_SIZE(6) | |
105 | for (i = 0; i < 19; i++) { |
91 | RS600_EFFECTIVE_L2_QUEUE_SIZE(6))); |
106 | WREG32_MC(R_00016C_MC_PT0_CLIENT0_CNTL + i, |
92 | for (i = 0; i < 19; i++) { |
107 | S_00016C_ENABLE_TRANSLATION_MODE_OVERRIDE(1) | |
93 | WREG32_MC(RS600_MC_PT0_CLIENT0_CNTL + i, |
108 | S_00016C_SYSTEM_ACCESS_MODE_MASK( |
94 | (RS600_ENABLE_TRANSLATION_MODE_OVERRIDE | |
109 | V_00016C_SYSTEM_ACCESS_MODE_IN_SYS) | |
Line 95... | Line 110... | ||
95 | RS600_SYSTEM_ACCESS_MODE_IN_SYS | |
110 | S_00016C_SYSTEM_APERTURE_UNMAPPED_ACCESS( |
96 | RS600_SYSTEM_APERTURE_UNMAPPED_ACCESS_DEFAULT_PAGE | |
111 | V_00016C_SYSTEM_APERTURE_UNMAPPED_DEFAULT_PAGE) | |
97 | RS600_EFFECTIVE_L1_CACHE_SIZE(3) | |
- | |
98 | RS600_ENABLE_FRAGMENT_PROCESSING | |
112 | S_00016C_EFFECTIVE_L1_CACHE_SIZE(1) | |
Line 99... | Line 113... | ||
99 | RS600_EFFECTIVE_L1_QUEUE_SIZE(3))); |
113 | S_00016C_ENABLE_FRAGMENT_PROCESSING(1) | |
100 | } |
114 | S_00016C_EFFECTIVE_L1_QUEUE_SIZE(1)); |
101 | - | ||
102 | /* System context map to GART space */ |
115 | } |
103 | WREG32_MC(RS600_MC_PT0_SYSTEM_APERTURE_LOW_ADDR, rdev->mc.gtt_location); |
116 | |
- | 117 | /* System context map to GART space */ |
|
104 | tmp = rdev->mc.gtt_location + rdev->mc.gtt_size - 1; |
118 | WREG32_MC(R_000112_MC_PT0_SYSTEM_APERTURE_LOW_ADDR, rdev->mc.gtt_start); |
105 | WREG32_MC(RS600_MC_PT0_SYSTEM_APERTURE_HIGH_ADDR, tmp); |
119 | WREG32_MC(R_000114_MC_PT0_SYSTEM_APERTURE_HIGH_ADDR, rdev->mc.gtt_end); |
106 | 120 | ||
107 | /* enable first context */ |
121 | /* enable first context */ |
108 | WREG32_MC(RS600_MC_PT0_CONTEXT0_FLAT_START_ADDR, rdev->mc.gtt_location); |
122 | WREG32_MC(R_00013C_MC_PT0_CONTEXT0_FLAT_START_ADDR, rdev->mc.gtt_start); |
Line 109... | Line 123... | ||
109 | tmp = rdev->mc.gtt_location + rdev->mc.gtt_size - 1; |
123 | WREG32_MC(R_00014C_MC_PT0_CONTEXT0_FLAT_END_ADDR, rdev->mc.gtt_end); |
110 | WREG32_MC(RS600_MC_PT0_CONTEXT0_FLAT_END_ADDR, tmp); |
124 | WREG32_MC(R_000102_MC_PT0_CONTEXT0_CNTL, |
111 | WREG32_MC(RS600_MC_PT0_CONTEXT0_CNTL, |
125 | S_000102_ENABLE_PAGE_TABLE(1) | |
112 | (RS600_ENABLE_PAGE_TABLE | RS600_PAGE_TABLE_TYPE_FLAT)); |
126 | S_000102_PAGE_TABLE_DEPTH(V_000102_PAGE_TABLE_FLAT)); |
Line 113... | Line 127... | ||
113 | /* disable all other contexts */ |
127 | /* disable all other contexts */ |
114 | for (i = 1; i < 8; i++) { |
128 | for (i = 1; i < 8; i++) { |
115 | WREG32_MC(RS600_MC_PT0_CONTEXT0_CNTL + i, 0); |
129 | WREG32_MC(R_000102_MC_PT0_CONTEXT0_CNTL + i, 0); |
116 | } |
130 | } |
117 | 131 | ||
118 | /* setup the page table */ |
132 | /* setup the page table */ |
119 | WREG32_MC(RS600_MC_PT0_CONTEXT0_FLAT_BASE_ADDR, |
133 | WREG32_MC(R_00012C_MC_PT0_CONTEXT0_FLAT_BASE_ADDR, |
120 | rdev->gart.table_addr); |
134 | rdev->gart.table_addr); |
121 | WREG32_MC(RS600_MC_PT0_CONTEXT0_DEFAULT_READ_ADDR, 0); |
135 | WREG32_MC(R_00011C_MC_PT0_CONTEXT0_DEFAULT_READ_ADDR, 0); |
Line 122... | Line 136... | ||
122 | 136 | ||
123 | /* enable page tables */ |
137 | /* enable page tables */ |
124 | tmp = RREG32_MC(RS600_MC_PT0_CNTL); |
138 | tmp = RREG32_MC(R_000100_MC_PT0_CNTL); |
Line 125... | Line 139... | ||
125 | WREG32_MC(RS600_MC_PT0_CNTL, (tmp | RS600_ENABLE_PT)); |
139 | WREG32_MC(R_000100_MC_PT0_CNTL, (tmp | S_000100_ENABLE_PT(1))); |
126 | tmp = RREG32_MC(RS600_MC_CNTL1); |
140 | tmp = RREG32_MC(R_000009_MC_CNTL1); |
127 | WREG32_MC(RS600_MC_CNTL1, (tmp | RS600_ENABLE_PAGE_TABLES)); |
141 | WREG32_MC(R_000009_MC_CNTL1, (tmp | S_000009_ENABLE_PAGE_TABLES(1))); |
128 | rs600_gart_tlb_flush(rdev); |
142 | rs600_gart_tlb_flush(rdev); |
129 | rdev->gart.ready = true; |
143 | rdev->gart.ready = true; |
130 | return 0; |
144 | return 0; |
131 | } |
145 | } |
132 | 146 | ||
- | 147 | void rs600_gart_disable(struct radeon_device *rdev) |
|
- | 148 | { |
|
- | 149 | uint32_t tmp; |
|
- | 150 | ||
- | 151 | /* FIXME: disable out of gart access */ |
|
- | 152 | WREG32_MC(R_000100_MC_PT0_CNTL, 0); |
|
- | 153 | tmp = RREG32_MC(R_000009_MC_CNTL1); |
|
- | 154 | WREG32_MC(R_000009_MC_CNTL1, tmp & C_000009_ENABLE_PAGE_TABLES); |
|
Line 133... | Line 155... | ||
133 | void rs600_gart_disable(struct radeon_device *rdev) |
155 | if (rdev->gart.table.vram.robj) { |
134 | { |
156 | // radeon_object_kunmap(rdev->gart.table.vram.robj); |
135 | uint32_t tmp; |
157 | // radeon_object_unpin(rdev->gart.table.vram.robj); |
136 | 158 | } |
|
Line 162... | Line 184... | ||
162 | writeq(addr, ((void __iomem *)ptr) + (i * 8)); |
184 | writeq(addr, ((void __iomem *)ptr) + (i * 8)); |
163 | return 0; |
185 | return 0; |
164 | } |
186 | } |
Line 165... | Line 187... | ||
165 | 187 | ||
166 | - | ||
167 | /* |
- | |
168 | * MC. |
188 | |
169 | */ |
189 | |
- | 190 | static inline uint32_t rs600_irq_ack(struct radeon_device *rdev, u32 *r500_disp_int) |
|
170 | void rs600_mc_disable_clients(struct radeon_device *rdev) |
191 | { |
Line 171... | Line 192... | ||
171 | { |
192 | uint32_t irqs = RREG32(R_000044_GEN_INT_STATUS); |
172 | unsigned tmp; |
193 | uint32_t irq_mask = ~C_000044_SW_INT; |
173 | 194 | ||
- | 195 | if (G_000044_DISPLAY_INT_STAT(irqs)) { |
|
- | 196 | *r500_disp_int = RREG32(R_007EDC_DISP_INTERRUPT_STATUS); |
|
174 | if (r100_gui_wait_for_idle(rdev)) { |
197 | if (G_007EDC_LB_D1_VBLANK_INTERRUPT(*r500_disp_int)) { |
175 | printk(KERN_WARNING "Failed to wait GUI idle while " |
- | |
176 | "programming pipes. Bad things might happen.\n"); |
- | |
177 | } |
- | |
178 | - | ||
179 | tmp = RREG32(AVIVO_D1VGA_CONTROL); |
- | |
180 | WREG32(AVIVO_D1VGA_CONTROL, tmp & ~AVIVO_DVGA_CONTROL_MODE_ENABLE); |
- | |
181 | tmp = RREG32(AVIVO_D2VGA_CONTROL); |
- | |
182 | WREG32(AVIVO_D2VGA_CONTROL, tmp & ~AVIVO_DVGA_CONTROL_MODE_ENABLE); |
198 | WREG32(R_006534_D1MODE_VBLANK_STATUS, |
183 | 199 | S_006534_D1MODE_VBLANK_ACK(1)); |
|
184 | tmp = RREG32(AVIVO_D1CRTC_CONTROL); |
- | |
185 | WREG32(AVIVO_D1CRTC_CONTROL, tmp & ~AVIVO_CRTC_EN); |
- | |
186 | tmp = RREG32(AVIVO_D2CRTC_CONTROL); |
- | |
187 | WREG32(AVIVO_D2CRTC_CONTROL, tmp & ~AVIVO_CRTC_EN); |
200 | } |
188 | - | ||
189 | /* make sure all previous write got through */ |
- | |
190 | tmp = RREG32(AVIVO_D2CRTC_CONTROL); |
201 | if (G_007EDC_LB_D2_VBLANK_INTERRUPT(*r500_disp_int)) { |
191 | - | ||
192 | mdelay(1); |
- | |
193 | } |
- | |
194 | - | ||
195 | int rs600_mc_init(struct radeon_device *rdev) |
202 | WREG32(R_006D34_D2MODE_VBLANK_STATUS, |
196 | { |
- | |
197 | uint32_t tmp; |
203 | S_006D34_D2MODE_VBLANK_ACK(1)); |
198 | int r; |
- | |
199 | 204 | } |
|
Line 200... | Line -... | ||
200 | if (r100_debugfs_rbbm_init(rdev)) { |
- | |
201 | DRM_ERROR("Failed to register debugfs file for RBBM !\n"); |
- | |
202 | } |
- | |
203 | - | ||
204 | rs600_gpu_init(rdev); |
- | |
205 | rs600_gart_disable(rdev); |
- | |
206 | - | ||
207 | /* Setup GPU memory space */ |
205 | } else { |
208 | rdev->mc.vram_location = 0xFFFFFFFFUL; |
206 | *r500_disp_int = 0; |
209 | rdev->mc.gtt_location = 0xFFFFFFFFUL; |
207 | } |
210 | r = radeon_mc_setup(rdev); |
- | |
211 | if (r) { |
- | |
212 | return r; |
- | |
213 | } |
- | |
214 | - | ||
215 | /* Program GPU memory space */ |
- | |
216 | /* Enable bus master */ |
- | |
217 | tmp = RREG32(RADEON_BUS_CNTL) & ~RS600_BUS_MASTER_DIS; |
- | |
218 | WREG32(RADEON_BUS_CNTL, tmp); |
- | |
219 | /* FIXME: What does AGP means for such chipset ? */ |
- | |
220 | WREG32_MC(RS600_MC_AGP_LOCATION, 0x0FFFFFFF); |
- | |
221 | /* FIXME: are this AGP reg in indirect MC range ? */ |
- | |
222 | WREG32_MC(RS600_MC_AGP_BASE, 0); |
- | |
223 | WREG32_MC(RS600_MC_AGP_BASE_2, 0); |
- | |
224 | rs600_mc_disable_clients(rdev); |
- | |
225 | if (rs600_mc_wait_for_idle(rdev)) { |
- | |
226 | printk(KERN_WARNING "Failed to wait MC idle while " |
- | |
227 | "programming pipes. Bad things might happen.\n"); |
- | |
228 | } |
- | |
229 | tmp = rdev->mc.vram_location + rdev->mc.mc_vram_size - 1; |
- | |
230 | tmp = REG_SET(RS600_MC_FB_TOP, tmp >> 16); |
208 | |
231 | tmp |= REG_SET(RS600_MC_FB_START, rdev->mc.vram_location >> 16); |
209 | if (irqs) { |
Line 232... | Line 210... | ||
232 | WREG32_MC(RS600_MC_FB_LOCATION, tmp); |
210 | WREG32(R_000044_GEN_INT_STATUS, irqs); |
233 | WREG32(RS690_HDP_FB_LOCATION, rdev->mc.vram_location >> 16); |
211 | } |
- | 212 | return irqs & irq_mask; |
|
- | 213 | } |
|
234 | return 0; |
214 | |
- | 215 | void rs600_irq_disable(struct radeon_device *rdev) |
|
235 | } |
216 | { |
- | 217 | u32 tmp; |
|
236 | 218 | ||
237 | void rs600_mc_fini(struct radeon_device *rdev) |
219 | WREG32(R_000040_GEN_INT_CNTL, 0); |
Line 238... | Line -... | ||
238 | { |
- | |
239 | rs600_gart_disable(rdev); |
- | |
240 | radeon_gart_table_vram_free(rdev); |
- | |
241 | radeon_gart_fini(rdev); |
220 | WREG32(R_006540_DxMODE_INT_MASK, 0); |
242 | } |
221 | /* Wait and acknowledge irq */ |
243 | - | ||
244 | - | ||
245 | /* |
- | |
246 | * Global GPU functions |
222 | mdelay(1); |
247 | */ |
223 | rs600_irq_ack(rdev, &tmp); |
248 | void rs600_disable_vga(struct radeon_device *rdev) |
224 | } |
249 | { |
- | |
250 | unsigned tmp; |
- | |
251 | 225 | ||
252 | WREG32(0x330, 0); |
- | |
253 | WREG32(0x338, 0); |
226 | |
Line 254... | Line 227... | ||
254 | tmp = RREG32(0x300); |
227 | u32 rs600_get_vblank_counter(struct radeon_device *rdev, int crtc) |
255 | tmp &= ~(3 << 16); |
228 | { |
256 | WREG32(0x300, tmp); |
229 | if (crtc == 0) |
257 | WREG32(0x308, (1 << 8)); |
- | |
Line 258... | Line 230... | ||
258 | WREG32(0x310, rdev->mc.vram_location); |
230 | return RREG32(R_0060A4_D1CRTC_STATUS_FRAME_COUNT); |
259 | WREG32(0x594, 0); |
- | |
260 | } |
231 | else |
261 | - | ||
262 | int rs600_mc_wait_for_idle(struct radeon_device *rdev) |
232 | return RREG32(R_0068A4_D2CRTC_STATUS_FRAME_COUNT); |
263 | { |
- | |
264 | unsigned i; |
233 | } |
265 | uint32_t tmp; |
234 | |
266 | 235 | int rs600_mc_wait_for_idle(struct radeon_device *rdev) |
|
267 | for (i = 0; i < rdev->usec_timeout; i++) { |
236 | { |
Line 268... | Line -... | ||
268 | /* read MC_STATUS */ |
- | |
269 | tmp = RREG32_MC(RS600_MC_STATUS); |
- | |
270 | if (tmp & RS600_MC_STATUS_IDLE) { |
- | |
271 | return 0; |
- | |
272 | } |
- | |
273 | DRM_UDELAY(1); |
237 | unsigned i; |
274 | } |
238 | |
275 | return -1; |
239 | for (i = 0; i < rdev->usec_timeout; i++) { |
276 | } |
240 | if (G_000000_MC_IDLE(RREG32_MC(R_000000_MC_STATUS))) |
277 | - | ||
278 | void rs600_errata(struct radeon_device *rdev) |
241 | return 0; |
279 | { |
242 | udelay(1); |
- | 243 | } |
|
280 | rdev->pll_errata = 0; |
244 | return -1; |
281 | } |
- | |
282 | 245 | } |
|
283 | void rs600_gpu_init(struct radeon_device *rdev) |
- | |
284 | { |
246 | |
Line 285... | Line -... | ||
285 | /* FIXME: HDP same place on rs600 ? */ |
- | |
286 | r100_hdp_reset(rdev); |
- | |
287 | rs600_disable_vga(rdev); |
- | |
288 | /* FIXME: is this correct ? */ |
- | |
289 | r420_pipes_init(rdev); |
247 | void rs600_gpu_init(struct radeon_device *rdev) |
290 | if (rs600_mc_wait_for_idle(rdev)) { |
248 | { |
291 | printk(KERN_WARNING "Failed to wait MC idle while " |
249 | /* FIXME: HDP same place on rs600 ? */ |
292 | "programming pipes. Bad things might happen.\n"); |
250 | r100_hdp_reset(rdev); |
293 | } |
251 | /* FIXME: is this correct ? */ |
Line 307... | Line 265... | ||
307 | void rs600_bandwidth_update(struct radeon_device *rdev) |
265 | void rs600_bandwidth_update(struct radeon_device *rdev) |
308 | { |
266 | { |
309 | /* FIXME: implement, should this be like rs690 ? */ |
267 | /* FIXME: implement, should this be like rs690 ? */ |
310 | } |
268 | } |
Line 311... | Line -... | ||
311 | - | ||
312 | - | ||
313 | /* |
- | |
314 | * Indirect registers accessor |
- | |
315 | */ |
269 | |
316 | uint32_t rs600_mc_rreg(struct radeon_device *rdev, uint32_t reg) |
270 | uint32_t rs600_mc_rreg(struct radeon_device *rdev, uint32_t reg) |
- | 271 | { |
|
- | 272 | WREG32(R_000070_MC_IND_INDEX, S_000070_MC_IND_ADDR(reg) | |
|
- | 273 | S_000070_MC_IND_CITF_ARB0(1)); |
|
- | 274 | return RREG32(R_000074_MC_IND_DATA); |
|
- | 275 | } |
|
- | 276 | ||
- | 277 | void rs600_mc_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v) |
|
- | 278 | { |
|
- | 279 | WREG32(R_000070_MC_IND_INDEX, S_000070_MC_IND_ADDR(reg) | |
|
- | 280 | S_000070_MC_IND_CITF_ARB0(1) | S_000070_MC_IND_WR_EN(1)); |
|
- | 281 | WREG32(R_000074_MC_IND_DATA, v); |
|
- | 282 | } |
|
- | 283 | ||
- | 284 | void rs600_debugfs(struct radeon_device *rdev) |
|
- | 285 | { |
|
- | 286 | if (r100_debugfs_rbbm_init(rdev)) |
|
- | 287 | DRM_ERROR("Failed to register debugfs file for RBBM !\n"); |
|
- | 288 | } |
|
- | 289 | ||
- | 290 | void rs600_set_safe_registers(struct radeon_device *rdev) |
|
- | 291 | { |
|
- | 292 | rdev->config.r300.reg_safe_bm = rs600_reg_safe_bm; |
|
- | 293 | rdev->config.r300.reg_safe_bm_size = ARRAY_SIZE(rs600_reg_safe_bm); |
|
- | 294 | } |
|
- | 295 | ||
- | 296 | static void rs600_mc_program(struct radeon_device *rdev) |
|
- | 297 | { |
|
- | 298 | struct rv515_mc_save save; |
|
- | 299 | ||
- | 300 | /* Stops all mc clients */ |
|
- | 301 | rv515_mc_stop(rdev, &save); |
|
- | 302 | ||
- | 303 | /* Wait for mc idle */ |
|
- | 304 | if (rs600_mc_wait_for_idle(rdev)) |
|
- | 305 | dev_warn(rdev->dev, "Wait MC idle timeout before updating MC.\n"); |
|
- | 306 | ||
- | 307 | /* FIXME: What does AGP means for such chipset ? */ |
|
- | 308 | WREG32_MC(R_000005_MC_AGP_LOCATION, 0x0FFFFFFF); |
|
- | 309 | WREG32_MC(R_000006_AGP_BASE, 0); |
|
- | 310 | WREG32_MC(R_000007_AGP_BASE_2, 0); |
|
- | 311 | /* Program MC */ |
|
- | 312 | WREG32_MC(R_000004_MC_FB_LOCATION, |
|
- | 313 | S_000004_MC_FB_START(rdev->mc.vram_start >> 16) | |
|
- | 314 | S_000004_MC_FB_TOP(rdev->mc.vram_end >> 16)); |
|
- | 315 | WREG32(R_000134_HDP_FB_LOCATION, |
|
- | 316 | S_000134_HDP_FB_START(rdev->mc.vram_start >> 16)); |
|
- | 317 | ||
- | 318 | rv515_mc_resume(rdev, &save); |
|
- | 319 | } |
|
- | 320 | ||
- | 321 | static int rs600_startup(struct radeon_device *rdev) |
|
317 | { |
322 | { |
Line -... | Line 323... | ||
- | 323 | int r; |
|
- | 324 | ||
- | 325 | rs600_mc_program(rdev); |
|
- | 326 | /* Resume clock */ |
|
318 | uint32_t r; |
327 | rv515_clock_startup(rdev); |
319 | 328 | /* Initialize GPU configuration (# pipes, ...) */ |
|
- | 329 | rs600_gpu_init(rdev); |
|
320 | WREG32(RS600_MC_INDEX, |
330 | /* Initialize GART (initialize after TTM so we can allocate |
- | 331 | * memory through TTM but finalize after TTM) */ |
|
321 | ((reg & RS600_MC_ADDR_MASK) | RS600_MC_IND_CITF_ARB0)); |
332 | r = rs600_gart_enable(rdev); |
- | 333 | if (r) |
|
- | 334 | return r; |
|
- | 335 | /* Enable IRQ */ |
|
- | 336 | // rdev->irq.sw_int = true; |
|
- | 337 | // rs600_irq_set(rdev); |
|
- | 338 | /* 1M ring buffer */ |
|
- | 339 | // r = r100_cp_init(rdev, 1024 * 1024); |
|
- | 340 | // if (r) { |
|
- | 341 | // dev_err(rdev->dev, "failled initializing CP (%d).\n", r); |
|
- | 342 | // return r; |
|
- | 343 | // } |
|
- | 344 | // r = r100_wb_init(rdev); |
|
- | 345 | // if (r) |
|
- | 346 | // dev_err(rdev->dev, "failled initializing WB (%d).\n", r); |
|
- | 347 | // r = r100_ib_init(rdev); |
|
- | 348 | // if (r) { |
|
- | 349 | // dev_err(rdev->dev, "failled initializing IB (%d).\n", r); |
|
- | 350 | // return r; |
|
322 | r = RREG32(RS600_MC_DATA); |
351 | // } |
Line -... | Line 352... | ||
- | 352 | return 0; |
|
- | 353 | } |
|
323 | return r; |
354 | |
324 | } |
355 | |
- | 356 | ||
- | 357 | int rs600_init(struct radeon_device *rdev) |
|
- | 358 | { |
|
- | 359 | int r; |
|
- | 360 | ||
- | 361 | /* Disable VGA */ |
|
- | 362 | rv515_vga_render_disable(rdev); |
|
- | 363 | /* Initialize scratch registers */ |
|
- | 364 | radeon_scratch_init(rdev); |
|
- | 365 | /* Initialize surface registers */ |
|
- | 366 | radeon_surface_init(rdev); |
|
- | 367 | /* BIOS */ |
|
- | 368 | if (!radeon_get_bios(rdev)) { |
|
- | 369 | if (ASIC_IS_AVIVO(rdev)) |
|
- | 370 | return -EINVAL; |
|
- | 371 | } |
|
- | 372 | if (rdev->is_atom_bios) { |
|
- | 373 | r = radeon_atombios_init(rdev); |
|
- | 374 | if (r) |
|
- | 375 | return r; |
|
- | 376 | } else { |
|
- | 377 | dev_err(rdev->dev, "Expecting atombios for RS600 GPU\n"); |
|
- | 378 | return -EINVAL; |
|
- | 379 | } |
|
- | 380 | /* Reset gpu before posting otherwise ATOM will enter infinite loop */ |
|
- | 381 | if (radeon_gpu_reset(rdev)) { |
|
325 | 382 | dev_warn(rdev->dev, |
|
- | 383 | "GPU reset failed ! (0xE40=0x%08X, 0x7C0=0x%08X)\n", |
|
- | 384 | RREG32(R_000E40_RBBM_STATUS), |
|
- | 385 | RREG32(R_0007C0_CP_STAT)); |
|
- | 386 | } |
|
326 | void rs600_mc_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v) |
387 | /* check if cards are posted or not */ |
- | 388 | if (!radeon_card_posted(rdev) && rdev->bios) { |
|
- | 389 | DRM_INFO("GPU not posted. posting now...\n"); |
|
- | 390 | atom_asic_init(rdev->mode_info.atom_context); |
|
- | 391 | } |
|
- | 392 | /* Initialize clocks */ |
|
- | 393 | radeon_get_clock_info(rdev->ddev); |
|
- | 394 | /* Get vram informations */ |
|
- | 395 | rs600_vram_info(rdev); |
|
- | 396 | /* Initialize memory controller (also test AGP) */ |
|
- | 397 | r = r420_mc_init(rdev); |
|
- | 398 | if (r) |
|
- | 399 | return r; |
|
- | 400 | rs600_debugfs(rdev); |
|
- | 401 | /* Fence driver */ |
|
- | 402 | // r = radeon_fence_driver_init(rdev); |
|
- | 403 | // if (r) |
|
- | 404 | // return r; |
|
- | 405 | // r = radeon_irq_kms_init(rdev); |
|
- | 406 | // if (r) |
|
- | 407 | // return r; |
|
- | 408 | /* Memory manager */ |
|
327 | { |
409 | r = radeon_object_init(rdev); |
- | 410 | if (r) |
|
- | 411 | return r; |
|
- | 412 | r = rs600_gart_init(rdev); |
|
- | 413 | if (r) |
|
328 | WREG32(RS600_MC_INDEX, |
414 | return r; |
- | 415 | rs600_set_safe_registers(rdev); |
|
- | 416 | rdev->accel_working = true; |
|
- | 417 | r = rs600_startup(rdev); |
|
- | 418 | if (r) { |
|
- | 419 | /* Somethings want wront with the accel init stop accel */ |
|
- | 420 | dev_err(rdev->dev, "Disabling GPU acceleration\n"); |
|
- | 421 | // rs600_suspend(rdev); |
|
- | 422 | // r100_cp_fini(rdev); |
|
- | 423 | // r100_wb_fini(rdev); |
|
- | 424 | // r100_ib_fini(rdev); |
|
- | 425 | rs600_gart_fini(rdev); |
|
- | 426 | // radeon_irq_kms_fini(rdev); |
|
329 | RS600_MC_IND_WR_EN | RS600_MC_IND_CITF_ARB0 | |
427 | rdev->accel_working = false; |