1*926deccbSFrançois Tigeot /* 2*926deccbSFrançois Tigeot * Copyright 2008 Advanced Micro Devices, Inc. 3*926deccbSFrançois Tigeot * Copyright 2008 Red Hat Inc. 4*926deccbSFrançois Tigeot * Copyright 2009 Jerome Glisse. 5*926deccbSFrançois Tigeot * 6*926deccbSFrançois Tigeot * Permission is hereby granted, free of charge, to any person obtaining a 7*926deccbSFrançois Tigeot * copy of this software and associated documentation files (the "Software"), 8*926deccbSFrançois Tigeot * to deal in the Software without restriction, including without limitation 9*926deccbSFrançois Tigeot * the rights to use, copy, modify, merge, publish, distribute, sublicense, 10*926deccbSFrançois Tigeot * and/or sell copies of the Software, and to permit persons to whom the 11*926deccbSFrançois Tigeot * Software is furnished to do so, subject to the following conditions: 12*926deccbSFrançois Tigeot * 13*926deccbSFrançois Tigeot * The above copyright notice and this permission notice shall be included in 14*926deccbSFrançois Tigeot * all copies or substantial portions of the Software. 15*926deccbSFrançois Tigeot * 16*926deccbSFrançois Tigeot * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17*926deccbSFrançois Tigeot * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18*926deccbSFrançois Tigeot * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19*926deccbSFrançois Tigeot * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR 20*926deccbSFrançois Tigeot * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 21*926deccbSFrançois Tigeot * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22*926deccbSFrançois Tigeot * OTHER DEALINGS IN THE SOFTWARE. 23*926deccbSFrançois Tigeot * 24*926deccbSFrançois Tigeot * Authors: Dave Airlie 25*926deccbSFrançois Tigeot * Alex Deucher 26*926deccbSFrançois Tigeot * Jerome Glisse 27*926deccbSFrançois Tigeot * 28*926deccbSFrançois Tigeot * $FreeBSD: head/sys/dev/drm2/radeon/rv515.c 254885 2013-08-25 19:37:15Z dumbbell $ 29*926deccbSFrançois Tigeot */ 30*926deccbSFrançois Tigeot 31*926deccbSFrançois Tigeot #include <drm/drmP.h> 32*926deccbSFrançois Tigeot #include "rv515d.h" 33*926deccbSFrançois Tigeot #include "radeon.h" 34*926deccbSFrançois Tigeot #include "radeon_asic.h" 35*926deccbSFrançois Tigeot #include "atom.h" 36*926deccbSFrançois Tigeot #include "rv515_reg_safe.h" 37*926deccbSFrançois Tigeot 38*926deccbSFrançois Tigeot /* This files gather functions specifics to: rv515 */ 39*926deccbSFrançois Tigeot static int rv515_debugfs_pipes_info_init(struct radeon_device *rdev); 40*926deccbSFrançois Tigeot static int rv515_debugfs_ga_info_init(struct radeon_device *rdev); 41*926deccbSFrançois Tigeot static void rv515_gpu_init(struct radeon_device *rdev); 42*926deccbSFrançois Tigeot 43*926deccbSFrançois Tigeot static const u32 crtc_offsets[2] = 44*926deccbSFrançois Tigeot { 45*926deccbSFrançois Tigeot 0, 46*926deccbSFrançois Tigeot AVIVO_D2CRTC_H_TOTAL - AVIVO_D1CRTC_H_TOTAL 47*926deccbSFrançois Tigeot }; 48*926deccbSFrançois Tigeot 49*926deccbSFrançois Tigeot void rv515_debugfs(struct radeon_device *rdev) 50*926deccbSFrançois Tigeot { 51*926deccbSFrançois Tigeot if (r100_debugfs_rbbm_init(rdev)) { 52*926deccbSFrançois Tigeot DRM_ERROR("Failed to register debugfs file for RBBM !\n"); 53*926deccbSFrançois Tigeot } 54*926deccbSFrançois Tigeot if (rv515_debugfs_pipes_info_init(rdev)) { 55*926deccbSFrançois Tigeot DRM_ERROR("Failed to register debugfs file for pipes !\n"); 56*926deccbSFrançois Tigeot } 57*926deccbSFrançois Tigeot if (rv515_debugfs_ga_info_init(rdev)) { 58*926deccbSFrançois Tigeot DRM_ERROR("Failed to register debugfs file for pipes !\n"); 59*926deccbSFrançois Tigeot } 60*926deccbSFrançois Tigeot } 61*926deccbSFrançois Tigeot 62*926deccbSFrançois Tigeot void rv515_ring_start(struct radeon_device *rdev, struct radeon_ring *ring) 63*926deccbSFrançois Tigeot { 64*926deccbSFrançois Tigeot int r; 65*926deccbSFrançois Tigeot 66*926deccbSFrançois Tigeot r = radeon_ring_lock(rdev, ring, 64); 67*926deccbSFrançois Tigeot if (r) { 68*926deccbSFrançois Tigeot return; 69*926deccbSFrançois Tigeot } 70*926deccbSFrançois Tigeot radeon_ring_write(ring, PACKET0(ISYNC_CNTL, 0)); 71*926deccbSFrançois Tigeot radeon_ring_write(ring, 72*926deccbSFrançois Tigeot ISYNC_ANY2D_IDLE3D | 73*926deccbSFrançois Tigeot ISYNC_ANY3D_IDLE2D | 74*926deccbSFrançois Tigeot ISYNC_WAIT_IDLEGUI | 75*926deccbSFrançois Tigeot ISYNC_CPSCRATCH_IDLEGUI); 76*926deccbSFrançois Tigeot radeon_ring_write(ring, PACKET0(WAIT_UNTIL, 0)); 77*926deccbSFrançois Tigeot radeon_ring_write(ring, WAIT_2D_IDLECLEAN | WAIT_3D_IDLECLEAN); 78*926deccbSFrançois Tigeot radeon_ring_write(ring, PACKET0(R300_DST_PIPE_CONFIG, 0)); 79*926deccbSFrançois Tigeot radeon_ring_write(ring, R300_PIPE_AUTO_CONFIG); 80*926deccbSFrançois Tigeot radeon_ring_write(ring, PACKET0(GB_SELECT, 0)); 81*926deccbSFrançois Tigeot radeon_ring_write(ring, 0); 82*926deccbSFrançois Tigeot radeon_ring_write(ring, PACKET0(GB_ENABLE, 0)); 83*926deccbSFrançois Tigeot radeon_ring_write(ring, 0); 84*926deccbSFrançois Tigeot radeon_ring_write(ring, PACKET0(R500_SU_REG_DEST, 0)); 85*926deccbSFrançois Tigeot radeon_ring_write(ring, (1 << rdev->num_gb_pipes) - 1); 86*926deccbSFrançois Tigeot radeon_ring_write(ring, PACKET0(VAP_INDEX_OFFSET, 0)); 87*926deccbSFrançois Tigeot radeon_ring_write(ring, 0); 88*926deccbSFrançois Tigeot radeon_ring_write(ring, PACKET0(RB3D_DSTCACHE_CTLSTAT, 0)); 89*926deccbSFrançois Tigeot radeon_ring_write(ring, RB3D_DC_FLUSH | RB3D_DC_FREE); 90*926deccbSFrançois Tigeot radeon_ring_write(ring, PACKET0(ZB_ZCACHE_CTLSTAT, 0)); 91*926deccbSFrançois Tigeot radeon_ring_write(ring, ZC_FLUSH | ZC_FREE); 92*926deccbSFrançois Tigeot radeon_ring_write(ring, PACKET0(WAIT_UNTIL, 0)); 93*926deccbSFrançois Tigeot radeon_ring_write(ring, WAIT_2D_IDLECLEAN | WAIT_3D_IDLECLEAN); 94*926deccbSFrançois Tigeot radeon_ring_write(ring, PACKET0(GB_AA_CONFIG, 0)); 95*926deccbSFrançois Tigeot radeon_ring_write(ring, 0); 96*926deccbSFrançois Tigeot radeon_ring_write(ring, PACKET0(RB3D_DSTCACHE_CTLSTAT, 0)); 97*926deccbSFrançois Tigeot radeon_ring_write(ring, RB3D_DC_FLUSH | RB3D_DC_FREE); 98*926deccbSFrançois Tigeot radeon_ring_write(ring, PACKET0(ZB_ZCACHE_CTLSTAT, 0)); 99*926deccbSFrançois Tigeot radeon_ring_write(ring, ZC_FLUSH | ZC_FREE); 100*926deccbSFrançois Tigeot radeon_ring_write(ring, PACKET0(GB_MSPOS0, 0)); 101*926deccbSFrançois Tigeot radeon_ring_write(ring, 102*926deccbSFrançois Tigeot ((6 << MS_X0_SHIFT) | 103*926deccbSFrançois Tigeot (6 << MS_Y0_SHIFT) | 104*926deccbSFrançois Tigeot (6 << MS_X1_SHIFT) | 105*926deccbSFrançois Tigeot (6 << MS_Y1_SHIFT) | 106*926deccbSFrançois Tigeot (6 << MS_X2_SHIFT) | 107*926deccbSFrançois Tigeot (6 << MS_Y2_SHIFT) | 108*926deccbSFrançois Tigeot (6 << MSBD0_Y_SHIFT) | 109*926deccbSFrançois Tigeot (6 << MSBD0_X_SHIFT))); 110*926deccbSFrançois Tigeot radeon_ring_write(ring, PACKET0(GB_MSPOS1, 0)); 111*926deccbSFrançois Tigeot radeon_ring_write(ring, 112*926deccbSFrançois Tigeot ((6 << MS_X3_SHIFT) | 113*926deccbSFrançois Tigeot (6 << MS_Y3_SHIFT) | 114*926deccbSFrançois Tigeot (6 << MS_X4_SHIFT) | 115*926deccbSFrançois Tigeot (6 << MS_Y4_SHIFT) | 116*926deccbSFrançois Tigeot (6 << MS_X5_SHIFT) | 117*926deccbSFrançois Tigeot (6 << MS_Y5_SHIFT) | 118*926deccbSFrançois Tigeot (6 << MSBD1_SHIFT))); 119*926deccbSFrançois Tigeot radeon_ring_write(ring, PACKET0(GA_ENHANCE, 0)); 120*926deccbSFrançois Tigeot radeon_ring_write(ring, GA_DEADLOCK_CNTL | GA_FASTSYNC_CNTL); 121*926deccbSFrançois Tigeot radeon_ring_write(ring, PACKET0(GA_POLY_MODE, 0)); 122*926deccbSFrançois Tigeot radeon_ring_write(ring, FRONT_PTYPE_TRIANGE | BACK_PTYPE_TRIANGE); 123*926deccbSFrançois Tigeot radeon_ring_write(ring, PACKET0(GA_ROUND_MODE, 0)); 124*926deccbSFrançois Tigeot radeon_ring_write(ring, GEOMETRY_ROUND_NEAREST | COLOR_ROUND_NEAREST); 125*926deccbSFrançois Tigeot radeon_ring_write(ring, PACKET0(0x20C8, 0)); 126*926deccbSFrançois Tigeot radeon_ring_write(ring, 0); 127*926deccbSFrançois Tigeot radeon_ring_unlock_commit(rdev, ring); 128*926deccbSFrançois Tigeot } 129*926deccbSFrançois Tigeot 130*926deccbSFrançois Tigeot int rv515_mc_wait_for_idle(struct radeon_device *rdev) 131*926deccbSFrançois Tigeot { 132*926deccbSFrançois Tigeot unsigned i; 133*926deccbSFrançois Tigeot uint32_t tmp; 134*926deccbSFrançois Tigeot 135*926deccbSFrançois Tigeot for (i = 0; i < rdev->usec_timeout; i++) { 136*926deccbSFrançois Tigeot /* read MC_STATUS */ 137*926deccbSFrançois Tigeot tmp = RREG32_MC(MC_STATUS); 138*926deccbSFrançois Tigeot if (tmp & MC_STATUS_IDLE) { 139*926deccbSFrançois Tigeot return 0; 140*926deccbSFrançois Tigeot } 141*926deccbSFrançois Tigeot DRM_UDELAY(1); 142*926deccbSFrançois Tigeot } 143*926deccbSFrançois Tigeot return -1; 144*926deccbSFrançois Tigeot } 145*926deccbSFrançois Tigeot 146*926deccbSFrançois Tigeot void rv515_vga_render_disable(struct radeon_device *rdev) 147*926deccbSFrançois Tigeot { 148*926deccbSFrançois Tigeot WREG32(R_000300_VGA_RENDER_CONTROL, 149*926deccbSFrançois Tigeot RREG32(R_000300_VGA_RENDER_CONTROL) & C_000300_VGA_VSTATUS_CNTL); 150*926deccbSFrançois Tigeot } 151*926deccbSFrançois Tigeot 152*926deccbSFrançois Tigeot static void rv515_gpu_init(struct radeon_device *rdev) 153*926deccbSFrançois Tigeot { 154*926deccbSFrançois Tigeot unsigned pipe_select_current, gb_pipe_select, tmp; 155*926deccbSFrançois Tigeot 156*926deccbSFrançois Tigeot if (r100_gui_wait_for_idle(rdev)) { 157*926deccbSFrançois Tigeot DRM_ERROR("Failed to wait GUI idle while " 158*926deccbSFrançois Tigeot "resetting GPU. Bad things might happen.\n"); 159*926deccbSFrançois Tigeot } 160*926deccbSFrançois Tigeot rv515_vga_render_disable(rdev); 161*926deccbSFrançois Tigeot r420_pipes_init(rdev); 162*926deccbSFrançois Tigeot gb_pipe_select = RREG32(R400_GB_PIPE_SELECT); 163*926deccbSFrançois Tigeot tmp = RREG32(R300_DST_PIPE_CONFIG); 164*926deccbSFrançois Tigeot pipe_select_current = (tmp >> 2) & 3; 165*926deccbSFrançois Tigeot tmp = (1 << pipe_select_current) | 166*926deccbSFrançois Tigeot (((gb_pipe_select >> 8) & 0xF) << 4); 167*926deccbSFrançois Tigeot WREG32_PLL(0x000D, tmp); 168*926deccbSFrançois Tigeot if (r100_gui_wait_for_idle(rdev)) { 169*926deccbSFrançois Tigeot DRM_ERROR("Failed to wait GUI idle while " 170*926deccbSFrançois Tigeot "resetting GPU. Bad things might happen.\n"); 171*926deccbSFrançois Tigeot } 172*926deccbSFrançois Tigeot if (rv515_mc_wait_for_idle(rdev)) { 173*926deccbSFrançois Tigeot DRM_ERROR("Failed to wait MC idle while " 174*926deccbSFrançois Tigeot "programming pipes. Bad things might happen.\n"); 175*926deccbSFrançois Tigeot } 176*926deccbSFrançois Tigeot } 177*926deccbSFrançois Tigeot 178*926deccbSFrançois Tigeot static void rv515_vram_get_type(struct radeon_device *rdev) 179*926deccbSFrançois Tigeot { 180*926deccbSFrançois Tigeot uint32_t tmp; 181*926deccbSFrançois Tigeot 182*926deccbSFrançois Tigeot rdev->mc.vram_width = 128; 183*926deccbSFrançois Tigeot rdev->mc.vram_is_ddr = true; 184*926deccbSFrançois Tigeot tmp = RREG32_MC(RV515_MC_CNTL) & MEM_NUM_CHANNELS_MASK; 185*926deccbSFrançois Tigeot switch (tmp) { 186*926deccbSFrançois Tigeot case 0: 187*926deccbSFrançois Tigeot rdev->mc.vram_width = 64; 188*926deccbSFrançois Tigeot break; 189*926deccbSFrançois Tigeot case 1: 190*926deccbSFrançois Tigeot rdev->mc.vram_width = 128; 191*926deccbSFrançois Tigeot break; 192*926deccbSFrançois Tigeot default: 193*926deccbSFrançois Tigeot rdev->mc.vram_width = 128; 194*926deccbSFrançois Tigeot break; 195*926deccbSFrançois Tigeot } 196*926deccbSFrançois Tigeot } 197*926deccbSFrançois Tigeot 198*926deccbSFrançois Tigeot static void rv515_mc_init(struct radeon_device *rdev) 199*926deccbSFrançois Tigeot { 200*926deccbSFrançois Tigeot 201*926deccbSFrançois Tigeot rv515_vram_get_type(rdev); 202*926deccbSFrançois Tigeot r100_vram_init_sizes(rdev); 203*926deccbSFrançois Tigeot radeon_vram_location(rdev, &rdev->mc, 0); 204*926deccbSFrançois Tigeot rdev->mc.gtt_base_align = 0; 205*926deccbSFrançois Tigeot if (!(rdev->flags & RADEON_IS_AGP)) 206*926deccbSFrançois Tigeot radeon_gtt_location(rdev, &rdev->mc); 207*926deccbSFrançois Tigeot radeon_update_bandwidth_info(rdev); 208*926deccbSFrançois Tigeot } 209*926deccbSFrançois Tigeot 210*926deccbSFrançois Tigeot uint32_t rv515_mc_rreg(struct radeon_device *rdev, uint32_t reg) 211*926deccbSFrançois Tigeot { 212*926deccbSFrançois Tigeot uint32_t r; 213*926deccbSFrançois Tigeot 214*926deccbSFrançois Tigeot WREG32(MC_IND_INDEX, 0x7f0000 | (reg & 0xffff)); 215*926deccbSFrançois Tigeot r = RREG32(MC_IND_DATA); 216*926deccbSFrançois Tigeot WREG32(MC_IND_INDEX, 0); 217*926deccbSFrançois Tigeot return r; 218*926deccbSFrançois Tigeot } 219*926deccbSFrançois Tigeot 220*926deccbSFrançois Tigeot void rv515_mc_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v) 221*926deccbSFrançois Tigeot { 222*926deccbSFrançois Tigeot WREG32(MC_IND_INDEX, 0xff0000 | ((reg) & 0xffff)); 223*926deccbSFrançois Tigeot WREG32(MC_IND_DATA, (v)); 224*926deccbSFrançois Tigeot WREG32(MC_IND_INDEX, 0); 225*926deccbSFrançois Tigeot } 226*926deccbSFrançois Tigeot 227*926deccbSFrançois Tigeot #if defined(CONFIG_DEBUG_FS) 228*926deccbSFrançois Tigeot static int rv515_debugfs_pipes_info(struct seq_file *m, void *data) 229*926deccbSFrançois Tigeot { 230*926deccbSFrançois Tigeot struct drm_info_node *node = (struct drm_info_node *) m->private; 231*926deccbSFrançois Tigeot struct drm_device *dev = node->minor->dev; 232*926deccbSFrançois Tigeot struct radeon_device *rdev = dev->dev_private; 233*926deccbSFrançois Tigeot uint32_t tmp; 234*926deccbSFrançois Tigeot 235*926deccbSFrançois Tigeot tmp = RREG32(GB_PIPE_SELECT); 236*926deccbSFrançois Tigeot seq_printf(m, "GB_PIPE_SELECT 0x%08x\n", tmp); 237*926deccbSFrançois Tigeot tmp = RREG32(SU_REG_DEST); 238*926deccbSFrançois Tigeot seq_printf(m, "SU_REG_DEST 0x%08x\n", tmp); 239*926deccbSFrançois Tigeot tmp = RREG32(GB_TILE_CONFIG); 240*926deccbSFrançois Tigeot seq_printf(m, "GB_TILE_CONFIG 0x%08x\n", tmp); 241*926deccbSFrançois Tigeot tmp = RREG32(DST_PIPE_CONFIG); 242*926deccbSFrançois Tigeot seq_printf(m, "DST_PIPE_CONFIG 0x%08x\n", tmp); 243*926deccbSFrançois Tigeot return 0; 244*926deccbSFrançois Tigeot } 245*926deccbSFrançois Tigeot 246*926deccbSFrançois Tigeot static int rv515_debugfs_ga_info(struct seq_file *m, void *data) 247*926deccbSFrançois Tigeot { 248*926deccbSFrançois Tigeot struct drm_info_node *node = (struct drm_info_node *) m->private; 249*926deccbSFrançois Tigeot struct drm_device *dev = node->minor->dev; 250*926deccbSFrançois Tigeot struct radeon_device *rdev = dev->dev_private; 251*926deccbSFrançois Tigeot uint32_t tmp; 252*926deccbSFrançois Tigeot 253*926deccbSFrançois Tigeot tmp = RREG32(0x2140); 254*926deccbSFrançois Tigeot seq_printf(m, "VAP_CNTL_STATUS 0x%08x\n", tmp); 255*926deccbSFrançois Tigeot radeon_asic_reset(rdev); 256*926deccbSFrançois Tigeot tmp = RREG32(0x425C); 257*926deccbSFrançois Tigeot seq_printf(m, "GA_IDLE 0x%08x\n", tmp); 258*926deccbSFrançois Tigeot return 0; 259*926deccbSFrançois Tigeot } 260*926deccbSFrançois Tigeot 261*926deccbSFrançois Tigeot static struct drm_info_list rv515_pipes_info_list[] = { 262*926deccbSFrançois Tigeot {"rv515_pipes_info", rv515_debugfs_pipes_info, 0, NULL}, 263*926deccbSFrançois Tigeot }; 264*926deccbSFrançois Tigeot 265*926deccbSFrançois Tigeot static struct drm_info_list rv515_ga_info_list[] = { 266*926deccbSFrançois Tigeot {"rv515_ga_info", rv515_debugfs_ga_info, 0, NULL}, 267*926deccbSFrançois Tigeot }; 268*926deccbSFrançois Tigeot #endif 269*926deccbSFrançois Tigeot 270*926deccbSFrançois Tigeot static int rv515_debugfs_pipes_info_init(struct radeon_device *rdev) 271*926deccbSFrançois Tigeot { 272*926deccbSFrançois Tigeot #if defined(CONFIG_DEBUG_FS) 273*926deccbSFrançois Tigeot return radeon_debugfs_add_files(rdev, rv515_pipes_info_list, 1); 274*926deccbSFrançois Tigeot #else 275*926deccbSFrançois Tigeot return 0; 276*926deccbSFrançois Tigeot #endif 277*926deccbSFrançois Tigeot } 278*926deccbSFrançois Tigeot 279*926deccbSFrançois Tigeot static int rv515_debugfs_ga_info_init(struct radeon_device *rdev) 280*926deccbSFrançois Tigeot { 281*926deccbSFrançois Tigeot #if defined(CONFIG_DEBUG_FS) 282*926deccbSFrançois Tigeot return radeon_debugfs_add_files(rdev, rv515_ga_info_list, 1); 283*926deccbSFrançois Tigeot #else 284*926deccbSFrançois Tigeot return 0; 285*926deccbSFrançois Tigeot #endif 286*926deccbSFrançois Tigeot } 287*926deccbSFrançois Tigeot 288*926deccbSFrançois Tigeot void rv515_mc_stop(struct radeon_device *rdev, struct rv515_mc_save *save) 289*926deccbSFrançois Tigeot { 290*926deccbSFrançois Tigeot u32 crtc_enabled, tmp, frame_count, blackout; 291*926deccbSFrançois Tigeot int i, j; 292*926deccbSFrançois Tigeot 293*926deccbSFrançois Tigeot save->vga_render_control = RREG32(R_000300_VGA_RENDER_CONTROL); 294*926deccbSFrançois Tigeot save->vga_hdp_control = RREG32(R_000328_VGA_HDP_CONTROL); 295*926deccbSFrançois Tigeot 296*926deccbSFrançois Tigeot /* disable VGA render */ 297*926deccbSFrançois Tigeot WREG32(R_000300_VGA_RENDER_CONTROL, 0); 298*926deccbSFrançois Tigeot /* blank the display controllers */ 299*926deccbSFrançois Tigeot for (i = 0; i < rdev->num_crtc; i++) { 300*926deccbSFrançois Tigeot crtc_enabled = RREG32(AVIVO_D1CRTC_CONTROL + crtc_offsets[i]) & AVIVO_CRTC_EN; 301*926deccbSFrançois Tigeot if (crtc_enabled) { 302*926deccbSFrançois Tigeot save->crtc_enabled[i] = true; 303*926deccbSFrançois Tigeot tmp = RREG32(AVIVO_D1CRTC_CONTROL + crtc_offsets[i]); 304*926deccbSFrançois Tigeot if (!(tmp & AVIVO_CRTC_DISP_READ_REQUEST_DISABLE)) { 305*926deccbSFrançois Tigeot radeon_wait_for_vblank(rdev, i); 306*926deccbSFrançois Tigeot tmp |= AVIVO_CRTC_DISP_READ_REQUEST_DISABLE; 307*926deccbSFrançois Tigeot WREG32(AVIVO_D1CRTC_CONTROL + crtc_offsets[i], tmp); 308*926deccbSFrançois Tigeot } 309*926deccbSFrançois Tigeot /* wait for the next frame */ 310*926deccbSFrançois Tigeot frame_count = radeon_get_vblank_counter(rdev, i); 311*926deccbSFrançois Tigeot for (j = 0; j < rdev->usec_timeout; j++) { 312*926deccbSFrançois Tigeot if (radeon_get_vblank_counter(rdev, i) != frame_count) 313*926deccbSFrançois Tigeot break; 314*926deccbSFrançois Tigeot DRM_UDELAY(1); 315*926deccbSFrançois Tigeot } 316*926deccbSFrançois Tigeot } else { 317*926deccbSFrançois Tigeot save->crtc_enabled[i] = false; 318*926deccbSFrançois Tigeot } 319*926deccbSFrançois Tigeot } 320*926deccbSFrançois Tigeot 321*926deccbSFrançois Tigeot radeon_mc_wait_for_idle(rdev); 322*926deccbSFrançois Tigeot 323*926deccbSFrançois Tigeot if (rdev->family >= CHIP_R600) { 324*926deccbSFrançois Tigeot if (rdev->family >= CHIP_RV770) 325*926deccbSFrançois Tigeot blackout = RREG32(R700_MC_CITF_CNTL); 326*926deccbSFrançois Tigeot else 327*926deccbSFrançois Tigeot blackout = RREG32(R600_CITF_CNTL); 328*926deccbSFrançois Tigeot if ((blackout & R600_BLACKOUT_MASK) != R600_BLACKOUT_MASK) { 329*926deccbSFrançois Tigeot /* Block CPU access */ 330*926deccbSFrançois Tigeot WREG32(R600_BIF_FB_EN, 0); 331*926deccbSFrançois Tigeot /* blackout the MC */ 332*926deccbSFrançois Tigeot blackout |= R600_BLACKOUT_MASK; 333*926deccbSFrançois Tigeot if (rdev->family >= CHIP_RV770) 334*926deccbSFrançois Tigeot WREG32(R700_MC_CITF_CNTL, blackout); 335*926deccbSFrançois Tigeot else 336*926deccbSFrançois Tigeot WREG32(R600_CITF_CNTL, blackout); 337*926deccbSFrançois Tigeot } 338*926deccbSFrançois Tigeot } 339*926deccbSFrançois Tigeot /* wait for the MC to settle */ 340*926deccbSFrançois Tigeot DRM_UDELAY(100); 341*926deccbSFrançois Tigeot } 342*926deccbSFrançois Tigeot 343*926deccbSFrançois Tigeot void rv515_mc_resume(struct radeon_device *rdev, struct rv515_mc_save *save) 344*926deccbSFrançois Tigeot { 345*926deccbSFrançois Tigeot u32 tmp, frame_count; 346*926deccbSFrançois Tigeot int i, j; 347*926deccbSFrançois Tigeot 348*926deccbSFrançois Tigeot /* update crtc base addresses */ 349*926deccbSFrançois Tigeot for (i = 0; i < rdev->num_crtc; i++) { 350*926deccbSFrançois Tigeot if (rdev->family >= CHIP_RV770) { 351*926deccbSFrançois Tigeot if (i == 1) { 352*926deccbSFrançois Tigeot WREG32(R700_D1GRPH_PRIMARY_SURFACE_ADDRESS_HIGH, 353*926deccbSFrançois Tigeot upper_32_bits(rdev->mc.vram_start)); 354*926deccbSFrançois Tigeot WREG32(R700_D1GRPH_SECONDARY_SURFACE_ADDRESS_HIGH, 355*926deccbSFrançois Tigeot upper_32_bits(rdev->mc.vram_start)); 356*926deccbSFrançois Tigeot } else { 357*926deccbSFrançois Tigeot WREG32(R700_D2GRPH_PRIMARY_SURFACE_ADDRESS_HIGH, 358*926deccbSFrançois Tigeot upper_32_bits(rdev->mc.vram_start)); 359*926deccbSFrançois Tigeot WREG32(R700_D2GRPH_SECONDARY_SURFACE_ADDRESS_HIGH, 360*926deccbSFrançois Tigeot upper_32_bits(rdev->mc.vram_start)); 361*926deccbSFrançois Tigeot } 362*926deccbSFrançois Tigeot } 363*926deccbSFrançois Tigeot WREG32(R_006110_D1GRPH_PRIMARY_SURFACE_ADDRESS + crtc_offsets[i], 364*926deccbSFrançois Tigeot (u32)rdev->mc.vram_start); 365*926deccbSFrançois Tigeot WREG32(R_006118_D1GRPH_SECONDARY_SURFACE_ADDRESS + crtc_offsets[i], 366*926deccbSFrançois Tigeot (u32)rdev->mc.vram_start); 367*926deccbSFrançois Tigeot } 368*926deccbSFrançois Tigeot WREG32(R_000310_VGA_MEMORY_BASE_ADDRESS, (u32)rdev->mc.vram_start); 369*926deccbSFrançois Tigeot 370*926deccbSFrançois Tigeot if (rdev->family >= CHIP_R600) { 371*926deccbSFrançois Tigeot /* unblackout the MC */ 372*926deccbSFrançois Tigeot if (rdev->family >= CHIP_RV770) 373*926deccbSFrançois Tigeot tmp = RREG32(R700_MC_CITF_CNTL); 374*926deccbSFrançois Tigeot else 375*926deccbSFrançois Tigeot tmp = RREG32(R600_CITF_CNTL); 376*926deccbSFrançois Tigeot tmp &= ~R600_BLACKOUT_MASK; 377*926deccbSFrançois Tigeot if (rdev->family >= CHIP_RV770) 378*926deccbSFrançois Tigeot WREG32(R700_MC_CITF_CNTL, tmp); 379*926deccbSFrançois Tigeot else 380*926deccbSFrançois Tigeot WREG32(R600_CITF_CNTL, tmp); 381*926deccbSFrançois Tigeot /* allow CPU access */ 382*926deccbSFrançois Tigeot WREG32(R600_BIF_FB_EN, R600_FB_READ_EN | R600_FB_WRITE_EN); 383*926deccbSFrançois Tigeot } 384*926deccbSFrançois Tigeot 385*926deccbSFrançois Tigeot for (i = 0; i < rdev->num_crtc; i++) { 386*926deccbSFrançois Tigeot if (save->crtc_enabled[i]) { 387*926deccbSFrançois Tigeot tmp = RREG32(AVIVO_D1CRTC_CONTROL + crtc_offsets[i]); 388*926deccbSFrançois Tigeot tmp &= ~AVIVO_CRTC_DISP_READ_REQUEST_DISABLE; 389*926deccbSFrançois Tigeot WREG32(AVIVO_D1CRTC_CONTROL + crtc_offsets[i], tmp); 390*926deccbSFrançois Tigeot /* wait for the next frame */ 391*926deccbSFrançois Tigeot frame_count = radeon_get_vblank_counter(rdev, i); 392*926deccbSFrançois Tigeot for (j = 0; j < rdev->usec_timeout; j++) { 393*926deccbSFrançois Tigeot if (radeon_get_vblank_counter(rdev, i) != frame_count) 394*926deccbSFrançois Tigeot break; 395*926deccbSFrançois Tigeot DRM_UDELAY(1); 396*926deccbSFrançois Tigeot } 397*926deccbSFrançois Tigeot } 398*926deccbSFrançois Tigeot } 399*926deccbSFrançois Tigeot /* Unlock vga access */ 400*926deccbSFrançois Tigeot WREG32(R_000328_VGA_HDP_CONTROL, save->vga_hdp_control); 401*926deccbSFrançois Tigeot DRM_MDELAY(1); 402*926deccbSFrançois Tigeot WREG32(R_000300_VGA_RENDER_CONTROL, save->vga_render_control); 403*926deccbSFrançois Tigeot } 404*926deccbSFrançois Tigeot 405*926deccbSFrançois Tigeot static void rv515_mc_program(struct radeon_device *rdev) 406*926deccbSFrançois Tigeot { 407*926deccbSFrançois Tigeot struct rv515_mc_save save; 408*926deccbSFrançois Tigeot 409*926deccbSFrançois Tigeot /* Stops all mc clients */ 410*926deccbSFrançois Tigeot rv515_mc_stop(rdev, &save); 411*926deccbSFrançois Tigeot 412*926deccbSFrançois Tigeot /* Wait for mc idle */ 413*926deccbSFrançois Tigeot if (rv515_mc_wait_for_idle(rdev)) 414*926deccbSFrançois Tigeot dev_warn(rdev->dev, "Wait MC idle timeout before updating MC.\n"); 415*926deccbSFrançois Tigeot /* Write VRAM size in case we are limiting it */ 416*926deccbSFrançois Tigeot WREG32(R_0000F8_CONFIG_MEMSIZE, rdev->mc.real_vram_size); 417*926deccbSFrançois Tigeot /* Program MC, should be a 32bits limited address space */ 418*926deccbSFrançois Tigeot WREG32_MC(R_000001_MC_FB_LOCATION, 419*926deccbSFrançois Tigeot S_000001_MC_FB_START(rdev->mc.vram_start >> 16) | 420*926deccbSFrançois Tigeot S_000001_MC_FB_TOP(rdev->mc.vram_end >> 16)); 421*926deccbSFrançois Tigeot WREG32(R_000134_HDP_FB_LOCATION, 422*926deccbSFrançois Tigeot S_000134_HDP_FB_START(rdev->mc.vram_start >> 16)); 423*926deccbSFrançois Tigeot if (rdev->flags & RADEON_IS_AGP) { 424*926deccbSFrançois Tigeot WREG32_MC(R_000002_MC_AGP_LOCATION, 425*926deccbSFrançois Tigeot S_000002_MC_AGP_START(rdev->mc.gtt_start >> 16) | 426*926deccbSFrançois Tigeot S_000002_MC_AGP_TOP(rdev->mc.gtt_end >> 16)); 427*926deccbSFrançois Tigeot WREG32_MC(R_000003_MC_AGP_BASE, lower_32_bits(rdev->mc.agp_base)); 428*926deccbSFrançois Tigeot WREG32_MC(R_000004_MC_AGP_BASE_2, 429*926deccbSFrançois Tigeot S_000004_AGP_BASE_ADDR_2(upper_32_bits(rdev->mc.agp_base))); 430*926deccbSFrançois Tigeot } else { 431*926deccbSFrançois Tigeot WREG32_MC(R_000002_MC_AGP_LOCATION, 0xFFFFFFFF); 432*926deccbSFrançois Tigeot WREG32_MC(R_000003_MC_AGP_BASE, 0); 433*926deccbSFrançois Tigeot WREG32_MC(R_000004_MC_AGP_BASE_2, 0); 434*926deccbSFrançois Tigeot } 435*926deccbSFrançois Tigeot 436*926deccbSFrançois Tigeot rv515_mc_resume(rdev, &save); 437*926deccbSFrançois Tigeot } 438*926deccbSFrançois Tigeot 439*926deccbSFrançois Tigeot void rv515_clock_startup(struct radeon_device *rdev) 440*926deccbSFrançois Tigeot { 441*926deccbSFrançois Tigeot if (radeon_dynclks != -1 && radeon_dynclks) 442*926deccbSFrançois Tigeot radeon_atom_set_clock_gating(rdev, 1); 443*926deccbSFrançois Tigeot /* We need to force on some of the block */ 444*926deccbSFrançois Tigeot WREG32_PLL(R_00000F_CP_DYN_CNTL, 445*926deccbSFrançois Tigeot RREG32_PLL(R_00000F_CP_DYN_CNTL) | S_00000F_CP_FORCEON(1)); 446*926deccbSFrançois Tigeot WREG32_PLL(R_000011_E2_DYN_CNTL, 447*926deccbSFrançois Tigeot RREG32_PLL(R_000011_E2_DYN_CNTL) | S_000011_E2_FORCEON(1)); 448*926deccbSFrançois Tigeot WREG32_PLL(R_000013_IDCT_DYN_CNTL, 449*926deccbSFrançois Tigeot RREG32_PLL(R_000013_IDCT_DYN_CNTL) | S_000013_IDCT_FORCEON(1)); 450*926deccbSFrançois Tigeot } 451*926deccbSFrançois Tigeot 452*926deccbSFrançois Tigeot static int rv515_startup(struct radeon_device *rdev) 453*926deccbSFrançois Tigeot { 454*926deccbSFrançois Tigeot int r; 455*926deccbSFrançois Tigeot 456*926deccbSFrançois Tigeot rv515_mc_program(rdev); 457*926deccbSFrançois Tigeot /* Resume clock */ 458*926deccbSFrançois Tigeot rv515_clock_startup(rdev); 459*926deccbSFrançois Tigeot /* Initialize GPU configuration (# pipes, ...) */ 460*926deccbSFrançois Tigeot rv515_gpu_init(rdev); 461*926deccbSFrançois Tigeot /* Initialize GART (initialize after TTM so we can allocate 462*926deccbSFrançois Tigeot * memory through TTM but finalize after TTM) */ 463*926deccbSFrançois Tigeot if (rdev->flags & RADEON_IS_PCIE) { 464*926deccbSFrançois Tigeot r = rv370_pcie_gart_enable(rdev); 465*926deccbSFrançois Tigeot if (r) 466*926deccbSFrançois Tigeot return r; 467*926deccbSFrançois Tigeot } 468*926deccbSFrançois Tigeot 469*926deccbSFrançois Tigeot /* allocate wb buffer */ 470*926deccbSFrançois Tigeot r = radeon_wb_init(rdev); 471*926deccbSFrançois Tigeot if (r) 472*926deccbSFrançois Tigeot return r; 473*926deccbSFrançois Tigeot 474*926deccbSFrançois Tigeot r = radeon_fence_driver_start_ring(rdev, RADEON_RING_TYPE_GFX_INDEX); 475*926deccbSFrançois Tigeot if (r) { 476*926deccbSFrançois Tigeot dev_err(rdev->dev, "failed initializing CP fences (%d).\n", r); 477*926deccbSFrançois Tigeot return r; 478*926deccbSFrançois Tigeot } 479*926deccbSFrançois Tigeot 480*926deccbSFrançois Tigeot /* Enable IRQ */ 481*926deccbSFrançois Tigeot rs600_irq_set(rdev); 482*926deccbSFrançois Tigeot rdev->config.r300.hdp_cntl = RREG32(RADEON_HOST_PATH_CNTL); 483*926deccbSFrançois Tigeot /* 1M ring buffer */ 484*926deccbSFrançois Tigeot r = r100_cp_init(rdev, 1024 * 1024); 485*926deccbSFrançois Tigeot if (r) { 486*926deccbSFrançois Tigeot dev_err(rdev->dev, "failed initializing CP (%d).\n", r); 487*926deccbSFrançois Tigeot return r; 488*926deccbSFrançois Tigeot } 489*926deccbSFrançois Tigeot 490*926deccbSFrançois Tigeot r = radeon_ib_pool_init(rdev); 491*926deccbSFrançois Tigeot if (r) { 492*926deccbSFrançois Tigeot dev_err(rdev->dev, "IB initialization failed (%d).\n", r); 493*926deccbSFrançois Tigeot return r; 494*926deccbSFrançois Tigeot } 495*926deccbSFrançois Tigeot 496*926deccbSFrançois Tigeot return 0; 497*926deccbSFrançois Tigeot } 498*926deccbSFrançois Tigeot 499*926deccbSFrançois Tigeot int rv515_resume(struct radeon_device *rdev) 500*926deccbSFrançois Tigeot { 501*926deccbSFrançois Tigeot int r; 502*926deccbSFrançois Tigeot 503*926deccbSFrançois Tigeot /* Make sur GART are not working */ 504*926deccbSFrançois Tigeot if (rdev->flags & RADEON_IS_PCIE) 505*926deccbSFrançois Tigeot rv370_pcie_gart_disable(rdev); 506*926deccbSFrançois Tigeot /* Resume clock before doing reset */ 507*926deccbSFrançois Tigeot rv515_clock_startup(rdev); 508*926deccbSFrançois Tigeot /* Reset gpu before posting otherwise ATOM will enter infinite loop */ 509*926deccbSFrançois Tigeot if (radeon_asic_reset(rdev)) { 510*926deccbSFrançois Tigeot dev_warn(rdev->dev, "GPU reset failed ! (0xE40=0x%08X, 0x7C0=0x%08X)\n", 511*926deccbSFrançois Tigeot RREG32(R_000E40_RBBM_STATUS), 512*926deccbSFrançois Tigeot RREG32(R_0007C0_CP_STAT)); 513*926deccbSFrançois Tigeot } 514*926deccbSFrançois Tigeot /* post */ 515*926deccbSFrançois Tigeot atom_asic_init(rdev->mode_info.atom_context); 516*926deccbSFrançois Tigeot /* Resume clock after posting */ 517*926deccbSFrançois Tigeot rv515_clock_startup(rdev); 518*926deccbSFrançois Tigeot /* Initialize surface registers */ 519*926deccbSFrançois Tigeot radeon_surface_init(rdev); 520*926deccbSFrançois Tigeot 521*926deccbSFrançois Tigeot rdev->accel_working = true; 522*926deccbSFrançois Tigeot r = rv515_startup(rdev); 523*926deccbSFrançois Tigeot if (r) { 524*926deccbSFrançois Tigeot rdev->accel_working = false; 525*926deccbSFrançois Tigeot } 526*926deccbSFrançois Tigeot return r; 527*926deccbSFrançois Tigeot } 528*926deccbSFrançois Tigeot 529*926deccbSFrançois Tigeot int rv515_suspend(struct radeon_device *rdev) 530*926deccbSFrançois Tigeot { 531*926deccbSFrançois Tigeot r100_cp_disable(rdev); 532*926deccbSFrançois Tigeot radeon_wb_disable(rdev); 533*926deccbSFrançois Tigeot rs600_irq_disable(rdev); 534*926deccbSFrançois Tigeot if (rdev->flags & RADEON_IS_PCIE) 535*926deccbSFrançois Tigeot rv370_pcie_gart_disable(rdev); 536*926deccbSFrançois Tigeot return 0; 537*926deccbSFrançois Tigeot } 538*926deccbSFrançois Tigeot 539*926deccbSFrançois Tigeot void rv515_set_safe_registers(struct radeon_device *rdev) 540*926deccbSFrançois Tigeot { 541*926deccbSFrançois Tigeot rdev->config.r300.reg_safe_bm = rv515_reg_safe_bm; 542*926deccbSFrançois Tigeot rdev->config.r300.reg_safe_bm_size = DRM_ARRAY_SIZE(rv515_reg_safe_bm); 543*926deccbSFrançois Tigeot } 544*926deccbSFrançois Tigeot 545*926deccbSFrançois Tigeot void rv515_fini(struct radeon_device *rdev) 546*926deccbSFrançois Tigeot { 547*926deccbSFrançois Tigeot r100_cp_fini(rdev); 548*926deccbSFrançois Tigeot radeon_wb_fini(rdev); 549*926deccbSFrançois Tigeot radeon_ib_pool_fini(rdev); 550*926deccbSFrançois Tigeot radeon_gem_fini(rdev); 551*926deccbSFrançois Tigeot rv370_pcie_gart_fini(rdev); 552*926deccbSFrançois Tigeot radeon_agp_fini(rdev); 553*926deccbSFrançois Tigeot radeon_irq_kms_fini(rdev); 554*926deccbSFrançois Tigeot radeon_fence_driver_fini(rdev); 555*926deccbSFrançois Tigeot radeon_bo_fini(rdev); 556*926deccbSFrançois Tigeot radeon_atombios_fini(rdev); 557*926deccbSFrançois Tigeot drm_free(rdev->bios, DRM_MEM_DRIVER); 558*926deccbSFrançois Tigeot rdev->bios = NULL; 559*926deccbSFrançois Tigeot } 560*926deccbSFrançois Tigeot 561*926deccbSFrançois Tigeot int rv515_init(struct radeon_device *rdev) 562*926deccbSFrançois Tigeot { 563*926deccbSFrançois Tigeot int r; 564*926deccbSFrançois Tigeot 565*926deccbSFrançois Tigeot /* Initialize scratch registers */ 566*926deccbSFrançois Tigeot radeon_scratch_init(rdev); 567*926deccbSFrançois Tigeot /* Initialize surface registers */ 568*926deccbSFrançois Tigeot radeon_surface_init(rdev); 569*926deccbSFrançois Tigeot /* TODO: disable VGA need to use VGA request */ 570*926deccbSFrançois Tigeot /* restore some register to sane defaults */ 571*926deccbSFrançois Tigeot r100_restore_sanity(rdev); 572*926deccbSFrançois Tigeot /* BIOS*/ 573*926deccbSFrançois Tigeot if (!radeon_get_bios(rdev)) { 574*926deccbSFrançois Tigeot if (ASIC_IS_AVIVO(rdev)) 575*926deccbSFrançois Tigeot return -EINVAL; 576*926deccbSFrançois Tigeot } 577*926deccbSFrançois Tigeot if (rdev->is_atom_bios) { 578*926deccbSFrançois Tigeot r = radeon_atombios_init(rdev); 579*926deccbSFrançois Tigeot if (r) 580*926deccbSFrançois Tigeot return r; 581*926deccbSFrançois Tigeot } else { 582*926deccbSFrançois Tigeot dev_err(rdev->dev, "Expecting atombios for RV515 GPU\n"); 583*926deccbSFrançois Tigeot return -EINVAL; 584*926deccbSFrançois Tigeot } 585*926deccbSFrançois Tigeot /* Reset gpu before posting otherwise ATOM will enter infinite loop */ 586*926deccbSFrançois Tigeot if (radeon_asic_reset(rdev)) { 587*926deccbSFrançois Tigeot dev_warn(rdev->dev, 588*926deccbSFrançois Tigeot "GPU reset failed ! (0xE40=0x%08X, 0x7C0=0x%08X)\n", 589*926deccbSFrançois Tigeot RREG32(R_000E40_RBBM_STATUS), 590*926deccbSFrançois Tigeot RREG32(R_0007C0_CP_STAT)); 591*926deccbSFrançois Tigeot } 592*926deccbSFrançois Tigeot /* check if cards are posted or not */ 593*926deccbSFrançois Tigeot if (radeon_boot_test_post_card(rdev) == false) 594*926deccbSFrançois Tigeot return -EINVAL; 595*926deccbSFrançois Tigeot /* Initialize clocks */ 596*926deccbSFrançois Tigeot radeon_get_clock_info(rdev->ddev); 597*926deccbSFrançois Tigeot /* initialize AGP */ 598*926deccbSFrançois Tigeot if (rdev->flags & RADEON_IS_AGP) { 599*926deccbSFrançois Tigeot r = radeon_agp_init(rdev); 600*926deccbSFrançois Tigeot if (r) { 601*926deccbSFrançois Tigeot radeon_agp_disable(rdev); 602*926deccbSFrançois Tigeot } 603*926deccbSFrançois Tigeot } 604*926deccbSFrançois Tigeot /* initialize memory controller */ 605*926deccbSFrançois Tigeot rv515_mc_init(rdev); 606*926deccbSFrançois Tigeot rv515_debugfs(rdev); 607*926deccbSFrançois Tigeot /* Fence driver */ 608*926deccbSFrançois Tigeot r = radeon_fence_driver_init(rdev); 609*926deccbSFrançois Tigeot if (r) 610*926deccbSFrançois Tigeot return r; 611*926deccbSFrançois Tigeot r = radeon_irq_kms_init(rdev); 612*926deccbSFrançois Tigeot if (r) 613*926deccbSFrançois Tigeot return r; 614*926deccbSFrançois Tigeot /* Memory manager */ 615*926deccbSFrançois Tigeot r = radeon_bo_init(rdev); 616*926deccbSFrançois Tigeot if (r) 617*926deccbSFrançois Tigeot return r; 618*926deccbSFrançois Tigeot r = rv370_pcie_gart_init(rdev); 619*926deccbSFrançois Tigeot if (r) 620*926deccbSFrançois Tigeot return r; 621*926deccbSFrançois Tigeot rv515_set_safe_registers(rdev); 622*926deccbSFrançois Tigeot 623*926deccbSFrançois Tigeot rdev->accel_working = true; 624*926deccbSFrançois Tigeot r = rv515_startup(rdev); 625*926deccbSFrançois Tigeot if (r) { 626*926deccbSFrançois Tigeot /* Somethings want wront with the accel init stop accel */ 627*926deccbSFrançois Tigeot dev_err(rdev->dev, "Disabling GPU acceleration\n"); 628*926deccbSFrançois Tigeot r100_cp_fini(rdev); 629*926deccbSFrançois Tigeot radeon_wb_fini(rdev); 630*926deccbSFrançois Tigeot radeon_ib_pool_fini(rdev); 631*926deccbSFrançois Tigeot radeon_irq_kms_fini(rdev); 632*926deccbSFrançois Tigeot rv370_pcie_gart_fini(rdev); 633*926deccbSFrançois Tigeot radeon_agp_fini(rdev); 634*926deccbSFrançois Tigeot rdev->accel_working = false; 635*926deccbSFrançois Tigeot } 636*926deccbSFrançois Tigeot return 0; 637*926deccbSFrançois Tigeot } 638*926deccbSFrançois Tigeot 639*926deccbSFrançois Tigeot void atom_rv515_force_tv_scaler(struct radeon_device *rdev, struct radeon_crtc *crtc) 640*926deccbSFrançois Tigeot { 641*926deccbSFrançois Tigeot int index_reg = 0x6578 + crtc->crtc_offset; 642*926deccbSFrançois Tigeot int data_reg = 0x657c + crtc->crtc_offset; 643*926deccbSFrançois Tigeot 644*926deccbSFrançois Tigeot WREG32(0x659C + crtc->crtc_offset, 0x0); 645*926deccbSFrançois Tigeot WREG32(0x6594 + crtc->crtc_offset, 0x705); 646*926deccbSFrançois Tigeot WREG32(0x65A4 + crtc->crtc_offset, 0x10001); 647*926deccbSFrançois Tigeot WREG32(0x65D8 + crtc->crtc_offset, 0x0); 648*926deccbSFrançois Tigeot WREG32(0x65B0 + crtc->crtc_offset, 0x0); 649*926deccbSFrançois Tigeot WREG32(0x65C0 + crtc->crtc_offset, 0x0); 650*926deccbSFrançois Tigeot WREG32(0x65D4 + crtc->crtc_offset, 0x0); 651*926deccbSFrançois Tigeot WREG32(index_reg, 0x0); 652*926deccbSFrançois Tigeot WREG32(data_reg, 0x841880A8); 653*926deccbSFrançois Tigeot WREG32(index_reg, 0x1); 654*926deccbSFrançois Tigeot WREG32(data_reg, 0x84208680); 655*926deccbSFrançois Tigeot WREG32(index_reg, 0x2); 656*926deccbSFrançois Tigeot WREG32(data_reg, 0xBFF880B0); 657*926deccbSFrançois Tigeot WREG32(index_reg, 0x100); 658*926deccbSFrançois Tigeot WREG32(data_reg, 0x83D88088); 659*926deccbSFrançois Tigeot WREG32(index_reg, 0x101); 660*926deccbSFrançois Tigeot WREG32(data_reg, 0x84608680); 661*926deccbSFrançois Tigeot WREG32(index_reg, 0x102); 662*926deccbSFrançois Tigeot WREG32(data_reg, 0xBFF080D0); 663*926deccbSFrançois Tigeot WREG32(index_reg, 0x200); 664*926deccbSFrançois Tigeot WREG32(data_reg, 0x83988068); 665*926deccbSFrançois Tigeot WREG32(index_reg, 0x201); 666*926deccbSFrançois Tigeot WREG32(data_reg, 0x84A08680); 667*926deccbSFrançois Tigeot WREG32(index_reg, 0x202); 668*926deccbSFrançois Tigeot WREG32(data_reg, 0xBFF080F8); 669*926deccbSFrançois Tigeot WREG32(index_reg, 0x300); 670*926deccbSFrançois Tigeot WREG32(data_reg, 0x83588058); 671*926deccbSFrançois Tigeot WREG32(index_reg, 0x301); 672*926deccbSFrançois Tigeot WREG32(data_reg, 0x84E08660); 673*926deccbSFrançois Tigeot WREG32(index_reg, 0x302); 674*926deccbSFrançois Tigeot WREG32(data_reg, 0xBFF88120); 675*926deccbSFrançois Tigeot WREG32(index_reg, 0x400); 676*926deccbSFrançois Tigeot WREG32(data_reg, 0x83188040); 677*926deccbSFrançois Tigeot WREG32(index_reg, 0x401); 678*926deccbSFrançois Tigeot WREG32(data_reg, 0x85008660); 679*926deccbSFrançois Tigeot WREG32(index_reg, 0x402); 680*926deccbSFrançois Tigeot WREG32(data_reg, 0xBFF88150); 681*926deccbSFrançois Tigeot WREG32(index_reg, 0x500); 682*926deccbSFrançois Tigeot WREG32(data_reg, 0x82D88030); 683*926deccbSFrançois Tigeot WREG32(index_reg, 0x501); 684*926deccbSFrançois Tigeot WREG32(data_reg, 0x85408640); 685*926deccbSFrançois Tigeot WREG32(index_reg, 0x502); 686*926deccbSFrançois Tigeot WREG32(data_reg, 0xBFF88180); 687*926deccbSFrançois Tigeot WREG32(index_reg, 0x600); 688*926deccbSFrançois Tigeot WREG32(data_reg, 0x82A08018); 689*926deccbSFrançois Tigeot WREG32(index_reg, 0x601); 690*926deccbSFrançois Tigeot WREG32(data_reg, 0x85808620); 691*926deccbSFrançois Tigeot WREG32(index_reg, 0x602); 692*926deccbSFrançois Tigeot WREG32(data_reg, 0xBFF081B8); 693*926deccbSFrançois Tigeot WREG32(index_reg, 0x700); 694*926deccbSFrançois Tigeot WREG32(data_reg, 0x82608010); 695*926deccbSFrançois Tigeot WREG32(index_reg, 0x701); 696*926deccbSFrançois Tigeot WREG32(data_reg, 0x85A08600); 697*926deccbSFrançois Tigeot WREG32(index_reg, 0x702); 698*926deccbSFrançois Tigeot WREG32(data_reg, 0x800081F0); 699*926deccbSFrançois Tigeot WREG32(index_reg, 0x800); 700*926deccbSFrançois Tigeot WREG32(data_reg, 0x8228BFF8); 701*926deccbSFrançois Tigeot WREG32(index_reg, 0x801); 702*926deccbSFrançois Tigeot WREG32(data_reg, 0x85E085E0); 703*926deccbSFrançois Tigeot WREG32(index_reg, 0x802); 704*926deccbSFrançois Tigeot WREG32(data_reg, 0xBFF88228); 705*926deccbSFrançois Tigeot WREG32(index_reg, 0x10000); 706*926deccbSFrançois Tigeot WREG32(data_reg, 0x82A8BF00); 707*926deccbSFrançois Tigeot WREG32(index_reg, 0x10001); 708*926deccbSFrançois Tigeot WREG32(data_reg, 0x82A08CC0); 709*926deccbSFrançois Tigeot WREG32(index_reg, 0x10002); 710*926deccbSFrançois Tigeot WREG32(data_reg, 0x8008BEF8); 711*926deccbSFrançois Tigeot WREG32(index_reg, 0x10100); 712*926deccbSFrançois Tigeot WREG32(data_reg, 0x81F0BF28); 713*926deccbSFrançois Tigeot WREG32(index_reg, 0x10101); 714*926deccbSFrançois Tigeot WREG32(data_reg, 0x83608CA0); 715*926deccbSFrançois Tigeot WREG32(index_reg, 0x10102); 716*926deccbSFrançois Tigeot WREG32(data_reg, 0x8018BED0); 717*926deccbSFrançois Tigeot WREG32(index_reg, 0x10200); 718*926deccbSFrançois Tigeot WREG32(data_reg, 0x8148BF38); 719*926deccbSFrançois Tigeot WREG32(index_reg, 0x10201); 720*926deccbSFrançois Tigeot WREG32(data_reg, 0x84408C80); 721*926deccbSFrançois Tigeot WREG32(index_reg, 0x10202); 722*926deccbSFrançois Tigeot WREG32(data_reg, 0x8008BEB8); 723*926deccbSFrançois Tigeot WREG32(index_reg, 0x10300); 724*926deccbSFrançois Tigeot WREG32(data_reg, 0x80B0BF78); 725*926deccbSFrançois Tigeot WREG32(index_reg, 0x10301); 726*926deccbSFrançois Tigeot WREG32(data_reg, 0x85008C20); 727*926deccbSFrançois Tigeot WREG32(index_reg, 0x10302); 728*926deccbSFrançois Tigeot WREG32(data_reg, 0x8020BEA0); 729*926deccbSFrançois Tigeot WREG32(index_reg, 0x10400); 730*926deccbSFrançois Tigeot WREG32(data_reg, 0x8028BF90); 731*926deccbSFrançois Tigeot WREG32(index_reg, 0x10401); 732*926deccbSFrançois Tigeot WREG32(data_reg, 0x85E08BC0); 733*926deccbSFrançois Tigeot WREG32(index_reg, 0x10402); 734*926deccbSFrançois Tigeot WREG32(data_reg, 0x8018BE90); 735*926deccbSFrançois Tigeot WREG32(index_reg, 0x10500); 736*926deccbSFrançois Tigeot WREG32(data_reg, 0xBFB8BFB0); 737*926deccbSFrançois Tigeot WREG32(index_reg, 0x10501); 738*926deccbSFrançois Tigeot WREG32(data_reg, 0x86C08B40); 739*926deccbSFrançois Tigeot WREG32(index_reg, 0x10502); 740*926deccbSFrançois Tigeot WREG32(data_reg, 0x8010BE90); 741*926deccbSFrançois Tigeot WREG32(index_reg, 0x10600); 742*926deccbSFrançois Tigeot WREG32(data_reg, 0xBF58BFC8); 743*926deccbSFrançois Tigeot WREG32(index_reg, 0x10601); 744*926deccbSFrançois Tigeot WREG32(data_reg, 0x87A08AA0); 745*926deccbSFrançois Tigeot WREG32(index_reg, 0x10602); 746*926deccbSFrançois Tigeot WREG32(data_reg, 0x8010BE98); 747*926deccbSFrançois Tigeot WREG32(index_reg, 0x10700); 748*926deccbSFrançois Tigeot WREG32(data_reg, 0xBF10BFF0); 749*926deccbSFrançois Tigeot WREG32(index_reg, 0x10701); 750*926deccbSFrançois Tigeot WREG32(data_reg, 0x886089E0); 751*926deccbSFrançois Tigeot WREG32(index_reg, 0x10702); 752*926deccbSFrançois Tigeot WREG32(data_reg, 0x8018BEB0); 753*926deccbSFrançois Tigeot WREG32(index_reg, 0x10800); 754*926deccbSFrançois Tigeot WREG32(data_reg, 0xBED8BFE8); 755*926deccbSFrançois Tigeot WREG32(index_reg, 0x10801); 756*926deccbSFrançois Tigeot WREG32(data_reg, 0x89408940); 757*926deccbSFrançois Tigeot WREG32(index_reg, 0x10802); 758*926deccbSFrançois Tigeot WREG32(data_reg, 0xBFE8BED8); 759*926deccbSFrançois Tigeot WREG32(index_reg, 0x20000); 760*926deccbSFrançois Tigeot WREG32(data_reg, 0x80008000); 761*926deccbSFrançois Tigeot WREG32(index_reg, 0x20001); 762*926deccbSFrançois Tigeot WREG32(data_reg, 0x90008000); 763*926deccbSFrançois Tigeot WREG32(index_reg, 0x20002); 764*926deccbSFrançois Tigeot WREG32(data_reg, 0x80008000); 765*926deccbSFrançois Tigeot WREG32(index_reg, 0x20003); 766*926deccbSFrançois Tigeot WREG32(data_reg, 0x80008000); 767*926deccbSFrançois Tigeot WREG32(index_reg, 0x20100); 768*926deccbSFrançois Tigeot WREG32(data_reg, 0x80108000); 769*926deccbSFrançois Tigeot WREG32(index_reg, 0x20101); 770*926deccbSFrançois Tigeot WREG32(data_reg, 0x8FE0BF70); 771*926deccbSFrançois Tigeot WREG32(index_reg, 0x20102); 772*926deccbSFrançois Tigeot WREG32(data_reg, 0xBFE880C0); 773*926deccbSFrançois Tigeot WREG32(index_reg, 0x20103); 774*926deccbSFrançois Tigeot WREG32(data_reg, 0x80008000); 775*926deccbSFrançois Tigeot WREG32(index_reg, 0x20200); 776*926deccbSFrançois Tigeot WREG32(data_reg, 0x8018BFF8); 777*926deccbSFrançois Tigeot WREG32(index_reg, 0x20201); 778*926deccbSFrançois Tigeot WREG32(data_reg, 0x8F80BF08); 779*926deccbSFrançois Tigeot WREG32(index_reg, 0x20202); 780*926deccbSFrançois Tigeot WREG32(data_reg, 0xBFD081A0); 781*926deccbSFrançois Tigeot WREG32(index_reg, 0x20203); 782*926deccbSFrançois Tigeot WREG32(data_reg, 0xBFF88000); 783*926deccbSFrançois Tigeot WREG32(index_reg, 0x20300); 784*926deccbSFrançois Tigeot WREG32(data_reg, 0x80188000); 785*926deccbSFrançois Tigeot WREG32(index_reg, 0x20301); 786*926deccbSFrançois Tigeot WREG32(data_reg, 0x8EE0BEC0); 787*926deccbSFrançois Tigeot WREG32(index_reg, 0x20302); 788*926deccbSFrançois Tigeot WREG32(data_reg, 0xBFB082A0); 789*926deccbSFrançois Tigeot WREG32(index_reg, 0x20303); 790*926deccbSFrançois Tigeot WREG32(data_reg, 0x80008000); 791*926deccbSFrançois Tigeot WREG32(index_reg, 0x20400); 792*926deccbSFrançois Tigeot WREG32(data_reg, 0x80188000); 793*926deccbSFrançois Tigeot WREG32(index_reg, 0x20401); 794*926deccbSFrançois Tigeot WREG32(data_reg, 0x8E00BEA0); 795*926deccbSFrançois Tigeot WREG32(index_reg, 0x20402); 796*926deccbSFrançois Tigeot WREG32(data_reg, 0xBF8883C0); 797*926deccbSFrançois Tigeot WREG32(index_reg, 0x20403); 798*926deccbSFrançois Tigeot WREG32(data_reg, 0x80008000); 799*926deccbSFrançois Tigeot WREG32(index_reg, 0x20500); 800*926deccbSFrançois Tigeot WREG32(data_reg, 0x80188000); 801*926deccbSFrançois Tigeot WREG32(index_reg, 0x20501); 802*926deccbSFrançois Tigeot WREG32(data_reg, 0x8D00BE90); 803*926deccbSFrançois Tigeot WREG32(index_reg, 0x20502); 804*926deccbSFrançois Tigeot WREG32(data_reg, 0xBF588500); 805*926deccbSFrançois Tigeot WREG32(index_reg, 0x20503); 806*926deccbSFrançois Tigeot WREG32(data_reg, 0x80008008); 807*926deccbSFrançois Tigeot WREG32(index_reg, 0x20600); 808*926deccbSFrançois Tigeot WREG32(data_reg, 0x80188000); 809*926deccbSFrançois Tigeot WREG32(index_reg, 0x20601); 810*926deccbSFrançois Tigeot WREG32(data_reg, 0x8BC0BE98); 811*926deccbSFrançois Tigeot WREG32(index_reg, 0x20602); 812*926deccbSFrançois Tigeot WREG32(data_reg, 0xBF308660); 813*926deccbSFrançois Tigeot WREG32(index_reg, 0x20603); 814*926deccbSFrançois Tigeot WREG32(data_reg, 0x80008008); 815*926deccbSFrançois Tigeot WREG32(index_reg, 0x20700); 816*926deccbSFrançois Tigeot WREG32(data_reg, 0x80108000); 817*926deccbSFrançois Tigeot WREG32(index_reg, 0x20701); 818*926deccbSFrançois Tigeot WREG32(data_reg, 0x8A80BEB0); 819*926deccbSFrançois Tigeot WREG32(index_reg, 0x20702); 820*926deccbSFrançois Tigeot WREG32(data_reg, 0xBF0087C0); 821*926deccbSFrançois Tigeot WREG32(index_reg, 0x20703); 822*926deccbSFrançois Tigeot WREG32(data_reg, 0x80008008); 823*926deccbSFrançois Tigeot WREG32(index_reg, 0x20800); 824*926deccbSFrançois Tigeot WREG32(data_reg, 0x80108000); 825*926deccbSFrançois Tigeot WREG32(index_reg, 0x20801); 826*926deccbSFrançois Tigeot WREG32(data_reg, 0x8920BED0); 827*926deccbSFrançois Tigeot WREG32(index_reg, 0x20802); 828*926deccbSFrançois Tigeot WREG32(data_reg, 0xBED08920); 829*926deccbSFrançois Tigeot WREG32(index_reg, 0x20803); 830*926deccbSFrançois Tigeot WREG32(data_reg, 0x80008010); 831*926deccbSFrançois Tigeot WREG32(index_reg, 0x30000); 832*926deccbSFrançois Tigeot WREG32(data_reg, 0x90008000); 833*926deccbSFrançois Tigeot WREG32(index_reg, 0x30001); 834*926deccbSFrançois Tigeot WREG32(data_reg, 0x80008000); 835*926deccbSFrançois Tigeot WREG32(index_reg, 0x30100); 836*926deccbSFrançois Tigeot WREG32(data_reg, 0x8FE0BF90); 837*926deccbSFrançois Tigeot WREG32(index_reg, 0x30101); 838*926deccbSFrançois Tigeot WREG32(data_reg, 0xBFF880A0); 839*926deccbSFrançois Tigeot WREG32(index_reg, 0x30200); 840*926deccbSFrançois Tigeot WREG32(data_reg, 0x8F60BF40); 841*926deccbSFrançois Tigeot WREG32(index_reg, 0x30201); 842*926deccbSFrançois Tigeot WREG32(data_reg, 0xBFE88180); 843*926deccbSFrançois Tigeot WREG32(index_reg, 0x30300); 844*926deccbSFrançois Tigeot WREG32(data_reg, 0x8EC0BF00); 845*926deccbSFrançois Tigeot WREG32(index_reg, 0x30301); 846*926deccbSFrançois Tigeot WREG32(data_reg, 0xBFC88280); 847*926deccbSFrançois Tigeot WREG32(index_reg, 0x30400); 848*926deccbSFrançois Tigeot WREG32(data_reg, 0x8DE0BEE0); 849*926deccbSFrançois Tigeot WREG32(index_reg, 0x30401); 850*926deccbSFrançois Tigeot WREG32(data_reg, 0xBFA083A0); 851*926deccbSFrançois Tigeot WREG32(index_reg, 0x30500); 852*926deccbSFrançois Tigeot WREG32(data_reg, 0x8CE0BED0); 853*926deccbSFrançois Tigeot WREG32(index_reg, 0x30501); 854*926deccbSFrançois Tigeot WREG32(data_reg, 0xBF7884E0); 855*926deccbSFrançois Tigeot WREG32(index_reg, 0x30600); 856*926deccbSFrançois Tigeot WREG32(data_reg, 0x8BA0BED8); 857*926deccbSFrançois Tigeot WREG32(index_reg, 0x30601); 858*926deccbSFrançois Tigeot WREG32(data_reg, 0xBF508640); 859*926deccbSFrançois Tigeot WREG32(index_reg, 0x30700); 860*926deccbSFrançois Tigeot WREG32(data_reg, 0x8A60BEE8); 861*926deccbSFrançois Tigeot WREG32(index_reg, 0x30701); 862*926deccbSFrançois Tigeot WREG32(data_reg, 0xBF2087A0); 863*926deccbSFrançois Tigeot WREG32(index_reg, 0x30800); 864*926deccbSFrançois Tigeot WREG32(data_reg, 0x8900BF00); 865*926deccbSFrançois Tigeot WREG32(index_reg, 0x30801); 866*926deccbSFrançois Tigeot WREG32(data_reg, 0xBF008900); 867*926deccbSFrançois Tigeot } 868*926deccbSFrançois Tigeot 869*926deccbSFrançois Tigeot struct rv515_watermark { 870*926deccbSFrançois Tigeot u32 lb_request_fifo_depth; 871*926deccbSFrançois Tigeot fixed20_12 num_line_pair; 872*926deccbSFrançois Tigeot fixed20_12 estimated_width; 873*926deccbSFrançois Tigeot fixed20_12 worst_case_latency; 874*926deccbSFrançois Tigeot fixed20_12 consumption_rate; 875*926deccbSFrançois Tigeot fixed20_12 active_time; 876*926deccbSFrançois Tigeot fixed20_12 dbpp; 877*926deccbSFrançois Tigeot fixed20_12 priority_mark_max; 878*926deccbSFrançois Tigeot fixed20_12 priority_mark; 879*926deccbSFrançois Tigeot fixed20_12 sclk; 880*926deccbSFrançois Tigeot }; 881*926deccbSFrançois Tigeot 882*926deccbSFrançois Tigeot static void rv515_crtc_bandwidth_compute(struct radeon_device *rdev, 883*926deccbSFrançois Tigeot struct radeon_crtc *crtc, 884*926deccbSFrançois Tigeot struct rv515_watermark *wm) 885*926deccbSFrançois Tigeot { 886*926deccbSFrançois Tigeot struct drm_display_mode *mode = &crtc->base.mode; 887*926deccbSFrançois Tigeot fixed20_12 a, b, c; 888*926deccbSFrançois Tigeot fixed20_12 pclk, request_fifo_depth, tolerable_latency, estimated_width; 889*926deccbSFrançois Tigeot fixed20_12 consumption_time, line_time, chunk_time, read_delay_latency; 890*926deccbSFrançois Tigeot 891*926deccbSFrançois Tigeot if (!crtc->base.enabled) { 892*926deccbSFrançois Tigeot /* FIXME: wouldn't it better to set priority mark to maximum */ 893*926deccbSFrançois Tigeot wm->lb_request_fifo_depth = 4; 894*926deccbSFrançois Tigeot return; 895*926deccbSFrançois Tigeot } 896*926deccbSFrançois Tigeot 897*926deccbSFrançois Tigeot if (crtc->vsc.full > dfixed_const(2)) 898*926deccbSFrançois Tigeot wm->num_line_pair.full = dfixed_const(2); 899*926deccbSFrançois Tigeot else 900*926deccbSFrançois Tigeot wm->num_line_pair.full = dfixed_const(1); 901*926deccbSFrançois Tigeot 902*926deccbSFrançois Tigeot b.full = dfixed_const(mode->crtc_hdisplay); 903*926deccbSFrançois Tigeot c.full = dfixed_const(256); 904*926deccbSFrançois Tigeot a.full = dfixed_div(b, c); 905*926deccbSFrançois Tigeot request_fifo_depth.full = dfixed_mul(a, wm->num_line_pair); 906*926deccbSFrançois Tigeot request_fifo_depth.full = dfixed_ceil(request_fifo_depth); 907*926deccbSFrançois Tigeot if (a.full < dfixed_const(4)) { 908*926deccbSFrançois Tigeot wm->lb_request_fifo_depth = 4; 909*926deccbSFrançois Tigeot } else { 910*926deccbSFrançois Tigeot wm->lb_request_fifo_depth = dfixed_trunc(request_fifo_depth); 911*926deccbSFrançois Tigeot } 912*926deccbSFrançois Tigeot 913*926deccbSFrançois Tigeot /* Determine consumption rate 914*926deccbSFrançois Tigeot * pclk = pixel clock period(ns) = 1000 / (mode.clock / 1000) 915*926deccbSFrançois Tigeot * vtaps = number of vertical taps, 916*926deccbSFrançois Tigeot * vsc = vertical scaling ratio, defined as source/destination 917*926deccbSFrançois Tigeot * hsc = horizontal scaling ration, defined as source/destination 918*926deccbSFrançois Tigeot */ 919*926deccbSFrançois Tigeot a.full = dfixed_const(mode->clock); 920*926deccbSFrançois Tigeot b.full = dfixed_const(1000); 921*926deccbSFrançois Tigeot a.full = dfixed_div(a, b); 922*926deccbSFrançois Tigeot pclk.full = dfixed_div(b, a); 923*926deccbSFrançois Tigeot if (crtc->rmx_type != RMX_OFF) { 924*926deccbSFrançois Tigeot b.full = dfixed_const(2); 925*926deccbSFrançois Tigeot if (crtc->vsc.full > b.full) 926*926deccbSFrançois Tigeot b.full = crtc->vsc.full; 927*926deccbSFrançois Tigeot b.full = dfixed_mul(b, crtc->hsc); 928*926deccbSFrançois Tigeot c.full = dfixed_const(2); 929*926deccbSFrançois Tigeot b.full = dfixed_div(b, c); 930*926deccbSFrançois Tigeot consumption_time.full = dfixed_div(pclk, b); 931*926deccbSFrançois Tigeot } else { 932*926deccbSFrançois Tigeot consumption_time.full = pclk.full; 933*926deccbSFrançois Tigeot } 934*926deccbSFrançois Tigeot a.full = dfixed_const(1); 935*926deccbSFrançois Tigeot wm->consumption_rate.full = dfixed_div(a, consumption_time); 936*926deccbSFrançois Tigeot 937*926deccbSFrançois Tigeot 938*926deccbSFrançois Tigeot /* Determine line time 939*926deccbSFrançois Tigeot * LineTime = total time for one line of displayhtotal 940*926deccbSFrançois Tigeot * LineTime = total number of horizontal pixels 941*926deccbSFrançois Tigeot * pclk = pixel clock period(ns) 942*926deccbSFrançois Tigeot */ 943*926deccbSFrançois Tigeot a.full = dfixed_const(crtc->base.mode.crtc_htotal); 944*926deccbSFrançois Tigeot line_time.full = dfixed_mul(a, pclk); 945*926deccbSFrançois Tigeot 946*926deccbSFrançois Tigeot /* Determine active time 947*926deccbSFrançois Tigeot * ActiveTime = time of active region of display within one line, 948*926deccbSFrançois Tigeot * hactive = total number of horizontal active pixels 949*926deccbSFrançois Tigeot * htotal = total number of horizontal pixels 950*926deccbSFrançois Tigeot */ 951*926deccbSFrançois Tigeot a.full = dfixed_const(crtc->base.mode.crtc_htotal); 952*926deccbSFrançois Tigeot b.full = dfixed_const(crtc->base.mode.crtc_hdisplay); 953*926deccbSFrançois Tigeot wm->active_time.full = dfixed_mul(line_time, b); 954*926deccbSFrançois Tigeot wm->active_time.full = dfixed_div(wm->active_time, a); 955*926deccbSFrançois Tigeot 956*926deccbSFrançois Tigeot /* Determine chunk time 957*926deccbSFrançois Tigeot * ChunkTime = the time it takes the DCP to send one chunk of data 958*926deccbSFrançois Tigeot * to the LB which consists of pipeline delay and inter chunk gap 959*926deccbSFrançois Tigeot * sclk = system clock(Mhz) 960*926deccbSFrançois Tigeot */ 961*926deccbSFrançois Tigeot a.full = dfixed_const(600 * 1000); 962*926deccbSFrançois Tigeot chunk_time.full = dfixed_div(a, rdev->pm.sclk); 963*926deccbSFrançois Tigeot read_delay_latency.full = dfixed_const(1000); 964*926deccbSFrançois Tigeot 965*926deccbSFrançois Tigeot /* Determine the worst case latency 966*926deccbSFrançois Tigeot * NumLinePair = Number of line pairs to request(1=2 lines, 2=4 lines) 967*926deccbSFrançois Tigeot * WorstCaseLatency = worst case time from urgent to when the MC starts 968*926deccbSFrançois Tigeot * to return data 969*926deccbSFrançois Tigeot * READ_DELAY_IDLE_MAX = constant of 1us 970*926deccbSFrançois Tigeot * ChunkTime = time it takes the DCP to send one chunk of data to the LB 971*926deccbSFrançois Tigeot * which consists of pipeline delay and inter chunk gap 972*926deccbSFrançois Tigeot */ 973*926deccbSFrançois Tigeot if (dfixed_trunc(wm->num_line_pair) > 1) { 974*926deccbSFrançois Tigeot a.full = dfixed_const(3); 975*926deccbSFrançois Tigeot wm->worst_case_latency.full = dfixed_mul(a, chunk_time); 976*926deccbSFrançois Tigeot wm->worst_case_latency.full += read_delay_latency.full; 977*926deccbSFrançois Tigeot } else { 978*926deccbSFrançois Tigeot wm->worst_case_latency.full = chunk_time.full + read_delay_latency.full; 979*926deccbSFrançois Tigeot } 980*926deccbSFrançois Tigeot 981*926deccbSFrançois Tigeot /* Determine the tolerable latency 982*926deccbSFrançois Tigeot * TolerableLatency = Any given request has only 1 line time 983*926deccbSFrançois Tigeot * for the data to be returned 984*926deccbSFrançois Tigeot * LBRequestFifoDepth = Number of chunk requests the LB can 985*926deccbSFrançois Tigeot * put into the request FIFO for a display 986*926deccbSFrançois Tigeot * LineTime = total time for one line of display 987*926deccbSFrançois Tigeot * ChunkTime = the time it takes the DCP to send one chunk 988*926deccbSFrançois Tigeot * of data to the LB which consists of 989*926deccbSFrançois Tigeot * pipeline delay and inter chunk gap 990*926deccbSFrançois Tigeot */ 991*926deccbSFrançois Tigeot if ((2+wm->lb_request_fifo_depth) >= dfixed_trunc(request_fifo_depth)) { 992*926deccbSFrançois Tigeot tolerable_latency.full = line_time.full; 993*926deccbSFrançois Tigeot } else { 994*926deccbSFrançois Tigeot tolerable_latency.full = dfixed_const(wm->lb_request_fifo_depth - 2); 995*926deccbSFrançois Tigeot tolerable_latency.full = request_fifo_depth.full - tolerable_latency.full; 996*926deccbSFrançois Tigeot tolerable_latency.full = dfixed_mul(tolerable_latency, chunk_time); 997*926deccbSFrançois Tigeot tolerable_latency.full = line_time.full - tolerable_latency.full; 998*926deccbSFrançois Tigeot } 999*926deccbSFrançois Tigeot /* We assume worst case 32bits (4 bytes) */ 1000*926deccbSFrançois Tigeot wm->dbpp.full = dfixed_const(2 * 16); 1001*926deccbSFrançois Tigeot 1002*926deccbSFrançois Tigeot /* Determine the maximum priority mark 1003*926deccbSFrançois Tigeot * width = viewport width in pixels 1004*926deccbSFrançois Tigeot */ 1005*926deccbSFrançois Tigeot a.full = dfixed_const(16); 1006*926deccbSFrançois Tigeot wm->priority_mark_max.full = dfixed_const(crtc->base.mode.crtc_hdisplay); 1007*926deccbSFrançois Tigeot wm->priority_mark_max.full = dfixed_div(wm->priority_mark_max, a); 1008*926deccbSFrançois Tigeot wm->priority_mark_max.full = dfixed_ceil(wm->priority_mark_max); 1009*926deccbSFrançois Tigeot 1010*926deccbSFrançois Tigeot /* Determine estimated width */ 1011*926deccbSFrançois Tigeot estimated_width.full = tolerable_latency.full - wm->worst_case_latency.full; 1012*926deccbSFrançois Tigeot estimated_width.full = dfixed_div(estimated_width, consumption_time); 1013*926deccbSFrançois Tigeot if (dfixed_trunc(estimated_width) > crtc->base.mode.crtc_hdisplay) { 1014*926deccbSFrançois Tigeot wm->priority_mark.full = wm->priority_mark_max.full; 1015*926deccbSFrançois Tigeot } else { 1016*926deccbSFrançois Tigeot a.full = dfixed_const(16); 1017*926deccbSFrançois Tigeot wm->priority_mark.full = dfixed_div(estimated_width, a); 1018*926deccbSFrançois Tigeot wm->priority_mark.full = dfixed_ceil(wm->priority_mark); 1019*926deccbSFrançois Tigeot wm->priority_mark.full = wm->priority_mark_max.full - wm->priority_mark.full; 1020*926deccbSFrançois Tigeot } 1021*926deccbSFrançois Tigeot } 1022*926deccbSFrançois Tigeot 1023*926deccbSFrançois Tigeot void rv515_bandwidth_avivo_update(struct radeon_device *rdev) 1024*926deccbSFrançois Tigeot { 1025*926deccbSFrançois Tigeot struct drm_display_mode *mode0 = NULL; 1026*926deccbSFrançois Tigeot struct drm_display_mode *mode1 = NULL; 1027*926deccbSFrançois Tigeot struct rv515_watermark wm0; 1028*926deccbSFrançois Tigeot struct rv515_watermark wm1; 1029*926deccbSFrançois Tigeot u32 tmp; 1030*926deccbSFrançois Tigeot u32 d1mode_priority_a_cnt = MODE_PRIORITY_OFF; 1031*926deccbSFrançois Tigeot u32 d2mode_priority_a_cnt = MODE_PRIORITY_OFF; 1032*926deccbSFrançois Tigeot fixed20_12 priority_mark02, priority_mark12, fill_rate; 1033*926deccbSFrançois Tigeot fixed20_12 a, b; 1034*926deccbSFrançois Tigeot 1035*926deccbSFrançois Tigeot if (rdev->mode_info.crtcs[0]->base.enabled) 1036*926deccbSFrançois Tigeot mode0 = &rdev->mode_info.crtcs[0]->base.mode; 1037*926deccbSFrançois Tigeot if (rdev->mode_info.crtcs[1]->base.enabled) 1038*926deccbSFrançois Tigeot mode1 = &rdev->mode_info.crtcs[1]->base.mode; 1039*926deccbSFrançois Tigeot rs690_line_buffer_adjust(rdev, mode0, mode1); 1040*926deccbSFrançois Tigeot 1041*926deccbSFrançois Tigeot rv515_crtc_bandwidth_compute(rdev, rdev->mode_info.crtcs[0], &wm0); 1042*926deccbSFrançois Tigeot rv515_crtc_bandwidth_compute(rdev, rdev->mode_info.crtcs[1], &wm1); 1043*926deccbSFrançois Tigeot 1044*926deccbSFrançois Tigeot tmp = wm0.lb_request_fifo_depth; 1045*926deccbSFrançois Tigeot tmp |= wm1.lb_request_fifo_depth << 16; 1046*926deccbSFrançois Tigeot WREG32(LB_MAX_REQ_OUTSTANDING, tmp); 1047*926deccbSFrançois Tigeot 1048*926deccbSFrançois Tigeot if (mode0 && mode1) { 1049*926deccbSFrançois Tigeot if (dfixed_trunc(wm0.dbpp) > 64) 1050*926deccbSFrançois Tigeot a.full = dfixed_div(wm0.dbpp, wm0.num_line_pair); 1051*926deccbSFrançois Tigeot else 1052*926deccbSFrançois Tigeot a.full = wm0.num_line_pair.full; 1053*926deccbSFrançois Tigeot if (dfixed_trunc(wm1.dbpp) > 64) 1054*926deccbSFrançois Tigeot b.full = dfixed_div(wm1.dbpp, wm1.num_line_pair); 1055*926deccbSFrançois Tigeot else 1056*926deccbSFrançois Tigeot b.full = wm1.num_line_pair.full; 1057*926deccbSFrançois Tigeot a.full += b.full; 1058*926deccbSFrançois Tigeot fill_rate.full = dfixed_div(wm0.sclk, a); 1059*926deccbSFrançois Tigeot if (wm0.consumption_rate.full > fill_rate.full) { 1060*926deccbSFrançois Tigeot b.full = wm0.consumption_rate.full - fill_rate.full; 1061*926deccbSFrançois Tigeot b.full = dfixed_mul(b, wm0.active_time); 1062*926deccbSFrançois Tigeot a.full = dfixed_const(16); 1063*926deccbSFrançois Tigeot b.full = dfixed_div(b, a); 1064*926deccbSFrançois Tigeot a.full = dfixed_mul(wm0.worst_case_latency, 1065*926deccbSFrançois Tigeot wm0.consumption_rate); 1066*926deccbSFrançois Tigeot priority_mark02.full = a.full + b.full; 1067*926deccbSFrançois Tigeot } else { 1068*926deccbSFrançois Tigeot a.full = dfixed_mul(wm0.worst_case_latency, 1069*926deccbSFrançois Tigeot wm0.consumption_rate); 1070*926deccbSFrançois Tigeot b.full = dfixed_const(16 * 1000); 1071*926deccbSFrançois Tigeot priority_mark02.full = dfixed_div(a, b); 1072*926deccbSFrançois Tigeot } 1073*926deccbSFrançois Tigeot if (wm1.consumption_rate.full > fill_rate.full) { 1074*926deccbSFrançois Tigeot b.full = wm1.consumption_rate.full - fill_rate.full; 1075*926deccbSFrançois Tigeot b.full = dfixed_mul(b, wm1.active_time); 1076*926deccbSFrançois Tigeot a.full = dfixed_const(16); 1077*926deccbSFrançois Tigeot b.full = dfixed_div(b, a); 1078*926deccbSFrançois Tigeot a.full = dfixed_mul(wm1.worst_case_latency, 1079*926deccbSFrançois Tigeot wm1.consumption_rate); 1080*926deccbSFrançois Tigeot priority_mark12.full = a.full + b.full; 1081*926deccbSFrançois Tigeot } else { 1082*926deccbSFrançois Tigeot a.full = dfixed_mul(wm1.worst_case_latency, 1083*926deccbSFrançois Tigeot wm1.consumption_rate); 1084*926deccbSFrançois Tigeot b.full = dfixed_const(16 * 1000); 1085*926deccbSFrançois Tigeot priority_mark12.full = dfixed_div(a, b); 1086*926deccbSFrançois Tigeot } 1087*926deccbSFrançois Tigeot if (wm0.priority_mark.full > priority_mark02.full) 1088*926deccbSFrançois Tigeot priority_mark02.full = wm0.priority_mark.full; 1089*926deccbSFrançois Tigeot if (dfixed_trunc(priority_mark02) < 0) 1090*926deccbSFrançois Tigeot priority_mark02.full = 0; 1091*926deccbSFrançois Tigeot if (wm0.priority_mark_max.full > priority_mark02.full) 1092*926deccbSFrançois Tigeot priority_mark02.full = wm0.priority_mark_max.full; 1093*926deccbSFrançois Tigeot if (wm1.priority_mark.full > priority_mark12.full) 1094*926deccbSFrançois Tigeot priority_mark12.full = wm1.priority_mark.full; 1095*926deccbSFrançois Tigeot if (dfixed_trunc(priority_mark12) < 0) 1096*926deccbSFrançois Tigeot priority_mark12.full = 0; 1097*926deccbSFrançois Tigeot if (wm1.priority_mark_max.full > priority_mark12.full) 1098*926deccbSFrançois Tigeot priority_mark12.full = wm1.priority_mark_max.full; 1099*926deccbSFrançois Tigeot d1mode_priority_a_cnt = dfixed_trunc(priority_mark02); 1100*926deccbSFrançois Tigeot d2mode_priority_a_cnt = dfixed_trunc(priority_mark12); 1101*926deccbSFrançois Tigeot if (rdev->disp_priority == 2) { 1102*926deccbSFrançois Tigeot d1mode_priority_a_cnt |= MODE_PRIORITY_ALWAYS_ON; 1103*926deccbSFrançois Tigeot d2mode_priority_a_cnt |= MODE_PRIORITY_ALWAYS_ON; 1104*926deccbSFrançois Tigeot } 1105*926deccbSFrançois Tigeot } else if (mode0) { 1106*926deccbSFrançois Tigeot if (dfixed_trunc(wm0.dbpp) > 64) 1107*926deccbSFrançois Tigeot a.full = dfixed_div(wm0.dbpp, wm0.num_line_pair); 1108*926deccbSFrançois Tigeot else 1109*926deccbSFrançois Tigeot a.full = wm0.num_line_pair.full; 1110*926deccbSFrançois Tigeot fill_rate.full = dfixed_div(wm0.sclk, a); 1111*926deccbSFrançois Tigeot if (wm0.consumption_rate.full > fill_rate.full) { 1112*926deccbSFrançois Tigeot b.full = wm0.consumption_rate.full - fill_rate.full; 1113*926deccbSFrançois Tigeot b.full = dfixed_mul(b, wm0.active_time); 1114*926deccbSFrançois Tigeot a.full = dfixed_const(16); 1115*926deccbSFrançois Tigeot b.full = dfixed_div(b, a); 1116*926deccbSFrançois Tigeot a.full = dfixed_mul(wm0.worst_case_latency, 1117*926deccbSFrançois Tigeot wm0.consumption_rate); 1118*926deccbSFrançois Tigeot priority_mark02.full = a.full + b.full; 1119*926deccbSFrançois Tigeot } else { 1120*926deccbSFrançois Tigeot a.full = dfixed_mul(wm0.worst_case_latency, 1121*926deccbSFrançois Tigeot wm0.consumption_rate); 1122*926deccbSFrançois Tigeot b.full = dfixed_const(16); 1123*926deccbSFrançois Tigeot priority_mark02.full = dfixed_div(a, b); 1124*926deccbSFrançois Tigeot } 1125*926deccbSFrançois Tigeot if (wm0.priority_mark.full > priority_mark02.full) 1126*926deccbSFrançois Tigeot priority_mark02.full = wm0.priority_mark.full; 1127*926deccbSFrançois Tigeot if (dfixed_trunc(priority_mark02) < 0) 1128*926deccbSFrançois Tigeot priority_mark02.full = 0; 1129*926deccbSFrançois Tigeot if (wm0.priority_mark_max.full > priority_mark02.full) 1130*926deccbSFrançois Tigeot priority_mark02.full = wm0.priority_mark_max.full; 1131*926deccbSFrançois Tigeot d1mode_priority_a_cnt = dfixed_trunc(priority_mark02); 1132*926deccbSFrançois Tigeot if (rdev->disp_priority == 2) 1133*926deccbSFrançois Tigeot d1mode_priority_a_cnt |= MODE_PRIORITY_ALWAYS_ON; 1134*926deccbSFrançois Tigeot } else if (mode1) { 1135*926deccbSFrançois Tigeot if (dfixed_trunc(wm1.dbpp) > 64) 1136*926deccbSFrançois Tigeot a.full = dfixed_div(wm1.dbpp, wm1.num_line_pair); 1137*926deccbSFrançois Tigeot else 1138*926deccbSFrançois Tigeot a.full = wm1.num_line_pair.full; 1139*926deccbSFrançois Tigeot fill_rate.full = dfixed_div(wm1.sclk, a); 1140*926deccbSFrançois Tigeot if (wm1.consumption_rate.full > fill_rate.full) { 1141*926deccbSFrançois Tigeot b.full = wm1.consumption_rate.full - fill_rate.full; 1142*926deccbSFrançois Tigeot b.full = dfixed_mul(b, wm1.active_time); 1143*926deccbSFrançois Tigeot a.full = dfixed_const(16); 1144*926deccbSFrançois Tigeot b.full = dfixed_div(b, a); 1145*926deccbSFrançois Tigeot a.full = dfixed_mul(wm1.worst_case_latency, 1146*926deccbSFrançois Tigeot wm1.consumption_rate); 1147*926deccbSFrançois Tigeot priority_mark12.full = a.full + b.full; 1148*926deccbSFrançois Tigeot } else { 1149*926deccbSFrançois Tigeot a.full = dfixed_mul(wm1.worst_case_latency, 1150*926deccbSFrançois Tigeot wm1.consumption_rate); 1151*926deccbSFrançois Tigeot b.full = dfixed_const(16 * 1000); 1152*926deccbSFrançois Tigeot priority_mark12.full = dfixed_div(a, b); 1153*926deccbSFrançois Tigeot } 1154*926deccbSFrançois Tigeot if (wm1.priority_mark.full > priority_mark12.full) 1155*926deccbSFrançois Tigeot priority_mark12.full = wm1.priority_mark.full; 1156*926deccbSFrançois Tigeot if (dfixed_trunc(priority_mark12) < 0) 1157*926deccbSFrançois Tigeot priority_mark12.full = 0; 1158*926deccbSFrançois Tigeot if (wm1.priority_mark_max.full > priority_mark12.full) 1159*926deccbSFrançois Tigeot priority_mark12.full = wm1.priority_mark_max.full; 1160*926deccbSFrançois Tigeot d2mode_priority_a_cnt = dfixed_trunc(priority_mark12); 1161*926deccbSFrançois Tigeot if (rdev->disp_priority == 2) 1162*926deccbSFrançois Tigeot d2mode_priority_a_cnt |= MODE_PRIORITY_ALWAYS_ON; 1163*926deccbSFrançois Tigeot } 1164*926deccbSFrançois Tigeot 1165*926deccbSFrançois Tigeot WREG32(D1MODE_PRIORITY_A_CNT, d1mode_priority_a_cnt); 1166*926deccbSFrançois Tigeot WREG32(D1MODE_PRIORITY_B_CNT, d1mode_priority_a_cnt); 1167*926deccbSFrançois Tigeot WREG32(D2MODE_PRIORITY_A_CNT, d2mode_priority_a_cnt); 1168*926deccbSFrançois Tigeot WREG32(D2MODE_PRIORITY_B_CNT, d2mode_priority_a_cnt); 1169*926deccbSFrançois Tigeot } 1170*926deccbSFrançois Tigeot 1171*926deccbSFrançois Tigeot void rv515_bandwidth_update(struct radeon_device *rdev) 1172*926deccbSFrançois Tigeot { 1173*926deccbSFrançois Tigeot uint32_t tmp; 1174*926deccbSFrançois Tigeot struct drm_display_mode *mode0 = NULL; 1175*926deccbSFrançois Tigeot struct drm_display_mode *mode1 = NULL; 1176*926deccbSFrançois Tigeot 1177*926deccbSFrançois Tigeot radeon_update_display_priority(rdev); 1178*926deccbSFrançois Tigeot 1179*926deccbSFrançois Tigeot if (rdev->mode_info.crtcs[0]->base.enabled) 1180*926deccbSFrançois Tigeot mode0 = &rdev->mode_info.crtcs[0]->base.mode; 1181*926deccbSFrançois Tigeot if (rdev->mode_info.crtcs[1]->base.enabled) 1182*926deccbSFrançois Tigeot mode1 = &rdev->mode_info.crtcs[1]->base.mode; 1183*926deccbSFrançois Tigeot /* 1184*926deccbSFrançois Tigeot * Set display0/1 priority up in the memory controller for 1185*926deccbSFrançois Tigeot * modes if the user specifies HIGH for displaypriority 1186*926deccbSFrançois Tigeot * option. 1187*926deccbSFrançois Tigeot */ 1188*926deccbSFrançois Tigeot if ((rdev->disp_priority == 2) && 1189*926deccbSFrançois Tigeot (rdev->family == CHIP_RV515)) { 1190*926deccbSFrançois Tigeot tmp = RREG32_MC(MC_MISC_LAT_TIMER); 1191*926deccbSFrançois Tigeot tmp &= ~MC_DISP1R_INIT_LAT_MASK; 1192*926deccbSFrançois Tigeot tmp &= ~MC_DISP0R_INIT_LAT_MASK; 1193*926deccbSFrançois Tigeot if (mode1) 1194*926deccbSFrançois Tigeot tmp |= (1 << MC_DISP1R_INIT_LAT_SHIFT); 1195*926deccbSFrançois Tigeot if (mode0) 1196*926deccbSFrançois Tigeot tmp |= (1 << MC_DISP0R_INIT_LAT_SHIFT); 1197*926deccbSFrançois Tigeot WREG32_MC(MC_MISC_LAT_TIMER, tmp); 1198*926deccbSFrançois Tigeot } 1199*926deccbSFrançois Tigeot rv515_bandwidth_avivo_update(rdev); 1200*926deccbSFrançois Tigeot } 1201