1254885Sdumbbell/* 2254885Sdumbbell * Copyright 2008 Advanced Micro Devices, Inc. 3254885Sdumbbell * Copyright 2008 Red Hat Inc. 4254885Sdumbbell * Copyright 2009 Jerome Glisse. 5254885Sdumbbell * 6254885Sdumbbell * Permission is hereby granted, free of charge, to any person obtaining a 7254885Sdumbbell * copy of this software and associated documentation files (the "Software"), 8254885Sdumbbell * to deal in the Software without restriction, including without limitation 9254885Sdumbbell * the rights to use, copy, modify, merge, publish, distribute, sublicense, 10254885Sdumbbell * and/or sell copies of the Software, and to permit persons to whom the 11254885Sdumbbell * Software is furnished to do so, subject to the following conditions: 12254885Sdumbbell * 13254885Sdumbbell * The above copyright notice and this permission notice shall be included in 14254885Sdumbbell * all copies or substantial portions of the Software. 15254885Sdumbbell * 16254885Sdumbbell * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17254885Sdumbbell * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18254885Sdumbbell * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19254885Sdumbbell * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR 20254885Sdumbbell * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 21254885Sdumbbell * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22254885Sdumbbell * OTHER DEALINGS IN THE SOFTWARE. 23254885Sdumbbell * 24254885Sdumbbell * Authors: Dave Airlie 25254885Sdumbbell * Alex Deucher 26254885Sdumbbell * Jerome Glisse 27254885Sdumbbell */ 28254885Sdumbbell 29254885Sdumbbell#include <sys/cdefs.h> 30254885Sdumbbell__FBSDID("$FreeBSD: releng/10.2/sys/dev/drm2/radeon/rv515.c 282199 2015-04-28 19:35:05Z dumbbell $"); 31254885Sdumbbell 32254885Sdumbbell#include <dev/drm2/drmP.h> 33254885Sdumbbell#include "rv515d.h" 34254885Sdumbbell#include "radeon.h" 35254885Sdumbbell#include "radeon_asic.h" 36254885Sdumbbell#include "atom.h" 37254885Sdumbbell#include "rv515_reg_safe.h" 38254885Sdumbbell 39254885Sdumbbell/* This files gather functions specifics to: rv515 */ 40254885Sdumbbellstatic int rv515_debugfs_pipes_info_init(struct radeon_device *rdev); 41254885Sdumbbellstatic int rv515_debugfs_ga_info_init(struct radeon_device *rdev); 42254885Sdumbbellstatic void rv515_gpu_init(struct radeon_device *rdev); 43282199Sdumbbell#ifdef FREEBSD_WIP /* FreeBSD: to please GCC 4.2. */ 44282199Sdumbbellint rv515_mc_wait_for_idle(struct radeon_device *rdev); 45282199Sdumbbell#endif 46254885Sdumbbell 47254885Sdumbbellstatic const u32 crtc_offsets[2] = 48254885Sdumbbell{ 49254885Sdumbbell 0, 50254885Sdumbbell AVIVO_D2CRTC_H_TOTAL - AVIVO_D1CRTC_H_TOTAL 51254885Sdumbbell}; 52254885Sdumbbell 53254885Sdumbbellvoid rv515_debugfs(struct radeon_device *rdev) 54254885Sdumbbell{ 55254885Sdumbbell if (r100_debugfs_rbbm_init(rdev)) { 56254885Sdumbbell DRM_ERROR("Failed to register debugfs file for RBBM !\n"); 57254885Sdumbbell } 58254885Sdumbbell if (rv515_debugfs_pipes_info_init(rdev)) { 59254885Sdumbbell DRM_ERROR("Failed to register debugfs file for pipes !\n"); 60254885Sdumbbell } 61254885Sdumbbell if (rv515_debugfs_ga_info_init(rdev)) { 62254885Sdumbbell DRM_ERROR("Failed to register debugfs file for pipes !\n"); 63254885Sdumbbell } 64254885Sdumbbell} 65254885Sdumbbell 66254885Sdumbbellvoid rv515_ring_start(struct radeon_device *rdev, struct radeon_ring *ring) 67254885Sdumbbell{ 68254885Sdumbbell int r; 69254885Sdumbbell 70254885Sdumbbell r = radeon_ring_lock(rdev, ring, 64); 71254885Sdumbbell if (r) { 72254885Sdumbbell return; 73254885Sdumbbell } 74254885Sdumbbell radeon_ring_write(ring, PACKET0(ISYNC_CNTL, 0)); 75254885Sdumbbell radeon_ring_write(ring, 76254885Sdumbbell ISYNC_ANY2D_IDLE3D | 77254885Sdumbbell ISYNC_ANY3D_IDLE2D | 78254885Sdumbbell ISYNC_WAIT_IDLEGUI | 79254885Sdumbbell ISYNC_CPSCRATCH_IDLEGUI); 80254885Sdumbbell radeon_ring_write(ring, PACKET0(WAIT_UNTIL, 0)); 81254885Sdumbbell radeon_ring_write(ring, WAIT_2D_IDLECLEAN | WAIT_3D_IDLECLEAN); 82254885Sdumbbell radeon_ring_write(ring, PACKET0(R300_DST_PIPE_CONFIG, 0)); 83254885Sdumbbell radeon_ring_write(ring, R300_PIPE_AUTO_CONFIG); 84254885Sdumbbell radeon_ring_write(ring, PACKET0(GB_SELECT, 0)); 85254885Sdumbbell radeon_ring_write(ring, 0); 86254885Sdumbbell radeon_ring_write(ring, PACKET0(GB_ENABLE, 0)); 87254885Sdumbbell radeon_ring_write(ring, 0); 88254885Sdumbbell radeon_ring_write(ring, PACKET0(R500_SU_REG_DEST, 0)); 89254885Sdumbbell radeon_ring_write(ring, (1 << rdev->num_gb_pipes) - 1); 90254885Sdumbbell radeon_ring_write(ring, PACKET0(VAP_INDEX_OFFSET, 0)); 91254885Sdumbbell radeon_ring_write(ring, 0); 92254885Sdumbbell radeon_ring_write(ring, PACKET0(RB3D_DSTCACHE_CTLSTAT, 0)); 93254885Sdumbbell radeon_ring_write(ring, RB3D_DC_FLUSH | RB3D_DC_FREE); 94254885Sdumbbell radeon_ring_write(ring, PACKET0(ZB_ZCACHE_CTLSTAT, 0)); 95254885Sdumbbell radeon_ring_write(ring, ZC_FLUSH | ZC_FREE); 96254885Sdumbbell radeon_ring_write(ring, PACKET0(WAIT_UNTIL, 0)); 97254885Sdumbbell radeon_ring_write(ring, WAIT_2D_IDLECLEAN | WAIT_3D_IDLECLEAN); 98254885Sdumbbell radeon_ring_write(ring, PACKET0(GB_AA_CONFIG, 0)); 99254885Sdumbbell radeon_ring_write(ring, 0); 100254885Sdumbbell radeon_ring_write(ring, PACKET0(RB3D_DSTCACHE_CTLSTAT, 0)); 101254885Sdumbbell radeon_ring_write(ring, RB3D_DC_FLUSH | RB3D_DC_FREE); 102254885Sdumbbell radeon_ring_write(ring, PACKET0(ZB_ZCACHE_CTLSTAT, 0)); 103254885Sdumbbell radeon_ring_write(ring, ZC_FLUSH | ZC_FREE); 104254885Sdumbbell radeon_ring_write(ring, PACKET0(GB_MSPOS0, 0)); 105254885Sdumbbell radeon_ring_write(ring, 106254885Sdumbbell ((6 << MS_X0_SHIFT) | 107254885Sdumbbell (6 << MS_Y0_SHIFT) | 108254885Sdumbbell (6 << MS_X1_SHIFT) | 109254885Sdumbbell (6 << MS_Y1_SHIFT) | 110254885Sdumbbell (6 << MS_X2_SHIFT) | 111254885Sdumbbell (6 << MS_Y2_SHIFT) | 112254885Sdumbbell (6 << MSBD0_Y_SHIFT) | 113254885Sdumbbell (6 << MSBD0_X_SHIFT))); 114254885Sdumbbell radeon_ring_write(ring, PACKET0(GB_MSPOS1, 0)); 115254885Sdumbbell radeon_ring_write(ring, 116254885Sdumbbell ((6 << MS_X3_SHIFT) | 117254885Sdumbbell (6 << MS_Y3_SHIFT) | 118254885Sdumbbell (6 << MS_X4_SHIFT) | 119254885Sdumbbell (6 << MS_Y4_SHIFT) | 120254885Sdumbbell (6 << MS_X5_SHIFT) | 121254885Sdumbbell (6 << MS_Y5_SHIFT) | 122254885Sdumbbell (6 << MSBD1_SHIFT))); 123254885Sdumbbell radeon_ring_write(ring, PACKET0(GA_ENHANCE, 0)); 124254885Sdumbbell radeon_ring_write(ring, GA_DEADLOCK_CNTL | GA_FASTSYNC_CNTL); 125254885Sdumbbell radeon_ring_write(ring, PACKET0(GA_POLY_MODE, 0)); 126254885Sdumbbell radeon_ring_write(ring, FRONT_PTYPE_TRIANGE | BACK_PTYPE_TRIANGE); 127254885Sdumbbell radeon_ring_write(ring, PACKET0(GA_ROUND_MODE, 0)); 128254885Sdumbbell radeon_ring_write(ring, GEOMETRY_ROUND_NEAREST | COLOR_ROUND_NEAREST); 129254885Sdumbbell radeon_ring_write(ring, PACKET0(0x20C8, 0)); 130254885Sdumbbell radeon_ring_write(ring, 0); 131254885Sdumbbell radeon_ring_unlock_commit(rdev, ring); 132254885Sdumbbell} 133254885Sdumbbell 134254885Sdumbbellint rv515_mc_wait_for_idle(struct radeon_device *rdev) 135254885Sdumbbell{ 136254885Sdumbbell unsigned i; 137254885Sdumbbell uint32_t tmp; 138254885Sdumbbell 139254885Sdumbbell for (i = 0; i < rdev->usec_timeout; i++) { 140254885Sdumbbell /* read MC_STATUS */ 141254885Sdumbbell tmp = RREG32_MC(MC_STATUS); 142254885Sdumbbell if (tmp & MC_STATUS_IDLE) { 143254885Sdumbbell return 0; 144254885Sdumbbell } 145254885Sdumbbell DRM_UDELAY(1); 146254885Sdumbbell } 147254885Sdumbbell return -1; 148254885Sdumbbell} 149254885Sdumbbell 150254885Sdumbbellvoid rv515_vga_render_disable(struct radeon_device *rdev) 151254885Sdumbbell{ 152254885Sdumbbell WREG32(R_000300_VGA_RENDER_CONTROL, 153254885Sdumbbell RREG32(R_000300_VGA_RENDER_CONTROL) & C_000300_VGA_VSTATUS_CNTL); 154254885Sdumbbell} 155254885Sdumbbell 156254885Sdumbbellstatic void rv515_gpu_init(struct radeon_device *rdev) 157254885Sdumbbell{ 158254885Sdumbbell unsigned pipe_select_current, gb_pipe_select, tmp; 159254885Sdumbbell 160254885Sdumbbell if (r100_gui_wait_for_idle(rdev)) { 161254885Sdumbbell DRM_ERROR("Failed to wait GUI idle while " 162254885Sdumbbell "resetting GPU. Bad things might happen.\n"); 163254885Sdumbbell } 164254885Sdumbbell rv515_vga_render_disable(rdev); 165254885Sdumbbell r420_pipes_init(rdev); 166254885Sdumbbell gb_pipe_select = RREG32(R400_GB_PIPE_SELECT); 167254885Sdumbbell tmp = RREG32(R300_DST_PIPE_CONFIG); 168254885Sdumbbell pipe_select_current = (tmp >> 2) & 3; 169254885Sdumbbell tmp = (1 << pipe_select_current) | 170254885Sdumbbell (((gb_pipe_select >> 8) & 0xF) << 4); 171254885Sdumbbell WREG32_PLL(0x000D, tmp); 172254885Sdumbbell if (r100_gui_wait_for_idle(rdev)) { 173254885Sdumbbell DRM_ERROR("Failed to wait GUI idle while " 174254885Sdumbbell "resetting GPU. Bad things might happen.\n"); 175254885Sdumbbell } 176254885Sdumbbell if (rv515_mc_wait_for_idle(rdev)) { 177254885Sdumbbell DRM_ERROR("Failed to wait MC idle while " 178254885Sdumbbell "programming pipes. Bad things might happen.\n"); 179254885Sdumbbell } 180254885Sdumbbell} 181254885Sdumbbell 182254885Sdumbbellstatic void rv515_vram_get_type(struct radeon_device *rdev) 183254885Sdumbbell{ 184254885Sdumbbell uint32_t tmp; 185254885Sdumbbell 186254885Sdumbbell rdev->mc.vram_width = 128; 187254885Sdumbbell rdev->mc.vram_is_ddr = true; 188254885Sdumbbell tmp = RREG32_MC(RV515_MC_CNTL) & MEM_NUM_CHANNELS_MASK; 189254885Sdumbbell switch (tmp) { 190254885Sdumbbell case 0: 191254885Sdumbbell rdev->mc.vram_width = 64; 192254885Sdumbbell break; 193254885Sdumbbell case 1: 194254885Sdumbbell rdev->mc.vram_width = 128; 195254885Sdumbbell break; 196254885Sdumbbell default: 197254885Sdumbbell rdev->mc.vram_width = 128; 198254885Sdumbbell break; 199254885Sdumbbell } 200254885Sdumbbell} 201254885Sdumbbell 202254885Sdumbbellstatic void rv515_mc_init(struct radeon_device *rdev) 203254885Sdumbbell{ 204254885Sdumbbell 205254885Sdumbbell rv515_vram_get_type(rdev); 206254885Sdumbbell r100_vram_init_sizes(rdev); 207254885Sdumbbell radeon_vram_location(rdev, &rdev->mc, 0); 208254885Sdumbbell rdev->mc.gtt_base_align = 0; 209254885Sdumbbell if (!(rdev->flags & RADEON_IS_AGP)) 210254885Sdumbbell radeon_gtt_location(rdev, &rdev->mc); 211254885Sdumbbell radeon_update_bandwidth_info(rdev); 212254885Sdumbbell} 213254885Sdumbbell 214254885Sdumbbelluint32_t rv515_mc_rreg(struct radeon_device *rdev, uint32_t reg) 215254885Sdumbbell{ 216254885Sdumbbell uint32_t r; 217254885Sdumbbell 218254885Sdumbbell WREG32(MC_IND_INDEX, 0x7f0000 | (reg & 0xffff)); 219254885Sdumbbell r = RREG32(MC_IND_DATA); 220254885Sdumbbell WREG32(MC_IND_INDEX, 0); 221254885Sdumbbell return r; 222254885Sdumbbell} 223254885Sdumbbell 224254885Sdumbbellvoid rv515_mc_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v) 225254885Sdumbbell{ 226254885Sdumbbell WREG32(MC_IND_INDEX, 0xff0000 | ((reg) & 0xffff)); 227254885Sdumbbell WREG32(MC_IND_DATA, (v)); 228254885Sdumbbell WREG32(MC_IND_INDEX, 0); 229254885Sdumbbell} 230254885Sdumbbell 231254885Sdumbbell#if defined(CONFIG_DEBUG_FS) 232254885Sdumbbellstatic int rv515_debugfs_pipes_info(struct seq_file *m, void *data) 233254885Sdumbbell{ 234254885Sdumbbell struct drm_info_node *node = (struct drm_info_node *) m->private; 235254885Sdumbbell struct drm_device *dev = node->minor->dev; 236254885Sdumbbell struct radeon_device *rdev = dev->dev_private; 237254885Sdumbbell uint32_t tmp; 238254885Sdumbbell 239254885Sdumbbell tmp = RREG32(GB_PIPE_SELECT); 240254885Sdumbbell seq_printf(m, "GB_PIPE_SELECT 0x%08x\n", tmp); 241254885Sdumbbell tmp = RREG32(SU_REG_DEST); 242254885Sdumbbell seq_printf(m, "SU_REG_DEST 0x%08x\n", tmp); 243254885Sdumbbell tmp = RREG32(GB_TILE_CONFIG); 244254885Sdumbbell seq_printf(m, "GB_TILE_CONFIG 0x%08x\n", tmp); 245254885Sdumbbell tmp = RREG32(DST_PIPE_CONFIG); 246254885Sdumbbell seq_printf(m, "DST_PIPE_CONFIG 0x%08x\n", tmp); 247254885Sdumbbell return 0; 248254885Sdumbbell} 249254885Sdumbbell 250254885Sdumbbellstatic int rv515_debugfs_ga_info(struct seq_file *m, void *data) 251254885Sdumbbell{ 252254885Sdumbbell struct drm_info_node *node = (struct drm_info_node *) m->private; 253254885Sdumbbell struct drm_device *dev = node->minor->dev; 254254885Sdumbbell struct radeon_device *rdev = dev->dev_private; 255254885Sdumbbell uint32_t tmp; 256254885Sdumbbell 257254885Sdumbbell tmp = RREG32(0x2140); 258254885Sdumbbell seq_printf(m, "VAP_CNTL_STATUS 0x%08x\n", tmp); 259254885Sdumbbell radeon_asic_reset(rdev); 260254885Sdumbbell tmp = RREG32(0x425C); 261254885Sdumbbell seq_printf(m, "GA_IDLE 0x%08x\n", tmp); 262254885Sdumbbell return 0; 263254885Sdumbbell} 264254885Sdumbbell 265254885Sdumbbellstatic struct drm_info_list rv515_pipes_info_list[] = { 266254885Sdumbbell {"rv515_pipes_info", rv515_debugfs_pipes_info, 0, NULL}, 267254885Sdumbbell}; 268254885Sdumbbell 269254885Sdumbbellstatic struct drm_info_list rv515_ga_info_list[] = { 270254885Sdumbbell {"rv515_ga_info", rv515_debugfs_ga_info, 0, NULL}, 271254885Sdumbbell}; 272254885Sdumbbell#endif 273254885Sdumbbell 274254885Sdumbbellstatic int rv515_debugfs_pipes_info_init(struct radeon_device *rdev) 275254885Sdumbbell{ 276254885Sdumbbell#if defined(CONFIG_DEBUG_FS) 277254885Sdumbbell return radeon_debugfs_add_files(rdev, rv515_pipes_info_list, 1); 278254885Sdumbbell#else 279254885Sdumbbell return 0; 280254885Sdumbbell#endif 281254885Sdumbbell} 282254885Sdumbbell 283254885Sdumbbellstatic int rv515_debugfs_ga_info_init(struct radeon_device *rdev) 284254885Sdumbbell{ 285254885Sdumbbell#if defined(CONFIG_DEBUG_FS) 286254885Sdumbbell return radeon_debugfs_add_files(rdev, rv515_ga_info_list, 1); 287254885Sdumbbell#else 288254885Sdumbbell return 0; 289254885Sdumbbell#endif 290254885Sdumbbell} 291254885Sdumbbell 292254885Sdumbbellvoid rv515_mc_stop(struct radeon_device *rdev, struct rv515_mc_save *save) 293254885Sdumbbell{ 294254885Sdumbbell u32 crtc_enabled, tmp, frame_count, blackout; 295254885Sdumbbell int i, j; 296254885Sdumbbell 297254885Sdumbbell save->vga_render_control = RREG32(R_000300_VGA_RENDER_CONTROL); 298254885Sdumbbell save->vga_hdp_control = RREG32(R_000328_VGA_HDP_CONTROL); 299254885Sdumbbell 300254885Sdumbbell /* disable VGA render */ 301254885Sdumbbell WREG32(R_000300_VGA_RENDER_CONTROL, 0); 302254885Sdumbbell /* blank the display controllers */ 303254885Sdumbbell for (i = 0; i < rdev->num_crtc; i++) { 304254885Sdumbbell crtc_enabled = RREG32(AVIVO_D1CRTC_CONTROL + crtc_offsets[i]) & AVIVO_CRTC_EN; 305254885Sdumbbell if (crtc_enabled) { 306254885Sdumbbell save->crtc_enabled[i] = true; 307254885Sdumbbell tmp = RREG32(AVIVO_D1CRTC_CONTROL + crtc_offsets[i]); 308254885Sdumbbell if (!(tmp & AVIVO_CRTC_DISP_READ_REQUEST_DISABLE)) { 309254885Sdumbbell radeon_wait_for_vblank(rdev, i); 310282199Sdumbbell WREG32(AVIVO_D1CRTC_UPDATE_LOCK + crtc_offsets[i], 1); 311254885Sdumbbell tmp |= AVIVO_CRTC_DISP_READ_REQUEST_DISABLE; 312254885Sdumbbell WREG32(AVIVO_D1CRTC_CONTROL + crtc_offsets[i], tmp); 313282199Sdumbbell WREG32(AVIVO_D1CRTC_UPDATE_LOCK + crtc_offsets[i], 0); 314254885Sdumbbell } 315254885Sdumbbell /* wait for the next frame */ 316254885Sdumbbell frame_count = radeon_get_vblank_counter(rdev, i); 317254885Sdumbbell for (j = 0; j < rdev->usec_timeout; j++) { 318254885Sdumbbell if (radeon_get_vblank_counter(rdev, i) != frame_count) 319254885Sdumbbell break; 320282199Sdumbbell udelay(1); 321254885Sdumbbell } 322282199Sdumbbell 323282199Sdumbbell /* XXX this is a hack to avoid strange behavior with EFI on certain systems */ 324282199Sdumbbell WREG32(AVIVO_D1CRTC_UPDATE_LOCK + crtc_offsets[i], 1); 325282199Sdumbbell tmp = RREG32(AVIVO_D1CRTC_CONTROL + crtc_offsets[i]); 326282199Sdumbbell tmp &= ~AVIVO_CRTC_EN; 327282199Sdumbbell WREG32(AVIVO_D1CRTC_CONTROL + crtc_offsets[i], tmp); 328282199Sdumbbell WREG32(AVIVO_D1CRTC_UPDATE_LOCK + crtc_offsets[i], 0); 329282199Sdumbbell save->crtc_enabled[i] = false; 330282199Sdumbbell /* ***** */ 331254885Sdumbbell } else { 332254885Sdumbbell save->crtc_enabled[i] = false; 333254885Sdumbbell } 334254885Sdumbbell } 335254885Sdumbbell 336254885Sdumbbell radeon_mc_wait_for_idle(rdev); 337254885Sdumbbell 338254885Sdumbbell if (rdev->family >= CHIP_R600) { 339254885Sdumbbell if (rdev->family >= CHIP_RV770) 340254885Sdumbbell blackout = RREG32(R700_MC_CITF_CNTL); 341254885Sdumbbell else 342254885Sdumbbell blackout = RREG32(R600_CITF_CNTL); 343254885Sdumbbell if ((blackout & R600_BLACKOUT_MASK) != R600_BLACKOUT_MASK) { 344254885Sdumbbell /* Block CPU access */ 345254885Sdumbbell WREG32(R600_BIF_FB_EN, 0); 346254885Sdumbbell /* blackout the MC */ 347254885Sdumbbell blackout |= R600_BLACKOUT_MASK; 348254885Sdumbbell if (rdev->family >= CHIP_RV770) 349254885Sdumbbell WREG32(R700_MC_CITF_CNTL, blackout); 350254885Sdumbbell else 351254885Sdumbbell WREG32(R600_CITF_CNTL, blackout); 352254885Sdumbbell } 353254885Sdumbbell } 354254885Sdumbbell /* wait for the MC to settle */ 355282199Sdumbbell udelay(100); 356282199Sdumbbell 357282199Sdumbbell /* lock double buffered regs */ 358282199Sdumbbell for (i = 0; i < rdev->num_crtc; i++) { 359282199Sdumbbell if (save->crtc_enabled[i]) { 360282199Sdumbbell tmp = RREG32(AVIVO_D1GRPH_UPDATE + crtc_offsets[i]); 361282199Sdumbbell if (!(tmp & AVIVO_D1GRPH_UPDATE_LOCK)) { 362282199Sdumbbell tmp |= AVIVO_D1GRPH_UPDATE_LOCK; 363282199Sdumbbell WREG32(AVIVO_D1GRPH_UPDATE + crtc_offsets[i], tmp); 364282199Sdumbbell } 365282199Sdumbbell tmp = RREG32(AVIVO_D1MODE_MASTER_UPDATE_LOCK + crtc_offsets[i]); 366282199Sdumbbell if (!(tmp & 1)) { 367282199Sdumbbell tmp |= 1; 368282199Sdumbbell WREG32(AVIVO_D1MODE_MASTER_UPDATE_LOCK + crtc_offsets[i], tmp); 369282199Sdumbbell } 370282199Sdumbbell } 371282199Sdumbbell } 372254885Sdumbbell} 373254885Sdumbbell 374254885Sdumbbellvoid rv515_mc_resume(struct radeon_device *rdev, struct rv515_mc_save *save) 375254885Sdumbbell{ 376254885Sdumbbell u32 tmp, frame_count; 377254885Sdumbbell int i, j; 378254885Sdumbbell 379254885Sdumbbell /* update crtc base addresses */ 380254885Sdumbbell for (i = 0; i < rdev->num_crtc; i++) { 381254885Sdumbbell if (rdev->family >= CHIP_RV770) { 382282199Sdumbbell if (i == 0) { 383254885Sdumbbell WREG32(R700_D1GRPH_PRIMARY_SURFACE_ADDRESS_HIGH, 384254885Sdumbbell upper_32_bits(rdev->mc.vram_start)); 385254885Sdumbbell WREG32(R700_D1GRPH_SECONDARY_SURFACE_ADDRESS_HIGH, 386254885Sdumbbell upper_32_bits(rdev->mc.vram_start)); 387254885Sdumbbell } else { 388254885Sdumbbell WREG32(R700_D2GRPH_PRIMARY_SURFACE_ADDRESS_HIGH, 389254885Sdumbbell upper_32_bits(rdev->mc.vram_start)); 390254885Sdumbbell WREG32(R700_D2GRPH_SECONDARY_SURFACE_ADDRESS_HIGH, 391254885Sdumbbell upper_32_bits(rdev->mc.vram_start)); 392254885Sdumbbell } 393254885Sdumbbell } 394254885Sdumbbell WREG32(R_006110_D1GRPH_PRIMARY_SURFACE_ADDRESS + crtc_offsets[i], 395254885Sdumbbell (u32)rdev->mc.vram_start); 396254885Sdumbbell WREG32(R_006118_D1GRPH_SECONDARY_SURFACE_ADDRESS + crtc_offsets[i], 397254885Sdumbbell (u32)rdev->mc.vram_start); 398254885Sdumbbell } 399254885Sdumbbell WREG32(R_000310_VGA_MEMORY_BASE_ADDRESS, (u32)rdev->mc.vram_start); 400254885Sdumbbell 401282199Sdumbbell /* unlock regs and wait for update */ 402282199Sdumbbell for (i = 0; i < rdev->num_crtc; i++) { 403282199Sdumbbell if (save->crtc_enabled[i]) { 404282199Sdumbbell tmp = RREG32(AVIVO_D1MODE_MASTER_UPDATE_MODE + crtc_offsets[i]); 405282199Sdumbbell if ((tmp & 0x3) != 0) { 406282199Sdumbbell tmp &= ~0x3; 407282199Sdumbbell WREG32(AVIVO_D1MODE_MASTER_UPDATE_MODE + crtc_offsets[i], tmp); 408282199Sdumbbell } 409282199Sdumbbell tmp = RREG32(AVIVO_D1GRPH_UPDATE + crtc_offsets[i]); 410282199Sdumbbell if (tmp & AVIVO_D1GRPH_UPDATE_LOCK) { 411282199Sdumbbell tmp &= ~AVIVO_D1GRPH_UPDATE_LOCK; 412282199Sdumbbell WREG32(AVIVO_D1GRPH_UPDATE + crtc_offsets[i], tmp); 413282199Sdumbbell } 414282199Sdumbbell tmp = RREG32(AVIVO_D1MODE_MASTER_UPDATE_LOCK + crtc_offsets[i]); 415282199Sdumbbell if (tmp & 1) { 416282199Sdumbbell tmp &= ~1; 417282199Sdumbbell WREG32(AVIVO_D1MODE_MASTER_UPDATE_LOCK + crtc_offsets[i], tmp); 418282199Sdumbbell } 419282199Sdumbbell for (j = 0; j < rdev->usec_timeout; j++) { 420282199Sdumbbell tmp = RREG32(AVIVO_D1GRPH_UPDATE + crtc_offsets[i]); 421282199Sdumbbell if ((tmp & AVIVO_D1GRPH_SURFACE_UPDATE_PENDING) == 0) 422282199Sdumbbell break; 423282199Sdumbbell udelay(1); 424282199Sdumbbell } 425282199Sdumbbell } 426282199Sdumbbell } 427282199Sdumbbell 428254885Sdumbbell if (rdev->family >= CHIP_R600) { 429254885Sdumbbell /* unblackout the MC */ 430254885Sdumbbell if (rdev->family >= CHIP_RV770) 431254885Sdumbbell tmp = RREG32(R700_MC_CITF_CNTL); 432254885Sdumbbell else 433254885Sdumbbell tmp = RREG32(R600_CITF_CNTL); 434254885Sdumbbell tmp &= ~R600_BLACKOUT_MASK; 435254885Sdumbbell if (rdev->family >= CHIP_RV770) 436254885Sdumbbell WREG32(R700_MC_CITF_CNTL, tmp); 437254885Sdumbbell else 438254885Sdumbbell WREG32(R600_CITF_CNTL, tmp); 439254885Sdumbbell /* allow CPU access */ 440254885Sdumbbell WREG32(R600_BIF_FB_EN, R600_FB_READ_EN | R600_FB_WRITE_EN); 441254885Sdumbbell } 442254885Sdumbbell 443254885Sdumbbell for (i = 0; i < rdev->num_crtc; i++) { 444254885Sdumbbell if (save->crtc_enabled[i]) { 445254885Sdumbbell tmp = RREG32(AVIVO_D1CRTC_CONTROL + crtc_offsets[i]); 446254885Sdumbbell tmp &= ~AVIVO_CRTC_DISP_READ_REQUEST_DISABLE; 447254885Sdumbbell WREG32(AVIVO_D1CRTC_CONTROL + crtc_offsets[i], tmp); 448254885Sdumbbell /* wait for the next frame */ 449254885Sdumbbell frame_count = radeon_get_vblank_counter(rdev, i); 450254885Sdumbbell for (j = 0; j < rdev->usec_timeout; j++) { 451254885Sdumbbell if (radeon_get_vblank_counter(rdev, i) != frame_count) 452254885Sdumbbell break; 453282199Sdumbbell udelay(1); 454254885Sdumbbell } 455254885Sdumbbell } 456254885Sdumbbell } 457254885Sdumbbell /* Unlock vga access */ 458254885Sdumbbell WREG32(R_000328_VGA_HDP_CONTROL, save->vga_hdp_control); 459282199Sdumbbell mdelay(1); 460254885Sdumbbell WREG32(R_000300_VGA_RENDER_CONTROL, save->vga_render_control); 461254885Sdumbbell} 462254885Sdumbbell 463254885Sdumbbellstatic void rv515_mc_program(struct radeon_device *rdev) 464254885Sdumbbell{ 465254885Sdumbbell struct rv515_mc_save save; 466254885Sdumbbell 467254885Sdumbbell /* Stops all mc clients */ 468254885Sdumbbell rv515_mc_stop(rdev, &save); 469254885Sdumbbell 470254885Sdumbbell /* Wait for mc idle */ 471254885Sdumbbell if (rv515_mc_wait_for_idle(rdev)) 472254885Sdumbbell dev_warn(rdev->dev, "Wait MC idle timeout before updating MC.\n"); 473254885Sdumbbell /* Write VRAM size in case we are limiting it */ 474254885Sdumbbell WREG32(R_0000F8_CONFIG_MEMSIZE, rdev->mc.real_vram_size); 475254885Sdumbbell /* Program MC, should be a 32bits limited address space */ 476254885Sdumbbell WREG32_MC(R_000001_MC_FB_LOCATION, 477254885Sdumbbell S_000001_MC_FB_START(rdev->mc.vram_start >> 16) | 478254885Sdumbbell S_000001_MC_FB_TOP(rdev->mc.vram_end >> 16)); 479254885Sdumbbell WREG32(R_000134_HDP_FB_LOCATION, 480254885Sdumbbell S_000134_HDP_FB_START(rdev->mc.vram_start >> 16)); 481254885Sdumbbell if (rdev->flags & RADEON_IS_AGP) { 482254885Sdumbbell WREG32_MC(R_000002_MC_AGP_LOCATION, 483254885Sdumbbell S_000002_MC_AGP_START(rdev->mc.gtt_start >> 16) | 484254885Sdumbbell S_000002_MC_AGP_TOP(rdev->mc.gtt_end >> 16)); 485254885Sdumbbell WREG32_MC(R_000003_MC_AGP_BASE, lower_32_bits(rdev->mc.agp_base)); 486254885Sdumbbell WREG32_MC(R_000004_MC_AGP_BASE_2, 487254885Sdumbbell S_000004_AGP_BASE_ADDR_2(upper_32_bits(rdev->mc.agp_base))); 488254885Sdumbbell } else { 489254885Sdumbbell WREG32_MC(R_000002_MC_AGP_LOCATION, 0xFFFFFFFF); 490254885Sdumbbell WREG32_MC(R_000003_MC_AGP_BASE, 0); 491254885Sdumbbell WREG32_MC(R_000004_MC_AGP_BASE_2, 0); 492254885Sdumbbell } 493254885Sdumbbell 494254885Sdumbbell rv515_mc_resume(rdev, &save); 495254885Sdumbbell} 496254885Sdumbbell 497254885Sdumbbellvoid rv515_clock_startup(struct radeon_device *rdev) 498254885Sdumbbell{ 499254885Sdumbbell if (radeon_dynclks != -1 && radeon_dynclks) 500254885Sdumbbell radeon_atom_set_clock_gating(rdev, 1); 501254885Sdumbbell /* We need to force on some of the block */ 502254885Sdumbbell WREG32_PLL(R_00000F_CP_DYN_CNTL, 503254885Sdumbbell RREG32_PLL(R_00000F_CP_DYN_CNTL) | S_00000F_CP_FORCEON(1)); 504254885Sdumbbell WREG32_PLL(R_000011_E2_DYN_CNTL, 505254885Sdumbbell RREG32_PLL(R_000011_E2_DYN_CNTL) | S_000011_E2_FORCEON(1)); 506254885Sdumbbell WREG32_PLL(R_000013_IDCT_DYN_CNTL, 507254885Sdumbbell RREG32_PLL(R_000013_IDCT_DYN_CNTL) | S_000013_IDCT_FORCEON(1)); 508254885Sdumbbell} 509254885Sdumbbell 510254885Sdumbbellstatic int rv515_startup(struct radeon_device *rdev) 511254885Sdumbbell{ 512254885Sdumbbell int r; 513254885Sdumbbell 514254885Sdumbbell rv515_mc_program(rdev); 515254885Sdumbbell /* Resume clock */ 516254885Sdumbbell rv515_clock_startup(rdev); 517254885Sdumbbell /* Initialize GPU configuration (# pipes, ...) */ 518254885Sdumbbell rv515_gpu_init(rdev); 519254885Sdumbbell /* Initialize GART (initialize after TTM so we can allocate 520254885Sdumbbell * memory through TTM but finalize after TTM) */ 521254885Sdumbbell if (rdev->flags & RADEON_IS_PCIE) { 522254885Sdumbbell r = rv370_pcie_gart_enable(rdev); 523254885Sdumbbell if (r) 524254885Sdumbbell return r; 525254885Sdumbbell } 526254885Sdumbbell 527254885Sdumbbell /* allocate wb buffer */ 528254885Sdumbbell r = radeon_wb_init(rdev); 529254885Sdumbbell if (r) 530254885Sdumbbell return r; 531254885Sdumbbell 532254885Sdumbbell r = radeon_fence_driver_start_ring(rdev, RADEON_RING_TYPE_GFX_INDEX); 533254885Sdumbbell if (r) { 534254885Sdumbbell dev_err(rdev->dev, "failed initializing CP fences (%d).\n", r); 535254885Sdumbbell return r; 536254885Sdumbbell } 537254885Sdumbbell 538254885Sdumbbell /* Enable IRQ */ 539254885Sdumbbell rs600_irq_set(rdev); 540254885Sdumbbell rdev->config.r300.hdp_cntl = RREG32(RADEON_HOST_PATH_CNTL); 541254885Sdumbbell /* 1M ring buffer */ 542254885Sdumbbell r = r100_cp_init(rdev, 1024 * 1024); 543254885Sdumbbell if (r) { 544254885Sdumbbell dev_err(rdev->dev, "failed initializing CP (%d).\n", r); 545254885Sdumbbell return r; 546254885Sdumbbell } 547254885Sdumbbell 548254885Sdumbbell r = radeon_ib_pool_init(rdev); 549254885Sdumbbell if (r) { 550254885Sdumbbell dev_err(rdev->dev, "IB initialization failed (%d).\n", r); 551254885Sdumbbell return r; 552254885Sdumbbell } 553254885Sdumbbell 554254885Sdumbbell return 0; 555254885Sdumbbell} 556254885Sdumbbell 557254885Sdumbbellint rv515_resume(struct radeon_device *rdev) 558254885Sdumbbell{ 559254885Sdumbbell int r; 560254885Sdumbbell 561254885Sdumbbell /* Make sur GART are not working */ 562254885Sdumbbell if (rdev->flags & RADEON_IS_PCIE) 563254885Sdumbbell rv370_pcie_gart_disable(rdev); 564254885Sdumbbell /* Resume clock before doing reset */ 565254885Sdumbbell rv515_clock_startup(rdev); 566254885Sdumbbell /* Reset gpu before posting otherwise ATOM will enter infinite loop */ 567254885Sdumbbell if (radeon_asic_reset(rdev)) { 568254885Sdumbbell dev_warn(rdev->dev, "GPU reset failed ! (0xE40=0x%08X, 0x7C0=0x%08X)\n", 569254885Sdumbbell RREG32(R_000E40_RBBM_STATUS), 570254885Sdumbbell RREG32(R_0007C0_CP_STAT)); 571254885Sdumbbell } 572254885Sdumbbell /* post */ 573254885Sdumbbell atom_asic_init(rdev->mode_info.atom_context); 574254885Sdumbbell /* Resume clock after posting */ 575254885Sdumbbell rv515_clock_startup(rdev); 576254885Sdumbbell /* Initialize surface registers */ 577254885Sdumbbell radeon_surface_init(rdev); 578254885Sdumbbell 579254885Sdumbbell rdev->accel_working = true; 580254885Sdumbbell r = rv515_startup(rdev); 581254885Sdumbbell if (r) { 582254885Sdumbbell rdev->accel_working = false; 583254885Sdumbbell } 584254885Sdumbbell return r; 585254885Sdumbbell} 586254885Sdumbbell 587254885Sdumbbellint rv515_suspend(struct radeon_device *rdev) 588254885Sdumbbell{ 589254885Sdumbbell r100_cp_disable(rdev); 590254885Sdumbbell radeon_wb_disable(rdev); 591254885Sdumbbell rs600_irq_disable(rdev); 592254885Sdumbbell if (rdev->flags & RADEON_IS_PCIE) 593254885Sdumbbell rv370_pcie_gart_disable(rdev); 594254885Sdumbbell return 0; 595254885Sdumbbell} 596254885Sdumbbell 597254885Sdumbbellvoid rv515_set_safe_registers(struct radeon_device *rdev) 598254885Sdumbbell{ 599254885Sdumbbell rdev->config.r300.reg_safe_bm = rv515_reg_safe_bm; 600282199Sdumbbell rdev->config.r300.reg_safe_bm_size = ARRAY_SIZE(rv515_reg_safe_bm); 601254885Sdumbbell} 602254885Sdumbbell 603254885Sdumbbellvoid rv515_fini(struct radeon_device *rdev) 604254885Sdumbbell{ 605254885Sdumbbell r100_cp_fini(rdev); 606254885Sdumbbell radeon_wb_fini(rdev); 607254885Sdumbbell radeon_ib_pool_fini(rdev); 608254885Sdumbbell radeon_gem_fini(rdev); 609254885Sdumbbell rv370_pcie_gart_fini(rdev); 610254885Sdumbbell radeon_agp_fini(rdev); 611254885Sdumbbell radeon_irq_kms_fini(rdev); 612254885Sdumbbell radeon_fence_driver_fini(rdev); 613254885Sdumbbell radeon_bo_fini(rdev); 614254885Sdumbbell radeon_atombios_fini(rdev); 615254885Sdumbbell free(rdev->bios, DRM_MEM_DRIVER); 616254885Sdumbbell rdev->bios = NULL; 617254885Sdumbbell} 618254885Sdumbbell 619254885Sdumbbellint rv515_init(struct radeon_device *rdev) 620254885Sdumbbell{ 621254885Sdumbbell int r; 622254885Sdumbbell 623254885Sdumbbell /* Initialize scratch registers */ 624254885Sdumbbell radeon_scratch_init(rdev); 625254885Sdumbbell /* Initialize surface registers */ 626254885Sdumbbell radeon_surface_init(rdev); 627254885Sdumbbell /* TODO: disable VGA need to use VGA request */ 628254885Sdumbbell /* restore some register to sane defaults */ 629254885Sdumbbell r100_restore_sanity(rdev); 630254885Sdumbbell /* BIOS*/ 631254885Sdumbbell if (!radeon_get_bios(rdev)) { 632254885Sdumbbell if (ASIC_IS_AVIVO(rdev)) 633254885Sdumbbell return -EINVAL; 634254885Sdumbbell } 635254885Sdumbbell if (rdev->is_atom_bios) { 636254885Sdumbbell r = radeon_atombios_init(rdev); 637254885Sdumbbell if (r) 638254885Sdumbbell return r; 639254885Sdumbbell } else { 640254885Sdumbbell dev_err(rdev->dev, "Expecting atombios for RV515 GPU\n"); 641254885Sdumbbell return -EINVAL; 642254885Sdumbbell } 643254885Sdumbbell /* Reset gpu before posting otherwise ATOM will enter infinite loop */ 644254885Sdumbbell if (radeon_asic_reset(rdev)) { 645254885Sdumbbell dev_warn(rdev->dev, 646254885Sdumbbell "GPU reset failed ! (0xE40=0x%08X, 0x7C0=0x%08X)\n", 647254885Sdumbbell RREG32(R_000E40_RBBM_STATUS), 648254885Sdumbbell RREG32(R_0007C0_CP_STAT)); 649254885Sdumbbell } 650254885Sdumbbell /* check if cards are posted or not */ 651254885Sdumbbell if (radeon_boot_test_post_card(rdev) == false) 652254885Sdumbbell return -EINVAL; 653254885Sdumbbell /* Initialize clocks */ 654254885Sdumbbell radeon_get_clock_info(rdev->ddev); 655254885Sdumbbell /* initialize AGP */ 656254885Sdumbbell if (rdev->flags & RADEON_IS_AGP) { 657254885Sdumbbell r = radeon_agp_init(rdev); 658254885Sdumbbell if (r) { 659254885Sdumbbell radeon_agp_disable(rdev); 660254885Sdumbbell } 661254885Sdumbbell } 662254885Sdumbbell /* initialize memory controller */ 663254885Sdumbbell rv515_mc_init(rdev); 664254885Sdumbbell rv515_debugfs(rdev); 665254885Sdumbbell /* Fence driver */ 666254885Sdumbbell r = radeon_fence_driver_init(rdev); 667254885Sdumbbell if (r) 668254885Sdumbbell return r; 669254885Sdumbbell r = radeon_irq_kms_init(rdev); 670254885Sdumbbell if (r) 671254885Sdumbbell return r; 672254885Sdumbbell /* Memory manager */ 673254885Sdumbbell r = radeon_bo_init(rdev); 674254885Sdumbbell if (r) 675254885Sdumbbell return r; 676254885Sdumbbell r = rv370_pcie_gart_init(rdev); 677254885Sdumbbell if (r) 678254885Sdumbbell return r; 679254885Sdumbbell rv515_set_safe_registers(rdev); 680254885Sdumbbell 681254885Sdumbbell rdev->accel_working = true; 682254885Sdumbbell r = rv515_startup(rdev); 683254885Sdumbbell if (r) { 684254885Sdumbbell /* Somethings want wront with the accel init stop accel */ 685254885Sdumbbell dev_err(rdev->dev, "Disabling GPU acceleration\n"); 686254885Sdumbbell r100_cp_fini(rdev); 687254885Sdumbbell radeon_wb_fini(rdev); 688254885Sdumbbell radeon_ib_pool_fini(rdev); 689254885Sdumbbell radeon_irq_kms_fini(rdev); 690254885Sdumbbell rv370_pcie_gart_fini(rdev); 691254885Sdumbbell radeon_agp_fini(rdev); 692254885Sdumbbell rdev->accel_working = false; 693254885Sdumbbell } 694254885Sdumbbell return 0; 695254885Sdumbbell} 696254885Sdumbbell 697254885Sdumbbellvoid atom_rv515_force_tv_scaler(struct radeon_device *rdev, struct radeon_crtc *crtc) 698254885Sdumbbell{ 699254885Sdumbbell int index_reg = 0x6578 + crtc->crtc_offset; 700254885Sdumbbell int data_reg = 0x657c + crtc->crtc_offset; 701254885Sdumbbell 702254885Sdumbbell WREG32(0x659C + crtc->crtc_offset, 0x0); 703254885Sdumbbell WREG32(0x6594 + crtc->crtc_offset, 0x705); 704254885Sdumbbell WREG32(0x65A4 + crtc->crtc_offset, 0x10001); 705254885Sdumbbell WREG32(0x65D8 + crtc->crtc_offset, 0x0); 706254885Sdumbbell WREG32(0x65B0 + crtc->crtc_offset, 0x0); 707254885Sdumbbell WREG32(0x65C0 + crtc->crtc_offset, 0x0); 708254885Sdumbbell WREG32(0x65D4 + crtc->crtc_offset, 0x0); 709254885Sdumbbell WREG32(index_reg, 0x0); 710254885Sdumbbell WREG32(data_reg, 0x841880A8); 711254885Sdumbbell WREG32(index_reg, 0x1); 712254885Sdumbbell WREG32(data_reg, 0x84208680); 713254885Sdumbbell WREG32(index_reg, 0x2); 714254885Sdumbbell WREG32(data_reg, 0xBFF880B0); 715254885Sdumbbell WREG32(index_reg, 0x100); 716254885Sdumbbell WREG32(data_reg, 0x83D88088); 717254885Sdumbbell WREG32(index_reg, 0x101); 718254885Sdumbbell WREG32(data_reg, 0x84608680); 719254885Sdumbbell WREG32(index_reg, 0x102); 720254885Sdumbbell WREG32(data_reg, 0xBFF080D0); 721254885Sdumbbell WREG32(index_reg, 0x200); 722254885Sdumbbell WREG32(data_reg, 0x83988068); 723254885Sdumbbell WREG32(index_reg, 0x201); 724254885Sdumbbell WREG32(data_reg, 0x84A08680); 725254885Sdumbbell WREG32(index_reg, 0x202); 726254885Sdumbbell WREG32(data_reg, 0xBFF080F8); 727254885Sdumbbell WREG32(index_reg, 0x300); 728254885Sdumbbell WREG32(data_reg, 0x83588058); 729254885Sdumbbell WREG32(index_reg, 0x301); 730254885Sdumbbell WREG32(data_reg, 0x84E08660); 731254885Sdumbbell WREG32(index_reg, 0x302); 732254885Sdumbbell WREG32(data_reg, 0xBFF88120); 733254885Sdumbbell WREG32(index_reg, 0x400); 734254885Sdumbbell WREG32(data_reg, 0x83188040); 735254885Sdumbbell WREG32(index_reg, 0x401); 736254885Sdumbbell WREG32(data_reg, 0x85008660); 737254885Sdumbbell WREG32(index_reg, 0x402); 738254885Sdumbbell WREG32(data_reg, 0xBFF88150); 739254885Sdumbbell WREG32(index_reg, 0x500); 740254885Sdumbbell WREG32(data_reg, 0x82D88030); 741254885Sdumbbell WREG32(index_reg, 0x501); 742254885Sdumbbell WREG32(data_reg, 0x85408640); 743254885Sdumbbell WREG32(index_reg, 0x502); 744254885Sdumbbell WREG32(data_reg, 0xBFF88180); 745254885Sdumbbell WREG32(index_reg, 0x600); 746254885Sdumbbell WREG32(data_reg, 0x82A08018); 747254885Sdumbbell WREG32(index_reg, 0x601); 748254885Sdumbbell WREG32(data_reg, 0x85808620); 749254885Sdumbbell WREG32(index_reg, 0x602); 750254885Sdumbbell WREG32(data_reg, 0xBFF081B8); 751254885Sdumbbell WREG32(index_reg, 0x700); 752254885Sdumbbell WREG32(data_reg, 0x82608010); 753254885Sdumbbell WREG32(index_reg, 0x701); 754254885Sdumbbell WREG32(data_reg, 0x85A08600); 755254885Sdumbbell WREG32(index_reg, 0x702); 756254885Sdumbbell WREG32(data_reg, 0x800081F0); 757254885Sdumbbell WREG32(index_reg, 0x800); 758254885Sdumbbell WREG32(data_reg, 0x8228BFF8); 759254885Sdumbbell WREG32(index_reg, 0x801); 760254885Sdumbbell WREG32(data_reg, 0x85E085E0); 761254885Sdumbbell WREG32(index_reg, 0x802); 762254885Sdumbbell WREG32(data_reg, 0xBFF88228); 763254885Sdumbbell WREG32(index_reg, 0x10000); 764254885Sdumbbell WREG32(data_reg, 0x82A8BF00); 765254885Sdumbbell WREG32(index_reg, 0x10001); 766254885Sdumbbell WREG32(data_reg, 0x82A08CC0); 767254885Sdumbbell WREG32(index_reg, 0x10002); 768254885Sdumbbell WREG32(data_reg, 0x8008BEF8); 769254885Sdumbbell WREG32(index_reg, 0x10100); 770254885Sdumbbell WREG32(data_reg, 0x81F0BF28); 771254885Sdumbbell WREG32(index_reg, 0x10101); 772254885Sdumbbell WREG32(data_reg, 0x83608CA0); 773254885Sdumbbell WREG32(index_reg, 0x10102); 774254885Sdumbbell WREG32(data_reg, 0x8018BED0); 775254885Sdumbbell WREG32(index_reg, 0x10200); 776254885Sdumbbell WREG32(data_reg, 0x8148BF38); 777254885Sdumbbell WREG32(index_reg, 0x10201); 778254885Sdumbbell WREG32(data_reg, 0x84408C80); 779254885Sdumbbell WREG32(index_reg, 0x10202); 780254885Sdumbbell WREG32(data_reg, 0x8008BEB8); 781254885Sdumbbell WREG32(index_reg, 0x10300); 782254885Sdumbbell WREG32(data_reg, 0x80B0BF78); 783254885Sdumbbell WREG32(index_reg, 0x10301); 784254885Sdumbbell WREG32(data_reg, 0x85008C20); 785254885Sdumbbell WREG32(index_reg, 0x10302); 786254885Sdumbbell WREG32(data_reg, 0x8020BEA0); 787254885Sdumbbell WREG32(index_reg, 0x10400); 788254885Sdumbbell WREG32(data_reg, 0x8028BF90); 789254885Sdumbbell WREG32(index_reg, 0x10401); 790254885Sdumbbell WREG32(data_reg, 0x85E08BC0); 791254885Sdumbbell WREG32(index_reg, 0x10402); 792254885Sdumbbell WREG32(data_reg, 0x8018BE90); 793254885Sdumbbell WREG32(index_reg, 0x10500); 794254885Sdumbbell WREG32(data_reg, 0xBFB8BFB0); 795254885Sdumbbell WREG32(index_reg, 0x10501); 796254885Sdumbbell WREG32(data_reg, 0x86C08B40); 797254885Sdumbbell WREG32(index_reg, 0x10502); 798254885Sdumbbell WREG32(data_reg, 0x8010BE90); 799254885Sdumbbell WREG32(index_reg, 0x10600); 800254885Sdumbbell WREG32(data_reg, 0xBF58BFC8); 801254885Sdumbbell WREG32(index_reg, 0x10601); 802254885Sdumbbell WREG32(data_reg, 0x87A08AA0); 803254885Sdumbbell WREG32(index_reg, 0x10602); 804254885Sdumbbell WREG32(data_reg, 0x8010BE98); 805254885Sdumbbell WREG32(index_reg, 0x10700); 806254885Sdumbbell WREG32(data_reg, 0xBF10BFF0); 807254885Sdumbbell WREG32(index_reg, 0x10701); 808254885Sdumbbell WREG32(data_reg, 0x886089E0); 809254885Sdumbbell WREG32(index_reg, 0x10702); 810254885Sdumbbell WREG32(data_reg, 0x8018BEB0); 811254885Sdumbbell WREG32(index_reg, 0x10800); 812254885Sdumbbell WREG32(data_reg, 0xBED8BFE8); 813254885Sdumbbell WREG32(index_reg, 0x10801); 814254885Sdumbbell WREG32(data_reg, 0x89408940); 815254885Sdumbbell WREG32(index_reg, 0x10802); 816254885Sdumbbell WREG32(data_reg, 0xBFE8BED8); 817254885Sdumbbell WREG32(index_reg, 0x20000); 818254885Sdumbbell WREG32(data_reg, 0x80008000); 819254885Sdumbbell WREG32(index_reg, 0x20001); 820254885Sdumbbell WREG32(data_reg, 0x90008000); 821254885Sdumbbell WREG32(index_reg, 0x20002); 822254885Sdumbbell WREG32(data_reg, 0x80008000); 823254885Sdumbbell WREG32(index_reg, 0x20003); 824254885Sdumbbell WREG32(data_reg, 0x80008000); 825254885Sdumbbell WREG32(index_reg, 0x20100); 826254885Sdumbbell WREG32(data_reg, 0x80108000); 827254885Sdumbbell WREG32(index_reg, 0x20101); 828254885Sdumbbell WREG32(data_reg, 0x8FE0BF70); 829254885Sdumbbell WREG32(index_reg, 0x20102); 830254885Sdumbbell WREG32(data_reg, 0xBFE880C0); 831254885Sdumbbell WREG32(index_reg, 0x20103); 832254885Sdumbbell WREG32(data_reg, 0x80008000); 833254885Sdumbbell WREG32(index_reg, 0x20200); 834254885Sdumbbell WREG32(data_reg, 0x8018BFF8); 835254885Sdumbbell WREG32(index_reg, 0x20201); 836254885Sdumbbell WREG32(data_reg, 0x8F80BF08); 837254885Sdumbbell WREG32(index_reg, 0x20202); 838254885Sdumbbell WREG32(data_reg, 0xBFD081A0); 839254885Sdumbbell WREG32(index_reg, 0x20203); 840254885Sdumbbell WREG32(data_reg, 0xBFF88000); 841254885Sdumbbell WREG32(index_reg, 0x20300); 842254885Sdumbbell WREG32(data_reg, 0x80188000); 843254885Sdumbbell WREG32(index_reg, 0x20301); 844254885Sdumbbell WREG32(data_reg, 0x8EE0BEC0); 845254885Sdumbbell WREG32(index_reg, 0x20302); 846254885Sdumbbell WREG32(data_reg, 0xBFB082A0); 847254885Sdumbbell WREG32(index_reg, 0x20303); 848254885Sdumbbell WREG32(data_reg, 0x80008000); 849254885Sdumbbell WREG32(index_reg, 0x20400); 850254885Sdumbbell WREG32(data_reg, 0x80188000); 851254885Sdumbbell WREG32(index_reg, 0x20401); 852254885Sdumbbell WREG32(data_reg, 0x8E00BEA0); 853254885Sdumbbell WREG32(index_reg, 0x20402); 854254885Sdumbbell WREG32(data_reg, 0xBF8883C0); 855254885Sdumbbell WREG32(index_reg, 0x20403); 856254885Sdumbbell WREG32(data_reg, 0x80008000); 857254885Sdumbbell WREG32(index_reg, 0x20500); 858254885Sdumbbell WREG32(data_reg, 0x80188000); 859254885Sdumbbell WREG32(index_reg, 0x20501); 860254885Sdumbbell WREG32(data_reg, 0x8D00BE90); 861254885Sdumbbell WREG32(index_reg, 0x20502); 862254885Sdumbbell WREG32(data_reg, 0xBF588500); 863254885Sdumbbell WREG32(index_reg, 0x20503); 864254885Sdumbbell WREG32(data_reg, 0x80008008); 865254885Sdumbbell WREG32(index_reg, 0x20600); 866254885Sdumbbell WREG32(data_reg, 0x80188000); 867254885Sdumbbell WREG32(index_reg, 0x20601); 868254885Sdumbbell WREG32(data_reg, 0x8BC0BE98); 869254885Sdumbbell WREG32(index_reg, 0x20602); 870254885Sdumbbell WREG32(data_reg, 0xBF308660); 871254885Sdumbbell WREG32(index_reg, 0x20603); 872254885Sdumbbell WREG32(data_reg, 0x80008008); 873254885Sdumbbell WREG32(index_reg, 0x20700); 874254885Sdumbbell WREG32(data_reg, 0x80108000); 875254885Sdumbbell WREG32(index_reg, 0x20701); 876254885Sdumbbell WREG32(data_reg, 0x8A80BEB0); 877254885Sdumbbell WREG32(index_reg, 0x20702); 878254885Sdumbbell WREG32(data_reg, 0xBF0087C0); 879254885Sdumbbell WREG32(index_reg, 0x20703); 880254885Sdumbbell WREG32(data_reg, 0x80008008); 881254885Sdumbbell WREG32(index_reg, 0x20800); 882254885Sdumbbell WREG32(data_reg, 0x80108000); 883254885Sdumbbell WREG32(index_reg, 0x20801); 884254885Sdumbbell WREG32(data_reg, 0x8920BED0); 885254885Sdumbbell WREG32(index_reg, 0x20802); 886254885Sdumbbell WREG32(data_reg, 0xBED08920); 887254885Sdumbbell WREG32(index_reg, 0x20803); 888254885Sdumbbell WREG32(data_reg, 0x80008010); 889254885Sdumbbell WREG32(index_reg, 0x30000); 890254885Sdumbbell WREG32(data_reg, 0x90008000); 891254885Sdumbbell WREG32(index_reg, 0x30001); 892254885Sdumbbell WREG32(data_reg, 0x80008000); 893254885Sdumbbell WREG32(index_reg, 0x30100); 894254885Sdumbbell WREG32(data_reg, 0x8FE0BF90); 895254885Sdumbbell WREG32(index_reg, 0x30101); 896254885Sdumbbell WREG32(data_reg, 0xBFF880A0); 897254885Sdumbbell WREG32(index_reg, 0x30200); 898254885Sdumbbell WREG32(data_reg, 0x8F60BF40); 899254885Sdumbbell WREG32(index_reg, 0x30201); 900254885Sdumbbell WREG32(data_reg, 0xBFE88180); 901254885Sdumbbell WREG32(index_reg, 0x30300); 902254885Sdumbbell WREG32(data_reg, 0x8EC0BF00); 903254885Sdumbbell WREG32(index_reg, 0x30301); 904254885Sdumbbell WREG32(data_reg, 0xBFC88280); 905254885Sdumbbell WREG32(index_reg, 0x30400); 906254885Sdumbbell WREG32(data_reg, 0x8DE0BEE0); 907254885Sdumbbell WREG32(index_reg, 0x30401); 908254885Sdumbbell WREG32(data_reg, 0xBFA083A0); 909254885Sdumbbell WREG32(index_reg, 0x30500); 910254885Sdumbbell WREG32(data_reg, 0x8CE0BED0); 911254885Sdumbbell WREG32(index_reg, 0x30501); 912254885Sdumbbell WREG32(data_reg, 0xBF7884E0); 913254885Sdumbbell WREG32(index_reg, 0x30600); 914254885Sdumbbell WREG32(data_reg, 0x8BA0BED8); 915254885Sdumbbell WREG32(index_reg, 0x30601); 916254885Sdumbbell WREG32(data_reg, 0xBF508640); 917254885Sdumbbell WREG32(index_reg, 0x30700); 918254885Sdumbbell WREG32(data_reg, 0x8A60BEE8); 919254885Sdumbbell WREG32(index_reg, 0x30701); 920254885Sdumbbell WREG32(data_reg, 0xBF2087A0); 921254885Sdumbbell WREG32(index_reg, 0x30800); 922254885Sdumbbell WREG32(data_reg, 0x8900BF00); 923254885Sdumbbell WREG32(index_reg, 0x30801); 924254885Sdumbbell WREG32(data_reg, 0xBF008900); 925254885Sdumbbell} 926254885Sdumbbell 927254885Sdumbbellstruct rv515_watermark { 928254885Sdumbbell u32 lb_request_fifo_depth; 929254885Sdumbbell fixed20_12 num_line_pair; 930254885Sdumbbell fixed20_12 estimated_width; 931254885Sdumbbell fixed20_12 worst_case_latency; 932254885Sdumbbell fixed20_12 consumption_rate; 933254885Sdumbbell fixed20_12 active_time; 934254885Sdumbbell fixed20_12 dbpp; 935254885Sdumbbell fixed20_12 priority_mark_max; 936254885Sdumbbell fixed20_12 priority_mark; 937254885Sdumbbell fixed20_12 sclk; 938254885Sdumbbell}; 939254885Sdumbbell 940254885Sdumbbellstatic void rv515_crtc_bandwidth_compute(struct radeon_device *rdev, 941254885Sdumbbell struct radeon_crtc *crtc, 942254885Sdumbbell struct rv515_watermark *wm) 943254885Sdumbbell{ 944254885Sdumbbell struct drm_display_mode *mode = &crtc->base.mode; 945254885Sdumbbell fixed20_12 a, b, c; 946254885Sdumbbell fixed20_12 pclk, request_fifo_depth, tolerable_latency, estimated_width; 947254885Sdumbbell fixed20_12 consumption_time, line_time, chunk_time, read_delay_latency; 948254885Sdumbbell 949254885Sdumbbell if (!crtc->base.enabled) { 950254885Sdumbbell /* FIXME: wouldn't it better to set priority mark to maximum */ 951254885Sdumbbell wm->lb_request_fifo_depth = 4; 952254885Sdumbbell return; 953254885Sdumbbell } 954254885Sdumbbell 955254885Sdumbbell if (crtc->vsc.full > dfixed_const(2)) 956254885Sdumbbell wm->num_line_pair.full = dfixed_const(2); 957254885Sdumbbell else 958254885Sdumbbell wm->num_line_pair.full = dfixed_const(1); 959254885Sdumbbell 960254885Sdumbbell b.full = dfixed_const(mode->crtc_hdisplay); 961254885Sdumbbell c.full = dfixed_const(256); 962254885Sdumbbell a.full = dfixed_div(b, c); 963254885Sdumbbell request_fifo_depth.full = dfixed_mul(a, wm->num_line_pair); 964254885Sdumbbell request_fifo_depth.full = dfixed_ceil(request_fifo_depth); 965254885Sdumbbell if (a.full < dfixed_const(4)) { 966254885Sdumbbell wm->lb_request_fifo_depth = 4; 967254885Sdumbbell } else { 968254885Sdumbbell wm->lb_request_fifo_depth = dfixed_trunc(request_fifo_depth); 969254885Sdumbbell } 970254885Sdumbbell 971254885Sdumbbell /* Determine consumption rate 972254885Sdumbbell * pclk = pixel clock period(ns) = 1000 / (mode.clock / 1000) 973254885Sdumbbell * vtaps = number of vertical taps, 974254885Sdumbbell * vsc = vertical scaling ratio, defined as source/destination 975254885Sdumbbell * hsc = horizontal scaling ration, defined as source/destination 976254885Sdumbbell */ 977254885Sdumbbell a.full = dfixed_const(mode->clock); 978254885Sdumbbell b.full = dfixed_const(1000); 979254885Sdumbbell a.full = dfixed_div(a, b); 980254885Sdumbbell pclk.full = dfixed_div(b, a); 981254885Sdumbbell if (crtc->rmx_type != RMX_OFF) { 982254885Sdumbbell b.full = dfixed_const(2); 983254885Sdumbbell if (crtc->vsc.full > b.full) 984254885Sdumbbell b.full = crtc->vsc.full; 985254885Sdumbbell b.full = dfixed_mul(b, crtc->hsc); 986254885Sdumbbell c.full = dfixed_const(2); 987254885Sdumbbell b.full = dfixed_div(b, c); 988254885Sdumbbell consumption_time.full = dfixed_div(pclk, b); 989254885Sdumbbell } else { 990254885Sdumbbell consumption_time.full = pclk.full; 991254885Sdumbbell } 992254885Sdumbbell a.full = dfixed_const(1); 993254885Sdumbbell wm->consumption_rate.full = dfixed_div(a, consumption_time); 994254885Sdumbbell 995254885Sdumbbell 996254885Sdumbbell /* Determine line time 997254885Sdumbbell * LineTime = total time for one line of displayhtotal 998254885Sdumbbell * LineTime = total number of horizontal pixels 999254885Sdumbbell * pclk = pixel clock period(ns) 1000254885Sdumbbell */ 1001254885Sdumbbell a.full = dfixed_const(crtc->base.mode.crtc_htotal); 1002254885Sdumbbell line_time.full = dfixed_mul(a, pclk); 1003254885Sdumbbell 1004254885Sdumbbell /* Determine active time 1005254885Sdumbbell * ActiveTime = time of active region of display within one line, 1006254885Sdumbbell * hactive = total number of horizontal active pixels 1007254885Sdumbbell * htotal = total number of horizontal pixels 1008254885Sdumbbell */ 1009254885Sdumbbell a.full = dfixed_const(crtc->base.mode.crtc_htotal); 1010254885Sdumbbell b.full = dfixed_const(crtc->base.mode.crtc_hdisplay); 1011254885Sdumbbell wm->active_time.full = dfixed_mul(line_time, b); 1012254885Sdumbbell wm->active_time.full = dfixed_div(wm->active_time, a); 1013254885Sdumbbell 1014254885Sdumbbell /* Determine chunk time 1015254885Sdumbbell * ChunkTime = the time it takes the DCP to send one chunk of data 1016254885Sdumbbell * to the LB which consists of pipeline delay and inter chunk gap 1017254885Sdumbbell * sclk = system clock(Mhz) 1018254885Sdumbbell */ 1019254885Sdumbbell a.full = dfixed_const(600 * 1000); 1020254885Sdumbbell chunk_time.full = dfixed_div(a, rdev->pm.sclk); 1021254885Sdumbbell read_delay_latency.full = dfixed_const(1000); 1022254885Sdumbbell 1023254885Sdumbbell /* Determine the worst case latency 1024254885Sdumbbell * NumLinePair = Number of line pairs to request(1=2 lines, 2=4 lines) 1025254885Sdumbbell * WorstCaseLatency = worst case time from urgent to when the MC starts 1026254885Sdumbbell * to return data 1027254885Sdumbbell * READ_DELAY_IDLE_MAX = constant of 1us 1028254885Sdumbbell * ChunkTime = time it takes the DCP to send one chunk of data to the LB 1029254885Sdumbbell * which consists of pipeline delay and inter chunk gap 1030254885Sdumbbell */ 1031254885Sdumbbell if (dfixed_trunc(wm->num_line_pair) > 1) { 1032254885Sdumbbell a.full = dfixed_const(3); 1033254885Sdumbbell wm->worst_case_latency.full = dfixed_mul(a, chunk_time); 1034254885Sdumbbell wm->worst_case_latency.full += read_delay_latency.full; 1035254885Sdumbbell } else { 1036254885Sdumbbell wm->worst_case_latency.full = chunk_time.full + read_delay_latency.full; 1037254885Sdumbbell } 1038254885Sdumbbell 1039254885Sdumbbell /* Determine the tolerable latency 1040254885Sdumbbell * TolerableLatency = Any given request has only 1 line time 1041254885Sdumbbell * for the data to be returned 1042254885Sdumbbell * LBRequestFifoDepth = Number of chunk requests the LB can 1043254885Sdumbbell * put into the request FIFO for a display 1044254885Sdumbbell * LineTime = total time for one line of display 1045254885Sdumbbell * ChunkTime = the time it takes the DCP to send one chunk 1046254885Sdumbbell * of data to the LB which consists of 1047254885Sdumbbell * pipeline delay and inter chunk gap 1048254885Sdumbbell */ 1049254885Sdumbbell if ((2+wm->lb_request_fifo_depth) >= dfixed_trunc(request_fifo_depth)) { 1050254885Sdumbbell tolerable_latency.full = line_time.full; 1051254885Sdumbbell } else { 1052254885Sdumbbell tolerable_latency.full = dfixed_const(wm->lb_request_fifo_depth - 2); 1053254885Sdumbbell tolerable_latency.full = request_fifo_depth.full - tolerable_latency.full; 1054254885Sdumbbell tolerable_latency.full = dfixed_mul(tolerable_latency, chunk_time); 1055254885Sdumbbell tolerable_latency.full = line_time.full - tolerable_latency.full; 1056254885Sdumbbell } 1057254885Sdumbbell /* We assume worst case 32bits (4 bytes) */ 1058254885Sdumbbell wm->dbpp.full = dfixed_const(2 * 16); 1059254885Sdumbbell 1060254885Sdumbbell /* Determine the maximum priority mark 1061254885Sdumbbell * width = viewport width in pixels 1062254885Sdumbbell */ 1063254885Sdumbbell a.full = dfixed_const(16); 1064254885Sdumbbell wm->priority_mark_max.full = dfixed_const(crtc->base.mode.crtc_hdisplay); 1065254885Sdumbbell wm->priority_mark_max.full = dfixed_div(wm->priority_mark_max, a); 1066254885Sdumbbell wm->priority_mark_max.full = dfixed_ceil(wm->priority_mark_max); 1067254885Sdumbbell 1068254885Sdumbbell /* Determine estimated width */ 1069254885Sdumbbell estimated_width.full = tolerable_latency.full - wm->worst_case_latency.full; 1070254885Sdumbbell estimated_width.full = dfixed_div(estimated_width, consumption_time); 1071254885Sdumbbell if (dfixed_trunc(estimated_width) > crtc->base.mode.crtc_hdisplay) { 1072254885Sdumbbell wm->priority_mark.full = wm->priority_mark_max.full; 1073254885Sdumbbell } else { 1074254885Sdumbbell a.full = dfixed_const(16); 1075254885Sdumbbell wm->priority_mark.full = dfixed_div(estimated_width, a); 1076254885Sdumbbell wm->priority_mark.full = dfixed_ceil(wm->priority_mark); 1077254885Sdumbbell wm->priority_mark.full = wm->priority_mark_max.full - wm->priority_mark.full; 1078254885Sdumbbell } 1079254885Sdumbbell} 1080254885Sdumbbell 1081254885Sdumbbellvoid rv515_bandwidth_avivo_update(struct radeon_device *rdev) 1082254885Sdumbbell{ 1083254885Sdumbbell struct drm_display_mode *mode0 = NULL; 1084254885Sdumbbell struct drm_display_mode *mode1 = NULL; 1085254885Sdumbbell struct rv515_watermark wm0; 1086254885Sdumbbell struct rv515_watermark wm1; 1087254885Sdumbbell u32 tmp; 1088254885Sdumbbell u32 d1mode_priority_a_cnt = MODE_PRIORITY_OFF; 1089254885Sdumbbell u32 d2mode_priority_a_cnt = MODE_PRIORITY_OFF; 1090254885Sdumbbell fixed20_12 priority_mark02, priority_mark12, fill_rate; 1091254885Sdumbbell fixed20_12 a, b; 1092254885Sdumbbell 1093254885Sdumbbell if (rdev->mode_info.crtcs[0]->base.enabled) 1094254885Sdumbbell mode0 = &rdev->mode_info.crtcs[0]->base.mode; 1095254885Sdumbbell if (rdev->mode_info.crtcs[1]->base.enabled) 1096254885Sdumbbell mode1 = &rdev->mode_info.crtcs[1]->base.mode; 1097254885Sdumbbell rs690_line_buffer_adjust(rdev, mode0, mode1); 1098254885Sdumbbell 1099254885Sdumbbell rv515_crtc_bandwidth_compute(rdev, rdev->mode_info.crtcs[0], &wm0); 1100254885Sdumbbell rv515_crtc_bandwidth_compute(rdev, rdev->mode_info.crtcs[1], &wm1); 1101254885Sdumbbell 1102254885Sdumbbell tmp = wm0.lb_request_fifo_depth; 1103254885Sdumbbell tmp |= wm1.lb_request_fifo_depth << 16; 1104254885Sdumbbell WREG32(LB_MAX_REQ_OUTSTANDING, tmp); 1105254885Sdumbbell 1106254885Sdumbbell if (mode0 && mode1) { 1107254885Sdumbbell if (dfixed_trunc(wm0.dbpp) > 64) 1108254885Sdumbbell a.full = dfixed_div(wm0.dbpp, wm0.num_line_pair); 1109254885Sdumbbell else 1110254885Sdumbbell a.full = wm0.num_line_pair.full; 1111254885Sdumbbell if (dfixed_trunc(wm1.dbpp) > 64) 1112254885Sdumbbell b.full = dfixed_div(wm1.dbpp, wm1.num_line_pair); 1113254885Sdumbbell else 1114254885Sdumbbell b.full = wm1.num_line_pair.full; 1115254885Sdumbbell a.full += b.full; 1116254885Sdumbbell fill_rate.full = dfixed_div(wm0.sclk, a); 1117254885Sdumbbell if (wm0.consumption_rate.full > fill_rate.full) { 1118254885Sdumbbell b.full = wm0.consumption_rate.full - fill_rate.full; 1119254885Sdumbbell b.full = dfixed_mul(b, wm0.active_time); 1120254885Sdumbbell a.full = dfixed_const(16); 1121254885Sdumbbell b.full = dfixed_div(b, a); 1122254885Sdumbbell a.full = dfixed_mul(wm0.worst_case_latency, 1123254885Sdumbbell wm0.consumption_rate); 1124254885Sdumbbell priority_mark02.full = a.full + b.full; 1125254885Sdumbbell } else { 1126254885Sdumbbell a.full = dfixed_mul(wm0.worst_case_latency, 1127254885Sdumbbell wm0.consumption_rate); 1128254885Sdumbbell b.full = dfixed_const(16 * 1000); 1129254885Sdumbbell priority_mark02.full = dfixed_div(a, b); 1130254885Sdumbbell } 1131254885Sdumbbell if (wm1.consumption_rate.full > fill_rate.full) { 1132254885Sdumbbell b.full = wm1.consumption_rate.full - fill_rate.full; 1133254885Sdumbbell b.full = dfixed_mul(b, wm1.active_time); 1134254885Sdumbbell a.full = dfixed_const(16); 1135254885Sdumbbell b.full = dfixed_div(b, a); 1136254885Sdumbbell a.full = dfixed_mul(wm1.worst_case_latency, 1137254885Sdumbbell wm1.consumption_rate); 1138254885Sdumbbell priority_mark12.full = a.full + b.full; 1139254885Sdumbbell } else { 1140254885Sdumbbell a.full = dfixed_mul(wm1.worst_case_latency, 1141254885Sdumbbell wm1.consumption_rate); 1142254885Sdumbbell b.full = dfixed_const(16 * 1000); 1143254885Sdumbbell priority_mark12.full = dfixed_div(a, b); 1144254885Sdumbbell } 1145254885Sdumbbell if (wm0.priority_mark.full > priority_mark02.full) 1146254885Sdumbbell priority_mark02.full = wm0.priority_mark.full; 1147254885Sdumbbell if (wm0.priority_mark_max.full > priority_mark02.full) 1148254885Sdumbbell priority_mark02.full = wm0.priority_mark_max.full; 1149254885Sdumbbell if (wm1.priority_mark.full > priority_mark12.full) 1150254885Sdumbbell priority_mark12.full = wm1.priority_mark.full; 1151254885Sdumbbell if (wm1.priority_mark_max.full > priority_mark12.full) 1152254885Sdumbbell priority_mark12.full = wm1.priority_mark_max.full; 1153254885Sdumbbell d1mode_priority_a_cnt = dfixed_trunc(priority_mark02); 1154254885Sdumbbell d2mode_priority_a_cnt = dfixed_trunc(priority_mark12); 1155254885Sdumbbell if (rdev->disp_priority == 2) { 1156254885Sdumbbell d1mode_priority_a_cnt |= MODE_PRIORITY_ALWAYS_ON; 1157254885Sdumbbell d2mode_priority_a_cnt |= MODE_PRIORITY_ALWAYS_ON; 1158254885Sdumbbell } 1159254885Sdumbbell } else if (mode0) { 1160254885Sdumbbell if (dfixed_trunc(wm0.dbpp) > 64) 1161254885Sdumbbell a.full = dfixed_div(wm0.dbpp, wm0.num_line_pair); 1162254885Sdumbbell else 1163254885Sdumbbell a.full = wm0.num_line_pair.full; 1164254885Sdumbbell fill_rate.full = dfixed_div(wm0.sclk, a); 1165254885Sdumbbell if (wm0.consumption_rate.full > fill_rate.full) { 1166254885Sdumbbell b.full = wm0.consumption_rate.full - fill_rate.full; 1167254885Sdumbbell b.full = dfixed_mul(b, wm0.active_time); 1168254885Sdumbbell a.full = dfixed_const(16); 1169254885Sdumbbell b.full = dfixed_div(b, a); 1170254885Sdumbbell a.full = dfixed_mul(wm0.worst_case_latency, 1171254885Sdumbbell wm0.consumption_rate); 1172254885Sdumbbell priority_mark02.full = a.full + b.full; 1173254885Sdumbbell } else { 1174254885Sdumbbell a.full = dfixed_mul(wm0.worst_case_latency, 1175254885Sdumbbell wm0.consumption_rate); 1176254885Sdumbbell b.full = dfixed_const(16); 1177254885Sdumbbell priority_mark02.full = dfixed_div(a, b); 1178254885Sdumbbell } 1179254885Sdumbbell if (wm0.priority_mark.full > priority_mark02.full) 1180254885Sdumbbell priority_mark02.full = wm0.priority_mark.full; 1181254885Sdumbbell if (wm0.priority_mark_max.full > priority_mark02.full) 1182254885Sdumbbell priority_mark02.full = wm0.priority_mark_max.full; 1183254885Sdumbbell d1mode_priority_a_cnt = dfixed_trunc(priority_mark02); 1184254885Sdumbbell if (rdev->disp_priority == 2) 1185254885Sdumbbell d1mode_priority_a_cnt |= MODE_PRIORITY_ALWAYS_ON; 1186254885Sdumbbell } else if (mode1) { 1187254885Sdumbbell if (dfixed_trunc(wm1.dbpp) > 64) 1188254885Sdumbbell a.full = dfixed_div(wm1.dbpp, wm1.num_line_pair); 1189254885Sdumbbell else 1190254885Sdumbbell a.full = wm1.num_line_pair.full; 1191254885Sdumbbell fill_rate.full = dfixed_div(wm1.sclk, a); 1192254885Sdumbbell if (wm1.consumption_rate.full > fill_rate.full) { 1193254885Sdumbbell b.full = wm1.consumption_rate.full - fill_rate.full; 1194254885Sdumbbell b.full = dfixed_mul(b, wm1.active_time); 1195254885Sdumbbell a.full = dfixed_const(16); 1196254885Sdumbbell b.full = dfixed_div(b, a); 1197254885Sdumbbell a.full = dfixed_mul(wm1.worst_case_latency, 1198254885Sdumbbell wm1.consumption_rate); 1199254885Sdumbbell priority_mark12.full = a.full + b.full; 1200254885Sdumbbell } else { 1201254885Sdumbbell a.full = dfixed_mul(wm1.worst_case_latency, 1202254885Sdumbbell wm1.consumption_rate); 1203254885Sdumbbell b.full = dfixed_const(16 * 1000); 1204254885Sdumbbell priority_mark12.full = dfixed_div(a, b); 1205254885Sdumbbell } 1206254885Sdumbbell if (wm1.priority_mark.full > priority_mark12.full) 1207254885Sdumbbell priority_mark12.full = wm1.priority_mark.full; 1208254885Sdumbbell if (wm1.priority_mark_max.full > priority_mark12.full) 1209254885Sdumbbell priority_mark12.full = wm1.priority_mark_max.full; 1210254885Sdumbbell d2mode_priority_a_cnt = dfixed_trunc(priority_mark12); 1211254885Sdumbbell if (rdev->disp_priority == 2) 1212254885Sdumbbell d2mode_priority_a_cnt |= MODE_PRIORITY_ALWAYS_ON; 1213254885Sdumbbell } 1214254885Sdumbbell 1215254885Sdumbbell WREG32(D1MODE_PRIORITY_A_CNT, d1mode_priority_a_cnt); 1216254885Sdumbbell WREG32(D1MODE_PRIORITY_B_CNT, d1mode_priority_a_cnt); 1217254885Sdumbbell WREG32(D2MODE_PRIORITY_A_CNT, d2mode_priority_a_cnt); 1218254885Sdumbbell WREG32(D2MODE_PRIORITY_B_CNT, d2mode_priority_a_cnt); 1219254885Sdumbbell} 1220254885Sdumbbell 1221254885Sdumbbellvoid rv515_bandwidth_update(struct radeon_device *rdev) 1222254885Sdumbbell{ 1223254885Sdumbbell uint32_t tmp; 1224254885Sdumbbell struct drm_display_mode *mode0 = NULL; 1225254885Sdumbbell struct drm_display_mode *mode1 = NULL; 1226254885Sdumbbell 1227254885Sdumbbell radeon_update_display_priority(rdev); 1228254885Sdumbbell 1229254885Sdumbbell if (rdev->mode_info.crtcs[0]->base.enabled) 1230254885Sdumbbell mode0 = &rdev->mode_info.crtcs[0]->base.mode; 1231254885Sdumbbell if (rdev->mode_info.crtcs[1]->base.enabled) 1232254885Sdumbbell mode1 = &rdev->mode_info.crtcs[1]->base.mode; 1233254885Sdumbbell /* 1234254885Sdumbbell * Set display0/1 priority up in the memory controller for 1235254885Sdumbbell * modes if the user specifies HIGH for displaypriority 1236254885Sdumbbell * option. 1237254885Sdumbbell */ 1238254885Sdumbbell if ((rdev->disp_priority == 2) && 1239254885Sdumbbell (rdev->family == CHIP_RV515)) { 1240254885Sdumbbell tmp = RREG32_MC(MC_MISC_LAT_TIMER); 1241254885Sdumbbell tmp &= ~MC_DISP1R_INIT_LAT_MASK; 1242254885Sdumbbell tmp &= ~MC_DISP0R_INIT_LAT_MASK; 1243254885Sdumbbell if (mode1) 1244254885Sdumbbell tmp |= (1 << MC_DISP1R_INIT_LAT_SHIFT); 1245254885Sdumbbell if (mode0) 1246254885Sdumbbell tmp |= (1 << MC_DISP0R_INIT_LAT_SHIFT); 1247254885Sdumbbell WREG32_MC(MC_MISC_LAT_TIMER, tmp); 1248254885Sdumbbell } 1249254885Sdumbbell rv515_bandwidth_avivo_update(rdev); 1250254885Sdumbbell} 1251