162306a36Sopenharmony_ci/* 262306a36Sopenharmony_ci * Copyright 2008 Advanced Micro Devices, Inc. 362306a36Sopenharmony_ci * Copyright 2008 Red Hat Inc. 462306a36Sopenharmony_ci * Copyright 2009 Jerome Glisse. 562306a36Sopenharmony_ci * 662306a36Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a 762306a36Sopenharmony_ci * copy of this software and associated documentation files (the "Software"), 862306a36Sopenharmony_ci * to deal in the Software without restriction, including without limitation 962306a36Sopenharmony_ci * the rights to use, copy, modify, merge, publish, distribute, sublicense, 1062306a36Sopenharmony_ci * and/or sell copies of the Software, and to permit persons to whom the 1162306a36Sopenharmony_ci * Software is furnished to do so, subject to the following conditions: 1262306a36Sopenharmony_ci * 1362306a36Sopenharmony_ci * The above copyright notice and this permission notice shall be included in 1462306a36Sopenharmony_ci * all copies or substantial portions of the Software. 1562306a36Sopenharmony_ci * 1662306a36Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 1762306a36Sopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 1862306a36Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 1962306a36Sopenharmony_ci * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR 2062306a36Sopenharmony_ci * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 2162306a36Sopenharmony_ci * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 2262306a36Sopenharmony_ci * OTHER DEALINGS IN THE SOFTWARE. 2362306a36Sopenharmony_ci * 2462306a36Sopenharmony_ci * Authors: Dave Airlie 2562306a36Sopenharmony_ci * Alex Deucher 2662306a36Sopenharmony_ci * Jerome Glisse 2762306a36Sopenharmony_ci */ 2862306a36Sopenharmony_ci 2962306a36Sopenharmony_ci#include <linux/seq_file.h> 3062306a36Sopenharmony_ci#include <linux/slab.h> 3162306a36Sopenharmony_ci 3262306a36Sopenharmony_ci#include <drm/drm_device.h> 3362306a36Sopenharmony_ci#include <drm/drm_file.h> 3462306a36Sopenharmony_ci 3562306a36Sopenharmony_ci#include "atom.h" 3662306a36Sopenharmony_ci#include "radeon.h" 3762306a36Sopenharmony_ci#include "radeon_asic.h" 3862306a36Sopenharmony_ci#include "rv515_reg_safe.h" 3962306a36Sopenharmony_ci#include "rv515d.h" 4062306a36Sopenharmony_ci 4162306a36Sopenharmony_ci/* This files gather functions specifics to: rv515 */ 4262306a36Sopenharmony_cistatic void rv515_gpu_init(struct radeon_device *rdev); 4362306a36Sopenharmony_ciint rv515_mc_wait_for_idle(struct radeon_device *rdev); 4462306a36Sopenharmony_ci 4562306a36Sopenharmony_cistatic const u32 crtc_offsets[2] = 4662306a36Sopenharmony_ci{ 4762306a36Sopenharmony_ci 0, 4862306a36Sopenharmony_ci AVIVO_D2CRTC_H_TOTAL - AVIVO_D1CRTC_H_TOTAL 4962306a36Sopenharmony_ci}; 5062306a36Sopenharmony_ci 5162306a36Sopenharmony_civoid rv515_ring_start(struct radeon_device *rdev, struct radeon_ring *ring) 5262306a36Sopenharmony_ci{ 5362306a36Sopenharmony_ci int r; 5462306a36Sopenharmony_ci 5562306a36Sopenharmony_ci r = radeon_ring_lock(rdev, ring, 64); 5662306a36Sopenharmony_ci if (r) { 5762306a36Sopenharmony_ci return; 5862306a36Sopenharmony_ci } 5962306a36Sopenharmony_ci radeon_ring_write(ring, PACKET0(ISYNC_CNTL, 0)); 6062306a36Sopenharmony_ci radeon_ring_write(ring, 6162306a36Sopenharmony_ci ISYNC_ANY2D_IDLE3D | 6262306a36Sopenharmony_ci ISYNC_ANY3D_IDLE2D | 6362306a36Sopenharmony_ci ISYNC_WAIT_IDLEGUI | 6462306a36Sopenharmony_ci ISYNC_CPSCRATCH_IDLEGUI); 6562306a36Sopenharmony_ci radeon_ring_write(ring, PACKET0(WAIT_UNTIL, 0)); 6662306a36Sopenharmony_ci radeon_ring_write(ring, WAIT_2D_IDLECLEAN | WAIT_3D_IDLECLEAN); 6762306a36Sopenharmony_ci radeon_ring_write(ring, PACKET0(R300_DST_PIPE_CONFIG, 0)); 6862306a36Sopenharmony_ci radeon_ring_write(ring, R300_PIPE_AUTO_CONFIG); 6962306a36Sopenharmony_ci radeon_ring_write(ring, PACKET0(GB_SELECT, 0)); 7062306a36Sopenharmony_ci radeon_ring_write(ring, 0); 7162306a36Sopenharmony_ci radeon_ring_write(ring, PACKET0(GB_ENABLE, 0)); 7262306a36Sopenharmony_ci radeon_ring_write(ring, 0); 7362306a36Sopenharmony_ci radeon_ring_write(ring, PACKET0(R500_SU_REG_DEST, 0)); 7462306a36Sopenharmony_ci radeon_ring_write(ring, (1 << rdev->num_gb_pipes) - 1); 7562306a36Sopenharmony_ci radeon_ring_write(ring, PACKET0(VAP_INDEX_OFFSET, 0)); 7662306a36Sopenharmony_ci radeon_ring_write(ring, 0); 7762306a36Sopenharmony_ci radeon_ring_write(ring, PACKET0(RB3D_DSTCACHE_CTLSTAT, 0)); 7862306a36Sopenharmony_ci radeon_ring_write(ring, RB3D_DC_FLUSH | RB3D_DC_FREE); 7962306a36Sopenharmony_ci radeon_ring_write(ring, PACKET0(ZB_ZCACHE_CTLSTAT, 0)); 8062306a36Sopenharmony_ci radeon_ring_write(ring, ZC_FLUSH | ZC_FREE); 8162306a36Sopenharmony_ci radeon_ring_write(ring, PACKET0(WAIT_UNTIL, 0)); 8262306a36Sopenharmony_ci radeon_ring_write(ring, WAIT_2D_IDLECLEAN | WAIT_3D_IDLECLEAN); 8362306a36Sopenharmony_ci radeon_ring_write(ring, PACKET0(GB_AA_CONFIG, 0)); 8462306a36Sopenharmony_ci radeon_ring_write(ring, 0); 8562306a36Sopenharmony_ci radeon_ring_write(ring, PACKET0(RB3D_DSTCACHE_CTLSTAT, 0)); 8662306a36Sopenharmony_ci radeon_ring_write(ring, RB3D_DC_FLUSH | RB3D_DC_FREE); 8762306a36Sopenharmony_ci radeon_ring_write(ring, PACKET0(ZB_ZCACHE_CTLSTAT, 0)); 8862306a36Sopenharmony_ci radeon_ring_write(ring, ZC_FLUSH | ZC_FREE); 8962306a36Sopenharmony_ci radeon_ring_write(ring, PACKET0(GB_MSPOS0, 0)); 9062306a36Sopenharmony_ci radeon_ring_write(ring, 9162306a36Sopenharmony_ci ((6 << MS_X0_SHIFT) | 9262306a36Sopenharmony_ci (6 << MS_Y0_SHIFT) | 9362306a36Sopenharmony_ci (6 << MS_X1_SHIFT) | 9462306a36Sopenharmony_ci (6 << MS_Y1_SHIFT) | 9562306a36Sopenharmony_ci (6 << MS_X2_SHIFT) | 9662306a36Sopenharmony_ci (6 << MS_Y2_SHIFT) | 9762306a36Sopenharmony_ci (6 << MSBD0_Y_SHIFT) | 9862306a36Sopenharmony_ci (6 << MSBD0_X_SHIFT))); 9962306a36Sopenharmony_ci radeon_ring_write(ring, PACKET0(GB_MSPOS1, 0)); 10062306a36Sopenharmony_ci radeon_ring_write(ring, 10162306a36Sopenharmony_ci ((6 << MS_X3_SHIFT) | 10262306a36Sopenharmony_ci (6 << MS_Y3_SHIFT) | 10362306a36Sopenharmony_ci (6 << MS_X4_SHIFT) | 10462306a36Sopenharmony_ci (6 << MS_Y4_SHIFT) | 10562306a36Sopenharmony_ci (6 << MS_X5_SHIFT) | 10662306a36Sopenharmony_ci (6 << MS_Y5_SHIFT) | 10762306a36Sopenharmony_ci (6 << MSBD1_SHIFT))); 10862306a36Sopenharmony_ci radeon_ring_write(ring, PACKET0(GA_ENHANCE, 0)); 10962306a36Sopenharmony_ci radeon_ring_write(ring, GA_DEADLOCK_CNTL | GA_FASTSYNC_CNTL); 11062306a36Sopenharmony_ci radeon_ring_write(ring, PACKET0(GA_POLY_MODE, 0)); 11162306a36Sopenharmony_ci radeon_ring_write(ring, FRONT_PTYPE_TRIANGE | BACK_PTYPE_TRIANGE); 11262306a36Sopenharmony_ci radeon_ring_write(ring, PACKET0(GA_ROUND_MODE, 0)); 11362306a36Sopenharmony_ci radeon_ring_write(ring, GEOMETRY_ROUND_NEAREST | COLOR_ROUND_NEAREST); 11462306a36Sopenharmony_ci radeon_ring_write(ring, PACKET0(0x20C8, 0)); 11562306a36Sopenharmony_ci radeon_ring_write(ring, 0); 11662306a36Sopenharmony_ci radeon_ring_unlock_commit(rdev, ring, false); 11762306a36Sopenharmony_ci} 11862306a36Sopenharmony_ci 11962306a36Sopenharmony_ciint rv515_mc_wait_for_idle(struct radeon_device *rdev) 12062306a36Sopenharmony_ci{ 12162306a36Sopenharmony_ci unsigned i; 12262306a36Sopenharmony_ci uint32_t tmp; 12362306a36Sopenharmony_ci 12462306a36Sopenharmony_ci for (i = 0; i < rdev->usec_timeout; i++) { 12562306a36Sopenharmony_ci /* read MC_STATUS */ 12662306a36Sopenharmony_ci tmp = RREG32_MC(MC_STATUS); 12762306a36Sopenharmony_ci if (tmp & MC_STATUS_IDLE) { 12862306a36Sopenharmony_ci return 0; 12962306a36Sopenharmony_ci } 13062306a36Sopenharmony_ci udelay(1); 13162306a36Sopenharmony_ci } 13262306a36Sopenharmony_ci return -1; 13362306a36Sopenharmony_ci} 13462306a36Sopenharmony_ci 13562306a36Sopenharmony_civoid rv515_vga_render_disable(struct radeon_device *rdev) 13662306a36Sopenharmony_ci{ 13762306a36Sopenharmony_ci WREG32(R_000300_VGA_RENDER_CONTROL, 13862306a36Sopenharmony_ci RREG32(R_000300_VGA_RENDER_CONTROL) & C_000300_VGA_VSTATUS_CNTL); 13962306a36Sopenharmony_ci} 14062306a36Sopenharmony_ci 14162306a36Sopenharmony_cistatic void rv515_gpu_init(struct radeon_device *rdev) 14262306a36Sopenharmony_ci{ 14362306a36Sopenharmony_ci unsigned pipe_select_current, gb_pipe_select, tmp; 14462306a36Sopenharmony_ci 14562306a36Sopenharmony_ci if (r100_gui_wait_for_idle(rdev)) { 14662306a36Sopenharmony_ci pr_warn("Failed to wait GUI idle while resetting GPU. Bad things might happen.\n"); 14762306a36Sopenharmony_ci } 14862306a36Sopenharmony_ci rv515_vga_render_disable(rdev); 14962306a36Sopenharmony_ci r420_pipes_init(rdev); 15062306a36Sopenharmony_ci gb_pipe_select = RREG32(R400_GB_PIPE_SELECT); 15162306a36Sopenharmony_ci tmp = RREG32(R300_DST_PIPE_CONFIG); 15262306a36Sopenharmony_ci pipe_select_current = (tmp >> 2) & 3; 15362306a36Sopenharmony_ci tmp = (1 << pipe_select_current) | 15462306a36Sopenharmony_ci (((gb_pipe_select >> 8) & 0xF) << 4); 15562306a36Sopenharmony_ci WREG32_PLL(0x000D, tmp); 15662306a36Sopenharmony_ci if (r100_gui_wait_for_idle(rdev)) { 15762306a36Sopenharmony_ci pr_warn("Failed to wait GUI idle while resetting GPU. Bad things might happen.\n"); 15862306a36Sopenharmony_ci } 15962306a36Sopenharmony_ci if (rv515_mc_wait_for_idle(rdev)) { 16062306a36Sopenharmony_ci pr_warn("Failed to wait MC idle while programming pipes. Bad things might happen.\n"); 16162306a36Sopenharmony_ci } 16262306a36Sopenharmony_ci} 16362306a36Sopenharmony_ci 16462306a36Sopenharmony_cistatic void rv515_vram_get_type(struct radeon_device *rdev) 16562306a36Sopenharmony_ci{ 16662306a36Sopenharmony_ci uint32_t tmp; 16762306a36Sopenharmony_ci 16862306a36Sopenharmony_ci rdev->mc.vram_width = 128; 16962306a36Sopenharmony_ci rdev->mc.vram_is_ddr = true; 17062306a36Sopenharmony_ci tmp = RREG32_MC(RV515_MC_CNTL) & MEM_NUM_CHANNELS_MASK; 17162306a36Sopenharmony_ci switch (tmp) { 17262306a36Sopenharmony_ci case 0: 17362306a36Sopenharmony_ci rdev->mc.vram_width = 64; 17462306a36Sopenharmony_ci break; 17562306a36Sopenharmony_ci case 1: 17662306a36Sopenharmony_ci rdev->mc.vram_width = 128; 17762306a36Sopenharmony_ci break; 17862306a36Sopenharmony_ci default: 17962306a36Sopenharmony_ci rdev->mc.vram_width = 128; 18062306a36Sopenharmony_ci break; 18162306a36Sopenharmony_ci } 18262306a36Sopenharmony_ci} 18362306a36Sopenharmony_ci 18462306a36Sopenharmony_cistatic void rv515_mc_init(struct radeon_device *rdev) 18562306a36Sopenharmony_ci{ 18662306a36Sopenharmony_ci 18762306a36Sopenharmony_ci rv515_vram_get_type(rdev); 18862306a36Sopenharmony_ci r100_vram_init_sizes(rdev); 18962306a36Sopenharmony_ci radeon_vram_location(rdev, &rdev->mc, 0); 19062306a36Sopenharmony_ci rdev->mc.gtt_base_align = 0; 19162306a36Sopenharmony_ci if (!(rdev->flags & RADEON_IS_AGP)) 19262306a36Sopenharmony_ci radeon_gtt_location(rdev, &rdev->mc); 19362306a36Sopenharmony_ci radeon_update_bandwidth_info(rdev); 19462306a36Sopenharmony_ci} 19562306a36Sopenharmony_ci 19662306a36Sopenharmony_ciuint32_t rv515_mc_rreg(struct radeon_device *rdev, uint32_t reg) 19762306a36Sopenharmony_ci{ 19862306a36Sopenharmony_ci unsigned long flags; 19962306a36Sopenharmony_ci uint32_t r; 20062306a36Sopenharmony_ci 20162306a36Sopenharmony_ci spin_lock_irqsave(&rdev->mc_idx_lock, flags); 20262306a36Sopenharmony_ci WREG32(MC_IND_INDEX, 0x7f0000 | (reg & 0xffff)); 20362306a36Sopenharmony_ci r = RREG32(MC_IND_DATA); 20462306a36Sopenharmony_ci WREG32(MC_IND_INDEX, 0); 20562306a36Sopenharmony_ci spin_unlock_irqrestore(&rdev->mc_idx_lock, flags); 20662306a36Sopenharmony_ci 20762306a36Sopenharmony_ci return r; 20862306a36Sopenharmony_ci} 20962306a36Sopenharmony_ci 21062306a36Sopenharmony_civoid rv515_mc_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v) 21162306a36Sopenharmony_ci{ 21262306a36Sopenharmony_ci unsigned long flags; 21362306a36Sopenharmony_ci 21462306a36Sopenharmony_ci spin_lock_irqsave(&rdev->mc_idx_lock, flags); 21562306a36Sopenharmony_ci WREG32(MC_IND_INDEX, 0xff0000 | ((reg) & 0xffff)); 21662306a36Sopenharmony_ci WREG32(MC_IND_DATA, (v)); 21762306a36Sopenharmony_ci WREG32(MC_IND_INDEX, 0); 21862306a36Sopenharmony_ci spin_unlock_irqrestore(&rdev->mc_idx_lock, flags); 21962306a36Sopenharmony_ci} 22062306a36Sopenharmony_ci 22162306a36Sopenharmony_ci#if defined(CONFIG_DEBUG_FS) 22262306a36Sopenharmony_cistatic int rv515_debugfs_pipes_info_show(struct seq_file *m, void *unused) 22362306a36Sopenharmony_ci{ 22462306a36Sopenharmony_ci struct radeon_device *rdev = m->private; 22562306a36Sopenharmony_ci uint32_t tmp; 22662306a36Sopenharmony_ci 22762306a36Sopenharmony_ci tmp = RREG32(GB_PIPE_SELECT); 22862306a36Sopenharmony_ci seq_printf(m, "GB_PIPE_SELECT 0x%08x\n", tmp); 22962306a36Sopenharmony_ci tmp = RREG32(SU_REG_DEST); 23062306a36Sopenharmony_ci seq_printf(m, "SU_REG_DEST 0x%08x\n", tmp); 23162306a36Sopenharmony_ci tmp = RREG32(GB_TILE_CONFIG); 23262306a36Sopenharmony_ci seq_printf(m, "GB_TILE_CONFIG 0x%08x\n", tmp); 23362306a36Sopenharmony_ci tmp = RREG32(DST_PIPE_CONFIG); 23462306a36Sopenharmony_ci seq_printf(m, "DST_PIPE_CONFIG 0x%08x\n", tmp); 23562306a36Sopenharmony_ci return 0; 23662306a36Sopenharmony_ci} 23762306a36Sopenharmony_ci 23862306a36Sopenharmony_cistatic int rv515_debugfs_ga_info_show(struct seq_file *m, void *unused) 23962306a36Sopenharmony_ci{ 24062306a36Sopenharmony_ci struct radeon_device *rdev = m->private; 24162306a36Sopenharmony_ci uint32_t tmp; 24262306a36Sopenharmony_ci 24362306a36Sopenharmony_ci tmp = RREG32(0x2140); 24462306a36Sopenharmony_ci seq_printf(m, "VAP_CNTL_STATUS 0x%08x\n", tmp); 24562306a36Sopenharmony_ci radeon_asic_reset(rdev); 24662306a36Sopenharmony_ci tmp = RREG32(0x425C); 24762306a36Sopenharmony_ci seq_printf(m, "GA_IDLE 0x%08x\n", tmp); 24862306a36Sopenharmony_ci return 0; 24962306a36Sopenharmony_ci} 25062306a36Sopenharmony_ci 25162306a36Sopenharmony_ciDEFINE_SHOW_ATTRIBUTE(rv515_debugfs_pipes_info); 25262306a36Sopenharmony_ciDEFINE_SHOW_ATTRIBUTE(rv515_debugfs_ga_info); 25362306a36Sopenharmony_ci#endif 25462306a36Sopenharmony_ci 25562306a36Sopenharmony_civoid rv515_debugfs(struct radeon_device *rdev) 25662306a36Sopenharmony_ci{ 25762306a36Sopenharmony_ci#if defined(CONFIG_DEBUG_FS) 25862306a36Sopenharmony_ci struct dentry *root = rdev->ddev->primary->debugfs_root; 25962306a36Sopenharmony_ci 26062306a36Sopenharmony_ci debugfs_create_file("rv515_pipes_info", 0444, root, rdev, 26162306a36Sopenharmony_ci &rv515_debugfs_pipes_info_fops); 26262306a36Sopenharmony_ci debugfs_create_file("rv515_ga_info", 0444, root, rdev, 26362306a36Sopenharmony_ci &rv515_debugfs_ga_info_fops); 26462306a36Sopenharmony_ci#endif 26562306a36Sopenharmony_ci r100_debugfs_rbbm_init(rdev); 26662306a36Sopenharmony_ci} 26762306a36Sopenharmony_ci 26862306a36Sopenharmony_civoid rv515_mc_stop(struct radeon_device *rdev, struct rv515_mc_save *save) 26962306a36Sopenharmony_ci{ 27062306a36Sopenharmony_ci u32 crtc_enabled, tmp, frame_count, blackout; 27162306a36Sopenharmony_ci int i, j; 27262306a36Sopenharmony_ci 27362306a36Sopenharmony_ci save->vga_render_control = RREG32(R_000300_VGA_RENDER_CONTROL); 27462306a36Sopenharmony_ci save->vga_hdp_control = RREG32(R_000328_VGA_HDP_CONTROL); 27562306a36Sopenharmony_ci 27662306a36Sopenharmony_ci /* disable VGA render */ 27762306a36Sopenharmony_ci WREG32(R_000300_VGA_RENDER_CONTROL, 0); 27862306a36Sopenharmony_ci /* blank the display controllers */ 27962306a36Sopenharmony_ci for (i = 0; i < rdev->num_crtc; i++) { 28062306a36Sopenharmony_ci crtc_enabled = RREG32(AVIVO_D1CRTC_CONTROL + crtc_offsets[i]) & AVIVO_CRTC_EN; 28162306a36Sopenharmony_ci if (crtc_enabled) { 28262306a36Sopenharmony_ci save->crtc_enabled[i] = true; 28362306a36Sopenharmony_ci tmp = RREG32(AVIVO_D1CRTC_CONTROL + crtc_offsets[i]); 28462306a36Sopenharmony_ci if (!(tmp & AVIVO_CRTC_DISP_READ_REQUEST_DISABLE)) { 28562306a36Sopenharmony_ci radeon_wait_for_vblank(rdev, i); 28662306a36Sopenharmony_ci WREG32(AVIVO_D1CRTC_UPDATE_LOCK + crtc_offsets[i], 1); 28762306a36Sopenharmony_ci tmp |= AVIVO_CRTC_DISP_READ_REQUEST_DISABLE; 28862306a36Sopenharmony_ci WREG32(AVIVO_D1CRTC_CONTROL + crtc_offsets[i], tmp); 28962306a36Sopenharmony_ci WREG32(AVIVO_D1CRTC_UPDATE_LOCK + crtc_offsets[i], 0); 29062306a36Sopenharmony_ci } 29162306a36Sopenharmony_ci /* wait for the next frame */ 29262306a36Sopenharmony_ci frame_count = radeon_get_vblank_counter(rdev, i); 29362306a36Sopenharmony_ci for (j = 0; j < rdev->usec_timeout; j++) { 29462306a36Sopenharmony_ci if (radeon_get_vblank_counter(rdev, i) != frame_count) 29562306a36Sopenharmony_ci break; 29662306a36Sopenharmony_ci udelay(1); 29762306a36Sopenharmony_ci } 29862306a36Sopenharmony_ci 29962306a36Sopenharmony_ci /* XXX this is a hack to avoid strange behavior with EFI on certain systems */ 30062306a36Sopenharmony_ci WREG32(AVIVO_D1CRTC_UPDATE_LOCK + crtc_offsets[i], 1); 30162306a36Sopenharmony_ci tmp = RREG32(AVIVO_D1CRTC_CONTROL + crtc_offsets[i]); 30262306a36Sopenharmony_ci tmp &= ~AVIVO_CRTC_EN; 30362306a36Sopenharmony_ci WREG32(AVIVO_D1CRTC_CONTROL + crtc_offsets[i], tmp); 30462306a36Sopenharmony_ci WREG32(AVIVO_D1CRTC_UPDATE_LOCK + crtc_offsets[i], 0); 30562306a36Sopenharmony_ci save->crtc_enabled[i] = false; 30662306a36Sopenharmony_ci /* ***** */ 30762306a36Sopenharmony_ci } else { 30862306a36Sopenharmony_ci save->crtc_enabled[i] = false; 30962306a36Sopenharmony_ci } 31062306a36Sopenharmony_ci } 31162306a36Sopenharmony_ci 31262306a36Sopenharmony_ci radeon_mc_wait_for_idle(rdev); 31362306a36Sopenharmony_ci 31462306a36Sopenharmony_ci if (rdev->family >= CHIP_R600) { 31562306a36Sopenharmony_ci if (rdev->family >= CHIP_RV770) 31662306a36Sopenharmony_ci blackout = RREG32(R700_MC_CITF_CNTL); 31762306a36Sopenharmony_ci else 31862306a36Sopenharmony_ci blackout = RREG32(R600_CITF_CNTL); 31962306a36Sopenharmony_ci if ((blackout & R600_BLACKOUT_MASK) != R600_BLACKOUT_MASK) { 32062306a36Sopenharmony_ci /* Block CPU access */ 32162306a36Sopenharmony_ci WREG32(R600_BIF_FB_EN, 0); 32262306a36Sopenharmony_ci /* blackout the MC */ 32362306a36Sopenharmony_ci blackout |= R600_BLACKOUT_MASK; 32462306a36Sopenharmony_ci if (rdev->family >= CHIP_RV770) 32562306a36Sopenharmony_ci WREG32(R700_MC_CITF_CNTL, blackout); 32662306a36Sopenharmony_ci else 32762306a36Sopenharmony_ci WREG32(R600_CITF_CNTL, blackout); 32862306a36Sopenharmony_ci } 32962306a36Sopenharmony_ci } 33062306a36Sopenharmony_ci /* wait for the MC to settle */ 33162306a36Sopenharmony_ci udelay(100); 33262306a36Sopenharmony_ci 33362306a36Sopenharmony_ci /* lock double buffered regs */ 33462306a36Sopenharmony_ci for (i = 0; i < rdev->num_crtc; i++) { 33562306a36Sopenharmony_ci if (save->crtc_enabled[i]) { 33662306a36Sopenharmony_ci tmp = RREG32(AVIVO_D1GRPH_UPDATE + crtc_offsets[i]); 33762306a36Sopenharmony_ci if (!(tmp & AVIVO_D1GRPH_UPDATE_LOCK)) { 33862306a36Sopenharmony_ci tmp |= AVIVO_D1GRPH_UPDATE_LOCK; 33962306a36Sopenharmony_ci WREG32(AVIVO_D1GRPH_UPDATE + crtc_offsets[i], tmp); 34062306a36Sopenharmony_ci } 34162306a36Sopenharmony_ci tmp = RREG32(AVIVO_D1MODE_MASTER_UPDATE_LOCK + crtc_offsets[i]); 34262306a36Sopenharmony_ci if (!(tmp & 1)) { 34362306a36Sopenharmony_ci tmp |= 1; 34462306a36Sopenharmony_ci WREG32(AVIVO_D1MODE_MASTER_UPDATE_LOCK + crtc_offsets[i], tmp); 34562306a36Sopenharmony_ci } 34662306a36Sopenharmony_ci } 34762306a36Sopenharmony_ci } 34862306a36Sopenharmony_ci} 34962306a36Sopenharmony_ci 35062306a36Sopenharmony_civoid rv515_mc_resume(struct radeon_device *rdev, struct rv515_mc_save *save) 35162306a36Sopenharmony_ci{ 35262306a36Sopenharmony_ci u32 tmp, frame_count; 35362306a36Sopenharmony_ci int i, j; 35462306a36Sopenharmony_ci 35562306a36Sopenharmony_ci /* update crtc base addresses */ 35662306a36Sopenharmony_ci for (i = 0; i < rdev->num_crtc; i++) { 35762306a36Sopenharmony_ci if (rdev->family >= CHIP_RV770) { 35862306a36Sopenharmony_ci if (i == 0) { 35962306a36Sopenharmony_ci WREG32(R700_D1GRPH_PRIMARY_SURFACE_ADDRESS_HIGH, 36062306a36Sopenharmony_ci upper_32_bits(rdev->mc.vram_start)); 36162306a36Sopenharmony_ci WREG32(R700_D1GRPH_SECONDARY_SURFACE_ADDRESS_HIGH, 36262306a36Sopenharmony_ci upper_32_bits(rdev->mc.vram_start)); 36362306a36Sopenharmony_ci } else { 36462306a36Sopenharmony_ci WREG32(R700_D2GRPH_PRIMARY_SURFACE_ADDRESS_HIGH, 36562306a36Sopenharmony_ci upper_32_bits(rdev->mc.vram_start)); 36662306a36Sopenharmony_ci WREG32(R700_D2GRPH_SECONDARY_SURFACE_ADDRESS_HIGH, 36762306a36Sopenharmony_ci upper_32_bits(rdev->mc.vram_start)); 36862306a36Sopenharmony_ci } 36962306a36Sopenharmony_ci } 37062306a36Sopenharmony_ci WREG32(R_006110_D1GRPH_PRIMARY_SURFACE_ADDRESS + crtc_offsets[i], 37162306a36Sopenharmony_ci (u32)rdev->mc.vram_start); 37262306a36Sopenharmony_ci WREG32(R_006118_D1GRPH_SECONDARY_SURFACE_ADDRESS + crtc_offsets[i], 37362306a36Sopenharmony_ci (u32)rdev->mc.vram_start); 37462306a36Sopenharmony_ci } 37562306a36Sopenharmony_ci WREG32(R_000310_VGA_MEMORY_BASE_ADDRESS, (u32)rdev->mc.vram_start); 37662306a36Sopenharmony_ci 37762306a36Sopenharmony_ci /* unlock regs and wait for update */ 37862306a36Sopenharmony_ci for (i = 0; i < rdev->num_crtc; i++) { 37962306a36Sopenharmony_ci if (save->crtc_enabled[i]) { 38062306a36Sopenharmony_ci tmp = RREG32(AVIVO_D1MODE_MASTER_UPDATE_MODE + crtc_offsets[i]); 38162306a36Sopenharmony_ci if ((tmp & 0x7) != 3) { 38262306a36Sopenharmony_ci tmp &= ~0x7; 38362306a36Sopenharmony_ci tmp |= 0x3; 38462306a36Sopenharmony_ci WREG32(AVIVO_D1MODE_MASTER_UPDATE_MODE + crtc_offsets[i], tmp); 38562306a36Sopenharmony_ci } 38662306a36Sopenharmony_ci tmp = RREG32(AVIVO_D1GRPH_UPDATE + crtc_offsets[i]); 38762306a36Sopenharmony_ci if (tmp & AVIVO_D1GRPH_UPDATE_LOCK) { 38862306a36Sopenharmony_ci tmp &= ~AVIVO_D1GRPH_UPDATE_LOCK; 38962306a36Sopenharmony_ci WREG32(AVIVO_D1GRPH_UPDATE + crtc_offsets[i], tmp); 39062306a36Sopenharmony_ci } 39162306a36Sopenharmony_ci tmp = RREG32(AVIVO_D1MODE_MASTER_UPDATE_LOCK + crtc_offsets[i]); 39262306a36Sopenharmony_ci if (tmp & 1) { 39362306a36Sopenharmony_ci tmp &= ~1; 39462306a36Sopenharmony_ci WREG32(AVIVO_D1MODE_MASTER_UPDATE_LOCK + crtc_offsets[i], tmp); 39562306a36Sopenharmony_ci } 39662306a36Sopenharmony_ci for (j = 0; j < rdev->usec_timeout; j++) { 39762306a36Sopenharmony_ci tmp = RREG32(AVIVO_D1GRPH_UPDATE + crtc_offsets[i]); 39862306a36Sopenharmony_ci if ((tmp & AVIVO_D1GRPH_SURFACE_UPDATE_PENDING) == 0) 39962306a36Sopenharmony_ci break; 40062306a36Sopenharmony_ci udelay(1); 40162306a36Sopenharmony_ci } 40262306a36Sopenharmony_ci } 40362306a36Sopenharmony_ci } 40462306a36Sopenharmony_ci 40562306a36Sopenharmony_ci if (rdev->family >= CHIP_R600) { 40662306a36Sopenharmony_ci /* unblackout the MC */ 40762306a36Sopenharmony_ci if (rdev->family >= CHIP_RV770) 40862306a36Sopenharmony_ci tmp = RREG32(R700_MC_CITF_CNTL); 40962306a36Sopenharmony_ci else 41062306a36Sopenharmony_ci tmp = RREG32(R600_CITF_CNTL); 41162306a36Sopenharmony_ci tmp &= ~R600_BLACKOUT_MASK; 41262306a36Sopenharmony_ci if (rdev->family >= CHIP_RV770) 41362306a36Sopenharmony_ci WREG32(R700_MC_CITF_CNTL, tmp); 41462306a36Sopenharmony_ci else 41562306a36Sopenharmony_ci WREG32(R600_CITF_CNTL, tmp); 41662306a36Sopenharmony_ci /* allow CPU access */ 41762306a36Sopenharmony_ci WREG32(R600_BIF_FB_EN, R600_FB_READ_EN | R600_FB_WRITE_EN); 41862306a36Sopenharmony_ci } 41962306a36Sopenharmony_ci 42062306a36Sopenharmony_ci for (i = 0; i < rdev->num_crtc; i++) { 42162306a36Sopenharmony_ci if (save->crtc_enabled[i]) { 42262306a36Sopenharmony_ci tmp = RREG32(AVIVO_D1CRTC_CONTROL + crtc_offsets[i]); 42362306a36Sopenharmony_ci tmp &= ~AVIVO_CRTC_DISP_READ_REQUEST_DISABLE; 42462306a36Sopenharmony_ci WREG32(AVIVO_D1CRTC_CONTROL + crtc_offsets[i], tmp); 42562306a36Sopenharmony_ci /* wait for the next frame */ 42662306a36Sopenharmony_ci frame_count = radeon_get_vblank_counter(rdev, i); 42762306a36Sopenharmony_ci for (j = 0; j < rdev->usec_timeout; j++) { 42862306a36Sopenharmony_ci if (radeon_get_vblank_counter(rdev, i) != frame_count) 42962306a36Sopenharmony_ci break; 43062306a36Sopenharmony_ci udelay(1); 43162306a36Sopenharmony_ci } 43262306a36Sopenharmony_ci } 43362306a36Sopenharmony_ci } 43462306a36Sopenharmony_ci /* Unlock vga access */ 43562306a36Sopenharmony_ci WREG32(R_000328_VGA_HDP_CONTROL, save->vga_hdp_control); 43662306a36Sopenharmony_ci mdelay(1); 43762306a36Sopenharmony_ci WREG32(R_000300_VGA_RENDER_CONTROL, save->vga_render_control); 43862306a36Sopenharmony_ci} 43962306a36Sopenharmony_ci 44062306a36Sopenharmony_cistatic void rv515_mc_program(struct radeon_device *rdev) 44162306a36Sopenharmony_ci{ 44262306a36Sopenharmony_ci struct rv515_mc_save save; 44362306a36Sopenharmony_ci 44462306a36Sopenharmony_ci /* Stops all mc clients */ 44562306a36Sopenharmony_ci rv515_mc_stop(rdev, &save); 44662306a36Sopenharmony_ci 44762306a36Sopenharmony_ci /* Wait for mc idle */ 44862306a36Sopenharmony_ci if (rv515_mc_wait_for_idle(rdev)) 44962306a36Sopenharmony_ci dev_warn(rdev->dev, "Wait MC idle timeout before updating MC.\n"); 45062306a36Sopenharmony_ci /* Write VRAM size in case we are limiting it */ 45162306a36Sopenharmony_ci WREG32(R_0000F8_CONFIG_MEMSIZE, rdev->mc.real_vram_size); 45262306a36Sopenharmony_ci /* Program MC, should be a 32bits limited address space */ 45362306a36Sopenharmony_ci WREG32_MC(R_000001_MC_FB_LOCATION, 45462306a36Sopenharmony_ci S_000001_MC_FB_START(rdev->mc.vram_start >> 16) | 45562306a36Sopenharmony_ci S_000001_MC_FB_TOP(rdev->mc.vram_end >> 16)); 45662306a36Sopenharmony_ci WREG32(R_000134_HDP_FB_LOCATION, 45762306a36Sopenharmony_ci S_000134_HDP_FB_START(rdev->mc.vram_start >> 16)); 45862306a36Sopenharmony_ci if (rdev->flags & RADEON_IS_AGP) { 45962306a36Sopenharmony_ci WREG32_MC(R_000002_MC_AGP_LOCATION, 46062306a36Sopenharmony_ci S_000002_MC_AGP_START(rdev->mc.gtt_start >> 16) | 46162306a36Sopenharmony_ci S_000002_MC_AGP_TOP(rdev->mc.gtt_end >> 16)); 46262306a36Sopenharmony_ci WREG32_MC(R_000003_MC_AGP_BASE, lower_32_bits(rdev->mc.agp_base)); 46362306a36Sopenharmony_ci WREG32_MC(R_000004_MC_AGP_BASE_2, 46462306a36Sopenharmony_ci S_000004_AGP_BASE_ADDR_2(upper_32_bits(rdev->mc.agp_base))); 46562306a36Sopenharmony_ci } else { 46662306a36Sopenharmony_ci WREG32_MC(R_000002_MC_AGP_LOCATION, 0xFFFFFFFF); 46762306a36Sopenharmony_ci WREG32_MC(R_000003_MC_AGP_BASE, 0); 46862306a36Sopenharmony_ci WREG32_MC(R_000004_MC_AGP_BASE_2, 0); 46962306a36Sopenharmony_ci } 47062306a36Sopenharmony_ci 47162306a36Sopenharmony_ci rv515_mc_resume(rdev, &save); 47262306a36Sopenharmony_ci} 47362306a36Sopenharmony_ci 47462306a36Sopenharmony_civoid rv515_clock_startup(struct radeon_device *rdev) 47562306a36Sopenharmony_ci{ 47662306a36Sopenharmony_ci if (radeon_dynclks != -1 && radeon_dynclks) 47762306a36Sopenharmony_ci radeon_atom_set_clock_gating(rdev, 1); 47862306a36Sopenharmony_ci /* We need to force on some of the block */ 47962306a36Sopenharmony_ci WREG32_PLL(R_00000F_CP_DYN_CNTL, 48062306a36Sopenharmony_ci RREG32_PLL(R_00000F_CP_DYN_CNTL) | S_00000F_CP_FORCEON(1)); 48162306a36Sopenharmony_ci WREG32_PLL(R_000011_E2_DYN_CNTL, 48262306a36Sopenharmony_ci RREG32_PLL(R_000011_E2_DYN_CNTL) | S_000011_E2_FORCEON(1)); 48362306a36Sopenharmony_ci WREG32_PLL(R_000013_IDCT_DYN_CNTL, 48462306a36Sopenharmony_ci RREG32_PLL(R_000013_IDCT_DYN_CNTL) | S_000013_IDCT_FORCEON(1)); 48562306a36Sopenharmony_ci} 48662306a36Sopenharmony_ci 48762306a36Sopenharmony_cistatic int rv515_startup(struct radeon_device *rdev) 48862306a36Sopenharmony_ci{ 48962306a36Sopenharmony_ci int r; 49062306a36Sopenharmony_ci 49162306a36Sopenharmony_ci rv515_mc_program(rdev); 49262306a36Sopenharmony_ci /* Resume clock */ 49362306a36Sopenharmony_ci rv515_clock_startup(rdev); 49462306a36Sopenharmony_ci /* Initialize GPU configuration (# pipes, ...) */ 49562306a36Sopenharmony_ci rv515_gpu_init(rdev); 49662306a36Sopenharmony_ci /* Initialize GART (initialize after TTM so we can allocate 49762306a36Sopenharmony_ci * memory through TTM but finalize after TTM) */ 49862306a36Sopenharmony_ci if (rdev->flags & RADEON_IS_PCIE) { 49962306a36Sopenharmony_ci r = rv370_pcie_gart_enable(rdev); 50062306a36Sopenharmony_ci if (r) 50162306a36Sopenharmony_ci return r; 50262306a36Sopenharmony_ci } 50362306a36Sopenharmony_ci 50462306a36Sopenharmony_ci /* allocate wb buffer */ 50562306a36Sopenharmony_ci r = radeon_wb_init(rdev); 50662306a36Sopenharmony_ci if (r) 50762306a36Sopenharmony_ci return r; 50862306a36Sopenharmony_ci 50962306a36Sopenharmony_ci r = radeon_fence_driver_start_ring(rdev, RADEON_RING_TYPE_GFX_INDEX); 51062306a36Sopenharmony_ci if (r) { 51162306a36Sopenharmony_ci dev_err(rdev->dev, "failed initializing CP fences (%d).\n", r); 51262306a36Sopenharmony_ci return r; 51362306a36Sopenharmony_ci } 51462306a36Sopenharmony_ci 51562306a36Sopenharmony_ci /* Enable IRQ */ 51662306a36Sopenharmony_ci if (!rdev->irq.installed) { 51762306a36Sopenharmony_ci r = radeon_irq_kms_init(rdev); 51862306a36Sopenharmony_ci if (r) 51962306a36Sopenharmony_ci return r; 52062306a36Sopenharmony_ci } 52162306a36Sopenharmony_ci 52262306a36Sopenharmony_ci rs600_irq_set(rdev); 52362306a36Sopenharmony_ci rdev->config.r300.hdp_cntl = RREG32(RADEON_HOST_PATH_CNTL); 52462306a36Sopenharmony_ci /* 1M ring buffer */ 52562306a36Sopenharmony_ci r = r100_cp_init(rdev, 1024 * 1024); 52662306a36Sopenharmony_ci if (r) { 52762306a36Sopenharmony_ci dev_err(rdev->dev, "failed initializing CP (%d).\n", r); 52862306a36Sopenharmony_ci return r; 52962306a36Sopenharmony_ci } 53062306a36Sopenharmony_ci 53162306a36Sopenharmony_ci r = radeon_ib_pool_init(rdev); 53262306a36Sopenharmony_ci if (r) { 53362306a36Sopenharmony_ci dev_err(rdev->dev, "IB initialization failed (%d).\n", r); 53462306a36Sopenharmony_ci return r; 53562306a36Sopenharmony_ci } 53662306a36Sopenharmony_ci 53762306a36Sopenharmony_ci return 0; 53862306a36Sopenharmony_ci} 53962306a36Sopenharmony_ci 54062306a36Sopenharmony_ciint rv515_resume(struct radeon_device *rdev) 54162306a36Sopenharmony_ci{ 54262306a36Sopenharmony_ci int r; 54362306a36Sopenharmony_ci 54462306a36Sopenharmony_ci /* Make sur GART are not working */ 54562306a36Sopenharmony_ci if (rdev->flags & RADEON_IS_PCIE) 54662306a36Sopenharmony_ci rv370_pcie_gart_disable(rdev); 54762306a36Sopenharmony_ci /* Resume clock before doing reset */ 54862306a36Sopenharmony_ci rv515_clock_startup(rdev); 54962306a36Sopenharmony_ci /* Reset gpu before posting otherwise ATOM will enter infinite loop */ 55062306a36Sopenharmony_ci if (radeon_asic_reset(rdev)) { 55162306a36Sopenharmony_ci dev_warn(rdev->dev, "GPU reset failed ! (0xE40=0x%08X, 0x7C0=0x%08X)\n", 55262306a36Sopenharmony_ci RREG32(R_000E40_RBBM_STATUS), 55362306a36Sopenharmony_ci RREG32(R_0007C0_CP_STAT)); 55462306a36Sopenharmony_ci } 55562306a36Sopenharmony_ci /* post */ 55662306a36Sopenharmony_ci atom_asic_init(rdev->mode_info.atom_context); 55762306a36Sopenharmony_ci /* Resume clock after posting */ 55862306a36Sopenharmony_ci rv515_clock_startup(rdev); 55962306a36Sopenharmony_ci /* Initialize surface registers */ 56062306a36Sopenharmony_ci radeon_surface_init(rdev); 56162306a36Sopenharmony_ci 56262306a36Sopenharmony_ci rdev->accel_working = true; 56362306a36Sopenharmony_ci r = rv515_startup(rdev); 56462306a36Sopenharmony_ci if (r) { 56562306a36Sopenharmony_ci rdev->accel_working = false; 56662306a36Sopenharmony_ci } 56762306a36Sopenharmony_ci return r; 56862306a36Sopenharmony_ci} 56962306a36Sopenharmony_ci 57062306a36Sopenharmony_ciint rv515_suspend(struct radeon_device *rdev) 57162306a36Sopenharmony_ci{ 57262306a36Sopenharmony_ci radeon_pm_suspend(rdev); 57362306a36Sopenharmony_ci r100_cp_disable(rdev); 57462306a36Sopenharmony_ci radeon_wb_disable(rdev); 57562306a36Sopenharmony_ci rs600_irq_disable(rdev); 57662306a36Sopenharmony_ci if (rdev->flags & RADEON_IS_PCIE) 57762306a36Sopenharmony_ci rv370_pcie_gart_disable(rdev); 57862306a36Sopenharmony_ci return 0; 57962306a36Sopenharmony_ci} 58062306a36Sopenharmony_ci 58162306a36Sopenharmony_civoid rv515_set_safe_registers(struct radeon_device *rdev) 58262306a36Sopenharmony_ci{ 58362306a36Sopenharmony_ci rdev->config.r300.reg_safe_bm = rv515_reg_safe_bm; 58462306a36Sopenharmony_ci rdev->config.r300.reg_safe_bm_size = ARRAY_SIZE(rv515_reg_safe_bm); 58562306a36Sopenharmony_ci} 58662306a36Sopenharmony_ci 58762306a36Sopenharmony_civoid rv515_fini(struct radeon_device *rdev) 58862306a36Sopenharmony_ci{ 58962306a36Sopenharmony_ci radeon_pm_fini(rdev); 59062306a36Sopenharmony_ci r100_cp_fini(rdev); 59162306a36Sopenharmony_ci radeon_wb_fini(rdev); 59262306a36Sopenharmony_ci radeon_ib_pool_fini(rdev); 59362306a36Sopenharmony_ci radeon_gem_fini(rdev); 59462306a36Sopenharmony_ci rv370_pcie_gart_fini(rdev); 59562306a36Sopenharmony_ci radeon_agp_fini(rdev); 59662306a36Sopenharmony_ci radeon_irq_kms_fini(rdev); 59762306a36Sopenharmony_ci radeon_fence_driver_fini(rdev); 59862306a36Sopenharmony_ci radeon_bo_fini(rdev); 59962306a36Sopenharmony_ci radeon_atombios_fini(rdev); 60062306a36Sopenharmony_ci kfree(rdev->bios); 60162306a36Sopenharmony_ci rdev->bios = NULL; 60262306a36Sopenharmony_ci} 60362306a36Sopenharmony_ci 60462306a36Sopenharmony_ciint rv515_init(struct radeon_device *rdev) 60562306a36Sopenharmony_ci{ 60662306a36Sopenharmony_ci int r; 60762306a36Sopenharmony_ci 60862306a36Sopenharmony_ci /* Initialize scratch registers */ 60962306a36Sopenharmony_ci radeon_scratch_init(rdev); 61062306a36Sopenharmony_ci /* Initialize surface registers */ 61162306a36Sopenharmony_ci radeon_surface_init(rdev); 61262306a36Sopenharmony_ci /* TODO: disable VGA need to use VGA request */ 61362306a36Sopenharmony_ci /* restore some register to sane defaults */ 61462306a36Sopenharmony_ci r100_restore_sanity(rdev); 61562306a36Sopenharmony_ci /* BIOS*/ 61662306a36Sopenharmony_ci if (!radeon_get_bios(rdev)) { 61762306a36Sopenharmony_ci if (ASIC_IS_AVIVO(rdev)) 61862306a36Sopenharmony_ci return -EINVAL; 61962306a36Sopenharmony_ci } 62062306a36Sopenharmony_ci if (rdev->is_atom_bios) { 62162306a36Sopenharmony_ci r = radeon_atombios_init(rdev); 62262306a36Sopenharmony_ci if (r) 62362306a36Sopenharmony_ci return r; 62462306a36Sopenharmony_ci } else { 62562306a36Sopenharmony_ci dev_err(rdev->dev, "Expecting atombios for RV515 GPU\n"); 62662306a36Sopenharmony_ci return -EINVAL; 62762306a36Sopenharmony_ci } 62862306a36Sopenharmony_ci /* Reset gpu before posting otherwise ATOM will enter infinite loop */ 62962306a36Sopenharmony_ci if (radeon_asic_reset(rdev)) { 63062306a36Sopenharmony_ci dev_warn(rdev->dev, 63162306a36Sopenharmony_ci "GPU reset failed ! (0xE40=0x%08X, 0x7C0=0x%08X)\n", 63262306a36Sopenharmony_ci RREG32(R_000E40_RBBM_STATUS), 63362306a36Sopenharmony_ci RREG32(R_0007C0_CP_STAT)); 63462306a36Sopenharmony_ci } 63562306a36Sopenharmony_ci /* check if cards are posted or not */ 63662306a36Sopenharmony_ci if (radeon_boot_test_post_card(rdev) == false) 63762306a36Sopenharmony_ci return -EINVAL; 63862306a36Sopenharmony_ci /* Initialize clocks */ 63962306a36Sopenharmony_ci radeon_get_clock_info(rdev->ddev); 64062306a36Sopenharmony_ci /* initialize AGP */ 64162306a36Sopenharmony_ci if (rdev->flags & RADEON_IS_AGP) { 64262306a36Sopenharmony_ci r = radeon_agp_init(rdev); 64362306a36Sopenharmony_ci if (r) { 64462306a36Sopenharmony_ci radeon_agp_disable(rdev); 64562306a36Sopenharmony_ci } 64662306a36Sopenharmony_ci } 64762306a36Sopenharmony_ci /* initialize memory controller */ 64862306a36Sopenharmony_ci rv515_mc_init(rdev); 64962306a36Sopenharmony_ci rv515_debugfs(rdev); 65062306a36Sopenharmony_ci /* Fence driver */ 65162306a36Sopenharmony_ci radeon_fence_driver_init(rdev); 65262306a36Sopenharmony_ci /* Memory manager */ 65362306a36Sopenharmony_ci r = radeon_bo_init(rdev); 65462306a36Sopenharmony_ci if (r) 65562306a36Sopenharmony_ci return r; 65662306a36Sopenharmony_ci r = rv370_pcie_gart_init(rdev); 65762306a36Sopenharmony_ci if (r) 65862306a36Sopenharmony_ci return r; 65962306a36Sopenharmony_ci rv515_set_safe_registers(rdev); 66062306a36Sopenharmony_ci 66162306a36Sopenharmony_ci /* Initialize power management */ 66262306a36Sopenharmony_ci radeon_pm_init(rdev); 66362306a36Sopenharmony_ci 66462306a36Sopenharmony_ci rdev->accel_working = true; 66562306a36Sopenharmony_ci r = rv515_startup(rdev); 66662306a36Sopenharmony_ci if (r) { 66762306a36Sopenharmony_ci /* Somethings want wront with the accel init stop accel */ 66862306a36Sopenharmony_ci dev_err(rdev->dev, "Disabling GPU acceleration\n"); 66962306a36Sopenharmony_ci r100_cp_fini(rdev); 67062306a36Sopenharmony_ci radeon_wb_fini(rdev); 67162306a36Sopenharmony_ci radeon_ib_pool_fini(rdev); 67262306a36Sopenharmony_ci radeon_irq_kms_fini(rdev); 67362306a36Sopenharmony_ci rv370_pcie_gart_fini(rdev); 67462306a36Sopenharmony_ci radeon_agp_fini(rdev); 67562306a36Sopenharmony_ci rdev->accel_working = false; 67662306a36Sopenharmony_ci } 67762306a36Sopenharmony_ci return 0; 67862306a36Sopenharmony_ci} 67962306a36Sopenharmony_ci 68062306a36Sopenharmony_civoid atom_rv515_force_tv_scaler(struct radeon_device *rdev, struct radeon_crtc *crtc) 68162306a36Sopenharmony_ci{ 68262306a36Sopenharmony_ci int index_reg = 0x6578 + crtc->crtc_offset; 68362306a36Sopenharmony_ci int data_reg = 0x657c + crtc->crtc_offset; 68462306a36Sopenharmony_ci 68562306a36Sopenharmony_ci WREG32(0x659C + crtc->crtc_offset, 0x0); 68662306a36Sopenharmony_ci WREG32(0x6594 + crtc->crtc_offset, 0x705); 68762306a36Sopenharmony_ci WREG32(0x65A4 + crtc->crtc_offset, 0x10001); 68862306a36Sopenharmony_ci WREG32(0x65D8 + crtc->crtc_offset, 0x0); 68962306a36Sopenharmony_ci WREG32(0x65B0 + crtc->crtc_offset, 0x0); 69062306a36Sopenharmony_ci WREG32(0x65C0 + crtc->crtc_offset, 0x0); 69162306a36Sopenharmony_ci WREG32(0x65D4 + crtc->crtc_offset, 0x0); 69262306a36Sopenharmony_ci WREG32(index_reg, 0x0); 69362306a36Sopenharmony_ci WREG32(data_reg, 0x841880A8); 69462306a36Sopenharmony_ci WREG32(index_reg, 0x1); 69562306a36Sopenharmony_ci WREG32(data_reg, 0x84208680); 69662306a36Sopenharmony_ci WREG32(index_reg, 0x2); 69762306a36Sopenharmony_ci WREG32(data_reg, 0xBFF880B0); 69862306a36Sopenharmony_ci WREG32(index_reg, 0x100); 69962306a36Sopenharmony_ci WREG32(data_reg, 0x83D88088); 70062306a36Sopenharmony_ci WREG32(index_reg, 0x101); 70162306a36Sopenharmony_ci WREG32(data_reg, 0x84608680); 70262306a36Sopenharmony_ci WREG32(index_reg, 0x102); 70362306a36Sopenharmony_ci WREG32(data_reg, 0xBFF080D0); 70462306a36Sopenharmony_ci WREG32(index_reg, 0x200); 70562306a36Sopenharmony_ci WREG32(data_reg, 0x83988068); 70662306a36Sopenharmony_ci WREG32(index_reg, 0x201); 70762306a36Sopenharmony_ci WREG32(data_reg, 0x84A08680); 70862306a36Sopenharmony_ci WREG32(index_reg, 0x202); 70962306a36Sopenharmony_ci WREG32(data_reg, 0xBFF080F8); 71062306a36Sopenharmony_ci WREG32(index_reg, 0x300); 71162306a36Sopenharmony_ci WREG32(data_reg, 0x83588058); 71262306a36Sopenharmony_ci WREG32(index_reg, 0x301); 71362306a36Sopenharmony_ci WREG32(data_reg, 0x84E08660); 71462306a36Sopenharmony_ci WREG32(index_reg, 0x302); 71562306a36Sopenharmony_ci WREG32(data_reg, 0xBFF88120); 71662306a36Sopenharmony_ci WREG32(index_reg, 0x400); 71762306a36Sopenharmony_ci WREG32(data_reg, 0x83188040); 71862306a36Sopenharmony_ci WREG32(index_reg, 0x401); 71962306a36Sopenharmony_ci WREG32(data_reg, 0x85008660); 72062306a36Sopenharmony_ci WREG32(index_reg, 0x402); 72162306a36Sopenharmony_ci WREG32(data_reg, 0xBFF88150); 72262306a36Sopenharmony_ci WREG32(index_reg, 0x500); 72362306a36Sopenharmony_ci WREG32(data_reg, 0x82D88030); 72462306a36Sopenharmony_ci WREG32(index_reg, 0x501); 72562306a36Sopenharmony_ci WREG32(data_reg, 0x85408640); 72662306a36Sopenharmony_ci WREG32(index_reg, 0x502); 72762306a36Sopenharmony_ci WREG32(data_reg, 0xBFF88180); 72862306a36Sopenharmony_ci WREG32(index_reg, 0x600); 72962306a36Sopenharmony_ci WREG32(data_reg, 0x82A08018); 73062306a36Sopenharmony_ci WREG32(index_reg, 0x601); 73162306a36Sopenharmony_ci WREG32(data_reg, 0x85808620); 73262306a36Sopenharmony_ci WREG32(index_reg, 0x602); 73362306a36Sopenharmony_ci WREG32(data_reg, 0xBFF081B8); 73462306a36Sopenharmony_ci WREG32(index_reg, 0x700); 73562306a36Sopenharmony_ci WREG32(data_reg, 0x82608010); 73662306a36Sopenharmony_ci WREG32(index_reg, 0x701); 73762306a36Sopenharmony_ci WREG32(data_reg, 0x85A08600); 73862306a36Sopenharmony_ci WREG32(index_reg, 0x702); 73962306a36Sopenharmony_ci WREG32(data_reg, 0x800081F0); 74062306a36Sopenharmony_ci WREG32(index_reg, 0x800); 74162306a36Sopenharmony_ci WREG32(data_reg, 0x8228BFF8); 74262306a36Sopenharmony_ci WREG32(index_reg, 0x801); 74362306a36Sopenharmony_ci WREG32(data_reg, 0x85E085E0); 74462306a36Sopenharmony_ci WREG32(index_reg, 0x802); 74562306a36Sopenharmony_ci WREG32(data_reg, 0xBFF88228); 74662306a36Sopenharmony_ci WREG32(index_reg, 0x10000); 74762306a36Sopenharmony_ci WREG32(data_reg, 0x82A8BF00); 74862306a36Sopenharmony_ci WREG32(index_reg, 0x10001); 74962306a36Sopenharmony_ci WREG32(data_reg, 0x82A08CC0); 75062306a36Sopenharmony_ci WREG32(index_reg, 0x10002); 75162306a36Sopenharmony_ci WREG32(data_reg, 0x8008BEF8); 75262306a36Sopenharmony_ci WREG32(index_reg, 0x10100); 75362306a36Sopenharmony_ci WREG32(data_reg, 0x81F0BF28); 75462306a36Sopenharmony_ci WREG32(index_reg, 0x10101); 75562306a36Sopenharmony_ci WREG32(data_reg, 0x83608CA0); 75662306a36Sopenharmony_ci WREG32(index_reg, 0x10102); 75762306a36Sopenharmony_ci WREG32(data_reg, 0x8018BED0); 75862306a36Sopenharmony_ci WREG32(index_reg, 0x10200); 75962306a36Sopenharmony_ci WREG32(data_reg, 0x8148BF38); 76062306a36Sopenharmony_ci WREG32(index_reg, 0x10201); 76162306a36Sopenharmony_ci WREG32(data_reg, 0x84408C80); 76262306a36Sopenharmony_ci WREG32(index_reg, 0x10202); 76362306a36Sopenharmony_ci WREG32(data_reg, 0x8008BEB8); 76462306a36Sopenharmony_ci WREG32(index_reg, 0x10300); 76562306a36Sopenharmony_ci WREG32(data_reg, 0x80B0BF78); 76662306a36Sopenharmony_ci WREG32(index_reg, 0x10301); 76762306a36Sopenharmony_ci WREG32(data_reg, 0x85008C20); 76862306a36Sopenharmony_ci WREG32(index_reg, 0x10302); 76962306a36Sopenharmony_ci WREG32(data_reg, 0x8020BEA0); 77062306a36Sopenharmony_ci WREG32(index_reg, 0x10400); 77162306a36Sopenharmony_ci WREG32(data_reg, 0x8028BF90); 77262306a36Sopenharmony_ci WREG32(index_reg, 0x10401); 77362306a36Sopenharmony_ci WREG32(data_reg, 0x85E08BC0); 77462306a36Sopenharmony_ci WREG32(index_reg, 0x10402); 77562306a36Sopenharmony_ci WREG32(data_reg, 0x8018BE90); 77662306a36Sopenharmony_ci WREG32(index_reg, 0x10500); 77762306a36Sopenharmony_ci WREG32(data_reg, 0xBFB8BFB0); 77862306a36Sopenharmony_ci WREG32(index_reg, 0x10501); 77962306a36Sopenharmony_ci WREG32(data_reg, 0x86C08B40); 78062306a36Sopenharmony_ci WREG32(index_reg, 0x10502); 78162306a36Sopenharmony_ci WREG32(data_reg, 0x8010BE90); 78262306a36Sopenharmony_ci WREG32(index_reg, 0x10600); 78362306a36Sopenharmony_ci WREG32(data_reg, 0xBF58BFC8); 78462306a36Sopenharmony_ci WREG32(index_reg, 0x10601); 78562306a36Sopenharmony_ci WREG32(data_reg, 0x87A08AA0); 78662306a36Sopenharmony_ci WREG32(index_reg, 0x10602); 78762306a36Sopenharmony_ci WREG32(data_reg, 0x8010BE98); 78862306a36Sopenharmony_ci WREG32(index_reg, 0x10700); 78962306a36Sopenharmony_ci WREG32(data_reg, 0xBF10BFF0); 79062306a36Sopenharmony_ci WREG32(index_reg, 0x10701); 79162306a36Sopenharmony_ci WREG32(data_reg, 0x886089E0); 79262306a36Sopenharmony_ci WREG32(index_reg, 0x10702); 79362306a36Sopenharmony_ci WREG32(data_reg, 0x8018BEB0); 79462306a36Sopenharmony_ci WREG32(index_reg, 0x10800); 79562306a36Sopenharmony_ci WREG32(data_reg, 0xBED8BFE8); 79662306a36Sopenharmony_ci WREG32(index_reg, 0x10801); 79762306a36Sopenharmony_ci WREG32(data_reg, 0x89408940); 79862306a36Sopenharmony_ci WREG32(index_reg, 0x10802); 79962306a36Sopenharmony_ci WREG32(data_reg, 0xBFE8BED8); 80062306a36Sopenharmony_ci WREG32(index_reg, 0x20000); 80162306a36Sopenharmony_ci WREG32(data_reg, 0x80008000); 80262306a36Sopenharmony_ci WREG32(index_reg, 0x20001); 80362306a36Sopenharmony_ci WREG32(data_reg, 0x90008000); 80462306a36Sopenharmony_ci WREG32(index_reg, 0x20002); 80562306a36Sopenharmony_ci WREG32(data_reg, 0x80008000); 80662306a36Sopenharmony_ci WREG32(index_reg, 0x20003); 80762306a36Sopenharmony_ci WREG32(data_reg, 0x80008000); 80862306a36Sopenharmony_ci WREG32(index_reg, 0x20100); 80962306a36Sopenharmony_ci WREG32(data_reg, 0x80108000); 81062306a36Sopenharmony_ci WREG32(index_reg, 0x20101); 81162306a36Sopenharmony_ci WREG32(data_reg, 0x8FE0BF70); 81262306a36Sopenharmony_ci WREG32(index_reg, 0x20102); 81362306a36Sopenharmony_ci WREG32(data_reg, 0xBFE880C0); 81462306a36Sopenharmony_ci WREG32(index_reg, 0x20103); 81562306a36Sopenharmony_ci WREG32(data_reg, 0x80008000); 81662306a36Sopenharmony_ci WREG32(index_reg, 0x20200); 81762306a36Sopenharmony_ci WREG32(data_reg, 0x8018BFF8); 81862306a36Sopenharmony_ci WREG32(index_reg, 0x20201); 81962306a36Sopenharmony_ci WREG32(data_reg, 0x8F80BF08); 82062306a36Sopenharmony_ci WREG32(index_reg, 0x20202); 82162306a36Sopenharmony_ci WREG32(data_reg, 0xBFD081A0); 82262306a36Sopenharmony_ci WREG32(index_reg, 0x20203); 82362306a36Sopenharmony_ci WREG32(data_reg, 0xBFF88000); 82462306a36Sopenharmony_ci WREG32(index_reg, 0x20300); 82562306a36Sopenharmony_ci WREG32(data_reg, 0x80188000); 82662306a36Sopenharmony_ci WREG32(index_reg, 0x20301); 82762306a36Sopenharmony_ci WREG32(data_reg, 0x8EE0BEC0); 82862306a36Sopenharmony_ci WREG32(index_reg, 0x20302); 82962306a36Sopenharmony_ci WREG32(data_reg, 0xBFB082A0); 83062306a36Sopenharmony_ci WREG32(index_reg, 0x20303); 83162306a36Sopenharmony_ci WREG32(data_reg, 0x80008000); 83262306a36Sopenharmony_ci WREG32(index_reg, 0x20400); 83362306a36Sopenharmony_ci WREG32(data_reg, 0x80188000); 83462306a36Sopenharmony_ci WREG32(index_reg, 0x20401); 83562306a36Sopenharmony_ci WREG32(data_reg, 0x8E00BEA0); 83662306a36Sopenharmony_ci WREG32(index_reg, 0x20402); 83762306a36Sopenharmony_ci WREG32(data_reg, 0xBF8883C0); 83862306a36Sopenharmony_ci WREG32(index_reg, 0x20403); 83962306a36Sopenharmony_ci WREG32(data_reg, 0x80008000); 84062306a36Sopenharmony_ci WREG32(index_reg, 0x20500); 84162306a36Sopenharmony_ci WREG32(data_reg, 0x80188000); 84262306a36Sopenharmony_ci WREG32(index_reg, 0x20501); 84362306a36Sopenharmony_ci WREG32(data_reg, 0x8D00BE90); 84462306a36Sopenharmony_ci WREG32(index_reg, 0x20502); 84562306a36Sopenharmony_ci WREG32(data_reg, 0xBF588500); 84662306a36Sopenharmony_ci WREG32(index_reg, 0x20503); 84762306a36Sopenharmony_ci WREG32(data_reg, 0x80008008); 84862306a36Sopenharmony_ci WREG32(index_reg, 0x20600); 84962306a36Sopenharmony_ci WREG32(data_reg, 0x80188000); 85062306a36Sopenharmony_ci WREG32(index_reg, 0x20601); 85162306a36Sopenharmony_ci WREG32(data_reg, 0x8BC0BE98); 85262306a36Sopenharmony_ci WREG32(index_reg, 0x20602); 85362306a36Sopenharmony_ci WREG32(data_reg, 0xBF308660); 85462306a36Sopenharmony_ci WREG32(index_reg, 0x20603); 85562306a36Sopenharmony_ci WREG32(data_reg, 0x80008008); 85662306a36Sopenharmony_ci WREG32(index_reg, 0x20700); 85762306a36Sopenharmony_ci WREG32(data_reg, 0x80108000); 85862306a36Sopenharmony_ci WREG32(index_reg, 0x20701); 85962306a36Sopenharmony_ci WREG32(data_reg, 0x8A80BEB0); 86062306a36Sopenharmony_ci WREG32(index_reg, 0x20702); 86162306a36Sopenharmony_ci WREG32(data_reg, 0xBF0087C0); 86262306a36Sopenharmony_ci WREG32(index_reg, 0x20703); 86362306a36Sopenharmony_ci WREG32(data_reg, 0x80008008); 86462306a36Sopenharmony_ci WREG32(index_reg, 0x20800); 86562306a36Sopenharmony_ci WREG32(data_reg, 0x80108000); 86662306a36Sopenharmony_ci WREG32(index_reg, 0x20801); 86762306a36Sopenharmony_ci WREG32(data_reg, 0x8920BED0); 86862306a36Sopenharmony_ci WREG32(index_reg, 0x20802); 86962306a36Sopenharmony_ci WREG32(data_reg, 0xBED08920); 87062306a36Sopenharmony_ci WREG32(index_reg, 0x20803); 87162306a36Sopenharmony_ci WREG32(data_reg, 0x80008010); 87262306a36Sopenharmony_ci WREG32(index_reg, 0x30000); 87362306a36Sopenharmony_ci WREG32(data_reg, 0x90008000); 87462306a36Sopenharmony_ci WREG32(index_reg, 0x30001); 87562306a36Sopenharmony_ci WREG32(data_reg, 0x80008000); 87662306a36Sopenharmony_ci WREG32(index_reg, 0x30100); 87762306a36Sopenharmony_ci WREG32(data_reg, 0x8FE0BF90); 87862306a36Sopenharmony_ci WREG32(index_reg, 0x30101); 87962306a36Sopenharmony_ci WREG32(data_reg, 0xBFF880A0); 88062306a36Sopenharmony_ci WREG32(index_reg, 0x30200); 88162306a36Sopenharmony_ci WREG32(data_reg, 0x8F60BF40); 88262306a36Sopenharmony_ci WREG32(index_reg, 0x30201); 88362306a36Sopenharmony_ci WREG32(data_reg, 0xBFE88180); 88462306a36Sopenharmony_ci WREG32(index_reg, 0x30300); 88562306a36Sopenharmony_ci WREG32(data_reg, 0x8EC0BF00); 88662306a36Sopenharmony_ci WREG32(index_reg, 0x30301); 88762306a36Sopenharmony_ci WREG32(data_reg, 0xBFC88280); 88862306a36Sopenharmony_ci WREG32(index_reg, 0x30400); 88962306a36Sopenharmony_ci WREG32(data_reg, 0x8DE0BEE0); 89062306a36Sopenharmony_ci WREG32(index_reg, 0x30401); 89162306a36Sopenharmony_ci WREG32(data_reg, 0xBFA083A0); 89262306a36Sopenharmony_ci WREG32(index_reg, 0x30500); 89362306a36Sopenharmony_ci WREG32(data_reg, 0x8CE0BED0); 89462306a36Sopenharmony_ci WREG32(index_reg, 0x30501); 89562306a36Sopenharmony_ci WREG32(data_reg, 0xBF7884E0); 89662306a36Sopenharmony_ci WREG32(index_reg, 0x30600); 89762306a36Sopenharmony_ci WREG32(data_reg, 0x8BA0BED8); 89862306a36Sopenharmony_ci WREG32(index_reg, 0x30601); 89962306a36Sopenharmony_ci WREG32(data_reg, 0xBF508640); 90062306a36Sopenharmony_ci WREG32(index_reg, 0x30700); 90162306a36Sopenharmony_ci WREG32(data_reg, 0x8A60BEE8); 90262306a36Sopenharmony_ci WREG32(index_reg, 0x30701); 90362306a36Sopenharmony_ci WREG32(data_reg, 0xBF2087A0); 90462306a36Sopenharmony_ci WREG32(index_reg, 0x30800); 90562306a36Sopenharmony_ci WREG32(data_reg, 0x8900BF00); 90662306a36Sopenharmony_ci WREG32(index_reg, 0x30801); 90762306a36Sopenharmony_ci WREG32(data_reg, 0xBF008900); 90862306a36Sopenharmony_ci} 90962306a36Sopenharmony_ci 91062306a36Sopenharmony_cistruct rv515_watermark { 91162306a36Sopenharmony_ci u32 lb_request_fifo_depth; 91262306a36Sopenharmony_ci fixed20_12 num_line_pair; 91362306a36Sopenharmony_ci fixed20_12 estimated_width; 91462306a36Sopenharmony_ci fixed20_12 worst_case_latency; 91562306a36Sopenharmony_ci fixed20_12 consumption_rate; 91662306a36Sopenharmony_ci fixed20_12 active_time; 91762306a36Sopenharmony_ci fixed20_12 dbpp; 91862306a36Sopenharmony_ci fixed20_12 priority_mark_max; 91962306a36Sopenharmony_ci fixed20_12 priority_mark; 92062306a36Sopenharmony_ci fixed20_12 sclk; 92162306a36Sopenharmony_ci}; 92262306a36Sopenharmony_ci 92362306a36Sopenharmony_cistatic void rv515_crtc_bandwidth_compute(struct radeon_device *rdev, 92462306a36Sopenharmony_ci struct radeon_crtc *crtc, 92562306a36Sopenharmony_ci struct rv515_watermark *wm, 92662306a36Sopenharmony_ci bool low) 92762306a36Sopenharmony_ci{ 92862306a36Sopenharmony_ci struct drm_display_mode *mode = &crtc->base.mode; 92962306a36Sopenharmony_ci fixed20_12 a, b, c; 93062306a36Sopenharmony_ci fixed20_12 pclk, request_fifo_depth, tolerable_latency, estimated_width; 93162306a36Sopenharmony_ci fixed20_12 consumption_time, line_time, chunk_time, read_delay_latency; 93262306a36Sopenharmony_ci fixed20_12 sclk; 93362306a36Sopenharmony_ci u32 selected_sclk; 93462306a36Sopenharmony_ci 93562306a36Sopenharmony_ci if (!crtc->base.enabled) { 93662306a36Sopenharmony_ci /* FIXME: wouldn't it better to set priority mark to maximum */ 93762306a36Sopenharmony_ci wm->lb_request_fifo_depth = 4; 93862306a36Sopenharmony_ci return; 93962306a36Sopenharmony_ci } 94062306a36Sopenharmony_ci 94162306a36Sopenharmony_ci /* rv6xx, rv7xx */ 94262306a36Sopenharmony_ci if ((rdev->family >= CHIP_RV610) && 94362306a36Sopenharmony_ci (rdev->pm.pm_method == PM_METHOD_DPM) && rdev->pm.dpm_enabled) 94462306a36Sopenharmony_ci selected_sclk = radeon_dpm_get_sclk(rdev, low); 94562306a36Sopenharmony_ci else 94662306a36Sopenharmony_ci selected_sclk = rdev->pm.current_sclk; 94762306a36Sopenharmony_ci 94862306a36Sopenharmony_ci /* sclk in Mhz */ 94962306a36Sopenharmony_ci a.full = dfixed_const(100); 95062306a36Sopenharmony_ci sclk.full = dfixed_const(selected_sclk); 95162306a36Sopenharmony_ci sclk.full = dfixed_div(sclk, a); 95262306a36Sopenharmony_ci 95362306a36Sopenharmony_ci if (crtc->vsc.full > dfixed_const(2)) 95462306a36Sopenharmony_ci wm->num_line_pair.full = dfixed_const(2); 95562306a36Sopenharmony_ci else 95662306a36Sopenharmony_ci wm->num_line_pair.full = dfixed_const(1); 95762306a36Sopenharmony_ci 95862306a36Sopenharmony_ci b.full = dfixed_const(mode->crtc_hdisplay); 95962306a36Sopenharmony_ci c.full = dfixed_const(256); 96062306a36Sopenharmony_ci a.full = dfixed_div(b, c); 96162306a36Sopenharmony_ci request_fifo_depth.full = dfixed_mul(a, wm->num_line_pair); 96262306a36Sopenharmony_ci request_fifo_depth.full = dfixed_ceil(request_fifo_depth); 96362306a36Sopenharmony_ci if (a.full < dfixed_const(4)) { 96462306a36Sopenharmony_ci wm->lb_request_fifo_depth = 4; 96562306a36Sopenharmony_ci } else { 96662306a36Sopenharmony_ci wm->lb_request_fifo_depth = dfixed_trunc(request_fifo_depth); 96762306a36Sopenharmony_ci } 96862306a36Sopenharmony_ci 96962306a36Sopenharmony_ci /* Determine consumption rate 97062306a36Sopenharmony_ci * pclk = pixel clock period(ns) = 1000 / (mode.clock / 1000) 97162306a36Sopenharmony_ci * vtaps = number of vertical taps, 97262306a36Sopenharmony_ci * vsc = vertical scaling ratio, defined as source/destination 97362306a36Sopenharmony_ci * hsc = horizontal scaling ration, defined as source/destination 97462306a36Sopenharmony_ci */ 97562306a36Sopenharmony_ci a.full = dfixed_const(mode->clock); 97662306a36Sopenharmony_ci b.full = dfixed_const(1000); 97762306a36Sopenharmony_ci a.full = dfixed_div(a, b); 97862306a36Sopenharmony_ci pclk.full = dfixed_div(b, a); 97962306a36Sopenharmony_ci if (crtc->rmx_type != RMX_OFF) { 98062306a36Sopenharmony_ci b.full = dfixed_const(2); 98162306a36Sopenharmony_ci if (crtc->vsc.full > b.full) 98262306a36Sopenharmony_ci b.full = crtc->vsc.full; 98362306a36Sopenharmony_ci b.full = dfixed_mul(b, crtc->hsc); 98462306a36Sopenharmony_ci c.full = dfixed_const(2); 98562306a36Sopenharmony_ci b.full = dfixed_div(b, c); 98662306a36Sopenharmony_ci consumption_time.full = dfixed_div(pclk, b); 98762306a36Sopenharmony_ci } else { 98862306a36Sopenharmony_ci consumption_time.full = pclk.full; 98962306a36Sopenharmony_ci } 99062306a36Sopenharmony_ci a.full = dfixed_const(1); 99162306a36Sopenharmony_ci wm->consumption_rate.full = dfixed_div(a, consumption_time); 99262306a36Sopenharmony_ci 99362306a36Sopenharmony_ci 99462306a36Sopenharmony_ci /* Determine line time 99562306a36Sopenharmony_ci * LineTime = total time for one line of displayhtotal 99662306a36Sopenharmony_ci * LineTime = total number of horizontal pixels 99762306a36Sopenharmony_ci * pclk = pixel clock period(ns) 99862306a36Sopenharmony_ci */ 99962306a36Sopenharmony_ci a.full = dfixed_const(crtc->base.mode.crtc_htotal); 100062306a36Sopenharmony_ci line_time.full = dfixed_mul(a, pclk); 100162306a36Sopenharmony_ci 100262306a36Sopenharmony_ci /* Determine active time 100362306a36Sopenharmony_ci * ActiveTime = time of active region of display within one line, 100462306a36Sopenharmony_ci * hactive = total number of horizontal active pixels 100562306a36Sopenharmony_ci * htotal = total number of horizontal pixels 100662306a36Sopenharmony_ci */ 100762306a36Sopenharmony_ci a.full = dfixed_const(crtc->base.mode.crtc_htotal); 100862306a36Sopenharmony_ci b.full = dfixed_const(crtc->base.mode.crtc_hdisplay); 100962306a36Sopenharmony_ci wm->active_time.full = dfixed_mul(line_time, b); 101062306a36Sopenharmony_ci wm->active_time.full = dfixed_div(wm->active_time, a); 101162306a36Sopenharmony_ci 101262306a36Sopenharmony_ci /* Determine chunk time 101362306a36Sopenharmony_ci * ChunkTime = the time it takes the DCP to send one chunk of data 101462306a36Sopenharmony_ci * to the LB which consists of pipeline delay and inter chunk gap 101562306a36Sopenharmony_ci * sclk = system clock(Mhz) 101662306a36Sopenharmony_ci */ 101762306a36Sopenharmony_ci a.full = dfixed_const(600 * 1000); 101862306a36Sopenharmony_ci chunk_time.full = dfixed_div(a, sclk); 101962306a36Sopenharmony_ci read_delay_latency.full = dfixed_const(1000); 102062306a36Sopenharmony_ci 102162306a36Sopenharmony_ci /* Determine the worst case latency 102262306a36Sopenharmony_ci * NumLinePair = Number of line pairs to request(1=2 lines, 2=4 lines) 102362306a36Sopenharmony_ci * WorstCaseLatency = worst case time from urgent to when the MC starts 102462306a36Sopenharmony_ci * to return data 102562306a36Sopenharmony_ci * READ_DELAY_IDLE_MAX = constant of 1us 102662306a36Sopenharmony_ci * ChunkTime = time it takes the DCP to send one chunk of data to the LB 102762306a36Sopenharmony_ci * which consists of pipeline delay and inter chunk gap 102862306a36Sopenharmony_ci */ 102962306a36Sopenharmony_ci if (dfixed_trunc(wm->num_line_pair) > 1) { 103062306a36Sopenharmony_ci a.full = dfixed_const(3); 103162306a36Sopenharmony_ci wm->worst_case_latency.full = dfixed_mul(a, chunk_time); 103262306a36Sopenharmony_ci wm->worst_case_latency.full += read_delay_latency.full; 103362306a36Sopenharmony_ci } else { 103462306a36Sopenharmony_ci wm->worst_case_latency.full = chunk_time.full + read_delay_latency.full; 103562306a36Sopenharmony_ci } 103662306a36Sopenharmony_ci 103762306a36Sopenharmony_ci /* Determine the tolerable latency 103862306a36Sopenharmony_ci * TolerableLatency = Any given request has only 1 line time 103962306a36Sopenharmony_ci * for the data to be returned 104062306a36Sopenharmony_ci * LBRequestFifoDepth = Number of chunk requests the LB can 104162306a36Sopenharmony_ci * put into the request FIFO for a display 104262306a36Sopenharmony_ci * LineTime = total time for one line of display 104362306a36Sopenharmony_ci * ChunkTime = the time it takes the DCP to send one chunk 104462306a36Sopenharmony_ci * of data to the LB which consists of 104562306a36Sopenharmony_ci * pipeline delay and inter chunk gap 104662306a36Sopenharmony_ci */ 104762306a36Sopenharmony_ci if ((2+wm->lb_request_fifo_depth) >= dfixed_trunc(request_fifo_depth)) { 104862306a36Sopenharmony_ci tolerable_latency.full = line_time.full; 104962306a36Sopenharmony_ci } else { 105062306a36Sopenharmony_ci tolerable_latency.full = dfixed_const(wm->lb_request_fifo_depth - 2); 105162306a36Sopenharmony_ci tolerable_latency.full = request_fifo_depth.full - tolerable_latency.full; 105262306a36Sopenharmony_ci tolerable_latency.full = dfixed_mul(tolerable_latency, chunk_time); 105362306a36Sopenharmony_ci tolerable_latency.full = line_time.full - tolerable_latency.full; 105462306a36Sopenharmony_ci } 105562306a36Sopenharmony_ci /* We assume worst case 32bits (4 bytes) */ 105662306a36Sopenharmony_ci wm->dbpp.full = dfixed_const(2 * 16); 105762306a36Sopenharmony_ci 105862306a36Sopenharmony_ci /* Determine the maximum priority mark 105962306a36Sopenharmony_ci * width = viewport width in pixels 106062306a36Sopenharmony_ci */ 106162306a36Sopenharmony_ci a.full = dfixed_const(16); 106262306a36Sopenharmony_ci wm->priority_mark_max.full = dfixed_const(crtc->base.mode.crtc_hdisplay); 106362306a36Sopenharmony_ci wm->priority_mark_max.full = dfixed_div(wm->priority_mark_max, a); 106462306a36Sopenharmony_ci wm->priority_mark_max.full = dfixed_ceil(wm->priority_mark_max); 106562306a36Sopenharmony_ci 106662306a36Sopenharmony_ci /* Determine estimated width */ 106762306a36Sopenharmony_ci estimated_width.full = tolerable_latency.full - wm->worst_case_latency.full; 106862306a36Sopenharmony_ci estimated_width.full = dfixed_div(estimated_width, consumption_time); 106962306a36Sopenharmony_ci if (dfixed_trunc(estimated_width) > crtc->base.mode.crtc_hdisplay) { 107062306a36Sopenharmony_ci wm->priority_mark.full = wm->priority_mark_max.full; 107162306a36Sopenharmony_ci } else { 107262306a36Sopenharmony_ci a.full = dfixed_const(16); 107362306a36Sopenharmony_ci wm->priority_mark.full = dfixed_div(estimated_width, a); 107462306a36Sopenharmony_ci wm->priority_mark.full = dfixed_ceil(wm->priority_mark); 107562306a36Sopenharmony_ci wm->priority_mark.full = wm->priority_mark_max.full - wm->priority_mark.full; 107662306a36Sopenharmony_ci } 107762306a36Sopenharmony_ci} 107862306a36Sopenharmony_ci 107962306a36Sopenharmony_cistatic void rv515_compute_mode_priority(struct radeon_device *rdev, 108062306a36Sopenharmony_ci struct rv515_watermark *wm0, 108162306a36Sopenharmony_ci struct rv515_watermark *wm1, 108262306a36Sopenharmony_ci struct drm_display_mode *mode0, 108362306a36Sopenharmony_ci struct drm_display_mode *mode1, 108462306a36Sopenharmony_ci u32 *d1mode_priority_a_cnt, 108562306a36Sopenharmony_ci u32 *d2mode_priority_a_cnt) 108662306a36Sopenharmony_ci{ 108762306a36Sopenharmony_ci fixed20_12 priority_mark02, priority_mark12, fill_rate; 108862306a36Sopenharmony_ci fixed20_12 a, b; 108962306a36Sopenharmony_ci 109062306a36Sopenharmony_ci *d1mode_priority_a_cnt = MODE_PRIORITY_OFF; 109162306a36Sopenharmony_ci *d2mode_priority_a_cnt = MODE_PRIORITY_OFF; 109262306a36Sopenharmony_ci 109362306a36Sopenharmony_ci if (mode0 && mode1) { 109462306a36Sopenharmony_ci if (dfixed_trunc(wm0->dbpp) > 64) 109562306a36Sopenharmony_ci a.full = dfixed_div(wm0->dbpp, wm0->num_line_pair); 109662306a36Sopenharmony_ci else 109762306a36Sopenharmony_ci a.full = wm0->num_line_pair.full; 109862306a36Sopenharmony_ci if (dfixed_trunc(wm1->dbpp) > 64) 109962306a36Sopenharmony_ci b.full = dfixed_div(wm1->dbpp, wm1->num_line_pair); 110062306a36Sopenharmony_ci else 110162306a36Sopenharmony_ci b.full = wm1->num_line_pair.full; 110262306a36Sopenharmony_ci a.full += b.full; 110362306a36Sopenharmony_ci fill_rate.full = dfixed_div(wm0->sclk, a); 110462306a36Sopenharmony_ci if (wm0->consumption_rate.full > fill_rate.full) { 110562306a36Sopenharmony_ci b.full = wm0->consumption_rate.full - fill_rate.full; 110662306a36Sopenharmony_ci b.full = dfixed_mul(b, wm0->active_time); 110762306a36Sopenharmony_ci a.full = dfixed_const(16); 110862306a36Sopenharmony_ci b.full = dfixed_div(b, a); 110962306a36Sopenharmony_ci a.full = dfixed_mul(wm0->worst_case_latency, 111062306a36Sopenharmony_ci wm0->consumption_rate); 111162306a36Sopenharmony_ci priority_mark02.full = a.full + b.full; 111262306a36Sopenharmony_ci } else { 111362306a36Sopenharmony_ci a.full = dfixed_mul(wm0->worst_case_latency, 111462306a36Sopenharmony_ci wm0->consumption_rate); 111562306a36Sopenharmony_ci b.full = dfixed_const(16 * 1000); 111662306a36Sopenharmony_ci priority_mark02.full = dfixed_div(a, b); 111762306a36Sopenharmony_ci } 111862306a36Sopenharmony_ci if (wm1->consumption_rate.full > fill_rate.full) { 111962306a36Sopenharmony_ci b.full = wm1->consumption_rate.full - fill_rate.full; 112062306a36Sopenharmony_ci b.full = dfixed_mul(b, wm1->active_time); 112162306a36Sopenharmony_ci a.full = dfixed_const(16); 112262306a36Sopenharmony_ci b.full = dfixed_div(b, a); 112362306a36Sopenharmony_ci a.full = dfixed_mul(wm1->worst_case_latency, 112462306a36Sopenharmony_ci wm1->consumption_rate); 112562306a36Sopenharmony_ci priority_mark12.full = a.full + b.full; 112662306a36Sopenharmony_ci } else { 112762306a36Sopenharmony_ci a.full = dfixed_mul(wm1->worst_case_latency, 112862306a36Sopenharmony_ci wm1->consumption_rate); 112962306a36Sopenharmony_ci b.full = dfixed_const(16 * 1000); 113062306a36Sopenharmony_ci priority_mark12.full = dfixed_div(a, b); 113162306a36Sopenharmony_ci } 113262306a36Sopenharmony_ci if (wm0->priority_mark.full > priority_mark02.full) 113362306a36Sopenharmony_ci priority_mark02.full = wm0->priority_mark.full; 113462306a36Sopenharmony_ci if (wm0->priority_mark_max.full > priority_mark02.full) 113562306a36Sopenharmony_ci priority_mark02.full = wm0->priority_mark_max.full; 113662306a36Sopenharmony_ci if (wm1->priority_mark.full > priority_mark12.full) 113762306a36Sopenharmony_ci priority_mark12.full = wm1->priority_mark.full; 113862306a36Sopenharmony_ci if (wm1->priority_mark_max.full > priority_mark12.full) 113962306a36Sopenharmony_ci priority_mark12.full = wm1->priority_mark_max.full; 114062306a36Sopenharmony_ci *d1mode_priority_a_cnt = dfixed_trunc(priority_mark02); 114162306a36Sopenharmony_ci *d2mode_priority_a_cnt = dfixed_trunc(priority_mark12); 114262306a36Sopenharmony_ci if (rdev->disp_priority == 2) { 114362306a36Sopenharmony_ci *d1mode_priority_a_cnt |= MODE_PRIORITY_ALWAYS_ON; 114462306a36Sopenharmony_ci *d2mode_priority_a_cnt |= MODE_PRIORITY_ALWAYS_ON; 114562306a36Sopenharmony_ci } 114662306a36Sopenharmony_ci } else if (mode0) { 114762306a36Sopenharmony_ci if (dfixed_trunc(wm0->dbpp) > 64) 114862306a36Sopenharmony_ci a.full = dfixed_div(wm0->dbpp, wm0->num_line_pair); 114962306a36Sopenharmony_ci else 115062306a36Sopenharmony_ci a.full = wm0->num_line_pair.full; 115162306a36Sopenharmony_ci fill_rate.full = dfixed_div(wm0->sclk, a); 115262306a36Sopenharmony_ci if (wm0->consumption_rate.full > fill_rate.full) { 115362306a36Sopenharmony_ci b.full = wm0->consumption_rate.full - fill_rate.full; 115462306a36Sopenharmony_ci b.full = dfixed_mul(b, wm0->active_time); 115562306a36Sopenharmony_ci a.full = dfixed_const(16); 115662306a36Sopenharmony_ci b.full = dfixed_div(b, a); 115762306a36Sopenharmony_ci a.full = dfixed_mul(wm0->worst_case_latency, 115862306a36Sopenharmony_ci wm0->consumption_rate); 115962306a36Sopenharmony_ci priority_mark02.full = a.full + b.full; 116062306a36Sopenharmony_ci } else { 116162306a36Sopenharmony_ci a.full = dfixed_mul(wm0->worst_case_latency, 116262306a36Sopenharmony_ci wm0->consumption_rate); 116362306a36Sopenharmony_ci b.full = dfixed_const(16); 116462306a36Sopenharmony_ci priority_mark02.full = dfixed_div(a, b); 116562306a36Sopenharmony_ci } 116662306a36Sopenharmony_ci if (wm0->priority_mark.full > priority_mark02.full) 116762306a36Sopenharmony_ci priority_mark02.full = wm0->priority_mark.full; 116862306a36Sopenharmony_ci if (wm0->priority_mark_max.full > priority_mark02.full) 116962306a36Sopenharmony_ci priority_mark02.full = wm0->priority_mark_max.full; 117062306a36Sopenharmony_ci *d1mode_priority_a_cnt = dfixed_trunc(priority_mark02); 117162306a36Sopenharmony_ci if (rdev->disp_priority == 2) 117262306a36Sopenharmony_ci *d1mode_priority_a_cnt |= MODE_PRIORITY_ALWAYS_ON; 117362306a36Sopenharmony_ci } else if (mode1) { 117462306a36Sopenharmony_ci if (dfixed_trunc(wm1->dbpp) > 64) 117562306a36Sopenharmony_ci a.full = dfixed_div(wm1->dbpp, wm1->num_line_pair); 117662306a36Sopenharmony_ci else 117762306a36Sopenharmony_ci a.full = wm1->num_line_pair.full; 117862306a36Sopenharmony_ci fill_rate.full = dfixed_div(wm1->sclk, a); 117962306a36Sopenharmony_ci if (wm1->consumption_rate.full > fill_rate.full) { 118062306a36Sopenharmony_ci b.full = wm1->consumption_rate.full - fill_rate.full; 118162306a36Sopenharmony_ci b.full = dfixed_mul(b, wm1->active_time); 118262306a36Sopenharmony_ci a.full = dfixed_const(16); 118362306a36Sopenharmony_ci b.full = dfixed_div(b, a); 118462306a36Sopenharmony_ci a.full = dfixed_mul(wm1->worst_case_latency, 118562306a36Sopenharmony_ci wm1->consumption_rate); 118662306a36Sopenharmony_ci priority_mark12.full = a.full + b.full; 118762306a36Sopenharmony_ci } else { 118862306a36Sopenharmony_ci a.full = dfixed_mul(wm1->worst_case_latency, 118962306a36Sopenharmony_ci wm1->consumption_rate); 119062306a36Sopenharmony_ci b.full = dfixed_const(16 * 1000); 119162306a36Sopenharmony_ci priority_mark12.full = dfixed_div(a, b); 119262306a36Sopenharmony_ci } 119362306a36Sopenharmony_ci if (wm1->priority_mark.full > priority_mark12.full) 119462306a36Sopenharmony_ci priority_mark12.full = wm1->priority_mark.full; 119562306a36Sopenharmony_ci if (wm1->priority_mark_max.full > priority_mark12.full) 119662306a36Sopenharmony_ci priority_mark12.full = wm1->priority_mark_max.full; 119762306a36Sopenharmony_ci *d2mode_priority_a_cnt = dfixed_trunc(priority_mark12); 119862306a36Sopenharmony_ci if (rdev->disp_priority == 2) 119962306a36Sopenharmony_ci *d2mode_priority_a_cnt |= MODE_PRIORITY_ALWAYS_ON; 120062306a36Sopenharmony_ci } 120162306a36Sopenharmony_ci} 120262306a36Sopenharmony_ci 120362306a36Sopenharmony_civoid rv515_bandwidth_avivo_update(struct radeon_device *rdev) 120462306a36Sopenharmony_ci{ 120562306a36Sopenharmony_ci struct drm_display_mode *mode0 = NULL; 120662306a36Sopenharmony_ci struct drm_display_mode *mode1 = NULL; 120762306a36Sopenharmony_ci struct rv515_watermark wm0_high, wm0_low; 120862306a36Sopenharmony_ci struct rv515_watermark wm1_high, wm1_low; 120962306a36Sopenharmony_ci u32 tmp; 121062306a36Sopenharmony_ci u32 d1mode_priority_a_cnt, d1mode_priority_b_cnt; 121162306a36Sopenharmony_ci u32 d2mode_priority_a_cnt, d2mode_priority_b_cnt; 121262306a36Sopenharmony_ci 121362306a36Sopenharmony_ci if (rdev->mode_info.crtcs[0]->base.enabled) 121462306a36Sopenharmony_ci mode0 = &rdev->mode_info.crtcs[0]->base.mode; 121562306a36Sopenharmony_ci if (rdev->mode_info.crtcs[1]->base.enabled) 121662306a36Sopenharmony_ci mode1 = &rdev->mode_info.crtcs[1]->base.mode; 121762306a36Sopenharmony_ci rs690_line_buffer_adjust(rdev, mode0, mode1); 121862306a36Sopenharmony_ci 121962306a36Sopenharmony_ci rv515_crtc_bandwidth_compute(rdev, rdev->mode_info.crtcs[0], &wm0_high, false); 122062306a36Sopenharmony_ci rv515_crtc_bandwidth_compute(rdev, rdev->mode_info.crtcs[1], &wm1_high, false); 122162306a36Sopenharmony_ci 122262306a36Sopenharmony_ci rv515_crtc_bandwidth_compute(rdev, rdev->mode_info.crtcs[0], &wm0_low, false); 122362306a36Sopenharmony_ci rv515_crtc_bandwidth_compute(rdev, rdev->mode_info.crtcs[1], &wm1_low, false); 122462306a36Sopenharmony_ci 122562306a36Sopenharmony_ci tmp = wm0_high.lb_request_fifo_depth; 122662306a36Sopenharmony_ci tmp |= wm1_high.lb_request_fifo_depth << 16; 122762306a36Sopenharmony_ci WREG32(LB_MAX_REQ_OUTSTANDING, tmp); 122862306a36Sopenharmony_ci 122962306a36Sopenharmony_ci rv515_compute_mode_priority(rdev, 123062306a36Sopenharmony_ci &wm0_high, &wm1_high, 123162306a36Sopenharmony_ci mode0, mode1, 123262306a36Sopenharmony_ci &d1mode_priority_a_cnt, &d2mode_priority_a_cnt); 123362306a36Sopenharmony_ci rv515_compute_mode_priority(rdev, 123462306a36Sopenharmony_ci &wm0_low, &wm1_low, 123562306a36Sopenharmony_ci mode0, mode1, 123662306a36Sopenharmony_ci &d1mode_priority_b_cnt, &d2mode_priority_b_cnt); 123762306a36Sopenharmony_ci 123862306a36Sopenharmony_ci WREG32(D1MODE_PRIORITY_A_CNT, d1mode_priority_a_cnt); 123962306a36Sopenharmony_ci WREG32(D1MODE_PRIORITY_B_CNT, d1mode_priority_b_cnt); 124062306a36Sopenharmony_ci WREG32(D2MODE_PRIORITY_A_CNT, d2mode_priority_a_cnt); 124162306a36Sopenharmony_ci WREG32(D2MODE_PRIORITY_B_CNT, d2mode_priority_b_cnt); 124262306a36Sopenharmony_ci} 124362306a36Sopenharmony_ci 124462306a36Sopenharmony_civoid rv515_bandwidth_update(struct radeon_device *rdev) 124562306a36Sopenharmony_ci{ 124662306a36Sopenharmony_ci uint32_t tmp; 124762306a36Sopenharmony_ci struct drm_display_mode *mode0 = NULL; 124862306a36Sopenharmony_ci struct drm_display_mode *mode1 = NULL; 124962306a36Sopenharmony_ci 125062306a36Sopenharmony_ci if (!rdev->mode_info.mode_config_initialized) 125162306a36Sopenharmony_ci return; 125262306a36Sopenharmony_ci 125362306a36Sopenharmony_ci radeon_update_display_priority(rdev); 125462306a36Sopenharmony_ci 125562306a36Sopenharmony_ci if (rdev->mode_info.crtcs[0]->base.enabled) 125662306a36Sopenharmony_ci mode0 = &rdev->mode_info.crtcs[0]->base.mode; 125762306a36Sopenharmony_ci if (rdev->mode_info.crtcs[1]->base.enabled) 125862306a36Sopenharmony_ci mode1 = &rdev->mode_info.crtcs[1]->base.mode; 125962306a36Sopenharmony_ci /* 126062306a36Sopenharmony_ci * Set display0/1 priority up in the memory controller for 126162306a36Sopenharmony_ci * modes if the user specifies HIGH for displaypriority 126262306a36Sopenharmony_ci * option. 126362306a36Sopenharmony_ci */ 126462306a36Sopenharmony_ci if ((rdev->disp_priority == 2) && 126562306a36Sopenharmony_ci (rdev->family == CHIP_RV515)) { 126662306a36Sopenharmony_ci tmp = RREG32_MC(MC_MISC_LAT_TIMER); 126762306a36Sopenharmony_ci tmp &= ~MC_DISP1R_INIT_LAT_MASK; 126862306a36Sopenharmony_ci tmp &= ~MC_DISP0R_INIT_LAT_MASK; 126962306a36Sopenharmony_ci if (mode1) 127062306a36Sopenharmony_ci tmp |= (1 << MC_DISP1R_INIT_LAT_SHIFT); 127162306a36Sopenharmony_ci if (mode0) 127262306a36Sopenharmony_ci tmp |= (1 << MC_DISP0R_INIT_LAT_SHIFT); 127362306a36Sopenharmony_ci WREG32_MC(MC_MISC_LAT_TIMER, tmp); 127462306a36Sopenharmony_ci } 127562306a36Sopenharmony_ci rv515_bandwidth_avivo_update(rdev); 127662306a36Sopenharmony_ci} 1277