diff options
author | Dave Airlie <airlied@redhat.com> | 2009-10-08 00:03:05 -0400 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2009-10-08 00:03:05 -0400 |
commit | c1176d6f03e1085797ce83648a2c76ae15a2b515 (patch) | |
tree | f9796cf97a6fbc75a486b1e4f6406d1f8f599a48 /drivers/gpu/drm/radeon/r100.c | |
parent | 0eca52a92735f43462165efe00a7e394345fb38e (diff) | |
parent | d4ac6a05d51357e31028cc9076874a58dd197b83 (diff) |
Merge branch 'drm-next' of ../drm-next into drm-linus
conflict in radeon since new init path merged with vga arb code.
Conflicts:
drivers/gpu/drm/radeon/radeon.h
drivers/gpu/drm/radeon/radeon_asic.h
drivers/gpu/drm/radeon/radeon_device.c
Diffstat (limited to 'drivers/gpu/drm/radeon/r100.c')
-rw-r--r-- | drivers/gpu/drm/radeon/r100.c | 432 |
1 files changed, 269 insertions, 163 deletions
diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c index e6cce24de802..161094c07d94 100644 --- a/drivers/gpu/drm/radeon/r100.c +++ b/drivers/gpu/drm/radeon/r100.c | |||
@@ -32,6 +32,9 @@ | |||
32 | #include "radeon_reg.h" | 32 | #include "radeon_reg.h" |
33 | #include "radeon.h" | 33 | #include "radeon.h" |
34 | #include "r100d.h" | 34 | #include "r100d.h" |
35 | #include "rs100d.h" | ||
36 | #include "rv200d.h" | ||
37 | #include "rv250d.h" | ||
35 | 38 | ||
36 | #include <linux/firmware.h> | 39 | #include <linux/firmware.h> |
37 | #include <linux/platform_device.h> | 40 | #include <linux/platform_device.h> |
@@ -60,18 +63,7 @@ MODULE_FIRMWARE(FIRMWARE_R520); | |||
60 | 63 | ||
61 | /* This files gather functions specifics to: | 64 | /* This files gather functions specifics to: |
62 | * r100,rv100,rs100,rv200,rs200,r200,rv250,rs300,rv280 | 65 | * r100,rv100,rs100,rv200,rs200,r200,rv250,rs300,rv280 |
63 | * | ||
64 | * Some of these functions might be used by newer ASICs. | ||
65 | */ | 66 | */ |
66 | int r200_init(struct radeon_device *rdev); | ||
67 | void r100_hdp_reset(struct radeon_device *rdev); | ||
68 | void r100_gpu_init(struct radeon_device *rdev); | ||
69 | int r100_gui_wait_for_idle(struct radeon_device *rdev); | ||
70 | int r100_mc_wait_for_idle(struct radeon_device *rdev); | ||
71 | void r100_gpu_wait_for_vsync(struct radeon_device *rdev); | ||
72 | void r100_gpu_wait_for_vsync2(struct radeon_device *rdev); | ||
73 | int r100_debugfs_mc_info_init(struct radeon_device *rdev); | ||
74 | |||
75 | 67 | ||
76 | /* | 68 | /* |
77 | * PCI GART | 69 | * PCI GART |
@@ -152,136 +144,6 @@ void r100_pci_gart_fini(struct radeon_device *rdev) | |||
152 | radeon_gart_fini(rdev); | 144 | radeon_gart_fini(rdev); |
153 | } | 145 | } |
154 | 146 | ||
155 | |||
156 | /* | ||
157 | * MC | ||
158 | */ | ||
159 | void r100_mc_disable_clients(struct radeon_device *rdev) | ||
160 | { | ||
161 | uint32_t ov0_scale_cntl, crtc_ext_cntl, crtc_gen_cntl, crtc2_gen_cntl; | ||
162 | |||
163 | /* FIXME: is this function correct for rs100,rs200,rs300 ? */ | ||
164 | if (r100_gui_wait_for_idle(rdev)) { | ||
165 | printk(KERN_WARNING "Failed to wait GUI idle while " | ||
166 | "programming pipes. Bad things might happen.\n"); | ||
167 | } | ||
168 | |||
169 | /* stop display and memory access */ | ||
170 | ov0_scale_cntl = RREG32(RADEON_OV0_SCALE_CNTL); | ||
171 | WREG32(RADEON_OV0_SCALE_CNTL, ov0_scale_cntl & ~RADEON_SCALER_ENABLE); | ||
172 | crtc_ext_cntl = RREG32(RADEON_CRTC_EXT_CNTL); | ||
173 | WREG32(RADEON_CRTC_EXT_CNTL, crtc_ext_cntl | RADEON_CRTC_DISPLAY_DIS); | ||
174 | crtc_gen_cntl = RREG32(RADEON_CRTC_GEN_CNTL); | ||
175 | |||
176 | r100_gpu_wait_for_vsync(rdev); | ||
177 | |||
178 | WREG32(RADEON_CRTC_GEN_CNTL, | ||
179 | (crtc_gen_cntl & ~(RADEON_CRTC_CUR_EN | RADEON_CRTC_ICON_EN)) | | ||
180 | RADEON_CRTC_DISP_REQ_EN_B | RADEON_CRTC_EXT_DISP_EN); | ||
181 | |||
182 | if (!(rdev->flags & RADEON_SINGLE_CRTC)) { | ||
183 | crtc2_gen_cntl = RREG32(RADEON_CRTC2_GEN_CNTL); | ||
184 | |||
185 | r100_gpu_wait_for_vsync2(rdev); | ||
186 | WREG32(RADEON_CRTC2_GEN_CNTL, | ||
187 | (crtc2_gen_cntl & | ||
188 | ~(RADEON_CRTC2_CUR_EN | RADEON_CRTC2_ICON_EN)) | | ||
189 | RADEON_CRTC2_DISP_REQ_EN_B); | ||
190 | } | ||
191 | |||
192 | udelay(500); | ||
193 | } | ||
194 | |||
195 | void r100_mc_setup(struct radeon_device *rdev) | ||
196 | { | ||
197 | uint32_t tmp; | ||
198 | int r; | ||
199 | |||
200 | r = r100_debugfs_mc_info_init(rdev); | ||
201 | if (r) { | ||
202 | DRM_ERROR("Failed to register debugfs file for R100 MC !\n"); | ||
203 | } | ||
204 | /* Write VRAM size in case we are limiting it */ | ||
205 | WREG32(RADEON_CONFIG_MEMSIZE, rdev->mc.real_vram_size); | ||
206 | /* Novell bug 204882 for RN50/M6/M7 with 8/16/32MB VRAM, | ||
207 | * if the aperture is 64MB but we have 32MB VRAM | ||
208 | * we report only 32MB VRAM but we have to set MC_FB_LOCATION | ||
209 | * to 64MB, otherwise the gpu accidentially dies */ | ||
210 | tmp = rdev->mc.vram_location + rdev->mc.mc_vram_size - 1; | ||
211 | tmp = REG_SET(RADEON_MC_FB_TOP, tmp >> 16); | ||
212 | tmp |= REG_SET(RADEON_MC_FB_START, rdev->mc.vram_location >> 16); | ||
213 | WREG32(RADEON_MC_FB_LOCATION, tmp); | ||
214 | |||
215 | /* Enable bus mastering */ | ||
216 | tmp = RREG32(RADEON_BUS_CNTL) & ~RADEON_BUS_MASTER_DIS; | ||
217 | WREG32(RADEON_BUS_CNTL, tmp); | ||
218 | |||
219 | if (rdev->flags & RADEON_IS_AGP) { | ||
220 | tmp = rdev->mc.gtt_location + rdev->mc.gtt_size - 1; | ||
221 | tmp = REG_SET(RADEON_MC_AGP_TOP, tmp >> 16); | ||
222 | tmp |= REG_SET(RADEON_MC_AGP_START, rdev->mc.gtt_location >> 16); | ||
223 | WREG32(RADEON_MC_AGP_LOCATION, tmp); | ||
224 | WREG32(RADEON_AGP_BASE, rdev->mc.agp_base); | ||
225 | } else { | ||
226 | WREG32(RADEON_MC_AGP_LOCATION, 0x0FFFFFFF); | ||
227 | WREG32(RADEON_AGP_BASE, 0); | ||
228 | } | ||
229 | |||
230 | tmp = RREG32(RADEON_HOST_PATH_CNTL) & RADEON_HDP_APER_CNTL; | ||
231 | tmp |= (7 << 28); | ||
232 | WREG32(RADEON_HOST_PATH_CNTL, tmp | RADEON_HDP_SOFT_RESET | RADEON_HDP_READ_BUFFER_INVALIDATE); | ||
233 | (void)RREG32(RADEON_HOST_PATH_CNTL); | ||
234 | WREG32(RADEON_HOST_PATH_CNTL, tmp); | ||
235 | (void)RREG32(RADEON_HOST_PATH_CNTL); | ||
236 | } | ||
237 | |||
238 | int r100_mc_init(struct radeon_device *rdev) | ||
239 | { | ||
240 | int r; | ||
241 | |||
242 | if (r100_debugfs_rbbm_init(rdev)) { | ||
243 | DRM_ERROR("Failed to register debugfs file for RBBM !\n"); | ||
244 | } | ||
245 | |||
246 | r100_gpu_init(rdev); | ||
247 | /* Disable gart which also disable out of gart access */ | ||
248 | r100_pci_gart_disable(rdev); | ||
249 | |||
250 | /* Setup GPU memory space */ | ||
251 | rdev->mc.gtt_location = 0xFFFFFFFFUL; | ||
252 | if (rdev->flags & RADEON_IS_AGP) { | ||
253 | r = radeon_agp_init(rdev); | ||
254 | if (r) { | ||
255 | printk(KERN_WARNING "[drm] Disabling AGP\n"); | ||
256 | rdev->flags &= ~RADEON_IS_AGP; | ||
257 | rdev->mc.gtt_size = radeon_gart_size * 1024 * 1024; | ||
258 | } else { | ||
259 | rdev->mc.gtt_location = rdev->mc.agp_base; | ||
260 | } | ||
261 | } | ||
262 | r = radeon_mc_setup(rdev); | ||
263 | if (r) { | ||
264 | return r; | ||
265 | } | ||
266 | |||
267 | r100_mc_disable_clients(rdev); | ||
268 | if (r100_mc_wait_for_idle(rdev)) { | ||
269 | printk(KERN_WARNING "Failed to wait MC idle while " | ||
270 | "programming pipes. Bad things might happen.\n"); | ||
271 | } | ||
272 | |||
273 | r100_mc_setup(rdev); | ||
274 | return 0; | ||
275 | } | ||
276 | |||
277 | void r100_mc_fini(struct radeon_device *rdev) | ||
278 | { | ||
279 | } | ||
280 | |||
281 | |||
282 | /* | ||
283 | * Interrupts | ||
284 | */ | ||
285 | int r100_irq_set(struct radeon_device *rdev) | 147 | int r100_irq_set(struct radeon_device *rdev) |
286 | { | 148 | { |
287 | uint32_t tmp = 0; | 149 | uint32_t tmp = 0; |
@@ -358,10 +220,6 @@ u32 r100_get_vblank_counter(struct radeon_device *rdev, int crtc) | |||
358 | return RREG32(RADEON_CRTC2_CRNT_FRAME); | 220 | return RREG32(RADEON_CRTC2_CRNT_FRAME); |
359 | } | 221 | } |
360 | 222 | ||
361 | |||
362 | /* | ||
363 | * Fence emission | ||
364 | */ | ||
365 | void r100_fence_ring_emit(struct radeon_device *rdev, | 223 | void r100_fence_ring_emit(struct radeon_device *rdev, |
366 | struct radeon_fence *fence) | 224 | struct radeon_fence *fence) |
367 | { | 225 | { |
@@ -377,10 +235,6 @@ void r100_fence_ring_emit(struct radeon_device *rdev, | |||
377 | radeon_ring_write(rdev, RADEON_SW_INT_FIRE); | 235 | radeon_ring_write(rdev, RADEON_SW_INT_FIRE); |
378 | } | 236 | } |
379 | 237 | ||
380 | |||
381 | /* | ||
382 | * Writeback | ||
383 | */ | ||
384 | int r100_wb_init(struct radeon_device *rdev) | 238 | int r100_wb_init(struct radeon_device *rdev) |
385 | { | 239 | { |
386 | int r; | 240 | int r; |
@@ -504,10 +358,6 @@ int r100_copy_blit(struct radeon_device *rdev, | |||
504 | return r; | 358 | return r; |
505 | } | 359 | } |
506 | 360 | ||
507 | |||
508 | /* | ||
509 | * CP | ||
510 | */ | ||
511 | static int r100_cp_wait_for_idle(struct radeon_device *rdev) | 361 | static int r100_cp_wait_for_idle(struct radeon_device *rdev) |
512 | { | 362 | { |
513 | unsigned i; | 363 | unsigned i; |
@@ -612,6 +462,7 @@ static int r100_cp_init_microcode(struct radeon_device *rdev) | |||
612 | } | 462 | } |
613 | return err; | 463 | return err; |
614 | } | 464 | } |
465 | |||
615 | static void r100_cp_load_microcode(struct radeon_device *rdev) | 466 | static void r100_cp_load_microcode(struct radeon_device *rdev) |
616 | { | 467 | { |
617 | const __be32 *fw_data; | 468 | const __be32 *fw_data; |
@@ -978,7 +829,7 @@ int r100_cs_packet_parse_vline(struct radeon_cs_parser *p) | |||
978 | 829 | ||
979 | header = radeon_get_ib_value(p, h_idx); | 830 | header = radeon_get_ib_value(p, h_idx); |
980 | crtc_id = radeon_get_ib_value(p, h_idx + 5); | 831 | crtc_id = radeon_get_ib_value(p, h_idx + 5); |
981 | reg = header >> 2; | 832 | reg = CP_PACKET0_GET_REG(header); |
982 | mutex_lock(&p->rdev->ddev->mode_config.mutex); | 833 | mutex_lock(&p->rdev->ddev->mode_config.mutex); |
983 | obj = drm_mode_object_find(p->rdev->ddev, crtc_id, DRM_MODE_OBJECT_CRTC); | 834 | obj = drm_mode_object_find(p->rdev->ddev, crtc_id, DRM_MODE_OBJECT_CRTC); |
984 | if (!obj) { | 835 | if (!obj) { |
@@ -1990,7 +1841,7 @@ void r100_pll_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v) | |||
1990 | r100_pll_errata_after_data(rdev); | 1841 | r100_pll_errata_after_data(rdev); |
1991 | } | 1842 | } |
1992 | 1843 | ||
1993 | int r100_init(struct radeon_device *rdev) | 1844 | void r100_set_safe_registers(struct radeon_device *rdev) |
1994 | { | 1845 | { |
1995 | if (ASIC_IS_RN50(rdev)) { | 1846 | if (ASIC_IS_RN50(rdev)) { |
1996 | rdev->config.r100.reg_safe_bm = rn50_reg_safe_bm; | 1847 | rdev->config.r100.reg_safe_bm = rn50_reg_safe_bm; |
@@ -1999,9 +1850,8 @@ int r100_init(struct radeon_device *rdev) | |||
1999 | rdev->config.r100.reg_safe_bm = r100_reg_safe_bm; | 1850 | rdev->config.r100.reg_safe_bm = r100_reg_safe_bm; |
2000 | rdev->config.r100.reg_safe_bm_size = ARRAY_SIZE(r100_reg_safe_bm); | 1851 | rdev->config.r100.reg_safe_bm_size = ARRAY_SIZE(r100_reg_safe_bm); |
2001 | } else { | 1852 | } else { |
2002 | return r200_init(rdev); | 1853 | r200_set_safe_registers(rdev); |
2003 | } | 1854 | } |
2004 | return 0; | ||
2005 | } | 1855 | } |
2006 | 1856 | ||
2007 | /* | 1857 | /* |
@@ -2299,9 +2149,11 @@ void r100_bandwidth_update(struct radeon_device *rdev) | |||
2299 | mode1 = &rdev->mode_info.crtcs[0]->base.mode; | 2149 | mode1 = &rdev->mode_info.crtcs[0]->base.mode; |
2300 | pixel_bytes1 = rdev->mode_info.crtcs[0]->base.fb->bits_per_pixel / 8; | 2150 | pixel_bytes1 = rdev->mode_info.crtcs[0]->base.fb->bits_per_pixel / 8; |
2301 | } | 2151 | } |
2302 | if (rdev->mode_info.crtcs[1]->base.enabled) { | 2152 | if (!(rdev->flags & RADEON_SINGLE_CRTC)) { |
2303 | mode2 = &rdev->mode_info.crtcs[1]->base.mode; | 2153 | if (rdev->mode_info.crtcs[1]->base.enabled) { |
2304 | pixel_bytes2 = rdev->mode_info.crtcs[1]->base.fb->bits_per_pixel / 8; | 2154 | mode2 = &rdev->mode_info.crtcs[1]->base.mode; |
2155 | pixel_bytes2 = rdev->mode_info.crtcs[1]->base.fb->bits_per_pixel / 8; | ||
2156 | } | ||
2305 | } | 2157 | } |
2306 | 2158 | ||
2307 | min_mem_eff.full = rfixed_const_8(0); | 2159 | min_mem_eff.full = rfixed_const_8(0); |
@@ -3114,7 +2966,7 @@ void r100_mc_stop(struct radeon_device *rdev, struct r100_mc_save *save) | |||
3114 | WREG32(R_000740_CP_CSQ_CNTL, 0); | 2966 | WREG32(R_000740_CP_CSQ_CNTL, 0); |
3115 | 2967 | ||
3116 | /* Save few CRTC registers */ | 2968 | /* Save few CRTC registers */ |
3117 | save->GENMO_WT = RREG32(R_0003C0_GENMO_WT); | 2969 | save->GENMO_WT = RREG8(R_0003C2_GENMO_WT); |
3118 | save->CRTC_EXT_CNTL = RREG32(R_000054_CRTC_EXT_CNTL); | 2970 | save->CRTC_EXT_CNTL = RREG32(R_000054_CRTC_EXT_CNTL); |
3119 | save->CRTC_GEN_CNTL = RREG32(R_000050_CRTC_GEN_CNTL); | 2971 | save->CRTC_GEN_CNTL = RREG32(R_000050_CRTC_GEN_CNTL); |
3120 | save->CUR_OFFSET = RREG32(R_000260_CUR_OFFSET); | 2972 | save->CUR_OFFSET = RREG32(R_000260_CUR_OFFSET); |
@@ -3124,7 +2976,7 @@ void r100_mc_stop(struct radeon_device *rdev, struct r100_mc_save *save) | |||
3124 | } | 2976 | } |
3125 | 2977 | ||
3126 | /* Disable VGA aperture access */ | 2978 | /* Disable VGA aperture access */ |
3127 | WREG32(R_0003C0_GENMO_WT, C_0003C0_VGA_RAM_EN & save->GENMO_WT); | 2979 | WREG8(R_0003C2_GENMO_WT, C_0003C2_VGA_RAM_EN & save->GENMO_WT); |
3128 | /* Disable cursor, overlay, crtc */ | 2980 | /* Disable cursor, overlay, crtc */ |
3129 | WREG32(R_000260_CUR_OFFSET, save->CUR_OFFSET | S_000260_CUR_LOCK(1)); | 2981 | WREG32(R_000260_CUR_OFFSET, save->CUR_OFFSET | S_000260_CUR_LOCK(1)); |
3130 | WREG32(R_000054_CRTC_EXT_CNTL, save->CRTC_EXT_CNTL | | 2982 | WREG32(R_000054_CRTC_EXT_CNTL, save->CRTC_EXT_CNTL | |
@@ -3156,10 +3008,264 @@ void r100_mc_resume(struct radeon_device *rdev, struct r100_mc_save *save) | |||
3156 | rdev->mc.vram_location); | 3008 | rdev->mc.vram_location); |
3157 | } | 3009 | } |
3158 | /* Restore CRTC registers */ | 3010 | /* Restore CRTC registers */ |
3159 | WREG32(R_0003C0_GENMO_WT, save->GENMO_WT); | 3011 | WREG8(R_0003C2_GENMO_WT, save->GENMO_WT); |
3160 | WREG32(R_000054_CRTC_EXT_CNTL, save->CRTC_EXT_CNTL); | 3012 | WREG32(R_000054_CRTC_EXT_CNTL, save->CRTC_EXT_CNTL); |
3161 | WREG32(R_000050_CRTC_GEN_CNTL, save->CRTC_GEN_CNTL); | 3013 | WREG32(R_000050_CRTC_GEN_CNTL, save->CRTC_GEN_CNTL); |
3162 | if (!(rdev->flags & RADEON_SINGLE_CRTC)) { | 3014 | if (!(rdev->flags & RADEON_SINGLE_CRTC)) { |
3163 | WREG32(R_0003F8_CRTC2_GEN_CNTL, save->CRTC2_GEN_CNTL); | 3015 | WREG32(R_0003F8_CRTC2_GEN_CNTL, save->CRTC2_GEN_CNTL); |
3164 | } | 3016 | } |
3165 | } | 3017 | } |
3018 | |||
3019 | void r100_vga_render_disable(struct radeon_device *rdev) | ||
3020 | { | ||
3021 | u32 tmp; | ||
3022 | |||
3023 | tmp = RREG8(R_0003C2_GENMO_WT); | ||
3024 | WREG8(R_0003C2_GENMO_WT, C_0003C2_VGA_RAM_EN & tmp); | ||
3025 | } | ||
3026 | |||
3027 | static void r100_debugfs(struct radeon_device *rdev) | ||
3028 | { | ||
3029 | int r; | ||
3030 | |||
3031 | r = r100_debugfs_mc_info_init(rdev); | ||
3032 | if (r) | ||
3033 | dev_warn(rdev->dev, "Failed to create r100_mc debugfs file.\n"); | ||
3034 | } | ||
3035 | |||
3036 | static void r100_mc_program(struct radeon_device *rdev) | ||
3037 | { | ||
3038 | struct r100_mc_save save; | ||
3039 | |||
3040 | /* Stops all mc clients */ | ||
3041 | r100_mc_stop(rdev, &save); | ||
3042 | if (rdev->flags & RADEON_IS_AGP) { | ||
3043 | WREG32(R_00014C_MC_AGP_LOCATION, | ||
3044 | S_00014C_MC_AGP_START(rdev->mc.gtt_start >> 16) | | ||
3045 | S_00014C_MC_AGP_TOP(rdev->mc.gtt_end >> 16)); | ||
3046 | WREG32(R_000170_AGP_BASE, lower_32_bits(rdev->mc.agp_base)); | ||
3047 | if (rdev->family > CHIP_RV200) | ||
3048 | WREG32(R_00015C_AGP_BASE_2, | ||
3049 | upper_32_bits(rdev->mc.agp_base) & 0xff); | ||
3050 | } else { | ||
3051 | WREG32(R_00014C_MC_AGP_LOCATION, 0x0FFFFFFF); | ||
3052 | WREG32(R_000170_AGP_BASE, 0); | ||
3053 | if (rdev->family > CHIP_RV200) | ||
3054 | WREG32(R_00015C_AGP_BASE_2, 0); | ||
3055 | } | ||
3056 | /* Wait for mc idle */ | ||
3057 | if (r100_mc_wait_for_idle(rdev)) | ||
3058 | dev_warn(rdev->dev, "Wait for MC idle timeout.\n"); | ||
3059 | /* Program MC, should be a 32bits limited address space */ | ||
3060 | WREG32(R_000148_MC_FB_LOCATION, | ||
3061 | S_000148_MC_FB_START(rdev->mc.vram_start >> 16) | | ||
3062 | S_000148_MC_FB_TOP(rdev->mc.vram_end >> 16)); | ||
3063 | r100_mc_resume(rdev, &save); | ||
3064 | } | ||
3065 | |||
3066 | void r100_clock_startup(struct radeon_device *rdev) | ||
3067 | { | ||
3068 | u32 tmp; | ||
3069 | |||
3070 | if (radeon_dynclks != -1 && radeon_dynclks) | ||
3071 | radeon_legacy_set_clock_gating(rdev, 1); | ||
3072 | /* We need to force on some of the block */ | ||
3073 | tmp = RREG32_PLL(R_00000D_SCLK_CNTL); | ||
3074 | tmp |= S_00000D_FORCE_CP(1) | S_00000D_FORCE_VIP(1); | ||
3075 | if ((rdev->family == CHIP_RV250) || (rdev->family == CHIP_RV280)) | ||
3076 | tmp |= S_00000D_FORCE_DISP1(1) | S_00000D_FORCE_DISP2(1); | ||
3077 | WREG32_PLL(R_00000D_SCLK_CNTL, tmp); | ||
3078 | } | ||
3079 | |||
3080 | static int r100_startup(struct radeon_device *rdev) | ||
3081 | { | ||
3082 | int r; | ||
3083 | |||
3084 | r100_mc_program(rdev); | ||
3085 | /* Resume clock */ | ||
3086 | r100_clock_startup(rdev); | ||
3087 | /* Initialize GPU configuration (# pipes, ...) */ | ||
3088 | r100_gpu_init(rdev); | ||
3089 | /* Initialize GART (initialize after TTM so we can allocate | ||
3090 | * memory through TTM but finalize after TTM) */ | ||
3091 | if (rdev->flags & RADEON_IS_PCI) { | ||
3092 | r = r100_pci_gart_enable(rdev); | ||
3093 | if (r) | ||
3094 | return r; | ||
3095 | } | ||
3096 | /* Enable IRQ */ | ||
3097 | rdev->irq.sw_int = true; | ||
3098 | r100_irq_set(rdev); | ||
3099 | /* 1M ring buffer */ | ||
3100 | r = r100_cp_init(rdev, 1024 * 1024); | ||
3101 | if (r) { | ||
3102 | dev_err(rdev->dev, "failled initializing CP (%d).\n", r); | ||
3103 | return r; | ||
3104 | } | ||
3105 | r = r100_wb_init(rdev); | ||
3106 | if (r) | ||
3107 | dev_err(rdev->dev, "failled initializing WB (%d).\n", r); | ||
3108 | r = r100_ib_init(rdev); | ||
3109 | if (r) { | ||
3110 | dev_err(rdev->dev, "failled initializing IB (%d).\n", r); | ||
3111 | return r; | ||
3112 | } | ||
3113 | return 0; | ||
3114 | } | ||
3115 | |||
3116 | int r100_resume(struct radeon_device *rdev) | ||
3117 | { | ||
3118 | /* Make sur GART are not working */ | ||
3119 | if (rdev->flags & RADEON_IS_PCI) | ||
3120 | r100_pci_gart_disable(rdev); | ||
3121 | /* Resume clock before doing reset */ | ||
3122 | r100_clock_startup(rdev); | ||
3123 | /* Reset gpu before posting otherwise ATOM will enter infinite loop */ | ||
3124 | if (radeon_gpu_reset(rdev)) { | ||
3125 | dev_warn(rdev->dev, "GPU reset failed ! (0xE40=0x%08X, 0x7C0=0x%08X)\n", | ||
3126 | RREG32(R_000E40_RBBM_STATUS), | ||
3127 | RREG32(R_0007C0_CP_STAT)); | ||
3128 | } | ||
3129 | /* post */ | ||
3130 | radeon_combios_asic_init(rdev->ddev); | ||
3131 | /* Resume clock after posting */ | ||
3132 | r100_clock_startup(rdev); | ||
3133 | return r100_startup(rdev); | ||
3134 | } | ||
3135 | |||
3136 | int r100_suspend(struct radeon_device *rdev) | ||
3137 | { | ||
3138 | r100_cp_disable(rdev); | ||
3139 | r100_wb_disable(rdev); | ||
3140 | r100_irq_disable(rdev); | ||
3141 | if (rdev->flags & RADEON_IS_PCI) | ||
3142 | r100_pci_gart_disable(rdev); | ||
3143 | return 0; | ||
3144 | } | ||
3145 | |||
3146 | void r100_fini(struct radeon_device *rdev) | ||
3147 | { | ||
3148 | r100_suspend(rdev); | ||
3149 | r100_cp_fini(rdev); | ||
3150 | r100_wb_fini(rdev); | ||
3151 | r100_ib_fini(rdev); | ||
3152 | radeon_gem_fini(rdev); | ||
3153 | if (rdev->flags & RADEON_IS_PCI) | ||
3154 | r100_pci_gart_fini(rdev); | ||
3155 | radeon_irq_kms_fini(rdev); | ||
3156 | radeon_fence_driver_fini(rdev); | ||
3157 | radeon_object_fini(rdev); | ||
3158 | radeon_atombios_fini(rdev); | ||
3159 | kfree(rdev->bios); | ||
3160 | rdev->bios = NULL; | ||
3161 | } | ||
3162 | |||
3163 | int r100_mc_init(struct radeon_device *rdev) | ||
3164 | { | ||
3165 | int r; | ||
3166 | u32 tmp; | ||
3167 | |||
3168 | /* Setup GPU memory space */ | ||
3169 | rdev->mc.vram_location = 0xFFFFFFFFUL; | ||
3170 | rdev->mc.gtt_location = 0xFFFFFFFFUL; | ||
3171 | if (rdev->flags & RADEON_IS_IGP) { | ||
3172 | tmp = G_00015C_MC_FB_START(RREG32(R_00015C_NB_TOM)); | ||
3173 | rdev->mc.vram_location = tmp << 16; | ||
3174 | } | ||
3175 | if (rdev->flags & RADEON_IS_AGP) { | ||
3176 | r = radeon_agp_init(rdev); | ||
3177 | if (r) { | ||
3178 | printk(KERN_WARNING "[drm] Disabling AGP\n"); | ||
3179 | rdev->flags &= ~RADEON_IS_AGP; | ||
3180 | rdev->mc.gtt_size = radeon_gart_size * 1024 * 1024; | ||
3181 | } else { | ||
3182 | rdev->mc.gtt_location = rdev->mc.agp_base; | ||
3183 | } | ||
3184 | } | ||
3185 | r = radeon_mc_setup(rdev); | ||
3186 | if (r) | ||
3187 | return r; | ||
3188 | return 0; | ||
3189 | } | ||
3190 | |||
3191 | int r100_init(struct radeon_device *rdev) | ||
3192 | { | ||
3193 | int r; | ||
3194 | |||
3195 | /* Register debugfs file specific to this group of asics */ | ||
3196 | r100_debugfs(rdev); | ||
3197 | /* Disable VGA */ | ||
3198 | r100_vga_render_disable(rdev); | ||
3199 | /* Initialize scratch registers */ | ||
3200 | radeon_scratch_init(rdev); | ||
3201 | /* Initialize surface registers */ | ||
3202 | radeon_surface_init(rdev); | ||
3203 | /* TODO: disable VGA need to use VGA request */ | ||
3204 | /* BIOS*/ | ||
3205 | if (!radeon_get_bios(rdev)) { | ||
3206 | if (ASIC_IS_AVIVO(rdev)) | ||
3207 | return -EINVAL; | ||
3208 | } | ||
3209 | if (rdev->is_atom_bios) { | ||
3210 | dev_err(rdev->dev, "Expecting combios for RS400/RS480 GPU\n"); | ||
3211 | return -EINVAL; | ||
3212 | } else { | ||
3213 | r = radeon_combios_init(rdev); | ||
3214 | if (r) | ||
3215 | return r; | ||
3216 | } | ||
3217 | /* Reset gpu before posting otherwise ATOM will enter infinite loop */ | ||
3218 | if (radeon_gpu_reset(rdev)) { | ||
3219 | dev_warn(rdev->dev, | ||
3220 | "GPU reset failed ! (0xE40=0x%08X, 0x7C0=0x%08X)\n", | ||
3221 | RREG32(R_000E40_RBBM_STATUS), | ||
3222 | RREG32(R_0007C0_CP_STAT)); | ||
3223 | } | ||
3224 | /* check if cards are posted or not */ | ||
3225 | if (!radeon_card_posted(rdev) && rdev->bios) { | ||
3226 | DRM_INFO("GPU not posted. posting now...\n"); | ||
3227 | radeon_combios_asic_init(rdev->ddev); | ||
3228 | } | ||
3229 | /* Set asic errata */ | ||
3230 | r100_errata(rdev); | ||
3231 | /* Initialize clocks */ | ||
3232 | radeon_get_clock_info(rdev->ddev); | ||
3233 | /* Get vram informations */ | ||
3234 | r100_vram_info(rdev); | ||
3235 | /* Initialize memory controller (also test AGP) */ | ||
3236 | r = r100_mc_init(rdev); | ||
3237 | if (r) | ||
3238 | return r; | ||
3239 | /* Fence driver */ | ||
3240 | r = radeon_fence_driver_init(rdev); | ||
3241 | if (r) | ||
3242 | return r; | ||
3243 | r = radeon_irq_kms_init(rdev); | ||
3244 | if (r) | ||
3245 | return r; | ||
3246 | /* Memory manager */ | ||
3247 | r = radeon_object_init(rdev); | ||
3248 | if (r) | ||
3249 | return r; | ||
3250 | if (rdev->flags & RADEON_IS_PCI) { | ||
3251 | r = r100_pci_gart_init(rdev); | ||
3252 | if (r) | ||
3253 | return r; | ||
3254 | } | ||
3255 | r100_set_safe_registers(rdev); | ||
3256 | rdev->accel_working = true; | ||
3257 | r = r100_startup(rdev); | ||
3258 | if (r) { | ||
3259 | /* Somethings want wront with the accel init stop accel */ | ||
3260 | dev_err(rdev->dev, "Disabling GPU acceleration\n"); | ||
3261 | r100_suspend(rdev); | ||
3262 | r100_cp_fini(rdev); | ||
3263 | r100_wb_fini(rdev); | ||
3264 | r100_ib_fini(rdev); | ||
3265 | if (rdev->flags & RADEON_IS_PCI) | ||
3266 | r100_pci_gart_fini(rdev); | ||
3267 | radeon_irq_kms_fini(rdev); | ||
3268 | rdev->accel_working = false; | ||
3269 | } | ||
3270 | return 0; | ||
3271 | } | ||