162306a36Sopenharmony_ci/* 262306a36Sopenharmony_ci * Copyright 2010 Advanced Micro Devices, Inc. 362306a36Sopenharmony_ci * 462306a36Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a 562306a36Sopenharmony_ci * copy of this software and associated documentation files (the "Software"), 662306a36Sopenharmony_ci * to deal in the Software without restriction, including without limitation 762306a36Sopenharmony_ci * the rights to use, copy, modify, merge, publish, distribute, sublicense, 862306a36Sopenharmony_ci * and/or sell copies of the Software, and to permit persons to whom the 962306a36Sopenharmony_ci * Software is furnished to do so, subject to the following conditions: 1062306a36Sopenharmony_ci * 1162306a36Sopenharmony_ci * The above copyright notice and this permission notice shall be included in 1262306a36Sopenharmony_ci * all copies or substantial portions of the Software. 1362306a36Sopenharmony_ci * 1462306a36Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 1562306a36Sopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 1662306a36Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 1762306a36Sopenharmony_ci * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR 1862306a36Sopenharmony_ci * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 1962306a36Sopenharmony_ci * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 2062306a36Sopenharmony_ci * OTHER DEALINGS IN THE SOFTWARE. 2162306a36Sopenharmony_ci * 2262306a36Sopenharmony_ci * Authors: Alex Deucher 2362306a36Sopenharmony_ci */ 2462306a36Sopenharmony_ci 2562306a36Sopenharmony_ci#include <linux/firmware.h> 2662306a36Sopenharmony_ci#include <linux/pci.h> 2762306a36Sopenharmony_ci#include <linux/slab.h> 2862306a36Sopenharmony_ci 2962306a36Sopenharmony_ci#include <drm/drm_vblank.h> 3062306a36Sopenharmony_ci#include <drm/radeon_drm.h> 3162306a36Sopenharmony_ci#include <drm/drm_fourcc.h> 3262306a36Sopenharmony_ci#include <drm/drm_framebuffer.h> 3362306a36Sopenharmony_ci 3462306a36Sopenharmony_ci#include "atom.h" 3562306a36Sopenharmony_ci#include "avivod.h" 3662306a36Sopenharmony_ci#include "cik.h" 3762306a36Sopenharmony_ci#include "ni.h" 3862306a36Sopenharmony_ci#include "rv770.h" 3962306a36Sopenharmony_ci#include "evergreen.h" 4062306a36Sopenharmony_ci#include "evergreen_blit_shaders.h" 4162306a36Sopenharmony_ci#include "evergreen_reg.h" 4262306a36Sopenharmony_ci#include "evergreend.h" 4362306a36Sopenharmony_ci#include "radeon.h" 4462306a36Sopenharmony_ci#include "radeon_asic.h" 4562306a36Sopenharmony_ci#include "radeon_audio.h" 4662306a36Sopenharmony_ci#include "radeon_ucode.h" 4762306a36Sopenharmony_ci#include "si.h" 4862306a36Sopenharmony_ci 4962306a36Sopenharmony_ci#define DC_HPDx_CONTROL(x) (DC_HPD1_CONTROL + (x * 0xc)) 5062306a36Sopenharmony_ci#define DC_HPDx_INT_CONTROL(x) (DC_HPD1_INT_CONTROL + (x * 0xc)) 5162306a36Sopenharmony_ci#define DC_HPDx_INT_STATUS_REG(x) (DC_HPD1_INT_STATUS + (x * 0xc)) 5262306a36Sopenharmony_ci 5362306a36Sopenharmony_ci/* 5462306a36Sopenharmony_ci * Indirect registers accessor 5562306a36Sopenharmony_ci */ 5662306a36Sopenharmony_ciu32 eg_cg_rreg(struct radeon_device *rdev, u32 reg) 5762306a36Sopenharmony_ci{ 5862306a36Sopenharmony_ci unsigned long flags; 5962306a36Sopenharmony_ci u32 r; 6062306a36Sopenharmony_ci 6162306a36Sopenharmony_ci spin_lock_irqsave(&rdev->cg_idx_lock, flags); 6262306a36Sopenharmony_ci WREG32(EVERGREEN_CG_IND_ADDR, ((reg) & 0xffff)); 6362306a36Sopenharmony_ci r = RREG32(EVERGREEN_CG_IND_DATA); 6462306a36Sopenharmony_ci spin_unlock_irqrestore(&rdev->cg_idx_lock, flags); 6562306a36Sopenharmony_ci return r; 6662306a36Sopenharmony_ci} 6762306a36Sopenharmony_ci 6862306a36Sopenharmony_civoid eg_cg_wreg(struct radeon_device *rdev, u32 reg, u32 v) 6962306a36Sopenharmony_ci{ 7062306a36Sopenharmony_ci unsigned long flags; 7162306a36Sopenharmony_ci 7262306a36Sopenharmony_ci spin_lock_irqsave(&rdev->cg_idx_lock, flags); 7362306a36Sopenharmony_ci WREG32(EVERGREEN_CG_IND_ADDR, ((reg) & 0xffff)); 7462306a36Sopenharmony_ci WREG32(EVERGREEN_CG_IND_DATA, (v)); 7562306a36Sopenharmony_ci spin_unlock_irqrestore(&rdev->cg_idx_lock, flags); 7662306a36Sopenharmony_ci} 7762306a36Sopenharmony_ci 7862306a36Sopenharmony_ciu32 eg_pif_phy0_rreg(struct radeon_device *rdev, u32 reg) 7962306a36Sopenharmony_ci{ 8062306a36Sopenharmony_ci unsigned long flags; 8162306a36Sopenharmony_ci u32 r; 8262306a36Sopenharmony_ci 8362306a36Sopenharmony_ci spin_lock_irqsave(&rdev->pif_idx_lock, flags); 8462306a36Sopenharmony_ci WREG32(EVERGREEN_PIF_PHY0_INDEX, ((reg) & 0xffff)); 8562306a36Sopenharmony_ci r = RREG32(EVERGREEN_PIF_PHY0_DATA); 8662306a36Sopenharmony_ci spin_unlock_irqrestore(&rdev->pif_idx_lock, flags); 8762306a36Sopenharmony_ci return r; 8862306a36Sopenharmony_ci} 8962306a36Sopenharmony_ci 9062306a36Sopenharmony_civoid eg_pif_phy0_wreg(struct radeon_device *rdev, u32 reg, u32 v) 9162306a36Sopenharmony_ci{ 9262306a36Sopenharmony_ci unsigned long flags; 9362306a36Sopenharmony_ci 9462306a36Sopenharmony_ci spin_lock_irqsave(&rdev->pif_idx_lock, flags); 9562306a36Sopenharmony_ci WREG32(EVERGREEN_PIF_PHY0_INDEX, ((reg) & 0xffff)); 9662306a36Sopenharmony_ci WREG32(EVERGREEN_PIF_PHY0_DATA, (v)); 9762306a36Sopenharmony_ci spin_unlock_irqrestore(&rdev->pif_idx_lock, flags); 9862306a36Sopenharmony_ci} 9962306a36Sopenharmony_ci 10062306a36Sopenharmony_ciu32 eg_pif_phy1_rreg(struct radeon_device *rdev, u32 reg) 10162306a36Sopenharmony_ci{ 10262306a36Sopenharmony_ci unsigned long flags; 10362306a36Sopenharmony_ci u32 r; 10462306a36Sopenharmony_ci 10562306a36Sopenharmony_ci spin_lock_irqsave(&rdev->pif_idx_lock, flags); 10662306a36Sopenharmony_ci WREG32(EVERGREEN_PIF_PHY1_INDEX, ((reg) & 0xffff)); 10762306a36Sopenharmony_ci r = RREG32(EVERGREEN_PIF_PHY1_DATA); 10862306a36Sopenharmony_ci spin_unlock_irqrestore(&rdev->pif_idx_lock, flags); 10962306a36Sopenharmony_ci return r; 11062306a36Sopenharmony_ci} 11162306a36Sopenharmony_ci 11262306a36Sopenharmony_civoid eg_pif_phy1_wreg(struct radeon_device *rdev, u32 reg, u32 v) 11362306a36Sopenharmony_ci{ 11462306a36Sopenharmony_ci unsigned long flags; 11562306a36Sopenharmony_ci 11662306a36Sopenharmony_ci spin_lock_irqsave(&rdev->pif_idx_lock, flags); 11762306a36Sopenharmony_ci WREG32(EVERGREEN_PIF_PHY1_INDEX, ((reg) & 0xffff)); 11862306a36Sopenharmony_ci WREG32(EVERGREEN_PIF_PHY1_DATA, (v)); 11962306a36Sopenharmony_ci spin_unlock_irqrestore(&rdev->pif_idx_lock, flags); 12062306a36Sopenharmony_ci} 12162306a36Sopenharmony_ci 12262306a36Sopenharmony_cistatic const u32 crtc_offsets[6] = 12362306a36Sopenharmony_ci{ 12462306a36Sopenharmony_ci EVERGREEN_CRTC0_REGISTER_OFFSET, 12562306a36Sopenharmony_ci EVERGREEN_CRTC1_REGISTER_OFFSET, 12662306a36Sopenharmony_ci EVERGREEN_CRTC2_REGISTER_OFFSET, 12762306a36Sopenharmony_ci EVERGREEN_CRTC3_REGISTER_OFFSET, 12862306a36Sopenharmony_ci EVERGREEN_CRTC4_REGISTER_OFFSET, 12962306a36Sopenharmony_ci EVERGREEN_CRTC5_REGISTER_OFFSET 13062306a36Sopenharmony_ci}; 13162306a36Sopenharmony_ci 13262306a36Sopenharmony_ci#include "clearstate_evergreen.h" 13362306a36Sopenharmony_ci 13462306a36Sopenharmony_cistatic const u32 sumo_rlc_save_restore_register_list[] = 13562306a36Sopenharmony_ci{ 13662306a36Sopenharmony_ci 0x98fc, 13762306a36Sopenharmony_ci 0x9830, 13862306a36Sopenharmony_ci 0x9834, 13962306a36Sopenharmony_ci 0x9838, 14062306a36Sopenharmony_ci 0x9870, 14162306a36Sopenharmony_ci 0x9874, 14262306a36Sopenharmony_ci 0x8a14, 14362306a36Sopenharmony_ci 0x8b24, 14462306a36Sopenharmony_ci 0x8bcc, 14562306a36Sopenharmony_ci 0x8b10, 14662306a36Sopenharmony_ci 0x8d00, 14762306a36Sopenharmony_ci 0x8d04, 14862306a36Sopenharmony_ci 0x8c00, 14962306a36Sopenharmony_ci 0x8c04, 15062306a36Sopenharmony_ci 0x8c08, 15162306a36Sopenharmony_ci 0x8c0c, 15262306a36Sopenharmony_ci 0x8d8c, 15362306a36Sopenharmony_ci 0x8c20, 15462306a36Sopenharmony_ci 0x8c24, 15562306a36Sopenharmony_ci 0x8c28, 15662306a36Sopenharmony_ci 0x8c18, 15762306a36Sopenharmony_ci 0x8c1c, 15862306a36Sopenharmony_ci 0x8cf0, 15962306a36Sopenharmony_ci 0x8e2c, 16062306a36Sopenharmony_ci 0x8e38, 16162306a36Sopenharmony_ci 0x8c30, 16262306a36Sopenharmony_ci 0x9508, 16362306a36Sopenharmony_ci 0x9688, 16462306a36Sopenharmony_ci 0x9608, 16562306a36Sopenharmony_ci 0x960c, 16662306a36Sopenharmony_ci 0x9610, 16762306a36Sopenharmony_ci 0x9614, 16862306a36Sopenharmony_ci 0x88c4, 16962306a36Sopenharmony_ci 0x88d4, 17062306a36Sopenharmony_ci 0xa008, 17162306a36Sopenharmony_ci 0x900c, 17262306a36Sopenharmony_ci 0x9100, 17362306a36Sopenharmony_ci 0x913c, 17462306a36Sopenharmony_ci 0x98f8, 17562306a36Sopenharmony_ci 0x98f4, 17662306a36Sopenharmony_ci 0x9b7c, 17762306a36Sopenharmony_ci 0x3f8c, 17862306a36Sopenharmony_ci 0x8950, 17962306a36Sopenharmony_ci 0x8954, 18062306a36Sopenharmony_ci 0x8a18, 18162306a36Sopenharmony_ci 0x8b28, 18262306a36Sopenharmony_ci 0x9144, 18362306a36Sopenharmony_ci 0x9148, 18462306a36Sopenharmony_ci 0x914c, 18562306a36Sopenharmony_ci 0x3f90, 18662306a36Sopenharmony_ci 0x3f94, 18762306a36Sopenharmony_ci 0x915c, 18862306a36Sopenharmony_ci 0x9160, 18962306a36Sopenharmony_ci 0x9178, 19062306a36Sopenharmony_ci 0x917c, 19162306a36Sopenharmony_ci 0x9180, 19262306a36Sopenharmony_ci 0x918c, 19362306a36Sopenharmony_ci 0x9190, 19462306a36Sopenharmony_ci 0x9194, 19562306a36Sopenharmony_ci 0x9198, 19662306a36Sopenharmony_ci 0x919c, 19762306a36Sopenharmony_ci 0x91a8, 19862306a36Sopenharmony_ci 0x91ac, 19962306a36Sopenharmony_ci 0x91b0, 20062306a36Sopenharmony_ci 0x91b4, 20162306a36Sopenharmony_ci 0x91b8, 20262306a36Sopenharmony_ci 0x91c4, 20362306a36Sopenharmony_ci 0x91c8, 20462306a36Sopenharmony_ci 0x91cc, 20562306a36Sopenharmony_ci 0x91d0, 20662306a36Sopenharmony_ci 0x91d4, 20762306a36Sopenharmony_ci 0x91e0, 20862306a36Sopenharmony_ci 0x91e4, 20962306a36Sopenharmony_ci 0x91ec, 21062306a36Sopenharmony_ci 0x91f0, 21162306a36Sopenharmony_ci 0x91f4, 21262306a36Sopenharmony_ci 0x9200, 21362306a36Sopenharmony_ci 0x9204, 21462306a36Sopenharmony_ci 0x929c, 21562306a36Sopenharmony_ci 0x9150, 21662306a36Sopenharmony_ci 0x802c, 21762306a36Sopenharmony_ci}; 21862306a36Sopenharmony_ci 21962306a36Sopenharmony_cistatic void evergreen_gpu_init(struct radeon_device *rdev); 22062306a36Sopenharmony_civoid evergreen_fini(struct radeon_device *rdev); 22162306a36Sopenharmony_civoid evergreen_pcie_gen2_enable(struct radeon_device *rdev); 22262306a36Sopenharmony_civoid evergreen_program_aspm(struct radeon_device *rdev); 22362306a36Sopenharmony_ci 22462306a36Sopenharmony_cistatic const u32 evergreen_golden_registers[] = 22562306a36Sopenharmony_ci{ 22662306a36Sopenharmony_ci 0x3f90, 0xffff0000, 0xff000000, 22762306a36Sopenharmony_ci 0x9148, 0xffff0000, 0xff000000, 22862306a36Sopenharmony_ci 0x3f94, 0xffff0000, 0xff000000, 22962306a36Sopenharmony_ci 0x914c, 0xffff0000, 0xff000000, 23062306a36Sopenharmony_ci 0x9b7c, 0xffffffff, 0x00000000, 23162306a36Sopenharmony_ci 0x8a14, 0xffffffff, 0x00000007, 23262306a36Sopenharmony_ci 0x8b10, 0xffffffff, 0x00000000, 23362306a36Sopenharmony_ci 0x960c, 0xffffffff, 0x54763210, 23462306a36Sopenharmony_ci 0x88c4, 0xffffffff, 0x000000c2, 23562306a36Sopenharmony_ci 0x88d4, 0xffffffff, 0x00000010, 23662306a36Sopenharmony_ci 0x8974, 0xffffffff, 0x00000000, 23762306a36Sopenharmony_ci 0xc78, 0x00000080, 0x00000080, 23862306a36Sopenharmony_ci 0x5eb4, 0xffffffff, 0x00000002, 23962306a36Sopenharmony_ci 0x5e78, 0xffffffff, 0x001000f0, 24062306a36Sopenharmony_ci 0x6104, 0x01000300, 0x00000000, 24162306a36Sopenharmony_ci 0x5bc0, 0x00300000, 0x00000000, 24262306a36Sopenharmony_ci 0x7030, 0xffffffff, 0x00000011, 24362306a36Sopenharmony_ci 0x7c30, 0xffffffff, 0x00000011, 24462306a36Sopenharmony_ci 0x10830, 0xffffffff, 0x00000011, 24562306a36Sopenharmony_ci 0x11430, 0xffffffff, 0x00000011, 24662306a36Sopenharmony_ci 0x12030, 0xffffffff, 0x00000011, 24762306a36Sopenharmony_ci 0x12c30, 0xffffffff, 0x00000011, 24862306a36Sopenharmony_ci 0xd02c, 0xffffffff, 0x08421000, 24962306a36Sopenharmony_ci 0x240c, 0xffffffff, 0x00000380, 25062306a36Sopenharmony_ci 0x8b24, 0xffffffff, 0x00ff0fff, 25162306a36Sopenharmony_ci 0x28a4c, 0x06000000, 0x06000000, 25262306a36Sopenharmony_ci 0x10c, 0x00000001, 0x00000001, 25362306a36Sopenharmony_ci 0x8d00, 0xffffffff, 0x100e4848, 25462306a36Sopenharmony_ci 0x8d04, 0xffffffff, 0x00164745, 25562306a36Sopenharmony_ci 0x8c00, 0xffffffff, 0xe4000003, 25662306a36Sopenharmony_ci 0x8c04, 0xffffffff, 0x40600060, 25762306a36Sopenharmony_ci 0x8c08, 0xffffffff, 0x001c001c, 25862306a36Sopenharmony_ci 0x8cf0, 0xffffffff, 0x08e00620, 25962306a36Sopenharmony_ci 0x8c20, 0xffffffff, 0x00800080, 26062306a36Sopenharmony_ci 0x8c24, 0xffffffff, 0x00800080, 26162306a36Sopenharmony_ci 0x8c18, 0xffffffff, 0x20202078, 26262306a36Sopenharmony_ci 0x8c1c, 0xffffffff, 0x00001010, 26362306a36Sopenharmony_ci 0x28350, 0xffffffff, 0x00000000, 26462306a36Sopenharmony_ci 0xa008, 0xffffffff, 0x00010000, 26562306a36Sopenharmony_ci 0x5c4, 0xffffffff, 0x00000001, 26662306a36Sopenharmony_ci 0x9508, 0xffffffff, 0x00000002, 26762306a36Sopenharmony_ci 0x913c, 0x0000000f, 0x0000000a 26862306a36Sopenharmony_ci}; 26962306a36Sopenharmony_ci 27062306a36Sopenharmony_cistatic const u32 evergreen_golden_registers2[] = 27162306a36Sopenharmony_ci{ 27262306a36Sopenharmony_ci 0x2f4c, 0xffffffff, 0x00000000, 27362306a36Sopenharmony_ci 0x54f4, 0xffffffff, 0x00000000, 27462306a36Sopenharmony_ci 0x54f0, 0xffffffff, 0x00000000, 27562306a36Sopenharmony_ci 0x5498, 0xffffffff, 0x00000000, 27662306a36Sopenharmony_ci 0x549c, 0xffffffff, 0x00000000, 27762306a36Sopenharmony_ci 0x5494, 0xffffffff, 0x00000000, 27862306a36Sopenharmony_ci 0x53cc, 0xffffffff, 0x00000000, 27962306a36Sopenharmony_ci 0x53c8, 0xffffffff, 0x00000000, 28062306a36Sopenharmony_ci 0x53c4, 0xffffffff, 0x00000000, 28162306a36Sopenharmony_ci 0x53c0, 0xffffffff, 0x00000000, 28262306a36Sopenharmony_ci 0x53bc, 0xffffffff, 0x00000000, 28362306a36Sopenharmony_ci 0x53b8, 0xffffffff, 0x00000000, 28462306a36Sopenharmony_ci 0x53b4, 0xffffffff, 0x00000000, 28562306a36Sopenharmony_ci 0x53b0, 0xffffffff, 0x00000000 28662306a36Sopenharmony_ci}; 28762306a36Sopenharmony_ci 28862306a36Sopenharmony_cistatic const u32 cypress_mgcg_init[] = 28962306a36Sopenharmony_ci{ 29062306a36Sopenharmony_ci 0x802c, 0xffffffff, 0xc0000000, 29162306a36Sopenharmony_ci 0x5448, 0xffffffff, 0x00000100, 29262306a36Sopenharmony_ci 0x55e4, 0xffffffff, 0x00000100, 29362306a36Sopenharmony_ci 0x160c, 0xffffffff, 0x00000100, 29462306a36Sopenharmony_ci 0x5644, 0xffffffff, 0x00000100, 29562306a36Sopenharmony_ci 0xc164, 0xffffffff, 0x00000100, 29662306a36Sopenharmony_ci 0x8a18, 0xffffffff, 0x00000100, 29762306a36Sopenharmony_ci 0x897c, 0xffffffff, 0x06000100, 29862306a36Sopenharmony_ci 0x8b28, 0xffffffff, 0x00000100, 29962306a36Sopenharmony_ci 0x9144, 0xffffffff, 0x00000100, 30062306a36Sopenharmony_ci 0x9a60, 0xffffffff, 0x00000100, 30162306a36Sopenharmony_ci 0x9868, 0xffffffff, 0x00000100, 30262306a36Sopenharmony_ci 0x8d58, 0xffffffff, 0x00000100, 30362306a36Sopenharmony_ci 0x9510, 0xffffffff, 0x00000100, 30462306a36Sopenharmony_ci 0x949c, 0xffffffff, 0x00000100, 30562306a36Sopenharmony_ci 0x9654, 0xffffffff, 0x00000100, 30662306a36Sopenharmony_ci 0x9030, 0xffffffff, 0x00000100, 30762306a36Sopenharmony_ci 0x9034, 0xffffffff, 0x00000100, 30862306a36Sopenharmony_ci 0x9038, 0xffffffff, 0x00000100, 30962306a36Sopenharmony_ci 0x903c, 0xffffffff, 0x00000100, 31062306a36Sopenharmony_ci 0x9040, 0xffffffff, 0x00000100, 31162306a36Sopenharmony_ci 0xa200, 0xffffffff, 0x00000100, 31262306a36Sopenharmony_ci 0xa204, 0xffffffff, 0x00000100, 31362306a36Sopenharmony_ci 0xa208, 0xffffffff, 0x00000100, 31462306a36Sopenharmony_ci 0xa20c, 0xffffffff, 0x00000100, 31562306a36Sopenharmony_ci 0x971c, 0xffffffff, 0x00000100, 31662306a36Sopenharmony_ci 0x977c, 0xffffffff, 0x00000100, 31762306a36Sopenharmony_ci 0x3f80, 0xffffffff, 0x00000100, 31862306a36Sopenharmony_ci 0xa210, 0xffffffff, 0x00000100, 31962306a36Sopenharmony_ci 0xa214, 0xffffffff, 0x00000100, 32062306a36Sopenharmony_ci 0x4d8, 0xffffffff, 0x00000100, 32162306a36Sopenharmony_ci 0x9784, 0xffffffff, 0x00000100, 32262306a36Sopenharmony_ci 0x9698, 0xffffffff, 0x00000100, 32362306a36Sopenharmony_ci 0x4d4, 0xffffffff, 0x00000200, 32462306a36Sopenharmony_ci 0x30cc, 0xffffffff, 0x00000100, 32562306a36Sopenharmony_ci 0xd0c0, 0xffffffff, 0xff000100, 32662306a36Sopenharmony_ci 0x802c, 0xffffffff, 0x40000000, 32762306a36Sopenharmony_ci 0x915c, 0xffffffff, 0x00010000, 32862306a36Sopenharmony_ci 0x9160, 0xffffffff, 0x00030002, 32962306a36Sopenharmony_ci 0x9178, 0xffffffff, 0x00070000, 33062306a36Sopenharmony_ci 0x917c, 0xffffffff, 0x00030002, 33162306a36Sopenharmony_ci 0x9180, 0xffffffff, 0x00050004, 33262306a36Sopenharmony_ci 0x918c, 0xffffffff, 0x00010006, 33362306a36Sopenharmony_ci 0x9190, 0xffffffff, 0x00090008, 33462306a36Sopenharmony_ci 0x9194, 0xffffffff, 0x00070000, 33562306a36Sopenharmony_ci 0x9198, 0xffffffff, 0x00030002, 33662306a36Sopenharmony_ci 0x919c, 0xffffffff, 0x00050004, 33762306a36Sopenharmony_ci 0x91a8, 0xffffffff, 0x00010006, 33862306a36Sopenharmony_ci 0x91ac, 0xffffffff, 0x00090008, 33962306a36Sopenharmony_ci 0x91b0, 0xffffffff, 0x00070000, 34062306a36Sopenharmony_ci 0x91b4, 0xffffffff, 0x00030002, 34162306a36Sopenharmony_ci 0x91b8, 0xffffffff, 0x00050004, 34262306a36Sopenharmony_ci 0x91c4, 0xffffffff, 0x00010006, 34362306a36Sopenharmony_ci 0x91c8, 0xffffffff, 0x00090008, 34462306a36Sopenharmony_ci 0x91cc, 0xffffffff, 0x00070000, 34562306a36Sopenharmony_ci 0x91d0, 0xffffffff, 0x00030002, 34662306a36Sopenharmony_ci 0x91d4, 0xffffffff, 0x00050004, 34762306a36Sopenharmony_ci 0x91e0, 0xffffffff, 0x00010006, 34862306a36Sopenharmony_ci 0x91e4, 0xffffffff, 0x00090008, 34962306a36Sopenharmony_ci 0x91e8, 0xffffffff, 0x00000000, 35062306a36Sopenharmony_ci 0x91ec, 0xffffffff, 0x00070000, 35162306a36Sopenharmony_ci 0x91f0, 0xffffffff, 0x00030002, 35262306a36Sopenharmony_ci 0x91f4, 0xffffffff, 0x00050004, 35362306a36Sopenharmony_ci 0x9200, 0xffffffff, 0x00010006, 35462306a36Sopenharmony_ci 0x9204, 0xffffffff, 0x00090008, 35562306a36Sopenharmony_ci 0x9208, 0xffffffff, 0x00070000, 35662306a36Sopenharmony_ci 0x920c, 0xffffffff, 0x00030002, 35762306a36Sopenharmony_ci 0x9210, 0xffffffff, 0x00050004, 35862306a36Sopenharmony_ci 0x921c, 0xffffffff, 0x00010006, 35962306a36Sopenharmony_ci 0x9220, 0xffffffff, 0x00090008, 36062306a36Sopenharmony_ci 0x9224, 0xffffffff, 0x00070000, 36162306a36Sopenharmony_ci 0x9228, 0xffffffff, 0x00030002, 36262306a36Sopenharmony_ci 0x922c, 0xffffffff, 0x00050004, 36362306a36Sopenharmony_ci 0x9238, 0xffffffff, 0x00010006, 36462306a36Sopenharmony_ci 0x923c, 0xffffffff, 0x00090008, 36562306a36Sopenharmony_ci 0x9240, 0xffffffff, 0x00070000, 36662306a36Sopenharmony_ci 0x9244, 0xffffffff, 0x00030002, 36762306a36Sopenharmony_ci 0x9248, 0xffffffff, 0x00050004, 36862306a36Sopenharmony_ci 0x9254, 0xffffffff, 0x00010006, 36962306a36Sopenharmony_ci 0x9258, 0xffffffff, 0x00090008, 37062306a36Sopenharmony_ci 0x925c, 0xffffffff, 0x00070000, 37162306a36Sopenharmony_ci 0x9260, 0xffffffff, 0x00030002, 37262306a36Sopenharmony_ci 0x9264, 0xffffffff, 0x00050004, 37362306a36Sopenharmony_ci 0x9270, 0xffffffff, 0x00010006, 37462306a36Sopenharmony_ci 0x9274, 0xffffffff, 0x00090008, 37562306a36Sopenharmony_ci 0x9278, 0xffffffff, 0x00070000, 37662306a36Sopenharmony_ci 0x927c, 0xffffffff, 0x00030002, 37762306a36Sopenharmony_ci 0x9280, 0xffffffff, 0x00050004, 37862306a36Sopenharmony_ci 0x928c, 0xffffffff, 0x00010006, 37962306a36Sopenharmony_ci 0x9290, 0xffffffff, 0x00090008, 38062306a36Sopenharmony_ci 0x9294, 0xffffffff, 0x00000000, 38162306a36Sopenharmony_ci 0x929c, 0xffffffff, 0x00000001, 38262306a36Sopenharmony_ci 0x802c, 0xffffffff, 0x40010000, 38362306a36Sopenharmony_ci 0x915c, 0xffffffff, 0x00010000, 38462306a36Sopenharmony_ci 0x9160, 0xffffffff, 0x00030002, 38562306a36Sopenharmony_ci 0x9178, 0xffffffff, 0x00070000, 38662306a36Sopenharmony_ci 0x917c, 0xffffffff, 0x00030002, 38762306a36Sopenharmony_ci 0x9180, 0xffffffff, 0x00050004, 38862306a36Sopenharmony_ci 0x918c, 0xffffffff, 0x00010006, 38962306a36Sopenharmony_ci 0x9190, 0xffffffff, 0x00090008, 39062306a36Sopenharmony_ci 0x9194, 0xffffffff, 0x00070000, 39162306a36Sopenharmony_ci 0x9198, 0xffffffff, 0x00030002, 39262306a36Sopenharmony_ci 0x919c, 0xffffffff, 0x00050004, 39362306a36Sopenharmony_ci 0x91a8, 0xffffffff, 0x00010006, 39462306a36Sopenharmony_ci 0x91ac, 0xffffffff, 0x00090008, 39562306a36Sopenharmony_ci 0x91b0, 0xffffffff, 0x00070000, 39662306a36Sopenharmony_ci 0x91b4, 0xffffffff, 0x00030002, 39762306a36Sopenharmony_ci 0x91b8, 0xffffffff, 0x00050004, 39862306a36Sopenharmony_ci 0x91c4, 0xffffffff, 0x00010006, 39962306a36Sopenharmony_ci 0x91c8, 0xffffffff, 0x00090008, 40062306a36Sopenharmony_ci 0x91cc, 0xffffffff, 0x00070000, 40162306a36Sopenharmony_ci 0x91d0, 0xffffffff, 0x00030002, 40262306a36Sopenharmony_ci 0x91d4, 0xffffffff, 0x00050004, 40362306a36Sopenharmony_ci 0x91e0, 0xffffffff, 0x00010006, 40462306a36Sopenharmony_ci 0x91e4, 0xffffffff, 0x00090008, 40562306a36Sopenharmony_ci 0x91e8, 0xffffffff, 0x00000000, 40662306a36Sopenharmony_ci 0x91ec, 0xffffffff, 0x00070000, 40762306a36Sopenharmony_ci 0x91f0, 0xffffffff, 0x00030002, 40862306a36Sopenharmony_ci 0x91f4, 0xffffffff, 0x00050004, 40962306a36Sopenharmony_ci 0x9200, 0xffffffff, 0x00010006, 41062306a36Sopenharmony_ci 0x9204, 0xffffffff, 0x00090008, 41162306a36Sopenharmony_ci 0x9208, 0xffffffff, 0x00070000, 41262306a36Sopenharmony_ci 0x920c, 0xffffffff, 0x00030002, 41362306a36Sopenharmony_ci 0x9210, 0xffffffff, 0x00050004, 41462306a36Sopenharmony_ci 0x921c, 0xffffffff, 0x00010006, 41562306a36Sopenharmony_ci 0x9220, 0xffffffff, 0x00090008, 41662306a36Sopenharmony_ci 0x9224, 0xffffffff, 0x00070000, 41762306a36Sopenharmony_ci 0x9228, 0xffffffff, 0x00030002, 41862306a36Sopenharmony_ci 0x922c, 0xffffffff, 0x00050004, 41962306a36Sopenharmony_ci 0x9238, 0xffffffff, 0x00010006, 42062306a36Sopenharmony_ci 0x923c, 0xffffffff, 0x00090008, 42162306a36Sopenharmony_ci 0x9240, 0xffffffff, 0x00070000, 42262306a36Sopenharmony_ci 0x9244, 0xffffffff, 0x00030002, 42362306a36Sopenharmony_ci 0x9248, 0xffffffff, 0x00050004, 42462306a36Sopenharmony_ci 0x9254, 0xffffffff, 0x00010006, 42562306a36Sopenharmony_ci 0x9258, 0xffffffff, 0x00090008, 42662306a36Sopenharmony_ci 0x925c, 0xffffffff, 0x00070000, 42762306a36Sopenharmony_ci 0x9260, 0xffffffff, 0x00030002, 42862306a36Sopenharmony_ci 0x9264, 0xffffffff, 0x00050004, 42962306a36Sopenharmony_ci 0x9270, 0xffffffff, 0x00010006, 43062306a36Sopenharmony_ci 0x9274, 0xffffffff, 0x00090008, 43162306a36Sopenharmony_ci 0x9278, 0xffffffff, 0x00070000, 43262306a36Sopenharmony_ci 0x927c, 0xffffffff, 0x00030002, 43362306a36Sopenharmony_ci 0x9280, 0xffffffff, 0x00050004, 43462306a36Sopenharmony_ci 0x928c, 0xffffffff, 0x00010006, 43562306a36Sopenharmony_ci 0x9290, 0xffffffff, 0x00090008, 43662306a36Sopenharmony_ci 0x9294, 0xffffffff, 0x00000000, 43762306a36Sopenharmony_ci 0x929c, 0xffffffff, 0x00000001, 43862306a36Sopenharmony_ci 0x802c, 0xffffffff, 0xc0000000 43962306a36Sopenharmony_ci}; 44062306a36Sopenharmony_ci 44162306a36Sopenharmony_cistatic const u32 redwood_mgcg_init[] = 44262306a36Sopenharmony_ci{ 44362306a36Sopenharmony_ci 0x802c, 0xffffffff, 0xc0000000, 44462306a36Sopenharmony_ci 0x5448, 0xffffffff, 0x00000100, 44562306a36Sopenharmony_ci 0x55e4, 0xffffffff, 0x00000100, 44662306a36Sopenharmony_ci 0x160c, 0xffffffff, 0x00000100, 44762306a36Sopenharmony_ci 0x5644, 0xffffffff, 0x00000100, 44862306a36Sopenharmony_ci 0xc164, 0xffffffff, 0x00000100, 44962306a36Sopenharmony_ci 0x8a18, 0xffffffff, 0x00000100, 45062306a36Sopenharmony_ci 0x897c, 0xffffffff, 0x06000100, 45162306a36Sopenharmony_ci 0x8b28, 0xffffffff, 0x00000100, 45262306a36Sopenharmony_ci 0x9144, 0xffffffff, 0x00000100, 45362306a36Sopenharmony_ci 0x9a60, 0xffffffff, 0x00000100, 45462306a36Sopenharmony_ci 0x9868, 0xffffffff, 0x00000100, 45562306a36Sopenharmony_ci 0x8d58, 0xffffffff, 0x00000100, 45662306a36Sopenharmony_ci 0x9510, 0xffffffff, 0x00000100, 45762306a36Sopenharmony_ci 0x949c, 0xffffffff, 0x00000100, 45862306a36Sopenharmony_ci 0x9654, 0xffffffff, 0x00000100, 45962306a36Sopenharmony_ci 0x9030, 0xffffffff, 0x00000100, 46062306a36Sopenharmony_ci 0x9034, 0xffffffff, 0x00000100, 46162306a36Sopenharmony_ci 0x9038, 0xffffffff, 0x00000100, 46262306a36Sopenharmony_ci 0x903c, 0xffffffff, 0x00000100, 46362306a36Sopenharmony_ci 0x9040, 0xffffffff, 0x00000100, 46462306a36Sopenharmony_ci 0xa200, 0xffffffff, 0x00000100, 46562306a36Sopenharmony_ci 0xa204, 0xffffffff, 0x00000100, 46662306a36Sopenharmony_ci 0xa208, 0xffffffff, 0x00000100, 46762306a36Sopenharmony_ci 0xa20c, 0xffffffff, 0x00000100, 46862306a36Sopenharmony_ci 0x971c, 0xffffffff, 0x00000100, 46962306a36Sopenharmony_ci 0x977c, 0xffffffff, 0x00000100, 47062306a36Sopenharmony_ci 0x3f80, 0xffffffff, 0x00000100, 47162306a36Sopenharmony_ci 0xa210, 0xffffffff, 0x00000100, 47262306a36Sopenharmony_ci 0xa214, 0xffffffff, 0x00000100, 47362306a36Sopenharmony_ci 0x4d8, 0xffffffff, 0x00000100, 47462306a36Sopenharmony_ci 0x9784, 0xffffffff, 0x00000100, 47562306a36Sopenharmony_ci 0x9698, 0xffffffff, 0x00000100, 47662306a36Sopenharmony_ci 0x4d4, 0xffffffff, 0x00000200, 47762306a36Sopenharmony_ci 0x30cc, 0xffffffff, 0x00000100, 47862306a36Sopenharmony_ci 0xd0c0, 0xffffffff, 0xff000100, 47962306a36Sopenharmony_ci 0x802c, 0xffffffff, 0x40000000, 48062306a36Sopenharmony_ci 0x915c, 0xffffffff, 0x00010000, 48162306a36Sopenharmony_ci 0x9160, 0xffffffff, 0x00030002, 48262306a36Sopenharmony_ci 0x9178, 0xffffffff, 0x00070000, 48362306a36Sopenharmony_ci 0x917c, 0xffffffff, 0x00030002, 48462306a36Sopenharmony_ci 0x9180, 0xffffffff, 0x00050004, 48562306a36Sopenharmony_ci 0x918c, 0xffffffff, 0x00010006, 48662306a36Sopenharmony_ci 0x9190, 0xffffffff, 0x00090008, 48762306a36Sopenharmony_ci 0x9194, 0xffffffff, 0x00070000, 48862306a36Sopenharmony_ci 0x9198, 0xffffffff, 0x00030002, 48962306a36Sopenharmony_ci 0x919c, 0xffffffff, 0x00050004, 49062306a36Sopenharmony_ci 0x91a8, 0xffffffff, 0x00010006, 49162306a36Sopenharmony_ci 0x91ac, 0xffffffff, 0x00090008, 49262306a36Sopenharmony_ci 0x91b0, 0xffffffff, 0x00070000, 49362306a36Sopenharmony_ci 0x91b4, 0xffffffff, 0x00030002, 49462306a36Sopenharmony_ci 0x91b8, 0xffffffff, 0x00050004, 49562306a36Sopenharmony_ci 0x91c4, 0xffffffff, 0x00010006, 49662306a36Sopenharmony_ci 0x91c8, 0xffffffff, 0x00090008, 49762306a36Sopenharmony_ci 0x91cc, 0xffffffff, 0x00070000, 49862306a36Sopenharmony_ci 0x91d0, 0xffffffff, 0x00030002, 49962306a36Sopenharmony_ci 0x91d4, 0xffffffff, 0x00050004, 50062306a36Sopenharmony_ci 0x91e0, 0xffffffff, 0x00010006, 50162306a36Sopenharmony_ci 0x91e4, 0xffffffff, 0x00090008, 50262306a36Sopenharmony_ci 0x91e8, 0xffffffff, 0x00000000, 50362306a36Sopenharmony_ci 0x91ec, 0xffffffff, 0x00070000, 50462306a36Sopenharmony_ci 0x91f0, 0xffffffff, 0x00030002, 50562306a36Sopenharmony_ci 0x91f4, 0xffffffff, 0x00050004, 50662306a36Sopenharmony_ci 0x9200, 0xffffffff, 0x00010006, 50762306a36Sopenharmony_ci 0x9204, 0xffffffff, 0x00090008, 50862306a36Sopenharmony_ci 0x9294, 0xffffffff, 0x00000000, 50962306a36Sopenharmony_ci 0x929c, 0xffffffff, 0x00000001, 51062306a36Sopenharmony_ci 0x802c, 0xffffffff, 0xc0000000 51162306a36Sopenharmony_ci}; 51262306a36Sopenharmony_ci 51362306a36Sopenharmony_cistatic const u32 cedar_golden_registers[] = 51462306a36Sopenharmony_ci{ 51562306a36Sopenharmony_ci 0x3f90, 0xffff0000, 0xff000000, 51662306a36Sopenharmony_ci 0x9148, 0xffff0000, 0xff000000, 51762306a36Sopenharmony_ci 0x3f94, 0xffff0000, 0xff000000, 51862306a36Sopenharmony_ci 0x914c, 0xffff0000, 0xff000000, 51962306a36Sopenharmony_ci 0x9b7c, 0xffffffff, 0x00000000, 52062306a36Sopenharmony_ci 0x8a14, 0xffffffff, 0x00000007, 52162306a36Sopenharmony_ci 0x8b10, 0xffffffff, 0x00000000, 52262306a36Sopenharmony_ci 0x960c, 0xffffffff, 0x54763210, 52362306a36Sopenharmony_ci 0x88c4, 0xffffffff, 0x000000c2, 52462306a36Sopenharmony_ci 0x88d4, 0xffffffff, 0x00000000, 52562306a36Sopenharmony_ci 0x8974, 0xffffffff, 0x00000000, 52662306a36Sopenharmony_ci 0xc78, 0x00000080, 0x00000080, 52762306a36Sopenharmony_ci 0x5eb4, 0xffffffff, 0x00000002, 52862306a36Sopenharmony_ci 0x5e78, 0xffffffff, 0x001000f0, 52962306a36Sopenharmony_ci 0x6104, 0x01000300, 0x00000000, 53062306a36Sopenharmony_ci 0x5bc0, 0x00300000, 0x00000000, 53162306a36Sopenharmony_ci 0x7030, 0xffffffff, 0x00000011, 53262306a36Sopenharmony_ci 0x7c30, 0xffffffff, 0x00000011, 53362306a36Sopenharmony_ci 0x10830, 0xffffffff, 0x00000011, 53462306a36Sopenharmony_ci 0x11430, 0xffffffff, 0x00000011, 53562306a36Sopenharmony_ci 0xd02c, 0xffffffff, 0x08421000, 53662306a36Sopenharmony_ci 0x240c, 0xffffffff, 0x00000380, 53762306a36Sopenharmony_ci 0x8b24, 0xffffffff, 0x00ff0fff, 53862306a36Sopenharmony_ci 0x28a4c, 0x06000000, 0x06000000, 53962306a36Sopenharmony_ci 0x10c, 0x00000001, 0x00000001, 54062306a36Sopenharmony_ci 0x8d00, 0xffffffff, 0x100e4848, 54162306a36Sopenharmony_ci 0x8d04, 0xffffffff, 0x00164745, 54262306a36Sopenharmony_ci 0x8c00, 0xffffffff, 0xe4000003, 54362306a36Sopenharmony_ci 0x8c04, 0xffffffff, 0x40600060, 54462306a36Sopenharmony_ci 0x8c08, 0xffffffff, 0x001c001c, 54562306a36Sopenharmony_ci 0x8cf0, 0xffffffff, 0x08e00410, 54662306a36Sopenharmony_ci 0x8c20, 0xffffffff, 0x00800080, 54762306a36Sopenharmony_ci 0x8c24, 0xffffffff, 0x00800080, 54862306a36Sopenharmony_ci 0x8c18, 0xffffffff, 0x20202078, 54962306a36Sopenharmony_ci 0x8c1c, 0xffffffff, 0x00001010, 55062306a36Sopenharmony_ci 0x28350, 0xffffffff, 0x00000000, 55162306a36Sopenharmony_ci 0xa008, 0xffffffff, 0x00010000, 55262306a36Sopenharmony_ci 0x5c4, 0xffffffff, 0x00000001, 55362306a36Sopenharmony_ci 0x9508, 0xffffffff, 0x00000002 55462306a36Sopenharmony_ci}; 55562306a36Sopenharmony_ci 55662306a36Sopenharmony_cistatic const u32 cedar_mgcg_init[] = 55762306a36Sopenharmony_ci{ 55862306a36Sopenharmony_ci 0x802c, 0xffffffff, 0xc0000000, 55962306a36Sopenharmony_ci 0x5448, 0xffffffff, 0x00000100, 56062306a36Sopenharmony_ci 0x55e4, 0xffffffff, 0x00000100, 56162306a36Sopenharmony_ci 0x160c, 0xffffffff, 0x00000100, 56262306a36Sopenharmony_ci 0x5644, 0xffffffff, 0x00000100, 56362306a36Sopenharmony_ci 0xc164, 0xffffffff, 0x00000100, 56462306a36Sopenharmony_ci 0x8a18, 0xffffffff, 0x00000100, 56562306a36Sopenharmony_ci 0x897c, 0xffffffff, 0x06000100, 56662306a36Sopenharmony_ci 0x8b28, 0xffffffff, 0x00000100, 56762306a36Sopenharmony_ci 0x9144, 0xffffffff, 0x00000100, 56862306a36Sopenharmony_ci 0x9a60, 0xffffffff, 0x00000100, 56962306a36Sopenharmony_ci 0x9868, 0xffffffff, 0x00000100, 57062306a36Sopenharmony_ci 0x8d58, 0xffffffff, 0x00000100, 57162306a36Sopenharmony_ci 0x9510, 0xffffffff, 0x00000100, 57262306a36Sopenharmony_ci 0x949c, 0xffffffff, 0x00000100, 57362306a36Sopenharmony_ci 0x9654, 0xffffffff, 0x00000100, 57462306a36Sopenharmony_ci 0x9030, 0xffffffff, 0x00000100, 57562306a36Sopenharmony_ci 0x9034, 0xffffffff, 0x00000100, 57662306a36Sopenharmony_ci 0x9038, 0xffffffff, 0x00000100, 57762306a36Sopenharmony_ci 0x903c, 0xffffffff, 0x00000100, 57862306a36Sopenharmony_ci 0x9040, 0xffffffff, 0x00000100, 57962306a36Sopenharmony_ci 0xa200, 0xffffffff, 0x00000100, 58062306a36Sopenharmony_ci 0xa204, 0xffffffff, 0x00000100, 58162306a36Sopenharmony_ci 0xa208, 0xffffffff, 0x00000100, 58262306a36Sopenharmony_ci 0xa20c, 0xffffffff, 0x00000100, 58362306a36Sopenharmony_ci 0x971c, 0xffffffff, 0x00000100, 58462306a36Sopenharmony_ci 0x977c, 0xffffffff, 0x00000100, 58562306a36Sopenharmony_ci 0x3f80, 0xffffffff, 0x00000100, 58662306a36Sopenharmony_ci 0xa210, 0xffffffff, 0x00000100, 58762306a36Sopenharmony_ci 0xa214, 0xffffffff, 0x00000100, 58862306a36Sopenharmony_ci 0x4d8, 0xffffffff, 0x00000100, 58962306a36Sopenharmony_ci 0x9784, 0xffffffff, 0x00000100, 59062306a36Sopenharmony_ci 0x9698, 0xffffffff, 0x00000100, 59162306a36Sopenharmony_ci 0x4d4, 0xffffffff, 0x00000200, 59262306a36Sopenharmony_ci 0x30cc, 0xffffffff, 0x00000100, 59362306a36Sopenharmony_ci 0xd0c0, 0xffffffff, 0xff000100, 59462306a36Sopenharmony_ci 0x802c, 0xffffffff, 0x40000000, 59562306a36Sopenharmony_ci 0x915c, 0xffffffff, 0x00010000, 59662306a36Sopenharmony_ci 0x9178, 0xffffffff, 0x00050000, 59762306a36Sopenharmony_ci 0x917c, 0xffffffff, 0x00030002, 59862306a36Sopenharmony_ci 0x918c, 0xffffffff, 0x00010004, 59962306a36Sopenharmony_ci 0x9190, 0xffffffff, 0x00070006, 60062306a36Sopenharmony_ci 0x9194, 0xffffffff, 0x00050000, 60162306a36Sopenharmony_ci 0x9198, 0xffffffff, 0x00030002, 60262306a36Sopenharmony_ci 0x91a8, 0xffffffff, 0x00010004, 60362306a36Sopenharmony_ci 0x91ac, 0xffffffff, 0x00070006, 60462306a36Sopenharmony_ci 0x91e8, 0xffffffff, 0x00000000, 60562306a36Sopenharmony_ci 0x9294, 0xffffffff, 0x00000000, 60662306a36Sopenharmony_ci 0x929c, 0xffffffff, 0x00000001, 60762306a36Sopenharmony_ci 0x802c, 0xffffffff, 0xc0000000 60862306a36Sopenharmony_ci}; 60962306a36Sopenharmony_ci 61062306a36Sopenharmony_cistatic const u32 juniper_mgcg_init[] = 61162306a36Sopenharmony_ci{ 61262306a36Sopenharmony_ci 0x802c, 0xffffffff, 0xc0000000, 61362306a36Sopenharmony_ci 0x5448, 0xffffffff, 0x00000100, 61462306a36Sopenharmony_ci 0x55e4, 0xffffffff, 0x00000100, 61562306a36Sopenharmony_ci 0x160c, 0xffffffff, 0x00000100, 61662306a36Sopenharmony_ci 0x5644, 0xffffffff, 0x00000100, 61762306a36Sopenharmony_ci 0xc164, 0xffffffff, 0x00000100, 61862306a36Sopenharmony_ci 0x8a18, 0xffffffff, 0x00000100, 61962306a36Sopenharmony_ci 0x897c, 0xffffffff, 0x06000100, 62062306a36Sopenharmony_ci 0x8b28, 0xffffffff, 0x00000100, 62162306a36Sopenharmony_ci 0x9144, 0xffffffff, 0x00000100, 62262306a36Sopenharmony_ci 0x9a60, 0xffffffff, 0x00000100, 62362306a36Sopenharmony_ci 0x9868, 0xffffffff, 0x00000100, 62462306a36Sopenharmony_ci 0x8d58, 0xffffffff, 0x00000100, 62562306a36Sopenharmony_ci 0x9510, 0xffffffff, 0x00000100, 62662306a36Sopenharmony_ci 0x949c, 0xffffffff, 0x00000100, 62762306a36Sopenharmony_ci 0x9654, 0xffffffff, 0x00000100, 62862306a36Sopenharmony_ci 0x9030, 0xffffffff, 0x00000100, 62962306a36Sopenharmony_ci 0x9034, 0xffffffff, 0x00000100, 63062306a36Sopenharmony_ci 0x9038, 0xffffffff, 0x00000100, 63162306a36Sopenharmony_ci 0x903c, 0xffffffff, 0x00000100, 63262306a36Sopenharmony_ci 0x9040, 0xffffffff, 0x00000100, 63362306a36Sopenharmony_ci 0xa200, 0xffffffff, 0x00000100, 63462306a36Sopenharmony_ci 0xa204, 0xffffffff, 0x00000100, 63562306a36Sopenharmony_ci 0xa208, 0xffffffff, 0x00000100, 63662306a36Sopenharmony_ci 0xa20c, 0xffffffff, 0x00000100, 63762306a36Sopenharmony_ci 0x971c, 0xffffffff, 0x00000100, 63862306a36Sopenharmony_ci 0xd0c0, 0xffffffff, 0xff000100, 63962306a36Sopenharmony_ci 0x802c, 0xffffffff, 0x40000000, 64062306a36Sopenharmony_ci 0x915c, 0xffffffff, 0x00010000, 64162306a36Sopenharmony_ci 0x9160, 0xffffffff, 0x00030002, 64262306a36Sopenharmony_ci 0x9178, 0xffffffff, 0x00070000, 64362306a36Sopenharmony_ci 0x917c, 0xffffffff, 0x00030002, 64462306a36Sopenharmony_ci 0x9180, 0xffffffff, 0x00050004, 64562306a36Sopenharmony_ci 0x918c, 0xffffffff, 0x00010006, 64662306a36Sopenharmony_ci 0x9190, 0xffffffff, 0x00090008, 64762306a36Sopenharmony_ci 0x9194, 0xffffffff, 0x00070000, 64862306a36Sopenharmony_ci 0x9198, 0xffffffff, 0x00030002, 64962306a36Sopenharmony_ci 0x919c, 0xffffffff, 0x00050004, 65062306a36Sopenharmony_ci 0x91a8, 0xffffffff, 0x00010006, 65162306a36Sopenharmony_ci 0x91ac, 0xffffffff, 0x00090008, 65262306a36Sopenharmony_ci 0x91b0, 0xffffffff, 0x00070000, 65362306a36Sopenharmony_ci 0x91b4, 0xffffffff, 0x00030002, 65462306a36Sopenharmony_ci 0x91b8, 0xffffffff, 0x00050004, 65562306a36Sopenharmony_ci 0x91c4, 0xffffffff, 0x00010006, 65662306a36Sopenharmony_ci 0x91c8, 0xffffffff, 0x00090008, 65762306a36Sopenharmony_ci 0x91cc, 0xffffffff, 0x00070000, 65862306a36Sopenharmony_ci 0x91d0, 0xffffffff, 0x00030002, 65962306a36Sopenharmony_ci 0x91d4, 0xffffffff, 0x00050004, 66062306a36Sopenharmony_ci 0x91e0, 0xffffffff, 0x00010006, 66162306a36Sopenharmony_ci 0x91e4, 0xffffffff, 0x00090008, 66262306a36Sopenharmony_ci 0x91e8, 0xffffffff, 0x00000000, 66362306a36Sopenharmony_ci 0x91ec, 0xffffffff, 0x00070000, 66462306a36Sopenharmony_ci 0x91f0, 0xffffffff, 0x00030002, 66562306a36Sopenharmony_ci 0x91f4, 0xffffffff, 0x00050004, 66662306a36Sopenharmony_ci 0x9200, 0xffffffff, 0x00010006, 66762306a36Sopenharmony_ci 0x9204, 0xffffffff, 0x00090008, 66862306a36Sopenharmony_ci 0x9208, 0xffffffff, 0x00070000, 66962306a36Sopenharmony_ci 0x920c, 0xffffffff, 0x00030002, 67062306a36Sopenharmony_ci 0x9210, 0xffffffff, 0x00050004, 67162306a36Sopenharmony_ci 0x921c, 0xffffffff, 0x00010006, 67262306a36Sopenharmony_ci 0x9220, 0xffffffff, 0x00090008, 67362306a36Sopenharmony_ci 0x9224, 0xffffffff, 0x00070000, 67462306a36Sopenharmony_ci 0x9228, 0xffffffff, 0x00030002, 67562306a36Sopenharmony_ci 0x922c, 0xffffffff, 0x00050004, 67662306a36Sopenharmony_ci 0x9238, 0xffffffff, 0x00010006, 67762306a36Sopenharmony_ci 0x923c, 0xffffffff, 0x00090008, 67862306a36Sopenharmony_ci 0x9240, 0xffffffff, 0x00070000, 67962306a36Sopenharmony_ci 0x9244, 0xffffffff, 0x00030002, 68062306a36Sopenharmony_ci 0x9248, 0xffffffff, 0x00050004, 68162306a36Sopenharmony_ci 0x9254, 0xffffffff, 0x00010006, 68262306a36Sopenharmony_ci 0x9258, 0xffffffff, 0x00090008, 68362306a36Sopenharmony_ci 0x925c, 0xffffffff, 0x00070000, 68462306a36Sopenharmony_ci 0x9260, 0xffffffff, 0x00030002, 68562306a36Sopenharmony_ci 0x9264, 0xffffffff, 0x00050004, 68662306a36Sopenharmony_ci 0x9270, 0xffffffff, 0x00010006, 68762306a36Sopenharmony_ci 0x9274, 0xffffffff, 0x00090008, 68862306a36Sopenharmony_ci 0x9278, 0xffffffff, 0x00070000, 68962306a36Sopenharmony_ci 0x927c, 0xffffffff, 0x00030002, 69062306a36Sopenharmony_ci 0x9280, 0xffffffff, 0x00050004, 69162306a36Sopenharmony_ci 0x928c, 0xffffffff, 0x00010006, 69262306a36Sopenharmony_ci 0x9290, 0xffffffff, 0x00090008, 69362306a36Sopenharmony_ci 0x9294, 0xffffffff, 0x00000000, 69462306a36Sopenharmony_ci 0x929c, 0xffffffff, 0x00000001, 69562306a36Sopenharmony_ci 0x802c, 0xffffffff, 0xc0000000, 69662306a36Sopenharmony_ci 0x977c, 0xffffffff, 0x00000100, 69762306a36Sopenharmony_ci 0x3f80, 0xffffffff, 0x00000100, 69862306a36Sopenharmony_ci 0xa210, 0xffffffff, 0x00000100, 69962306a36Sopenharmony_ci 0xa214, 0xffffffff, 0x00000100, 70062306a36Sopenharmony_ci 0x4d8, 0xffffffff, 0x00000100, 70162306a36Sopenharmony_ci 0x9784, 0xffffffff, 0x00000100, 70262306a36Sopenharmony_ci 0x9698, 0xffffffff, 0x00000100, 70362306a36Sopenharmony_ci 0x4d4, 0xffffffff, 0x00000200, 70462306a36Sopenharmony_ci 0x30cc, 0xffffffff, 0x00000100, 70562306a36Sopenharmony_ci 0x802c, 0xffffffff, 0xc0000000 70662306a36Sopenharmony_ci}; 70762306a36Sopenharmony_ci 70862306a36Sopenharmony_cistatic const u32 supersumo_golden_registers[] = 70962306a36Sopenharmony_ci{ 71062306a36Sopenharmony_ci 0x5eb4, 0xffffffff, 0x00000002, 71162306a36Sopenharmony_ci 0x5c4, 0xffffffff, 0x00000001, 71262306a36Sopenharmony_ci 0x7030, 0xffffffff, 0x00000011, 71362306a36Sopenharmony_ci 0x7c30, 0xffffffff, 0x00000011, 71462306a36Sopenharmony_ci 0x6104, 0x01000300, 0x00000000, 71562306a36Sopenharmony_ci 0x5bc0, 0x00300000, 0x00000000, 71662306a36Sopenharmony_ci 0x8c04, 0xffffffff, 0x40600060, 71762306a36Sopenharmony_ci 0x8c08, 0xffffffff, 0x001c001c, 71862306a36Sopenharmony_ci 0x8c20, 0xffffffff, 0x00800080, 71962306a36Sopenharmony_ci 0x8c24, 0xffffffff, 0x00800080, 72062306a36Sopenharmony_ci 0x8c18, 0xffffffff, 0x20202078, 72162306a36Sopenharmony_ci 0x8c1c, 0xffffffff, 0x00001010, 72262306a36Sopenharmony_ci 0x918c, 0xffffffff, 0x00010006, 72362306a36Sopenharmony_ci 0x91a8, 0xffffffff, 0x00010006, 72462306a36Sopenharmony_ci 0x91c4, 0xffffffff, 0x00010006, 72562306a36Sopenharmony_ci 0x91e0, 0xffffffff, 0x00010006, 72662306a36Sopenharmony_ci 0x9200, 0xffffffff, 0x00010006, 72762306a36Sopenharmony_ci 0x9150, 0xffffffff, 0x6e944040, 72862306a36Sopenharmony_ci 0x917c, 0xffffffff, 0x00030002, 72962306a36Sopenharmony_ci 0x9180, 0xffffffff, 0x00050004, 73062306a36Sopenharmony_ci 0x9198, 0xffffffff, 0x00030002, 73162306a36Sopenharmony_ci 0x919c, 0xffffffff, 0x00050004, 73262306a36Sopenharmony_ci 0x91b4, 0xffffffff, 0x00030002, 73362306a36Sopenharmony_ci 0x91b8, 0xffffffff, 0x00050004, 73462306a36Sopenharmony_ci 0x91d0, 0xffffffff, 0x00030002, 73562306a36Sopenharmony_ci 0x91d4, 0xffffffff, 0x00050004, 73662306a36Sopenharmony_ci 0x91f0, 0xffffffff, 0x00030002, 73762306a36Sopenharmony_ci 0x91f4, 0xffffffff, 0x00050004, 73862306a36Sopenharmony_ci 0x915c, 0xffffffff, 0x00010000, 73962306a36Sopenharmony_ci 0x9160, 0xffffffff, 0x00030002, 74062306a36Sopenharmony_ci 0x3f90, 0xffff0000, 0xff000000, 74162306a36Sopenharmony_ci 0x9178, 0xffffffff, 0x00070000, 74262306a36Sopenharmony_ci 0x9194, 0xffffffff, 0x00070000, 74362306a36Sopenharmony_ci 0x91b0, 0xffffffff, 0x00070000, 74462306a36Sopenharmony_ci 0x91cc, 0xffffffff, 0x00070000, 74562306a36Sopenharmony_ci 0x91ec, 0xffffffff, 0x00070000, 74662306a36Sopenharmony_ci 0x9148, 0xffff0000, 0xff000000, 74762306a36Sopenharmony_ci 0x9190, 0xffffffff, 0x00090008, 74862306a36Sopenharmony_ci 0x91ac, 0xffffffff, 0x00090008, 74962306a36Sopenharmony_ci 0x91c8, 0xffffffff, 0x00090008, 75062306a36Sopenharmony_ci 0x91e4, 0xffffffff, 0x00090008, 75162306a36Sopenharmony_ci 0x9204, 0xffffffff, 0x00090008, 75262306a36Sopenharmony_ci 0x3f94, 0xffff0000, 0xff000000, 75362306a36Sopenharmony_ci 0x914c, 0xffff0000, 0xff000000, 75462306a36Sopenharmony_ci 0x929c, 0xffffffff, 0x00000001, 75562306a36Sopenharmony_ci 0x8a18, 0xffffffff, 0x00000100, 75662306a36Sopenharmony_ci 0x8b28, 0xffffffff, 0x00000100, 75762306a36Sopenharmony_ci 0x9144, 0xffffffff, 0x00000100, 75862306a36Sopenharmony_ci 0x5644, 0xffffffff, 0x00000100, 75962306a36Sopenharmony_ci 0x9b7c, 0xffffffff, 0x00000000, 76062306a36Sopenharmony_ci 0x8030, 0xffffffff, 0x0000100a, 76162306a36Sopenharmony_ci 0x8a14, 0xffffffff, 0x00000007, 76262306a36Sopenharmony_ci 0x8b24, 0xffffffff, 0x00ff0fff, 76362306a36Sopenharmony_ci 0x8b10, 0xffffffff, 0x00000000, 76462306a36Sopenharmony_ci 0x28a4c, 0x06000000, 0x06000000, 76562306a36Sopenharmony_ci 0x4d8, 0xffffffff, 0x00000100, 76662306a36Sopenharmony_ci 0x913c, 0xffff000f, 0x0100000a, 76762306a36Sopenharmony_ci 0x960c, 0xffffffff, 0x54763210, 76862306a36Sopenharmony_ci 0x88c4, 0xffffffff, 0x000000c2, 76962306a36Sopenharmony_ci 0x88d4, 0xffffffff, 0x00000010, 77062306a36Sopenharmony_ci 0x8974, 0xffffffff, 0x00000000, 77162306a36Sopenharmony_ci 0xc78, 0x00000080, 0x00000080, 77262306a36Sopenharmony_ci 0x5e78, 0xffffffff, 0x001000f0, 77362306a36Sopenharmony_ci 0xd02c, 0xffffffff, 0x08421000, 77462306a36Sopenharmony_ci 0xa008, 0xffffffff, 0x00010000, 77562306a36Sopenharmony_ci 0x8d00, 0xffffffff, 0x100e4848, 77662306a36Sopenharmony_ci 0x8d04, 0xffffffff, 0x00164745, 77762306a36Sopenharmony_ci 0x8c00, 0xffffffff, 0xe4000003, 77862306a36Sopenharmony_ci 0x8cf0, 0x1fffffff, 0x08e00620, 77962306a36Sopenharmony_ci 0x28350, 0xffffffff, 0x00000000, 78062306a36Sopenharmony_ci 0x9508, 0xffffffff, 0x00000002 78162306a36Sopenharmony_ci}; 78262306a36Sopenharmony_ci 78362306a36Sopenharmony_cistatic const u32 sumo_golden_registers[] = 78462306a36Sopenharmony_ci{ 78562306a36Sopenharmony_ci 0x900c, 0x00ffffff, 0x0017071f, 78662306a36Sopenharmony_ci 0x8c18, 0xffffffff, 0x10101060, 78762306a36Sopenharmony_ci 0x8c1c, 0xffffffff, 0x00001010, 78862306a36Sopenharmony_ci 0x8c30, 0x0000000f, 0x00000005, 78962306a36Sopenharmony_ci 0x9688, 0x0000000f, 0x00000007 79062306a36Sopenharmony_ci}; 79162306a36Sopenharmony_ci 79262306a36Sopenharmony_cistatic const u32 wrestler_golden_registers[] = 79362306a36Sopenharmony_ci{ 79462306a36Sopenharmony_ci 0x5eb4, 0xffffffff, 0x00000002, 79562306a36Sopenharmony_ci 0x5c4, 0xffffffff, 0x00000001, 79662306a36Sopenharmony_ci 0x7030, 0xffffffff, 0x00000011, 79762306a36Sopenharmony_ci 0x7c30, 0xffffffff, 0x00000011, 79862306a36Sopenharmony_ci 0x6104, 0x01000300, 0x00000000, 79962306a36Sopenharmony_ci 0x5bc0, 0x00300000, 0x00000000, 80062306a36Sopenharmony_ci 0x918c, 0xffffffff, 0x00010006, 80162306a36Sopenharmony_ci 0x91a8, 0xffffffff, 0x00010006, 80262306a36Sopenharmony_ci 0x9150, 0xffffffff, 0x6e944040, 80362306a36Sopenharmony_ci 0x917c, 0xffffffff, 0x00030002, 80462306a36Sopenharmony_ci 0x9198, 0xffffffff, 0x00030002, 80562306a36Sopenharmony_ci 0x915c, 0xffffffff, 0x00010000, 80662306a36Sopenharmony_ci 0x3f90, 0xffff0000, 0xff000000, 80762306a36Sopenharmony_ci 0x9178, 0xffffffff, 0x00070000, 80862306a36Sopenharmony_ci 0x9194, 0xffffffff, 0x00070000, 80962306a36Sopenharmony_ci 0x9148, 0xffff0000, 0xff000000, 81062306a36Sopenharmony_ci 0x9190, 0xffffffff, 0x00090008, 81162306a36Sopenharmony_ci 0x91ac, 0xffffffff, 0x00090008, 81262306a36Sopenharmony_ci 0x3f94, 0xffff0000, 0xff000000, 81362306a36Sopenharmony_ci 0x914c, 0xffff0000, 0xff000000, 81462306a36Sopenharmony_ci 0x929c, 0xffffffff, 0x00000001, 81562306a36Sopenharmony_ci 0x8a18, 0xffffffff, 0x00000100, 81662306a36Sopenharmony_ci 0x8b28, 0xffffffff, 0x00000100, 81762306a36Sopenharmony_ci 0x9144, 0xffffffff, 0x00000100, 81862306a36Sopenharmony_ci 0x9b7c, 0xffffffff, 0x00000000, 81962306a36Sopenharmony_ci 0x8030, 0xffffffff, 0x0000100a, 82062306a36Sopenharmony_ci 0x8a14, 0xffffffff, 0x00000001, 82162306a36Sopenharmony_ci 0x8b24, 0xffffffff, 0x00ff0fff, 82262306a36Sopenharmony_ci 0x8b10, 0xffffffff, 0x00000000, 82362306a36Sopenharmony_ci 0x28a4c, 0x06000000, 0x06000000, 82462306a36Sopenharmony_ci 0x4d8, 0xffffffff, 0x00000100, 82562306a36Sopenharmony_ci 0x913c, 0xffff000f, 0x0100000a, 82662306a36Sopenharmony_ci 0x960c, 0xffffffff, 0x54763210, 82762306a36Sopenharmony_ci 0x88c4, 0xffffffff, 0x000000c2, 82862306a36Sopenharmony_ci 0x88d4, 0xffffffff, 0x00000010, 82962306a36Sopenharmony_ci 0x8974, 0xffffffff, 0x00000000, 83062306a36Sopenharmony_ci 0xc78, 0x00000080, 0x00000080, 83162306a36Sopenharmony_ci 0x5e78, 0xffffffff, 0x001000f0, 83262306a36Sopenharmony_ci 0xd02c, 0xffffffff, 0x08421000, 83362306a36Sopenharmony_ci 0xa008, 0xffffffff, 0x00010000, 83462306a36Sopenharmony_ci 0x8d00, 0xffffffff, 0x100e4848, 83562306a36Sopenharmony_ci 0x8d04, 0xffffffff, 0x00164745, 83662306a36Sopenharmony_ci 0x8c00, 0xffffffff, 0xe4000003, 83762306a36Sopenharmony_ci 0x8cf0, 0x1fffffff, 0x08e00410, 83862306a36Sopenharmony_ci 0x28350, 0xffffffff, 0x00000000, 83962306a36Sopenharmony_ci 0x9508, 0xffffffff, 0x00000002, 84062306a36Sopenharmony_ci 0x900c, 0xffffffff, 0x0017071f, 84162306a36Sopenharmony_ci 0x8c18, 0xffffffff, 0x10101060, 84262306a36Sopenharmony_ci 0x8c1c, 0xffffffff, 0x00001010 84362306a36Sopenharmony_ci}; 84462306a36Sopenharmony_ci 84562306a36Sopenharmony_cistatic const u32 barts_golden_registers[] = 84662306a36Sopenharmony_ci{ 84762306a36Sopenharmony_ci 0x5eb4, 0xffffffff, 0x00000002, 84862306a36Sopenharmony_ci 0x5e78, 0x8f311ff1, 0x001000f0, 84962306a36Sopenharmony_ci 0x3f90, 0xffff0000, 0xff000000, 85062306a36Sopenharmony_ci 0x9148, 0xffff0000, 0xff000000, 85162306a36Sopenharmony_ci 0x3f94, 0xffff0000, 0xff000000, 85262306a36Sopenharmony_ci 0x914c, 0xffff0000, 0xff000000, 85362306a36Sopenharmony_ci 0xc78, 0x00000080, 0x00000080, 85462306a36Sopenharmony_ci 0xbd4, 0x70073777, 0x00010001, 85562306a36Sopenharmony_ci 0xd02c, 0xbfffff1f, 0x08421000, 85662306a36Sopenharmony_ci 0xd0b8, 0x03773777, 0x02011003, 85762306a36Sopenharmony_ci 0x5bc0, 0x00200000, 0x50100000, 85862306a36Sopenharmony_ci 0x98f8, 0x33773777, 0x02011003, 85962306a36Sopenharmony_ci 0x98fc, 0xffffffff, 0x76543210, 86062306a36Sopenharmony_ci 0x7030, 0x31000311, 0x00000011, 86162306a36Sopenharmony_ci 0x2f48, 0x00000007, 0x02011003, 86262306a36Sopenharmony_ci 0x6b28, 0x00000010, 0x00000012, 86362306a36Sopenharmony_ci 0x7728, 0x00000010, 0x00000012, 86462306a36Sopenharmony_ci 0x10328, 0x00000010, 0x00000012, 86562306a36Sopenharmony_ci 0x10f28, 0x00000010, 0x00000012, 86662306a36Sopenharmony_ci 0x11b28, 0x00000010, 0x00000012, 86762306a36Sopenharmony_ci 0x12728, 0x00000010, 0x00000012, 86862306a36Sopenharmony_ci 0x240c, 0x000007ff, 0x00000380, 86962306a36Sopenharmony_ci 0x8a14, 0xf000001f, 0x00000007, 87062306a36Sopenharmony_ci 0x8b24, 0x3fff3fff, 0x00ff0fff, 87162306a36Sopenharmony_ci 0x8b10, 0x0000ff0f, 0x00000000, 87262306a36Sopenharmony_ci 0x28a4c, 0x07ffffff, 0x06000000, 87362306a36Sopenharmony_ci 0x10c, 0x00000001, 0x00010003, 87462306a36Sopenharmony_ci 0xa02c, 0xffffffff, 0x0000009b, 87562306a36Sopenharmony_ci 0x913c, 0x0000000f, 0x0100000a, 87662306a36Sopenharmony_ci 0x8d00, 0xffff7f7f, 0x100e4848, 87762306a36Sopenharmony_ci 0x8d04, 0x00ffffff, 0x00164745, 87862306a36Sopenharmony_ci 0x8c00, 0xfffc0003, 0xe4000003, 87962306a36Sopenharmony_ci 0x8c04, 0xf8ff00ff, 0x40600060, 88062306a36Sopenharmony_ci 0x8c08, 0x00ff00ff, 0x001c001c, 88162306a36Sopenharmony_ci 0x8cf0, 0x1fff1fff, 0x08e00620, 88262306a36Sopenharmony_ci 0x8c20, 0x0fff0fff, 0x00800080, 88362306a36Sopenharmony_ci 0x8c24, 0x0fff0fff, 0x00800080, 88462306a36Sopenharmony_ci 0x8c18, 0xffffffff, 0x20202078, 88562306a36Sopenharmony_ci 0x8c1c, 0x0000ffff, 0x00001010, 88662306a36Sopenharmony_ci 0x28350, 0x00000f01, 0x00000000, 88762306a36Sopenharmony_ci 0x9508, 0x3700001f, 0x00000002, 88862306a36Sopenharmony_ci 0x960c, 0xffffffff, 0x54763210, 88962306a36Sopenharmony_ci 0x88c4, 0x001f3ae3, 0x000000c2, 89062306a36Sopenharmony_ci 0x88d4, 0x0000001f, 0x00000010, 89162306a36Sopenharmony_ci 0x8974, 0xffffffff, 0x00000000 89262306a36Sopenharmony_ci}; 89362306a36Sopenharmony_ci 89462306a36Sopenharmony_cistatic const u32 turks_golden_registers[] = 89562306a36Sopenharmony_ci{ 89662306a36Sopenharmony_ci 0x5eb4, 0xffffffff, 0x00000002, 89762306a36Sopenharmony_ci 0x5e78, 0x8f311ff1, 0x001000f0, 89862306a36Sopenharmony_ci 0x8c8, 0x00003000, 0x00001070, 89962306a36Sopenharmony_ci 0x8cc, 0x000fffff, 0x00040035, 90062306a36Sopenharmony_ci 0x3f90, 0xffff0000, 0xfff00000, 90162306a36Sopenharmony_ci 0x9148, 0xffff0000, 0xfff00000, 90262306a36Sopenharmony_ci 0x3f94, 0xffff0000, 0xfff00000, 90362306a36Sopenharmony_ci 0x914c, 0xffff0000, 0xfff00000, 90462306a36Sopenharmony_ci 0xc78, 0x00000080, 0x00000080, 90562306a36Sopenharmony_ci 0xbd4, 0x00073007, 0x00010002, 90662306a36Sopenharmony_ci 0xd02c, 0xbfffff1f, 0x08421000, 90762306a36Sopenharmony_ci 0xd0b8, 0x03773777, 0x02010002, 90862306a36Sopenharmony_ci 0x5bc0, 0x00200000, 0x50100000, 90962306a36Sopenharmony_ci 0x98f8, 0x33773777, 0x00010002, 91062306a36Sopenharmony_ci 0x98fc, 0xffffffff, 0x33221100, 91162306a36Sopenharmony_ci 0x7030, 0x31000311, 0x00000011, 91262306a36Sopenharmony_ci 0x2f48, 0x33773777, 0x00010002, 91362306a36Sopenharmony_ci 0x6b28, 0x00000010, 0x00000012, 91462306a36Sopenharmony_ci 0x7728, 0x00000010, 0x00000012, 91562306a36Sopenharmony_ci 0x10328, 0x00000010, 0x00000012, 91662306a36Sopenharmony_ci 0x10f28, 0x00000010, 0x00000012, 91762306a36Sopenharmony_ci 0x11b28, 0x00000010, 0x00000012, 91862306a36Sopenharmony_ci 0x12728, 0x00000010, 0x00000012, 91962306a36Sopenharmony_ci 0x240c, 0x000007ff, 0x00000380, 92062306a36Sopenharmony_ci 0x8a14, 0xf000001f, 0x00000007, 92162306a36Sopenharmony_ci 0x8b24, 0x3fff3fff, 0x00ff0fff, 92262306a36Sopenharmony_ci 0x8b10, 0x0000ff0f, 0x00000000, 92362306a36Sopenharmony_ci 0x28a4c, 0x07ffffff, 0x06000000, 92462306a36Sopenharmony_ci 0x10c, 0x00000001, 0x00010003, 92562306a36Sopenharmony_ci 0xa02c, 0xffffffff, 0x0000009b, 92662306a36Sopenharmony_ci 0x913c, 0x0000000f, 0x0100000a, 92762306a36Sopenharmony_ci 0x8d00, 0xffff7f7f, 0x100e4848, 92862306a36Sopenharmony_ci 0x8d04, 0x00ffffff, 0x00164745, 92962306a36Sopenharmony_ci 0x8c00, 0xfffc0003, 0xe4000003, 93062306a36Sopenharmony_ci 0x8c04, 0xf8ff00ff, 0x40600060, 93162306a36Sopenharmony_ci 0x8c08, 0x00ff00ff, 0x001c001c, 93262306a36Sopenharmony_ci 0x8cf0, 0x1fff1fff, 0x08e00410, 93362306a36Sopenharmony_ci 0x8c20, 0x0fff0fff, 0x00800080, 93462306a36Sopenharmony_ci 0x8c24, 0x0fff0fff, 0x00800080, 93562306a36Sopenharmony_ci 0x8c18, 0xffffffff, 0x20202078, 93662306a36Sopenharmony_ci 0x8c1c, 0x0000ffff, 0x00001010, 93762306a36Sopenharmony_ci 0x28350, 0x00000f01, 0x00000000, 93862306a36Sopenharmony_ci 0x9508, 0x3700001f, 0x00000002, 93962306a36Sopenharmony_ci 0x960c, 0xffffffff, 0x54763210, 94062306a36Sopenharmony_ci 0x88c4, 0x001f3ae3, 0x000000c2, 94162306a36Sopenharmony_ci 0x88d4, 0x0000001f, 0x00000010, 94262306a36Sopenharmony_ci 0x8974, 0xffffffff, 0x00000000 94362306a36Sopenharmony_ci}; 94462306a36Sopenharmony_ci 94562306a36Sopenharmony_cistatic const u32 caicos_golden_registers[] = 94662306a36Sopenharmony_ci{ 94762306a36Sopenharmony_ci 0x5eb4, 0xffffffff, 0x00000002, 94862306a36Sopenharmony_ci 0x5e78, 0x8f311ff1, 0x001000f0, 94962306a36Sopenharmony_ci 0x8c8, 0x00003420, 0x00001450, 95062306a36Sopenharmony_ci 0x8cc, 0x000fffff, 0x00040035, 95162306a36Sopenharmony_ci 0x3f90, 0xffff0000, 0xfffc0000, 95262306a36Sopenharmony_ci 0x9148, 0xffff0000, 0xfffc0000, 95362306a36Sopenharmony_ci 0x3f94, 0xffff0000, 0xfffc0000, 95462306a36Sopenharmony_ci 0x914c, 0xffff0000, 0xfffc0000, 95562306a36Sopenharmony_ci 0xc78, 0x00000080, 0x00000080, 95662306a36Sopenharmony_ci 0xbd4, 0x00073007, 0x00010001, 95762306a36Sopenharmony_ci 0xd02c, 0xbfffff1f, 0x08421000, 95862306a36Sopenharmony_ci 0xd0b8, 0x03773777, 0x02010001, 95962306a36Sopenharmony_ci 0x5bc0, 0x00200000, 0x50100000, 96062306a36Sopenharmony_ci 0x98f8, 0x33773777, 0x02010001, 96162306a36Sopenharmony_ci 0x98fc, 0xffffffff, 0x33221100, 96262306a36Sopenharmony_ci 0x7030, 0x31000311, 0x00000011, 96362306a36Sopenharmony_ci 0x2f48, 0x33773777, 0x02010001, 96462306a36Sopenharmony_ci 0x6b28, 0x00000010, 0x00000012, 96562306a36Sopenharmony_ci 0x7728, 0x00000010, 0x00000012, 96662306a36Sopenharmony_ci 0x10328, 0x00000010, 0x00000012, 96762306a36Sopenharmony_ci 0x10f28, 0x00000010, 0x00000012, 96862306a36Sopenharmony_ci 0x11b28, 0x00000010, 0x00000012, 96962306a36Sopenharmony_ci 0x12728, 0x00000010, 0x00000012, 97062306a36Sopenharmony_ci 0x240c, 0x000007ff, 0x00000380, 97162306a36Sopenharmony_ci 0x8a14, 0xf000001f, 0x00000001, 97262306a36Sopenharmony_ci 0x8b24, 0x3fff3fff, 0x00ff0fff, 97362306a36Sopenharmony_ci 0x8b10, 0x0000ff0f, 0x00000000, 97462306a36Sopenharmony_ci 0x28a4c, 0x07ffffff, 0x06000000, 97562306a36Sopenharmony_ci 0x10c, 0x00000001, 0x00010003, 97662306a36Sopenharmony_ci 0xa02c, 0xffffffff, 0x0000009b, 97762306a36Sopenharmony_ci 0x913c, 0x0000000f, 0x0100000a, 97862306a36Sopenharmony_ci 0x8d00, 0xffff7f7f, 0x100e4848, 97962306a36Sopenharmony_ci 0x8d04, 0x00ffffff, 0x00164745, 98062306a36Sopenharmony_ci 0x8c00, 0xfffc0003, 0xe4000003, 98162306a36Sopenharmony_ci 0x8c04, 0xf8ff00ff, 0x40600060, 98262306a36Sopenharmony_ci 0x8c08, 0x00ff00ff, 0x001c001c, 98362306a36Sopenharmony_ci 0x8cf0, 0x1fff1fff, 0x08e00410, 98462306a36Sopenharmony_ci 0x8c20, 0x0fff0fff, 0x00800080, 98562306a36Sopenharmony_ci 0x8c24, 0x0fff0fff, 0x00800080, 98662306a36Sopenharmony_ci 0x8c18, 0xffffffff, 0x20202078, 98762306a36Sopenharmony_ci 0x8c1c, 0x0000ffff, 0x00001010, 98862306a36Sopenharmony_ci 0x28350, 0x00000f01, 0x00000000, 98962306a36Sopenharmony_ci 0x9508, 0x3700001f, 0x00000002, 99062306a36Sopenharmony_ci 0x960c, 0xffffffff, 0x54763210, 99162306a36Sopenharmony_ci 0x88c4, 0x001f3ae3, 0x000000c2, 99262306a36Sopenharmony_ci 0x88d4, 0x0000001f, 0x00000010, 99362306a36Sopenharmony_ci 0x8974, 0xffffffff, 0x00000000 99462306a36Sopenharmony_ci}; 99562306a36Sopenharmony_ci 99662306a36Sopenharmony_cistatic void evergreen_init_golden_registers(struct radeon_device *rdev) 99762306a36Sopenharmony_ci{ 99862306a36Sopenharmony_ci switch (rdev->family) { 99962306a36Sopenharmony_ci case CHIP_CYPRESS: 100062306a36Sopenharmony_ci case CHIP_HEMLOCK: 100162306a36Sopenharmony_ci radeon_program_register_sequence(rdev, 100262306a36Sopenharmony_ci evergreen_golden_registers, 100362306a36Sopenharmony_ci (const u32)ARRAY_SIZE(evergreen_golden_registers)); 100462306a36Sopenharmony_ci radeon_program_register_sequence(rdev, 100562306a36Sopenharmony_ci evergreen_golden_registers2, 100662306a36Sopenharmony_ci (const u32)ARRAY_SIZE(evergreen_golden_registers2)); 100762306a36Sopenharmony_ci radeon_program_register_sequence(rdev, 100862306a36Sopenharmony_ci cypress_mgcg_init, 100962306a36Sopenharmony_ci (const u32)ARRAY_SIZE(cypress_mgcg_init)); 101062306a36Sopenharmony_ci break; 101162306a36Sopenharmony_ci case CHIP_JUNIPER: 101262306a36Sopenharmony_ci radeon_program_register_sequence(rdev, 101362306a36Sopenharmony_ci evergreen_golden_registers, 101462306a36Sopenharmony_ci (const u32)ARRAY_SIZE(evergreen_golden_registers)); 101562306a36Sopenharmony_ci radeon_program_register_sequence(rdev, 101662306a36Sopenharmony_ci evergreen_golden_registers2, 101762306a36Sopenharmony_ci (const u32)ARRAY_SIZE(evergreen_golden_registers2)); 101862306a36Sopenharmony_ci radeon_program_register_sequence(rdev, 101962306a36Sopenharmony_ci juniper_mgcg_init, 102062306a36Sopenharmony_ci (const u32)ARRAY_SIZE(juniper_mgcg_init)); 102162306a36Sopenharmony_ci break; 102262306a36Sopenharmony_ci case CHIP_REDWOOD: 102362306a36Sopenharmony_ci radeon_program_register_sequence(rdev, 102462306a36Sopenharmony_ci evergreen_golden_registers, 102562306a36Sopenharmony_ci (const u32)ARRAY_SIZE(evergreen_golden_registers)); 102662306a36Sopenharmony_ci radeon_program_register_sequence(rdev, 102762306a36Sopenharmony_ci evergreen_golden_registers2, 102862306a36Sopenharmony_ci (const u32)ARRAY_SIZE(evergreen_golden_registers2)); 102962306a36Sopenharmony_ci radeon_program_register_sequence(rdev, 103062306a36Sopenharmony_ci redwood_mgcg_init, 103162306a36Sopenharmony_ci (const u32)ARRAY_SIZE(redwood_mgcg_init)); 103262306a36Sopenharmony_ci break; 103362306a36Sopenharmony_ci case CHIP_CEDAR: 103462306a36Sopenharmony_ci radeon_program_register_sequence(rdev, 103562306a36Sopenharmony_ci cedar_golden_registers, 103662306a36Sopenharmony_ci (const u32)ARRAY_SIZE(cedar_golden_registers)); 103762306a36Sopenharmony_ci radeon_program_register_sequence(rdev, 103862306a36Sopenharmony_ci evergreen_golden_registers2, 103962306a36Sopenharmony_ci (const u32)ARRAY_SIZE(evergreen_golden_registers2)); 104062306a36Sopenharmony_ci radeon_program_register_sequence(rdev, 104162306a36Sopenharmony_ci cedar_mgcg_init, 104262306a36Sopenharmony_ci (const u32)ARRAY_SIZE(cedar_mgcg_init)); 104362306a36Sopenharmony_ci break; 104462306a36Sopenharmony_ci case CHIP_PALM: 104562306a36Sopenharmony_ci radeon_program_register_sequence(rdev, 104662306a36Sopenharmony_ci wrestler_golden_registers, 104762306a36Sopenharmony_ci (const u32)ARRAY_SIZE(wrestler_golden_registers)); 104862306a36Sopenharmony_ci break; 104962306a36Sopenharmony_ci case CHIP_SUMO: 105062306a36Sopenharmony_ci radeon_program_register_sequence(rdev, 105162306a36Sopenharmony_ci supersumo_golden_registers, 105262306a36Sopenharmony_ci (const u32)ARRAY_SIZE(supersumo_golden_registers)); 105362306a36Sopenharmony_ci break; 105462306a36Sopenharmony_ci case CHIP_SUMO2: 105562306a36Sopenharmony_ci radeon_program_register_sequence(rdev, 105662306a36Sopenharmony_ci supersumo_golden_registers, 105762306a36Sopenharmony_ci (const u32)ARRAY_SIZE(supersumo_golden_registers)); 105862306a36Sopenharmony_ci radeon_program_register_sequence(rdev, 105962306a36Sopenharmony_ci sumo_golden_registers, 106062306a36Sopenharmony_ci (const u32)ARRAY_SIZE(sumo_golden_registers)); 106162306a36Sopenharmony_ci break; 106262306a36Sopenharmony_ci case CHIP_BARTS: 106362306a36Sopenharmony_ci radeon_program_register_sequence(rdev, 106462306a36Sopenharmony_ci barts_golden_registers, 106562306a36Sopenharmony_ci (const u32)ARRAY_SIZE(barts_golden_registers)); 106662306a36Sopenharmony_ci break; 106762306a36Sopenharmony_ci case CHIP_TURKS: 106862306a36Sopenharmony_ci radeon_program_register_sequence(rdev, 106962306a36Sopenharmony_ci turks_golden_registers, 107062306a36Sopenharmony_ci (const u32)ARRAY_SIZE(turks_golden_registers)); 107162306a36Sopenharmony_ci break; 107262306a36Sopenharmony_ci case CHIP_CAICOS: 107362306a36Sopenharmony_ci radeon_program_register_sequence(rdev, 107462306a36Sopenharmony_ci caicos_golden_registers, 107562306a36Sopenharmony_ci (const u32)ARRAY_SIZE(caicos_golden_registers)); 107662306a36Sopenharmony_ci break; 107762306a36Sopenharmony_ci default: 107862306a36Sopenharmony_ci break; 107962306a36Sopenharmony_ci } 108062306a36Sopenharmony_ci} 108162306a36Sopenharmony_ci 108262306a36Sopenharmony_ci/** 108362306a36Sopenharmony_ci * evergreen_get_allowed_info_register - fetch the register for the info ioctl 108462306a36Sopenharmony_ci * 108562306a36Sopenharmony_ci * @rdev: radeon_device pointer 108662306a36Sopenharmony_ci * @reg: register offset in bytes 108762306a36Sopenharmony_ci * @val: register value 108862306a36Sopenharmony_ci * 108962306a36Sopenharmony_ci * Returns 0 for success or -EINVAL for an invalid register 109062306a36Sopenharmony_ci * 109162306a36Sopenharmony_ci */ 109262306a36Sopenharmony_ciint evergreen_get_allowed_info_register(struct radeon_device *rdev, 109362306a36Sopenharmony_ci u32 reg, u32 *val) 109462306a36Sopenharmony_ci{ 109562306a36Sopenharmony_ci switch (reg) { 109662306a36Sopenharmony_ci case GRBM_STATUS: 109762306a36Sopenharmony_ci case GRBM_STATUS_SE0: 109862306a36Sopenharmony_ci case GRBM_STATUS_SE1: 109962306a36Sopenharmony_ci case SRBM_STATUS: 110062306a36Sopenharmony_ci case SRBM_STATUS2: 110162306a36Sopenharmony_ci case DMA_STATUS_REG: 110262306a36Sopenharmony_ci case UVD_STATUS: 110362306a36Sopenharmony_ci *val = RREG32(reg); 110462306a36Sopenharmony_ci return 0; 110562306a36Sopenharmony_ci default: 110662306a36Sopenharmony_ci return -EINVAL; 110762306a36Sopenharmony_ci } 110862306a36Sopenharmony_ci} 110962306a36Sopenharmony_ci 111062306a36Sopenharmony_civoid evergreen_tiling_fields(unsigned tiling_flags, unsigned *bankw, 111162306a36Sopenharmony_ci unsigned *bankh, unsigned *mtaspect, 111262306a36Sopenharmony_ci unsigned *tile_split) 111362306a36Sopenharmony_ci{ 111462306a36Sopenharmony_ci *bankw = (tiling_flags >> RADEON_TILING_EG_BANKW_SHIFT) & RADEON_TILING_EG_BANKW_MASK; 111562306a36Sopenharmony_ci *bankh = (tiling_flags >> RADEON_TILING_EG_BANKH_SHIFT) & RADEON_TILING_EG_BANKH_MASK; 111662306a36Sopenharmony_ci *mtaspect = (tiling_flags >> RADEON_TILING_EG_MACRO_TILE_ASPECT_SHIFT) & RADEON_TILING_EG_MACRO_TILE_ASPECT_MASK; 111762306a36Sopenharmony_ci *tile_split = (tiling_flags >> RADEON_TILING_EG_TILE_SPLIT_SHIFT) & RADEON_TILING_EG_TILE_SPLIT_MASK; 111862306a36Sopenharmony_ci switch (*bankw) { 111962306a36Sopenharmony_ci default: 112062306a36Sopenharmony_ci case 1: *bankw = EVERGREEN_ADDR_SURF_BANK_WIDTH_1; break; 112162306a36Sopenharmony_ci case 2: *bankw = EVERGREEN_ADDR_SURF_BANK_WIDTH_2; break; 112262306a36Sopenharmony_ci case 4: *bankw = EVERGREEN_ADDR_SURF_BANK_WIDTH_4; break; 112362306a36Sopenharmony_ci case 8: *bankw = EVERGREEN_ADDR_SURF_BANK_WIDTH_8; break; 112462306a36Sopenharmony_ci } 112562306a36Sopenharmony_ci switch (*bankh) { 112662306a36Sopenharmony_ci default: 112762306a36Sopenharmony_ci case 1: *bankh = EVERGREEN_ADDR_SURF_BANK_HEIGHT_1; break; 112862306a36Sopenharmony_ci case 2: *bankh = EVERGREEN_ADDR_SURF_BANK_HEIGHT_2; break; 112962306a36Sopenharmony_ci case 4: *bankh = EVERGREEN_ADDR_SURF_BANK_HEIGHT_4; break; 113062306a36Sopenharmony_ci case 8: *bankh = EVERGREEN_ADDR_SURF_BANK_HEIGHT_8; break; 113162306a36Sopenharmony_ci } 113262306a36Sopenharmony_ci switch (*mtaspect) { 113362306a36Sopenharmony_ci default: 113462306a36Sopenharmony_ci case 1: *mtaspect = EVERGREEN_ADDR_SURF_MACRO_TILE_ASPECT_1; break; 113562306a36Sopenharmony_ci case 2: *mtaspect = EVERGREEN_ADDR_SURF_MACRO_TILE_ASPECT_2; break; 113662306a36Sopenharmony_ci case 4: *mtaspect = EVERGREEN_ADDR_SURF_MACRO_TILE_ASPECT_4; break; 113762306a36Sopenharmony_ci case 8: *mtaspect = EVERGREEN_ADDR_SURF_MACRO_TILE_ASPECT_8; break; 113862306a36Sopenharmony_ci } 113962306a36Sopenharmony_ci} 114062306a36Sopenharmony_ci 114162306a36Sopenharmony_cistatic int sumo_set_uvd_clock(struct radeon_device *rdev, u32 clock, 114262306a36Sopenharmony_ci u32 cntl_reg, u32 status_reg) 114362306a36Sopenharmony_ci{ 114462306a36Sopenharmony_ci int r, i; 114562306a36Sopenharmony_ci struct atom_clock_dividers dividers; 114662306a36Sopenharmony_ci 114762306a36Sopenharmony_ci r = radeon_atom_get_clock_dividers(rdev, COMPUTE_ENGINE_PLL_PARAM, 114862306a36Sopenharmony_ci clock, false, ÷rs); 114962306a36Sopenharmony_ci if (r) 115062306a36Sopenharmony_ci return r; 115162306a36Sopenharmony_ci 115262306a36Sopenharmony_ci WREG32_P(cntl_reg, dividers.post_div, ~(DCLK_DIR_CNTL_EN|DCLK_DIVIDER_MASK)); 115362306a36Sopenharmony_ci 115462306a36Sopenharmony_ci for (i = 0; i < 100; i++) { 115562306a36Sopenharmony_ci if (RREG32(status_reg) & DCLK_STATUS) 115662306a36Sopenharmony_ci break; 115762306a36Sopenharmony_ci mdelay(10); 115862306a36Sopenharmony_ci } 115962306a36Sopenharmony_ci if (i == 100) 116062306a36Sopenharmony_ci return -ETIMEDOUT; 116162306a36Sopenharmony_ci 116262306a36Sopenharmony_ci return 0; 116362306a36Sopenharmony_ci} 116462306a36Sopenharmony_ci 116562306a36Sopenharmony_ciint sumo_set_uvd_clocks(struct radeon_device *rdev, u32 vclk, u32 dclk) 116662306a36Sopenharmony_ci{ 116762306a36Sopenharmony_ci int r = 0; 116862306a36Sopenharmony_ci u32 cg_scratch = RREG32(CG_SCRATCH1); 116962306a36Sopenharmony_ci 117062306a36Sopenharmony_ci r = sumo_set_uvd_clock(rdev, vclk, CG_VCLK_CNTL, CG_VCLK_STATUS); 117162306a36Sopenharmony_ci if (r) 117262306a36Sopenharmony_ci goto done; 117362306a36Sopenharmony_ci cg_scratch &= 0xffff0000; 117462306a36Sopenharmony_ci cg_scratch |= vclk / 100; /* Mhz */ 117562306a36Sopenharmony_ci 117662306a36Sopenharmony_ci r = sumo_set_uvd_clock(rdev, dclk, CG_DCLK_CNTL, CG_DCLK_STATUS); 117762306a36Sopenharmony_ci if (r) 117862306a36Sopenharmony_ci goto done; 117962306a36Sopenharmony_ci cg_scratch &= 0x0000ffff; 118062306a36Sopenharmony_ci cg_scratch |= (dclk / 100) << 16; /* Mhz */ 118162306a36Sopenharmony_ci 118262306a36Sopenharmony_cidone: 118362306a36Sopenharmony_ci WREG32(CG_SCRATCH1, cg_scratch); 118462306a36Sopenharmony_ci 118562306a36Sopenharmony_ci return r; 118662306a36Sopenharmony_ci} 118762306a36Sopenharmony_ci 118862306a36Sopenharmony_ciint evergreen_set_uvd_clocks(struct radeon_device *rdev, u32 vclk, u32 dclk) 118962306a36Sopenharmony_ci{ 119062306a36Sopenharmony_ci /* start off with something large */ 119162306a36Sopenharmony_ci unsigned fb_div = 0, vclk_div = 0, dclk_div = 0; 119262306a36Sopenharmony_ci int r; 119362306a36Sopenharmony_ci 119462306a36Sopenharmony_ci /* bypass vclk and dclk with bclk */ 119562306a36Sopenharmony_ci WREG32_P(CG_UPLL_FUNC_CNTL_2, 119662306a36Sopenharmony_ci VCLK_SRC_SEL(1) | DCLK_SRC_SEL(1), 119762306a36Sopenharmony_ci ~(VCLK_SRC_SEL_MASK | DCLK_SRC_SEL_MASK)); 119862306a36Sopenharmony_ci 119962306a36Sopenharmony_ci /* put PLL in bypass mode */ 120062306a36Sopenharmony_ci WREG32_P(CG_UPLL_FUNC_CNTL, UPLL_BYPASS_EN_MASK, ~UPLL_BYPASS_EN_MASK); 120162306a36Sopenharmony_ci 120262306a36Sopenharmony_ci if (!vclk || !dclk) { 120362306a36Sopenharmony_ci /* keep the Bypass mode, put PLL to sleep */ 120462306a36Sopenharmony_ci WREG32_P(CG_UPLL_FUNC_CNTL, UPLL_SLEEP_MASK, ~UPLL_SLEEP_MASK); 120562306a36Sopenharmony_ci return 0; 120662306a36Sopenharmony_ci } 120762306a36Sopenharmony_ci 120862306a36Sopenharmony_ci r = radeon_uvd_calc_upll_dividers(rdev, vclk, dclk, 125000, 250000, 120962306a36Sopenharmony_ci 16384, 0x03FFFFFF, 0, 128, 5, 121062306a36Sopenharmony_ci &fb_div, &vclk_div, &dclk_div); 121162306a36Sopenharmony_ci if (r) 121262306a36Sopenharmony_ci return r; 121362306a36Sopenharmony_ci 121462306a36Sopenharmony_ci /* set VCO_MODE to 1 */ 121562306a36Sopenharmony_ci WREG32_P(CG_UPLL_FUNC_CNTL, UPLL_VCO_MODE_MASK, ~UPLL_VCO_MODE_MASK); 121662306a36Sopenharmony_ci 121762306a36Sopenharmony_ci /* toggle UPLL_SLEEP to 1 then back to 0 */ 121862306a36Sopenharmony_ci WREG32_P(CG_UPLL_FUNC_CNTL, UPLL_SLEEP_MASK, ~UPLL_SLEEP_MASK); 121962306a36Sopenharmony_ci WREG32_P(CG_UPLL_FUNC_CNTL, 0, ~UPLL_SLEEP_MASK); 122062306a36Sopenharmony_ci 122162306a36Sopenharmony_ci /* deassert UPLL_RESET */ 122262306a36Sopenharmony_ci WREG32_P(CG_UPLL_FUNC_CNTL, 0, ~UPLL_RESET_MASK); 122362306a36Sopenharmony_ci 122462306a36Sopenharmony_ci mdelay(1); 122562306a36Sopenharmony_ci 122662306a36Sopenharmony_ci r = radeon_uvd_send_upll_ctlreq(rdev, CG_UPLL_FUNC_CNTL); 122762306a36Sopenharmony_ci if (r) 122862306a36Sopenharmony_ci return r; 122962306a36Sopenharmony_ci 123062306a36Sopenharmony_ci /* assert UPLL_RESET again */ 123162306a36Sopenharmony_ci WREG32_P(CG_UPLL_FUNC_CNTL, UPLL_RESET_MASK, ~UPLL_RESET_MASK); 123262306a36Sopenharmony_ci 123362306a36Sopenharmony_ci /* disable spread spectrum. */ 123462306a36Sopenharmony_ci WREG32_P(CG_UPLL_SPREAD_SPECTRUM, 0, ~SSEN_MASK); 123562306a36Sopenharmony_ci 123662306a36Sopenharmony_ci /* set feedback divider */ 123762306a36Sopenharmony_ci WREG32_P(CG_UPLL_FUNC_CNTL_3, UPLL_FB_DIV(fb_div), ~UPLL_FB_DIV_MASK); 123862306a36Sopenharmony_ci 123962306a36Sopenharmony_ci /* set ref divider to 0 */ 124062306a36Sopenharmony_ci WREG32_P(CG_UPLL_FUNC_CNTL, 0, ~UPLL_REF_DIV_MASK); 124162306a36Sopenharmony_ci 124262306a36Sopenharmony_ci if (fb_div < 307200) 124362306a36Sopenharmony_ci WREG32_P(CG_UPLL_FUNC_CNTL_4, 0, ~UPLL_SPARE_ISPARE9); 124462306a36Sopenharmony_ci else 124562306a36Sopenharmony_ci WREG32_P(CG_UPLL_FUNC_CNTL_4, UPLL_SPARE_ISPARE9, ~UPLL_SPARE_ISPARE9); 124662306a36Sopenharmony_ci 124762306a36Sopenharmony_ci /* set PDIV_A and PDIV_B */ 124862306a36Sopenharmony_ci WREG32_P(CG_UPLL_FUNC_CNTL_2, 124962306a36Sopenharmony_ci UPLL_PDIV_A(vclk_div) | UPLL_PDIV_B(dclk_div), 125062306a36Sopenharmony_ci ~(UPLL_PDIV_A_MASK | UPLL_PDIV_B_MASK)); 125162306a36Sopenharmony_ci 125262306a36Sopenharmony_ci /* give the PLL some time to settle */ 125362306a36Sopenharmony_ci mdelay(15); 125462306a36Sopenharmony_ci 125562306a36Sopenharmony_ci /* deassert PLL_RESET */ 125662306a36Sopenharmony_ci WREG32_P(CG_UPLL_FUNC_CNTL, 0, ~UPLL_RESET_MASK); 125762306a36Sopenharmony_ci 125862306a36Sopenharmony_ci mdelay(15); 125962306a36Sopenharmony_ci 126062306a36Sopenharmony_ci /* switch from bypass mode to normal mode */ 126162306a36Sopenharmony_ci WREG32_P(CG_UPLL_FUNC_CNTL, 0, ~UPLL_BYPASS_EN_MASK); 126262306a36Sopenharmony_ci 126362306a36Sopenharmony_ci r = radeon_uvd_send_upll_ctlreq(rdev, CG_UPLL_FUNC_CNTL); 126462306a36Sopenharmony_ci if (r) 126562306a36Sopenharmony_ci return r; 126662306a36Sopenharmony_ci 126762306a36Sopenharmony_ci /* switch VCLK and DCLK selection */ 126862306a36Sopenharmony_ci WREG32_P(CG_UPLL_FUNC_CNTL_2, 126962306a36Sopenharmony_ci VCLK_SRC_SEL(2) | DCLK_SRC_SEL(2), 127062306a36Sopenharmony_ci ~(VCLK_SRC_SEL_MASK | DCLK_SRC_SEL_MASK)); 127162306a36Sopenharmony_ci 127262306a36Sopenharmony_ci mdelay(100); 127362306a36Sopenharmony_ci 127462306a36Sopenharmony_ci return 0; 127562306a36Sopenharmony_ci} 127662306a36Sopenharmony_ci 127762306a36Sopenharmony_civoid evergreen_fix_pci_max_read_req_size(struct radeon_device *rdev) 127862306a36Sopenharmony_ci{ 127962306a36Sopenharmony_ci int readrq; 128062306a36Sopenharmony_ci u16 v; 128162306a36Sopenharmony_ci 128262306a36Sopenharmony_ci readrq = pcie_get_readrq(rdev->pdev); 128362306a36Sopenharmony_ci v = ffs(readrq) - 8; 128462306a36Sopenharmony_ci /* if bios or OS sets MAX_READ_REQUEST_SIZE to an invalid value, fix it 128562306a36Sopenharmony_ci * to avoid hangs or perfomance issues 128662306a36Sopenharmony_ci */ 128762306a36Sopenharmony_ci if ((v == 0) || (v == 6) || (v == 7)) 128862306a36Sopenharmony_ci pcie_set_readrq(rdev->pdev, 512); 128962306a36Sopenharmony_ci} 129062306a36Sopenharmony_ci 129162306a36Sopenharmony_civoid dce4_program_fmt(struct drm_encoder *encoder) 129262306a36Sopenharmony_ci{ 129362306a36Sopenharmony_ci struct drm_device *dev = encoder->dev; 129462306a36Sopenharmony_ci struct radeon_device *rdev = dev->dev_private; 129562306a36Sopenharmony_ci struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); 129662306a36Sopenharmony_ci struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc); 129762306a36Sopenharmony_ci struct drm_connector *connector = radeon_get_connector_for_encoder(encoder); 129862306a36Sopenharmony_ci int bpc = 0; 129962306a36Sopenharmony_ci u32 tmp = 0; 130062306a36Sopenharmony_ci enum radeon_connector_dither dither = RADEON_FMT_DITHER_DISABLE; 130162306a36Sopenharmony_ci 130262306a36Sopenharmony_ci if (connector) { 130362306a36Sopenharmony_ci struct radeon_connector *radeon_connector = to_radeon_connector(connector); 130462306a36Sopenharmony_ci bpc = radeon_get_monitor_bpc(connector); 130562306a36Sopenharmony_ci dither = radeon_connector->dither; 130662306a36Sopenharmony_ci } 130762306a36Sopenharmony_ci 130862306a36Sopenharmony_ci /* LVDS/eDP FMT is set up by atom */ 130962306a36Sopenharmony_ci if (radeon_encoder->devices & ATOM_DEVICE_LCD_SUPPORT) 131062306a36Sopenharmony_ci return; 131162306a36Sopenharmony_ci 131262306a36Sopenharmony_ci /* not needed for analog */ 131362306a36Sopenharmony_ci if ((radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1) || 131462306a36Sopenharmony_ci (radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2)) 131562306a36Sopenharmony_ci return; 131662306a36Sopenharmony_ci 131762306a36Sopenharmony_ci if (bpc == 0) 131862306a36Sopenharmony_ci return; 131962306a36Sopenharmony_ci 132062306a36Sopenharmony_ci switch (bpc) { 132162306a36Sopenharmony_ci case 6: 132262306a36Sopenharmony_ci if (dither == RADEON_FMT_DITHER_ENABLE) 132362306a36Sopenharmony_ci /* XXX sort out optimal dither settings */ 132462306a36Sopenharmony_ci tmp |= (FMT_FRAME_RANDOM_ENABLE | FMT_HIGHPASS_RANDOM_ENABLE | 132562306a36Sopenharmony_ci FMT_SPATIAL_DITHER_EN); 132662306a36Sopenharmony_ci else 132762306a36Sopenharmony_ci tmp |= FMT_TRUNCATE_EN; 132862306a36Sopenharmony_ci break; 132962306a36Sopenharmony_ci case 8: 133062306a36Sopenharmony_ci if (dither == RADEON_FMT_DITHER_ENABLE) 133162306a36Sopenharmony_ci /* XXX sort out optimal dither settings */ 133262306a36Sopenharmony_ci tmp |= (FMT_FRAME_RANDOM_ENABLE | FMT_HIGHPASS_RANDOM_ENABLE | 133362306a36Sopenharmony_ci FMT_RGB_RANDOM_ENABLE | 133462306a36Sopenharmony_ci FMT_SPATIAL_DITHER_EN | FMT_SPATIAL_DITHER_DEPTH); 133562306a36Sopenharmony_ci else 133662306a36Sopenharmony_ci tmp |= (FMT_TRUNCATE_EN | FMT_TRUNCATE_DEPTH); 133762306a36Sopenharmony_ci break; 133862306a36Sopenharmony_ci case 10: 133962306a36Sopenharmony_ci default: 134062306a36Sopenharmony_ci /* not needed */ 134162306a36Sopenharmony_ci break; 134262306a36Sopenharmony_ci } 134362306a36Sopenharmony_ci 134462306a36Sopenharmony_ci WREG32(FMT_BIT_DEPTH_CONTROL + radeon_crtc->crtc_offset, tmp); 134562306a36Sopenharmony_ci} 134662306a36Sopenharmony_ci 134762306a36Sopenharmony_cistatic bool dce4_is_in_vblank(struct radeon_device *rdev, int crtc) 134862306a36Sopenharmony_ci{ 134962306a36Sopenharmony_ci if (RREG32(EVERGREEN_CRTC_STATUS + crtc_offsets[crtc]) & EVERGREEN_CRTC_V_BLANK) 135062306a36Sopenharmony_ci return true; 135162306a36Sopenharmony_ci else 135262306a36Sopenharmony_ci return false; 135362306a36Sopenharmony_ci} 135462306a36Sopenharmony_ci 135562306a36Sopenharmony_cistatic bool dce4_is_counter_moving(struct radeon_device *rdev, int crtc) 135662306a36Sopenharmony_ci{ 135762306a36Sopenharmony_ci u32 pos1, pos2; 135862306a36Sopenharmony_ci 135962306a36Sopenharmony_ci pos1 = RREG32(EVERGREEN_CRTC_STATUS_POSITION + crtc_offsets[crtc]); 136062306a36Sopenharmony_ci pos2 = RREG32(EVERGREEN_CRTC_STATUS_POSITION + crtc_offsets[crtc]); 136162306a36Sopenharmony_ci 136262306a36Sopenharmony_ci if (pos1 != pos2) 136362306a36Sopenharmony_ci return true; 136462306a36Sopenharmony_ci else 136562306a36Sopenharmony_ci return false; 136662306a36Sopenharmony_ci} 136762306a36Sopenharmony_ci 136862306a36Sopenharmony_ci/** 136962306a36Sopenharmony_ci * dce4_wait_for_vblank - vblank wait asic callback. 137062306a36Sopenharmony_ci * 137162306a36Sopenharmony_ci * @rdev: radeon_device pointer 137262306a36Sopenharmony_ci * @crtc: crtc to wait for vblank on 137362306a36Sopenharmony_ci * 137462306a36Sopenharmony_ci * Wait for vblank on the requested crtc (evergreen+). 137562306a36Sopenharmony_ci */ 137662306a36Sopenharmony_civoid dce4_wait_for_vblank(struct radeon_device *rdev, int crtc) 137762306a36Sopenharmony_ci{ 137862306a36Sopenharmony_ci unsigned i = 0; 137962306a36Sopenharmony_ci 138062306a36Sopenharmony_ci if (crtc >= rdev->num_crtc) 138162306a36Sopenharmony_ci return; 138262306a36Sopenharmony_ci 138362306a36Sopenharmony_ci if (!(RREG32(EVERGREEN_CRTC_CONTROL + crtc_offsets[crtc]) & EVERGREEN_CRTC_MASTER_EN)) 138462306a36Sopenharmony_ci return; 138562306a36Sopenharmony_ci 138662306a36Sopenharmony_ci /* depending on when we hit vblank, we may be close to active; if so, 138762306a36Sopenharmony_ci * wait for another frame. 138862306a36Sopenharmony_ci */ 138962306a36Sopenharmony_ci while (dce4_is_in_vblank(rdev, crtc)) { 139062306a36Sopenharmony_ci if (i++ % 100 == 0) { 139162306a36Sopenharmony_ci if (!dce4_is_counter_moving(rdev, crtc)) 139262306a36Sopenharmony_ci break; 139362306a36Sopenharmony_ci } 139462306a36Sopenharmony_ci } 139562306a36Sopenharmony_ci 139662306a36Sopenharmony_ci while (!dce4_is_in_vblank(rdev, crtc)) { 139762306a36Sopenharmony_ci if (i++ % 100 == 0) { 139862306a36Sopenharmony_ci if (!dce4_is_counter_moving(rdev, crtc)) 139962306a36Sopenharmony_ci break; 140062306a36Sopenharmony_ci } 140162306a36Sopenharmony_ci } 140262306a36Sopenharmony_ci} 140362306a36Sopenharmony_ci 140462306a36Sopenharmony_ci/** 140562306a36Sopenharmony_ci * evergreen_page_flip - pageflip callback. 140662306a36Sopenharmony_ci * 140762306a36Sopenharmony_ci * @rdev: radeon_device pointer 140862306a36Sopenharmony_ci * @crtc_id: crtc to cleanup pageflip on 140962306a36Sopenharmony_ci * @crtc_base: new address of the crtc (GPU MC address) 141062306a36Sopenharmony_ci * @async: asynchronous flip 141162306a36Sopenharmony_ci * 141262306a36Sopenharmony_ci * Triggers the actual pageflip by updating the primary 141362306a36Sopenharmony_ci * surface base address (evergreen+). 141462306a36Sopenharmony_ci */ 141562306a36Sopenharmony_civoid evergreen_page_flip(struct radeon_device *rdev, int crtc_id, u64 crtc_base, 141662306a36Sopenharmony_ci bool async) 141762306a36Sopenharmony_ci{ 141862306a36Sopenharmony_ci struct radeon_crtc *radeon_crtc = rdev->mode_info.crtcs[crtc_id]; 141962306a36Sopenharmony_ci struct drm_framebuffer *fb = radeon_crtc->base.primary->fb; 142062306a36Sopenharmony_ci 142162306a36Sopenharmony_ci /* flip at hsync for async, default is vsync */ 142262306a36Sopenharmony_ci WREG32(EVERGREEN_GRPH_FLIP_CONTROL + radeon_crtc->crtc_offset, 142362306a36Sopenharmony_ci async ? EVERGREEN_GRPH_SURFACE_UPDATE_H_RETRACE_EN : 0); 142462306a36Sopenharmony_ci /* update pitch */ 142562306a36Sopenharmony_ci WREG32(EVERGREEN_GRPH_PITCH + radeon_crtc->crtc_offset, 142662306a36Sopenharmony_ci fb->pitches[0] / fb->format->cpp[0]); 142762306a36Sopenharmony_ci /* update the scanout addresses */ 142862306a36Sopenharmony_ci WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH + radeon_crtc->crtc_offset, 142962306a36Sopenharmony_ci upper_32_bits(crtc_base)); 143062306a36Sopenharmony_ci WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS + radeon_crtc->crtc_offset, 143162306a36Sopenharmony_ci (u32)crtc_base); 143262306a36Sopenharmony_ci /* post the write */ 143362306a36Sopenharmony_ci RREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS + radeon_crtc->crtc_offset); 143462306a36Sopenharmony_ci} 143562306a36Sopenharmony_ci 143662306a36Sopenharmony_ci/** 143762306a36Sopenharmony_ci * evergreen_page_flip_pending - check if page flip is still pending 143862306a36Sopenharmony_ci * 143962306a36Sopenharmony_ci * @rdev: radeon_device pointer 144062306a36Sopenharmony_ci * @crtc_id: crtc to check 144162306a36Sopenharmony_ci * 144262306a36Sopenharmony_ci * Returns the current update pending status. 144362306a36Sopenharmony_ci */ 144462306a36Sopenharmony_cibool evergreen_page_flip_pending(struct radeon_device *rdev, int crtc_id) 144562306a36Sopenharmony_ci{ 144662306a36Sopenharmony_ci struct radeon_crtc *radeon_crtc = rdev->mode_info.crtcs[crtc_id]; 144762306a36Sopenharmony_ci 144862306a36Sopenharmony_ci /* Return current update_pending status: */ 144962306a36Sopenharmony_ci return !!(RREG32(EVERGREEN_GRPH_UPDATE + radeon_crtc->crtc_offset) & 145062306a36Sopenharmony_ci EVERGREEN_GRPH_SURFACE_UPDATE_PENDING); 145162306a36Sopenharmony_ci} 145262306a36Sopenharmony_ci 145362306a36Sopenharmony_ci/* get temperature in millidegrees */ 145462306a36Sopenharmony_ciint evergreen_get_temp(struct radeon_device *rdev) 145562306a36Sopenharmony_ci{ 145662306a36Sopenharmony_ci u32 temp, toffset; 145762306a36Sopenharmony_ci int actual_temp = 0; 145862306a36Sopenharmony_ci 145962306a36Sopenharmony_ci if (rdev->family == CHIP_JUNIPER) { 146062306a36Sopenharmony_ci toffset = (RREG32(CG_THERMAL_CTRL) & TOFFSET_MASK) >> 146162306a36Sopenharmony_ci TOFFSET_SHIFT; 146262306a36Sopenharmony_ci temp = (RREG32(CG_TS0_STATUS) & TS0_ADC_DOUT_MASK) >> 146362306a36Sopenharmony_ci TS0_ADC_DOUT_SHIFT; 146462306a36Sopenharmony_ci 146562306a36Sopenharmony_ci if (toffset & 0x100) 146662306a36Sopenharmony_ci actual_temp = temp / 2 - (0x200 - toffset); 146762306a36Sopenharmony_ci else 146862306a36Sopenharmony_ci actual_temp = temp / 2 + toffset; 146962306a36Sopenharmony_ci 147062306a36Sopenharmony_ci actual_temp = actual_temp * 1000; 147162306a36Sopenharmony_ci 147262306a36Sopenharmony_ci } else { 147362306a36Sopenharmony_ci temp = (RREG32(CG_MULT_THERMAL_STATUS) & ASIC_T_MASK) >> 147462306a36Sopenharmony_ci ASIC_T_SHIFT; 147562306a36Sopenharmony_ci 147662306a36Sopenharmony_ci if (temp & 0x400) 147762306a36Sopenharmony_ci actual_temp = -256; 147862306a36Sopenharmony_ci else if (temp & 0x200) 147962306a36Sopenharmony_ci actual_temp = 255; 148062306a36Sopenharmony_ci else if (temp & 0x100) { 148162306a36Sopenharmony_ci actual_temp = temp & 0x1ff; 148262306a36Sopenharmony_ci actual_temp |= ~0x1ff; 148362306a36Sopenharmony_ci } else 148462306a36Sopenharmony_ci actual_temp = temp & 0xff; 148562306a36Sopenharmony_ci 148662306a36Sopenharmony_ci actual_temp = (actual_temp * 1000) / 2; 148762306a36Sopenharmony_ci } 148862306a36Sopenharmony_ci 148962306a36Sopenharmony_ci return actual_temp; 149062306a36Sopenharmony_ci} 149162306a36Sopenharmony_ci 149262306a36Sopenharmony_ciint sumo_get_temp(struct radeon_device *rdev) 149362306a36Sopenharmony_ci{ 149462306a36Sopenharmony_ci u32 temp = RREG32(CG_THERMAL_STATUS) & 0xff; 149562306a36Sopenharmony_ci int actual_temp = temp - 49; 149662306a36Sopenharmony_ci 149762306a36Sopenharmony_ci return actual_temp * 1000; 149862306a36Sopenharmony_ci} 149962306a36Sopenharmony_ci 150062306a36Sopenharmony_ci/** 150162306a36Sopenharmony_ci * sumo_pm_init_profile - Initialize power profiles callback. 150262306a36Sopenharmony_ci * 150362306a36Sopenharmony_ci * @rdev: radeon_device pointer 150462306a36Sopenharmony_ci * 150562306a36Sopenharmony_ci * Initialize the power states used in profile mode 150662306a36Sopenharmony_ci * (sumo, trinity, SI). 150762306a36Sopenharmony_ci * Used for profile mode only. 150862306a36Sopenharmony_ci */ 150962306a36Sopenharmony_civoid sumo_pm_init_profile(struct radeon_device *rdev) 151062306a36Sopenharmony_ci{ 151162306a36Sopenharmony_ci int idx; 151262306a36Sopenharmony_ci 151362306a36Sopenharmony_ci /* default */ 151462306a36Sopenharmony_ci rdev->pm.profiles[PM_PROFILE_DEFAULT_IDX].dpms_off_ps_idx = rdev->pm.default_power_state_index; 151562306a36Sopenharmony_ci rdev->pm.profiles[PM_PROFILE_DEFAULT_IDX].dpms_on_ps_idx = rdev->pm.default_power_state_index; 151662306a36Sopenharmony_ci rdev->pm.profiles[PM_PROFILE_DEFAULT_IDX].dpms_off_cm_idx = 0; 151762306a36Sopenharmony_ci rdev->pm.profiles[PM_PROFILE_DEFAULT_IDX].dpms_on_cm_idx = 0; 151862306a36Sopenharmony_ci 151962306a36Sopenharmony_ci /* low,mid sh/mh */ 152062306a36Sopenharmony_ci if (rdev->flags & RADEON_IS_MOBILITY) 152162306a36Sopenharmony_ci idx = radeon_pm_get_type_index(rdev, POWER_STATE_TYPE_BATTERY, 0); 152262306a36Sopenharmony_ci else 152362306a36Sopenharmony_ci idx = radeon_pm_get_type_index(rdev, POWER_STATE_TYPE_PERFORMANCE, 0); 152462306a36Sopenharmony_ci 152562306a36Sopenharmony_ci rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_off_ps_idx = idx; 152662306a36Sopenharmony_ci rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_on_ps_idx = idx; 152762306a36Sopenharmony_ci rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_off_cm_idx = 0; 152862306a36Sopenharmony_ci rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_on_cm_idx = 0; 152962306a36Sopenharmony_ci 153062306a36Sopenharmony_ci rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_off_ps_idx = idx; 153162306a36Sopenharmony_ci rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_on_ps_idx = idx; 153262306a36Sopenharmony_ci rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_off_cm_idx = 0; 153362306a36Sopenharmony_ci rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_on_cm_idx = 0; 153462306a36Sopenharmony_ci 153562306a36Sopenharmony_ci rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_off_ps_idx = idx; 153662306a36Sopenharmony_ci rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_on_ps_idx = idx; 153762306a36Sopenharmony_ci rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_off_cm_idx = 0; 153862306a36Sopenharmony_ci rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_on_cm_idx = 0; 153962306a36Sopenharmony_ci 154062306a36Sopenharmony_ci rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_off_ps_idx = idx; 154162306a36Sopenharmony_ci rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_on_ps_idx = idx; 154262306a36Sopenharmony_ci rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_off_cm_idx = 0; 154362306a36Sopenharmony_ci rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_on_cm_idx = 0; 154462306a36Sopenharmony_ci 154562306a36Sopenharmony_ci /* high sh/mh */ 154662306a36Sopenharmony_ci idx = radeon_pm_get_type_index(rdev, POWER_STATE_TYPE_PERFORMANCE, 0); 154762306a36Sopenharmony_ci rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_off_ps_idx = idx; 154862306a36Sopenharmony_ci rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_on_ps_idx = idx; 154962306a36Sopenharmony_ci rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_off_cm_idx = 0; 155062306a36Sopenharmony_ci rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_on_cm_idx = 155162306a36Sopenharmony_ci rdev->pm.power_state[idx].num_clock_modes - 1; 155262306a36Sopenharmony_ci 155362306a36Sopenharmony_ci rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_off_ps_idx = idx; 155462306a36Sopenharmony_ci rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_on_ps_idx = idx; 155562306a36Sopenharmony_ci rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_off_cm_idx = 0; 155662306a36Sopenharmony_ci rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_on_cm_idx = 155762306a36Sopenharmony_ci rdev->pm.power_state[idx].num_clock_modes - 1; 155862306a36Sopenharmony_ci} 155962306a36Sopenharmony_ci 156062306a36Sopenharmony_ci/** 156162306a36Sopenharmony_ci * btc_pm_init_profile - Initialize power profiles callback. 156262306a36Sopenharmony_ci * 156362306a36Sopenharmony_ci * @rdev: radeon_device pointer 156462306a36Sopenharmony_ci * 156562306a36Sopenharmony_ci * Initialize the power states used in profile mode 156662306a36Sopenharmony_ci * (BTC, cayman). 156762306a36Sopenharmony_ci * Used for profile mode only. 156862306a36Sopenharmony_ci */ 156962306a36Sopenharmony_civoid btc_pm_init_profile(struct radeon_device *rdev) 157062306a36Sopenharmony_ci{ 157162306a36Sopenharmony_ci int idx; 157262306a36Sopenharmony_ci 157362306a36Sopenharmony_ci /* default */ 157462306a36Sopenharmony_ci rdev->pm.profiles[PM_PROFILE_DEFAULT_IDX].dpms_off_ps_idx = rdev->pm.default_power_state_index; 157562306a36Sopenharmony_ci rdev->pm.profiles[PM_PROFILE_DEFAULT_IDX].dpms_on_ps_idx = rdev->pm.default_power_state_index; 157662306a36Sopenharmony_ci rdev->pm.profiles[PM_PROFILE_DEFAULT_IDX].dpms_off_cm_idx = 0; 157762306a36Sopenharmony_ci rdev->pm.profiles[PM_PROFILE_DEFAULT_IDX].dpms_on_cm_idx = 2; 157862306a36Sopenharmony_ci /* starting with BTC, there is one state that is used for both 157962306a36Sopenharmony_ci * MH and SH. Difference is that we always use the high clock index for 158062306a36Sopenharmony_ci * mclk. 158162306a36Sopenharmony_ci */ 158262306a36Sopenharmony_ci if (rdev->flags & RADEON_IS_MOBILITY) 158362306a36Sopenharmony_ci idx = radeon_pm_get_type_index(rdev, POWER_STATE_TYPE_BATTERY, 0); 158462306a36Sopenharmony_ci else 158562306a36Sopenharmony_ci idx = radeon_pm_get_type_index(rdev, POWER_STATE_TYPE_PERFORMANCE, 0); 158662306a36Sopenharmony_ci /* low sh */ 158762306a36Sopenharmony_ci rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_off_ps_idx = idx; 158862306a36Sopenharmony_ci rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_on_ps_idx = idx; 158962306a36Sopenharmony_ci rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_off_cm_idx = 0; 159062306a36Sopenharmony_ci rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_on_cm_idx = 0; 159162306a36Sopenharmony_ci /* mid sh */ 159262306a36Sopenharmony_ci rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_off_ps_idx = idx; 159362306a36Sopenharmony_ci rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_on_ps_idx = idx; 159462306a36Sopenharmony_ci rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_off_cm_idx = 0; 159562306a36Sopenharmony_ci rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_on_cm_idx = 1; 159662306a36Sopenharmony_ci /* high sh */ 159762306a36Sopenharmony_ci rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_off_ps_idx = idx; 159862306a36Sopenharmony_ci rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_on_ps_idx = idx; 159962306a36Sopenharmony_ci rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_off_cm_idx = 0; 160062306a36Sopenharmony_ci rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_on_cm_idx = 2; 160162306a36Sopenharmony_ci /* low mh */ 160262306a36Sopenharmony_ci rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_off_ps_idx = idx; 160362306a36Sopenharmony_ci rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_on_ps_idx = idx; 160462306a36Sopenharmony_ci rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_off_cm_idx = 0; 160562306a36Sopenharmony_ci rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_on_cm_idx = 0; 160662306a36Sopenharmony_ci /* mid mh */ 160762306a36Sopenharmony_ci rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_off_ps_idx = idx; 160862306a36Sopenharmony_ci rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_on_ps_idx = idx; 160962306a36Sopenharmony_ci rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_off_cm_idx = 0; 161062306a36Sopenharmony_ci rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_on_cm_idx = 1; 161162306a36Sopenharmony_ci /* high mh */ 161262306a36Sopenharmony_ci rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_off_ps_idx = idx; 161362306a36Sopenharmony_ci rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_on_ps_idx = idx; 161462306a36Sopenharmony_ci rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_off_cm_idx = 0; 161562306a36Sopenharmony_ci rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_on_cm_idx = 2; 161662306a36Sopenharmony_ci} 161762306a36Sopenharmony_ci 161862306a36Sopenharmony_ci/** 161962306a36Sopenharmony_ci * evergreen_pm_misc - set additional pm hw parameters callback. 162062306a36Sopenharmony_ci * 162162306a36Sopenharmony_ci * @rdev: radeon_device pointer 162262306a36Sopenharmony_ci * 162362306a36Sopenharmony_ci * Set non-clock parameters associated with a power state 162462306a36Sopenharmony_ci * (voltage, etc.) (evergreen+). 162562306a36Sopenharmony_ci */ 162662306a36Sopenharmony_civoid evergreen_pm_misc(struct radeon_device *rdev) 162762306a36Sopenharmony_ci{ 162862306a36Sopenharmony_ci int req_ps_idx = rdev->pm.requested_power_state_index; 162962306a36Sopenharmony_ci int req_cm_idx = rdev->pm.requested_clock_mode_index; 163062306a36Sopenharmony_ci struct radeon_power_state *ps = &rdev->pm.power_state[req_ps_idx]; 163162306a36Sopenharmony_ci struct radeon_voltage *voltage = &ps->clock_info[req_cm_idx].voltage; 163262306a36Sopenharmony_ci 163362306a36Sopenharmony_ci if (voltage->type == VOLTAGE_SW) { 163462306a36Sopenharmony_ci /* 0xff0x are flags rather then an actual voltage */ 163562306a36Sopenharmony_ci if ((voltage->voltage & 0xff00) == 0xff00) 163662306a36Sopenharmony_ci return; 163762306a36Sopenharmony_ci if (voltage->voltage && (voltage->voltage != rdev->pm.current_vddc)) { 163862306a36Sopenharmony_ci radeon_atom_set_voltage(rdev, voltage->voltage, SET_VOLTAGE_TYPE_ASIC_VDDC); 163962306a36Sopenharmony_ci rdev->pm.current_vddc = voltage->voltage; 164062306a36Sopenharmony_ci DRM_DEBUG("Setting: vddc: %d\n", voltage->voltage); 164162306a36Sopenharmony_ci } 164262306a36Sopenharmony_ci 164362306a36Sopenharmony_ci /* starting with BTC, there is one state that is used for both 164462306a36Sopenharmony_ci * MH and SH. Difference is that we always use the high clock index for 164562306a36Sopenharmony_ci * mclk and vddci. 164662306a36Sopenharmony_ci */ 164762306a36Sopenharmony_ci if ((rdev->pm.pm_method == PM_METHOD_PROFILE) && 164862306a36Sopenharmony_ci (rdev->family >= CHIP_BARTS) && 164962306a36Sopenharmony_ci rdev->pm.active_crtc_count && 165062306a36Sopenharmony_ci ((rdev->pm.profile_index == PM_PROFILE_MID_MH_IDX) || 165162306a36Sopenharmony_ci (rdev->pm.profile_index == PM_PROFILE_LOW_MH_IDX))) 165262306a36Sopenharmony_ci voltage = &rdev->pm.power_state[req_ps_idx]. 165362306a36Sopenharmony_ci clock_info[rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_on_cm_idx].voltage; 165462306a36Sopenharmony_ci 165562306a36Sopenharmony_ci /* 0xff0x are flags rather then an actual voltage */ 165662306a36Sopenharmony_ci if ((voltage->vddci & 0xff00) == 0xff00) 165762306a36Sopenharmony_ci return; 165862306a36Sopenharmony_ci if (voltage->vddci && (voltage->vddci != rdev->pm.current_vddci)) { 165962306a36Sopenharmony_ci radeon_atom_set_voltage(rdev, voltage->vddci, SET_VOLTAGE_TYPE_ASIC_VDDCI); 166062306a36Sopenharmony_ci rdev->pm.current_vddci = voltage->vddci; 166162306a36Sopenharmony_ci DRM_DEBUG("Setting: vddci: %d\n", voltage->vddci); 166262306a36Sopenharmony_ci } 166362306a36Sopenharmony_ci } 166462306a36Sopenharmony_ci} 166562306a36Sopenharmony_ci 166662306a36Sopenharmony_ci/** 166762306a36Sopenharmony_ci * evergreen_pm_prepare - pre-power state change callback. 166862306a36Sopenharmony_ci * 166962306a36Sopenharmony_ci * @rdev: radeon_device pointer 167062306a36Sopenharmony_ci * 167162306a36Sopenharmony_ci * Prepare for a power state change (evergreen+). 167262306a36Sopenharmony_ci */ 167362306a36Sopenharmony_civoid evergreen_pm_prepare(struct radeon_device *rdev) 167462306a36Sopenharmony_ci{ 167562306a36Sopenharmony_ci struct drm_device *ddev = rdev->ddev; 167662306a36Sopenharmony_ci struct drm_crtc *crtc; 167762306a36Sopenharmony_ci struct radeon_crtc *radeon_crtc; 167862306a36Sopenharmony_ci u32 tmp; 167962306a36Sopenharmony_ci 168062306a36Sopenharmony_ci /* disable any active CRTCs */ 168162306a36Sopenharmony_ci list_for_each_entry(crtc, &ddev->mode_config.crtc_list, head) { 168262306a36Sopenharmony_ci radeon_crtc = to_radeon_crtc(crtc); 168362306a36Sopenharmony_ci if (radeon_crtc->enabled) { 168462306a36Sopenharmony_ci tmp = RREG32(EVERGREEN_CRTC_CONTROL + radeon_crtc->crtc_offset); 168562306a36Sopenharmony_ci tmp |= EVERGREEN_CRTC_DISP_READ_REQUEST_DISABLE; 168662306a36Sopenharmony_ci WREG32(EVERGREEN_CRTC_CONTROL + radeon_crtc->crtc_offset, tmp); 168762306a36Sopenharmony_ci } 168862306a36Sopenharmony_ci } 168962306a36Sopenharmony_ci} 169062306a36Sopenharmony_ci 169162306a36Sopenharmony_ci/** 169262306a36Sopenharmony_ci * evergreen_pm_finish - post-power state change callback. 169362306a36Sopenharmony_ci * 169462306a36Sopenharmony_ci * @rdev: radeon_device pointer 169562306a36Sopenharmony_ci * 169662306a36Sopenharmony_ci * Clean up after a power state change (evergreen+). 169762306a36Sopenharmony_ci */ 169862306a36Sopenharmony_civoid evergreen_pm_finish(struct radeon_device *rdev) 169962306a36Sopenharmony_ci{ 170062306a36Sopenharmony_ci struct drm_device *ddev = rdev->ddev; 170162306a36Sopenharmony_ci struct drm_crtc *crtc; 170262306a36Sopenharmony_ci struct radeon_crtc *radeon_crtc; 170362306a36Sopenharmony_ci u32 tmp; 170462306a36Sopenharmony_ci 170562306a36Sopenharmony_ci /* enable any active CRTCs */ 170662306a36Sopenharmony_ci list_for_each_entry(crtc, &ddev->mode_config.crtc_list, head) { 170762306a36Sopenharmony_ci radeon_crtc = to_radeon_crtc(crtc); 170862306a36Sopenharmony_ci if (radeon_crtc->enabled) { 170962306a36Sopenharmony_ci tmp = RREG32(EVERGREEN_CRTC_CONTROL + radeon_crtc->crtc_offset); 171062306a36Sopenharmony_ci tmp &= ~EVERGREEN_CRTC_DISP_READ_REQUEST_DISABLE; 171162306a36Sopenharmony_ci WREG32(EVERGREEN_CRTC_CONTROL + radeon_crtc->crtc_offset, tmp); 171262306a36Sopenharmony_ci } 171362306a36Sopenharmony_ci } 171462306a36Sopenharmony_ci} 171562306a36Sopenharmony_ci 171662306a36Sopenharmony_ci/** 171762306a36Sopenharmony_ci * evergreen_hpd_sense - hpd sense callback. 171862306a36Sopenharmony_ci * 171962306a36Sopenharmony_ci * @rdev: radeon_device pointer 172062306a36Sopenharmony_ci * @hpd: hpd (hotplug detect) pin 172162306a36Sopenharmony_ci * 172262306a36Sopenharmony_ci * Checks if a digital monitor is connected (evergreen+). 172362306a36Sopenharmony_ci * Returns true if connected, false if not connected. 172462306a36Sopenharmony_ci */ 172562306a36Sopenharmony_cibool evergreen_hpd_sense(struct radeon_device *rdev, enum radeon_hpd_id hpd) 172662306a36Sopenharmony_ci{ 172762306a36Sopenharmony_ci if (hpd == RADEON_HPD_NONE) 172862306a36Sopenharmony_ci return false; 172962306a36Sopenharmony_ci 173062306a36Sopenharmony_ci return !!(RREG32(DC_HPDx_INT_STATUS_REG(hpd)) & DC_HPDx_SENSE); 173162306a36Sopenharmony_ci} 173262306a36Sopenharmony_ci 173362306a36Sopenharmony_ci/** 173462306a36Sopenharmony_ci * evergreen_hpd_set_polarity - hpd set polarity callback. 173562306a36Sopenharmony_ci * 173662306a36Sopenharmony_ci * @rdev: radeon_device pointer 173762306a36Sopenharmony_ci * @hpd: hpd (hotplug detect) pin 173862306a36Sopenharmony_ci * 173962306a36Sopenharmony_ci * Set the polarity of the hpd pin (evergreen+). 174062306a36Sopenharmony_ci */ 174162306a36Sopenharmony_civoid evergreen_hpd_set_polarity(struct radeon_device *rdev, 174262306a36Sopenharmony_ci enum radeon_hpd_id hpd) 174362306a36Sopenharmony_ci{ 174462306a36Sopenharmony_ci bool connected = evergreen_hpd_sense(rdev, hpd); 174562306a36Sopenharmony_ci 174662306a36Sopenharmony_ci if (hpd == RADEON_HPD_NONE) 174762306a36Sopenharmony_ci return; 174862306a36Sopenharmony_ci 174962306a36Sopenharmony_ci if (connected) 175062306a36Sopenharmony_ci WREG32_AND(DC_HPDx_INT_CONTROL(hpd), ~DC_HPDx_INT_POLARITY); 175162306a36Sopenharmony_ci else 175262306a36Sopenharmony_ci WREG32_OR(DC_HPDx_INT_CONTROL(hpd), DC_HPDx_INT_POLARITY); 175362306a36Sopenharmony_ci} 175462306a36Sopenharmony_ci 175562306a36Sopenharmony_ci/** 175662306a36Sopenharmony_ci * evergreen_hpd_init - hpd setup callback. 175762306a36Sopenharmony_ci * 175862306a36Sopenharmony_ci * @rdev: radeon_device pointer 175962306a36Sopenharmony_ci * 176062306a36Sopenharmony_ci * Setup the hpd pins used by the card (evergreen+). 176162306a36Sopenharmony_ci * Enable the pin, set the polarity, and enable the hpd interrupts. 176262306a36Sopenharmony_ci */ 176362306a36Sopenharmony_civoid evergreen_hpd_init(struct radeon_device *rdev) 176462306a36Sopenharmony_ci{ 176562306a36Sopenharmony_ci struct drm_device *dev = rdev->ddev; 176662306a36Sopenharmony_ci struct drm_connector *connector; 176762306a36Sopenharmony_ci unsigned enabled = 0; 176862306a36Sopenharmony_ci u32 tmp = DC_HPDx_CONNECTION_TIMER(0x9c4) | 176962306a36Sopenharmony_ci DC_HPDx_RX_INT_TIMER(0xfa) | DC_HPDx_EN; 177062306a36Sopenharmony_ci 177162306a36Sopenharmony_ci list_for_each_entry(connector, &dev->mode_config.connector_list, head) { 177262306a36Sopenharmony_ci enum radeon_hpd_id hpd = 177362306a36Sopenharmony_ci to_radeon_connector(connector)->hpd.hpd; 177462306a36Sopenharmony_ci 177562306a36Sopenharmony_ci if (connector->connector_type == DRM_MODE_CONNECTOR_eDP || 177662306a36Sopenharmony_ci connector->connector_type == DRM_MODE_CONNECTOR_LVDS) { 177762306a36Sopenharmony_ci /* don't try to enable hpd on eDP or LVDS avoid breaking the 177862306a36Sopenharmony_ci * aux dp channel on imac and help (but not completely fix) 177962306a36Sopenharmony_ci * https://bugzilla.redhat.com/show_bug.cgi?id=726143 178062306a36Sopenharmony_ci * also avoid interrupt storms during dpms. 178162306a36Sopenharmony_ci */ 178262306a36Sopenharmony_ci continue; 178362306a36Sopenharmony_ci } 178462306a36Sopenharmony_ci 178562306a36Sopenharmony_ci if (hpd == RADEON_HPD_NONE) 178662306a36Sopenharmony_ci continue; 178762306a36Sopenharmony_ci 178862306a36Sopenharmony_ci WREG32(DC_HPDx_CONTROL(hpd), tmp); 178962306a36Sopenharmony_ci enabled |= 1 << hpd; 179062306a36Sopenharmony_ci 179162306a36Sopenharmony_ci radeon_hpd_set_polarity(rdev, hpd); 179262306a36Sopenharmony_ci } 179362306a36Sopenharmony_ci radeon_irq_kms_enable_hpd(rdev, enabled); 179462306a36Sopenharmony_ci} 179562306a36Sopenharmony_ci 179662306a36Sopenharmony_ci/** 179762306a36Sopenharmony_ci * evergreen_hpd_fini - hpd tear down callback. 179862306a36Sopenharmony_ci * 179962306a36Sopenharmony_ci * @rdev: radeon_device pointer 180062306a36Sopenharmony_ci * 180162306a36Sopenharmony_ci * Tear down the hpd pins used by the card (evergreen+). 180262306a36Sopenharmony_ci * Disable the hpd interrupts. 180362306a36Sopenharmony_ci */ 180462306a36Sopenharmony_civoid evergreen_hpd_fini(struct radeon_device *rdev) 180562306a36Sopenharmony_ci{ 180662306a36Sopenharmony_ci struct drm_device *dev = rdev->ddev; 180762306a36Sopenharmony_ci struct drm_connector *connector; 180862306a36Sopenharmony_ci unsigned disabled = 0; 180962306a36Sopenharmony_ci 181062306a36Sopenharmony_ci list_for_each_entry(connector, &dev->mode_config.connector_list, head) { 181162306a36Sopenharmony_ci enum radeon_hpd_id hpd = 181262306a36Sopenharmony_ci to_radeon_connector(connector)->hpd.hpd; 181362306a36Sopenharmony_ci 181462306a36Sopenharmony_ci if (hpd == RADEON_HPD_NONE) 181562306a36Sopenharmony_ci continue; 181662306a36Sopenharmony_ci 181762306a36Sopenharmony_ci WREG32(DC_HPDx_CONTROL(hpd), 0); 181862306a36Sopenharmony_ci disabled |= 1 << hpd; 181962306a36Sopenharmony_ci } 182062306a36Sopenharmony_ci radeon_irq_kms_disable_hpd(rdev, disabled); 182162306a36Sopenharmony_ci} 182262306a36Sopenharmony_ci 182362306a36Sopenharmony_ci/* watermark setup */ 182462306a36Sopenharmony_ci 182562306a36Sopenharmony_cistatic u32 evergreen_line_buffer_adjust(struct radeon_device *rdev, 182662306a36Sopenharmony_ci struct radeon_crtc *radeon_crtc, 182762306a36Sopenharmony_ci struct drm_display_mode *mode, 182862306a36Sopenharmony_ci struct drm_display_mode *other_mode) 182962306a36Sopenharmony_ci{ 183062306a36Sopenharmony_ci u32 tmp, buffer_alloc, i; 183162306a36Sopenharmony_ci u32 pipe_offset = radeon_crtc->crtc_id * 0x20; 183262306a36Sopenharmony_ci /* 183362306a36Sopenharmony_ci * Line Buffer Setup 183462306a36Sopenharmony_ci * There are 3 line buffers, each one shared by 2 display controllers. 183562306a36Sopenharmony_ci * DC_LB_MEMORY_SPLIT controls how that line buffer is shared between 183662306a36Sopenharmony_ci * the display controllers. The paritioning is done via one of four 183762306a36Sopenharmony_ci * preset allocations specified in bits 2:0: 183862306a36Sopenharmony_ci * first display controller 183962306a36Sopenharmony_ci * 0 - first half of lb (3840 * 2) 184062306a36Sopenharmony_ci * 1 - first 3/4 of lb (5760 * 2) 184162306a36Sopenharmony_ci * 2 - whole lb (7680 * 2), other crtc must be disabled 184262306a36Sopenharmony_ci * 3 - first 1/4 of lb (1920 * 2) 184362306a36Sopenharmony_ci * second display controller 184462306a36Sopenharmony_ci * 4 - second half of lb (3840 * 2) 184562306a36Sopenharmony_ci * 5 - second 3/4 of lb (5760 * 2) 184662306a36Sopenharmony_ci * 6 - whole lb (7680 * 2), other crtc must be disabled 184762306a36Sopenharmony_ci * 7 - last 1/4 of lb (1920 * 2) 184862306a36Sopenharmony_ci */ 184962306a36Sopenharmony_ci /* this can get tricky if we have two large displays on a paired group 185062306a36Sopenharmony_ci * of crtcs. Ideally for multiple large displays we'd assign them to 185162306a36Sopenharmony_ci * non-linked crtcs for maximum line buffer allocation. 185262306a36Sopenharmony_ci */ 185362306a36Sopenharmony_ci if (radeon_crtc->base.enabled && mode) { 185462306a36Sopenharmony_ci if (other_mode) { 185562306a36Sopenharmony_ci tmp = 0; /* 1/2 */ 185662306a36Sopenharmony_ci buffer_alloc = 1; 185762306a36Sopenharmony_ci } else { 185862306a36Sopenharmony_ci tmp = 2; /* whole */ 185962306a36Sopenharmony_ci buffer_alloc = 2; 186062306a36Sopenharmony_ci } 186162306a36Sopenharmony_ci } else { 186262306a36Sopenharmony_ci tmp = 0; 186362306a36Sopenharmony_ci buffer_alloc = 0; 186462306a36Sopenharmony_ci } 186562306a36Sopenharmony_ci 186662306a36Sopenharmony_ci /* second controller of the pair uses second half of the lb */ 186762306a36Sopenharmony_ci if (radeon_crtc->crtc_id % 2) 186862306a36Sopenharmony_ci tmp += 4; 186962306a36Sopenharmony_ci WREG32(DC_LB_MEMORY_SPLIT + radeon_crtc->crtc_offset, tmp); 187062306a36Sopenharmony_ci 187162306a36Sopenharmony_ci if (ASIC_IS_DCE41(rdev) || ASIC_IS_DCE5(rdev)) { 187262306a36Sopenharmony_ci WREG32(PIPE0_DMIF_BUFFER_CONTROL + pipe_offset, 187362306a36Sopenharmony_ci DMIF_BUFFERS_ALLOCATED(buffer_alloc)); 187462306a36Sopenharmony_ci for (i = 0; i < rdev->usec_timeout; i++) { 187562306a36Sopenharmony_ci if (RREG32(PIPE0_DMIF_BUFFER_CONTROL + pipe_offset) & 187662306a36Sopenharmony_ci DMIF_BUFFERS_ALLOCATED_COMPLETED) 187762306a36Sopenharmony_ci break; 187862306a36Sopenharmony_ci udelay(1); 187962306a36Sopenharmony_ci } 188062306a36Sopenharmony_ci } 188162306a36Sopenharmony_ci 188262306a36Sopenharmony_ci if (radeon_crtc->base.enabled && mode) { 188362306a36Sopenharmony_ci switch (tmp) { 188462306a36Sopenharmony_ci case 0: 188562306a36Sopenharmony_ci case 4: 188662306a36Sopenharmony_ci default: 188762306a36Sopenharmony_ci if (ASIC_IS_DCE5(rdev)) 188862306a36Sopenharmony_ci return 4096 * 2; 188962306a36Sopenharmony_ci else 189062306a36Sopenharmony_ci return 3840 * 2; 189162306a36Sopenharmony_ci case 1: 189262306a36Sopenharmony_ci case 5: 189362306a36Sopenharmony_ci if (ASIC_IS_DCE5(rdev)) 189462306a36Sopenharmony_ci return 6144 * 2; 189562306a36Sopenharmony_ci else 189662306a36Sopenharmony_ci return 5760 * 2; 189762306a36Sopenharmony_ci case 2: 189862306a36Sopenharmony_ci case 6: 189962306a36Sopenharmony_ci if (ASIC_IS_DCE5(rdev)) 190062306a36Sopenharmony_ci return 8192 * 2; 190162306a36Sopenharmony_ci else 190262306a36Sopenharmony_ci return 7680 * 2; 190362306a36Sopenharmony_ci case 3: 190462306a36Sopenharmony_ci case 7: 190562306a36Sopenharmony_ci if (ASIC_IS_DCE5(rdev)) 190662306a36Sopenharmony_ci return 2048 * 2; 190762306a36Sopenharmony_ci else 190862306a36Sopenharmony_ci return 1920 * 2; 190962306a36Sopenharmony_ci } 191062306a36Sopenharmony_ci } 191162306a36Sopenharmony_ci 191262306a36Sopenharmony_ci /* controller not enabled, so no lb used */ 191362306a36Sopenharmony_ci return 0; 191462306a36Sopenharmony_ci} 191562306a36Sopenharmony_ci 191662306a36Sopenharmony_ciu32 evergreen_get_number_of_dram_channels(struct radeon_device *rdev) 191762306a36Sopenharmony_ci{ 191862306a36Sopenharmony_ci u32 tmp = RREG32(MC_SHARED_CHMAP); 191962306a36Sopenharmony_ci 192062306a36Sopenharmony_ci switch ((tmp & NOOFCHAN_MASK) >> NOOFCHAN_SHIFT) { 192162306a36Sopenharmony_ci case 0: 192262306a36Sopenharmony_ci default: 192362306a36Sopenharmony_ci return 1; 192462306a36Sopenharmony_ci case 1: 192562306a36Sopenharmony_ci return 2; 192662306a36Sopenharmony_ci case 2: 192762306a36Sopenharmony_ci return 4; 192862306a36Sopenharmony_ci case 3: 192962306a36Sopenharmony_ci return 8; 193062306a36Sopenharmony_ci } 193162306a36Sopenharmony_ci} 193262306a36Sopenharmony_ci 193362306a36Sopenharmony_cistruct evergreen_wm_params { 193462306a36Sopenharmony_ci u32 dram_channels; /* number of dram channels */ 193562306a36Sopenharmony_ci u32 yclk; /* bandwidth per dram data pin in kHz */ 193662306a36Sopenharmony_ci u32 sclk; /* engine clock in kHz */ 193762306a36Sopenharmony_ci u32 disp_clk; /* display clock in kHz */ 193862306a36Sopenharmony_ci u32 src_width; /* viewport width */ 193962306a36Sopenharmony_ci u32 active_time; /* active display time in ns */ 194062306a36Sopenharmony_ci u32 blank_time; /* blank time in ns */ 194162306a36Sopenharmony_ci bool interlaced; /* mode is interlaced */ 194262306a36Sopenharmony_ci fixed20_12 vsc; /* vertical scale ratio */ 194362306a36Sopenharmony_ci u32 num_heads; /* number of active crtcs */ 194462306a36Sopenharmony_ci u32 bytes_per_pixel; /* bytes per pixel display + overlay */ 194562306a36Sopenharmony_ci u32 lb_size; /* line buffer allocated to pipe */ 194662306a36Sopenharmony_ci u32 vtaps; /* vertical scaler taps */ 194762306a36Sopenharmony_ci}; 194862306a36Sopenharmony_ci 194962306a36Sopenharmony_cistatic u32 evergreen_dram_bandwidth(struct evergreen_wm_params *wm) 195062306a36Sopenharmony_ci{ 195162306a36Sopenharmony_ci /* Calculate DRAM Bandwidth and the part allocated to display. */ 195262306a36Sopenharmony_ci fixed20_12 dram_efficiency; /* 0.7 */ 195362306a36Sopenharmony_ci fixed20_12 yclk, dram_channels, bandwidth; 195462306a36Sopenharmony_ci fixed20_12 a; 195562306a36Sopenharmony_ci 195662306a36Sopenharmony_ci a.full = dfixed_const(1000); 195762306a36Sopenharmony_ci yclk.full = dfixed_const(wm->yclk); 195862306a36Sopenharmony_ci yclk.full = dfixed_div(yclk, a); 195962306a36Sopenharmony_ci dram_channels.full = dfixed_const(wm->dram_channels * 4); 196062306a36Sopenharmony_ci a.full = dfixed_const(10); 196162306a36Sopenharmony_ci dram_efficiency.full = dfixed_const(7); 196262306a36Sopenharmony_ci dram_efficiency.full = dfixed_div(dram_efficiency, a); 196362306a36Sopenharmony_ci bandwidth.full = dfixed_mul(dram_channels, yclk); 196462306a36Sopenharmony_ci bandwidth.full = dfixed_mul(bandwidth, dram_efficiency); 196562306a36Sopenharmony_ci 196662306a36Sopenharmony_ci return dfixed_trunc(bandwidth); 196762306a36Sopenharmony_ci} 196862306a36Sopenharmony_ci 196962306a36Sopenharmony_cistatic u32 evergreen_dram_bandwidth_for_display(struct evergreen_wm_params *wm) 197062306a36Sopenharmony_ci{ 197162306a36Sopenharmony_ci /* Calculate DRAM Bandwidth and the part allocated to display. */ 197262306a36Sopenharmony_ci fixed20_12 disp_dram_allocation; /* 0.3 to 0.7 */ 197362306a36Sopenharmony_ci fixed20_12 yclk, dram_channels, bandwidth; 197462306a36Sopenharmony_ci fixed20_12 a; 197562306a36Sopenharmony_ci 197662306a36Sopenharmony_ci a.full = dfixed_const(1000); 197762306a36Sopenharmony_ci yclk.full = dfixed_const(wm->yclk); 197862306a36Sopenharmony_ci yclk.full = dfixed_div(yclk, a); 197962306a36Sopenharmony_ci dram_channels.full = dfixed_const(wm->dram_channels * 4); 198062306a36Sopenharmony_ci a.full = dfixed_const(10); 198162306a36Sopenharmony_ci disp_dram_allocation.full = dfixed_const(3); /* XXX worse case value 0.3 */ 198262306a36Sopenharmony_ci disp_dram_allocation.full = dfixed_div(disp_dram_allocation, a); 198362306a36Sopenharmony_ci bandwidth.full = dfixed_mul(dram_channels, yclk); 198462306a36Sopenharmony_ci bandwidth.full = dfixed_mul(bandwidth, disp_dram_allocation); 198562306a36Sopenharmony_ci 198662306a36Sopenharmony_ci return dfixed_trunc(bandwidth); 198762306a36Sopenharmony_ci} 198862306a36Sopenharmony_ci 198962306a36Sopenharmony_cistatic u32 evergreen_data_return_bandwidth(struct evergreen_wm_params *wm) 199062306a36Sopenharmony_ci{ 199162306a36Sopenharmony_ci /* Calculate the display Data return Bandwidth */ 199262306a36Sopenharmony_ci fixed20_12 return_efficiency; /* 0.8 */ 199362306a36Sopenharmony_ci fixed20_12 sclk, bandwidth; 199462306a36Sopenharmony_ci fixed20_12 a; 199562306a36Sopenharmony_ci 199662306a36Sopenharmony_ci a.full = dfixed_const(1000); 199762306a36Sopenharmony_ci sclk.full = dfixed_const(wm->sclk); 199862306a36Sopenharmony_ci sclk.full = dfixed_div(sclk, a); 199962306a36Sopenharmony_ci a.full = dfixed_const(10); 200062306a36Sopenharmony_ci return_efficiency.full = dfixed_const(8); 200162306a36Sopenharmony_ci return_efficiency.full = dfixed_div(return_efficiency, a); 200262306a36Sopenharmony_ci a.full = dfixed_const(32); 200362306a36Sopenharmony_ci bandwidth.full = dfixed_mul(a, sclk); 200462306a36Sopenharmony_ci bandwidth.full = dfixed_mul(bandwidth, return_efficiency); 200562306a36Sopenharmony_ci 200662306a36Sopenharmony_ci return dfixed_trunc(bandwidth); 200762306a36Sopenharmony_ci} 200862306a36Sopenharmony_ci 200962306a36Sopenharmony_cistatic u32 evergreen_dmif_request_bandwidth(struct evergreen_wm_params *wm) 201062306a36Sopenharmony_ci{ 201162306a36Sopenharmony_ci /* Calculate the DMIF Request Bandwidth */ 201262306a36Sopenharmony_ci fixed20_12 disp_clk_request_efficiency; /* 0.8 */ 201362306a36Sopenharmony_ci fixed20_12 disp_clk, bandwidth; 201462306a36Sopenharmony_ci fixed20_12 a; 201562306a36Sopenharmony_ci 201662306a36Sopenharmony_ci a.full = dfixed_const(1000); 201762306a36Sopenharmony_ci disp_clk.full = dfixed_const(wm->disp_clk); 201862306a36Sopenharmony_ci disp_clk.full = dfixed_div(disp_clk, a); 201962306a36Sopenharmony_ci a.full = dfixed_const(10); 202062306a36Sopenharmony_ci disp_clk_request_efficiency.full = dfixed_const(8); 202162306a36Sopenharmony_ci disp_clk_request_efficiency.full = dfixed_div(disp_clk_request_efficiency, a); 202262306a36Sopenharmony_ci a.full = dfixed_const(32); 202362306a36Sopenharmony_ci bandwidth.full = dfixed_mul(a, disp_clk); 202462306a36Sopenharmony_ci bandwidth.full = dfixed_mul(bandwidth, disp_clk_request_efficiency); 202562306a36Sopenharmony_ci 202662306a36Sopenharmony_ci return dfixed_trunc(bandwidth); 202762306a36Sopenharmony_ci} 202862306a36Sopenharmony_ci 202962306a36Sopenharmony_cistatic u32 evergreen_available_bandwidth(struct evergreen_wm_params *wm) 203062306a36Sopenharmony_ci{ 203162306a36Sopenharmony_ci /* Calculate the Available bandwidth. Display can use this temporarily but not in average. */ 203262306a36Sopenharmony_ci u32 dram_bandwidth = evergreen_dram_bandwidth(wm); 203362306a36Sopenharmony_ci u32 data_return_bandwidth = evergreen_data_return_bandwidth(wm); 203462306a36Sopenharmony_ci u32 dmif_req_bandwidth = evergreen_dmif_request_bandwidth(wm); 203562306a36Sopenharmony_ci 203662306a36Sopenharmony_ci return min(dram_bandwidth, min(data_return_bandwidth, dmif_req_bandwidth)); 203762306a36Sopenharmony_ci} 203862306a36Sopenharmony_ci 203962306a36Sopenharmony_cistatic u32 evergreen_average_bandwidth(struct evergreen_wm_params *wm) 204062306a36Sopenharmony_ci{ 204162306a36Sopenharmony_ci /* Calculate the display mode Average Bandwidth 204262306a36Sopenharmony_ci * DisplayMode should contain the source and destination dimensions, 204362306a36Sopenharmony_ci * timing, etc. 204462306a36Sopenharmony_ci */ 204562306a36Sopenharmony_ci fixed20_12 bpp; 204662306a36Sopenharmony_ci fixed20_12 line_time; 204762306a36Sopenharmony_ci fixed20_12 src_width; 204862306a36Sopenharmony_ci fixed20_12 bandwidth; 204962306a36Sopenharmony_ci fixed20_12 a; 205062306a36Sopenharmony_ci 205162306a36Sopenharmony_ci a.full = dfixed_const(1000); 205262306a36Sopenharmony_ci line_time.full = dfixed_const(wm->active_time + wm->blank_time); 205362306a36Sopenharmony_ci line_time.full = dfixed_div(line_time, a); 205462306a36Sopenharmony_ci bpp.full = dfixed_const(wm->bytes_per_pixel); 205562306a36Sopenharmony_ci src_width.full = dfixed_const(wm->src_width); 205662306a36Sopenharmony_ci bandwidth.full = dfixed_mul(src_width, bpp); 205762306a36Sopenharmony_ci bandwidth.full = dfixed_mul(bandwidth, wm->vsc); 205862306a36Sopenharmony_ci bandwidth.full = dfixed_div(bandwidth, line_time); 205962306a36Sopenharmony_ci 206062306a36Sopenharmony_ci return dfixed_trunc(bandwidth); 206162306a36Sopenharmony_ci} 206262306a36Sopenharmony_ci 206362306a36Sopenharmony_cistatic u32 evergreen_latency_watermark(struct evergreen_wm_params *wm) 206462306a36Sopenharmony_ci{ 206562306a36Sopenharmony_ci /* First calcualte the latency in ns */ 206662306a36Sopenharmony_ci u32 mc_latency = 2000; /* 2000 ns. */ 206762306a36Sopenharmony_ci u32 available_bandwidth = evergreen_available_bandwidth(wm); 206862306a36Sopenharmony_ci u32 worst_chunk_return_time = (512 * 8 * 1000) / available_bandwidth; 206962306a36Sopenharmony_ci u32 cursor_line_pair_return_time = (128 * 4 * 1000) / available_bandwidth; 207062306a36Sopenharmony_ci u32 dc_latency = 40000000 / wm->disp_clk; /* dc pipe latency */ 207162306a36Sopenharmony_ci u32 other_heads_data_return_time = ((wm->num_heads + 1) * worst_chunk_return_time) + 207262306a36Sopenharmony_ci (wm->num_heads * cursor_line_pair_return_time); 207362306a36Sopenharmony_ci u32 latency = mc_latency + other_heads_data_return_time + dc_latency; 207462306a36Sopenharmony_ci u32 max_src_lines_per_dst_line, lb_fill_bw, line_fill_time; 207562306a36Sopenharmony_ci fixed20_12 a, b, c; 207662306a36Sopenharmony_ci 207762306a36Sopenharmony_ci if (wm->num_heads == 0) 207862306a36Sopenharmony_ci return 0; 207962306a36Sopenharmony_ci 208062306a36Sopenharmony_ci a.full = dfixed_const(2); 208162306a36Sopenharmony_ci b.full = dfixed_const(1); 208262306a36Sopenharmony_ci if ((wm->vsc.full > a.full) || 208362306a36Sopenharmony_ci ((wm->vsc.full > b.full) && (wm->vtaps >= 3)) || 208462306a36Sopenharmony_ci (wm->vtaps >= 5) || 208562306a36Sopenharmony_ci ((wm->vsc.full >= a.full) && wm->interlaced)) 208662306a36Sopenharmony_ci max_src_lines_per_dst_line = 4; 208762306a36Sopenharmony_ci else 208862306a36Sopenharmony_ci max_src_lines_per_dst_line = 2; 208962306a36Sopenharmony_ci 209062306a36Sopenharmony_ci a.full = dfixed_const(available_bandwidth); 209162306a36Sopenharmony_ci b.full = dfixed_const(wm->num_heads); 209262306a36Sopenharmony_ci a.full = dfixed_div(a, b); 209362306a36Sopenharmony_ci 209462306a36Sopenharmony_ci lb_fill_bw = min(dfixed_trunc(a), wm->disp_clk * wm->bytes_per_pixel / 1000); 209562306a36Sopenharmony_ci 209662306a36Sopenharmony_ci a.full = dfixed_const(max_src_lines_per_dst_line * wm->src_width * wm->bytes_per_pixel); 209762306a36Sopenharmony_ci b.full = dfixed_const(1000); 209862306a36Sopenharmony_ci c.full = dfixed_const(lb_fill_bw); 209962306a36Sopenharmony_ci b.full = dfixed_div(c, b); 210062306a36Sopenharmony_ci a.full = dfixed_div(a, b); 210162306a36Sopenharmony_ci line_fill_time = dfixed_trunc(a); 210262306a36Sopenharmony_ci 210362306a36Sopenharmony_ci if (line_fill_time < wm->active_time) 210462306a36Sopenharmony_ci return latency; 210562306a36Sopenharmony_ci else 210662306a36Sopenharmony_ci return latency + (line_fill_time - wm->active_time); 210762306a36Sopenharmony_ci 210862306a36Sopenharmony_ci} 210962306a36Sopenharmony_ci 211062306a36Sopenharmony_cistatic bool evergreen_average_bandwidth_vs_dram_bandwidth_for_display(struct evergreen_wm_params *wm) 211162306a36Sopenharmony_ci{ 211262306a36Sopenharmony_ci if (evergreen_average_bandwidth(wm) <= 211362306a36Sopenharmony_ci (evergreen_dram_bandwidth_for_display(wm) / wm->num_heads)) 211462306a36Sopenharmony_ci return true; 211562306a36Sopenharmony_ci else 211662306a36Sopenharmony_ci return false; 211762306a36Sopenharmony_ci}; 211862306a36Sopenharmony_ci 211962306a36Sopenharmony_cistatic bool evergreen_average_bandwidth_vs_available_bandwidth(struct evergreen_wm_params *wm) 212062306a36Sopenharmony_ci{ 212162306a36Sopenharmony_ci if (evergreen_average_bandwidth(wm) <= 212262306a36Sopenharmony_ci (evergreen_available_bandwidth(wm) / wm->num_heads)) 212362306a36Sopenharmony_ci return true; 212462306a36Sopenharmony_ci else 212562306a36Sopenharmony_ci return false; 212662306a36Sopenharmony_ci}; 212762306a36Sopenharmony_ci 212862306a36Sopenharmony_cistatic bool evergreen_check_latency_hiding(struct evergreen_wm_params *wm) 212962306a36Sopenharmony_ci{ 213062306a36Sopenharmony_ci u32 lb_partitions = wm->lb_size / wm->src_width; 213162306a36Sopenharmony_ci u32 line_time = wm->active_time + wm->blank_time; 213262306a36Sopenharmony_ci u32 latency_tolerant_lines; 213362306a36Sopenharmony_ci u32 latency_hiding; 213462306a36Sopenharmony_ci fixed20_12 a; 213562306a36Sopenharmony_ci 213662306a36Sopenharmony_ci a.full = dfixed_const(1); 213762306a36Sopenharmony_ci if (wm->vsc.full > a.full) 213862306a36Sopenharmony_ci latency_tolerant_lines = 1; 213962306a36Sopenharmony_ci else { 214062306a36Sopenharmony_ci if (lb_partitions <= (wm->vtaps + 1)) 214162306a36Sopenharmony_ci latency_tolerant_lines = 1; 214262306a36Sopenharmony_ci else 214362306a36Sopenharmony_ci latency_tolerant_lines = 2; 214462306a36Sopenharmony_ci } 214562306a36Sopenharmony_ci 214662306a36Sopenharmony_ci latency_hiding = (latency_tolerant_lines * line_time + wm->blank_time); 214762306a36Sopenharmony_ci 214862306a36Sopenharmony_ci if (evergreen_latency_watermark(wm) <= latency_hiding) 214962306a36Sopenharmony_ci return true; 215062306a36Sopenharmony_ci else 215162306a36Sopenharmony_ci return false; 215262306a36Sopenharmony_ci} 215362306a36Sopenharmony_ci 215462306a36Sopenharmony_cistatic void evergreen_program_watermarks(struct radeon_device *rdev, 215562306a36Sopenharmony_ci struct radeon_crtc *radeon_crtc, 215662306a36Sopenharmony_ci u32 lb_size, u32 num_heads) 215762306a36Sopenharmony_ci{ 215862306a36Sopenharmony_ci struct drm_display_mode *mode = &radeon_crtc->base.mode; 215962306a36Sopenharmony_ci struct evergreen_wm_params wm_low, wm_high; 216062306a36Sopenharmony_ci u32 dram_channels; 216162306a36Sopenharmony_ci u32 active_time; 216262306a36Sopenharmony_ci u32 line_time = 0; 216362306a36Sopenharmony_ci u32 latency_watermark_a = 0, latency_watermark_b = 0; 216462306a36Sopenharmony_ci u32 priority_a_mark = 0, priority_b_mark = 0; 216562306a36Sopenharmony_ci u32 priority_a_cnt = PRIORITY_OFF; 216662306a36Sopenharmony_ci u32 priority_b_cnt = PRIORITY_OFF; 216762306a36Sopenharmony_ci u32 pipe_offset = radeon_crtc->crtc_id * 16; 216862306a36Sopenharmony_ci u32 tmp, arb_control3; 216962306a36Sopenharmony_ci fixed20_12 a, b, c; 217062306a36Sopenharmony_ci 217162306a36Sopenharmony_ci if (radeon_crtc->base.enabled && num_heads && mode) { 217262306a36Sopenharmony_ci active_time = (u32) div_u64((u64)mode->crtc_hdisplay * 1000000, 217362306a36Sopenharmony_ci (u32)mode->clock); 217462306a36Sopenharmony_ci line_time = (u32) div_u64((u64)mode->crtc_htotal * 1000000, 217562306a36Sopenharmony_ci (u32)mode->clock); 217662306a36Sopenharmony_ci line_time = min(line_time, (u32)65535); 217762306a36Sopenharmony_ci priority_a_cnt = 0; 217862306a36Sopenharmony_ci priority_b_cnt = 0; 217962306a36Sopenharmony_ci dram_channels = evergreen_get_number_of_dram_channels(rdev); 218062306a36Sopenharmony_ci 218162306a36Sopenharmony_ci /* watermark for high clocks */ 218262306a36Sopenharmony_ci if ((rdev->pm.pm_method == PM_METHOD_DPM) && rdev->pm.dpm_enabled) { 218362306a36Sopenharmony_ci wm_high.yclk = 218462306a36Sopenharmony_ci radeon_dpm_get_mclk(rdev, false) * 10; 218562306a36Sopenharmony_ci wm_high.sclk = 218662306a36Sopenharmony_ci radeon_dpm_get_sclk(rdev, false) * 10; 218762306a36Sopenharmony_ci } else { 218862306a36Sopenharmony_ci wm_high.yclk = rdev->pm.current_mclk * 10; 218962306a36Sopenharmony_ci wm_high.sclk = rdev->pm.current_sclk * 10; 219062306a36Sopenharmony_ci } 219162306a36Sopenharmony_ci 219262306a36Sopenharmony_ci wm_high.disp_clk = mode->clock; 219362306a36Sopenharmony_ci wm_high.src_width = mode->crtc_hdisplay; 219462306a36Sopenharmony_ci wm_high.active_time = active_time; 219562306a36Sopenharmony_ci wm_high.blank_time = line_time - wm_high.active_time; 219662306a36Sopenharmony_ci wm_high.interlaced = false; 219762306a36Sopenharmony_ci if (mode->flags & DRM_MODE_FLAG_INTERLACE) 219862306a36Sopenharmony_ci wm_high.interlaced = true; 219962306a36Sopenharmony_ci wm_high.vsc = radeon_crtc->vsc; 220062306a36Sopenharmony_ci wm_high.vtaps = 1; 220162306a36Sopenharmony_ci if (radeon_crtc->rmx_type != RMX_OFF) 220262306a36Sopenharmony_ci wm_high.vtaps = 2; 220362306a36Sopenharmony_ci wm_high.bytes_per_pixel = 4; /* XXX: get this from fb config */ 220462306a36Sopenharmony_ci wm_high.lb_size = lb_size; 220562306a36Sopenharmony_ci wm_high.dram_channels = dram_channels; 220662306a36Sopenharmony_ci wm_high.num_heads = num_heads; 220762306a36Sopenharmony_ci 220862306a36Sopenharmony_ci /* watermark for low clocks */ 220962306a36Sopenharmony_ci if ((rdev->pm.pm_method == PM_METHOD_DPM) && rdev->pm.dpm_enabled) { 221062306a36Sopenharmony_ci wm_low.yclk = 221162306a36Sopenharmony_ci radeon_dpm_get_mclk(rdev, true) * 10; 221262306a36Sopenharmony_ci wm_low.sclk = 221362306a36Sopenharmony_ci radeon_dpm_get_sclk(rdev, true) * 10; 221462306a36Sopenharmony_ci } else { 221562306a36Sopenharmony_ci wm_low.yclk = rdev->pm.current_mclk * 10; 221662306a36Sopenharmony_ci wm_low.sclk = rdev->pm.current_sclk * 10; 221762306a36Sopenharmony_ci } 221862306a36Sopenharmony_ci 221962306a36Sopenharmony_ci wm_low.disp_clk = mode->clock; 222062306a36Sopenharmony_ci wm_low.src_width = mode->crtc_hdisplay; 222162306a36Sopenharmony_ci wm_low.active_time = active_time; 222262306a36Sopenharmony_ci wm_low.blank_time = line_time - wm_low.active_time; 222362306a36Sopenharmony_ci wm_low.interlaced = false; 222462306a36Sopenharmony_ci if (mode->flags & DRM_MODE_FLAG_INTERLACE) 222562306a36Sopenharmony_ci wm_low.interlaced = true; 222662306a36Sopenharmony_ci wm_low.vsc = radeon_crtc->vsc; 222762306a36Sopenharmony_ci wm_low.vtaps = 1; 222862306a36Sopenharmony_ci if (radeon_crtc->rmx_type != RMX_OFF) 222962306a36Sopenharmony_ci wm_low.vtaps = 2; 223062306a36Sopenharmony_ci wm_low.bytes_per_pixel = 4; /* XXX: get this from fb config */ 223162306a36Sopenharmony_ci wm_low.lb_size = lb_size; 223262306a36Sopenharmony_ci wm_low.dram_channels = dram_channels; 223362306a36Sopenharmony_ci wm_low.num_heads = num_heads; 223462306a36Sopenharmony_ci 223562306a36Sopenharmony_ci /* set for high clocks */ 223662306a36Sopenharmony_ci latency_watermark_a = min(evergreen_latency_watermark(&wm_high), (u32)65535); 223762306a36Sopenharmony_ci /* set for low clocks */ 223862306a36Sopenharmony_ci latency_watermark_b = min(evergreen_latency_watermark(&wm_low), (u32)65535); 223962306a36Sopenharmony_ci 224062306a36Sopenharmony_ci /* possibly force display priority to high */ 224162306a36Sopenharmony_ci /* should really do this at mode validation time... */ 224262306a36Sopenharmony_ci if (!evergreen_average_bandwidth_vs_dram_bandwidth_for_display(&wm_high) || 224362306a36Sopenharmony_ci !evergreen_average_bandwidth_vs_available_bandwidth(&wm_high) || 224462306a36Sopenharmony_ci !evergreen_check_latency_hiding(&wm_high) || 224562306a36Sopenharmony_ci (rdev->disp_priority == 2)) { 224662306a36Sopenharmony_ci DRM_DEBUG_KMS("force priority a to high\n"); 224762306a36Sopenharmony_ci priority_a_cnt |= PRIORITY_ALWAYS_ON; 224862306a36Sopenharmony_ci } 224962306a36Sopenharmony_ci if (!evergreen_average_bandwidth_vs_dram_bandwidth_for_display(&wm_low) || 225062306a36Sopenharmony_ci !evergreen_average_bandwidth_vs_available_bandwidth(&wm_low) || 225162306a36Sopenharmony_ci !evergreen_check_latency_hiding(&wm_low) || 225262306a36Sopenharmony_ci (rdev->disp_priority == 2)) { 225362306a36Sopenharmony_ci DRM_DEBUG_KMS("force priority b to high\n"); 225462306a36Sopenharmony_ci priority_b_cnt |= PRIORITY_ALWAYS_ON; 225562306a36Sopenharmony_ci } 225662306a36Sopenharmony_ci 225762306a36Sopenharmony_ci a.full = dfixed_const(1000); 225862306a36Sopenharmony_ci b.full = dfixed_const(mode->clock); 225962306a36Sopenharmony_ci b.full = dfixed_div(b, a); 226062306a36Sopenharmony_ci c.full = dfixed_const(latency_watermark_a); 226162306a36Sopenharmony_ci c.full = dfixed_mul(c, b); 226262306a36Sopenharmony_ci c.full = dfixed_mul(c, radeon_crtc->hsc); 226362306a36Sopenharmony_ci c.full = dfixed_div(c, a); 226462306a36Sopenharmony_ci a.full = dfixed_const(16); 226562306a36Sopenharmony_ci c.full = dfixed_div(c, a); 226662306a36Sopenharmony_ci priority_a_mark = dfixed_trunc(c); 226762306a36Sopenharmony_ci priority_a_cnt |= priority_a_mark & PRIORITY_MARK_MASK; 226862306a36Sopenharmony_ci 226962306a36Sopenharmony_ci a.full = dfixed_const(1000); 227062306a36Sopenharmony_ci b.full = dfixed_const(mode->clock); 227162306a36Sopenharmony_ci b.full = dfixed_div(b, a); 227262306a36Sopenharmony_ci c.full = dfixed_const(latency_watermark_b); 227362306a36Sopenharmony_ci c.full = dfixed_mul(c, b); 227462306a36Sopenharmony_ci c.full = dfixed_mul(c, radeon_crtc->hsc); 227562306a36Sopenharmony_ci c.full = dfixed_div(c, a); 227662306a36Sopenharmony_ci a.full = dfixed_const(16); 227762306a36Sopenharmony_ci c.full = dfixed_div(c, a); 227862306a36Sopenharmony_ci priority_b_mark = dfixed_trunc(c); 227962306a36Sopenharmony_ci priority_b_cnt |= priority_b_mark & PRIORITY_MARK_MASK; 228062306a36Sopenharmony_ci 228162306a36Sopenharmony_ci /* Save number of lines the linebuffer leads before the scanout */ 228262306a36Sopenharmony_ci radeon_crtc->lb_vblank_lead_lines = DIV_ROUND_UP(lb_size, mode->crtc_hdisplay); 228362306a36Sopenharmony_ci } 228462306a36Sopenharmony_ci 228562306a36Sopenharmony_ci /* select wm A */ 228662306a36Sopenharmony_ci arb_control3 = RREG32(PIPE0_ARBITRATION_CONTROL3 + pipe_offset); 228762306a36Sopenharmony_ci tmp = arb_control3; 228862306a36Sopenharmony_ci tmp &= ~LATENCY_WATERMARK_MASK(3); 228962306a36Sopenharmony_ci tmp |= LATENCY_WATERMARK_MASK(1); 229062306a36Sopenharmony_ci WREG32(PIPE0_ARBITRATION_CONTROL3 + pipe_offset, tmp); 229162306a36Sopenharmony_ci WREG32(PIPE0_LATENCY_CONTROL + pipe_offset, 229262306a36Sopenharmony_ci (LATENCY_LOW_WATERMARK(latency_watermark_a) | 229362306a36Sopenharmony_ci LATENCY_HIGH_WATERMARK(line_time))); 229462306a36Sopenharmony_ci /* select wm B */ 229562306a36Sopenharmony_ci tmp = RREG32(PIPE0_ARBITRATION_CONTROL3 + pipe_offset); 229662306a36Sopenharmony_ci tmp &= ~LATENCY_WATERMARK_MASK(3); 229762306a36Sopenharmony_ci tmp |= LATENCY_WATERMARK_MASK(2); 229862306a36Sopenharmony_ci WREG32(PIPE0_ARBITRATION_CONTROL3 + pipe_offset, tmp); 229962306a36Sopenharmony_ci WREG32(PIPE0_LATENCY_CONTROL + pipe_offset, 230062306a36Sopenharmony_ci (LATENCY_LOW_WATERMARK(latency_watermark_b) | 230162306a36Sopenharmony_ci LATENCY_HIGH_WATERMARK(line_time))); 230262306a36Sopenharmony_ci /* restore original selection */ 230362306a36Sopenharmony_ci WREG32(PIPE0_ARBITRATION_CONTROL3 + pipe_offset, arb_control3); 230462306a36Sopenharmony_ci 230562306a36Sopenharmony_ci /* write the priority marks */ 230662306a36Sopenharmony_ci WREG32(PRIORITY_A_CNT + radeon_crtc->crtc_offset, priority_a_cnt); 230762306a36Sopenharmony_ci WREG32(PRIORITY_B_CNT + radeon_crtc->crtc_offset, priority_b_cnt); 230862306a36Sopenharmony_ci 230962306a36Sopenharmony_ci /* save values for DPM */ 231062306a36Sopenharmony_ci radeon_crtc->line_time = line_time; 231162306a36Sopenharmony_ci radeon_crtc->wm_high = latency_watermark_a; 231262306a36Sopenharmony_ci radeon_crtc->wm_low = latency_watermark_b; 231362306a36Sopenharmony_ci} 231462306a36Sopenharmony_ci 231562306a36Sopenharmony_ci/** 231662306a36Sopenharmony_ci * evergreen_bandwidth_update - update display watermarks callback. 231762306a36Sopenharmony_ci * 231862306a36Sopenharmony_ci * @rdev: radeon_device pointer 231962306a36Sopenharmony_ci * 232062306a36Sopenharmony_ci * Update the display watermarks based on the requested mode(s) 232162306a36Sopenharmony_ci * (evergreen+). 232262306a36Sopenharmony_ci */ 232362306a36Sopenharmony_civoid evergreen_bandwidth_update(struct radeon_device *rdev) 232462306a36Sopenharmony_ci{ 232562306a36Sopenharmony_ci struct drm_display_mode *mode0 = NULL; 232662306a36Sopenharmony_ci struct drm_display_mode *mode1 = NULL; 232762306a36Sopenharmony_ci u32 num_heads = 0, lb_size; 232862306a36Sopenharmony_ci int i; 232962306a36Sopenharmony_ci 233062306a36Sopenharmony_ci if (!rdev->mode_info.mode_config_initialized) 233162306a36Sopenharmony_ci return; 233262306a36Sopenharmony_ci 233362306a36Sopenharmony_ci radeon_update_display_priority(rdev); 233462306a36Sopenharmony_ci 233562306a36Sopenharmony_ci for (i = 0; i < rdev->num_crtc; i++) { 233662306a36Sopenharmony_ci if (rdev->mode_info.crtcs[i]->base.enabled) 233762306a36Sopenharmony_ci num_heads++; 233862306a36Sopenharmony_ci } 233962306a36Sopenharmony_ci for (i = 0; i < rdev->num_crtc; i += 2) { 234062306a36Sopenharmony_ci mode0 = &rdev->mode_info.crtcs[i]->base.mode; 234162306a36Sopenharmony_ci mode1 = &rdev->mode_info.crtcs[i+1]->base.mode; 234262306a36Sopenharmony_ci lb_size = evergreen_line_buffer_adjust(rdev, rdev->mode_info.crtcs[i], mode0, mode1); 234362306a36Sopenharmony_ci evergreen_program_watermarks(rdev, rdev->mode_info.crtcs[i], lb_size, num_heads); 234462306a36Sopenharmony_ci lb_size = evergreen_line_buffer_adjust(rdev, rdev->mode_info.crtcs[i+1], mode1, mode0); 234562306a36Sopenharmony_ci evergreen_program_watermarks(rdev, rdev->mode_info.crtcs[i+1], lb_size, num_heads); 234662306a36Sopenharmony_ci } 234762306a36Sopenharmony_ci} 234862306a36Sopenharmony_ci 234962306a36Sopenharmony_ci/** 235062306a36Sopenharmony_ci * evergreen_mc_wait_for_idle - wait for MC idle callback. 235162306a36Sopenharmony_ci * 235262306a36Sopenharmony_ci * @rdev: radeon_device pointer 235362306a36Sopenharmony_ci * 235462306a36Sopenharmony_ci * Wait for the MC (memory controller) to be idle. 235562306a36Sopenharmony_ci * (evergreen+). 235662306a36Sopenharmony_ci * Returns 0 if the MC is idle, -1 if not. 235762306a36Sopenharmony_ci */ 235862306a36Sopenharmony_ciint evergreen_mc_wait_for_idle(struct radeon_device *rdev) 235962306a36Sopenharmony_ci{ 236062306a36Sopenharmony_ci unsigned i; 236162306a36Sopenharmony_ci u32 tmp; 236262306a36Sopenharmony_ci 236362306a36Sopenharmony_ci for (i = 0; i < rdev->usec_timeout; i++) { 236462306a36Sopenharmony_ci /* read MC_STATUS */ 236562306a36Sopenharmony_ci tmp = RREG32(SRBM_STATUS) & 0x1F00; 236662306a36Sopenharmony_ci if (!tmp) 236762306a36Sopenharmony_ci return 0; 236862306a36Sopenharmony_ci udelay(1); 236962306a36Sopenharmony_ci } 237062306a36Sopenharmony_ci return -1; 237162306a36Sopenharmony_ci} 237262306a36Sopenharmony_ci 237362306a36Sopenharmony_ci/* 237462306a36Sopenharmony_ci * GART 237562306a36Sopenharmony_ci */ 237662306a36Sopenharmony_civoid evergreen_pcie_gart_tlb_flush(struct radeon_device *rdev) 237762306a36Sopenharmony_ci{ 237862306a36Sopenharmony_ci unsigned i; 237962306a36Sopenharmony_ci u32 tmp; 238062306a36Sopenharmony_ci 238162306a36Sopenharmony_ci WREG32(HDP_MEM_COHERENCY_FLUSH_CNTL, 0x1); 238262306a36Sopenharmony_ci 238362306a36Sopenharmony_ci WREG32(VM_CONTEXT0_REQUEST_RESPONSE, REQUEST_TYPE(1)); 238462306a36Sopenharmony_ci for (i = 0; i < rdev->usec_timeout; i++) { 238562306a36Sopenharmony_ci /* read MC_STATUS */ 238662306a36Sopenharmony_ci tmp = RREG32(VM_CONTEXT0_REQUEST_RESPONSE); 238762306a36Sopenharmony_ci tmp = (tmp & RESPONSE_TYPE_MASK) >> RESPONSE_TYPE_SHIFT; 238862306a36Sopenharmony_ci if (tmp == 2) { 238962306a36Sopenharmony_ci pr_warn("[drm] r600 flush TLB failed\n"); 239062306a36Sopenharmony_ci return; 239162306a36Sopenharmony_ci } 239262306a36Sopenharmony_ci if (tmp) { 239362306a36Sopenharmony_ci return; 239462306a36Sopenharmony_ci } 239562306a36Sopenharmony_ci udelay(1); 239662306a36Sopenharmony_ci } 239762306a36Sopenharmony_ci} 239862306a36Sopenharmony_ci 239962306a36Sopenharmony_cistatic int evergreen_pcie_gart_enable(struct radeon_device *rdev) 240062306a36Sopenharmony_ci{ 240162306a36Sopenharmony_ci u32 tmp; 240262306a36Sopenharmony_ci int r; 240362306a36Sopenharmony_ci 240462306a36Sopenharmony_ci if (rdev->gart.robj == NULL) { 240562306a36Sopenharmony_ci dev_err(rdev->dev, "No VRAM object for PCIE GART.\n"); 240662306a36Sopenharmony_ci return -EINVAL; 240762306a36Sopenharmony_ci } 240862306a36Sopenharmony_ci r = radeon_gart_table_vram_pin(rdev); 240962306a36Sopenharmony_ci if (r) 241062306a36Sopenharmony_ci return r; 241162306a36Sopenharmony_ci /* Setup L2 cache */ 241262306a36Sopenharmony_ci WREG32(VM_L2_CNTL, ENABLE_L2_CACHE | ENABLE_L2_FRAGMENT_PROCESSING | 241362306a36Sopenharmony_ci ENABLE_L2_PTE_CACHE_LRU_UPDATE_BY_WRITE | 241462306a36Sopenharmony_ci EFFECTIVE_L2_QUEUE_SIZE(7)); 241562306a36Sopenharmony_ci WREG32(VM_L2_CNTL2, 0); 241662306a36Sopenharmony_ci WREG32(VM_L2_CNTL3, BANK_SELECT(0) | CACHE_UPDATE_MODE(2)); 241762306a36Sopenharmony_ci /* Setup TLB control */ 241862306a36Sopenharmony_ci tmp = ENABLE_L1_TLB | ENABLE_L1_FRAGMENT_PROCESSING | 241962306a36Sopenharmony_ci SYSTEM_ACCESS_MODE_NOT_IN_SYS | 242062306a36Sopenharmony_ci SYSTEM_APERTURE_UNMAPPED_ACCESS_PASS_THRU | 242162306a36Sopenharmony_ci EFFECTIVE_L1_TLB_SIZE(5) | EFFECTIVE_L1_QUEUE_SIZE(5); 242262306a36Sopenharmony_ci if (rdev->flags & RADEON_IS_IGP) { 242362306a36Sopenharmony_ci WREG32(FUS_MC_VM_MD_L1_TLB0_CNTL, tmp); 242462306a36Sopenharmony_ci WREG32(FUS_MC_VM_MD_L1_TLB1_CNTL, tmp); 242562306a36Sopenharmony_ci WREG32(FUS_MC_VM_MD_L1_TLB2_CNTL, tmp); 242662306a36Sopenharmony_ci } else { 242762306a36Sopenharmony_ci WREG32(MC_VM_MD_L1_TLB0_CNTL, tmp); 242862306a36Sopenharmony_ci WREG32(MC_VM_MD_L1_TLB1_CNTL, tmp); 242962306a36Sopenharmony_ci WREG32(MC_VM_MD_L1_TLB2_CNTL, tmp); 243062306a36Sopenharmony_ci if ((rdev->family == CHIP_JUNIPER) || 243162306a36Sopenharmony_ci (rdev->family == CHIP_CYPRESS) || 243262306a36Sopenharmony_ci (rdev->family == CHIP_HEMLOCK) || 243362306a36Sopenharmony_ci (rdev->family == CHIP_BARTS)) 243462306a36Sopenharmony_ci WREG32(MC_VM_MD_L1_TLB3_CNTL, tmp); 243562306a36Sopenharmony_ci } 243662306a36Sopenharmony_ci WREG32(MC_VM_MB_L1_TLB0_CNTL, tmp); 243762306a36Sopenharmony_ci WREG32(MC_VM_MB_L1_TLB1_CNTL, tmp); 243862306a36Sopenharmony_ci WREG32(MC_VM_MB_L1_TLB2_CNTL, tmp); 243962306a36Sopenharmony_ci WREG32(MC_VM_MB_L1_TLB3_CNTL, tmp); 244062306a36Sopenharmony_ci WREG32(VM_CONTEXT0_PAGE_TABLE_START_ADDR, rdev->mc.gtt_start >> 12); 244162306a36Sopenharmony_ci WREG32(VM_CONTEXT0_PAGE_TABLE_END_ADDR, rdev->mc.gtt_end >> 12); 244262306a36Sopenharmony_ci WREG32(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR, rdev->gart.table_addr >> 12); 244362306a36Sopenharmony_ci WREG32(VM_CONTEXT0_CNTL, ENABLE_CONTEXT | PAGE_TABLE_DEPTH(0) | 244462306a36Sopenharmony_ci RANGE_PROTECTION_FAULT_ENABLE_DEFAULT); 244562306a36Sopenharmony_ci WREG32(VM_CONTEXT0_PROTECTION_FAULT_DEFAULT_ADDR, 244662306a36Sopenharmony_ci (u32)(rdev->dummy_page.addr >> 12)); 244762306a36Sopenharmony_ci WREG32(VM_CONTEXT1_CNTL, 0); 244862306a36Sopenharmony_ci 244962306a36Sopenharmony_ci evergreen_pcie_gart_tlb_flush(rdev); 245062306a36Sopenharmony_ci DRM_INFO("PCIE GART of %uM enabled (table at 0x%016llX).\n", 245162306a36Sopenharmony_ci (unsigned)(rdev->mc.gtt_size >> 20), 245262306a36Sopenharmony_ci (unsigned long long)rdev->gart.table_addr); 245362306a36Sopenharmony_ci rdev->gart.ready = true; 245462306a36Sopenharmony_ci return 0; 245562306a36Sopenharmony_ci} 245662306a36Sopenharmony_ci 245762306a36Sopenharmony_cistatic void evergreen_pcie_gart_disable(struct radeon_device *rdev) 245862306a36Sopenharmony_ci{ 245962306a36Sopenharmony_ci u32 tmp; 246062306a36Sopenharmony_ci 246162306a36Sopenharmony_ci /* Disable all tables */ 246262306a36Sopenharmony_ci WREG32(VM_CONTEXT0_CNTL, 0); 246362306a36Sopenharmony_ci WREG32(VM_CONTEXT1_CNTL, 0); 246462306a36Sopenharmony_ci 246562306a36Sopenharmony_ci /* Setup L2 cache */ 246662306a36Sopenharmony_ci WREG32(VM_L2_CNTL, ENABLE_L2_FRAGMENT_PROCESSING | 246762306a36Sopenharmony_ci EFFECTIVE_L2_QUEUE_SIZE(7)); 246862306a36Sopenharmony_ci WREG32(VM_L2_CNTL2, 0); 246962306a36Sopenharmony_ci WREG32(VM_L2_CNTL3, BANK_SELECT(0) | CACHE_UPDATE_MODE(2)); 247062306a36Sopenharmony_ci /* Setup TLB control */ 247162306a36Sopenharmony_ci tmp = EFFECTIVE_L1_TLB_SIZE(5) | EFFECTIVE_L1_QUEUE_SIZE(5); 247262306a36Sopenharmony_ci WREG32(MC_VM_MD_L1_TLB0_CNTL, tmp); 247362306a36Sopenharmony_ci WREG32(MC_VM_MD_L1_TLB1_CNTL, tmp); 247462306a36Sopenharmony_ci WREG32(MC_VM_MD_L1_TLB2_CNTL, tmp); 247562306a36Sopenharmony_ci WREG32(MC_VM_MB_L1_TLB0_CNTL, tmp); 247662306a36Sopenharmony_ci WREG32(MC_VM_MB_L1_TLB1_CNTL, tmp); 247762306a36Sopenharmony_ci WREG32(MC_VM_MB_L1_TLB2_CNTL, tmp); 247862306a36Sopenharmony_ci WREG32(MC_VM_MB_L1_TLB3_CNTL, tmp); 247962306a36Sopenharmony_ci radeon_gart_table_vram_unpin(rdev); 248062306a36Sopenharmony_ci} 248162306a36Sopenharmony_ci 248262306a36Sopenharmony_cistatic void evergreen_pcie_gart_fini(struct radeon_device *rdev) 248362306a36Sopenharmony_ci{ 248462306a36Sopenharmony_ci evergreen_pcie_gart_disable(rdev); 248562306a36Sopenharmony_ci radeon_gart_table_vram_free(rdev); 248662306a36Sopenharmony_ci radeon_gart_fini(rdev); 248762306a36Sopenharmony_ci} 248862306a36Sopenharmony_ci 248962306a36Sopenharmony_ci 249062306a36Sopenharmony_cistatic void evergreen_agp_enable(struct radeon_device *rdev) 249162306a36Sopenharmony_ci{ 249262306a36Sopenharmony_ci u32 tmp; 249362306a36Sopenharmony_ci 249462306a36Sopenharmony_ci /* Setup L2 cache */ 249562306a36Sopenharmony_ci WREG32(VM_L2_CNTL, ENABLE_L2_CACHE | ENABLE_L2_FRAGMENT_PROCESSING | 249662306a36Sopenharmony_ci ENABLE_L2_PTE_CACHE_LRU_UPDATE_BY_WRITE | 249762306a36Sopenharmony_ci EFFECTIVE_L2_QUEUE_SIZE(7)); 249862306a36Sopenharmony_ci WREG32(VM_L2_CNTL2, 0); 249962306a36Sopenharmony_ci WREG32(VM_L2_CNTL3, BANK_SELECT(0) | CACHE_UPDATE_MODE(2)); 250062306a36Sopenharmony_ci /* Setup TLB control */ 250162306a36Sopenharmony_ci tmp = ENABLE_L1_TLB | ENABLE_L1_FRAGMENT_PROCESSING | 250262306a36Sopenharmony_ci SYSTEM_ACCESS_MODE_NOT_IN_SYS | 250362306a36Sopenharmony_ci SYSTEM_APERTURE_UNMAPPED_ACCESS_PASS_THRU | 250462306a36Sopenharmony_ci EFFECTIVE_L1_TLB_SIZE(5) | EFFECTIVE_L1_QUEUE_SIZE(5); 250562306a36Sopenharmony_ci WREG32(MC_VM_MD_L1_TLB0_CNTL, tmp); 250662306a36Sopenharmony_ci WREG32(MC_VM_MD_L1_TLB1_CNTL, tmp); 250762306a36Sopenharmony_ci WREG32(MC_VM_MD_L1_TLB2_CNTL, tmp); 250862306a36Sopenharmony_ci WREG32(MC_VM_MB_L1_TLB0_CNTL, tmp); 250962306a36Sopenharmony_ci WREG32(MC_VM_MB_L1_TLB1_CNTL, tmp); 251062306a36Sopenharmony_ci WREG32(MC_VM_MB_L1_TLB2_CNTL, tmp); 251162306a36Sopenharmony_ci WREG32(MC_VM_MB_L1_TLB3_CNTL, tmp); 251262306a36Sopenharmony_ci WREG32(VM_CONTEXT0_CNTL, 0); 251362306a36Sopenharmony_ci WREG32(VM_CONTEXT1_CNTL, 0); 251462306a36Sopenharmony_ci} 251562306a36Sopenharmony_ci 251662306a36Sopenharmony_cistatic const unsigned ni_dig_offsets[] = 251762306a36Sopenharmony_ci{ 251862306a36Sopenharmony_ci NI_DIG0_REGISTER_OFFSET, 251962306a36Sopenharmony_ci NI_DIG1_REGISTER_OFFSET, 252062306a36Sopenharmony_ci NI_DIG2_REGISTER_OFFSET, 252162306a36Sopenharmony_ci NI_DIG3_REGISTER_OFFSET, 252262306a36Sopenharmony_ci NI_DIG4_REGISTER_OFFSET, 252362306a36Sopenharmony_ci NI_DIG5_REGISTER_OFFSET 252462306a36Sopenharmony_ci}; 252562306a36Sopenharmony_ci 252662306a36Sopenharmony_cistatic const unsigned ni_tx_offsets[] = 252762306a36Sopenharmony_ci{ 252862306a36Sopenharmony_ci NI_DCIO_UNIPHY0_UNIPHY_TX_CONTROL1, 252962306a36Sopenharmony_ci NI_DCIO_UNIPHY1_UNIPHY_TX_CONTROL1, 253062306a36Sopenharmony_ci NI_DCIO_UNIPHY2_UNIPHY_TX_CONTROL1, 253162306a36Sopenharmony_ci NI_DCIO_UNIPHY3_UNIPHY_TX_CONTROL1, 253262306a36Sopenharmony_ci NI_DCIO_UNIPHY4_UNIPHY_TX_CONTROL1, 253362306a36Sopenharmony_ci NI_DCIO_UNIPHY5_UNIPHY_TX_CONTROL1 253462306a36Sopenharmony_ci}; 253562306a36Sopenharmony_ci 253662306a36Sopenharmony_cistatic const unsigned evergreen_dp_offsets[] = 253762306a36Sopenharmony_ci{ 253862306a36Sopenharmony_ci EVERGREEN_DP0_REGISTER_OFFSET, 253962306a36Sopenharmony_ci EVERGREEN_DP1_REGISTER_OFFSET, 254062306a36Sopenharmony_ci EVERGREEN_DP2_REGISTER_OFFSET, 254162306a36Sopenharmony_ci EVERGREEN_DP3_REGISTER_OFFSET, 254262306a36Sopenharmony_ci EVERGREEN_DP4_REGISTER_OFFSET, 254362306a36Sopenharmony_ci EVERGREEN_DP5_REGISTER_OFFSET 254462306a36Sopenharmony_ci}; 254562306a36Sopenharmony_ci 254662306a36Sopenharmony_cistatic const unsigned evergreen_disp_int_status[] = 254762306a36Sopenharmony_ci{ 254862306a36Sopenharmony_ci DISP_INTERRUPT_STATUS, 254962306a36Sopenharmony_ci DISP_INTERRUPT_STATUS_CONTINUE, 255062306a36Sopenharmony_ci DISP_INTERRUPT_STATUS_CONTINUE2, 255162306a36Sopenharmony_ci DISP_INTERRUPT_STATUS_CONTINUE3, 255262306a36Sopenharmony_ci DISP_INTERRUPT_STATUS_CONTINUE4, 255362306a36Sopenharmony_ci DISP_INTERRUPT_STATUS_CONTINUE5 255462306a36Sopenharmony_ci}; 255562306a36Sopenharmony_ci 255662306a36Sopenharmony_ci/* 255762306a36Sopenharmony_ci * Assumption is that EVERGREEN_CRTC_MASTER_EN enable for requested crtc 255862306a36Sopenharmony_ci * We go from crtc to connector and it is not relible since it 255962306a36Sopenharmony_ci * should be an opposite direction .If crtc is enable then 256062306a36Sopenharmony_ci * find the dig_fe which selects this crtc and insure that it enable. 256162306a36Sopenharmony_ci * if such dig_fe is found then find dig_be which selects found dig_be and 256262306a36Sopenharmony_ci * insure that it enable and in DP_SST mode. 256362306a36Sopenharmony_ci * if UNIPHY_PLL_CONTROL1.enable then we should disconnect timing 256462306a36Sopenharmony_ci * from dp symbols clocks . 256562306a36Sopenharmony_ci */ 256662306a36Sopenharmony_cistatic bool evergreen_is_dp_sst_stream_enabled(struct radeon_device *rdev, 256762306a36Sopenharmony_ci unsigned crtc_id, unsigned *ret_dig_fe) 256862306a36Sopenharmony_ci{ 256962306a36Sopenharmony_ci unsigned i; 257062306a36Sopenharmony_ci unsigned dig_fe; 257162306a36Sopenharmony_ci unsigned dig_be; 257262306a36Sopenharmony_ci unsigned dig_en_be; 257362306a36Sopenharmony_ci unsigned uniphy_pll; 257462306a36Sopenharmony_ci unsigned digs_fe_selected; 257562306a36Sopenharmony_ci unsigned dig_be_mode; 257662306a36Sopenharmony_ci unsigned dig_fe_mask; 257762306a36Sopenharmony_ci bool is_enabled = false; 257862306a36Sopenharmony_ci bool found_crtc = false; 257962306a36Sopenharmony_ci 258062306a36Sopenharmony_ci /* loop through all running dig_fe to find selected crtc */ 258162306a36Sopenharmony_ci for (i = 0; i < ARRAY_SIZE(ni_dig_offsets); i++) { 258262306a36Sopenharmony_ci dig_fe = RREG32(NI_DIG_FE_CNTL + ni_dig_offsets[i]); 258362306a36Sopenharmony_ci if (dig_fe & NI_DIG_FE_CNTL_SYMCLK_FE_ON && 258462306a36Sopenharmony_ci crtc_id == NI_DIG_FE_CNTL_SOURCE_SELECT(dig_fe)) { 258562306a36Sopenharmony_ci /* found running pipe */ 258662306a36Sopenharmony_ci found_crtc = true; 258762306a36Sopenharmony_ci dig_fe_mask = 1 << i; 258862306a36Sopenharmony_ci dig_fe = i; 258962306a36Sopenharmony_ci break; 259062306a36Sopenharmony_ci } 259162306a36Sopenharmony_ci } 259262306a36Sopenharmony_ci 259362306a36Sopenharmony_ci if (found_crtc) { 259462306a36Sopenharmony_ci /* loop through all running dig_be to find selected dig_fe */ 259562306a36Sopenharmony_ci for (i = 0; i < ARRAY_SIZE(ni_dig_offsets); i++) { 259662306a36Sopenharmony_ci dig_be = RREG32(NI_DIG_BE_CNTL + ni_dig_offsets[i]); 259762306a36Sopenharmony_ci /* if dig_fe_selected by dig_be? */ 259862306a36Sopenharmony_ci digs_fe_selected = NI_DIG_BE_CNTL_FE_SOURCE_SELECT(dig_be); 259962306a36Sopenharmony_ci dig_be_mode = NI_DIG_FE_CNTL_MODE(dig_be); 260062306a36Sopenharmony_ci if (dig_fe_mask & digs_fe_selected && 260162306a36Sopenharmony_ci /* if dig_be in sst mode? */ 260262306a36Sopenharmony_ci dig_be_mode == NI_DIG_BE_DPSST) { 260362306a36Sopenharmony_ci dig_en_be = RREG32(NI_DIG_BE_EN_CNTL + 260462306a36Sopenharmony_ci ni_dig_offsets[i]); 260562306a36Sopenharmony_ci uniphy_pll = RREG32(NI_DCIO_UNIPHY0_PLL_CONTROL1 + 260662306a36Sopenharmony_ci ni_tx_offsets[i]); 260762306a36Sopenharmony_ci /* dig_be enable and tx is running */ 260862306a36Sopenharmony_ci if (dig_en_be & NI_DIG_BE_EN_CNTL_ENABLE && 260962306a36Sopenharmony_ci dig_en_be & NI_DIG_BE_EN_CNTL_SYMBCLK_ON && 261062306a36Sopenharmony_ci uniphy_pll & NI_DCIO_UNIPHY0_PLL_CONTROL1_ENABLE) { 261162306a36Sopenharmony_ci is_enabled = true; 261262306a36Sopenharmony_ci *ret_dig_fe = dig_fe; 261362306a36Sopenharmony_ci break; 261462306a36Sopenharmony_ci } 261562306a36Sopenharmony_ci } 261662306a36Sopenharmony_ci } 261762306a36Sopenharmony_ci } 261862306a36Sopenharmony_ci 261962306a36Sopenharmony_ci return is_enabled; 262062306a36Sopenharmony_ci} 262162306a36Sopenharmony_ci 262262306a36Sopenharmony_ci/* 262362306a36Sopenharmony_ci * Blank dig when in dp sst mode 262462306a36Sopenharmony_ci * Dig ignores crtc timing 262562306a36Sopenharmony_ci */ 262662306a36Sopenharmony_cistatic void evergreen_blank_dp_output(struct radeon_device *rdev, 262762306a36Sopenharmony_ci unsigned dig_fe) 262862306a36Sopenharmony_ci{ 262962306a36Sopenharmony_ci unsigned stream_ctrl; 263062306a36Sopenharmony_ci unsigned fifo_ctrl; 263162306a36Sopenharmony_ci unsigned counter = 0; 263262306a36Sopenharmony_ci 263362306a36Sopenharmony_ci if (dig_fe >= ARRAY_SIZE(evergreen_dp_offsets)) { 263462306a36Sopenharmony_ci DRM_ERROR("invalid dig_fe %d\n", dig_fe); 263562306a36Sopenharmony_ci return; 263662306a36Sopenharmony_ci } 263762306a36Sopenharmony_ci 263862306a36Sopenharmony_ci stream_ctrl = RREG32(EVERGREEN_DP_VID_STREAM_CNTL + 263962306a36Sopenharmony_ci evergreen_dp_offsets[dig_fe]); 264062306a36Sopenharmony_ci if (!(stream_ctrl & EVERGREEN_DP_VID_STREAM_CNTL_ENABLE)) { 264162306a36Sopenharmony_ci DRM_ERROR("dig %d , should be enable\n", dig_fe); 264262306a36Sopenharmony_ci return; 264362306a36Sopenharmony_ci } 264462306a36Sopenharmony_ci 264562306a36Sopenharmony_ci stream_ctrl &=~EVERGREEN_DP_VID_STREAM_CNTL_ENABLE; 264662306a36Sopenharmony_ci WREG32(EVERGREEN_DP_VID_STREAM_CNTL + 264762306a36Sopenharmony_ci evergreen_dp_offsets[dig_fe], stream_ctrl); 264862306a36Sopenharmony_ci 264962306a36Sopenharmony_ci stream_ctrl = RREG32(EVERGREEN_DP_VID_STREAM_CNTL + 265062306a36Sopenharmony_ci evergreen_dp_offsets[dig_fe]); 265162306a36Sopenharmony_ci while (counter < 32 && stream_ctrl & EVERGREEN_DP_VID_STREAM_STATUS) { 265262306a36Sopenharmony_ci msleep(1); 265362306a36Sopenharmony_ci counter++; 265462306a36Sopenharmony_ci stream_ctrl = RREG32(EVERGREEN_DP_VID_STREAM_CNTL + 265562306a36Sopenharmony_ci evergreen_dp_offsets[dig_fe]); 265662306a36Sopenharmony_ci } 265762306a36Sopenharmony_ci if (counter >= 32 ) 265862306a36Sopenharmony_ci DRM_ERROR("counter exceeds %d\n", counter); 265962306a36Sopenharmony_ci 266062306a36Sopenharmony_ci fifo_ctrl = RREG32(EVERGREEN_DP_STEER_FIFO + evergreen_dp_offsets[dig_fe]); 266162306a36Sopenharmony_ci fifo_ctrl |= EVERGREEN_DP_STEER_FIFO_RESET; 266262306a36Sopenharmony_ci WREG32(EVERGREEN_DP_STEER_FIFO + evergreen_dp_offsets[dig_fe], fifo_ctrl); 266362306a36Sopenharmony_ci 266462306a36Sopenharmony_ci} 266562306a36Sopenharmony_ci 266662306a36Sopenharmony_civoid evergreen_mc_stop(struct radeon_device *rdev, struct evergreen_mc_save *save) 266762306a36Sopenharmony_ci{ 266862306a36Sopenharmony_ci u32 crtc_enabled, tmp, frame_count, blackout; 266962306a36Sopenharmony_ci int i, j; 267062306a36Sopenharmony_ci unsigned dig_fe; 267162306a36Sopenharmony_ci 267262306a36Sopenharmony_ci if (!ASIC_IS_NODCE(rdev)) { 267362306a36Sopenharmony_ci save->vga_render_control = RREG32(VGA_RENDER_CONTROL); 267462306a36Sopenharmony_ci save->vga_hdp_control = RREG32(VGA_HDP_CONTROL); 267562306a36Sopenharmony_ci 267662306a36Sopenharmony_ci /* disable VGA render */ 267762306a36Sopenharmony_ci WREG32(VGA_RENDER_CONTROL, 0); 267862306a36Sopenharmony_ci } 267962306a36Sopenharmony_ci /* blank the display controllers */ 268062306a36Sopenharmony_ci for (i = 0; i < rdev->num_crtc; i++) { 268162306a36Sopenharmony_ci crtc_enabled = RREG32(EVERGREEN_CRTC_CONTROL + crtc_offsets[i]) & EVERGREEN_CRTC_MASTER_EN; 268262306a36Sopenharmony_ci if (crtc_enabled) { 268362306a36Sopenharmony_ci save->crtc_enabled[i] = true; 268462306a36Sopenharmony_ci if (ASIC_IS_DCE6(rdev)) { 268562306a36Sopenharmony_ci tmp = RREG32(EVERGREEN_CRTC_BLANK_CONTROL + crtc_offsets[i]); 268662306a36Sopenharmony_ci if (!(tmp & EVERGREEN_CRTC_BLANK_DATA_EN)) { 268762306a36Sopenharmony_ci radeon_wait_for_vblank(rdev, i); 268862306a36Sopenharmony_ci WREG32(EVERGREEN_CRTC_UPDATE_LOCK + crtc_offsets[i], 1); 268962306a36Sopenharmony_ci tmp |= EVERGREEN_CRTC_BLANK_DATA_EN; 269062306a36Sopenharmony_ci WREG32(EVERGREEN_CRTC_BLANK_CONTROL + crtc_offsets[i], tmp); 269162306a36Sopenharmony_ci WREG32(EVERGREEN_CRTC_UPDATE_LOCK + crtc_offsets[i], 0); 269262306a36Sopenharmony_ci } 269362306a36Sopenharmony_ci } else { 269462306a36Sopenharmony_ci tmp = RREG32(EVERGREEN_CRTC_CONTROL + crtc_offsets[i]); 269562306a36Sopenharmony_ci if (!(tmp & EVERGREEN_CRTC_DISP_READ_REQUEST_DISABLE)) { 269662306a36Sopenharmony_ci radeon_wait_for_vblank(rdev, i); 269762306a36Sopenharmony_ci WREG32(EVERGREEN_CRTC_UPDATE_LOCK + crtc_offsets[i], 1); 269862306a36Sopenharmony_ci tmp |= EVERGREEN_CRTC_DISP_READ_REQUEST_DISABLE; 269962306a36Sopenharmony_ci WREG32(EVERGREEN_CRTC_CONTROL + crtc_offsets[i], tmp); 270062306a36Sopenharmony_ci WREG32(EVERGREEN_CRTC_UPDATE_LOCK + crtc_offsets[i], 0); 270162306a36Sopenharmony_ci } 270262306a36Sopenharmony_ci } 270362306a36Sopenharmony_ci /* wait for the next frame */ 270462306a36Sopenharmony_ci frame_count = radeon_get_vblank_counter(rdev, i); 270562306a36Sopenharmony_ci for (j = 0; j < rdev->usec_timeout; j++) { 270662306a36Sopenharmony_ci if (radeon_get_vblank_counter(rdev, i) != frame_count) 270762306a36Sopenharmony_ci break; 270862306a36Sopenharmony_ci udelay(1); 270962306a36Sopenharmony_ci } 271062306a36Sopenharmony_ci /*we should disable dig if it drives dp sst*/ 271162306a36Sopenharmony_ci /*but we are in radeon_device_init and the topology is unknown*/ 271262306a36Sopenharmony_ci /*and it is available after radeon_modeset_init*/ 271362306a36Sopenharmony_ci /*the following method radeon_atom_encoder_dpms_dig*/ 271462306a36Sopenharmony_ci /*does the job if we initialize it properly*/ 271562306a36Sopenharmony_ci /*for now we do it this manually*/ 271662306a36Sopenharmony_ci /**/ 271762306a36Sopenharmony_ci if (ASIC_IS_DCE5(rdev) && 271862306a36Sopenharmony_ci evergreen_is_dp_sst_stream_enabled(rdev, i ,&dig_fe)) 271962306a36Sopenharmony_ci evergreen_blank_dp_output(rdev, dig_fe); 272062306a36Sopenharmony_ci /*we could remove 6 lines below*/ 272162306a36Sopenharmony_ci /* XXX this is a hack to avoid strange behavior with EFI on certain systems */ 272262306a36Sopenharmony_ci WREG32(EVERGREEN_CRTC_UPDATE_LOCK + crtc_offsets[i], 1); 272362306a36Sopenharmony_ci tmp = RREG32(EVERGREEN_CRTC_CONTROL + crtc_offsets[i]); 272462306a36Sopenharmony_ci tmp &= ~EVERGREEN_CRTC_MASTER_EN; 272562306a36Sopenharmony_ci WREG32(EVERGREEN_CRTC_CONTROL + crtc_offsets[i], tmp); 272662306a36Sopenharmony_ci WREG32(EVERGREEN_CRTC_UPDATE_LOCK + crtc_offsets[i], 0); 272762306a36Sopenharmony_ci save->crtc_enabled[i] = false; 272862306a36Sopenharmony_ci /* ***** */ 272962306a36Sopenharmony_ci } else { 273062306a36Sopenharmony_ci save->crtc_enabled[i] = false; 273162306a36Sopenharmony_ci } 273262306a36Sopenharmony_ci } 273362306a36Sopenharmony_ci 273462306a36Sopenharmony_ci radeon_mc_wait_for_idle(rdev); 273562306a36Sopenharmony_ci 273662306a36Sopenharmony_ci blackout = RREG32(MC_SHARED_BLACKOUT_CNTL); 273762306a36Sopenharmony_ci if ((blackout & BLACKOUT_MODE_MASK) != 1) { 273862306a36Sopenharmony_ci /* Block CPU access */ 273962306a36Sopenharmony_ci WREG32(BIF_FB_EN, 0); 274062306a36Sopenharmony_ci /* blackout the MC */ 274162306a36Sopenharmony_ci blackout &= ~BLACKOUT_MODE_MASK; 274262306a36Sopenharmony_ci WREG32(MC_SHARED_BLACKOUT_CNTL, blackout | 1); 274362306a36Sopenharmony_ci } 274462306a36Sopenharmony_ci /* wait for the MC to settle */ 274562306a36Sopenharmony_ci udelay(100); 274662306a36Sopenharmony_ci 274762306a36Sopenharmony_ci /* lock double buffered regs */ 274862306a36Sopenharmony_ci for (i = 0; i < rdev->num_crtc; i++) { 274962306a36Sopenharmony_ci if (save->crtc_enabled[i]) { 275062306a36Sopenharmony_ci tmp = RREG32(EVERGREEN_GRPH_UPDATE + crtc_offsets[i]); 275162306a36Sopenharmony_ci if (!(tmp & EVERGREEN_GRPH_UPDATE_LOCK)) { 275262306a36Sopenharmony_ci tmp |= EVERGREEN_GRPH_UPDATE_LOCK; 275362306a36Sopenharmony_ci WREG32(EVERGREEN_GRPH_UPDATE + crtc_offsets[i], tmp); 275462306a36Sopenharmony_ci } 275562306a36Sopenharmony_ci tmp = RREG32(EVERGREEN_MASTER_UPDATE_LOCK + crtc_offsets[i]); 275662306a36Sopenharmony_ci if (!(tmp & 1)) { 275762306a36Sopenharmony_ci tmp |= 1; 275862306a36Sopenharmony_ci WREG32(EVERGREEN_MASTER_UPDATE_LOCK + crtc_offsets[i], tmp); 275962306a36Sopenharmony_ci } 276062306a36Sopenharmony_ci } 276162306a36Sopenharmony_ci } 276262306a36Sopenharmony_ci} 276362306a36Sopenharmony_ci 276462306a36Sopenharmony_civoid evergreen_mc_resume(struct radeon_device *rdev, struct evergreen_mc_save *save) 276562306a36Sopenharmony_ci{ 276662306a36Sopenharmony_ci u32 tmp, frame_count; 276762306a36Sopenharmony_ci int i, j; 276862306a36Sopenharmony_ci 276962306a36Sopenharmony_ci /* update crtc base addresses */ 277062306a36Sopenharmony_ci for (i = 0; i < rdev->num_crtc; i++) { 277162306a36Sopenharmony_ci WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH + crtc_offsets[i], 277262306a36Sopenharmony_ci upper_32_bits(rdev->mc.vram_start)); 277362306a36Sopenharmony_ci WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS_HIGH + crtc_offsets[i], 277462306a36Sopenharmony_ci upper_32_bits(rdev->mc.vram_start)); 277562306a36Sopenharmony_ci WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS + crtc_offsets[i], 277662306a36Sopenharmony_ci (u32)rdev->mc.vram_start); 277762306a36Sopenharmony_ci WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS + crtc_offsets[i], 277862306a36Sopenharmony_ci (u32)rdev->mc.vram_start); 277962306a36Sopenharmony_ci } 278062306a36Sopenharmony_ci 278162306a36Sopenharmony_ci if (!ASIC_IS_NODCE(rdev)) { 278262306a36Sopenharmony_ci WREG32(EVERGREEN_VGA_MEMORY_BASE_ADDRESS_HIGH, upper_32_bits(rdev->mc.vram_start)); 278362306a36Sopenharmony_ci WREG32(EVERGREEN_VGA_MEMORY_BASE_ADDRESS, (u32)rdev->mc.vram_start); 278462306a36Sopenharmony_ci } 278562306a36Sopenharmony_ci 278662306a36Sopenharmony_ci /* unlock regs and wait for update */ 278762306a36Sopenharmony_ci for (i = 0; i < rdev->num_crtc; i++) { 278862306a36Sopenharmony_ci if (save->crtc_enabled[i]) { 278962306a36Sopenharmony_ci tmp = RREG32(EVERGREEN_MASTER_UPDATE_MODE + crtc_offsets[i]); 279062306a36Sopenharmony_ci if ((tmp & 0x7) != 0) { 279162306a36Sopenharmony_ci tmp &= ~0x7; 279262306a36Sopenharmony_ci WREG32(EVERGREEN_MASTER_UPDATE_MODE + crtc_offsets[i], tmp); 279362306a36Sopenharmony_ci } 279462306a36Sopenharmony_ci tmp = RREG32(EVERGREEN_GRPH_UPDATE + crtc_offsets[i]); 279562306a36Sopenharmony_ci if (tmp & EVERGREEN_GRPH_UPDATE_LOCK) { 279662306a36Sopenharmony_ci tmp &= ~EVERGREEN_GRPH_UPDATE_LOCK; 279762306a36Sopenharmony_ci WREG32(EVERGREEN_GRPH_UPDATE + crtc_offsets[i], tmp); 279862306a36Sopenharmony_ci } 279962306a36Sopenharmony_ci tmp = RREG32(EVERGREEN_MASTER_UPDATE_LOCK + crtc_offsets[i]); 280062306a36Sopenharmony_ci if (tmp & 1) { 280162306a36Sopenharmony_ci tmp &= ~1; 280262306a36Sopenharmony_ci WREG32(EVERGREEN_MASTER_UPDATE_LOCK + crtc_offsets[i], tmp); 280362306a36Sopenharmony_ci } 280462306a36Sopenharmony_ci for (j = 0; j < rdev->usec_timeout; j++) { 280562306a36Sopenharmony_ci tmp = RREG32(EVERGREEN_GRPH_UPDATE + crtc_offsets[i]); 280662306a36Sopenharmony_ci if ((tmp & EVERGREEN_GRPH_SURFACE_UPDATE_PENDING) == 0) 280762306a36Sopenharmony_ci break; 280862306a36Sopenharmony_ci udelay(1); 280962306a36Sopenharmony_ci } 281062306a36Sopenharmony_ci } 281162306a36Sopenharmony_ci } 281262306a36Sopenharmony_ci 281362306a36Sopenharmony_ci /* unblackout the MC */ 281462306a36Sopenharmony_ci tmp = RREG32(MC_SHARED_BLACKOUT_CNTL); 281562306a36Sopenharmony_ci tmp &= ~BLACKOUT_MODE_MASK; 281662306a36Sopenharmony_ci WREG32(MC_SHARED_BLACKOUT_CNTL, tmp); 281762306a36Sopenharmony_ci /* allow CPU access */ 281862306a36Sopenharmony_ci WREG32(BIF_FB_EN, FB_READ_EN | FB_WRITE_EN); 281962306a36Sopenharmony_ci 282062306a36Sopenharmony_ci for (i = 0; i < rdev->num_crtc; i++) { 282162306a36Sopenharmony_ci if (save->crtc_enabled[i]) { 282262306a36Sopenharmony_ci if (ASIC_IS_DCE6(rdev)) { 282362306a36Sopenharmony_ci tmp = RREG32(EVERGREEN_CRTC_BLANK_CONTROL + crtc_offsets[i]); 282462306a36Sopenharmony_ci tmp &= ~EVERGREEN_CRTC_BLANK_DATA_EN; 282562306a36Sopenharmony_ci WREG32(EVERGREEN_CRTC_UPDATE_LOCK + crtc_offsets[i], 1); 282662306a36Sopenharmony_ci WREG32(EVERGREEN_CRTC_BLANK_CONTROL + crtc_offsets[i], tmp); 282762306a36Sopenharmony_ci WREG32(EVERGREEN_CRTC_UPDATE_LOCK + crtc_offsets[i], 0); 282862306a36Sopenharmony_ci } else { 282962306a36Sopenharmony_ci tmp = RREG32(EVERGREEN_CRTC_CONTROL + crtc_offsets[i]); 283062306a36Sopenharmony_ci tmp &= ~EVERGREEN_CRTC_DISP_READ_REQUEST_DISABLE; 283162306a36Sopenharmony_ci WREG32(EVERGREEN_CRTC_UPDATE_LOCK + crtc_offsets[i], 1); 283262306a36Sopenharmony_ci WREG32(EVERGREEN_CRTC_CONTROL + crtc_offsets[i], tmp); 283362306a36Sopenharmony_ci WREG32(EVERGREEN_CRTC_UPDATE_LOCK + crtc_offsets[i], 0); 283462306a36Sopenharmony_ci } 283562306a36Sopenharmony_ci /* wait for the next frame */ 283662306a36Sopenharmony_ci frame_count = radeon_get_vblank_counter(rdev, i); 283762306a36Sopenharmony_ci for (j = 0; j < rdev->usec_timeout; j++) { 283862306a36Sopenharmony_ci if (radeon_get_vblank_counter(rdev, i) != frame_count) 283962306a36Sopenharmony_ci break; 284062306a36Sopenharmony_ci udelay(1); 284162306a36Sopenharmony_ci } 284262306a36Sopenharmony_ci } 284362306a36Sopenharmony_ci } 284462306a36Sopenharmony_ci if (!ASIC_IS_NODCE(rdev)) { 284562306a36Sopenharmony_ci /* Unlock vga access */ 284662306a36Sopenharmony_ci WREG32(VGA_HDP_CONTROL, save->vga_hdp_control); 284762306a36Sopenharmony_ci mdelay(1); 284862306a36Sopenharmony_ci WREG32(VGA_RENDER_CONTROL, save->vga_render_control); 284962306a36Sopenharmony_ci } 285062306a36Sopenharmony_ci} 285162306a36Sopenharmony_ci 285262306a36Sopenharmony_civoid evergreen_mc_program(struct radeon_device *rdev) 285362306a36Sopenharmony_ci{ 285462306a36Sopenharmony_ci struct evergreen_mc_save save; 285562306a36Sopenharmony_ci u32 tmp; 285662306a36Sopenharmony_ci int i, j; 285762306a36Sopenharmony_ci 285862306a36Sopenharmony_ci /* Initialize HDP */ 285962306a36Sopenharmony_ci for (i = 0, j = 0; i < 32; i++, j += 0x18) { 286062306a36Sopenharmony_ci WREG32((0x2c14 + j), 0x00000000); 286162306a36Sopenharmony_ci WREG32((0x2c18 + j), 0x00000000); 286262306a36Sopenharmony_ci WREG32((0x2c1c + j), 0x00000000); 286362306a36Sopenharmony_ci WREG32((0x2c20 + j), 0x00000000); 286462306a36Sopenharmony_ci WREG32((0x2c24 + j), 0x00000000); 286562306a36Sopenharmony_ci } 286662306a36Sopenharmony_ci WREG32(HDP_REG_COHERENCY_FLUSH_CNTL, 0); 286762306a36Sopenharmony_ci 286862306a36Sopenharmony_ci evergreen_mc_stop(rdev, &save); 286962306a36Sopenharmony_ci if (evergreen_mc_wait_for_idle(rdev)) { 287062306a36Sopenharmony_ci dev_warn(rdev->dev, "Wait for MC idle timedout !\n"); 287162306a36Sopenharmony_ci } 287262306a36Sopenharmony_ci /* Lockout access through VGA aperture*/ 287362306a36Sopenharmony_ci WREG32(VGA_HDP_CONTROL, VGA_MEMORY_DISABLE); 287462306a36Sopenharmony_ci /* Update configuration */ 287562306a36Sopenharmony_ci if (rdev->flags & RADEON_IS_AGP) { 287662306a36Sopenharmony_ci if (rdev->mc.vram_start < rdev->mc.gtt_start) { 287762306a36Sopenharmony_ci /* VRAM before AGP */ 287862306a36Sopenharmony_ci WREG32(MC_VM_SYSTEM_APERTURE_LOW_ADDR, 287962306a36Sopenharmony_ci rdev->mc.vram_start >> 12); 288062306a36Sopenharmony_ci WREG32(MC_VM_SYSTEM_APERTURE_HIGH_ADDR, 288162306a36Sopenharmony_ci rdev->mc.gtt_end >> 12); 288262306a36Sopenharmony_ci } else { 288362306a36Sopenharmony_ci /* VRAM after AGP */ 288462306a36Sopenharmony_ci WREG32(MC_VM_SYSTEM_APERTURE_LOW_ADDR, 288562306a36Sopenharmony_ci rdev->mc.gtt_start >> 12); 288662306a36Sopenharmony_ci WREG32(MC_VM_SYSTEM_APERTURE_HIGH_ADDR, 288762306a36Sopenharmony_ci rdev->mc.vram_end >> 12); 288862306a36Sopenharmony_ci } 288962306a36Sopenharmony_ci } else { 289062306a36Sopenharmony_ci WREG32(MC_VM_SYSTEM_APERTURE_LOW_ADDR, 289162306a36Sopenharmony_ci rdev->mc.vram_start >> 12); 289262306a36Sopenharmony_ci WREG32(MC_VM_SYSTEM_APERTURE_HIGH_ADDR, 289362306a36Sopenharmony_ci rdev->mc.vram_end >> 12); 289462306a36Sopenharmony_ci } 289562306a36Sopenharmony_ci WREG32(MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR, rdev->vram_scratch.gpu_addr >> 12); 289662306a36Sopenharmony_ci /* llano/ontario only */ 289762306a36Sopenharmony_ci if ((rdev->family == CHIP_PALM) || 289862306a36Sopenharmony_ci (rdev->family == CHIP_SUMO) || 289962306a36Sopenharmony_ci (rdev->family == CHIP_SUMO2)) { 290062306a36Sopenharmony_ci tmp = RREG32(MC_FUS_VM_FB_OFFSET) & 0x000FFFFF; 290162306a36Sopenharmony_ci tmp |= ((rdev->mc.vram_end >> 20) & 0xF) << 24; 290262306a36Sopenharmony_ci tmp |= ((rdev->mc.vram_start >> 20) & 0xF) << 20; 290362306a36Sopenharmony_ci WREG32(MC_FUS_VM_FB_OFFSET, tmp); 290462306a36Sopenharmony_ci } 290562306a36Sopenharmony_ci tmp = ((rdev->mc.vram_end >> 24) & 0xFFFF) << 16; 290662306a36Sopenharmony_ci tmp |= ((rdev->mc.vram_start >> 24) & 0xFFFF); 290762306a36Sopenharmony_ci WREG32(MC_VM_FB_LOCATION, tmp); 290862306a36Sopenharmony_ci WREG32(HDP_NONSURFACE_BASE, (rdev->mc.vram_start >> 8)); 290962306a36Sopenharmony_ci WREG32(HDP_NONSURFACE_INFO, (2 << 7) | (1 << 30)); 291062306a36Sopenharmony_ci WREG32(HDP_NONSURFACE_SIZE, 0x3FFFFFFF); 291162306a36Sopenharmony_ci if (rdev->flags & RADEON_IS_AGP) { 291262306a36Sopenharmony_ci WREG32(MC_VM_AGP_TOP, rdev->mc.gtt_end >> 16); 291362306a36Sopenharmony_ci WREG32(MC_VM_AGP_BOT, rdev->mc.gtt_start >> 16); 291462306a36Sopenharmony_ci WREG32(MC_VM_AGP_BASE, rdev->mc.agp_base >> 22); 291562306a36Sopenharmony_ci } else { 291662306a36Sopenharmony_ci WREG32(MC_VM_AGP_BASE, 0); 291762306a36Sopenharmony_ci WREG32(MC_VM_AGP_TOP, 0x0FFFFFFF); 291862306a36Sopenharmony_ci WREG32(MC_VM_AGP_BOT, 0x0FFFFFFF); 291962306a36Sopenharmony_ci } 292062306a36Sopenharmony_ci if (evergreen_mc_wait_for_idle(rdev)) { 292162306a36Sopenharmony_ci dev_warn(rdev->dev, "Wait for MC idle timedout !\n"); 292262306a36Sopenharmony_ci } 292362306a36Sopenharmony_ci evergreen_mc_resume(rdev, &save); 292462306a36Sopenharmony_ci /* we need to own VRAM, so turn off the VGA renderer here 292562306a36Sopenharmony_ci * to stop it overwriting our objects */ 292662306a36Sopenharmony_ci rv515_vga_render_disable(rdev); 292762306a36Sopenharmony_ci} 292862306a36Sopenharmony_ci 292962306a36Sopenharmony_ci/* 293062306a36Sopenharmony_ci * CP. 293162306a36Sopenharmony_ci */ 293262306a36Sopenharmony_civoid evergreen_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib) 293362306a36Sopenharmony_ci{ 293462306a36Sopenharmony_ci struct radeon_ring *ring = &rdev->ring[ib->ring]; 293562306a36Sopenharmony_ci u32 next_rptr; 293662306a36Sopenharmony_ci 293762306a36Sopenharmony_ci /* set to DX10/11 mode */ 293862306a36Sopenharmony_ci radeon_ring_write(ring, PACKET3(PACKET3_MODE_CONTROL, 0)); 293962306a36Sopenharmony_ci radeon_ring_write(ring, 1); 294062306a36Sopenharmony_ci 294162306a36Sopenharmony_ci if (ring->rptr_save_reg) { 294262306a36Sopenharmony_ci next_rptr = ring->wptr + 3 + 4; 294362306a36Sopenharmony_ci radeon_ring_write(ring, PACKET3(PACKET3_SET_CONFIG_REG, 1)); 294462306a36Sopenharmony_ci radeon_ring_write(ring, ((ring->rptr_save_reg - 294562306a36Sopenharmony_ci PACKET3_SET_CONFIG_REG_START) >> 2)); 294662306a36Sopenharmony_ci radeon_ring_write(ring, next_rptr); 294762306a36Sopenharmony_ci } else if (rdev->wb.enabled) { 294862306a36Sopenharmony_ci next_rptr = ring->wptr + 5 + 4; 294962306a36Sopenharmony_ci radeon_ring_write(ring, PACKET3(PACKET3_MEM_WRITE, 3)); 295062306a36Sopenharmony_ci radeon_ring_write(ring, ring->next_rptr_gpu_addr & 0xfffffffc); 295162306a36Sopenharmony_ci radeon_ring_write(ring, (upper_32_bits(ring->next_rptr_gpu_addr) & 0xff) | (1 << 18)); 295262306a36Sopenharmony_ci radeon_ring_write(ring, next_rptr); 295362306a36Sopenharmony_ci radeon_ring_write(ring, 0); 295462306a36Sopenharmony_ci } 295562306a36Sopenharmony_ci 295662306a36Sopenharmony_ci radeon_ring_write(ring, PACKET3(PACKET3_INDIRECT_BUFFER, 2)); 295762306a36Sopenharmony_ci radeon_ring_write(ring, 295862306a36Sopenharmony_ci#ifdef __BIG_ENDIAN 295962306a36Sopenharmony_ci (2 << 0) | 296062306a36Sopenharmony_ci#endif 296162306a36Sopenharmony_ci (ib->gpu_addr & 0xFFFFFFFC)); 296262306a36Sopenharmony_ci radeon_ring_write(ring, upper_32_bits(ib->gpu_addr) & 0xFF); 296362306a36Sopenharmony_ci radeon_ring_write(ring, ib->length_dw); 296462306a36Sopenharmony_ci} 296562306a36Sopenharmony_ci 296662306a36Sopenharmony_ci 296762306a36Sopenharmony_cistatic int evergreen_cp_load_microcode(struct radeon_device *rdev) 296862306a36Sopenharmony_ci{ 296962306a36Sopenharmony_ci const __be32 *fw_data; 297062306a36Sopenharmony_ci int i; 297162306a36Sopenharmony_ci 297262306a36Sopenharmony_ci if (!rdev->me_fw || !rdev->pfp_fw) 297362306a36Sopenharmony_ci return -EINVAL; 297462306a36Sopenharmony_ci 297562306a36Sopenharmony_ci r700_cp_stop(rdev); 297662306a36Sopenharmony_ci WREG32(CP_RB_CNTL, 297762306a36Sopenharmony_ci#ifdef __BIG_ENDIAN 297862306a36Sopenharmony_ci BUF_SWAP_32BIT | 297962306a36Sopenharmony_ci#endif 298062306a36Sopenharmony_ci RB_NO_UPDATE | RB_BLKSZ(15) | RB_BUFSZ(3)); 298162306a36Sopenharmony_ci 298262306a36Sopenharmony_ci fw_data = (const __be32 *)rdev->pfp_fw->data; 298362306a36Sopenharmony_ci WREG32(CP_PFP_UCODE_ADDR, 0); 298462306a36Sopenharmony_ci for (i = 0; i < EVERGREEN_PFP_UCODE_SIZE; i++) 298562306a36Sopenharmony_ci WREG32(CP_PFP_UCODE_DATA, be32_to_cpup(fw_data++)); 298662306a36Sopenharmony_ci WREG32(CP_PFP_UCODE_ADDR, 0); 298762306a36Sopenharmony_ci 298862306a36Sopenharmony_ci fw_data = (const __be32 *)rdev->me_fw->data; 298962306a36Sopenharmony_ci WREG32(CP_ME_RAM_WADDR, 0); 299062306a36Sopenharmony_ci for (i = 0; i < EVERGREEN_PM4_UCODE_SIZE; i++) 299162306a36Sopenharmony_ci WREG32(CP_ME_RAM_DATA, be32_to_cpup(fw_data++)); 299262306a36Sopenharmony_ci 299362306a36Sopenharmony_ci WREG32(CP_PFP_UCODE_ADDR, 0); 299462306a36Sopenharmony_ci WREG32(CP_ME_RAM_WADDR, 0); 299562306a36Sopenharmony_ci WREG32(CP_ME_RAM_RADDR, 0); 299662306a36Sopenharmony_ci return 0; 299762306a36Sopenharmony_ci} 299862306a36Sopenharmony_ci 299962306a36Sopenharmony_cistatic int evergreen_cp_start(struct radeon_device *rdev) 300062306a36Sopenharmony_ci{ 300162306a36Sopenharmony_ci struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]; 300262306a36Sopenharmony_ci int r, i; 300362306a36Sopenharmony_ci uint32_t cp_me; 300462306a36Sopenharmony_ci 300562306a36Sopenharmony_ci r = radeon_ring_lock(rdev, ring, 7); 300662306a36Sopenharmony_ci if (r) { 300762306a36Sopenharmony_ci DRM_ERROR("radeon: cp failed to lock ring (%d).\n", r); 300862306a36Sopenharmony_ci return r; 300962306a36Sopenharmony_ci } 301062306a36Sopenharmony_ci radeon_ring_write(ring, PACKET3(PACKET3_ME_INITIALIZE, 5)); 301162306a36Sopenharmony_ci radeon_ring_write(ring, 0x1); 301262306a36Sopenharmony_ci radeon_ring_write(ring, 0x0); 301362306a36Sopenharmony_ci radeon_ring_write(ring, rdev->config.evergreen.max_hw_contexts - 1); 301462306a36Sopenharmony_ci radeon_ring_write(ring, PACKET3_ME_INITIALIZE_DEVICE_ID(1)); 301562306a36Sopenharmony_ci radeon_ring_write(ring, 0); 301662306a36Sopenharmony_ci radeon_ring_write(ring, 0); 301762306a36Sopenharmony_ci radeon_ring_unlock_commit(rdev, ring, false); 301862306a36Sopenharmony_ci 301962306a36Sopenharmony_ci cp_me = 0xff; 302062306a36Sopenharmony_ci WREG32(CP_ME_CNTL, cp_me); 302162306a36Sopenharmony_ci 302262306a36Sopenharmony_ci r = radeon_ring_lock(rdev, ring, evergreen_default_size + 19); 302362306a36Sopenharmony_ci if (r) { 302462306a36Sopenharmony_ci DRM_ERROR("radeon: cp failed to lock ring (%d).\n", r); 302562306a36Sopenharmony_ci return r; 302662306a36Sopenharmony_ci } 302762306a36Sopenharmony_ci 302862306a36Sopenharmony_ci /* setup clear context state */ 302962306a36Sopenharmony_ci radeon_ring_write(ring, PACKET3(PACKET3_PREAMBLE_CNTL, 0)); 303062306a36Sopenharmony_ci radeon_ring_write(ring, PACKET3_PREAMBLE_BEGIN_CLEAR_STATE); 303162306a36Sopenharmony_ci 303262306a36Sopenharmony_ci for (i = 0; i < evergreen_default_size; i++) 303362306a36Sopenharmony_ci radeon_ring_write(ring, evergreen_default_state[i]); 303462306a36Sopenharmony_ci 303562306a36Sopenharmony_ci radeon_ring_write(ring, PACKET3(PACKET3_PREAMBLE_CNTL, 0)); 303662306a36Sopenharmony_ci radeon_ring_write(ring, PACKET3_PREAMBLE_END_CLEAR_STATE); 303762306a36Sopenharmony_ci 303862306a36Sopenharmony_ci /* set clear context state */ 303962306a36Sopenharmony_ci radeon_ring_write(ring, PACKET3(PACKET3_CLEAR_STATE, 0)); 304062306a36Sopenharmony_ci radeon_ring_write(ring, 0); 304162306a36Sopenharmony_ci 304262306a36Sopenharmony_ci /* SQ_VTX_BASE_VTX_LOC */ 304362306a36Sopenharmony_ci radeon_ring_write(ring, 0xc0026f00); 304462306a36Sopenharmony_ci radeon_ring_write(ring, 0x00000000); 304562306a36Sopenharmony_ci radeon_ring_write(ring, 0x00000000); 304662306a36Sopenharmony_ci radeon_ring_write(ring, 0x00000000); 304762306a36Sopenharmony_ci 304862306a36Sopenharmony_ci /* Clear consts */ 304962306a36Sopenharmony_ci radeon_ring_write(ring, 0xc0036f00); 305062306a36Sopenharmony_ci radeon_ring_write(ring, 0x00000bc4); 305162306a36Sopenharmony_ci radeon_ring_write(ring, 0xffffffff); 305262306a36Sopenharmony_ci radeon_ring_write(ring, 0xffffffff); 305362306a36Sopenharmony_ci radeon_ring_write(ring, 0xffffffff); 305462306a36Sopenharmony_ci 305562306a36Sopenharmony_ci radeon_ring_write(ring, 0xc0026900); 305662306a36Sopenharmony_ci radeon_ring_write(ring, 0x00000316); 305762306a36Sopenharmony_ci radeon_ring_write(ring, 0x0000000e); /* VGT_VERTEX_REUSE_BLOCK_CNTL */ 305862306a36Sopenharmony_ci radeon_ring_write(ring, 0x00000010); /* */ 305962306a36Sopenharmony_ci 306062306a36Sopenharmony_ci radeon_ring_unlock_commit(rdev, ring, false); 306162306a36Sopenharmony_ci 306262306a36Sopenharmony_ci return 0; 306362306a36Sopenharmony_ci} 306462306a36Sopenharmony_ci 306562306a36Sopenharmony_cistatic int evergreen_cp_resume(struct radeon_device *rdev) 306662306a36Sopenharmony_ci{ 306762306a36Sopenharmony_ci struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]; 306862306a36Sopenharmony_ci u32 tmp; 306962306a36Sopenharmony_ci u32 rb_bufsz; 307062306a36Sopenharmony_ci int r; 307162306a36Sopenharmony_ci 307262306a36Sopenharmony_ci /* Reset cp; if cp is reset, then PA, SH, VGT also need to be reset */ 307362306a36Sopenharmony_ci WREG32(GRBM_SOFT_RESET, (SOFT_RESET_CP | 307462306a36Sopenharmony_ci SOFT_RESET_PA | 307562306a36Sopenharmony_ci SOFT_RESET_SH | 307662306a36Sopenharmony_ci SOFT_RESET_VGT | 307762306a36Sopenharmony_ci SOFT_RESET_SPI | 307862306a36Sopenharmony_ci SOFT_RESET_SX)); 307962306a36Sopenharmony_ci RREG32(GRBM_SOFT_RESET); 308062306a36Sopenharmony_ci mdelay(15); 308162306a36Sopenharmony_ci WREG32(GRBM_SOFT_RESET, 0); 308262306a36Sopenharmony_ci RREG32(GRBM_SOFT_RESET); 308362306a36Sopenharmony_ci 308462306a36Sopenharmony_ci /* Set ring buffer size */ 308562306a36Sopenharmony_ci rb_bufsz = order_base_2(ring->ring_size / 8); 308662306a36Sopenharmony_ci tmp = (order_base_2(RADEON_GPU_PAGE_SIZE/8) << 8) | rb_bufsz; 308762306a36Sopenharmony_ci#ifdef __BIG_ENDIAN 308862306a36Sopenharmony_ci tmp |= BUF_SWAP_32BIT; 308962306a36Sopenharmony_ci#endif 309062306a36Sopenharmony_ci WREG32(CP_RB_CNTL, tmp); 309162306a36Sopenharmony_ci WREG32(CP_SEM_WAIT_TIMER, 0x0); 309262306a36Sopenharmony_ci WREG32(CP_SEM_INCOMPLETE_TIMER_CNTL, 0x0); 309362306a36Sopenharmony_ci 309462306a36Sopenharmony_ci /* Set the write pointer delay */ 309562306a36Sopenharmony_ci WREG32(CP_RB_WPTR_DELAY, 0); 309662306a36Sopenharmony_ci 309762306a36Sopenharmony_ci /* Initialize the ring buffer's read and write pointers */ 309862306a36Sopenharmony_ci WREG32(CP_RB_CNTL, tmp | RB_RPTR_WR_ENA); 309962306a36Sopenharmony_ci WREG32(CP_RB_RPTR_WR, 0); 310062306a36Sopenharmony_ci ring->wptr = 0; 310162306a36Sopenharmony_ci WREG32(CP_RB_WPTR, ring->wptr); 310262306a36Sopenharmony_ci 310362306a36Sopenharmony_ci /* set the wb address whether it's enabled or not */ 310462306a36Sopenharmony_ci WREG32(CP_RB_RPTR_ADDR, 310562306a36Sopenharmony_ci ((rdev->wb.gpu_addr + RADEON_WB_CP_RPTR_OFFSET) & 0xFFFFFFFC)); 310662306a36Sopenharmony_ci WREG32(CP_RB_RPTR_ADDR_HI, upper_32_bits(rdev->wb.gpu_addr + RADEON_WB_CP_RPTR_OFFSET) & 0xFF); 310762306a36Sopenharmony_ci WREG32(SCRATCH_ADDR, ((rdev->wb.gpu_addr + RADEON_WB_SCRATCH_OFFSET) >> 8) & 0xFFFFFFFF); 310862306a36Sopenharmony_ci 310962306a36Sopenharmony_ci if (rdev->wb.enabled) 311062306a36Sopenharmony_ci WREG32(SCRATCH_UMSK, 0xff); 311162306a36Sopenharmony_ci else { 311262306a36Sopenharmony_ci tmp |= RB_NO_UPDATE; 311362306a36Sopenharmony_ci WREG32(SCRATCH_UMSK, 0); 311462306a36Sopenharmony_ci } 311562306a36Sopenharmony_ci 311662306a36Sopenharmony_ci mdelay(1); 311762306a36Sopenharmony_ci WREG32(CP_RB_CNTL, tmp); 311862306a36Sopenharmony_ci 311962306a36Sopenharmony_ci WREG32(CP_RB_BASE, ring->gpu_addr >> 8); 312062306a36Sopenharmony_ci WREG32(CP_DEBUG, (1 << 27) | (1 << 28)); 312162306a36Sopenharmony_ci 312262306a36Sopenharmony_ci evergreen_cp_start(rdev); 312362306a36Sopenharmony_ci ring->ready = true; 312462306a36Sopenharmony_ci r = radeon_ring_test(rdev, RADEON_RING_TYPE_GFX_INDEX, ring); 312562306a36Sopenharmony_ci if (r) { 312662306a36Sopenharmony_ci ring->ready = false; 312762306a36Sopenharmony_ci return r; 312862306a36Sopenharmony_ci } 312962306a36Sopenharmony_ci return 0; 313062306a36Sopenharmony_ci} 313162306a36Sopenharmony_ci 313262306a36Sopenharmony_ci/* 313362306a36Sopenharmony_ci * Core functions 313462306a36Sopenharmony_ci */ 313562306a36Sopenharmony_cistatic void evergreen_gpu_init(struct radeon_device *rdev) 313662306a36Sopenharmony_ci{ 313762306a36Sopenharmony_ci u32 gb_addr_config; 313862306a36Sopenharmony_ci u32 mc_arb_ramcfg; 313962306a36Sopenharmony_ci u32 sx_debug_1; 314062306a36Sopenharmony_ci u32 smx_dc_ctl0; 314162306a36Sopenharmony_ci u32 sq_config; 314262306a36Sopenharmony_ci u32 sq_lds_resource_mgmt; 314362306a36Sopenharmony_ci u32 sq_gpr_resource_mgmt_1; 314462306a36Sopenharmony_ci u32 sq_gpr_resource_mgmt_2; 314562306a36Sopenharmony_ci u32 sq_gpr_resource_mgmt_3; 314662306a36Sopenharmony_ci u32 sq_thread_resource_mgmt; 314762306a36Sopenharmony_ci u32 sq_thread_resource_mgmt_2; 314862306a36Sopenharmony_ci u32 sq_stack_resource_mgmt_1; 314962306a36Sopenharmony_ci u32 sq_stack_resource_mgmt_2; 315062306a36Sopenharmony_ci u32 sq_stack_resource_mgmt_3; 315162306a36Sopenharmony_ci u32 vgt_cache_invalidation; 315262306a36Sopenharmony_ci u32 hdp_host_path_cntl, tmp; 315362306a36Sopenharmony_ci u32 disabled_rb_mask; 315462306a36Sopenharmony_ci int i, j, ps_thread_count; 315562306a36Sopenharmony_ci 315662306a36Sopenharmony_ci switch (rdev->family) { 315762306a36Sopenharmony_ci case CHIP_CYPRESS: 315862306a36Sopenharmony_ci case CHIP_HEMLOCK: 315962306a36Sopenharmony_ci rdev->config.evergreen.num_ses = 2; 316062306a36Sopenharmony_ci rdev->config.evergreen.max_pipes = 4; 316162306a36Sopenharmony_ci rdev->config.evergreen.max_tile_pipes = 8; 316262306a36Sopenharmony_ci rdev->config.evergreen.max_simds = 10; 316362306a36Sopenharmony_ci rdev->config.evergreen.max_backends = 4 * rdev->config.evergreen.num_ses; 316462306a36Sopenharmony_ci rdev->config.evergreen.max_gprs = 256; 316562306a36Sopenharmony_ci rdev->config.evergreen.max_threads = 248; 316662306a36Sopenharmony_ci rdev->config.evergreen.max_gs_threads = 32; 316762306a36Sopenharmony_ci rdev->config.evergreen.max_stack_entries = 512; 316862306a36Sopenharmony_ci rdev->config.evergreen.sx_num_of_sets = 4; 316962306a36Sopenharmony_ci rdev->config.evergreen.sx_max_export_size = 256; 317062306a36Sopenharmony_ci rdev->config.evergreen.sx_max_export_pos_size = 64; 317162306a36Sopenharmony_ci rdev->config.evergreen.sx_max_export_smx_size = 192; 317262306a36Sopenharmony_ci rdev->config.evergreen.max_hw_contexts = 8; 317362306a36Sopenharmony_ci rdev->config.evergreen.sq_num_cf_insts = 2; 317462306a36Sopenharmony_ci 317562306a36Sopenharmony_ci rdev->config.evergreen.sc_prim_fifo_size = 0x100; 317662306a36Sopenharmony_ci rdev->config.evergreen.sc_hiz_tile_fifo_size = 0x30; 317762306a36Sopenharmony_ci rdev->config.evergreen.sc_earlyz_tile_fifo_size = 0x130; 317862306a36Sopenharmony_ci gb_addr_config = CYPRESS_GB_ADDR_CONFIG_GOLDEN; 317962306a36Sopenharmony_ci break; 318062306a36Sopenharmony_ci case CHIP_JUNIPER: 318162306a36Sopenharmony_ci rdev->config.evergreen.num_ses = 1; 318262306a36Sopenharmony_ci rdev->config.evergreen.max_pipes = 4; 318362306a36Sopenharmony_ci rdev->config.evergreen.max_tile_pipes = 4; 318462306a36Sopenharmony_ci rdev->config.evergreen.max_simds = 10; 318562306a36Sopenharmony_ci rdev->config.evergreen.max_backends = 4 * rdev->config.evergreen.num_ses; 318662306a36Sopenharmony_ci rdev->config.evergreen.max_gprs = 256; 318762306a36Sopenharmony_ci rdev->config.evergreen.max_threads = 248; 318862306a36Sopenharmony_ci rdev->config.evergreen.max_gs_threads = 32; 318962306a36Sopenharmony_ci rdev->config.evergreen.max_stack_entries = 512; 319062306a36Sopenharmony_ci rdev->config.evergreen.sx_num_of_sets = 4; 319162306a36Sopenharmony_ci rdev->config.evergreen.sx_max_export_size = 256; 319262306a36Sopenharmony_ci rdev->config.evergreen.sx_max_export_pos_size = 64; 319362306a36Sopenharmony_ci rdev->config.evergreen.sx_max_export_smx_size = 192; 319462306a36Sopenharmony_ci rdev->config.evergreen.max_hw_contexts = 8; 319562306a36Sopenharmony_ci rdev->config.evergreen.sq_num_cf_insts = 2; 319662306a36Sopenharmony_ci 319762306a36Sopenharmony_ci rdev->config.evergreen.sc_prim_fifo_size = 0x100; 319862306a36Sopenharmony_ci rdev->config.evergreen.sc_hiz_tile_fifo_size = 0x30; 319962306a36Sopenharmony_ci rdev->config.evergreen.sc_earlyz_tile_fifo_size = 0x130; 320062306a36Sopenharmony_ci gb_addr_config = JUNIPER_GB_ADDR_CONFIG_GOLDEN; 320162306a36Sopenharmony_ci break; 320262306a36Sopenharmony_ci case CHIP_REDWOOD: 320362306a36Sopenharmony_ci rdev->config.evergreen.num_ses = 1; 320462306a36Sopenharmony_ci rdev->config.evergreen.max_pipes = 4; 320562306a36Sopenharmony_ci rdev->config.evergreen.max_tile_pipes = 4; 320662306a36Sopenharmony_ci rdev->config.evergreen.max_simds = 5; 320762306a36Sopenharmony_ci rdev->config.evergreen.max_backends = 2 * rdev->config.evergreen.num_ses; 320862306a36Sopenharmony_ci rdev->config.evergreen.max_gprs = 256; 320962306a36Sopenharmony_ci rdev->config.evergreen.max_threads = 248; 321062306a36Sopenharmony_ci rdev->config.evergreen.max_gs_threads = 32; 321162306a36Sopenharmony_ci rdev->config.evergreen.max_stack_entries = 256; 321262306a36Sopenharmony_ci rdev->config.evergreen.sx_num_of_sets = 4; 321362306a36Sopenharmony_ci rdev->config.evergreen.sx_max_export_size = 256; 321462306a36Sopenharmony_ci rdev->config.evergreen.sx_max_export_pos_size = 64; 321562306a36Sopenharmony_ci rdev->config.evergreen.sx_max_export_smx_size = 192; 321662306a36Sopenharmony_ci rdev->config.evergreen.max_hw_contexts = 8; 321762306a36Sopenharmony_ci rdev->config.evergreen.sq_num_cf_insts = 2; 321862306a36Sopenharmony_ci 321962306a36Sopenharmony_ci rdev->config.evergreen.sc_prim_fifo_size = 0x100; 322062306a36Sopenharmony_ci rdev->config.evergreen.sc_hiz_tile_fifo_size = 0x30; 322162306a36Sopenharmony_ci rdev->config.evergreen.sc_earlyz_tile_fifo_size = 0x130; 322262306a36Sopenharmony_ci gb_addr_config = REDWOOD_GB_ADDR_CONFIG_GOLDEN; 322362306a36Sopenharmony_ci break; 322462306a36Sopenharmony_ci case CHIP_CEDAR: 322562306a36Sopenharmony_ci default: 322662306a36Sopenharmony_ci rdev->config.evergreen.num_ses = 1; 322762306a36Sopenharmony_ci rdev->config.evergreen.max_pipes = 2; 322862306a36Sopenharmony_ci rdev->config.evergreen.max_tile_pipes = 2; 322962306a36Sopenharmony_ci rdev->config.evergreen.max_simds = 2; 323062306a36Sopenharmony_ci rdev->config.evergreen.max_backends = 1 * rdev->config.evergreen.num_ses; 323162306a36Sopenharmony_ci rdev->config.evergreen.max_gprs = 256; 323262306a36Sopenharmony_ci rdev->config.evergreen.max_threads = 192; 323362306a36Sopenharmony_ci rdev->config.evergreen.max_gs_threads = 16; 323462306a36Sopenharmony_ci rdev->config.evergreen.max_stack_entries = 256; 323562306a36Sopenharmony_ci rdev->config.evergreen.sx_num_of_sets = 4; 323662306a36Sopenharmony_ci rdev->config.evergreen.sx_max_export_size = 128; 323762306a36Sopenharmony_ci rdev->config.evergreen.sx_max_export_pos_size = 32; 323862306a36Sopenharmony_ci rdev->config.evergreen.sx_max_export_smx_size = 96; 323962306a36Sopenharmony_ci rdev->config.evergreen.max_hw_contexts = 4; 324062306a36Sopenharmony_ci rdev->config.evergreen.sq_num_cf_insts = 1; 324162306a36Sopenharmony_ci 324262306a36Sopenharmony_ci rdev->config.evergreen.sc_prim_fifo_size = 0x40; 324362306a36Sopenharmony_ci rdev->config.evergreen.sc_hiz_tile_fifo_size = 0x30; 324462306a36Sopenharmony_ci rdev->config.evergreen.sc_earlyz_tile_fifo_size = 0x130; 324562306a36Sopenharmony_ci gb_addr_config = CEDAR_GB_ADDR_CONFIG_GOLDEN; 324662306a36Sopenharmony_ci break; 324762306a36Sopenharmony_ci case CHIP_PALM: 324862306a36Sopenharmony_ci rdev->config.evergreen.num_ses = 1; 324962306a36Sopenharmony_ci rdev->config.evergreen.max_pipes = 2; 325062306a36Sopenharmony_ci rdev->config.evergreen.max_tile_pipes = 2; 325162306a36Sopenharmony_ci rdev->config.evergreen.max_simds = 2; 325262306a36Sopenharmony_ci rdev->config.evergreen.max_backends = 1 * rdev->config.evergreen.num_ses; 325362306a36Sopenharmony_ci rdev->config.evergreen.max_gprs = 256; 325462306a36Sopenharmony_ci rdev->config.evergreen.max_threads = 192; 325562306a36Sopenharmony_ci rdev->config.evergreen.max_gs_threads = 16; 325662306a36Sopenharmony_ci rdev->config.evergreen.max_stack_entries = 256; 325762306a36Sopenharmony_ci rdev->config.evergreen.sx_num_of_sets = 4; 325862306a36Sopenharmony_ci rdev->config.evergreen.sx_max_export_size = 128; 325962306a36Sopenharmony_ci rdev->config.evergreen.sx_max_export_pos_size = 32; 326062306a36Sopenharmony_ci rdev->config.evergreen.sx_max_export_smx_size = 96; 326162306a36Sopenharmony_ci rdev->config.evergreen.max_hw_contexts = 4; 326262306a36Sopenharmony_ci rdev->config.evergreen.sq_num_cf_insts = 1; 326362306a36Sopenharmony_ci 326462306a36Sopenharmony_ci rdev->config.evergreen.sc_prim_fifo_size = 0x40; 326562306a36Sopenharmony_ci rdev->config.evergreen.sc_hiz_tile_fifo_size = 0x30; 326662306a36Sopenharmony_ci rdev->config.evergreen.sc_earlyz_tile_fifo_size = 0x130; 326762306a36Sopenharmony_ci gb_addr_config = CEDAR_GB_ADDR_CONFIG_GOLDEN; 326862306a36Sopenharmony_ci break; 326962306a36Sopenharmony_ci case CHIP_SUMO: 327062306a36Sopenharmony_ci rdev->config.evergreen.num_ses = 1; 327162306a36Sopenharmony_ci rdev->config.evergreen.max_pipes = 4; 327262306a36Sopenharmony_ci rdev->config.evergreen.max_tile_pipes = 4; 327362306a36Sopenharmony_ci if (rdev->pdev->device == 0x9648) 327462306a36Sopenharmony_ci rdev->config.evergreen.max_simds = 3; 327562306a36Sopenharmony_ci else if ((rdev->pdev->device == 0x9647) || 327662306a36Sopenharmony_ci (rdev->pdev->device == 0x964a)) 327762306a36Sopenharmony_ci rdev->config.evergreen.max_simds = 4; 327862306a36Sopenharmony_ci else 327962306a36Sopenharmony_ci rdev->config.evergreen.max_simds = 5; 328062306a36Sopenharmony_ci rdev->config.evergreen.max_backends = 2 * rdev->config.evergreen.num_ses; 328162306a36Sopenharmony_ci rdev->config.evergreen.max_gprs = 256; 328262306a36Sopenharmony_ci rdev->config.evergreen.max_threads = 248; 328362306a36Sopenharmony_ci rdev->config.evergreen.max_gs_threads = 32; 328462306a36Sopenharmony_ci rdev->config.evergreen.max_stack_entries = 256; 328562306a36Sopenharmony_ci rdev->config.evergreen.sx_num_of_sets = 4; 328662306a36Sopenharmony_ci rdev->config.evergreen.sx_max_export_size = 256; 328762306a36Sopenharmony_ci rdev->config.evergreen.sx_max_export_pos_size = 64; 328862306a36Sopenharmony_ci rdev->config.evergreen.sx_max_export_smx_size = 192; 328962306a36Sopenharmony_ci rdev->config.evergreen.max_hw_contexts = 8; 329062306a36Sopenharmony_ci rdev->config.evergreen.sq_num_cf_insts = 2; 329162306a36Sopenharmony_ci 329262306a36Sopenharmony_ci rdev->config.evergreen.sc_prim_fifo_size = 0x40; 329362306a36Sopenharmony_ci rdev->config.evergreen.sc_hiz_tile_fifo_size = 0x30; 329462306a36Sopenharmony_ci rdev->config.evergreen.sc_earlyz_tile_fifo_size = 0x130; 329562306a36Sopenharmony_ci gb_addr_config = SUMO_GB_ADDR_CONFIG_GOLDEN; 329662306a36Sopenharmony_ci break; 329762306a36Sopenharmony_ci case CHIP_SUMO2: 329862306a36Sopenharmony_ci rdev->config.evergreen.num_ses = 1; 329962306a36Sopenharmony_ci rdev->config.evergreen.max_pipes = 4; 330062306a36Sopenharmony_ci rdev->config.evergreen.max_tile_pipes = 4; 330162306a36Sopenharmony_ci rdev->config.evergreen.max_simds = 2; 330262306a36Sopenharmony_ci rdev->config.evergreen.max_backends = 1 * rdev->config.evergreen.num_ses; 330362306a36Sopenharmony_ci rdev->config.evergreen.max_gprs = 256; 330462306a36Sopenharmony_ci rdev->config.evergreen.max_threads = 248; 330562306a36Sopenharmony_ci rdev->config.evergreen.max_gs_threads = 32; 330662306a36Sopenharmony_ci rdev->config.evergreen.max_stack_entries = 512; 330762306a36Sopenharmony_ci rdev->config.evergreen.sx_num_of_sets = 4; 330862306a36Sopenharmony_ci rdev->config.evergreen.sx_max_export_size = 256; 330962306a36Sopenharmony_ci rdev->config.evergreen.sx_max_export_pos_size = 64; 331062306a36Sopenharmony_ci rdev->config.evergreen.sx_max_export_smx_size = 192; 331162306a36Sopenharmony_ci rdev->config.evergreen.max_hw_contexts = 4; 331262306a36Sopenharmony_ci rdev->config.evergreen.sq_num_cf_insts = 2; 331362306a36Sopenharmony_ci 331462306a36Sopenharmony_ci rdev->config.evergreen.sc_prim_fifo_size = 0x40; 331562306a36Sopenharmony_ci rdev->config.evergreen.sc_hiz_tile_fifo_size = 0x30; 331662306a36Sopenharmony_ci rdev->config.evergreen.sc_earlyz_tile_fifo_size = 0x130; 331762306a36Sopenharmony_ci gb_addr_config = SUMO2_GB_ADDR_CONFIG_GOLDEN; 331862306a36Sopenharmony_ci break; 331962306a36Sopenharmony_ci case CHIP_BARTS: 332062306a36Sopenharmony_ci rdev->config.evergreen.num_ses = 2; 332162306a36Sopenharmony_ci rdev->config.evergreen.max_pipes = 4; 332262306a36Sopenharmony_ci rdev->config.evergreen.max_tile_pipes = 8; 332362306a36Sopenharmony_ci rdev->config.evergreen.max_simds = 7; 332462306a36Sopenharmony_ci rdev->config.evergreen.max_backends = 4 * rdev->config.evergreen.num_ses; 332562306a36Sopenharmony_ci rdev->config.evergreen.max_gprs = 256; 332662306a36Sopenharmony_ci rdev->config.evergreen.max_threads = 248; 332762306a36Sopenharmony_ci rdev->config.evergreen.max_gs_threads = 32; 332862306a36Sopenharmony_ci rdev->config.evergreen.max_stack_entries = 512; 332962306a36Sopenharmony_ci rdev->config.evergreen.sx_num_of_sets = 4; 333062306a36Sopenharmony_ci rdev->config.evergreen.sx_max_export_size = 256; 333162306a36Sopenharmony_ci rdev->config.evergreen.sx_max_export_pos_size = 64; 333262306a36Sopenharmony_ci rdev->config.evergreen.sx_max_export_smx_size = 192; 333362306a36Sopenharmony_ci rdev->config.evergreen.max_hw_contexts = 8; 333462306a36Sopenharmony_ci rdev->config.evergreen.sq_num_cf_insts = 2; 333562306a36Sopenharmony_ci 333662306a36Sopenharmony_ci rdev->config.evergreen.sc_prim_fifo_size = 0x100; 333762306a36Sopenharmony_ci rdev->config.evergreen.sc_hiz_tile_fifo_size = 0x30; 333862306a36Sopenharmony_ci rdev->config.evergreen.sc_earlyz_tile_fifo_size = 0x130; 333962306a36Sopenharmony_ci gb_addr_config = BARTS_GB_ADDR_CONFIG_GOLDEN; 334062306a36Sopenharmony_ci break; 334162306a36Sopenharmony_ci case CHIP_TURKS: 334262306a36Sopenharmony_ci rdev->config.evergreen.num_ses = 1; 334362306a36Sopenharmony_ci rdev->config.evergreen.max_pipes = 4; 334462306a36Sopenharmony_ci rdev->config.evergreen.max_tile_pipes = 4; 334562306a36Sopenharmony_ci rdev->config.evergreen.max_simds = 6; 334662306a36Sopenharmony_ci rdev->config.evergreen.max_backends = 2 * rdev->config.evergreen.num_ses; 334762306a36Sopenharmony_ci rdev->config.evergreen.max_gprs = 256; 334862306a36Sopenharmony_ci rdev->config.evergreen.max_threads = 248; 334962306a36Sopenharmony_ci rdev->config.evergreen.max_gs_threads = 32; 335062306a36Sopenharmony_ci rdev->config.evergreen.max_stack_entries = 256; 335162306a36Sopenharmony_ci rdev->config.evergreen.sx_num_of_sets = 4; 335262306a36Sopenharmony_ci rdev->config.evergreen.sx_max_export_size = 256; 335362306a36Sopenharmony_ci rdev->config.evergreen.sx_max_export_pos_size = 64; 335462306a36Sopenharmony_ci rdev->config.evergreen.sx_max_export_smx_size = 192; 335562306a36Sopenharmony_ci rdev->config.evergreen.max_hw_contexts = 8; 335662306a36Sopenharmony_ci rdev->config.evergreen.sq_num_cf_insts = 2; 335762306a36Sopenharmony_ci 335862306a36Sopenharmony_ci rdev->config.evergreen.sc_prim_fifo_size = 0x100; 335962306a36Sopenharmony_ci rdev->config.evergreen.sc_hiz_tile_fifo_size = 0x30; 336062306a36Sopenharmony_ci rdev->config.evergreen.sc_earlyz_tile_fifo_size = 0x130; 336162306a36Sopenharmony_ci gb_addr_config = TURKS_GB_ADDR_CONFIG_GOLDEN; 336262306a36Sopenharmony_ci break; 336362306a36Sopenharmony_ci case CHIP_CAICOS: 336462306a36Sopenharmony_ci rdev->config.evergreen.num_ses = 1; 336562306a36Sopenharmony_ci rdev->config.evergreen.max_pipes = 2; 336662306a36Sopenharmony_ci rdev->config.evergreen.max_tile_pipes = 2; 336762306a36Sopenharmony_ci rdev->config.evergreen.max_simds = 2; 336862306a36Sopenharmony_ci rdev->config.evergreen.max_backends = 1 * rdev->config.evergreen.num_ses; 336962306a36Sopenharmony_ci rdev->config.evergreen.max_gprs = 256; 337062306a36Sopenharmony_ci rdev->config.evergreen.max_threads = 192; 337162306a36Sopenharmony_ci rdev->config.evergreen.max_gs_threads = 16; 337262306a36Sopenharmony_ci rdev->config.evergreen.max_stack_entries = 256; 337362306a36Sopenharmony_ci rdev->config.evergreen.sx_num_of_sets = 4; 337462306a36Sopenharmony_ci rdev->config.evergreen.sx_max_export_size = 128; 337562306a36Sopenharmony_ci rdev->config.evergreen.sx_max_export_pos_size = 32; 337662306a36Sopenharmony_ci rdev->config.evergreen.sx_max_export_smx_size = 96; 337762306a36Sopenharmony_ci rdev->config.evergreen.max_hw_contexts = 4; 337862306a36Sopenharmony_ci rdev->config.evergreen.sq_num_cf_insts = 1; 337962306a36Sopenharmony_ci 338062306a36Sopenharmony_ci rdev->config.evergreen.sc_prim_fifo_size = 0x40; 338162306a36Sopenharmony_ci rdev->config.evergreen.sc_hiz_tile_fifo_size = 0x30; 338262306a36Sopenharmony_ci rdev->config.evergreen.sc_earlyz_tile_fifo_size = 0x130; 338362306a36Sopenharmony_ci gb_addr_config = CAICOS_GB_ADDR_CONFIG_GOLDEN; 338462306a36Sopenharmony_ci break; 338562306a36Sopenharmony_ci } 338662306a36Sopenharmony_ci 338762306a36Sopenharmony_ci /* Initialize HDP */ 338862306a36Sopenharmony_ci for (i = 0, j = 0; i < 32; i++, j += 0x18) { 338962306a36Sopenharmony_ci WREG32((0x2c14 + j), 0x00000000); 339062306a36Sopenharmony_ci WREG32((0x2c18 + j), 0x00000000); 339162306a36Sopenharmony_ci WREG32((0x2c1c + j), 0x00000000); 339262306a36Sopenharmony_ci WREG32((0x2c20 + j), 0x00000000); 339362306a36Sopenharmony_ci WREG32((0x2c24 + j), 0x00000000); 339462306a36Sopenharmony_ci } 339562306a36Sopenharmony_ci 339662306a36Sopenharmony_ci WREG32(GRBM_CNTL, GRBM_READ_TIMEOUT(0xff)); 339762306a36Sopenharmony_ci WREG32(SRBM_INT_CNTL, 0x1); 339862306a36Sopenharmony_ci WREG32(SRBM_INT_ACK, 0x1); 339962306a36Sopenharmony_ci 340062306a36Sopenharmony_ci evergreen_fix_pci_max_read_req_size(rdev); 340162306a36Sopenharmony_ci 340262306a36Sopenharmony_ci RREG32(MC_SHARED_CHMAP); 340362306a36Sopenharmony_ci if ((rdev->family == CHIP_PALM) || 340462306a36Sopenharmony_ci (rdev->family == CHIP_SUMO) || 340562306a36Sopenharmony_ci (rdev->family == CHIP_SUMO2)) 340662306a36Sopenharmony_ci mc_arb_ramcfg = RREG32(FUS_MC_ARB_RAMCFG); 340762306a36Sopenharmony_ci else 340862306a36Sopenharmony_ci mc_arb_ramcfg = RREG32(MC_ARB_RAMCFG); 340962306a36Sopenharmony_ci 341062306a36Sopenharmony_ci /* setup tiling info dword. gb_addr_config is not adequate since it does 341162306a36Sopenharmony_ci * not have bank info, so create a custom tiling dword. 341262306a36Sopenharmony_ci * bits 3:0 num_pipes 341362306a36Sopenharmony_ci * bits 7:4 num_banks 341462306a36Sopenharmony_ci * bits 11:8 group_size 341562306a36Sopenharmony_ci * bits 15:12 row_size 341662306a36Sopenharmony_ci */ 341762306a36Sopenharmony_ci rdev->config.evergreen.tile_config = 0; 341862306a36Sopenharmony_ci switch (rdev->config.evergreen.max_tile_pipes) { 341962306a36Sopenharmony_ci case 1: 342062306a36Sopenharmony_ci default: 342162306a36Sopenharmony_ci rdev->config.evergreen.tile_config |= (0 << 0); 342262306a36Sopenharmony_ci break; 342362306a36Sopenharmony_ci case 2: 342462306a36Sopenharmony_ci rdev->config.evergreen.tile_config |= (1 << 0); 342562306a36Sopenharmony_ci break; 342662306a36Sopenharmony_ci case 4: 342762306a36Sopenharmony_ci rdev->config.evergreen.tile_config |= (2 << 0); 342862306a36Sopenharmony_ci break; 342962306a36Sopenharmony_ci case 8: 343062306a36Sopenharmony_ci rdev->config.evergreen.tile_config |= (3 << 0); 343162306a36Sopenharmony_ci break; 343262306a36Sopenharmony_ci } 343362306a36Sopenharmony_ci /* num banks is 8 on all fusion asics. 0 = 4, 1 = 8, 2 = 16 */ 343462306a36Sopenharmony_ci if (rdev->flags & RADEON_IS_IGP) 343562306a36Sopenharmony_ci rdev->config.evergreen.tile_config |= 1 << 4; 343662306a36Sopenharmony_ci else { 343762306a36Sopenharmony_ci switch ((mc_arb_ramcfg & NOOFBANK_MASK) >> NOOFBANK_SHIFT) { 343862306a36Sopenharmony_ci case 0: /* four banks */ 343962306a36Sopenharmony_ci rdev->config.evergreen.tile_config |= 0 << 4; 344062306a36Sopenharmony_ci break; 344162306a36Sopenharmony_ci case 1: /* eight banks */ 344262306a36Sopenharmony_ci rdev->config.evergreen.tile_config |= 1 << 4; 344362306a36Sopenharmony_ci break; 344462306a36Sopenharmony_ci case 2: /* sixteen banks */ 344562306a36Sopenharmony_ci default: 344662306a36Sopenharmony_ci rdev->config.evergreen.tile_config |= 2 << 4; 344762306a36Sopenharmony_ci break; 344862306a36Sopenharmony_ci } 344962306a36Sopenharmony_ci } 345062306a36Sopenharmony_ci rdev->config.evergreen.tile_config |= 0 << 8; 345162306a36Sopenharmony_ci rdev->config.evergreen.tile_config |= 345262306a36Sopenharmony_ci ((gb_addr_config & 0x30000000) >> 28) << 12; 345362306a36Sopenharmony_ci 345462306a36Sopenharmony_ci if ((rdev->family >= CHIP_CEDAR) && (rdev->family <= CHIP_HEMLOCK)) { 345562306a36Sopenharmony_ci u32 efuse_straps_4; 345662306a36Sopenharmony_ci u32 efuse_straps_3; 345762306a36Sopenharmony_ci 345862306a36Sopenharmony_ci efuse_straps_4 = RREG32_RCU(0x204); 345962306a36Sopenharmony_ci efuse_straps_3 = RREG32_RCU(0x203); 346062306a36Sopenharmony_ci tmp = (((efuse_straps_4 & 0xf) << 4) | 346162306a36Sopenharmony_ci ((efuse_straps_3 & 0xf0000000) >> 28)); 346262306a36Sopenharmony_ci } else { 346362306a36Sopenharmony_ci tmp = 0; 346462306a36Sopenharmony_ci for (i = (rdev->config.evergreen.num_ses - 1); i >= 0; i--) { 346562306a36Sopenharmony_ci u32 rb_disable_bitmap; 346662306a36Sopenharmony_ci 346762306a36Sopenharmony_ci WREG32(GRBM_GFX_INDEX, INSTANCE_BROADCAST_WRITES | SE_INDEX(i)); 346862306a36Sopenharmony_ci WREG32(RLC_GFX_INDEX, INSTANCE_BROADCAST_WRITES | SE_INDEX(i)); 346962306a36Sopenharmony_ci rb_disable_bitmap = (RREG32(CC_RB_BACKEND_DISABLE) & 0x00ff0000) >> 16; 347062306a36Sopenharmony_ci tmp <<= 4; 347162306a36Sopenharmony_ci tmp |= rb_disable_bitmap; 347262306a36Sopenharmony_ci } 347362306a36Sopenharmony_ci } 347462306a36Sopenharmony_ci /* enabled rb are just the one not disabled :) */ 347562306a36Sopenharmony_ci disabled_rb_mask = tmp; 347662306a36Sopenharmony_ci tmp = 0; 347762306a36Sopenharmony_ci for (i = 0; i < rdev->config.evergreen.max_backends; i++) 347862306a36Sopenharmony_ci tmp |= (1 << i); 347962306a36Sopenharmony_ci /* if all the backends are disabled, fix it up here */ 348062306a36Sopenharmony_ci if ((disabled_rb_mask & tmp) == tmp) { 348162306a36Sopenharmony_ci for (i = 0; i < rdev->config.evergreen.max_backends; i++) 348262306a36Sopenharmony_ci disabled_rb_mask &= ~(1 << i); 348362306a36Sopenharmony_ci } 348462306a36Sopenharmony_ci 348562306a36Sopenharmony_ci for (i = 0; i < rdev->config.evergreen.num_ses; i++) { 348662306a36Sopenharmony_ci u32 simd_disable_bitmap; 348762306a36Sopenharmony_ci 348862306a36Sopenharmony_ci WREG32(GRBM_GFX_INDEX, INSTANCE_BROADCAST_WRITES | SE_INDEX(i)); 348962306a36Sopenharmony_ci WREG32(RLC_GFX_INDEX, INSTANCE_BROADCAST_WRITES | SE_INDEX(i)); 349062306a36Sopenharmony_ci simd_disable_bitmap = (RREG32(CC_GC_SHADER_PIPE_CONFIG) & 0xffff0000) >> 16; 349162306a36Sopenharmony_ci simd_disable_bitmap |= 0xffffffff << rdev->config.evergreen.max_simds; 349262306a36Sopenharmony_ci tmp <<= 16; 349362306a36Sopenharmony_ci tmp |= simd_disable_bitmap; 349462306a36Sopenharmony_ci } 349562306a36Sopenharmony_ci rdev->config.evergreen.active_simds = hweight32(~tmp); 349662306a36Sopenharmony_ci 349762306a36Sopenharmony_ci WREG32(GRBM_GFX_INDEX, INSTANCE_BROADCAST_WRITES | SE_BROADCAST_WRITES); 349862306a36Sopenharmony_ci WREG32(RLC_GFX_INDEX, INSTANCE_BROADCAST_WRITES | SE_BROADCAST_WRITES); 349962306a36Sopenharmony_ci 350062306a36Sopenharmony_ci WREG32(GB_ADDR_CONFIG, gb_addr_config); 350162306a36Sopenharmony_ci WREG32(DMIF_ADDR_CONFIG, gb_addr_config); 350262306a36Sopenharmony_ci WREG32(HDP_ADDR_CONFIG, gb_addr_config); 350362306a36Sopenharmony_ci WREG32(DMA_TILING_CONFIG, gb_addr_config); 350462306a36Sopenharmony_ci WREG32(UVD_UDEC_ADDR_CONFIG, gb_addr_config); 350562306a36Sopenharmony_ci WREG32(UVD_UDEC_DB_ADDR_CONFIG, gb_addr_config); 350662306a36Sopenharmony_ci WREG32(UVD_UDEC_DBW_ADDR_CONFIG, gb_addr_config); 350762306a36Sopenharmony_ci 350862306a36Sopenharmony_ci if ((rdev->config.evergreen.max_backends == 1) && 350962306a36Sopenharmony_ci (rdev->flags & RADEON_IS_IGP)) { 351062306a36Sopenharmony_ci if ((disabled_rb_mask & 3) == 1) { 351162306a36Sopenharmony_ci /* RB0 disabled, RB1 enabled */ 351262306a36Sopenharmony_ci tmp = 0x11111111; 351362306a36Sopenharmony_ci } else { 351462306a36Sopenharmony_ci /* RB1 disabled, RB0 enabled */ 351562306a36Sopenharmony_ci tmp = 0x00000000; 351662306a36Sopenharmony_ci } 351762306a36Sopenharmony_ci } else { 351862306a36Sopenharmony_ci tmp = gb_addr_config & NUM_PIPES_MASK; 351962306a36Sopenharmony_ci tmp = r6xx_remap_render_backend(rdev, tmp, rdev->config.evergreen.max_backends, 352062306a36Sopenharmony_ci EVERGREEN_MAX_BACKENDS, disabled_rb_mask); 352162306a36Sopenharmony_ci } 352262306a36Sopenharmony_ci rdev->config.evergreen.backend_map = tmp; 352362306a36Sopenharmony_ci WREG32(GB_BACKEND_MAP, tmp); 352462306a36Sopenharmony_ci 352562306a36Sopenharmony_ci WREG32(CGTS_SYS_TCC_DISABLE, 0); 352662306a36Sopenharmony_ci WREG32(CGTS_TCC_DISABLE, 0); 352762306a36Sopenharmony_ci WREG32(CGTS_USER_SYS_TCC_DISABLE, 0); 352862306a36Sopenharmony_ci WREG32(CGTS_USER_TCC_DISABLE, 0); 352962306a36Sopenharmony_ci 353062306a36Sopenharmony_ci /* set HW defaults for 3D engine */ 353162306a36Sopenharmony_ci WREG32(CP_QUEUE_THRESHOLDS, (ROQ_IB1_START(0x16) | 353262306a36Sopenharmony_ci ROQ_IB2_START(0x2b))); 353362306a36Sopenharmony_ci 353462306a36Sopenharmony_ci WREG32(CP_MEQ_THRESHOLDS, STQ_SPLIT(0x30)); 353562306a36Sopenharmony_ci 353662306a36Sopenharmony_ci WREG32(TA_CNTL_AUX, (DISABLE_CUBE_ANISO | 353762306a36Sopenharmony_ci SYNC_GRADIENT | 353862306a36Sopenharmony_ci SYNC_WALKER | 353962306a36Sopenharmony_ci SYNC_ALIGNER)); 354062306a36Sopenharmony_ci 354162306a36Sopenharmony_ci sx_debug_1 = RREG32(SX_DEBUG_1); 354262306a36Sopenharmony_ci sx_debug_1 |= ENABLE_NEW_SMX_ADDRESS; 354362306a36Sopenharmony_ci WREG32(SX_DEBUG_1, sx_debug_1); 354462306a36Sopenharmony_ci 354562306a36Sopenharmony_ci 354662306a36Sopenharmony_ci smx_dc_ctl0 = RREG32(SMX_DC_CTL0); 354762306a36Sopenharmony_ci smx_dc_ctl0 &= ~NUMBER_OF_SETS(0x1ff); 354862306a36Sopenharmony_ci smx_dc_ctl0 |= NUMBER_OF_SETS(rdev->config.evergreen.sx_num_of_sets); 354962306a36Sopenharmony_ci WREG32(SMX_DC_CTL0, smx_dc_ctl0); 355062306a36Sopenharmony_ci 355162306a36Sopenharmony_ci if (rdev->family <= CHIP_SUMO2) 355262306a36Sopenharmony_ci WREG32(SMX_SAR_CTL0, 0x00010000); 355362306a36Sopenharmony_ci 355462306a36Sopenharmony_ci WREG32(SX_EXPORT_BUFFER_SIZES, (COLOR_BUFFER_SIZE((rdev->config.evergreen.sx_max_export_size / 4) - 1) | 355562306a36Sopenharmony_ci POSITION_BUFFER_SIZE((rdev->config.evergreen.sx_max_export_pos_size / 4) - 1) | 355662306a36Sopenharmony_ci SMX_BUFFER_SIZE((rdev->config.evergreen.sx_max_export_smx_size / 4) - 1))); 355762306a36Sopenharmony_ci 355862306a36Sopenharmony_ci WREG32(PA_SC_FIFO_SIZE, (SC_PRIM_FIFO_SIZE(rdev->config.evergreen.sc_prim_fifo_size) | 355962306a36Sopenharmony_ci SC_HIZ_TILE_FIFO_SIZE(rdev->config.evergreen.sc_hiz_tile_fifo_size) | 356062306a36Sopenharmony_ci SC_EARLYZ_TILE_FIFO_SIZE(rdev->config.evergreen.sc_earlyz_tile_fifo_size))); 356162306a36Sopenharmony_ci 356262306a36Sopenharmony_ci WREG32(VGT_NUM_INSTANCES, 1); 356362306a36Sopenharmony_ci WREG32(SPI_CONFIG_CNTL, 0); 356462306a36Sopenharmony_ci WREG32(SPI_CONFIG_CNTL_1, VTX_DONE_DELAY(4)); 356562306a36Sopenharmony_ci WREG32(CP_PERFMON_CNTL, 0); 356662306a36Sopenharmony_ci 356762306a36Sopenharmony_ci WREG32(SQ_MS_FIFO_SIZES, (CACHE_FIFO_SIZE(16 * rdev->config.evergreen.sq_num_cf_insts) | 356862306a36Sopenharmony_ci FETCH_FIFO_HIWATER(0x4) | 356962306a36Sopenharmony_ci DONE_FIFO_HIWATER(0xe0) | 357062306a36Sopenharmony_ci ALU_UPDATE_FIFO_HIWATER(0x8))); 357162306a36Sopenharmony_ci 357262306a36Sopenharmony_ci sq_config = RREG32(SQ_CONFIG); 357362306a36Sopenharmony_ci sq_config &= ~(PS_PRIO(3) | 357462306a36Sopenharmony_ci VS_PRIO(3) | 357562306a36Sopenharmony_ci GS_PRIO(3) | 357662306a36Sopenharmony_ci ES_PRIO(3)); 357762306a36Sopenharmony_ci sq_config |= (VC_ENABLE | 357862306a36Sopenharmony_ci EXPORT_SRC_C | 357962306a36Sopenharmony_ci PS_PRIO(0) | 358062306a36Sopenharmony_ci VS_PRIO(1) | 358162306a36Sopenharmony_ci GS_PRIO(2) | 358262306a36Sopenharmony_ci ES_PRIO(3)); 358362306a36Sopenharmony_ci 358462306a36Sopenharmony_ci switch (rdev->family) { 358562306a36Sopenharmony_ci case CHIP_CEDAR: 358662306a36Sopenharmony_ci case CHIP_PALM: 358762306a36Sopenharmony_ci case CHIP_SUMO: 358862306a36Sopenharmony_ci case CHIP_SUMO2: 358962306a36Sopenharmony_ci case CHIP_CAICOS: 359062306a36Sopenharmony_ci /* no vertex cache */ 359162306a36Sopenharmony_ci sq_config &= ~VC_ENABLE; 359262306a36Sopenharmony_ci break; 359362306a36Sopenharmony_ci default: 359462306a36Sopenharmony_ci break; 359562306a36Sopenharmony_ci } 359662306a36Sopenharmony_ci 359762306a36Sopenharmony_ci sq_lds_resource_mgmt = RREG32(SQ_LDS_RESOURCE_MGMT); 359862306a36Sopenharmony_ci 359962306a36Sopenharmony_ci sq_gpr_resource_mgmt_1 = NUM_PS_GPRS((rdev->config.evergreen.max_gprs - (4 * 2))* 12 / 32); 360062306a36Sopenharmony_ci sq_gpr_resource_mgmt_1 |= NUM_VS_GPRS((rdev->config.evergreen.max_gprs - (4 * 2)) * 6 / 32); 360162306a36Sopenharmony_ci sq_gpr_resource_mgmt_1 |= NUM_CLAUSE_TEMP_GPRS(4); 360262306a36Sopenharmony_ci sq_gpr_resource_mgmt_2 = NUM_GS_GPRS((rdev->config.evergreen.max_gprs - (4 * 2)) * 4 / 32); 360362306a36Sopenharmony_ci sq_gpr_resource_mgmt_2 |= NUM_ES_GPRS((rdev->config.evergreen.max_gprs - (4 * 2)) * 4 / 32); 360462306a36Sopenharmony_ci sq_gpr_resource_mgmt_3 = NUM_HS_GPRS((rdev->config.evergreen.max_gprs - (4 * 2)) * 3 / 32); 360562306a36Sopenharmony_ci sq_gpr_resource_mgmt_3 |= NUM_LS_GPRS((rdev->config.evergreen.max_gprs - (4 * 2)) * 3 / 32); 360662306a36Sopenharmony_ci 360762306a36Sopenharmony_ci switch (rdev->family) { 360862306a36Sopenharmony_ci case CHIP_CEDAR: 360962306a36Sopenharmony_ci case CHIP_PALM: 361062306a36Sopenharmony_ci case CHIP_SUMO: 361162306a36Sopenharmony_ci case CHIP_SUMO2: 361262306a36Sopenharmony_ci ps_thread_count = 96; 361362306a36Sopenharmony_ci break; 361462306a36Sopenharmony_ci default: 361562306a36Sopenharmony_ci ps_thread_count = 128; 361662306a36Sopenharmony_ci break; 361762306a36Sopenharmony_ci } 361862306a36Sopenharmony_ci 361962306a36Sopenharmony_ci sq_thread_resource_mgmt = NUM_PS_THREADS(ps_thread_count); 362062306a36Sopenharmony_ci sq_thread_resource_mgmt |= NUM_VS_THREADS((((rdev->config.evergreen.max_threads - ps_thread_count) / 6) / 8) * 8); 362162306a36Sopenharmony_ci sq_thread_resource_mgmt |= NUM_GS_THREADS((((rdev->config.evergreen.max_threads - ps_thread_count) / 6) / 8) * 8); 362262306a36Sopenharmony_ci sq_thread_resource_mgmt |= NUM_ES_THREADS((((rdev->config.evergreen.max_threads - ps_thread_count) / 6) / 8) * 8); 362362306a36Sopenharmony_ci sq_thread_resource_mgmt_2 = NUM_HS_THREADS((((rdev->config.evergreen.max_threads - ps_thread_count) / 6) / 8) * 8); 362462306a36Sopenharmony_ci sq_thread_resource_mgmt_2 |= NUM_LS_THREADS((((rdev->config.evergreen.max_threads - ps_thread_count) / 6) / 8) * 8); 362562306a36Sopenharmony_ci 362662306a36Sopenharmony_ci sq_stack_resource_mgmt_1 = NUM_PS_STACK_ENTRIES((rdev->config.evergreen.max_stack_entries * 1) / 6); 362762306a36Sopenharmony_ci sq_stack_resource_mgmt_1 |= NUM_VS_STACK_ENTRIES((rdev->config.evergreen.max_stack_entries * 1) / 6); 362862306a36Sopenharmony_ci sq_stack_resource_mgmt_2 = NUM_GS_STACK_ENTRIES((rdev->config.evergreen.max_stack_entries * 1) / 6); 362962306a36Sopenharmony_ci sq_stack_resource_mgmt_2 |= NUM_ES_STACK_ENTRIES((rdev->config.evergreen.max_stack_entries * 1) / 6); 363062306a36Sopenharmony_ci sq_stack_resource_mgmt_3 = NUM_HS_STACK_ENTRIES((rdev->config.evergreen.max_stack_entries * 1) / 6); 363162306a36Sopenharmony_ci sq_stack_resource_mgmt_3 |= NUM_LS_STACK_ENTRIES((rdev->config.evergreen.max_stack_entries * 1) / 6); 363262306a36Sopenharmony_ci 363362306a36Sopenharmony_ci WREG32(SQ_CONFIG, sq_config); 363462306a36Sopenharmony_ci WREG32(SQ_GPR_RESOURCE_MGMT_1, sq_gpr_resource_mgmt_1); 363562306a36Sopenharmony_ci WREG32(SQ_GPR_RESOURCE_MGMT_2, sq_gpr_resource_mgmt_2); 363662306a36Sopenharmony_ci WREG32(SQ_GPR_RESOURCE_MGMT_3, sq_gpr_resource_mgmt_3); 363762306a36Sopenharmony_ci WREG32(SQ_THREAD_RESOURCE_MGMT, sq_thread_resource_mgmt); 363862306a36Sopenharmony_ci WREG32(SQ_THREAD_RESOURCE_MGMT_2, sq_thread_resource_mgmt_2); 363962306a36Sopenharmony_ci WREG32(SQ_STACK_RESOURCE_MGMT_1, sq_stack_resource_mgmt_1); 364062306a36Sopenharmony_ci WREG32(SQ_STACK_RESOURCE_MGMT_2, sq_stack_resource_mgmt_2); 364162306a36Sopenharmony_ci WREG32(SQ_STACK_RESOURCE_MGMT_3, sq_stack_resource_mgmt_3); 364262306a36Sopenharmony_ci WREG32(SQ_DYN_GPR_CNTL_PS_FLUSH_REQ, 0); 364362306a36Sopenharmony_ci WREG32(SQ_LDS_RESOURCE_MGMT, sq_lds_resource_mgmt); 364462306a36Sopenharmony_ci 364562306a36Sopenharmony_ci WREG32(PA_SC_FORCE_EOV_MAX_CNTS, (FORCE_EOV_MAX_CLK_CNT(4095) | 364662306a36Sopenharmony_ci FORCE_EOV_MAX_REZ_CNT(255))); 364762306a36Sopenharmony_ci 364862306a36Sopenharmony_ci switch (rdev->family) { 364962306a36Sopenharmony_ci case CHIP_CEDAR: 365062306a36Sopenharmony_ci case CHIP_PALM: 365162306a36Sopenharmony_ci case CHIP_SUMO: 365262306a36Sopenharmony_ci case CHIP_SUMO2: 365362306a36Sopenharmony_ci case CHIP_CAICOS: 365462306a36Sopenharmony_ci vgt_cache_invalidation = CACHE_INVALIDATION(TC_ONLY); 365562306a36Sopenharmony_ci break; 365662306a36Sopenharmony_ci default: 365762306a36Sopenharmony_ci vgt_cache_invalidation = CACHE_INVALIDATION(VC_AND_TC); 365862306a36Sopenharmony_ci break; 365962306a36Sopenharmony_ci } 366062306a36Sopenharmony_ci vgt_cache_invalidation |= AUTO_INVLD_EN(ES_AND_GS_AUTO); 366162306a36Sopenharmony_ci WREG32(VGT_CACHE_INVALIDATION, vgt_cache_invalidation); 366262306a36Sopenharmony_ci 366362306a36Sopenharmony_ci WREG32(VGT_GS_VERTEX_REUSE, 16); 366462306a36Sopenharmony_ci WREG32(PA_SU_LINE_STIPPLE_VALUE, 0); 366562306a36Sopenharmony_ci WREG32(PA_SC_LINE_STIPPLE_STATE, 0); 366662306a36Sopenharmony_ci 366762306a36Sopenharmony_ci WREG32(VGT_VERTEX_REUSE_BLOCK_CNTL, 14); 366862306a36Sopenharmony_ci WREG32(VGT_OUT_DEALLOC_CNTL, 16); 366962306a36Sopenharmony_ci 367062306a36Sopenharmony_ci WREG32(CB_PERF_CTR0_SEL_0, 0); 367162306a36Sopenharmony_ci WREG32(CB_PERF_CTR0_SEL_1, 0); 367262306a36Sopenharmony_ci WREG32(CB_PERF_CTR1_SEL_0, 0); 367362306a36Sopenharmony_ci WREG32(CB_PERF_CTR1_SEL_1, 0); 367462306a36Sopenharmony_ci WREG32(CB_PERF_CTR2_SEL_0, 0); 367562306a36Sopenharmony_ci WREG32(CB_PERF_CTR2_SEL_1, 0); 367662306a36Sopenharmony_ci WREG32(CB_PERF_CTR3_SEL_0, 0); 367762306a36Sopenharmony_ci WREG32(CB_PERF_CTR3_SEL_1, 0); 367862306a36Sopenharmony_ci 367962306a36Sopenharmony_ci /* clear render buffer base addresses */ 368062306a36Sopenharmony_ci WREG32(CB_COLOR0_BASE, 0); 368162306a36Sopenharmony_ci WREG32(CB_COLOR1_BASE, 0); 368262306a36Sopenharmony_ci WREG32(CB_COLOR2_BASE, 0); 368362306a36Sopenharmony_ci WREG32(CB_COLOR3_BASE, 0); 368462306a36Sopenharmony_ci WREG32(CB_COLOR4_BASE, 0); 368562306a36Sopenharmony_ci WREG32(CB_COLOR5_BASE, 0); 368662306a36Sopenharmony_ci WREG32(CB_COLOR6_BASE, 0); 368762306a36Sopenharmony_ci WREG32(CB_COLOR7_BASE, 0); 368862306a36Sopenharmony_ci WREG32(CB_COLOR8_BASE, 0); 368962306a36Sopenharmony_ci WREG32(CB_COLOR9_BASE, 0); 369062306a36Sopenharmony_ci WREG32(CB_COLOR10_BASE, 0); 369162306a36Sopenharmony_ci WREG32(CB_COLOR11_BASE, 0); 369262306a36Sopenharmony_ci 369362306a36Sopenharmony_ci /* set the shader const cache sizes to 0 */ 369462306a36Sopenharmony_ci for (i = SQ_ALU_CONST_BUFFER_SIZE_PS_0; i < 0x28200; i += 4) 369562306a36Sopenharmony_ci WREG32(i, 0); 369662306a36Sopenharmony_ci for (i = SQ_ALU_CONST_BUFFER_SIZE_HS_0; i < 0x29000; i += 4) 369762306a36Sopenharmony_ci WREG32(i, 0); 369862306a36Sopenharmony_ci 369962306a36Sopenharmony_ci tmp = RREG32(HDP_MISC_CNTL); 370062306a36Sopenharmony_ci tmp |= HDP_FLUSH_INVALIDATE_CACHE; 370162306a36Sopenharmony_ci WREG32(HDP_MISC_CNTL, tmp); 370262306a36Sopenharmony_ci 370362306a36Sopenharmony_ci hdp_host_path_cntl = RREG32(HDP_HOST_PATH_CNTL); 370462306a36Sopenharmony_ci WREG32(HDP_HOST_PATH_CNTL, hdp_host_path_cntl); 370562306a36Sopenharmony_ci 370662306a36Sopenharmony_ci WREG32(PA_CL_ENHANCE, CLIP_VTX_REORDER_ENA | NUM_CLIP_SEQ(3)); 370762306a36Sopenharmony_ci 370862306a36Sopenharmony_ci udelay(50); 370962306a36Sopenharmony_ci 371062306a36Sopenharmony_ci} 371162306a36Sopenharmony_ci 371262306a36Sopenharmony_ciint evergreen_mc_init(struct radeon_device *rdev) 371362306a36Sopenharmony_ci{ 371462306a36Sopenharmony_ci u32 tmp; 371562306a36Sopenharmony_ci int chansize, numchan; 371662306a36Sopenharmony_ci 371762306a36Sopenharmony_ci /* Get VRAM informations */ 371862306a36Sopenharmony_ci rdev->mc.vram_is_ddr = true; 371962306a36Sopenharmony_ci if ((rdev->family == CHIP_PALM) || 372062306a36Sopenharmony_ci (rdev->family == CHIP_SUMO) || 372162306a36Sopenharmony_ci (rdev->family == CHIP_SUMO2)) 372262306a36Sopenharmony_ci tmp = RREG32(FUS_MC_ARB_RAMCFG); 372362306a36Sopenharmony_ci else 372462306a36Sopenharmony_ci tmp = RREG32(MC_ARB_RAMCFG); 372562306a36Sopenharmony_ci if (tmp & CHANSIZE_OVERRIDE) { 372662306a36Sopenharmony_ci chansize = 16; 372762306a36Sopenharmony_ci } else if (tmp & CHANSIZE_MASK) { 372862306a36Sopenharmony_ci chansize = 64; 372962306a36Sopenharmony_ci } else { 373062306a36Sopenharmony_ci chansize = 32; 373162306a36Sopenharmony_ci } 373262306a36Sopenharmony_ci tmp = RREG32(MC_SHARED_CHMAP); 373362306a36Sopenharmony_ci switch ((tmp & NOOFCHAN_MASK) >> NOOFCHAN_SHIFT) { 373462306a36Sopenharmony_ci case 0: 373562306a36Sopenharmony_ci default: 373662306a36Sopenharmony_ci numchan = 1; 373762306a36Sopenharmony_ci break; 373862306a36Sopenharmony_ci case 1: 373962306a36Sopenharmony_ci numchan = 2; 374062306a36Sopenharmony_ci break; 374162306a36Sopenharmony_ci case 2: 374262306a36Sopenharmony_ci numchan = 4; 374362306a36Sopenharmony_ci break; 374462306a36Sopenharmony_ci case 3: 374562306a36Sopenharmony_ci numchan = 8; 374662306a36Sopenharmony_ci break; 374762306a36Sopenharmony_ci } 374862306a36Sopenharmony_ci rdev->mc.vram_width = numchan * chansize; 374962306a36Sopenharmony_ci /* Could aper size report 0 ? */ 375062306a36Sopenharmony_ci rdev->mc.aper_base = pci_resource_start(rdev->pdev, 0); 375162306a36Sopenharmony_ci rdev->mc.aper_size = pci_resource_len(rdev->pdev, 0); 375262306a36Sopenharmony_ci /* Setup GPU memory space */ 375362306a36Sopenharmony_ci if ((rdev->family == CHIP_PALM) || 375462306a36Sopenharmony_ci (rdev->family == CHIP_SUMO) || 375562306a36Sopenharmony_ci (rdev->family == CHIP_SUMO2)) { 375662306a36Sopenharmony_ci /* size in bytes on fusion */ 375762306a36Sopenharmony_ci rdev->mc.mc_vram_size = RREG32(CONFIG_MEMSIZE); 375862306a36Sopenharmony_ci rdev->mc.real_vram_size = RREG32(CONFIG_MEMSIZE); 375962306a36Sopenharmony_ci } else { 376062306a36Sopenharmony_ci /* size in MB on evergreen/cayman/tn */ 376162306a36Sopenharmony_ci rdev->mc.mc_vram_size = RREG32(CONFIG_MEMSIZE) * 1024ULL * 1024ULL; 376262306a36Sopenharmony_ci rdev->mc.real_vram_size = RREG32(CONFIG_MEMSIZE) * 1024ULL * 1024ULL; 376362306a36Sopenharmony_ci } 376462306a36Sopenharmony_ci rdev->mc.visible_vram_size = rdev->mc.aper_size; 376562306a36Sopenharmony_ci r700_vram_gtt_location(rdev, &rdev->mc); 376662306a36Sopenharmony_ci radeon_update_bandwidth_info(rdev); 376762306a36Sopenharmony_ci 376862306a36Sopenharmony_ci return 0; 376962306a36Sopenharmony_ci} 377062306a36Sopenharmony_ci 377162306a36Sopenharmony_civoid evergreen_print_gpu_status_regs(struct radeon_device *rdev) 377262306a36Sopenharmony_ci{ 377362306a36Sopenharmony_ci dev_info(rdev->dev, " GRBM_STATUS = 0x%08X\n", 377462306a36Sopenharmony_ci RREG32(GRBM_STATUS)); 377562306a36Sopenharmony_ci dev_info(rdev->dev, " GRBM_STATUS_SE0 = 0x%08X\n", 377662306a36Sopenharmony_ci RREG32(GRBM_STATUS_SE0)); 377762306a36Sopenharmony_ci dev_info(rdev->dev, " GRBM_STATUS_SE1 = 0x%08X\n", 377862306a36Sopenharmony_ci RREG32(GRBM_STATUS_SE1)); 377962306a36Sopenharmony_ci dev_info(rdev->dev, " SRBM_STATUS = 0x%08X\n", 378062306a36Sopenharmony_ci RREG32(SRBM_STATUS)); 378162306a36Sopenharmony_ci dev_info(rdev->dev, " SRBM_STATUS2 = 0x%08X\n", 378262306a36Sopenharmony_ci RREG32(SRBM_STATUS2)); 378362306a36Sopenharmony_ci dev_info(rdev->dev, " R_008674_CP_STALLED_STAT1 = 0x%08X\n", 378462306a36Sopenharmony_ci RREG32(CP_STALLED_STAT1)); 378562306a36Sopenharmony_ci dev_info(rdev->dev, " R_008678_CP_STALLED_STAT2 = 0x%08X\n", 378662306a36Sopenharmony_ci RREG32(CP_STALLED_STAT2)); 378762306a36Sopenharmony_ci dev_info(rdev->dev, " R_00867C_CP_BUSY_STAT = 0x%08X\n", 378862306a36Sopenharmony_ci RREG32(CP_BUSY_STAT)); 378962306a36Sopenharmony_ci dev_info(rdev->dev, " R_008680_CP_STAT = 0x%08X\n", 379062306a36Sopenharmony_ci RREG32(CP_STAT)); 379162306a36Sopenharmony_ci dev_info(rdev->dev, " R_00D034_DMA_STATUS_REG = 0x%08X\n", 379262306a36Sopenharmony_ci RREG32(DMA_STATUS_REG)); 379362306a36Sopenharmony_ci if (rdev->family >= CHIP_CAYMAN) { 379462306a36Sopenharmony_ci dev_info(rdev->dev, " R_00D834_DMA_STATUS_REG = 0x%08X\n", 379562306a36Sopenharmony_ci RREG32(DMA_STATUS_REG + 0x800)); 379662306a36Sopenharmony_ci } 379762306a36Sopenharmony_ci} 379862306a36Sopenharmony_ci 379962306a36Sopenharmony_cibool evergreen_is_display_hung(struct radeon_device *rdev) 380062306a36Sopenharmony_ci{ 380162306a36Sopenharmony_ci u32 crtc_hung = 0; 380262306a36Sopenharmony_ci u32 crtc_status[6]; 380362306a36Sopenharmony_ci u32 i, j, tmp; 380462306a36Sopenharmony_ci 380562306a36Sopenharmony_ci for (i = 0; i < rdev->num_crtc; i++) { 380662306a36Sopenharmony_ci if (RREG32(EVERGREEN_CRTC_CONTROL + crtc_offsets[i]) & EVERGREEN_CRTC_MASTER_EN) { 380762306a36Sopenharmony_ci crtc_status[i] = RREG32(EVERGREEN_CRTC_STATUS_HV_COUNT + crtc_offsets[i]); 380862306a36Sopenharmony_ci crtc_hung |= (1 << i); 380962306a36Sopenharmony_ci } 381062306a36Sopenharmony_ci } 381162306a36Sopenharmony_ci 381262306a36Sopenharmony_ci for (j = 0; j < 10; j++) { 381362306a36Sopenharmony_ci for (i = 0; i < rdev->num_crtc; i++) { 381462306a36Sopenharmony_ci if (crtc_hung & (1 << i)) { 381562306a36Sopenharmony_ci tmp = RREG32(EVERGREEN_CRTC_STATUS_HV_COUNT + crtc_offsets[i]); 381662306a36Sopenharmony_ci if (tmp != crtc_status[i]) 381762306a36Sopenharmony_ci crtc_hung &= ~(1 << i); 381862306a36Sopenharmony_ci } 381962306a36Sopenharmony_ci } 382062306a36Sopenharmony_ci if (crtc_hung == 0) 382162306a36Sopenharmony_ci return false; 382262306a36Sopenharmony_ci udelay(100); 382362306a36Sopenharmony_ci } 382462306a36Sopenharmony_ci 382562306a36Sopenharmony_ci return true; 382662306a36Sopenharmony_ci} 382762306a36Sopenharmony_ci 382862306a36Sopenharmony_ciu32 evergreen_gpu_check_soft_reset(struct radeon_device *rdev) 382962306a36Sopenharmony_ci{ 383062306a36Sopenharmony_ci u32 reset_mask = 0; 383162306a36Sopenharmony_ci u32 tmp; 383262306a36Sopenharmony_ci 383362306a36Sopenharmony_ci /* GRBM_STATUS */ 383462306a36Sopenharmony_ci tmp = RREG32(GRBM_STATUS); 383562306a36Sopenharmony_ci if (tmp & (PA_BUSY | SC_BUSY | 383662306a36Sopenharmony_ci SH_BUSY | SX_BUSY | 383762306a36Sopenharmony_ci TA_BUSY | VGT_BUSY | 383862306a36Sopenharmony_ci DB_BUSY | CB_BUSY | 383962306a36Sopenharmony_ci SPI_BUSY | VGT_BUSY_NO_DMA)) 384062306a36Sopenharmony_ci reset_mask |= RADEON_RESET_GFX; 384162306a36Sopenharmony_ci 384262306a36Sopenharmony_ci if (tmp & (CF_RQ_PENDING | PF_RQ_PENDING | 384362306a36Sopenharmony_ci CP_BUSY | CP_COHERENCY_BUSY)) 384462306a36Sopenharmony_ci reset_mask |= RADEON_RESET_CP; 384562306a36Sopenharmony_ci 384662306a36Sopenharmony_ci if (tmp & GRBM_EE_BUSY) 384762306a36Sopenharmony_ci reset_mask |= RADEON_RESET_GRBM | RADEON_RESET_GFX | RADEON_RESET_CP; 384862306a36Sopenharmony_ci 384962306a36Sopenharmony_ci /* DMA_STATUS_REG */ 385062306a36Sopenharmony_ci tmp = RREG32(DMA_STATUS_REG); 385162306a36Sopenharmony_ci if (!(tmp & DMA_IDLE)) 385262306a36Sopenharmony_ci reset_mask |= RADEON_RESET_DMA; 385362306a36Sopenharmony_ci 385462306a36Sopenharmony_ci /* SRBM_STATUS2 */ 385562306a36Sopenharmony_ci tmp = RREG32(SRBM_STATUS2); 385662306a36Sopenharmony_ci if (tmp & DMA_BUSY) 385762306a36Sopenharmony_ci reset_mask |= RADEON_RESET_DMA; 385862306a36Sopenharmony_ci 385962306a36Sopenharmony_ci /* SRBM_STATUS */ 386062306a36Sopenharmony_ci tmp = RREG32(SRBM_STATUS); 386162306a36Sopenharmony_ci if (tmp & (RLC_RQ_PENDING | RLC_BUSY)) 386262306a36Sopenharmony_ci reset_mask |= RADEON_RESET_RLC; 386362306a36Sopenharmony_ci 386462306a36Sopenharmony_ci if (tmp & IH_BUSY) 386562306a36Sopenharmony_ci reset_mask |= RADEON_RESET_IH; 386662306a36Sopenharmony_ci 386762306a36Sopenharmony_ci if (tmp & SEM_BUSY) 386862306a36Sopenharmony_ci reset_mask |= RADEON_RESET_SEM; 386962306a36Sopenharmony_ci 387062306a36Sopenharmony_ci if (tmp & GRBM_RQ_PENDING) 387162306a36Sopenharmony_ci reset_mask |= RADEON_RESET_GRBM; 387262306a36Sopenharmony_ci 387362306a36Sopenharmony_ci if (tmp & VMC_BUSY) 387462306a36Sopenharmony_ci reset_mask |= RADEON_RESET_VMC; 387562306a36Sopenharmony_ci 387662306a36Sopenharmony_ci if (tmp & (MCB_BUSY | MCB_NON_DISPLAY_BUSY | 387762306a36Sopenharmony_ci MCC_BUSY | MCD_BUSY)) 387862306a36Sopenharmony_ci reset_mask |= RADEON_RESET_MC; 387962306a36Sopenharmony_ci 388062306a36Sopenharmony_ci if (evergreen_is_display_hung(rdev)) 388162306a36Sopenharmony_ci reset_mask |= RADEON_RESET_DISPLAY; 388262306a36Sopenharmony_ci 388362306a36Sopenharmony_ci /* VM_L2_STATUS */ 388462306a36Sopenharmony_ci tmp = RREG32(VM_L2_STATUS); 388562306a36Sopenharmony_ci if (tmp & L2_BUSY) 388662306a36Sopenharmony_ci reset_mask |= RADEON_RESET_VMC; 388762306a36Sopenharmony_ci 388862306a36Sopenharmony_ci /* Skip MC reset as it's mostly likely not hung, just busy */ 388962306a36Sopenharmony_ci if (reset_mask & RADEON_RESET_MC) { 389062306a36Sopenharmony_ci DRM_DEBUG("MC busy: 0x%08X, clearing.\n", reset_mask); 389162306a36Sopenharmony_ci reset_mask &= ~RADEON_RESET_MC; 389262306a36Sopenharmony_ci } 389362306a36Sopenharmony_ci 389462306a36Sopenharmony_ci return reset_mask; 389562306a36Sopenharmony_ci} 389662306a36Sopenharmony_ci 389762306a36Sopenharmony_cistatic void evergreen_gpu_soft_reset(struct radeon_device *rdev, u32 reset_mask) 389862306a36Sopenharmony_ci{ 389962306a36Sopenharmony_ci struct evergreen_mc_save save; 390062306a36Sopenharmony_ci u32 grbm_soft_reset = 0, srbm_soft_reset = 0; 390162306a36Sopenharmony_ci u32 tmp; 390262306a36Sopenharmony_ci 390362306a36Sopenharmony_ci if (reset_mask == 0) 390462306a36Sopenharmony_ci return; 390562306a36Sopenharmony_ci 390662306a36Sopenharmony_ci dev_info(rdev->dev, "GPU softreset: 0x%08X\n", reset_mask); 390762306a36Sopenharmony_ci 390862306a36Sopenharmony_ci evergreen_print_gpu_status_regs(rdev); 390962306a36Sopenharmony_ci 391062306a36Sopenharmony_ci /* Disable CP parsing/prefetching */ 391162306a36Sopenharmony_ci WREG32(CP_ME_CNTL, CP_ME_HALT | CP_PFP_HALT); 391262306a36Sopenharmony_ci 391362306a36Sopenharmony_ci if (reset_mask & RADEON_RESET_DMA) { 391462306a36Sopenharmony_ci /* Disable DMA */ 391562306a36Sopenharmony_ci tmp = RREG32(DMA_RB_CNTL); 391662306a36Sopenharmony_ci tmp &= ~DMA_RB_ENABLE; 391762306a36Sopenharmony_ci WREG32(DMA_RB_CNTL, tmp); 391862306a36Sopenharmony_ci } 391962306a36Sopenharmony_ci 392062306a36Sopenharmony_ci udelay(50); 392162306a36Sopenharmony_ci 392262306a36Sopenharmony_ci evergreen_mc_stop(rdev, &save); 392362306a36Sopenharmony_ci if (evergreen_mc_wait_for_idle(rdev)) { 392462306a36Sopenharmony_ci dev_warn(rdev->dev, "Wait for MC idle timedout !\n"); 392562306a36Sopenharmony_ci } 392662306a36Sopenharmony_ci 392762306a36Sopenharmony_ci if (reset_mask & (RADEON_RESET_GFX | RADEON_RESET_COMPUTE)) { 392862306a36Sopenharmony_ci grbm_soft_reset |= SOFT_RESET_DB | 392962306a36Sopenharmony_ci SOFT_RESET_CB | 393062306a36Sopenharmony_ci SOFT_RESET_PA | 393162306a36Sopenharmony_ci SOFT_RESET_SC | 393262306a36Sopenharmony_ci SOFT_RESET_SPI | 393362306a36Sopenharmony_ci SOFT_RESET_SX | 393462306a36Sopenharmony_ci SOFT_RESET_SH | 393562306a36Sopenharmony_ci SOFT_RESET_TC | 393662306a36Sopenharmony_ci SOFT_RESET_TA | 393762306a36Sopenharmony_ci SOFT_RESET_VC | 393862306a36Sopenharmony_ci SOFT_RESET_VGT; 393962306a36Sopenharmony_ci } 394062306a36Sopenharmony_ci 394162306a36Sopenharmony_ci if (reset_mask & RADEON_RESET_CP) { 394262306a36Sopenharmony_ci grbm_soft_reset |= SOFT_RESET_CP | 394362306a36Sopenharmony_ci SOFT_RESET_VGT; 394462306a36Sopenharmony_ci 394562306a36Sopenharmony_ci srbm_soft_reset |= SOFT_RESET_GRBM; 394662306a36Sopenharmony_ci } 394762306a36Sopenharmony_ci 394862306a36Sopenharmony_ci if (reset_mask & RADEON_RESET_DMA) 394962306a36Sopenharmony_ci srbm_soft_reset |= SOFT_RESET_DMA; 395062306a36Sopenharmony_ci 395162306a36Sopenharmony_ci if (reset_mask & RADEON_RESET_DISPLAY) 395262306a36Sopenharmony_ci srbm_soft_reset |= SOFT_RESET_DC; 395362306a36Sopenharmony_ci 395462306a36Sopenharmony_ci if (reset_mask & RADEON_RESET_RLC) 395562306a36Sopenharmony_ci srbm_soft_reset |= SOFT_RESET_RLC; 395662306a36Sopenharmony_ci 395762306a36Sopenharmony_ci if (reset_mask & RADEON_RESET_SEM) 395862306a36Sopenharmony_ci srbm_soft_reset |= SOFT_RESET_SEM; 395962306a36Sopenharmony_ci 396062306a36Sopenharmony_ci if (reset_mask & RADEON_RESET_IH) 396162306a36Sopenharmony_ci srbm_soft_reset |= SOFT_RESET_IH; 396262306a36Sopenharmony_ci 396362306a36Sopenharmony_ci if (reset_mask & RADEON_RESET_GRBM) 396462306a36Sopenharmony_ci srbm_soft_reset |= SOFT_RESET_GRBM; 396562306a36Sopenharmony_ci 396662306a36Sopenharmony_ci if (reset_mask & RADEON_RESET_VMC) 396762306a36Sopenharmony_ci srbm_soft_reset |= SOFT_RESET_VMC; 396862306a36Sopenharmony_ci 396962306a36Sopenharmony_ci if (!(rdev->flags & RADEON_IS_IGP)) { 397062306a36Sopenharmony_ci if (reset_mask & RADEON_RESET_MC) 397162306a36Sopenharmony_ci srbm_soft_reset |= SOFT_RESET_MC; 397262306a36Sopenharmony_ci } 397362306a36Sopenharmony_ci 397462306a36Sopenharmony_ci if (grbm_soft_reset) { 397562306a36Sopenharmony_ci tmp = RREG32(GRBM_SOFT_RESET); 397662306a36Sopenharmony_ci tmp |= grbm_soft_reset; 397762306a36Sopenharmony_ci dev_info(rdev->dev, "GRBM_SOFT_RESET=0x%08X\n", tmp); 397862306a36Sopenharmony_ci WREG32(GRBM_SOFT_RESET, tmp); 397962306a36Sopenharmony_ci tmp = RREG32(GRBM_SOFT_RESET); 398062306a36Sopenharmony_ci 398162306a36Sopenharmony_ci udelay(50); 398262306a36Sopenharmony_ci 398362306a36Sopenharmony_ci tmp &= ~grbm_soft_reset; 398462306a36Sopenharmony_ci WREG32(GRBM_SOFT_RESET, tmp); 398562306a36Sopenharmony_ci tmp = RREG32(GRBM_SOFT_RESET); 398662306a36Sopenharmony_ci } 398762306a36Sopenharmony_ci 398862306a36Sopenharmony_ci if (srbm_soft_reset) { 398962306a36Sopenharmony_ci tmp = RREG32(SRBM_SOFT_RESET); 399062306a36Sopenharmony_ci tmp |= srbm_soft_reset; 399162306a36Sopenharmony_ci dev_info(rdev->dev, "SRBM_SOFT_RESET=0x%08X\n", tmp); 399262306a36Sopenharmony_ci WREG32(SRBM_SOFT_RESET, tmp); 399362306a36Sopenharmony_ci tmp = RREG32(SRBM_SOFT_RESET); 399462306a36Sopenharmony_ci 399562306a36Sopenharmony_ci udelay(50); 399662306a36Sopenharmony_ci 399762306a36Sopenharmony_ci tmp &= ~srbm_soft_reset; 399862306a36Sopenharmony_ci WREG32(SRBM_SOFT_RESET, tmp); 399962306a36Sopenharmony_ci tmp = RREG32(SRBM_SOFT_RESET); 400062306a36Sopenharmony_ci } 400162306a36Sopenharmony_ci 400262306a36Sopenharmony_ci /* Wait a little for things to settle down */ 400362306a36Sopenharmony_ci udelay(50); 400462306a36Sopenharmony_ci 400562306a36Sopenharmony_ci evergreen_mc_resume(rdev, &save); 400662306a36Sopenharmony_ci udelay(50); 400762306a36Sopenharmony_ci 400862306a36Sopenharmony_ci evergreen_print_gpu_status_regs(rdev); 400962306a36Sopenharmony_ci} 401062306a36Sopenharmony_ci 401162306a36Sopenharmony_civoid evergreen_gpu_pci_config_reset(struct radeon_device *rdev) 401262306a36Sopenharmony_ci{ 401362306a36Sopenharmony_ci struct evergreen_mc_save save; 401462306a36Sopenharmony_ci u32 tmp, i; 401562306a36Sopenharmony_ci 401662306a36Sopenharmony_ci dev_info(rdev->dev, "GPU pci config reset\n"); 401762306a36Sopenharmony_ci 401862306a36Sopenharmony_ci /* disable dpm? */ 401962306a36Sopenharmony_ci 402062306a36Sopenharmony_ci /* Disable CP parsing/prefetching */ 402162306a36Sopenharmony_ci WREG32(CP_ME_CNTL, CP_ME_HALT | CP_PFP_HALT); 402262306a36Sopenharmony_ci udelay(50); 402362306a36Sopenharmony_ci /* Disable DMA */ 402462306a36Sopenharmony_ci tmp = RREG32(DMA_RB_CNTL); 402562306a36Sopenharmony_ci tmp &= ~DMA_RB_ENABLE; 402662306a36Sopenharmony_ci WREG32(DMA_RB_CNTL, tmp); 402762306a36Sopenharmony_ci /* XXX other engines? */ 402862306a36Sopenharmony_ci 402962306a36Sopenharmony_ci /* halt the rlc */ 403062306a36Sopenharmony_ci r600_rlc_stop(rdev); 403162306a36Sopenharmony_ci 403262306a36Sopenharmony_ci udelay(50); 403362306a36Sopenharmony_ci 403462306a36Sopenharmony_ci /* set mclk/sclk to bypass */ 403562306a36Sopenharmony_ci rv770_set_clk_bypass_mode(rdev); 403662306a36Sopenharmony_ci /* disable BM */ 403762306a36Sopenharmony_ci pci_clear_master(rdev->pdev); 403862306a36Sopenharmony_ci /* disable mem access */ 403962306a36Sopenharmony_ci evergreen_mc_stop(rdev, &save); 404062306a36Sopenharmony_ci if (evergreen_mc_wait_for_idle(rdev)) { 404162306a36Sopenharmony_ci dev_warn(rdev->dev, "Wait for MC idle timed out !\n"); 404262306a36Sopenharmony_ci } 404362306a36Sopenharmony_ci /* reset */ 404462306a36Sopenharmony_ci radeon_pci_config_reset(rdev); 404562306a36Sopenharmony_ci /* wait for asic to come out of reset */ 404662306a36Sopenharmony_ci for (i = 0; i < rdev->usec_timeout; i++) { 404762306a36Sopenharmony_ci if (RREG32(CONFIG_MEMSIZE) != 0xffffffff) 404862306a36Sopenharmony_ci break; 404962306a36Sopenharmony_ci udelay(1); 405062306a36Sopenharmony_ci } 405162306a36Sopenharmony_ci} 405262306a36Sopenharmony_ci 405362306a36Sopenharmony_ciint evergreen_asic_reset(struct radeon_device *rdev, bool hard) 405462306a36Sopenharmony_ci{ 405562306a36Sopenharmony_ci u32 reset_mask; 405662306a36Sopenharmony_ci 405762306a36Sopenharmony_ci if (hard) { 405862306a36Sopenharmony_ci evergreen_gpu_pci_config_reset(rdev); 405962306a36Sopenharmony_ci return 0; 406062306a36Sopenharmony_ci } 406162306a36Sopenharmony_ci 406262306a36Sopenharmony_ci reset_mask = evergreen_gpu_check_soft_reset(rdev); 406362306a36Sopenharmony_ci 406462306a36Sopenharmony_ci if (reset_mask) 406562306a36Sopenharmony_ci r600_set_bios_scratch_engine_hung(rdev, true); 406662306a36Sopenharmony_ci 406762306a36Sopenharmony_ci /* try soft reset */ 406862306a36Sopenharmony_ci evergreen_gpu_soft_reset(rdev, reset_mask); 406962306a36Sopenharmony_ci 407062306a36Sopenharmony_ci reset_mask = evergreen_gpu_check_soft_reset(rdev); 407162306a36Sopenharmony_ci 407262306a36Sopenharmony_ci /* try pci config reset */ 407362306a36Sopenharmony_ci if (reset_mask && radeon_hard_reset) 407462306a36Sopenharmony_ci evergreen_gpu_pci_config_reset(rdev); 407562306a36Sopenharmony_ci 407662306a36Sopenharmony_ci reset_mask = evergreen_gpu_check_soft_reset(rdev); 407762306a36Sopenharmony_ci 407862306a36Sopenharmony_ci if (!reset_mask) 407962306a36Sopenharmony_ci r600_set_bios_scratch_engine_hung(rdev, false); 408062306a36Sopenharmony_ci 408162306a36Sopenharmony_ci return 0; 408262306a36Sopenharmony_ci} 408362306a36Sopenharmony_ci 408462306a36Sopenharmony_ci/** 408562306a36Sopenharmony_ci * evergreen_gfx_is_lockup - Check if the GFX engine is locked up 408662306a36Sopenharmony_ci * 408762306a36Sopenharmony_ci * @rdev: radeon_device pointer 408862306a36Sopenharmony_ci * @ring: radeon_ring structure holding ring information 408962306a36Sopenharmony_ci * 409062306a36Sopenharmony_ci * Check if the GFX engine is locked up. 409162306a36Sopenharmony_ci * Returns true if the engine appears to be locked up, false if not. 409262306a36Sopenharmony_ci */ 409362306a36Sopenharmony_cibool evergreen_gfx_is_lockup(struct radeon_device *rdev, struct radeon_ring *ring) 409462306a36Sopenharmony_ci{ 409562306a36Sopenharmony_ci u32 reset_mask = evergreen_gpu_check_soft_reset(rdev); 409662306a36Sopenharmony_ci 409762306a36Sopenharmony_ci if (!(reset_mask & (RADEON_RESET_GFX | 409862306a36Sopenharmony_ci RADEON_RESET_COMPUTE | 409962306a36Sopenharmony_ci RADEON_RESET_CP))) { 410062306a36Sopenharmony_ci radeon_ring_lockup_update(rdev, ring); 410162306a36Sopenharmony_ci return false; 410262306a36Sopenharmony_ci } 410362306a36Sopenharmony_ci return radeon_ring_test_lockup(rdev, ring); 410462306a36Sopenharmony_ci} 410562306a36Sopenharmony_ci 410662306a36Sopenharmony_ci/* 410762306a36Sopenharmony_ci * RLC 410862306a36Sopenharmony_ci */ 410962306a36Sopenharmony_ci#define RLC_SAVE_RESTORE_LIST_END_MARKER 0x00000000 411062306a36Sopenharmony_ci#define RLC_CLEAR_STATE_END_MARKER 0x00000001 411162306a36Sopenharmony_ci 411262306a36Sopenharmony_civoid sumo_rlc_fini(struct radeon_device *rdev) 411362306a36Sopenharmony_ci{ 411462306a36Sopenharmony_ci int r; 411562306a36Sopenharmony_ci 411662306a36Sopenharmony_ci /* save restore block */ 411762306a36Sopenharmony_ci if (rdev->rlc.save_restore_obj) { 411862306a36Sopenharmony_ci r = radeon_bo_reserve(rdev->rlc.save_restore_obj, false); 411962306a36Sopenharmony_ci if (unlikely(r != 0)) 412062306a36Sopenharmony_ci dev_warn(rdev->dev, "(%d) reserve RLC sr bo failed\n", r); 412162306a36Sopenharmony_ci radeon_bo_unpin(rdev->rlc.save_restore_obj); 412262306a36Sopenharmony_ci radeon_bo_unreserve(rdev->rlc.save_restore_obj); 412362306a36Sopenharmony_ci 412462306a36Sopenharmony_ci radeon_bo_unref(&rdev->rlc.save_restore_obj); 412562306a36Sopenharmony_ci rdev->rlc.save_restore_obj = NULL; 412662306a36Sopenharmony_ci } 412762306a36Sopenharmony_ci 412862306a36Sopenharmony_ci /* clear state block */ 412962306a36Sopenharmony_ci if (rdev->rlc.clear_state_obj) { 413062306a36Sopenharmony_ci r = radeon_bo_reserve(rdev->rlc.clear_state_obj, false); 413162306a36Sopenharmony_ci if (unlikely(r != 0)) 413262306a36Sopenharmony_ci dev_warn(rdev->dev, "(%d) reserve RLC c bo failed\n", r); 413362306a36Sopenharmony_ci radeon_bo_unpin(rdev->rlc.clear_state_obj); 413462306a36Sopenharmony_ci radeon_bo_unreserve(rdev->rlc.clear_state_obj); 413562306a36Sopenharmony_ci 413662306a36Sopenharmony_ci radeon_bo_unref(&rdev->rlc.clear_state_obj); 413762306a36Sopenharmony_ci rdev->rlc.clear_state_obj = NULL; 413862306a36Sopenharmony_ci } 413962306a36Sopenharmony_ci 414062306a36Sopenharmony_ci /* clear state block */ 414162306a36Sopenharmony_ci if (rdev->rlc.cp_table_obj) { 414262306a36Sopenharmony_ci r = radeon_bo_reserve(rdev->rlc.cp_table_obj, false); 414362306a36Sopenharmony_ci if (unlikely(r != 0)) 414462306a36Sopenharmony_ci dev_warn(rdev->dev, "(%d) reserve RLC cp table bo failed\n", r); 414562306a36Sopenharmony_ci radeon_bo_unpin(rdev->rlc.cp_table_obj); 414662306a36Sopenharmony_ci radeon_bo_unreserve(rdev->rlc.cp_table_obj); 414762306a36Sopenharmony_ci 414862306a36Sopenharmony_ci radeon_bo_unref(&rdev->rlc.cp_table_obj); 414962306a36Sopenharmony_ci rdev->rlc.cp_table_obj = NULL; 415062306a36Sopenharmony_ci } 415162306a36Sopenharmony_ci} 415262306a36Sopenharmony_ci 415362306a36Sopenharmony_ci#define CP_ME_TABLE_SIZE 96 415462306a36Sopenharmony_ci 415562306a36Sopenharmony_ciint sumo_rlc_init(struct radeon_device *rdev) 415662306a36Sopenharmony_ci{ 415762306a36Sopenharmony_ci const u32 *src_ptr; 415862306a36Sopenharmony_ci volatile u32 *dst_ptr; 415962306a36Sopenharmony_ci u32 dws, data, i, j, k, reg_num; 416062306a36Sopenharmony_ci u32 reg_list_num, reg_list_hdr_blk_index, reg_list_blk_index = 0; 416162306a36Sopenharmony_ci u64 reg_list_mc_addr; 416262306a36Sopenharmony_ci const struct cs_section_def *cs_data; 416362306a36Sopenharmony_ci int r; 416462306a36Sopenharmony_ci 416562306a36Sopenharmony_ci src_ptr = rdev->rlc.reg_list; 416662306a36Sopenharmony_ci dws = rdev->rlc.reg_list_size; 416762306a36Sopenharmony_ci if (rdev->family >= CHIP_BONAIRE) { 416862306a36Sopenharmony_ci dws += (5 * 16) + 48 + 48 + 64; 416962306a36Sopenharmony_ci } 417062306a36Sopenharmony_ci cs_data = rdev->rlc.cs_data; 417162306a36Sopenharmony_ci 417262306a36Sopenharmony_ci if (src_ptr) { 417362306a36Sopenharmony_ci /* save restore block */ 417462306a36Sopenharmony_ci if (rdev->rlc.save_restore_obj == NULL) { 417562306a36Sopenharmony_ci r = radeon_bo_create(rdev, dws * 4, PAGE_SIZE, true, 417662306a36Sopenharmony_ci RADEON_GEM_DOMAIN_VRAM, 0, NULL, 417762306a36Sopenharmony_ci NULL, &rdev->rlc.save_restore_obj); 417862306a36Sopenharmony_ci if (r) { 417962306a36Sopenharmony_ci dev_warn(rdev->dev, "(%d) create RLC sr bo failed\n", r); 418062306a36Sopenharmony_ci return r; 418162306a36Sopenharmony_ci } 418262306a36Sopenharmony_ci } 418362306a36Sopenharmony_ci 418462306a36Sopenharmony_ci r = radeon_bo_reserve(rdev->rlc.save_restore_obj, false); 418562306a36Sopenharmony_ci if (unlikely(r != 0)) { 418662306a36Sopenharmony_ci sumo_rlc_fini(rdev); 418762306a36Sopenharmony_ci return r; 418862306a36Sopenharmony_ci } 418962306a36Sopenharmony_ci r = radeon_bo_pin(rdev->rlc.save_restore_obj, RADEON_GEM_DOMAIN_VRAM, 419062306a36Sopenharmony_ci &rdev->rlc.save_restore_gpu_addr); 419162306a36Sopenharmony_ci if (r) { 419262306a36Sopenharmony_ci radeon_bo_unreserve(rdev->rlc.save_restore_obj); 419362306a36Sopenharmony_ci dev_warn(rdev->dev, "(%d) pin RLC sr bo failed\n", r); 419462306a36Sopenharmony_ci sumo_rlc_fini(rdev); 419562306a36Sopenharmony_ci return r; 419662306a36Sopenharmony_ci } 419762306a36Sopenharmony_ci 419862306a36Sopenharmony_ci r = radeon_bo_kmap(rdev->rlc.save_restore_obj, (void **)&rdev->rlc.sr_ptr); 419962306a36Sopenharmony_ci if (r) { 420062306a36Sopenharmony_ci dev_warn(rdev->dev, "(%d) map RLC sr bo failed\n", r); 420162306a36Sopenharmony_ci sumo_rlc_fini(rdev); 420262306a36Sopenharmony_ci return r; 420362306a36Sopenharmony_ci } 420462306a36Sopenharmony_ci /* write the sr buffer */ 420562306a36Sopenharmony_ci dst_ptr = rdev->rlc.sr_ptr; 420662306a36Sopenharmony_ci if (rdev->family >= CHIP_TAHITI) { 420762306a36Sopenharmony_ci /* SI */ 420862306a36Sopenharmony_ci for (i = 0; i < rdev->rlc.reg_list_size; i++) 420962306a36Sopenharmony_ci dst_ptr[i] = cpu_to_le32(src_ptr[i]); 421062306a36Sopenharmony_ci } else { 421162306a36Sopenharmony_ci /* ON/LN/TN */ 421262306a36Sopenharmony_ci /* format: 421362306a36Sopenharmony_ci * dw0: (reg2 << 16) | reg1 421462306a36Sopenharmony_ci * dw1: reg1 save space 421562306a36Sopenharmony_ci * dw2: reg2 save space 421662306a36Sopenharmony_ci */ 421762306a36Sopenharmony_ci for (i = 0; i < dws; i++) { 421862306a36Sopenharmony_ci data = src_ptr[i] >> 2; 421962306a36Sopenharmony_ci i++; 422062306a36Sopenharmony_ci if (i < dws) 422162306a36Sopenharmony_ci data |= (src_ptr[i] >> 2) << 16; 422262306a36Sopenharmony_ci j = (((i - 1) * 3) / 2); 422362306a36Sopenharmony_ci dst_ptr[j] = cpu_to_le32(data); 422462306a36Sopenharmony_ci } 422562306a36Sopenharmony_ci j = ((i * 3) / 2); 422662306a36Sopenharmony_ci dst_ptr[j] = cpu_to_le32(RLC_SAVE_RESTORE_LIST_END_MARKER); 422762306a36Sopenharmony_ci } 422862306a36Sopenharmony_ci radeon_bo_kunmap(rdev->rlc.save_restore_obj); 422962306a36Sopenharmony_ci radeon_bo_unreserve(rdev->rlc.save_restore_obj); 423062306a36Sopenharmony_ci } 423162306a36Sopenharmony_ci 423262306a36Sopenharmony_ci if (cs_data) { 423362306a36Sopenharmony_ci /* clear state block */ 423462306a36Sopenharmony_ci if (rdev->family >= CHIP_BONAIRE) { 423562306a36Sopenharmony_ci rdev->rlc.clear_state_size = dws = cik_get_csb_size(rdev); 423662306a36Sopenharmony_ci } else if (rdev->family >= CHIP_TAHITI) { 423762306a36Sopenharmony_ci rdev->rlc.clear_state_size = si_get_csb_size(rdev); 423862306a36Sopenharmony_ci dws = rdev->rlc.clear_state_size + (256 / 4); 423962306a36Sopenharmony_ci } else { 424062306a36Sopenharmony_ci reg_list_num = 0; 424162306a36Sopenharmony_ci dws = 0; 424262306a36Sopenharmony_ci for (i = 0; cs_data[i].section != NULL; i++) { 424362306a36Sopenharmony_ci for (j = 0; cs_data[i].section[j].extent != NULL; j++) { 424462306a36Sopenharmony_ci reg_list_num++; 424562306a36Sopenharmony_ci dws += cs_data[i].section[j].reg_count; 424662306a36Sopenharmony_ci } 424762306a36Sopenharmony_ci } 424862306a36Sopenharmony_ci reg_list_blk_index = (3 * reg_list_num + 2); 424962306a36Sopenharmony_ci dws += reg_list_blk_index; 425062306a36Sopenharmony_ci rdev->rlc.clear_state_size = dws; 425162306a36Sopenharmony_ci } 425262306a36Sopenharmony_ci 425362306a36Sopenharmony_ci if (rdev->rlc.clear_state_obj == NULL) { 425462306a36Sopenharmony_ci r = radeon_bo_create(rdev, dws * 4, PAGE_SIZE, true, 425562306a36Sopenharmony_ci RADEON_GEM_DOMAIN_VRAM, 0, NULL, 425662306a36Sopenharmony_ci NULL, &rdev->rlc.clear_state_obj); 425762306a36Sopenharmony_ci if (r) { 425862306a36Sopenharmony_ci dev_warn(rdev->dev, "(%d) create RLC c bo failed\n", r); 425962306a36Sopenharmony_ci sumo_rlc_fini(rdev); 426062306a36Sopenharmony_ci return r; 426162306a36Sopenharmony_ci } 426262306a36Sopenharmony_ci } 426362306a36Sopenharmony_ci r = radeon_bo_reserve(rdev->rlc.clear_state_obj, false); 426462306a36Sopenharmony_ci if (unlikely(r != 0)) { 426562306a36Sopenharmony_ci sumo_rlc_fini(rdev); 426662306a36Sopenharmony_ci return r; 426762306a36Sopenharmony_ci } 426862306a36Sopenharmony_ci r = radeon_bo_pin(rdev->rlc.clear_state_obj, RADEON_GEM_DOMAIN_VRAM, 426962306a36Sopenharmony_ci &rdev->rlc.clear_state_gpu_addr); 427062306a36Sopenharmony_ci if (r) { 427162306a36Sopenharmony_ci radeon_bo_unreserve(rdev->rlc.clear_state_obj); 427262306a36Sopenharmony_ci dev_warn(rdev->dev, "(%d) pin RLC c bo failed\n", r); 427362306a36Sopenharmony_ci sumo_rlc_fini(rdev); 427462306a36Sopenharmony_ci return r; 427562306a36Sopenharmony_ci } 427662306a36Sopenharmony_ci 427762306a36Sopenharmony_ci r = radeon_bo_kmap(rdev->rlc.clear_state_obj, (void **)&rdev->rlc.cs_ptr); 427862306a36Sopenharmony_ci if (r) { 427962306a36Sopenharmony_ci dev_warn(rdev->dev, "(%d) map RLC c bo failed\n", r); 428062306a36Sopenharmony_ci sumo_rlc_fini(rdev); 428162306a36Sopenharmony_ci return r; 428262306a36Sopenharmony_ci } 428362306a36Sopenharmony_ci /* set up the cs buffer */ 428462306a36Sopenharmony_ci dst_ptr = rdev->rlc.cs_ptr; 428562306a36Sopenharmony_ci if (rdev->family >= CHIP_BONAIRE) { 428662306a36Sopenharmony_ci cik_get_csb_buffer(rdev, dst_ptr); 428762306a36Sopenharmony_ci } else if (rdev->family >= CHIP_TAHITI) { 428862306a36Sopenharmony_ci reg_list_mc_addr = rdev->rlc.clear_state_gpu_addr + 256; 428962306a36Sopenharmony_ci dst_ptr[0] = cpu_to_le32(upper_32_bits(reg_list_mc_addr)); 429062306a36Sopenharmony_ci dst_ptr[1] = cpu_to_le32(lower_32_bits(reg_list_mc_addr)); 429162306a36Sopenharmony_ci dst_ptr[2] = cpu_to_le32(rdev->rlc.clear_state_size); 429262306a36Sopenharmony_ci si_get_csb_buffer(rdev, &dst_ptr[(256/4)]); 429362306a36Sopenharmony_ci } else { 429462306a36Sopenharmony_ci reg_list_hdr_blk_index = 0; 429562306a36Sopenharmony_ci reg_list_mc_addr = rdev->rlc.clear_state_gpu_addr + (reg_list_blk_index * 4); 429662306a36Sopenharmony_ci data = upper_32_bits(reg_list_mc_addr); 429762306a36Sopenharmony_ci dst_ptr[reg_list_hdr_blk_index] = cpu_to_le32(data); 429862306a36Sopenharmony_ci reg_list_hdr_blk_index++; 429962306a36Sopenharmony_ci for (i = 0; cs_data[i].section != NULL; i++) { 430062306a36Sopenharmony_ci for (j = 0; cs_data[i].section[j].extent != NULL; j++) { 430162306a36Sopenharmony_ci reg_num = cs_data[i].section[j].reg_count; 430262306a36Sopenharmony_ci data = reg_list_mc_addr & 0xffffffff; 430362306a36Sopenharmony_ci dst_ptr[reg_list_hdr_blk_index] = cpu_to_le32(data); 430462306a36Sopenharmony_ci reg_list_hdr_blk_index++; 430562306a36Sopenharmony_ci 430662306a36Sopenharmony_ci data = (cs_data[i].section[j].reg_index * 4) & 0xffffffff; 430762306a36Sopenharmony_ci dst_ptr[reg_list_hdr_blk_index] = cpu_to_le32(data); 430862306a36Sopenharmony_ci reg_list_hdr_blk_index++; 430962306a36Sopenharmony_ci 431062306a36Sopenharmony_ci data = 0x08000000 | (reg_num * 4); 431162306a36Sopenharmony_ci dst_ptr[reg_list_hdr_blk_index] = cpu_to_le32(data); 431262306a36Sopenharmony_ci reg_list_hdr_blk_index++; 431362306a36Sopenharmony_ci 431462306a36Sopenharmony_ci for (k = 0; k < reg_num; k++) { 431562306a36Sopenharmony_ci data = cs_data[i].section[j].extent[k]; 431662306a36Sopenharmony_ci dst_ptr[reg_list_blk_index + k] = cpu_to_le32(data); 431762306a36Sopenharmony_ci } 431862306a36Sopenharmony_ci reg_list_mc_addr += reg_num * 4; 431962306a36Sopenharmony_ci reg_list_blk_index += reg_num; 432062306a36Sopenharmony_ci } 432162306a36Sopenharmony_ci } 432262306a36Sopenharmony_ci dst_ptr[reg_list_hdr_blk_index] = cpu_to_le32(RLC_CLEAR_STATE_END_MARKER); 432362306a36Sopenharmony_ci } 432462306a36Sopenharmony_ci radeon_bo_kunmap(rdev->rlc.clear_state_obj); 432562306a36Sopenharmony_ci radeon_bo_unreserve(rdev->rlc.clear_state_obj); 432662306a36Sopenharmony_ci } 432762306a36Sopenharmony_ci 432862306a36Sopenharmony_ci if (rdev->rlc.cp_table_size) { 432962306a36Sopenharmony_ci if (rdev->rlc.cp_table_obj == NULL) { 433062306a36Sopenharmony_ci r = radeon_bo_create(rdev, rdev->rlc.cp_table_size, 433162306a36Sopenharmony_ci PAGE_SIZE, true, 433262306a36Sopenharmony_ci RADEON_GEM_DOMAIN_VRAM, 0, NULL, 433362306a36Sopenharmony_ci NULL, &rdev->rlc.cp_table_obj); 433462306a36Sopenharmony_ci if (r) { 433562306a36Sopenharmony_ci dev_warn(rdev->dev, "(%d) create RLC cp table bo failed\n", r); 433662306a36Sopenharmony_ci sumo_rlc_fini(rdev); 433762306a36Sopenharmony_ci return r; 433862306a36Sopenharmony_ci } 433962306a36Sopenharmony_ci } 434062306a36Sopenharmony_ci 434162306a36Sopenharmony_ci r = radeon_bo_reserve(rdev->rlc.cp_table_obj, false); 434262306a36Sopenharmony_ci if (unlikely(r != 0)) { 434362306a36Sopenharmony_ci dev_warn(rdev->dev, "(%d) reserve RLC cp table bo failed\n", r); 434462306a36Sopenharmony_ci sumo_rlc_fini(rdev); 434562306a36Sopenharmony_ci return r; 434662306a36Sopenharmony_ci } 434762306a36Sopenharmony_ci r = radeon_bo_pin(rdev->rlc.cp_table_obj, RADEON_GEM_DOMAIN_VRAM, 434862306a36Sopenharmony_ci &rdev->rlc.cp_table_gpu_addr); 434962306a36Sopenharmony_ci if (r) { 435062306a36Sopenharmony_ci radeon_bo_unreserve(rdev->rlc.cp_table_obj); 435162306a36Sopenharmony_ci dev_warn(rdev->dev, "(%d) pin RLC cp_table bo failed\n", r); 435262306a36Sopenharmony_ci sumo_rlc_fini(rdev); 435362306a36Sopenharmony_ci return r; 435462306a36Sopenharmony_ci } 435562306a36Sopenharmony_ci r = radeon_bo_kmap(rdev->rlc.cp_table_obj, (void **)&rdev->rlc.cp_table_ptr); 435662306a36Sopenharmony_ci if (r) { 435762306a36Sopenharmony_ci dev_warn(rdev->dev, "(%d) map RLC cp table bo failed\n", r); 435862306a36Sopenharmony_ci sumo_rlc_fini(rdev); 435962306a36Sopenharmony_ci return r; 436062306a36Sopenharmony_ci } 436162306a36Sopenharmony_ci 436262306a36Sopenharmony_ci cik_init_cp_pg_table(rdev); 436362306a36Sopenharmony_ci 436462306a36Sopenharmony_ci radeon_bo_kunmap(rdev->rlc.cp_table_obj); 436562306a36Sopenharmony_ci radeon_bo_unreserve(rdev->rlc.cp_table_obj); 436662306a36Sopenharmony_ci 436762306a36Sopenharmony_ci } 436862306a36Sopenharmony_ci 436962306a36Sopenharmony_ci return 0; 437062306a36Sopenharmony_ci} 437162306a36Sopenharmony_ci 437262306a36Sopenharmony_cistatic void evergreen_rlc_start(struct radeon_device *rdev) 437362306a36Sopenharmony_ci{ 437462306a36Sopenharmony_ci u32 mask = RLC_ENABLE; 437562306a36Sopenharmony_ci 437662306a36Sopenharmony_ci if (rdev->flags & RADEON_IS_IGP) { 437762306a36Sopenharmony_ci mask |= GFX_POWER_GATING_ENABLE | GFX_POWER_GATING_SRC; 437862306a36Sopenharmony_ci } 437962306a36Sopenharmony_ci 438062306a36Sopenharmony_ci WREG32(RLC_CNTL, mask); 438162306a36Sopenharmony_ci} 438262306a36Sopenharmony_ci 438362306a36Sopenharmony_ciint evergreen_rlc_resume(struct radeon_device *rdev) 438462306a36Sopenharmony_ci{ 438562306a36Sopenharmony_ci u32 i; 438662306a36Sopenharmony_ci const __be32 *fw_data; 438762306a36Sopenharmony_ci 438862306a36Sopenharmony_ci if (!rdev->rlc_fw) 438962306a36Sopenharmony_ci return -EINVAL; 439062306a36Sopenharmony_ci 439162306a36Sopenharmony_ci r600_rlc_stop(rdev); 439262306a36Sopenharmony_ci 439362306a36Sopenharmony_ci WREG32(RLC_HB_CNTL, 0); 439462306a36Sopenharmony_ci 439562306a36Sopenharmony_ci if (rdev->flags & RADEON_IS_IGP) { 439662306a36Sopenharmony_ci if (rdev->family == CHIP_ARUBA) { 439762306a36Sopenharmony_ci u32 always_on_bitmap = 439862306a36Sopenharmony_ci 3 | (3 << (16 * rdev->config.cayman.max_shader_engines)); 439962306a36Sopenharmony_ci /* find out the number of active simds */ 440062306a36Sopenharmony_ci u32 tmp = (RREG32(CC_GC_SHADER_PIPE_CONFIG) & 0xffff0000) >> 16; 440162306a36Sopenharmony_ci tmp |= 0xffffffff << rdev->config.cayman.max_simds_per_se; 440262306a36Sopenharmony_ci tmp = hweight32(~tmp); 440362306a36Sopenharmony_ci if (tmp == rdev->config.cayman.max_simds_per_se) { 440462306a36Sopenharmony_ci WREG32(TN_RLC_LB_ALWAYS_ACTIVE_SIMD_MASK, always_on_bitmap); 440562306a36Sopenharmony_ci WREG32(TN_RLC_LB_PARAMS, 0x00601004); 440662306a36Sopenharmony_ci WREG32(TN_RLC_LB_INIT_SIMD_MASK, 0xffffffff); 440762306a36Sopenharmony_ci WREG32(TN_RLC_LB_CNTR_INIT, 0x00000000); 440862306a36Sopenharmony_ci WREG32(TN_RLC_LB_CNTR_MAX, 0x00002000); 440962306a36Sopenharmony_ci } 441062306a36Sopenharmony_ci } else { 441162306a36Sopenharmony_ci WREG32(RLC_HB_WPTR_LSB_ADDR, 0); 441262306a36Sopenharmony_ci WREG32(RLC_HB_WPTR_MSB_ADDR, 0); 441362306a36Sopenharmony_ci } 441462306a36Sopenharmony_ci WREG32(TN_RLC_SAVE_AND_RESTORE_BASE, rdev->rlc.save_restore_gpu_addr >> 8); 441562306a36Sopenharmony_ci WREG32(TN_RLC_CLEAR_STATE_RESTORE_BASE, rdev->rlc.clear_state_gpu_addr >> 8); 441662306a36Sopenharmony_ci } else { 441762306a36Sopenharmony_ci WREG32(RLC_HB_BASE, 0); 441862306a36Sopenharmony_ci WREG32(RLC_HB_RPTR, 0); 441962306a36Sopenharmony_ci WREG32(RLC_HB_WPTR, 0); 442062306a36Sopenharmony_ci WREG32(RLC_HB_WPTR_LSB_ADDR, 0); 442162306a36Sopenharmony_ci WREG32(RLC_HB_WPTR_MSB_ADDR, 0); 442262306a36Sopenharmony_ci } 442362306a36Sopenharmony_ci WREG32(RLC_MC_CNTL, 0); 442462306a36Sopenharmony_ci WREG32(RLC_UCODE_CNTL, 0); 442562306a36Sopenharmony_ci 442662306a36Sopenharmony_ci fw_data = (const __be32 *)rdev->rlc_fw->data; 442762306a36Sopenharmony_ci if (rdev->family >= CHIP_ARUBA) { 442862306a36Sopenharmony_ci for (i = 0; i < ARUBA_RLC_UCODE_SIZE; i++) { 442962306a36Sopenharmony_ci WREG32(RLC_UCODE_ADDR, i); 443062306a36Sopenharmony_ci WREG32(RLC_UCODE_DATA, be32_to_cpup(fw_data++)); 443162306a36Sopenharmony_ci } 443262306a36Sopenharmony_ci } else if (rdev->family >= CHIP_CAYMAN) { 443362306a36Sopenharmony_ci for (i = 0; i < CAYMAN_RLC_UCODE_SIZE; i++) { 443462306a36Sopenharmony_ci WREG32(RLC_UCODE_ADDR, i); 443562306a36Sopenharmony_ci WREG32(RLC_UCODE_DATA, be32_to_cpup(fw_data++)); 443662306a36Sopenharmony_ci } 443762306a36Sopenharmony_ci } else { 443862306a36Sopenharmony_ci for (i = 0; i < EVERGREEN_RLC_UCODE_SIZE; i++) { 443962306a36Sopenharmony_ci WREG32(RLC_UCODE_ADDR, i); 444062306a36Sopenharmony_ci WREG32(RLC_UCODE_DATA, be32_to_cpup(fw_data++)); 444162306a36Sopenharmony_ci } 444262306a36Sopenharmony_ci } 444362306a36Sopenharmony_ci WREG32(RLC_UCODE_ADDR, 0); 444462306a36Sopenharmony_ci 444562306a36Sopenharmony_ci evergreen_rlc_start(rdev); 444662306a36Sopenharmony_ci 444762306a36Sopenharmony_ci return 0; 444862306a36Sopenharmony_ci} 444962306a36Sopenharmony_ci 445062306a36Sopenharmony_ci/* Interrupts */ 445162306a36Sopenharmony_ci 445262306a36Sopenharmony_ciu32 evergreen_get_vblank_counter(struct radeon_device *rdev, int crtc) 445362306a36Sopenharmony_ci{ 445462306a36Sopenharmony_ci if (crtc >= rdev->num_crtc) 445562306a36Sopenharmony_ci return 0; 445662306a36Sopenharmony_ci else 445762306a36Sopenharmony_ci return RREG32(CRTC_STATUS_FRAME_COUNT + crtc_offsets[crtc]); 445862306a36Sopenharmony_ci} 445962306a36Sopenharmony_ci 446062306a36Sopenharmony_civoid evergreen_disable_interrupt_state(struct radeon_device *rdev) 446162306a36Sopenharmony_ci{ 446262306a36Sopenharmony_ci int i; 446362306a36Sopenharmony_ci u32 tmp; 446462306a36Sopenharmony_ci 446562306a36Sopenharmony_ci if (rdev->family >= CHIP_CAYMAN) { 446662306a36Sopenharmony_ci cayman_cp_int_cntl_setup(rdev, 0, 446762306a36Sopenharmony_ci CNTX_BUSY_INT_ENABLE | CNTX_EMPTY_INT_ENABLE); 446862306a36Sopenharmony_ci cayman_cp_int_cntl_setup(rdev, 1, 0); 446962306a36Sopenharmony_ci cayman_cp_int_cntl_setup(rdev, 2, 0); 447062306a36Sopenharmony_ci tmp = RREG32(CAYMAN_DMA1_CNTL) & ~TRAP_ENABLE; 447162306a36Sopenharmony_ci WREG32(CAYMAN_DMA1_CNTL, tmp); 447262306a36Sopenharmony_ci } else 447362306a36Sopenharmony_ci WREG32(CP_INT_CNTL, CNTX_BUSY_INT_ENABLE | CNTX_EMPTY_INT_ENABLE); 447462306a36Sopenharmony_ci tmp = RREG32(DMA_CNTL) & ~TRAP_ENABLE; 447562306a36Sopenharmony_ci WREG32(DMA_CNTL, tmp); 447662306a36Sopenharmony_ci WREG32(GRBM_INT_CNTL, 0); 447762306a36Sopenharmony_ci WREG32(SRBM_INT_CNTL, 0); 447862306a36Sopenharmony_ci for (i = 0; i < rdev->num_crtc; i++) 447962306a36Sopenharmony_ci WREG32(INT_MASK + crtc_offsets[i], 0); 448062306a36Sopenharmony_ci for (i = 0; i < rdev->num_crtc; i++) 448162306a36Sopenharmony_ci WREG32(GRPH_INT_CONTROL + crtc_offsets[i], 0); 448262306a36Sopenharmony_ci 448362306a36Sopenharmony_ci /* only one DAC on DCE5 */ 448462306a36Sopenharmony_ci if (!ASIC_IS_DCE5(rdev)) 448562306a36Sopenharmony_ci WREG32(DACA_AUTODETECT_INT_CONTROL, 0); 448662306a36Sopenharmony_ci WREG32(DACB_AUTODETECT_INT_CONTROL, 0); 448762306a36Sopenharmony_ci 448862306a36Sopenharmony_ci for (i = 0; i < 6; i++) 448962306a36Sopenharmony_ci WREG32_AND(DC_HPDx_INT_CONTROL(i), DC_HPDx_INT_POLARITY); 449062306a36Sopenharmony_ci} 449162306a36Sopenharmony_ci 449262306a36Sopenharmony_ci/* Note that the order we write back regs here is important */ 449362306a36Sopenharmony_ciint evergreen_irq_set(struct radeon_device *rdev) 449462306a36Sopenharmony_ci{ 449562306a36Sopenharmony_ci int i; 449662306a36Sopenharmony_ci u32 cp_int_cntl = CNTX_BUSY_INT_ENABLE | CNTX_EMPTY_INT_ENABLE; 449762306a36Sopenharmony_ci u32 cp_int_cntl1 = 0, cp_int_cntl2 = 0; 449862306a36Sopenharmony_ci u32 grbm_int_cntl = 0; 449962306a36Sopenharmony_ci u32 dma_cntl, dma_cntl1 = 0; 450062306a36Sopenharmony_ci u32 thermal_int = 0; 450162306a36Sopenharmony_ci 450262306a36Sopenharmony_ci if (!rdev->irq.installed) { 450362306a36Sopenharmony_ci WARN(1, "Can't enable IRQ/MSI because no handler is installed\n"); 450462306a36Sopenharmony_ci return -EINVAL; 450562306a36Sopenharmony_ci } 450662306a36Sopenharmony_ci /* don't enable anything if the ih is disabled */ 450762306a36Sopenharmony_ci if (!rdev->ih.enabled) { 450862306a36Sopenharmony_ci r600_disable_interrupts(rdev); 450962306a36Sopenharmony_ci /* force the active interrupt state to all disabled */ 451062306a36Sopenharmony_ci evergreen_disable_interrupt_state(rdev); 451162306a36Sopenharmony_ci return 0; 451262306a36Sopenharmony_ci } 451362306a36Sopenharmony_ci 451462306a36Sopenharmony_ci if (rdev->family == CHIP_ARUBA) 451562306a36Sopenharmony_ci thermal_int = RREG32(TN_CG_THERMAL_INT_CTRL) & 451662306a36Sopenharmony_ci ~(THERM_INT_MASK_HIGH | THERM_INT_MASK_LOW); 451762306a36Sopenharmony_ci else 451862306a36Sopenharmony_ci thermal_int = RREG32(CG_THERMAL_INT) & 451962306a36Sopenharmony_ci ~(THERM_INT_MASK_HIGH | THERM_INT_MASK_LOW); 452062306a36Sopenharmony_ci 452162306a36Sopenharmony_ci dma_cntl = RREG32(DMA_CNTL) & ~TRAP_ENABLE; 452262306a36Sopenharmony_ci 452362306a36Sopenharmony_ci if (rdev->family >= CHIP_CAYMAN) { 452462306a36Sopenharmony_ci /* enable CP interrupts on all rings */ 452562306a36Sopenharmony_ci if (atomic_read(&rdev->irq.ring_int[RADEON_RING_TYPE_GFX_INDEX])) { 452662306a36Sopenharmony_ci DRM_DEBUG("evergreen_irq_set: sw int gfx\n"); 452762306a36Sopenharmony_ci cp_int_cntl |= TIME_STAMP_INT_ENABLE; 452862306a36Sopenharmony_ci } 452962306a36Sopenharmony_ci if (atomic_read(&rdev->irq.ring_int[CAYMAN_RING_TYPE_CP1_INDEX])) { 453062306a36Sopenharmony_ci DRM_DEBUG("evergreen_irq_set: sw int cp1\n"); 453162306a36Sopenharmony_ci cp_int_cntl1 |= TIME_STAMP_INT_ENABLE; 453262306a36Sopenharmony_ci } 453362306a36Sopenharmony_ci if (atomic_read(&rdev->irq.ring_int[CAYMAN_RING_TYPE_CP2_INDEX])) { 453462306a36Sopenharmony_ci DRM_DEBUG("evergreen_irq_set: sw int cp2\n"); 453562306a36Sopenharmony_ci cp_int_cntl2 |= TIME_STAMP_INT_ENABLE; 453662306a36Sopenharmony_ci } 453762306a36Sopenharmony_ci } else { 453862306a36Sopenharmony_ci if (atomic_read(&rdev->irq.ring_int[RADEON_RING_TYPE_GFX_INDEX])) { 453962306a36Sopenharmony_ci DRM_DEBUG("evergreen_irq_set: sw int gfx\n"); 454062306a36Sopenharmony_ci cp_int_cntl |= RB_INT_ENABLE; 454162306a36Sopenharmony_ci cp_int_cntl |= TIME_STAMP_INT_ENABLE; 454262306a36Sopenharmony_ci } 454362306a36Sopenharmony_ci } 454462306a36Sopenharmony_ci 454562306a36Sopenharmony_ci if (atomic_read(&rdev->irq.ring_int[R600_RING_TYPE_DMA_INDEX])) { 454662306a36Sopenharmony_ci DRM_DEBUG("r600_irq_set: sw int dma\n"); 454762306a36Sopenharmony_ci dma_cntl |= TRAP_ENABLE; 454862306a36Sopenharmony_ci } 454962306a36Sopenharmony_ci 455062306a36Sopenharmony_ci if (rdev->family >= CHIP_CAYMAN) { 455162306a36Sopenharmony_ci dma_cntl1 = RREG32(CAYMAN_DMA1_CNTL) & ~TRAP_ENABLE; 455262306a36Sopenharmony_ci if (atomic_read(&rdev->irq.ring_int[CAYMAN_RING_TYPE_DMA1_INDEX])) { 455362306a36Sopenharmony_ci DRM_DEBUG("r600_irq_set: sw int dma1\n"); 455462306a36Sopenharmony_ci dma_cntl1 |= TRAP_ENABLE; 455562306a36Sopenharmony_ci } 455662306a36Sopenharmony_ci } 455762306a36Sopenharmony_ci 455862306a36Sopenharmony_ci if (rdev->irq.dpm_thermal) { 455962306a36Sopenharmony_ci DRM_DEBUG("dpm thermal\n"); 456062306a36Sopenharmony_ci thermal_int |= THERM_INT_MASK_HIGH | THERM_INT_MASK_LOW; 456162306a36Sopenharmony_ci } 456262306a36Sopenharmony_ci 456362306a36Sopenharmony_ci if (rdev->family >= CHIP_CAYMAN) { 456462306a36Sopenharmony_ci cayman_cp_int_cntl_setup(rdev, 0, cp_int_cntl); 456562306a36Sopenharmony_ci cayman_cp_int_cntl_setup(rdev, 1, cp_int_cntl1); 456662306a36Sopenharmony_ci cayman_cp_int_cntl_setup(rdev, 2, cp_int_cntl2); 456762306a36Sopenharmony_ci } else 456862306a36Sopenharmony_ci WREG32(CP_INT_CNTL, cp_int_cntl); 456962306a36Sopenharmony_ci 457062306a36Sopenharmony_ci WREG32(DMA_CNTL, dma_cntl); 457162306a36Sopenharmony_ci 457262306a36Sopenharmony_ci if (rdev->family >= CHIP_CAYMAN) 457362306a36Sopenharmony_ci WREG32(CAYMAN_DMA1_CNTL, dma_cntl1); 457462306a36Sopenharmony_ci 457562306a36Sopenharmony_ci WREG32(GRBM_INT_CNTL, grbm_int_cntl); 457662306a36Sopenharmony_ci 457762306a36Sopenharmony_ci for (i = 0; i < rdev->num_crtc; i++) { 457862306a36Sopenharmony_ci radeon_irq_kms_set_irq_n_enabled( 457962306a36Sopenharmony_ci rdev, INT_MASK + crtc_offsets[i], 458062306a36Sopenharmony_ci VBLANK_INT_MASK, 458162306a36Sopenharmony_ci rdev->irq.crtc_vblank_int[i] || 458262306a36Sopenharmony_ci atomic_read(&rdev->irq.pflip[i]), "vblank", i); 458362306a36Sopenharmony_ci } 458462306a36Sopenharmony_ci 458562306a36Sopenharmony_ci for (i = 0; i < rdev->num_crtc; i++) 458662306a36Sopenharmony_ci WREG32(GRPH_INT_CONTROL + crtc_offsets[i], GRPH_PFLIP_INT_MASK); 458762306a36Sopenharmony_ci 458862306a36Sopenharmony_ci for (i = 0; i < 6; i++) { 458962306a36Sopenharmony_ci radeon_irq_kms_set_irq_n_enabled( 459062306a36Sopenharmony_ci rdev, DC_HPDx_INT_CONTROL(i), 459162306a36Sopenharmony_ci DC_HPDx_INT_EN | DC_HPDx_RX_INT_EN, 459262306a36Sopenharmony_ci rdev->irq.hpd[i], "HPD", i); 459362306a36Sopenharmony_ci } 459462306a36Sopenharmony_ci 459562306a36Sopenharmony_ci if (rdev->family == CHIP_ARUBA) 459662306a36Sopenharmony_ci WREG32(TN_CG_THERMAL_INT_CTRL, thermal_int); 459762306a36Sopenharmony_ci else 459862306a36Sopenharmony_ci WREG32(CG_THERMAL_INT, thermal_int); 459962306a36Sopenharmony_ci 460062306a36Sopenharmony_ci for (i = 0; i < 6; i++) { 460162306a36Sopenharmony_ci radeon_irq_kms_set_irq_n_enabled( 460262306a36Sopenharmony_ci rdev, AFMT_AUDIO_PACKET_CONTROL + crtc_offsets[i], 460362306a36Sopenharmony_ci AFMT_AZ_FORMAT_WTRIG_MASK, 460462306a36Sopenharmony_ci rdev->irq.afmt[i], "HDMI", i); 460562306a36Sopenharmony_ci } 460662306a36Sopenharmony_ci 460762306a36Sopenharmony_ci /* posting read */ 460862306a36Sopenharmony_ci RREG32(SRBM_STATUS); 460962306a36Sopenharmony_ci 461062306a36Sopenharmony_ci return 0; 461162306a36Sopenharmony_ci} 461262306a36Sopenharmony_ci 461362306a36Sopenharmony_ci/* Note that the order we write back regs here is important */ 461462306a36Sopenharmony_cistatic void evergreen_irq_ack(struct radeon_device *rdev) 461562306a36Sopenharmony_ci{ 461662306a36Sopenharmony_ci int i, j; 461762306a36Sopenharmony_ci u32 *grph_int = rdev->irq.stat_regs.evergreen.grph_int; 461862306a36Sopenharmony_ci u32 *disp_int = rdev->irq.stat_regs.evergreen.disp_int; 461962306a36Sopenharmony_ci u32 *afmt_status = rdev->irq.stat_regs.evergreen.afmt_status; 462062306a36Sopenharmony_ci 462162306a36Sopenharmony_ci for (i = 0; i < 6; i++) { 462262306a36Sopenharmony_ci disp_int[i] = RREG32(evergreen_disp_int_status[i]); 462362306a36Sopenharmony_ci afmt_status[i] = RREG32(AFMT_STATUS + crtc_offsets[i]); 462462306a36Sopenharmony_ci if (i < rdev->num_crtc) 462562306a36Sopenharmony_ci grph_int[i] = RREG32(GRPH_INT_STATUS + crtc_offsets[i]); 462662306a36Sopenharmony_ci } 462762306a36Sopenharmony_ci 462862306a36Sopenharmony_ci /* We write back each interrupt register in pairs of two */ 462962306a36Sopenharmony_ci for (i = 0; i < rdev->num_crtc; i += 2) { 463062306a36Sopenharmony_ci for (j = i; j < (i + 2); j++) { 463162306a36Sopenharmony_ci if (grph_int[j] & GRPH_PFLIP_INT_OCCURRED) 463262306a36Sopenharmony_ci WREG32(GRPH_INT_STATUS + crtc_offsets[j], 463362306a36Sopenharmony_ci GRPH_PFLIP_INT_CLEAR); 463462306a36Sopenharmony_ci } 463562306a36Sopenharmony_ci 463662306a36Sopenharmony_ci for (j = i; j < (i + 2); j++) { 463762306a36Sopenharmony_ci if (disp_int[j] & LB_D1_VBLANK_INTERRUPT) 463862306a36Sopenharmony_ci WREG32(VBLANK_STATUS + crtc_offsets[j], 463962306a36Sopenharmony_ci VBLANK_ACK); 464062306a36Sopenharmony_ci if (disp_int[j] & LB_D1_VLINE_INTERRUPT) 464162306a36Sopenharmony_ci WREG32(VLINE_STATUS + crtc_offsets[j], 464262306a36Sopenharmony_ci VLINE_ACK); 464362306a36Sopenharmony_ci } 464462306a36Sopenharmony_ci } 464562306a36Sopenharmony_ci 464662306a36Sopenharmony_ci for (i = 0; i < 6; i++) { 464762306a36Sopenharmony_ci if (disp_int[i] & DC_HPD1_INTERRUPT) 464862306a36Sopenharmony_ci WREG32_OR(DC_HPDx_INT_CONTROL(i), DC_HPDx_INT_ACK); 464962306a36Sopenharmony_ci } 465062306a36Sopenharmony_ci 465162306a36Sopenharmony_ci for (i = 0; i < 6; i++) { 465262306a36Sopenharmony_ci if (disp_int[i] & DC_HPD1_RX_INTERRUPT) 465362306a36Sopenharmony_ci WREG32_OR(DC_HPDx_INT_CONTROL(i), DC_HPDx_RX_INT_ACK); 465462306a36Sopenharmony_ci } 465562306a36Sopenharmony_ci 465662306a36Sopenharmony_ci for (i = 0; i < 6; i++) { 465762306a36Sopenharmony_ci if (afmt_status[i] & AFMT_AZ_FORMAT_WTRIG) 465862306a36Sopenharmony_ci WREG32_OR(AFMT_AUDIO_PACKET_CONTROL + crtc_offsets[i], 465962306a36Sopenharmony_ci AFMT_AZ_FORMAT_WTRIG_ACK); 466062306a36Sopenharmony_ci } 466162306a36Sopenharmony_ci} 466262306a36Sopenharmony_ci 466362306a36Sopenharmony_cistatic void evergreen_irq_disable(struct radeon_device *rdev) 466462306a36Sopenharmony_ci{ 466562306a36Sopenharmony_ci r600_disable_interrupts(rdev); 466662306a36Sopenharmony_ci /* Wait and acknowledge irq */ 466762306a36Sopenharmony_ci mdelay(1); 466862306a36Sopenharmony_ci evergreen_irq_ack(rdev); 466962306a36Sopenharmony_ci evergreen_disable_interrupt_state(rdev); 467062306a36Sopenharmony_ci} 467162306a36Sopenharmony_ci 467262306a36Sopenharmony_civoid evergreen_irq_suspend(struct radeon_device *rdev) 467362306a36Sopenharmony_ci{ 467462306a36Sopenharmony_ci evergreen_irq_disable(rdev); 467562306a36Sopenharmony_ci r600_rlc_stop(rdev); 467662306a36Sopenharmony_ci} 467762306a36Sopenharmony_ci 467862306a36Sopenharmony_cistatic u32 evergreen_get_ih_wptr(struct radeon_device *rdev) 467962306a36Sopenharmony_ci{ 468062306a36Sopenharmony_ci u32 wptr, tmp; 468162306a36Sopenharmony_ci 468262306a36Sopenharmony_ci if (rdev->wb.enabled) 468362306a36Sopenharmony_ci wptr = le32_to_cpu(rdev->wb.wb[R600_WB_IH_WPTR_OFFSET/4]); 468462306a36Sopenharmony_ci else 468562306a36Sopenharmony_ci wptr = RREG32(IH_RB_WPTR); 468662306a36Sopenharmony_ci 468762306a36Sopenharmony_ci if (wptr & RB_OVERFLOW) { 468862306a36Sopenharmony_ci wptr &= ~RB_OVERFLOW; 468962306a36Sopenharmony_ci /* When a ring buffer overflow happen start parsing interrupt 469062306a36Sopenharmony_ci * from the last not overwritten vector (wptr + 16). Hopefully 469162306a36Sopenharmony_ci * this should allow us to catchup. 469262306a36Sopenharmony_ci */ 469362306a36Sopenharmony_ci dev_warn(rdev->dev, "IH ring buffer overflow (0x%08X, 0x%08X, 0x%08X)\n", 469462306a36Sopenharmony_ci wptr, rdev->ih.rptr, (wptr + 16) & rdev->ih.ptr_mask); 469562306a36Sopenharmony_ci rdev->ih.rptr = (wptr + 16) & rdev->ih.ptr_mask; 469662306a36Sopenharmony_ci tmp = RREG32(IH_RB_CNTL); 469762306a36Sopenharmony_ci tmp |= IH_WPTR_OVERFLOW_CLEAR; 469862306a36Sopenharmony_ci WREG32(IH_RB_CNTL, tmp); 469962306a36Sopenharmony_ci } 470062306a36Sopenharmony_ci return (wptr & rdev->ih.ptr_mask); 470162306a36Sopenharmony_ci} 470262306a36Sopenharmony_ci 470362306a36Sopenharmony_ciint evergreen_irq_process(struct radeon_device *rdev) 470462306a36Sopenharmony_ci{ 470562306a36Sopenharmony_ci u32 *disp_int = rdev->irq.stat_regs.evergreen.disp_int; 470662306a36Sopenharmony_ci u32 *afmt_status = rdev->irq.stat_regs.evergreen.afmt_status; 470762306a36Sopenharmony_ci u32 crtc_idx, hpd_idx, afmt_idx; 470862306a36Sopenharmony_ci u32 mask; 470962306a36Sopenharmony_ci u32 wptr; 471062306a36Sopenharmony_ci u32 rptr; 471162306a36Sopenharmony_ci u32 src_id, src_data; 471262306a36Sopenharmony_ci u32 ring_index; 471362306a36Sopenharmony_ci bool queue_hotplug = false; 471462306a36Sopenharmony_ci bool queue_hdmi = false; 471562306a36Sopenharmony_ci bool queue_dp = false; 471662306a36Sopenharmony_ci bool queue_thermal = false; 471762306a36Sopenharmony_ci u32 status, addr; 471862306a36Sopenharmony_ci const char *event_name; 471962306a36Sopenharmony_ci 472062306a36Sopenharmony_ci if (!rdev->ih.enabled || rdev->shutdown) 472162306a36Sopenharmony_ci return IRQ_NONE; 472262306a36Sopenharmony_ci 472362306a36Sopenharmony_ci wptr = evergreen_get_ih_wptr(rdev); 472462306a36Sopenharmony_ci 472562306a36Sopenharmony_cirestart_ih: 472662306a36Sopenharmony_ci /* is somebody else already processing irqs? */ 472762306a36Sopenharmony_ci if (atomic_xchg(&rdev->ih.lock, 1)) 472862306a36Sopenharmony_ci return IRQ_NONE; 472962306a36Sopenharmony_ci 473062306a36Sopenharmony_ci rptr = rdev->ih.rptr; 473162306a36Sopenharmony_ci DRM_DEBUG("evergreen_irq_process start: rptr %d, wptr %d\n", rptr, wptr); 473262306a36Sopenharmony_ci 473362306a36Sopenharmony_ci /* Order reading of wptr vs. reading of IH ring data */ 473462306a36Sopenharmony_ci rmb(); 473562306a36Sopenharmony_ci 473662306a36Sopenharmony_ci /* display interrupts */ 473762306a36Sopenharmony_ci evergreen_irq_ack(rdev); 473862306a36Sopenharmony_ci 473962306a36Sopenharmony_ci while (rptr != wptr) { 474062306a36Sopenharmony_ci /* wptr/rptr are in bytes! */ 474162306a36Sopenharmony_ci ring_index = rptr / 4; 474262306a36Sopenharmony_ci src_id = le32_to_cpu(rdev->ih.ring[ring_index]) & 0xff; 474362306a36Sopenharmony_ci src_data = le32_to_cpu(rdev->ih.ring[ring_index + 1]) & 0xfffffff; 474462306a36Sopenharmony_ci 474562306a36Sopenharmony_ci switch (src_id) { 474662306a36Sopenharmony_ci case 1: /* D1 vblank/vline */ 474762306a36Sopenharmony_ci case 2: /* D2 vblank/vline */ 474862306a36Sopenharmony_ci case 3: /* D3 vblank/vline */ 474962306a36Sopenharmony_ci case 4: /* D4 vblank/vline */ 475062306a36Sopenharmony_ci case 5: /* D5 vblank/vline */ 475162306a36Sopenharmony_ci case 6: /* D6 vblank/vline */ 475262306a36Sopenharmony_ci crtc_idx = src_id - 1; 475362306a36Sopenharmony_ci 475462306a36Sopenharmony_ci if (src_data == 0) { /* vblank */ 475562306a36Sopenharmony_ci mask = LB_D1_VBLANK_INTERRUPT; 475662306a36Sopenharmony_ci event_name = "vblank"; 475762306a36Sopenharmony_ci 475862306a36Sopenharmony_ci if (rdev->irq.crtc_vblank_int[crtc_idx]) { 475962306a36Sopenharmony_ci drm_handle_vblank(rdev->ddev, crtc_idx); 476062306a36Sopenharmony_ci rdev->pm.vblank_sync = true; 476162306a36Sopenharmony_ci wake_up(&rdev->irq.vblank_queue); 476262306a36Sopenharmony_ci } 476362306a36Sopenharmony_ci if (atomic_read(&rdev->irq.pflip[crtc_idx])) { 476462306a36Sopenharmony_ci radeon_crtc_handle_vblank(rdev, 476562306a36Sopenharmony_ci crtc_idx); 476662306a36Sopenharmony_ci } 476762306a36Sopenharmony_ci 476862306a36Sopenharmony_ci } else if (src_data == 1) { /* vline */ 476962306a36Sopenharmony_ci mask = LB_D1_VLINE_INTERRUPT; 477062306a36Sopenharmony_ci event_name = "vline"; 477162306a36Sopenharmony_ci } else { 477262306a36Sopenharmony_ci DRM_DEBUG("Unhandled interrupt: %d %d\n", 477362306a36Sopenharmony_ci src_id, src_data); 477462306a36Sopenharmony_ci break; 477562306a36Sopenharmony_ci } 477662306a36Sopenharmony_ci 477762306a36Sopenharmony_ci if (!(disp_int[crtc_idx] & mask)) { 477862306a36Sopenharmony_ci DRM_DEBUG("IH: D%d %s - IH event w/o asserted irq bit?\n", 477962306a36Sopenharmony_ci crtc_idx + 1, event_name); 478062306a36Sopenharmony_ci } 478162306a36Sopenharmony_ci 478262306a36Sopenharmony_ci disp_int[crtc_idx] &= ~mask; 478362306a36Sopenharmony_ci DRM_DEBUG("IH: D%d %s\n", crtc_idx + 1, event_name); 478462306a36Sopenharmony_ci 478562306a36Sopenharmony_ci break; 478662306a36Sopenharmony_ci case 8: /* D1 page flip */ 478762306a36Sopenharmony_ci case 10: /* D2 page flip */ 478862306a36Sopenharmony_ci case 12: /* D3 page flip */ 478962306a36Sopenharmony_ci case 14: /* D4 page flip */ 479062306a36Sopenharmony_ci case 16: /* D5 page flip */ 479162306a36Sopenharmony_ci case 18: /* D6 page flip */ 479262306a36Sopenharmony_ci DRM_DEBUG("IH: D%d flip\n", ((src_id - 8) >> 1) + 1); 479362306a36Sopenharmony_ci if (radeon_use_pflipirq > 0) 479462306a36Sopenharmony_ci radeon_crtc_handle_flip(rdev, (src_id - 8) >> 1); 479562306a36Sopenharmony_ci break; 479662306a36Sopenharmony_ci case 42: /* HPD hotplug */ 479762306a36Sopenharmony_ci if (src_data <= 5) { 479862306a36Sopenharmony_ci hpd_idx = src_data; 479962306a36Sopenharmony_ci mask = DC_HPD1_INTERRUPT; 480062306a36Sopenharmony_ci queue_hotplug = true; 480162306a36Sopenharmony_ci event_name = "HPD"; 480262306a36Sopenharmony_ci 480362306a36Sopenharmony_ci } else if (src_data <= 11) { 480462306a36Sopenharmony_ci hpd_idx = src_data - 6; 480562306a36Sopenharmony_ci mask = DC_HPD1_RX_INTERRUPT; 480662306a36Sopenharmony_ci queue_dp = true; 480762306a36Sopenharmony_ci event_name = "HPD_RX"; 480862306a36Sopenharmony_ci 480962306a36Sopenharmony_ci } else { 481062306a36Sopenharmony_ci DRM_DEBUG("Unhandled interrupt: %d %d\n", 481162306a36Sopenharmony_ci src_id, src_data); 481262306a36Sopenharmony_ci break; 481362306a36Sopenharmony_ci } 481462306a36Sopenharmony_ci 481562306a36Sopenharmony_ci if (!(disp_int[hpd_idx] & mask)) 481662306a36Sopenharmony_ci DRM_DEBUG("IH: IH event w/o asserted irq bit?\n"); 481762306a36Sopenharmony_ci 481862306a36Sopenharmony_ci disp_int[hpd_idx] &= ~mask; 481962306a36Sopenharmony_ci DRM_DEBUG("IH: %s%d\n", event_name, hpd_idx + 1); 482062306a36Sopenharmony_ci 482162306a36Sopenharmony_ci break; 482262306a36Sopenharmony_ci case 44: /* hdmi */ 482362306a36Sopenharmony_ci afmt_idx = src_data; 482462306a36Sopenharmony_ci if (afmt_idx > 5) { 482562306a36Sopenharmony_ci DRM_ERROR("Unhandled interrupt: %d %d\n", 482662306a36Sopenharmony_ci src_id, src_data); 482762306a36Sopenharmony_ci break; 482862306a36Sopenharmony_ci } 482962306a36Sopenharmony_ci 483062306a36Sopenharmony_ci if (!(afmt_status[afmt_idx] & AFMT_AZ_FORMAT_WTRIG)) 483162306a36Sopenharmony_ci DRM_DEBUG("IH: IH event w/o asserted irq bit?\n"); 483262306a36Sopenharmony_ci 483362306a36Sopenharmony_ci afmt_status[afmt_idx] &= ~AFMT_AZ_FORMAT_WTRIG; 483462306a36Sopenharmony_ci queue_hdmi = true; 483562306a36Sopenharmony_ci DRM_DEBUG("IH: HDMI%d\n", afmt_idx + 1); 483662306a36Sopenharmony_ci break; 483762306a36Sopenharmony_ci case 96: 483862306a36Sopenharmony_ci DRM_ERROR("SRBM_READ_ERROR: 0x%x\n", RREG32(SRBM_READ_ERROR)); 483962306a36Sopenharmony_ci WREG32(SRBM_INT_ACK, 0x1); 484062306a36Sopenharmony_ci break; 484162306a36Sopenharmony_ci case 124: /* UVD */ 484262306a36Sopenharmony_ci DRM_DEBUG("IH: UVD int: 0x%08x\n", src_data); 484362306a36Sopenharmony_ci radeon_fence_process(rdev, R600_RING_TYPE_UVD_INDEX); 484462306a36Sopenharmony_ci break; 484562306a36Sopenharmony_ci case 146: 484662306a36Sopenharmony_ci case 147: 484762306a36Sopenharmony_ci addr = RREG32(VM_CONTEXT1_PROTECTION_FAULT_ADDR); 484862306a36Sopenharmony_ci status = RREG32(VM_CONTEXT1_PROTECTION_FAULT_STATUS); 484962306a36Sopenharmony_ci /* reset addr and status */ 485062306a36Sopenharmony_ci WREG32_P(VM_CONTEXT1_CNTL2, 1, ~1); 485162306a36Sopenharmony_ci if (addr == 0x0 && status == 0x0) 485262306a36Sopenharmony_ci break; 485362306a36Sopenharmony_ci dev_err(rdev->dev, "GPU fault detected: %d 0x%08x\n", src_id, src_data); 485462306a36Sopenharmony_ci dev_err(rdev->dev, " VM_CONTEXT1_PROTECTION_FAULT_ADDR 0x%08X\n", 485562306a36Sopenharmony_ci addr); 485662306a36Sopenharmony_ci dev_err(rdev->dev, " VM_CONTEXT1_PROTECTION_FAULT_STATUS 0x%08X\n", 485762306a36Sopenharmony_ci status); 485862306a36Sopenharmony_ci cayman_vm_decode_fault(rdev, status, addr); 485962306a36Sopenharmony_ci break; 486062306a36Sopenharmony_ci case 176: /* CP_INT in ring buffer */ 486162306a36Sopenharmony_ci case 177: /* CP_INT in IB1 */ 486262306a36Sopenharmony_ci case 178: /* CP_INT in IB2 */ 486362306a36Sopenharmony_ci DRM_DEBUG("IH: CP int: 0x%08x\n", src_data); 486462306a36Sopenharmony_ci radeon_fence_process(rdev, RADEON_RING_TYPE_GFX_INDEX); 486562306a36Sopenharmony_ci break; 486662306a36Sopenharmony_ci case 181: /* CP EOP event */ 486762306a36Sopenharmony_ci DRM_DEBUG("IH: CP EOP\n"); 486862306a36Sopenharmony_ci if (rdev->family >= CHIP_CAYMAN) { 486962306a36Sopenharmony_ci switch (src_data) { 487062306a36Sopenharmony_ci case 0: 487162306a36Sopenharmony_ci radeon_fence_process(rdev, RADEON_RING_TYPE_GFX_INDEX); 487262306a36Sopenharmony_ci break; 487362306a36Sopenharmony_ci case 1: 487462306a36Sopenharmony_ci radeon_fence_process(rdev, CAYMAN_RING_TYPE_CP1_INDEX); 487562306a36Sopenharmony_ci break; 487662306a36Sopenharmony_ci case 2: 487762306a36Sopenharmony_ci radeon_fence_process(rdev, CAYMAN_RING_TYPE_CP2_INDEX); 487862306a36Sopenharmony_ci break; 487962306a36Sopenharmony_ci } 488062306a36Sopenharmony_ci } else 488162306a36Sopenharmony_ci radeon_fence_process(rdev, RADEON_RING_TYPE_GFX_INDEX); 488262306a36Sopenharmony_ci break; 488362306a36Sopenharmony_ci case 224: /* DMA trap event */ 488462306a36Sopenharmony_ci DRM_DEBUG("IH: DMA trap\n"); 488562306a36Sopenharmony_ci radeon_fence_process(rdev, R600_RING_TYPE_DMA_INDEX); 488662306a36Sopenharmony_ci break; 488762306a36Sopenharmony_ci case 230: /* thermal low to high */ 488862306a36Sopenharmony_ci DRM_DEBUG("IH: thermal low to high\n"); 488962306a36Sopenharmony_ci rdev->pm.dpm.thermal.high_to_low = false; 489062306a36Sopenharmony_ci queue_thermal = true; 489162306a36Sopenharmony_ci break; 489262306a36Sopenharmony_ci case 231: /* thermal high to low */ 489362306a36Sopenharmony_ci DRM_DEBUG("IH: thermal high to low\n"); 489462306a36Sopenharmony_ci rdev->pm.dpm.thermal.high_to_low = true; 489562306a36Sopenharmony_ci queue_thermal = true; 489662306a36Sopenharmony_ci break; 489762306a36Sopenharmony_ci case 233: /* GUI IDLE */ 489862306a36Sopenharmony_ci DRM_DEBUG("IH: GUI idle\n"); 489962306a36Sopenharmony_ci break; 490062306a36Sopenharmony_ci case 244: /* DMA trap event */ 490162306a36Sopenharmony_ci if (rdev->family >= CHIP_CAYMAN) { 490262306a36Sopenharmony_ci DRM_DEBUG("IH: DMA1 trap\n"); 490362306a36Sopenharmony_ci radeon_fence_process(rdev, CAYMAN_RING_TYPE_DMA1_INDEX); 490462306a36Sopenharmony_ci } 490562306a36Sopenharmony_ci break; 490662306a36Sopenharmony_ci default: 490762306a36Sopenharmony_ci DRM_DEBUG("Unhandled interrupt: %d %d\n", src_id, src_data); 490862306a36Sopenharmony_ci break; 490962306a36Sopenharmony_ci } 491062306a36Sopenharmony_ci 491162306a36Sopenharmony_ci /* wptr/rptr are in bytes! */ 491262306a36Sopenharmony_ci rptr += 16; 491362306a36Sopenharmony_ci rptr &= rdev->ih.ptr_mask; 491462306a36Sopenharmony_ci WREG32(IH_RB_RPTR, rptr); 491562306a36Sopenharmony_ci } 491662306a36Sopenharmony_ci if (queue_dp) 491762306a36Sopenharmony_ci schedule_work(&rdev->dp_work); 491862306a36Sopenharmony_ci if (queue_hotplug) 491962306a36Sopenharmony_ci schedule_delayed_work(&rdev->hotplug_work, 0); 492062306a36Sopenharmony_ci if (queue_hdmi) 492162306a36Sopenharmony_ci schedule_work(&rdev->audio_work); 492262306a36Sopenharmony_ci if (queue_thermal && rdev->pm.dpm_enabled) 492362306a36Sopenharmony_ci schedule_work(&rdev->pm.dpm.thermal.work); 492462306a36Sopenharmony_ci rdev->ih.rptr = rptr; 492562306a36Sopenharmony_ci atomic_set(&rdev->ih.lock, 0); 492662306a36Sopenharmony_ci 492762306a36Sopenharmony_ci /* make sure wptr hasn't changed while processing */ 492862306a36Sopenharmony_ci wptr = evergreen_get_ih_wptr(rdev); 492962306a36Sopenharmony_ci if (wptr != rptr) 493062306a36Sopenharmony_ci goto restart_ih; 493162306a36Sopenharmony_ci 493262306a36Sopenharmony_ci return IRQ_HANDLED; 493362306a36Sopenharmony_ci} 493462306a36Sopenharmony_ci 493562306a36Sopenharmony_cistatic void evergreen_uvd_init(struct radeon_device *rdev) 493662306a36Sopenharmony_ci{ 493762306a36Sopenharmony_ci int r; 493862306a36Sopenharmony_ci 493962306a36Sopenharmony_ci if (!rdev->has_uvd) 494062306a36Sopenharmony_ci return; 494162306a36Sopenharmony_ci 494262306a36Sopenharmony_ci r = radeon_uvd_init(rdev); 494362306a36Sopenharmony_ci if (r) { 494462306a36Sopenharmony_ci dev_err(rdev->dev, "failed UVD (%d) init.\n", r); 494562306a36Sopenharmony_ci /* 494662306a36Sopenharmony_ci * At this point rdev->uvd.vcpu_bo is NULL which trickles down 494762306a36Sopenharmony_ci * to early fails uvd_v2_2_resume() and thus nothing happens 494862306a36Sopenharmony_ci * there. So it is pointless to try to go through that code 494962306a36Sopenharmony_ci * hence why we disable uvd here. 495062306a36Sopenharmony_ci */ 495162306a36Sopenharmony_ci rdev->has_uvd = false; 495262306a36Sopenharmony_ci return; 495362306a36Sopenharmony_ci } 495462306a36Sopenharmony_ci rdev->ring[R600_RING_TYPE_UVD_INDEX].ring_obj = NULL; 495562306a36Sopenharmony_ci r600_ring_init(rdev, &rdev->ring[R600_RING_TYPE_UVD_INDEX], 4096); 495662306a36Sopenharmony_ci} 495762306a36Sopenharmony_ci 495862306a36Sopenharmony_cistatic void evergreen_uvd_start(struct radeon_device *rdev) 495962306a36Sopenharmony_ci{ 496062306a36Sopenharmony_ci int r; 496162306a36Sopenharmony_ci 496262306a36Sopenharmony_ci if (!rdev->has_uvd) 496362306a36Sopenharmony_ci return; 496462306a36Sopenharmony_ci 496562306a36Sopenharmony_ci r = uvd_v2_2_resume(rdev); 496662306a36Sopenharmony_ci if (r) { 496762306a36Sopenharmony_ci dev_err(rdev->dev, "failed UVD resume (%d).\n", r); 496862306a36Sopenharmony_ci goto error; 496962306a36Sopenharmony_ci } 497062306a36Sopenharmony_ci r = radeon_fence_driver_start_ring(rdev, R600_RING_TYPE_UVD_INDEX); 497162306a36Sopenharmony_ci if (r) { 497262306a36Sopenharmony_ci dev_err(rdev->dev, "failed initializing UVD fences (%d).\n", r); 497362306a36Sopenharmony_ci goto error; 497462306a36Sopenharmony_ci } 497562306a36Sopenharmony_ci return; 497662306a36Sopenharmony_ci 497762306a36Sopenharmony_cierror: 497862306a36Sopenharmony_ci rdev->ring[R600_RING_TYPE_UVD_INDEX].ring_size = 0; 497962306a36Sopenharmony_ci} 498062306a36Sopenharmony_ci 498162306a36Sopenharmony_cistatic void evergreen_uvd_resume(struct radeon_device *rdev) 498262306a36Sopenharmony_ci{ 498362306a36Sopenharmony_ci struct radeon_ring *ring; 498462306a36Sopenharmony_ci int r; 498562306a36Sopenharmony_ci 498662306a36Sopenharmony_ci if (!rdev->has_uvd || !rdev->ring[R600_RING_TYPE_UVD_INDEX].ring_size) 498762306a36Sopenharmony_ci return; 498862306a36Sopenharmony_ci 498962306a36Sopenharmony_ci ring = &rdev->ring[R600_RING_TYPE_UVD_INDEX]; 499062306a36Sopenharmony_ci r = radeon_ring_init(rdev, ring, ring->ring_size, 0, PACKET0(UVD_NO_OP, 0)); 499162306a36Sopenharmony_ci if (r) { 499262306a36Sopenharmony_ci dev_err(rdev->dev, "failed initializing UVD ring (%d).\n", r); 499362306a36Sopenharmony_ci return; 499462306a36Sopenharmony_ci } 499562306a36Sopenharmony_ci r = uvd_v1_0_init(rdev); 499662306a36Sopenharmony_ci if (r) { 499762306a36Sopenharmony_ci dev_err(rdev->dev, "failed initializing UVD (%d).\n", r); 499862306a36Sopenharmony_ci return; 499962306a36Sopenharmony_ci } 500062306a36Sopenharmony_ci} 500162306a36Sopenharmony_ci 500262306a36Sopenharmony_cistatic int evergreen_startup(struct radeon_device *rdev) 500362306a36Sopenharmony_ci{ 500462306a36Sopenharmony_ci struct radeon_ring *ring; 500562306a36Sopenharmony_ci int r; 500662306a36Sopenharmony_ci 500762306a36Sopenharmony_ci /* enable pcie gen2 link */ 500862306a36Sopenharmony_ci evergreen_pcie_gen2_enable(rdev); 500962306a36Sopenharmony_ci /* enable aspm */ 501062306a36Sopenharmony_ci evergreen_program_aspm(rdev); 501162306a36Sopenharmony_ci 501262306a36Sopenharmony_ci /* scratch needs to be initialized before MC */ 501362306a36Sopenharmony_ci r = r600_vram_scratch_init(rdev); 501462306a36Sopenharmony_ci if (r) 501562306a36Sopenharmony_ci return r; 501662306a36Sopenharmony_ci 501762306a36Sopenharmony_ci evergreen_mc_program(rdev); 501862306a36Sopenharmony_ci 501962306a36Sopenharmony_ci if (ASIC_IS_DCE5(rdev) && !rdev->pm.dpm_enabled) { 502062306a36Sopenharmony_ci r = ni_mc_load_microcode(rdev); 502162306a36Sopenharmony_ci if (r) { 502262306a36Sopenharmony_ci DRM_ERROR("Failed to load MC firmware!\n"); 502362306a36Sopenharmony_ci return r; 502462306a36Sopenharmony_ci } 502562306a36Sopenharmony_ci } 502662306a36Sopenharmony_ci 502762306a36Sopenharmony_ci if (rdev->flags & RADEON_IS_AGP) { 502862306a36Sopenharmony_ci evergreen_agp_enable(rdev); 502962306a36Sopenharmony_ci } else { 503062306a36Sopenharmony_ci r = evergreen_pcie_gart_enable(rdev); 503162306a36Sopenharmony_ci if (r) 503262306a36Sopenharmony_ci return r; 503362306a36Sopenharmony_ci } 503462306a36Sopenharmony_ci evergreen_gpu_init(rdev); 503562306a36Sopenharmony_ci 503662306a36Sopenharmony_ci /* allocate rlc buffers */ 503762306a36Sopenharmony_ci if (rdev->flags & RADEON_IS_IGP) { 503862306a36Sopenharmony_ci rdev->rlc.reg_list = sumo_rlc_save_restore_register_list; 503962306a36Sopenharmony_ci rdev->rlc.reg_list_size = 504062306a36Sopenharmony_ci (u32)ARRAY_SIZE(sumo_rlc_save_restore_register_list); 504162306a36Sopenharmony_ci rdev->rlc.cs_data = evergreen_cs_data; 504262306a36Sopenharmony_ci r = sumo_rlc_init(rdev); 504362306a36Sopenharmony_ci if (r) { 504462306a36Sopenharmony_ci DRM_ERROR("Failed to init rlc BOs!\n"); 504562306a36Sopenharmony_ci return r; 504662306a36Sopenharmony_ci } 504762306a36Sopenharmony_ci } 504862306a36Sopenharmony_ci 504962306a36Sopenharmony_ci /* allocate wb buffer */ 505062306a36Sopenharmony_ci r = radeon_wb_init(rdev); 505162306a36Sopenharmony_ci if (r) 505262306a36Sopenharmony_ci return r; 505362306a36Sopenharmony_ci 505462306a36Sopenharmony_ci r = radeon_fence_driver_start_ring(rdev, RADEON_RING_TYPE_GFX_INDEX); 505562306a36Sopenharmony_ci if (r) { 505662306a36Sopenharmony_ci dev_err(rdev->dev, "failed initializing CP fences (%d).\n", r); 505762306a36Sopenharmony_ci return r; 505862306a36Sopenharmony_ci } 505962306a36Sopenharmony_ci 506062306a36Sopenharmony_ci r = radeon_fence_driver_start_ring(rdev, R600_RING_TYPE_DMA_INDEX); 506162306a36Sopenharmony_ci if (r) { 506262306a36Sopenharmony_ci dev_err(rdev->dev, "failed initializing DMA fences (%d).\n", r); 506362306a36Sopenharmony_ci return r; 506462306a36Sopenharmony_ci } 506562306a36Sopenharmony_ci 506662306a36Sopenharmony_ci evergreen_uvd_start(rdev); 506762306a36Sopenharmony_ci 506862306a36Sopenharmony_ci /* Enable IRQ */ 506962306a36Sopenharmony_ci if (!rdev->irq.installed) { 507062306a36Sopenharmony_ci r = radeon_irq_kms_init(rdev); 507162306a36Sopenharmony_ci if (r) 507262306a36Sopenharmony_ci return r; 507362306a36Sopenharmony_ci } 507462306a36Sopenharmony_ci 507562306a36Sopenharmony_ci r = r600_irq_init(rdev); 507662306a36Sopenharmony_ci if (r) { 507762306a36Sopenharmony_ci DRM_ERROR("radeon: IH init failed (%d).\n", r); 507862306a36Sopenharmony_ci radeon_irq_kms_fini(rdev); 507962306a36Sopenharmony_ci return r; 508062306a36Sopenharmony_ci } 508162306a36Sopenharmony_ci evergreen_irq_set(rdev); 508262306a36Sopenharmony_ci 508362306a36Sopenharmony_ci ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]; 508462306a36Sopenharmony_ci r = radeon_ring_init(rdev, ring, ring->ring_size, RADEON_WB_CP_RPTR_OFFSET, 508562306a36Sopenharmony_ci RADEON_CP_PACKET2); 508662306a36Sopenharmony_ci if (r) 508762306a36Sopenharmony_ci return r; 508862306a36Sopenharmony_ci 508962306a36Sopenharmony_ci ring = &rdev->ring[R600_RING_TYPE_DMA_INDEX]; 509062306a36Sopenharmony_ci r = radeon_ring_init(rdev, ring, ring->ring_size, R600_WB_DMA_RPTR_OFFSET, 509162306a36Sopenharmony_ci DMA_PACKET(DMA_PACKET_NOP, 0, 0)); 509262306a36Sopenharmony_ci if (r) 509362306a36Sopenharmony_ci return r; 509462306a36Sopenharmony_ci 509562306a36Sopenharmony_ci r = evergreen_cp_load_microcode(rdev); 509662306a36Sopenharmony_ci if (r) 509762306a36Sopenharmony_ci return r; 509862306a36Sopenharmony_ci r = evergreen_cp_resume(rdev); 509962306a36Sopenharmony_ci if (r) 510062306a36Sopenharmony_ci return r; 510162306a36Sopenharmony_ci r = r600_dma_resume(rdev); 510262306a36Sopenharmony_ci if (r) 510362306a36Sopenharmony_ci return r; 510462306a36Sopenharmony_ci 510562306a36Sopenharmony_ci evergreen_uvd_resume(rdev); 510662306a36Sopenharmony_ci 510762306a36Sopenharmony_ci r = radeon_ib_pool_init(rdev); 510862306a36Sopenharmony_ci if (r) { 510962306a36Sopenharmony_ci dev_err(rdev->dev, "IB initialization failed (%d).\n", r); 511062306a36Sopenharmony_ci return r; 511162306a36Sopenharmony_ci } 511262306a36Sopenharmony_ci 511362306a36Sopenharmony_ci r = radeon_audio_init(rdev); 511462306a36Sopenharmony_ci if (r) { 511562306a36Sopenharmony_ci DRM_ERROR("radeon: audio init failed\n"); 511662306a36Sopenharmony_ci return r; 511762306a36Sopenharmony_ci } 511862306a36Sopenharmony_ci 511962306a36Sopenharmony_ci return 0; 512062306a36Sopenharmony_ci} 512162306a36Sopenharmony_ci 512262306a36Sopenharmony_ciint evergreen_resume(struct radeon_device *rdev) 512362306a36Sopenharmony_ci{ 512462306a36Sopenharmony_ci int r; 512562306a36Sopenharmony_ci 512662306a36Sopenharmony_ci /* reset the asic, the gfx blocks are often in a bad state 512762306a36Sopenharmony_ci * after the driver is unloaded or after a resume 512862306a36Sopenharmony_ci */ 512962306a36Sopenharmony_ci if (radeon_asic_reset(rdev)) 513062306a36Sopenharmony_ci dev_warn(rdev->dev, "GPU reset failed !\n"); 513162306a36Sopenharmony_ci /* Do not reset GPU before posting, on rv770 hw unlike on r500 hw, 513262306a36Sopenharmony_ci * posting will perform necessary task to bring back GPU into good 513362306a36Sopenharmony_ci * shape. 513462306a36Sopenharmony_ci */ 513562306a36Sopenharmony_ci /* post card */ 513662306a36Sopenharmony_ci atom_asic_init(rdev->mode_info.atom_context); 513762306a36Sopenharmony_ci 513862306a36Sopenharmony_ci /* init golden registers */ 513962306a36Sopenharmony_ci evergreen_init_golden_registers(rdev); 514062306a36Sopenharmony_ci 514162306a36Sopenharmony_ci if (rdev->pm.pm_method == PM_METHOD_DPM) 514262306a36Sopenharmony_ci radeon_pm_resume(rdev); 514362306a36Sopenharmony_ci 514462306a36Sopenharmony_ci rdev->accel_working = true; 514562306a36Sopenharmony_ci r = evergreen_startup(rdev); 514662306a36Sopenharmony_ci if (r) { 514762306a36Sopenharmony_ci DRM_ERROR("evergreen startup failed on resume\n"); 514862306a36Sopenharmony_ci rdev->accel_working = false; 514962306a36Sopenharmony_ci return r; 515062306a36Sopenharmony_ci } 515162306a36Sopenharmony_ci 515262306a36Sopenharmony_ci return r; 515362306a36Sopenharmony_ci 515462306a36Sopenharmony_ci} 515562306a36Sopenharmony_ci 515662306a36Sopenharmony_ciint evergreen_suspend(struct radeon_device *rdev) 515762306a36Sopenharmony_ci{ 515862306a36Sopenharmony_ci radeon_pm_suspend(rdev); 515962306a36Sopenharmony_ci radeon_audio_fini(rdev); 516062306a36Sopenharmony_ci if (rdev->has_uvd) { 516162306a36Sopenharmony_ci radeon_uvd_suspend(rdev); 516262306a36Sopenharmony_ci uvd_v1_0_fini(rdev); 516362306a36Sopenharmony_ci } 516462306a36Sopenharmony_ci r700_cp_stop(rdev); 516562306a36Sopenharmony_ci r600_dma_stop(rdev); 516662306a36Sopenharmony_ci evergreen_irq_suspend(rdev); 516762306a36Sopenharmony_ci radeon_wb_disable(rdev); 516862306a36Sopenharmony_ci evergreen_pcie_gart_disable(rdev); 516962306a36Sopenharmony_ci 517062306a36Sopenharmony_ci return 0; 517162306a36Sopenharmony_ci} 517262306a36Sopenharmony_ci 517362306a36Sopenharmony_ci/* Plan is to move initialization in that function and use 517462306a36Sopenharmony_ci * helper function so that radeon_device_init pretty much 517562306a36Sopenharmony_ci * do nothing more than calling asic specific function. This 517662306a36Sopenharmony_ci * should also allow to remove a bunch of callback function 517762306a36Sopenharmony_ci * like vram_info. 517862306a36Sopenharmony_ci */ 517962306a36Sopenharmony_ciint evergreen_init(struct radeon_device *rdev) 518062306a36Sopenharmony_ci{ 518162306a36Sopenharmony_ci int r; 518262306a36Sopenharmony_ci 518362306a36Sopenharmony_ci /* Read BIOS */ 518462306a36Sopenharmony_ci if (!radeon_get_bios(rdev)) { 518562306a36Sopenharmony_ci if (ASIC_IS_AVIVO(rdev)) 518662306a36Sopenharmony_ci return -EINVAL; 518762306a36Sopenharmony_ci } 518862306a36Sopenharmony_ci /* Must be an ATOMBIOS */ 518962306a36Sopenharmony_ci if (!rdev->is_atom_bios) { 519062306a36Sopenharmony_ci dev_err(rdev->dev, "Expecting atombios for evergreen GPU\n"); 519162306a36Sopenharmony_ci return -EINVAL; 519262306a36Sopenharmony_ci } 519362306a36Sopenharmony_ci r = radeon_atombios_init(rdev); 519462306a36Sopenharmony_ci if (r) 519562306a36Sopenharmony_ci return r; 519662306a36Sopenharmony_ci /* reset the asic, the gfx blocks are often in a bad state 519762306a36Sopenharmony_ci * after the driver is unloaded or after a resume 519862306a36Sopenharmony_ci */ 519962306a36Sopenharmony_ci if (radeon_asic_reset(rdev)) 520062306a36Sopenharmony_ci dev_warn(rdev->dev, "GPU reset failed !\n"); 520162306a36Sopenharmony_ci /* Post card if necessary */ 520262306a36Sopenharmony_ci if (!radeon_card_posted(rdev)) { 520362306a36Sopenharmony_ci if (!rdev->bios) { 520462306a36Sopenharmony_ci dev_err(rdev->dev, "Card not posted and no BIOS - ignoring\n"); 520562306a36Sopenharmony_ci return -EINVAL; 520662306a36Sopenharmony_ci } 520762306a36Sopenharmony_ci DRM_INFO("GPU not posted. posting now...\n"); 520862306a36Sopenharmony_ci atom_asic_init(rdev->mode_info.atom_context); 520962306a36Sopenharmony_ci } 521062306a36Sopenharmony_ci /* init golden registers */ 521162306a36Sopenharmony_ci evergreen_init_golden_registers(rdev); 521262306a36Sopenharmony_ci /* Initialize scratch registers */ 521362306a36Sopenharmony_ci r600_scratch_init(rdev); 521462306a36Sopenharmony_ci /* Initialize surface registers */ 521562306a36Sopenharmony_ci radeon_surface_init(rdev); 521662306a36Sopenharmony_ci /* Initialize clocks */ 521762306a36Sopenharmony_ci radeon_get_clock_info(rdev->ddev); 521862306a36Sopenharmony_ci /* Fence driver */ 521962306a36Sopenharmony_ci radeon_fence_driver_init(rdev); 522062306a36Sopenharmony_ci /* initialize AGP */ 522162306a36Sopenharmony_ci if (rdev->flags & RADEON_IS_AGP) { 522262306a36Sopenharmony_ci r = radeon_agp_init(rdev); 522362306a36Sopenharmony_ci if (r) 522462306a36Sopenharmony_ci radeon_agp_disable(rdev); 522562306a36Sopenharmony_ci } 522662306a36Sopenharmony_ci /* initialize memory controller */ 522762306a36Sopenharmony_ci r = evergreen_mc_init(rdev); 522862306a36Sopenharmony_ci if (r) 522962306a36Sopenharmony_ci return r; 523062306a36Sopenharmony_ci /* Memory manager */ 523162306a36Sopenharmony_ci r = radeon_bo_init(rdev); 523262306a36Sopenharmony_ci if (r) 523362306a36Sopenharmony_ci return r; 523462306a36Sopenharmony_ci 523562306a36Sopenharmony_ci if (ASIC_IS_DCE5(rdev)) { 523662306a36Sopenharmony_ci if (!rdev->me_fw || !rdev->pfp_fw || !rdev->rlc_fw || !rdev->mc_fw) { 523762306a36Sopenharmony_ci r = ni_init_microcode(rdev); 523862306a36Sopenharmony_ci if (r) { 523962306a36Sopenharmony_ci DRM_ERROR("Failed to load firmware!\n"); 524062306a36Sopenharmony_ci return r; 524162306a36Sopenharmony_ci } 524262306a36Sopenharmony_ci } 524362306a36Sopenharmony_ci } else { 524462306a36Sopenharmony_ci if (!rdev->me_fw || !rdev->pfp_fw || !rdev->rlc_fw) { 524562306a36Sopenharmony_ci r = r600_init_microcode(rdev); 524662306a36Sopenharmony_ci if (r) { 524762306a36Sopenharmony_ci DRM_ERROR("Failed to load firmware!\n"); 524862306a36Sopenharmony_ci return r; 524962306a36Sopenharmony_ci } 525062306a36Sopenharmony_ci } 525162306a36Sopenharmony_ci } 525262306a36Sopenharmony_ci 525362306a36Sopenharmony_ci /* Initialize power management */ 525462306a36Sopenharmony_ci radeon_pm_init(rdev); 525562306a36Sopenharmony_ci 525662306a36Sopenharmony_ci rdev->ring[RADEON_RING_TYPE_GFX_INDEX].ring_obj = NULL; 525762306a36Sopenharmony_ci r600_ring_init(rdev, &rdev->ring[RADEON_RING_TYPE_GFX_INDEX], 1024 * 1024); 525862306a36Sopenharmony_ci 525962306a36Sopenharmony_ci rdev->ring[R600_RING_TYPE_DMA_INDEX].ring_obj = NULL; 526062306a36Sopenharmony_ci r600_ring_init(rdev, &rdev->ring[R600_RING_TYPE_DMA_INDEX], 64 * 1024); 526162306a36Sopenharmony_ci 526262306a36Sopenharmony_ci evergreen_uvd_init(rdev); 526362306a36Sopenharmony_ci 526462306a36Sopenharmony_ci rdev->ih.ring_obj = NULL; 526562306a36Sopenharmony_ci r600_ih_ring_init(rdev, 64 * 1024); 526662306a36Sopenharmony_ci 526762306a36Sopenharmony_ci r = r600_pcie_gart_init(rdev); 526862306a36Sopenharmony_ci if (r) 526962306a36Sopenharmony_ci return r; 527062306a36Sopenharmony_ci 527162306a36Sopenharmony_ci rdev->accel_working = true; 527262306a36Sopenharmony_ci r = evergreen_startup(rdev); 527362306a36Sopenharmony_ci if (r) { 527462306a36Sopenharmony_ci dev_err(rdev->dev, "disabling GPU acceleration\n"); 527562306a36Sopenharmony_ci r700_cp_fini(rdev); 527662306a36Sopenharmony_ci r600_dma_fini(rdev); 527762306a36Sopenharmony_ci r600_irq_fini(rdev); 527862306a36Sopenharmony_ci if (rdev->flags & RADEON_IS_IGP) 527962306a36Sopenharmony_ci sumo_rlc_fini(rdev); 528062306a36Sopenharmony_ci radeon_wb_fini(rdev); 528162306a36Sopenharmony_ci radeon_ib_pool_fini(rdev); 528262306a36Sopenharmony_ci radeon_irq_kms_fini(rdev); 528362306a36Sopenharmony_ci evergreen_pcie_gart_fini(rdev); 528462306a36Sopenharmony_ci rdev->accel_working = false; 528562306a36Sopenharmony_ci } 528662306a36Sopenharmony_ci 528762306a36Sopenharmony_ci /* Don't start up if the MC ucode is missing on BTC parts. 528862306a36Sopenharmony_ci * The default clocks and voltages before the MC ucode 528962306a36Sopenharmony_ci * is loaded are not suffient for advanced operations. 529062306a36Sopenharmony_ci */ 529162306a36Sopenharmony_ci if (ASIC_IS_DCE5(rdev)) { 529262306a36Sopenharmony_ci if (!rdev->mc_fw && !(rdev->flags & RADEON_IS_IGP)) { 529362306a36Sopenharmony_ci DRM_ERROR("radeon: MC ucode required for NI+.\n"); 529462306a36Sopenharmony_ci return -EINVAL; 529562306a36Sopenharmony_ci } 529662306a36Sopenharmony_ci } 529762306a36Sopenharmony_ci 529862306a36Sopenharmony_ci return 0; 529962306a36Sopenharmony_ci} 530062306a36Sopenharmony_ci 530162306a36Sopenharmony_civoid evergreen_fini(struct radeon_device *rdev) 530262306a36Sopenharmony_ci{ 530362306a36Sopenharmony_ci radeon_pm_fini(rdev); 530462306a36Sopenharmony_ci radeon_audio_fini(rdev); 530562306a36Sopenharmony_ci r700_cp_fini(rdev); 530662306a36Sopenharmony_ci r600_dma_fini(rdev); 530762306a36Sopenharmony_ci r600_irq_fini(rdev); 530862306a36Sopenharmony_ci if (rdev->flags & RADEON_IS_IGP) 530962306a36Sopenharmony_ci sumo_rlc_fini(rdev); 531062306a36Sopenharmony_ci radeon_wb_fini(rdev); 531162306a36Sopenharmony_ci radeon_ib_pool_fini(rdev); 531262306a36Sopenharmony_ci radeon_irq_kms_fini(rdev); 531362306a36Sopenharmony_ci uvd_v1_0_fini(rdev); 531462306a36Sopenharmony_ci radeon_uvd_fini(rdev); 531562306a36Sopenharmony_ci evergreen_pcie_gart_fini(rdev); 531662306a36Sopenharmony_ci r600_vram_scratch_fini(rdev); 531762306a36Sopenharmony_ci radeon_gem_fini(rdev); 531862306a36Sopenharmony_ci radeon_fence_driver_fini(rdev); 531962306a36Sopenharmony_ci radeon_agp_fini(rdev); 532062306a36Sopenharmony_ci radeon_bo_fini(rdev); 532162306a36Sopenharmony_ci radeon_atombios_fini(rdev); 532262306a36Sopenharmony_ci kfree(rdev->bios); 532362306a36Sopenharmony_ci rdev->bios = NULL; 532462306a36Sopenharmony_ci} 532562306a36Sopenharmony_ci 532662306a36Sopenharmony_civoid evergreen_pcie_gen2_enable(struct radeon_device *rdev) 532762306a36Sopenharmony_ci{ 532862306a36Sopenharmony_ci u32 link_width_cntl, speed_cntl; 532962306a36Sopenharmony_ci 533062306a36Sopenharmony_ci if (radeon_pcie_gen2 == 0) 533162306a36Sopenharmony_ci return; 533262306a36Sopenharmony_ci 533362306a36Sopenharmony_ci if (rdev->flags & RADEON_IS_IGP) 533462306a36Sopenharmony_ci return; 533562306a36Sopenharmony_ci 533662306a36Sopenharmony_ci if (!(rdev->flags & RADEON_IS_PCIE)) 533762306a36Sopenharmony_ci return; 533862306a36Sopenharmony_ci 533962306a36Sopenharmony_ci /* x2 cards have a special sequence */ 534062306a36Sopenharmony_ci if (ASIC_IS_X2(rdev)) 534162306a36Sopenharmony_ci return; 534262306a36Sopenharmony_ci 534362306a36Sopenharmony_ci if ((rdev->pdev->bus->max_bus_speed != PCIE_SPEED_5_0GT) && 534462306a36Sopenharmony_ci (rdev->pdev->bus->max_bus_speed != PCIE_SPEED_8_0GT)) 534562306a36Sopenharmony_ci return; 534662306a36Sopenharmony_ci 534762306a36Sopenharmony_ci speed_cntl = RREG32_PCIE_PORT(PCIE_LC_SPEED_CNTL); 534862306a36Sopenharmony_ci if (speed_cntl & LC_CURRENT_DATA_RATE) { 534962306a36Sopenharmony_ci DRM_INFO("PCIE gen 2 link speeds already enabled\n"); 535062306a36Sopenharmony_ci return; 535162306a36Sopenharmony_ci } 535262306a36Sopenharmony_ci 535362306a36Sopenharmony_ci DRM_INFO("enabling PCIE gen 2 link speeds, disable with radeon.pcie_gen2=0\n"); 535462306a36Sopenharmony_ci 535562306a36Sopenharmony_ci if ((speed_cntl & LC_OTHER_SIDE_EVER_SENT_GEN2) || 535662306a36Sopenharmony_ci (speed_cntl & LC_OTHER_SIDE_SUPPORTS_GEN2)) { 535762306a36Sopenharmony_ci 535862306a36Sopenharmony_ci link_width_cntl = RREG32_PCIE_PORT(PCIE_LC_LINK_WIDTH_CNTL); 535962306a36Sopenharmony_ci link_width_cntl &= ~LC_UPCONFIGURE_DIS; 536062306a36Sopenharmony_ci WREG32_PCIE_PORT(PCIE_LC_LINK_WIDTH_CNTL, link_width_cntl); 536162306a36Sopenharmony_ci 536262306a36Sopenharmony_ci speed_cntl = RREG32_PCIE_PORT(PCIE_LC_SPEED_CNTL); 536362306a36Sopenharmony_ci speed_cntl &= ~LC_TARGET_LINK_SPEED_OVERRIDE_EN; 536462306a36Sopenharmony_ci WREG32_PCIE_PORT(PCIE_LC_SPEED_CNTL, speed_cntl); 536562306a36Sopenharmony_ci 536662306a36Sopenharmony_ci speed_cntl = RREG32_PCIE_PORT(PCIE_LC_SPEED_CNTL); 536762306a36Sopenharmony_ci speed_cntl |= LC_CLR_FAILED_SPD_CHANGE_CNT; 536862306a36Sopenharmony_ci WREG32_PCIE_PORT(PCIE_LC_SPEED_CNTL, speed_cntl); 536962306a36Sopenharmony_ci 537062306a36Sopenharmony_ci speed_cntl = RREG32_PCIE_PORT(PCIE_LC_SPEED_CNTL); 537162306a36Sopenharmony_ci speed_cntl &= ~LC_CLR_FAILED_SPD_CHANGE_CNT; 537262306a36Sopenharmony_ci WREG32_PCIE_PORT(PCIE_LC_SPEED_CNTL, speed_cntl); 537362306a36Sopenharmony_ci 537462306a36Sopenharmony_ci speed_cntl = RREG32_PCIE_PORT(PCIE_LC_SPEED_CNTL); 537562306a36Sopenharmony_ci speed_cntl |= LC_GEN2_EN_STRAP; 537662306a36Sopenharmony_ci WREG32_PCIE_PORT(PCIE_LC_SPEED_CNTL, speed_cntl); 537762306a36Sopenharmony_ci 537862306a36Sopenharmony_ci } else { 537962306a36Sopenharmony_ci link_width_cntl = RREG32_PCIE_PORT(PCIE_LC_LINK_WIDTH_CNTL); 538062306a36Sopenharmony_ci /* XXX: only disable it if gen1 bridge vendor == 0x111d or 0x1106 */ 538162306a36Sopenharmony_ci if (1) 538262306a36Sopenharmony_ci link_width_cntl |= LC_UPCONFIGURE_DIS; 538362306a36Sopenharmony_ci else 538462306a36Sopenharmony_ci link_width_cntl &= ~LC_UPCONFIGURE_DIS; 538562306a36Sopenharmony_ci WREG32_PCIE_PORT(PCIE_LC_LINK_WIDTH_CNTL, link_width_cntl); 538662306a36Sopenharmony_ci } 538762306a36Sopenharmony_ci} 538862306a36Sopenharmony_ci 538962306a36Sopenharmony_civoid evergreen_program_aspm(struct radeon_device *rdev) 539062306a36Sopenharmony_ci{ 539162306a36Sopenharmony_ci u32 data, orig; 539262306a36Sopenharmony_ci u32 pcie_lc_cntl, pcie_lc_cntl_old; 539362306a36Sopenharmony_ci bool disable_l0s, disable_l1 = false, disable_plloff_in_l1 = false; 539462306a36Sopenharmony_ci /* fusion_platform = true 539562306a36Sopenharmony_ci * if the system is a fusion system 539662306a36Sopenharmony_ci * (APU or DGPU in a fusion system). 539762306a36Sopenharmony_ci * todo: check if the system is a fusion platform. 539862306a36Sopenharmony_ci */ 539962306a36Sopenharmony_ci bool fusion_platform = false; 540062306a36Sopenharmony_ci 540162306a36Sopenharmony_ci if (radeon_aspm == 0) 540262306a36Sopenharmony_ci return; 540362306a36Sopenharmony_ci 540462306a36Sopenharmony_ci if (!(rdev->flags & RADEON_IS_PCIE)) 540562306a36Sopenharmony_ci return; 540662306a36Sopenharmony_ci 540762306a36Sopenharmony_ci switch (rdev->family) { 540862306a36Sopenharmony_ci case CHIP_CYPRESS: 540962306a36Sopenharmony_ci case CHIP_HEMLOCK: 541062306a36Sopenharmony_ci case CHIP_JUNIPER: 541162306a36Sopenharmony_ci case CHIP_REDWOOD: 541262306a36Sopenharmony_ci case CHIP_CEDAR: 541362306a36Sopenharmony_ci case CHIP_SUMO: 541462306a36Sopenharmony_ci case CHIP_SUMO2: 541562306a36Sopenharmony_ci case CHIP_PALM: 541662306a36Sopenharmony_ci case CHIP_ARUBA: 541762306a36Sopenharmony_ci disable_l0s = true; 541862306a36Sopenharmony_ci break; 541962306a36Sopenharmony_ci default: 542062306a36Sopenharmony_ci disable_l0s = false; 542162306a36Sopenharmony_ci break; 542262306a36Sopenharmony_ci } 542362306a36Sopenharmony_ci 542462306a36Sopenharmony_ci if (rdev->flags & RADEON_IS_IGP) 542562306a36Sopenharmony_ci fusion_platform = true; /* XXX also dGPUs in a fusion system */ 542662306a36Sopenharmony_ci 542762306a36Sopenharmony_ci data = orig = RREG32_PIF_PHY0(PB0_PIF_PAIRING); 542862306a36Sopenharmony_ci if (fusion_platform) 542962306a36Sopenharmony_ci data &= ~MULTI_PIF; 543062306a36Sopenharmony_ci else 543162306a36Sopenharmony_ci data |= MULTI_PIF; 543262306a36Sopenharmony_ci if (data != orig) 543362306a36Sopenharmony_ci WREG32_PIF_PHY0(PB0_PIF_PAIRING, data); 543462306a36Sopenharmony_ci 543562306a36Sopenharmony_ci data = orig = RREG32_PIF_PHY1(PB1_PIF_PAIRING); 543662306a36Sopenharmony_ci if (fusion_platform) 543762306a36Sopenharmony_ci data &= ~MULTI_PIF; 543862306a36Sopenharmony_ci else 543962306a36Sopenharmony_ci data |= MULTI_PIF; 544062306a36Sopenharmony_ci if (data != orig) 544162306a36Sopenharmony_ci WREG32_PIF_PHY1(PB1_PIF_PAIRING, data); 544262306a36Sopenharmony_ci 544362306a36Sopenharmony_ci pcie_lc_cntl = pcie_lc_cntl_old = RREG32_PCIE_PORT(PCIE_LC_CNTL); 544462306a36Sopenharmony_ci pcie_lc_cntl &= ~(LC_L0S_INACTIVITY_MASK | LC_L1_INACTIVITY_MASK); 544562306a36Sopenharmony_ci if (!disable_l0s) { 544662306a36Sopenharmony_ci if (rdev->family >= CHIP_BARTS) 544762306a36Sopenharmony_ci pcie_lc_cntl |= LC_L0S_INACTIVITY(7); 544862306a36Sopenharmony_ci else 544962306a36Sopenharmony_ci pcie_lc_cntl |= LC_L0S_INACTIVITY(3); 545062306a36Sopenharmony_ci } 545162306a36Sopenharmony_ci 545262306a36Sopenharmony_ci if (!disable_l1) { 545362306a36Sopenharmony_ci if (rdev->family >= CHIP_BARTS) 545462306a36Sopenharmony_ci pcie_lc_cntl |= LC_L1_INACTIVITY(7); 545562306a36Sopenharmony_ci else 545662306a36Sopenharmony_ci pcie_lc_cntl |= LC_L1_INACTIVITY(8); 545762306a36Sopenharmony_ci 545862306a36Sopenharmony_ci if (!disable_plloff_in_l1) { 545962306a36Sopenharmony_ci data = orig = RREG32_PIF_PHY0(PB0_PIF_PWRDOWN_0); 546062306a36Sopenharmony_ci data &= ~(PLL_POWER_STATE_IN_OFF_0_MASK | PLL_POWER_STATE_IN_TXS2_0_MASK); 546162306a36Sopenharmony_ci data |= PLL_POWER_STATE_IN_OFF_0(7) | PLL_POWER_STATE_IN_TXS2_0(7); 546262306a36Sopenharmony_ci if (data != orig) 546362306a36Sopenharmony_ci WREG32_PIF_PHY0(PB0_PIF_PWRDOWN_0, data); 546462306a36Sopenharmony_ci 546562306a36Sopenharmony_ci data = orig = RREG32_PIF_PHY0(PB0_PIF_PWRDOWN_1); 546662306a36Sopenharmony_ci data &= ~(PLL_POWER_STATE_IN_OFF_1_MASK | PLL_POWER_STATE_IN_TXS2_1_MASK); 546762306a36Sopenharmony_ci data |= PLL_POWER_STATE_IN_OFF_1(7) | PLL_POWER_STATE_IN_TXS2_1(7); 546862306a36Sopenharmony_ci if (data != orig) 546962306a36Sopenharmony_ci WREG32_PIF_PHY0(PB0_PIF_PWRDOWN_1, data); 547062306a36Sopenharmony_ci 547162306a36Sopenharmony_ci data = orig = RREG32_PIF_PHY1(PB1_PIF_PWRDOWN_0); 547262306a36Sopenharmony_ci data &= ~(PLL_POWER_STATE_IN_OFF_0_MASK | PLL_POWER_STATE_IN_TXS2_0_MASK); 547362306a36Sopenharmony_ci data |= PLL_POWER_STATE_IN_OFF_0(7) | PLL_POWER_STATE_IN_TXS2_0(7); 547462306a36Sopenharmony_ci if (data != orig) 547562306a36Sopenharmony_ci WREG32_PIF_PHY1(PB1_PIF_PWRDOWN_0, data); 547662306a36Sopenharmony_ci 547762306a36Sopenharmony_ci data = orig = RREG32_PIF_PHY1(PB1_PIF_PWRDOWN_1); 547862306a36Sopenharmony_ci data &= ~(PLL_POWER_STATE_IN_OFF_1_MASK | PLL_POWER_STATE_IN_TXS2_1_MASK); 547962306a36Sopenharmony_ci data |= PLL_POWER_STATE_IN_OFF_1(7) | PLL_POWER_STATE_IN_TXS2_1(7); 548062306a36Sopenharmony_ci if (data != orig) 548162306a36Sopenharmony_ci WREG32_PIF_PHY1(PB1_PIF_PWRDOWN_1, data); 548262306a36Sopenharmony_ci 548362306a36Sopenharmony_ci if (rdev->family >= CHIP_BARTS) { 548462306a36Sopenharmony_ci data = orig = RREG32_PIF_PHY0(PB0_PIF_PWRDOWN_0); 548562306a36Sopenharmony_ci data &= ~PLL_RAMP_UP_TIME_0_MASK; 548662306a36Sopenharmony_ci data |= PLL_RAMP_UP_TIME_0(4); 548762306a36Sopenharmony_ci if (data != orig) 548862306a36Sopenharmony_ci WREG32_PIF_PHY0(PB0_PIF_PWRDOWN_0, data); 548962306a36Sopenharmony_ci 549062306a36Sopenharmony_ci data = orig = RREG32_PIF_PHY0(PB0_PIF_PWRDOWN_1); 549162306a36Sopenharmony_ci data &= ~PLL_RAMP_UP_TIME_1_MASK; 549262306a36Sopenharmony_ci data |= PLL_RAMP_UP_TIME_1(4); 549362306a36Sopenharmony_ci if (data != orig) 549462306a36Sopenharmony_ci WREG32_PIF_PHY0(PB0_PIF_PWRDOWN_1, data); 549562306a36Sopenharmony_ci 549662306a36Sopenharmony_ci data = orig = RREG32_PIF_PHY1(PB1_PIF_PWRDOWN_0); 549762306a36Sopenharmony_ci data &= ~PLL_RAMP_UP_TIME_0_MASK; 549862306a36Sopenharmony_ci data |= PLL_RAMP_UP_TIME_0(4); 549962306a36Sopenharmony_ci if (data != orig) 550062306a36Sopenharmony_ci WREG32_PIF_PHY1(PB1_PIF_PWRDOWN_0, data); 550162306a36Sopenharmony_ci 550262306a36Sopenharmony_ci data = orig = RREG32_PIF_PHY1(PB1_PIF_PWRDOWN_1); 550362306a36Sopenharmony_ci data &= ~PLL_RAMP_UP_TIME_1_MASK; 550462306a36Sopenharmony_ci data |= PLL_RAMP_UP_TIME_1(4); 550562306a36Sopenharmony_ci if (data != orig) 550662306a36Sopenharmony_ci WREG32_PIF_PHY1(PB1_PIF_PWRDOWN_1, data); 550762306a36Sopenharmony_ci } 550862306a36Sopenharmony_ci 550962306a36Sopenharmony_ci data = orig = RREG32_PCIE_PORT(PCIE_LC_LINK_WIDTH_CNTL); 551062306a36Sopenharmony_ci data &= ~LC_DYN_LANES_PWR_STATE_MASK; 551162306a36Sopenharmony_ci data |= LC_DYN_LANES_PWR_STATE(3); 551262306a36Sopenharmony_ci if (data != orig) 551362306a36Sopenharmony_ci WREG32_PCIE_PORT(PCIE_LC_LINK_WIDTH_CNTL, data); 551462306a36Sopenharmony_ci 551562306a36Sopenharmony_ci if (rdev->family >= CHIP_BARTS) { 551662306a36Sopenharmony_ci data = orig = RREG32_PIF_PHY0(PB0_PIF_CNTL); 551762306a36Sopenharmony_ci data &= ~LS2_EXIT_TIME_MASK; 551862306a36Sopenharmony_ci data |= LS2_EXIT_TIME(1); 551962306a36Sopenharmony_ci if (data != orig) 552062306a36Sopenharmony_ci WREG32_PIF_PHY0(PB0_PIF_CNTL, data); 552162306a36Sopenharmony_ci 552262306a36Sopenharmony_ci data = orig = RREG32_PIF_PHY1(PB1_PIF_CNTL); 552362306a36Sopenharmony_ci data &= ~LS2_EXIT_TIME_MASK; 552462306a36Sopenharmony_ci data |= LS2_EXIT_TIME(1); 552562306a36Sopenharmony_ci if (data != orig) 552662306a36Sopenharmony_ci WREG32_PIF_PHY1(PB1_PIF_CNTL, data); 552762306a36Sopenharmony_ci } 552862306a36Sopenharmony_ci } 552962306a36Sopenharmony_ci } 553062306a36Sopenharmony_ci 553162306a36Sopenharmony_ci /* evergreen parts only */ 553262306a36Sopenharmony_ci if (rdev->family < CHIP_BARTS) 553362306a36Sopenharmony_ci pcie_lc_cntl |= LC_PMI_TO_L1_DIS; 553462306a36Sopenharmony_ci 553562306a36Sopenharmony_ci if (pcie_lc_cntl != pcie_lc_cntl_old) 553662306a36Sopenharmony_ci WREG32_PCIE_PORT(PCIE_LC_CNTL, pcie_lc_cntl); 553762306a36Sopenharmony_ci} 5538