diff options
Diffstat (limited to 'drivers/gpu/drm/radeon/r100.c')
-rw-r--r-- | drivers/gpu/drm/radeon/r100.c | 413 |
1 files changed, 255 insertions, 158 deletions
diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c index dc45ec1d4189..0a475617a70f 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; |
@@ -1976,7 +1827,7 @@ void r100_pll_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v) | |||
1976 | r100_pll_errata_after_data(rdev); | 1827 | r100_pll_errata_after_data(rdev); |
1977 | } | 1828 | } |
1978 | 1829 | ||
1979 | int r100_init(struct radeon_device *rdev) | 1830 | void r100_set_safe_registers(struct radeon_device *rdev) |
1980 | { | 1831 | { |
1981 | if (ASIC_IS_RN50(rdev)) { | 1832 | if (ASIC_IS_RN50(rdev)) { |
1982 | rdev->config.r100.reg_safe_bm = rn50_reg_safe_bm; | 1833 | rdev->config.r100.reg_safe_bm = rn50_reg_safe_bm; |
@@ -1985,9 +1836,8 @@ int r100_init(struct radeon_device *rdev) | |||
1985 | rdev->config.r100.reg_safe_bm = r100_reg_safe_bm; | 1836 | rdev->config.r100.reg_safe_bm = r100_reg_safe_bm; |
1986 | rdev->config.r100.reg_safe_bm_size = ARRAY_SIZE(r100_reg_safe_bm); | 1837 | rdev->config.r100.reg_safe_bm_size = ARRAY_SIZE(r100_reg_safe_bm); |
1987 | } else { | 1838 | } else { |
1988 | return r200_init(rdev); | 1839 | r200_set_safe_registers(rdev); |
1989 | } | 1840 | } |
1990 | return 0; | ||
1991 | } | 1841 | } |
1992 | 1842 | ||
1993 | /* | 1843 | /* |
@@ -3152,8 +3002,255 @@ void r100_mc_resume(struct radeon_device *rdev, struct r100_mc_save *save) | |||
3152 | 3002 | ||
3153 | void r100_vga_render_disable(struct radeon_device *rdev) | 3003 | void r100_vga_render_disable(struct radeon_device *rdev) |
3154 | { | 3004 | { |
3155 | u32 tmp; | 3005 | u32 tmp; |
3156 | 3006 | ||
3157 | tmp = RREG8(R_0003C2_GENMO_WT); | 3007 | tmp = RREG8(R_0003C2_GENMO_WT); |
3158 | WREG8(R_0003C2_GENMO_WT, C_0003C2_VGA_RAM_EN & tmp); | 3008 | WREG8(R_0003C2_GENMO_WT, C_0003C2_VGA_RAM_EN & tmp); |
3159 | } | 3009 | } |
3010 | |||
3011 | static void r100_debugfs(struct radeon_device *rdev) | ||
3012 | { | ||
3013 | int r; | ||
3014 | |||
3015 | r = r100_debugfs_mc_info_init(rdev); | ||
3016 | if (r) | ||
3017 | dev_warn(rdev->dev, "Failed to create r100_mc debugfs file.\n"); | ||
3018 | } | ||
3019 | |||
3020 | static void r100_mc_program(struct radeon_device *rdev) | ||
3021 | { | ||
3022 | struct r100_mc_save save; | ||
3023 | |||
3024 | /* Stops all mc clients */ | ||
3025 | r100_mc_stop(rdev, &save); | ||
3026 | if (rdev->flags & RADEON_IS_AGP) { | ||
3027 | WREG32(R_00014C_MC_AGP_LOCATION, | ||
3028 | S_00014C_MC_AGP_START(rdev->mc.gtt_start >> 16) | | ||
3029 | S_00014C_MC_AGP_TOP(rdev->mc.gtt_end >> 16)); | ||
3030 | WREG32(R_000170_AGP_BASE, lower_32_bits(rdev->mc.agp_base)); | ||
3031 | if (rdev->family > CHIP_RV200) | ||
3032 | WREG32(R_00015C_AGP_BASE_2, | ||
3033 | upper_32_bits(rdev->mc.agp_base) & 0xff); | ||
3034 | } else { | ||
3035 | WREG32(R_00014C_MC_AGP_LOCATION, 0x0FFFFFFF); | ||
3036 | WREG32(R_000170_AGP_BASE, 0); | ||
3037 | if (rdev->family > CHIP_RV200) | ||
3038 | WREG32(R_00015C_AGP_BASE_2, 0); | ||
3039 | } | ||
3040 | /* Wait for mc idle */ | ||
3041 | if (r100_mc_wait_for_idle(rdev)) | ||
3042 | dev_warn(rdev->dev, "Wait for MC idle timeout.\n"); | ||
3043 | /* Program MC, should be a 32bits limited address space */ | ||
3044 | WREG32(R_000148_MC_FB_LOCATION, | ||
3045 | S_000148_MC_FB_START(rdev->mc.vram_start >> 16) | | ||
3046 | S_000148_MC_FB_TOP(rdev->mc.vram_end >> 16)); | ||
3047 | r100_mc_resume(rdev, &save); | ||
3048 | } | ||
3049 | |||
3050 | void r100_clock_startup(struct radeon_device *rdev) | ||
3051 | { | ||
3052 | u32 tmp; | ||
3053 | |||
3054 | if (radeon_dynclks != -1 && radeon_dynclks) | ||
3055 | radeon_legacy_set_clock_gating(rdev, 1); | ||
3056 | /* We need to force on some of the block */ | ||
3057 | tmp = RREG32_PLL(R_00000D_SCLK_CNTL); | ||
3058 | tmp |= S_00000D_FORCE_CP(1) | S_00000D_FORCE_VIP(1); | ||
3059 | if ((rdev->family == CHIP_RV250) || (rdev->family == CHIP_RV280)) | ||
3060 | tmp |= S_00000D_FORCE_DISP1(1) | S_00000D_FORCE_DISP2(1); | ||
3061 | WREG32_PLL(R_00000D_SCLK_CNTL, tmp); | ||
3062 | } | ||
3063 | |||
3064 | static int r100_startup(struct radeon_device *rdev) | ||
3065 | { | ||
3066 | int r; | ||
3067 | |||
3068 | r100_mc_program(rdev); | ||
3069 | /* Resume clock */ | ||
3070 | r100_clock_startup(rdev); | ||
3071 | /* Initialize GPU configuration (# pipes, ...) */ | ||
3072 | r100_gpu_init(rdev); | ||
3073 | /* Initialize GART (initialize after TTM so we can allocate | ||
3074 | * memory through TTM but finalize after TTM) */ | ||
3075 | if (rdev->flags & RADEON_IS_PCI) { | ||
3076 | r = r100_pci_gart_enable(rdev); | ||
3077 | if (r) | ||
3078 | return r; | ||
3079 | } | ||
3080 | /* Enable IRQ */ | ||
3081 | rdev->irq.sw_int = true; | ||
3082 | r100_irq_set(rdev); | ||
3083 | /* 1M ring buffer */ | ||
3084 | r = r100_cp_init(rdev, 1024 * 1024); | ||
3085 | if (r) { | ||
3086 | dev_err(rdev->dev, "failled initializing CP (%d).\n", r); | ||
3087 | return r; | ||
3088 | } | ||
3089 | r = r100_wb_init(rdev); | ||
3090 | if (r) | ||
3091 | dev_err(rdev->dev, "failled initializing WB (%d).\n", r); | ||
3092 | r = r100_ib_init(rdev); | ||
3093 | if (r) { | ||
3094 | dev_err(rdev->dev, "failled initializing IB (%d).\n", r); | ||
3095 | return r; | ||
3096 | } | ||
3097 | return 0; | ||
3098 | } | ||
3099 | |||
3100 | int r100_resume(struct radeon_device *rdev) | ||
3101 | { | ||
3102 | /* Make sur GART are not working */ | ||
3103 | if (rdev->flags & RADEON_IS_PCI) | ||
3104 | r100_pci_gart_disable(rdev); | ||
3105 | /* Resume clock before doing reset */ | ||
3106 | r100_clock_startup(rdev); | ||
3107 | /* Reset gpu before posting otherwise ATOM will enter infinite loop */ | ||
3108 | if (radeon_gpu_reset(rdev)) { | ||
3109 | dev_warn(rdev->dev, "GPU reset failed ! (0xE40=0x%08X, 0x7C0=0x%08X)\n", | ||
3110 | RREG32(R_000E40_RBBM_STATUS), | ||
3111 | RREG32(R_0007C0_CP_STAT)); | ||
3112 | } | ||
3113 | /* post */ | ||
3114 | radeon_combios_asic_init(rdev->ddev); | ||
3115 | /* Resume clock after posting */ | ||
3116 | r100_clock_startup(rdev); | ||
3117 | return r100_startup(rdev); | ||
3118 | } | ||
3119 | |||
3120 | int r100_suspend(struct radeon_device *rdev) | ||
3121 | { | ||
3122 | r100_cp_disable(rdev); | ||
3123 | r100_wb_disable(rdev); | ||
3124 | r100_irq_disable(rdev); | ||
3125 | if (rdev->flags & RADEON_IS_PCI) | ||
3126 | r100_pci_gart_disable(rdev); | ||
3127 | return 0; | ||
3128 | } | ||
3129 | |||
3130 | void r100_fini(struct radeon_device *rdev) | ||
3131 | { | ||
3132 | r100_suspend(rdev); | ||
3133 | r100_cp_fini(rdev); | ||
3134 | r100_wb_fini(rdev); | ||
3135 | r100_ib_fini(rdev); | ||
3136 | radeon_gem_fini(rdev); | ||
3137 | if (rdev->flags & RADEON_IS_PCI) | ||
3138 | r100_pci_gart_fini(rdev); | ||
3139 | radeon_irq_kms_fini(rdev); | ||
3140 | radeon_fence_driver_fini(rdev); | ||
3141 | radeon_object_fini(rdev); | ||
3142 | radeon_atombios_fini(rdev); | ||
3143 | kfree(rdev->bios); | ||
3144 | rdev->bios = NULL; | ||
3145 | } | ||
3146 | |||
3147 | int r100_mc_init(struct radeon_device *rdev) | ||
3148 | { | ||
3149 | int r; | ||
3150 | u32 tmp; | ||
3151 | |||
3152 | /* Setup GPU memory space */ | ||
3153 | rdev->mc.vram_location = 0xFFFFFFFFUL; | ||
3154 | rdev->mc.gtt_location = 0xFFFFFFFFUL; | ||
3155 | if (rdev->flags & RADEON_IS_IGP) { | ||
3156 | tmp = G_00015C_MC_FB_START(RREG32(R_00015C_NB_TOM)); | ||
3157 | rdev->mc.vram_location = tmp << 16; | ||
3158 | } | ||
3159 | if (rdev->flags & RADEON_IS_AGP) { | ||
3160 | r = radeon_agp_init(rdev); | ||
3161 | if (r) { | ||
3162 | printk(KERN_WARNING "[drm] Disabling AGP\n"); | ||
3163 | rdev->flags &= ~RADEON_IS_AGP; | ||
3164 | rdev->mc.gtt_size = radeon_gart_size * 1024 * 1024; | ||
3165 | } else { | ||
3166 | rdev->mc.gtt_location = rdev->mc.agp_base; | ||
3167 | } | ||
3168 | } | ||
3169 | r = radeon_mc_setup(rdev); | ||
3170 | if (r) | ||
3171 | return r; | ||
3172 | return 0; | ||
3173 | } | ||
3174 | |||
3175 | int r100_init(struct radeon_device *rdev) | ||
3176 | { | ||
3177 | int r; | ||
3178 | |||
3179 | rdev->new_init_path = true; | ||
3180 | /* Register debugfs file specific to this group of asics */ | ||
3181 | r100_debugfs(rdev); | ||
3182 | /* Disable VGA */ | ||
3183 | r100_vga_render_disable(rdev); | ||
3184 | /* Initialize scratch registers */ | ||
3185 | radeon_scratch_init(rdev); | ||
3186 | /* Initialize surface registers */ | ||
3187 | radeon_surface_init(rdev); | ||
3188 | /* TODO: disable VGA need to use VGA request */ | ||
3189 | /* BIOS*/ | ||
3190 | if (!radeon_get_bios(rdev)) { | ||
3191 | if (ASIC_IS_AVIVO(rdev)) | ||
3192 | return -EINVAL; | ||
3193 | } | ||
3194 | if (rdev->is_atom_bios) { | ||
3195 | dev_err(rdev->dev, "Expecting combios for RS400/RS480 GPU\n"); | ||
3196 | return -EINVAL; | ||
3197 | } else { | ||
3198 | r = radeon_combios_init(rdev); | ||
3199 | if (r) | ||
3200 | return r; | ||
3201 | } | ||
3202 | /* Reset gpu before posting otherwise ATOM will enter infinite loop */ | ||
3203 | if (radeon_gpu_reset(rdev)) { | ||
3204 | dev_warn(rdev->dev, | ||
3205 | "GPU reset failed ! (0xE40=0x%08X, 0x7C0=0x%08X)\n", | ||
3206 | RREG32(R_000E40_RBBM_STATUS), | ||
3207 | RREG32(R_0007C0_CP_STAT)); | ||
3208 | } | ||
3209 | /* check if cards are posted or not */ | ||
3210 | if (!radeon_card_posted(rdev) && rdev->bios) { | ||
3211 | DRM_INFO("GPU not posted. posting now...\n"); | ||
3212 | radeon_combios_asic_init(rdev->ddev); | ||
3213 | } | ||
3214 | /* Set asic errata */ | ||
3215 | r100_errata(rdev); | ||
3216 | /* Initialize clocks */ | ||
3217 | radeon_get_clock_info(rdev->ddev); | ||
3218 | /* Get vram informations */ | ||
3219 | r100_vram_info(rdev); | ||
3220 | /* Initialize memory controller (also test AGP) */ | ||
3221 | r = r100_mc_init(rdev); | ||
3222 | if (r) | ||
3223 | return r; | ||
3224 | /* Fence driver */ | ||
3225 | r = radeon_fence_driver_init(rdev); | ||
3226 | if (r) | ||
3227 | return r; | ||
3228 | r = radeon_irq_kms_init(rdev); | ||
3229 | if (r) | ||
3230 | return r; | ||
3231 | /* Memory manager */ | ||
3232 | r = radeon_object_init(rdev); | ||
3233 | if (r) | ||
3234 | return r; | ||
3235 | if (rdev->flags & RADEON_IS_PCI) { | ||
3236 | r = r100_pci_gart_init(rdev); | ||
3237 | if (r) | ||
3238 | return r; | ||
3239 | } | ||
3240 | r100_set_safe_registers(rdev); | ||
3241 | rdev->accel_working = true; | ||
3242 | r = r100_startup(rdev); | ||
3243 | if (r) { | ||
3244 | /* Somethings want wront with the accel init stop accel */ | ||
3245 | dev_err(rdev->dev, "Disabling GPU acceleration\n"); | ||
3246 | r100_suspend(rdev); | ||
3247 | r100_cp_fini(rdev); | ||
3248 | r100_wb_fini(rdev); | ||
3249 | r100_ib_fini(rdev); | ||
3250 | if (rdev->flags & RADEON_IS_PCI) | ||
3251 | r100_pci_gart_fini(rdev); | ||
3252 | radeon_irq_kms_fini(rdev); | ||
3253 | rdev->accel_working = false; | ||
3254 | } | ||
3255 | return 0; | ||
3256 | } | ||