162306a36Sopenharmony_ci/* 262306a36Sopenharmony_ci * Copyright 2012 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/module.h> 2762306a36Sopenharmony_ci#include <linux/pci.h> 2862306a36Sopenharmony_ci#include <linux/slab.h> 2962306a36Sopenharmony_ci 3062306a36Sopenharmony_ci#include <drm/drm_vblank.h> 3162306a36Sopenharmony_ci 3262306a36Sopenharmony_ci#include "atom.h" 3362306a36Sopenharmony_ci#include "evergreen.h" 3462306a36Sopenharmony_ci#include "cik_blit_shaders.h" 3562306a36Sopenharmony_ci#include "cik.h" 3662306a36Sopenharmony_ci#include "cikd.h" 3762306a36Sopenharmony_ci#include "clearstate_ci.h" 3862306a36Sopenharmony_ci#include "r600.h" 3962306a36Sopenharmony_ci#include "radeon.h" 4062306a36Sopenharmony_ci#include "radeon_asic.h" 4162306a36Sopenharmony_ci#include "radeon_audio.h" 4262306a36Sopenharmony_ci#include "radeon_ucode.h" 4362306a36Sopenharmony_ci#include "si.h" 4462306a36Sopenharmony_ci#include "vce.h" 4562306a36Sopenharmony_ci 4662306a36Sopenharmony_ci#define SH_MEM_CONFIG_GFX_DEFAULT \ 4762306a36Sopenharmony_ci ALIGNMENT_MODE(SH_MEM_ALIGNMENT_MODE_UNALIGNED) 4862306a36Sopenharmony_ci 4962306a36Sopenharmony_ciMODULE_FIRMWARE("radeon/BONAIRE_pfp.bin"); 5062306a36Sopenharmony_ciMODULE_FIRMWARE("radeon/BONAIRE_me.bin"); 5162306a36Sopenharmony_ciMODULE_FIRMWARE("radeon/BONAIRE_ce.bin"); 5262306a36Sopenharmony_ciMODULE_FIRMWARE("radeon/BONAIRE_mec.bin"); 5362306a36Sopenharmony_ciMODULE_FIRMWARE("radeon/BONAIRE_mc.bin"); 5462306a36Sopenharmony_ciMODULE_FIRMWARE("radeon/BONAIRE_mc2.bin"); 5562306a36Sopenharmony_ciMODULE_FIRMWARE("radeon/BONAIRE_rlc.bin"); 5662306a36Sopenharmony_ciMODULE_FIRMWARE("radeon/BONAIRE_sdma.bin"); 5762306a36Sopenharmony_ciMODULE_FIRMWARE("radeon/BONAIRE_smc.bin"); 5862306a36Sopenharmony_ci 5962306a36Sopenharmony_ciMODULE_FIRMWARE("radeon/bonaire_pfp.bin"); 6062306a36Sopenharmony_ciMODULE_FIRMWARE("radeon/bonaire_me.bin"); 6162306a36Sopenharmony_ciMODULE_FIRMWARE("radeon/bonaire_ce.bin"); 6262306a36Sopenharmony_ciMODULE_FIRMWARE("radeon/bonaire_mec.bin"); 6362306a36Sopenharmony_ciMODULE_FIRMWARE("radeon/bonaire_mc.bin"); 6462306a36Sopenharmony_ciMODULE_FIRMWARE("radeon/bonaire_rlc.bin"); 6562306a36Sopenharmony_ciMODULE_FIRMWARE("radeon/bonaire_sdma.bin"); 6662306a36Sopenharmony_ciMODULE_FIRMWARE("radeon/bonaire_smc.bin"); 6762306a36Sopenharmony_ciMODULE_FIRMWARE("radeon/bonaire_k_smc.bin"); 6862306a36Sopenharmony_ci 6962306a36Sopenharmony_ciMODULE_FIRMWARE("radeon/HAWAII_pfp.bin"); 7062306a36Sopenharmony_ciMODULE_FIRMWARE("radeon/HAWAII_me.bin"); 7162306a36Sopenharmony_ciMODULE_FIRMWARE("radeon/HAWAII_ce.bin"); 7262306a36Sopenharmony_ciMODULE_FIRMWARE("radeon/HAWAII_mec.bin"); 7362306a36Sopenharmony_ciMODULE_FIRMWARE("radeon/HAWAII_mc.bin"); 7462306a36Sopenharmony_ciMODULE_FIRMWARE("radeon/HAWAII_mc2.bin"); 7562306a36Sopenharmony_ciMODULE_FIRMWARE("radeon/HAWAII_rlc.bin"); 7662306a36Sopenharmony_ciMODULE_FIRMWARE("radeon/HAWAII_sdma.bin"); 7762306a36Sopenharmony_ciMODULE_FIRMWARE("radeon/HAWAII_smc.bin"); 7862306a36Sopenharmony_ci 7962306a36Sopenharmony_ciMODULE_FIRMWARE("radeon/hawaii_pfp.bin"); 8062306a36Sopenharmony_ciMODULE_FIRMWARE("radeon/hawaii_me.bin"); 8162306a36Sopenharmony_ciMODULE_FIRMWARE("radeon/hawaii_ce.bin"); 8262306a36Sopenharmony_ciMODULE_FIRMWARE("radeon/hawaii_mec.bin"); 8362306a36Sopenharmony_ciMODULE_FIRMWARE("radeon/hawaii_mc.bin"); 8462306a36Sopenharmony_ciMODULE_FIRMWARE("radeon/hawaii_rlc.bin"); 8562306a36Sopenharmony_ciMODULE_FIRMWARE("radeon/hawaii_sdma.bin"); 8662306a36Sopenharmony_ciMODULE_FIRMWARE("radeon/hawaii_smc.bin"); 8762306a36Sopenharmony_ciMODULE_FIRMWARE("radeon/hawaii_k_smc.bin"); 8862306a36Sopenharmony_ci 8962306a36Sopenharmony_ciMODULE_FIRMWARE("radeon/KAVERI_pfp.bin"); 9062306a36Sopenharmony_ciMODULE_FIRMWARE("radeon/KAVERI_me.bin"); 9162306a36Sopenharmony_ciMODULE_FIRMWARE("radeon/KAVERI_ce.bin"); 9262306a36Sopenharmony_ciMODULE_FIRMWARE("radeon/KAVERI_mec.bin"); 9362306a36Sopenharmony_ciMODULE_FIRMWARE("radeon/KAVERI_rlc.bin"); 9462306a36Sopenharmony_ciMODULE_FIRMWARE("radeon/KAVERI_sdma.bin"); 9562306a36Sopenharmony_ci 9662306a36Sopenharmony_ciMODULE_FIRMWARE("radeon/kaveri_pfp.bin"); 9762306a36Sopenharmony_ciMODULE_FIRMWARE("radeon/kaveri_me.bin"); 9862306a36Sopenharmony_ciMODULE_FIRMWARE("radeon/kaveri_ce.bin"); 9962306a36Sopenharmony_ciMODULE_FIRMWARE("radeon/kaveri_mec.bin"); 10062306a36Sopenharmony_ciMODULE_FIRMWARE("radeon/kaveri_mec2.bin"); 10162306a36Sopenharmony_ciMODULE_FIRMWARE("radeon/kaveri_rlc.bin"); 10262306a36Sopenharmony_ciMODULE_FIRMWARE("radeon/kaveri_sdma.bin"); 10362306a36Sopenharmony_ci 10462306a36Sopenharmony_ciMODULE_FIRMWARE("radeon/KABINI_pfp.bin"); 10562306a36Sopenharmony_ciMODULE_FIRMWARE("radeon/KABINI_me.bin"); 10662306a36Sopenharmony_ciMODULE_FIRMWARE("radeon/KABINI_ce.bin"); 10762306a36Sopenharmony_ciMODULE_FIRMWARE("radeon/KABINI_mec.bin"); 10862306a36Sopenharmony_ciMODULE_FIRMWARE("radeon/KABINI_rlc.bin"); 10962306a36Sopenharmony_ciMODULE_FIRMWARE("radeon/KABINI_sdma.bin"); 11062306a36Sopenharmony_ci 11162306a36Sopenharmony_ciMODULE_FIRMWARE("radeon/kabini_pfp.bin"); 11262306a36Sopenharmony_ciMODULE_FIRMWARE("radeon/kabini_me.bin"); 11362306a36Sopenharmony_ciMODULE_FIRMWARE("radeon/kabini_ce.bin"); 11462306a36Sopenharmony_ciMODULE_FIRMWARE("radeon/kabini_mec.bin"); 11562306a36Sopenharmony_ciMODULE_FIRMWARE("radeon/kabini_rlc.bin"); 11662306a36Sopenharmony_ciMODULE_FIRMWARE("radeon/kabini_sdma.bin"); 11762306a36Sopenharmony_ci 11862306a36Sopenharmony_ciMODULE_FIRMWARE("radeon/MULLINS_pfp.bin"); 11962306a36Sopenharmony_ciMODULE_FIRMWARE("radeon/MULLINS_me.bin"); 12062306a36Sopenharmony_ciMODULE_FIRMWARE("radeon/MULLINS_ce.bin"); 12162306a36Sopenharmony_ciMODULE_FIRMWARE("radeon/MULLINS_mec.bin"); 12262306a36Sopenharmony_ciMODULE_FIRMWARE("radeon/MULLINS_rlc.bin"); 12362306a36Sopenharmony_ciMODULE_FIRMWARE("radeon/MULLINS_sdma.bin"); 12462306a36Sopenharmony_ci 12562306a36Sopenharmony_ciMODULE_FIRMWARE("radeon/mullins_pfp.bin"); 12662306a36Sopenharmony_ciMODULE_FIRMWARE("radeon/mullins_me.bin"); 12762306a36Sopenharmony_ciMODULE_FIRMWARE("radeon/mullins_ce.bin"); 12862306a36Sopenharmony_ciMODULE_FIRMWARE("radeon/mullins_mec.bin"); 12962306a36Sopenharmony_ciMODULE_FIRMWARE("radeon/mullins_rlc.bin"); 13062306a36Sopenharmony_ciMODULE_FIRMWARE("radeon/mullins_sdma.bin"); 13162306a36Sopenharmony_ci 13262306a36Sopenharmony_cistatic u32 cik_get_cu_active_bitmap(struct radeon_device *rdev, u32 se, u32 sh); 13362306a36Sopenharmony_cistatic void cik_rlc_stop(struct radeon_device *rdev); 13462306a36Sopenharmony_cistatic void cik_pcie_gen3_enable(struct radeon_device *rdev); 13562306a36Sopenharmony_cistatic void cik_program_aspm(struct radeon_device *rdev); 13662306a36Sopenharmony_cistatic void cik_init_pg(struct radeon_device *rdev); 13762306a36Sopenharmony_cistatic void cik_init_cg(struct radeon_device *rdev); 13862306a36Sopenharmony_cistatic void cik_fini_pg(struct radeon_device *rdev); 13962306a36Sopenharmony_cistatic void cik_fini_cg(struct radeon_device *rdev); 14062306a36Sopenharmony_cistatic void cik_enable_gui_idle_interrupt(struct radeon_device *rdev, 14162306a36Sopenharmony_ci bool enable); 14262306a36Sopenharmony_ci 14362306a36Sopenharmony_ci/** 14462306a36Sopenharmony_ci * cik_get_allowed_info_register - fetch the register for the info ioctl 14562306a36Sopenharmony_ci * 14662306a36Sopenharmony_ci * @rdev: radeon_device pointer 14762306a36Sopenharmony_ci * @reg: register offset in bytes 14862306a36Sopenharmony_ci * @val: register value 14962306a36Sopenharmony_ci * 15062306a36Sopenharmony_ci * Returns 0 for success or -EINVAL for an invalid register 15162306a36Sopenharmony_ci * 15262306a36Sopenharmony_ci */ 15362306a36Sopenharmony_ciint cik_get_allowed_info_register(struct radeon_device *rdev, 15462306a36Sopenharmony_ci u32 reg, u32 *val) 15562306a36Sopenharmony_ci{ 15662306a36Sopenharmony_ci switch (reg) { 15762306a36Sopenharmony_ci case GRBM_STATUS: 15862306a36Sopenharmony_ci case GRBM_STATUS2: 15962306a36Sopenharmony_ci case GRBM_STATUS_SE0: 16062306a36Sopenharmony_ci case GRBM_STATUS_SE1: 16162306a36Sopenharmony_ci case GRBM_STATUS_SE2: 16262306a36Sopenharmony_ci case GRBM_STATUS_SE3: 16362306a36Sopenharmony_ci case SRBM_STATUS: 16462306a36Sopenharmony_ci case SRBM_STATUS2: 16562306a36Sopenharmony_ci case (SDMA0_STATUS_REG + SDMA0_REGISTER_OFFSET): 16662306a36Sopenharmony_ci case (SDMA0_STATUS_REG + SDMA1_REGISTER_OFFSET): 16762306a36Sopenharmony_ci case UVD_STATUS: 16862306a36Sopenharmony_ci /* TODO VCE */ 16962306a36Sopenharmony_ci *val = RREG32(reg); 17062306a36Sopenharmony_ci return 0; 17162306a36Sopenharmony_ci default: 17262306a36Sopenharmony_ci return -EINVAL; 17362306a36Sopenharmony_ci } 17462306a36Sopenharmony_ci} 17562306a36Sopenharmony_ci 17662306a36Sopenharmony_ci/* 17762306a36Sopenharmony_ci * Indirect registers accessor 17862306a36Sopenharmony_ci */ 17962306a36Sopenharmony_ciu32 cik_didt_rreg(struct radeon_device *rdev, u32 reg) 18062306a36Sopenharmony_ci{ 18162306a36Sopenharmony_ci unsigned long flags; 18262306a36Sopenharmony_ci u32 r; 18362306a36Sopenharmony_ci 18462306a36Sopenharmony_ci spin_lock_irqsave(&rdev->didt_idx_lock, flags); 18562306a36Sopenharmony_ci WREG32(CIK_DIDT_IND_INDEX, (reg)); 18662306a36Sopenharmony_ci r = RREG32(CIK_DIDT_IND_DATA); 18762306a36Sopenharmony_ci spin_unlock_irqrestore(&rdev->didt_idx_lock, flags); 18862306a36Sopenharmony_ci return r; 18962306a36Sopenharmony_ci} 19062306a36Sopenharmony_ci 19162306a36Sopenharmony_civoid cik_didt_wreg(struct radeon_device *rdev, u32 reg, u32 v) 19262306a36Sopenharmony_ci{ 19362306a36Sopenharmony_ci unsigned long flags; 19462306a36Sopenharmony_ci 19562306a36Sopenharmony_ci spin_lock_irqsave(&rdev->didt_idx_lock, flags); 19662306a36Sopenharmony_ci WREG32(CIK_DIDT_IND_INDEX, (reg)); 19762306a36Sopenharmony_ci WREG32(CIK_DIDT_IND_DATA, (v)); 19862306a36Sopenharmony_ci spin_unlock_irqrestore(&rdev->didt_idx_lock, flags); 19962306a36Sopenharmony_ci} 20062306a36Sopenharmony_ci 20162306a36Sopenharmony_ci/* get temperature in millidegrees */ 20262306a36Sopenharmony_ciint ci_get_temp(struct radeon_device *rdev) 20362306a36Sopenharmony_ci{ 20462306a36Sopenharmony_ci u32 temp; 20562306a36Sopenharmony_ci int actual_temp = 0; 20662306a36Sopenharmony_ci 20762306a36Sopenharmony_ci temp = (RREG32_SMC(CG_MULT_THERMAL_STATUS) & CTF_TEMP_MASK) >> 20862306a36Sopenharmony_ci CTF_TEMP_SHIFT; 20962306a36Sopenharmony_ci 21062306a36Sopenharmony_ci if (temp & 0x200) 21162306a36Sopenharmony_ci actual_temp = 255; 21262306a36Sopenharmony_ci else 21362306a36Sopenharmony_ci actual_temp = temp & 0x1ff; 21462306a36Sopenharmony_ci 21562306a36Sopenharmony_ci return actual_temp * 1000; 21662306a36Sopenharmony_ci} 21762306a36Sopenharmony_ci 21862306a36Sopenharmony_ci/* get temperature in millidegrees */ 21962306a36Sopenharmony_ciint kv_get_temp(struct radeon_device *rdev) 22062306a36Sopenharmony_ci{ 22162306a36Sopenharmony_ci u32 temp; 22262306a36Sopenharmony_ci int actual_temp = 0; 22362306a36Sopenharmony_ci 22462306a36Sopenharmony_ci temp = RREG32_SMC(0xC0300E0C); 22562306a36Sopenharmony_ci 22662306a36Sopenharmony_ci if (temp) 22762306a36Sopenharmony_ci actual_temp = (temp / 8) - 49; 22862306a36Sopenharmony_ci else 22962306a36Sopenharmony_ci actual_temp = 0; 23062306a36Sopenharmony_ci 23162306a36Sopenharmony_ci return actual_temp * 1000; 23262306a36Sopenharmony_ci} 23362306a36Sopenharmony_ci 23462306a36Sopenharmony_ci/* 23562306a36Sopenharmony_ci * Indirect registers accessor 23662306a36Sopenharmony_ci */ 23762306a36Sopenharmony_ciu32 cik_pciep_rreg(struct radeon_device *rdev, u32 reg) 23862306a36Sopenharmony_ci{ 23962306a36Sopenharmony_ci unsigned long flags; 24062306a36Sopenharmony_ci u32 r; 24162306a36Sopenharmony_ci 24262306a36Sopenharmony_ci spin_lock_irqsave(&rdev->pciep_idx_lock, flags); 24362306a36Sopenharmony_ci WREG32(PCIE_INDEX, reg); 24462306a36Sopenharmony_ci (void)RREG32(PCIE_INDEX); 24562306a36Sopenharmony_ci r = RREG32(PCIE_DATA); 24662306a36Sopenharmony_ci spin_unlock_irqrestore(&rdev->pciep_idx_lock, flags); 24762306a36Sopenharmony_ci return r; 24862306a36Sopenharmony_ci} 24962306a36Sopenharmony_ci 25062306a36Sopenharmony_civoid cik_pciep_wreg(struct radeon_device *rdev, u32 reg, u32 v) 25162306a36Sopenharmony_ci{ 25262306a36Sopenharmony_ci unsigned long flags; 25362306a36Sopenharmony_ci 25462306a36Sopenharmony_ci spin_lock_irqsave(&rdev->pciep_idx_lock, flags); 25562306a36Sopenharmony_ci WREG32(PCIE_INDEX, reg); 25662306a36Sopenharmony_ci (void)RREG32(PCIE_INDEX); 25762306a36Sopenharmony_ci WREG32(PCIE_DATA, v); 25862306a36Sopenharmony_ci (void)RREG32(PCIE_DATA); 25962306a36Sopenharmony_ci spin_unlock_irqrestore(&rdev->pciep_idx_lock, flags); 26062306a36Sopenharmony_ci} 26162306a36Sopenharmony_ci 26262306a36Sopenharmony_cistatic const u32 spectre_rlc_save_restore_register_list[] = 26362306a36Sopenharmony_ci{ 26462306a36Sopenharmony_ci (0x0e00 << 16) | (0xc12c >> 2), 26562306a36Sopenharmony_ci 0x00000000, 26662306a36Sopenharmony_ci (0x0e00 << 16) | (0xc140 >> 2), 26762306a36Sopenharmony_ci 0x00000000, 26862306a36Sopenharmony_ci (0x0e00 << 16) | (0xc150 >> 2), 26962306a36Sopenharmony_ci 0x00000000, 27062306a36Sopenharmony_ci (0x0e00 << 16) | (0xc15c >> 2), 27162306a36Sopenharmony_ci 0x00000000, 27262306a36Sopenharmony_ci (0x0e00 << 16) | (0xc168 >> 2), 27362306a36Sopenharmony_ci 0x00000000, 27462306a36Sopenharmony_ci (0x0e00 << 16) | (0xc170 >> 2), 27562306a36Sopenharmony_ci 0x00000000, 27662306a36Sopenharmony_ci (0x0e00 << 16) | (0xc178 >> 2), 27762306a36Sopenharmony_ci 0x00000000, 27862306a36Sopenharmony_ci (0x0e00 << 16) | (0xc204 >> 2), 27962306a36Sopenharmony_ci 0x00000000, 28062306a36Sopenharmony_ci (0x0e00 << 16) | (0xc2b4 >> 2), 28162306a36Sopenharmony_ci 0x00000000, 28262306a36Sopenharmony_ci (0x0e00 << 16) | (0xc2b8 >> 2), 28362306a36Sopenharmony_ci 0x00000000, 28462306a36Sopenharmony_ci (0x0e00 << 16) | (0xc2bc >> 2), 28562306a36Sopenharmony_ci 0x00000000, 28662306a36Sopenharmony_ci (0x0e00 << 16) | (0xc2c0 >> 2), 28762306a36Sopenharmony_ci 0x00000000, 28862306a36Sopenharmony_ci (0x0e00 << 16) | (0x8228 >> 2), 28962306a36Sopenharmony_ci 0x00000000, 29062306a36Sopenharmony_ci (0x0e00 << 16) | (0x829c >> 2), 29162306a36Sopenharmony_ci 0x00000000, 29262306a36Sopenharmony_ci (0x0e00 << 16) | (0x869c >> 2), 29362306a36Sopenharmony_ci 0x00000000, 29462306a36Sopenharmony_ci (0x0600 << 16) | (0x98f4 >> 2), 29562306a36Sopenharmony_ci 0x00000000, 29662306a36Sopenharmony_ci (0x0e00 << 16) | (0x98f8 >> 2), 29762306a36Sopenharmony_ci 0x00000000, 29862306a36Sopenharmony_ci (0x0e00 << 16) | (0x9900 >> 2), 29962306a36Sopenharmony_ci 0x00000000, 30062306a36Sopenharmony_ci (0x0e00 << 16) | (0xc260 >> 2), 30162306a36Sopenharmony_ci 0x00000000, 30262306a36Sopenharmony_ci (0x0e00 << 16) | (0x90e8 >> 2), 30362306a36Sopenharmony_ci 0x00000000, 30462306a36Sopenharmony_ci (0x0e00 << 16) | (0x3c000 >> 2), 30562306a36Sopenharmony_ci 0x00000000, 30662306a36Sopenharmony_ci (0x0e00 << 16) | (0x3c00c >> 2), 30762306a36Sopenharmony_ci 0x00000000, 30862306a36Sopenharmony_ci (0x0e00 << 16) | (0x8c1c >> 2), 30962306a36Sopenharmony_ci 0x00000000, 31062306a36Sopenharmony_ci (0x0e00 << 16) | (0x9700 >> 2), 31162306a36Sopenharmony_ci 0x00000000, 31262306a36Sopenharmony_ci (0x0e00 << 16) | (0xcd20 >> 2), 31362306a36Sopenharmony_ci 0x00000000, 31462306a36Sopenharmony_ci (0x4e00 << 16) | (0xcd20 >> 2), 31562306a36Sopenharmony_ci 0x00000000, 31662306a36Sopenharmony_ci (0x5e00 << 16) | (0xcd20 >> 2), 31762306a36Sopenharmony_ci 0x00000000, 31862306a36Sopenharmony_ci (0x6e00 << 16) | (0xcd20 >> 2), 31962306a36Sopenharmony_ci 0x00000000, 32062306a36Sopenharmony_ci (0x7e00 << 16) | (0xcd20 >> 2), 32162306a36Sopenharmony_ci 0x00000000, 32262306a36Sopenharmony_ci (0x8e00 << 16) | (0xcd20 >> 2), 32362306a36Sopenharmony_ci 0x00000000, 32462306a36Sopenharmony_ci (0x9e00 << 16) | (0xcd20 >> 2), 32562306a36Sopenharmony_ci 0x00000000, 32662306a36Sopenharmony_ci (0xae00 << 16) | (0xcd20 >> 2), 32762306a36Sopenharmony_ci 0x00000000, 32862306a36Sopenharmony_ci (0xbe00 << 16) | (0xcd20 >> 2), 32962306a36Sopenharmony_ci 0x00000000, 33062306a36Sopenharmony_ci (0x0e00 << 16) | (0x89bc >> 2), 33162306a36Sopenharmony_ci 0x00000000, 33262306a36Sopenharmony_ci (0x0e00 << 16) | (0x8900 >> 2), 33362306a36Sopenharmony_ci 0x00000000, 33462306a36Sopenharmony_ci 0x3, 33562306a36Sopenharmony_ci (0x0e00 << 16) | (0xc130 >> 2), 33662306a36Sopenharmony_ci 0x00000000, 33762306a36Sopenharmony_ci (0x0e00 << 16) | (0xc134 >> 2), 33862306a36Sopenharmony_ci 0x00000000, 33962306a36Sopenharmony_ci (0x0e00 << 16) | (0xc1fc >> 2), 34062306a36Sopenharmony_ci 0x00000000, 34162306a36Sopenharmony_ci (0x0e00 << 16) | (0xc208 >> 2), 34262306a36Sopenharmony_ci 0x00000000, 34362306a36Sopenharmony_ci (0x0e00 << 16) | (0xc264 >> 2), 34462306a36Sopenharmony_ci 0x00000000, 34562306a36Sopenharmony_ci (0x0e00 << 16) | (0xc268 >> 2), 34662306a36Sopenharmony_ci 0x00000000, 34762306a36Sopenharmony_ci (0x0e00 << 16) | (0xc26c >> 2), 34862306a36Sopenharmony_ci 0x00000000, 34962306a36Sopenharmony_ci (0x0e00 << 16) | (0xc270 >> 2), 35062306a36Sopenharmony_ci 0x00000000, 35162306a36Sopenharmony_ci (0x0e00 << 16) | (0xc274 >> 2), 35262306a36Sopenharmony_ci 0x00000000, 35362306a36Sopenharmony_ci (0x0e00 << 16) | (0xc278 >> 2), 35462306a36Sopenharmony_ci 0x00000000, 35562306a36Sopenharmony_ci (0x0e00 << 16) | (0xc27c >> 2), 35662306a36Sopenharmony_ci 0x00000000, 35762306a36Sopenharmony_ci (0x0e00 << 16) | (0xc280 >> 2), 35862306a36Sopenharmony_ci 0x00000000, 35962306a36Sopenharmony_ci (0x0e00 << 16) | (0xc284 >> 2), 36062306a36Sopenharmony_ci 0x00000000, 36162306a36Sopenharmony_ci (0x0e00 << 16) | (0xc288 >> 2), 36262306a36Sopenharmony_ci 0x00000000, 36362306a36Sopenharmony_ci (0x0e00 << 16) | (0xc28c >> 2), 36462306a36Sopenharmony_ci 0x00000000, 36562306a36Sopenharmony_ci (0x0e00 << 16) | (0xc290 >> 2), 36662306a36Sopenharmony_ci 0x00000000, 36762306a36Sopenharmony_ci (0x0e00 << 16) | (0xc294 >> 2), 36862306a36Sopenharmony_ci 0x00000000, 36962306a36Sopenharmony_ci (0x0e00 << 16) | (0xc298 >> 2), 37062306a36Sopenharmony_ci 0x00000000, 37162306a36Sopenharmony_ci (0x0e00 << 16) | (0xc29c >> 2), 37262306a36Sopenharmony_ci 0x00000000, 37362306a36Sopenharmony_ci (0x0e00 << 16) | (0xc2a0 >> 2), 37462306a36Sopenharmony_ci 0x00000000, 37562306a36Sopenharmony_ci (0x0e00 << 16) | (0xc2a4 >> 2), 37662306a36Sopenharmony_ci 0x00000000, 37762306a36Sopenharmony_ci (0x0e00 << 16) | (0xc2a8 >> 2), 37862306a36Sopenharmony_ci 0x00000000, 37962306a36Sopenharmony_ci (0x0e00 << 16) | (0xc2ac >> 2), 38062306a36Sopenharmony_ci 0x00000000, 38162306a36Sopenharmony_ci (0x0e00 << 16) | (0xc2b0 >> 2), 38262306a36Sopenharmony_ci 0x00000000, 38362306a36Sopenharmony_ci (0x0e00 << 16) | (0x301d0 >> 2), 38462306a36Sopenharmony_ci 0x00000000, 38562306a36Sopenharmony_ci (0x0e00 << 16) | (0x30238 >> 2), 38662306a36Sopenharmony_ci 0x00000000, 38762306a36Sopenharmony_ci (0x0e00 << 16) | (0x30250 >> 2), 38862306a36Sopenharmony_ci 0x00000000, 38962306a36Sopenharmony_ci (0x0e00 << 16) | (0x30254 >> 2), 39062306a36Sopenharmony_ci 0x00000000, 39162306a36Sopenharmony_ci (0x0e00 << 16) | (0x30258 >> 2), 39262306a36Sopenharmony_ci 0x00000000, 39362306a36Sopenharmony_ci (0x0e00 << 16) | (0x3025c >> 2), 39462306a36Sopenharmony_ci 0x00000000, 39562306a36Sopenharmony_ci (0x4e00 << 16) | (0xc900 >> 2), 39662306a36Sopenharmony_ci 0x00000000, 39762306a36Sopenharmony_ci (0x5e00 << 16) | (0xc900 >> 2), 39862306a36Sopenharmony_ci 0x00000000, 39962306a36Sopenharmony_ci (0x6e00 << 16) | (0xc900 >> 2), 40062306a36Sopenharmony_ci 0x00000000, 40162306a36Sopenharmony_ci (0x7e00 << 16) | (0xc900 >> 2), 40262306a36Sopenharmony_ci 0x00000000, 40362306a36Sopenharmony_ci (0x8e00 << 16) | (0xc900 >> 2), 40462306a36Sopenharmony_ci 0x00000000, 40562306a36Sopenharmony_ci (0x9e00 << 16) | (0xc900 >> 2), 40662306a36Sopenharmony_ci 0x00000000, 40762306a36Sopenharmony_ci (0xae00 << 16) | (0xc900 >> 2), 40862306a36Sopenharmony_ci 0x00000000, 40962306a36Sopenharmony_ci (0xbe00 << 16) | (0xc900 >> 2), 41062306a36Sopenharmony_ci 0x00000000, 41162306a36Sopenharmony_ci (0x4e00 << 16) | (0xc904 >> 2), 41262306a36Sopenharmony_ci 0x00000000, 41362306a36Sopenharmony_ci (0x5e00 << 16) | (0xc904 >> 2), 41462306a36Sopenharmony_ci 0x00000000, 41562306a36Sopenharmony_ci (0x6e00 << 16) | (0xc904 >> 2), 41662306a36Sopenharmony_ci 0x00000000, 41762306a36Sopenharmony_ci (0x7e00 << 16) | (0xc904 >> 2), 41862306a36Sopenharmony_ci 0x00000000, 41962306a36Sopenharmony_ci (0x8e00 << 16) | (0xc904 >> 2), 42062306a36Sopenharmony_ci 0x00000000, 42162306a36Sopenharmony_ci (0x9e00 << 16) | (0xc904 >> 2), 42262306a36Sopenharmony_ci 0x00000000, 42362306a36Sopenharmony_ci (0xae00 << 16) | (0xc904 >> 2), 42462306a36Sopenharmony_ci 0x00000000, 42562306a36Sopenharmony_ci (0xbe00 << 16) | (0xc904 >> 2), 42662306a36Sopenharmony_ci 0x00000000, 42762306a36Sopenharmony_ci (0x4e00 << 16) | (0xc908 >> 2), 42862306a36Sopenharmony_ci 0x00000000, 42962306a36Sopenharmony_ci (0x5e00 << 16) | (0xc908 >> 2), 43062306a36Sopenharmony_ci 0x00000000, 43162306a36Sopenharmony_ci (0x6e00 << 16) | (0xc908 >> 2), 43262306a36Sopenharmony_ci 0x00000000, 43362306a36Sopenharmony_ci (0x7e00 << 16) | (0xc908 >> 2), 43462306a36Sopenharmony_ci 0x00000000, 43562306a36Sopenharmony_ci (0x8e00 << 16) | (0xc908 >> 2), 43662306a36Sopenharmony_ci 0x00000000, 43762306a36Sopenharmony_ci (0x9e00 << 16) | (0xc908 >> 2), 43862306a36Sopenharmony_ci 0x00000000, 43962306a36Sopenharmony_ci (0xae00 << 16) | (0xc908 >> 2), 44062306a36Sopenharmony_ci 0x00000000, 44162306a36Sopenharmony_ci (0xbe00 << 16) | (0xc908 >> 2), 44262306a36Sopenharmony_ci 0x00000000, 44362306a36Sopenharmony_ci (0x4e00 << 16) | (0xc90c >> 2), 44462306a36Sopenharmony_ci 0x00000000, 44562306a36Sopenharmony_ci (0x5e00 << 16) | (0xc90c >> 2), 44662306a36Sopenharmony_ci 0x00000000, 44762306a36Sopenharmony_ci (0x6e00 << 16) | (0xc90c >> 2), 44862306a36Sopenharmony_ci 0x00000000, 44962306a36Sopenharmony_ci (0x7e00 << 16) | (0xc90c >> 2), 45062306a36Sopenharmony_ci 0x00000000, 45162306a36Sopenharmony_ci (0x8e00 << 16) | (0xc90c >> 2), 45262306a36Sopenharmony_ci 0x00000000, 45362306a36Sopenharmony_ci (0x9e00 << 16) | (0xc90c >> 2), 45462306a36Sopenharmony_ci 0x00000000, 45562306a36Sopenharmony_ci (0xae00 << 16) | (0xc90c >> 2), 45662306a36Sopenharmony_ci 0x00000000, 45762306a36Sopenharmony_ci (0xbe00 << 16) | (0xc90c >> 2), 45862306a36Sopenharmony_ci 0x00000000, 45962306a36Sopenharmony_ci (0x4e00 << 16) | (0xc910 >> 2), 46062306a36Sopenharmony_ci 0x00000000, 46162306a36Sopenharmony_ci (0x5e00 << 16) | (0xc910 >> 2), 46262306a36Sopenharmony_ci 0x00000000, 46362306a36Sopenharmony_ci (0x6e00 << 16) | (0xc910 >> 2), 46462306a36Sopenharmony_ci 0x00000000, 46562306a36Sopenharmony_ci (0x7e00 << 16) | (0xc910 >> 2), 46662306a36Sopenharmony_ci 0x00000000, 46762306a36Sopenharmony_ci (0x8e00 << 16) | (0xc910 >> 2), 46862306a36Sopenharmony_ci 0x00000000, 46962306a36Sopenharmony_ci (0x9e00 << 16) | (0xc910 >> 2), 47062306a36Sopenharmony_ci 0x00000000, 47162306a36Sopenharmony_ci (0xae00 << 16) | (0xc910 >> 2), 47262306a36Sopenharmony_ci 0x00000000, 47362306a36Sopenharmony_ci (0xbe00 << 16) | (0xc910 >> 2), 47462306a36Sopenharmony_ci 0x00000000, 47562306a36Sopenharmony_ci (0x0e00 << 16) | (0xc99c >> 2), 47662306a36Sopenharmony_ci 0x00000000, 47762306a36Sopenharmony_ci (0x0e00 << 16) | (0x9834 >> 2), 47862306a36Sopenharmony_ci 0x00000000, 47962306a36Sopenharmony_ci (0x0000 << 16) | (0x30f00 >> 2), 48062306a36Sopenharmony_ci 0x00000000, 48162306a36Sopenharmony_ci (0x0001 << 16) | (0x30f00 >> 2), 48262306a36Sopenharmony_ci 0x00000000, 48362306a36Sopenharmony_ci (0x0000 << 16) | (0x30f04 >> 2), 48462306a36Sopenharmony_ci 0x00000000, 48562306a36Sopenharmony_ci (0x0001 << 16) | (0x30f04 >> 2), 48662306a36Sopenharmony_ci 0x00000000, 48762306a36Sopenharmony_ci (0x0000 << 16) | (0x30f08 >> 2), 48862306a36Sopenharmony_ci 0x00000000, 48962306a36Sopenharmony_ci (0x0001 << 16) | (0x30f08 >> 2), 49062306a36Sopenharmony_ci 0x00000000, 49162306a36Sopenharmony_ci (0x0000 << 16) | (0x30f0c >> 2), 49262306a36Sopenharmony_ci 0x00000000, 49362306a36Sopenharmony_ci (0x0001 << 16) | (0x30f0c >> 2), 49462306a36Sopenharmony_ci 0x00000000, 49562306a36Sopenharmony_ci (0x0600 << 16) | (0x9b7c >> 2), 49662306a36Sopenharmony_ci 0x00000000, 49762306a36Sopenharmony_ci (0x0e00 << 16) | (0x8a14 >> 2), 49862306a36Sopenharmony_ci 0x00000000, 49962306a36Sopenharmony_ci (0x0e00 << 16) | (0x8a18 >> 2), 50062306a36Sopenharmony_ci 0x00000000, 50162306a36Sopenharmony_ci (0x0600 << 16) | (0x30a00 >> 2), 50262306a36Sopenharmony_ci 0x00000000, 50362306a36Sopenharmony_ci (0x0e00 << 16) | (0x8bf0 >> 2), 50462306a36Sopenharmony_ci 0x00000000, 50562306a36Sopenharmony_ci (0x0e00 << 16) | (0x8bcc >> 2), 50662306a36Sopenharmony_ci 0x00000000, 50762306a36Sopenharmony_ci (0x0e00 << 16) | (0x8b24 >> 2), 50862306a36Sopenharmony_ci 0x00000000, 50962306a36Sopenharmony_ci (0x0e00 << 16) | (0x30a04 >> 2), 51062306a36Sopenharmony_ci 0x00000000, 51162306a36Sopenharmony_ci (0x0600 << 16) | (0x30a10 >> 2), 51262306a36Sopenharmony_ci 0x00000000, 51362306a36Sopenharmony_ci (0x0600 << 16) | (0x30a14 >> 2), 51462306a36Sopenharmony_ci 0x00000000, 51562306a36Sopenharmony_ci (0x0600 << 16) | (0x30a18 >> 2), 51662306a36Sopenharmony_ci 0x00000000, 51762306a36Sopenharmony_ci (0x0600 << 16) | (0x30a2c >> 2), 51862306a36Sopenharmony_ci 0x00000000, 51962306a36Sopenharmony_ci (0x0e00 << 16) | (0xc700 >> 2), 52062306a36Sopenharmony_ci 0x00000000, 52162306a36Sopenharmony_ci (0x0e00 << 16) | (0xc704 >> 2), 52262306a36Sopenharmony_ci 0x00000000, 52362306a36Sopenharmony_ci (0x0e00 << 16) | (0xc708 >> 2), 52462306a36Sopenharmony_ci 0x00000000, 52562306a36Sopenharmony_ci (0x0e00 << 16) | (0xc768 >> 2), 52662306a36Sopenharmony_ci 0x00000000, 52762306a36Sopenharmony_ci (0x0400 << 16) | (0xc770 >> 2), 52862306a36Sopenharmony_ci 0x00000000, 52962306a36Sopenharmony_ci (0x0400 << 16) | (0xc774 >> 2), 53062306a36Sopenharmony_ci 0x00000000, 53162306a36Sopenharmony_ci (0x0400 << 16) | (0xc778 >> 2), 53262306a36Sopenharmony_ci 0x00000000, 53362306a36Sopenharmony_ci (0x0400 << 16) | (0xc77c >> 2), 53462306a36Sopenharmony_ci 0x00000000, 53562306a36Sopenharmony_ci (0x0400 << 16) | (0xc780 >> 2), 53662306a36Sopenharmony_ci 0x00000000, 53762306a36Sopenharmony_ci (0x0400 << 16) | (0xc784 >> 2), 53862306a36Sopenharmony_ci 0x00000000, 53962306a36Sopenharmony_ci (0x0400 << 16) | (0xc788 >> 2), 54062306a36Sopenharmony_ci 0x00000000, 54162306a36Sopenharmony_ci (0x0400 << 16) | (0xc78c >> 2), 54262306a36Sopenharmony_ci 0x00000000, 54362306a36Sopenharmony_ci (0x0400 << 16) | (0xc798 >> 2), 54462306a36Sopenharmony_ci 0x00000000, 54562306a36Sopenharmony_ci (0x0400 << 16) | (0xc79c >> 2), 54662306a36Sopenharmony_ci 0x00000000, 54762306a36Sopenharmony_ci (0x0400 << 16) | (0xc7a0 >> 2), 54862306a36Sopenharmony_ci 0x00000000, 54962306a36Sopenharmony_ci (0x0400 << 16) | (0xc7a4 >> 2), 55062306a36Sopenharmony_ci 0x00000000, 55162306a36Sopenharmony_ci (0x0400 << 16) | (0xc7a8 >> 2), 55262306a36Sopenharmony_ci 0x00000000, 55362306a36Sopenharmony_ci (0x0400 << 16) | (0xc7ac >> 2), 55462306a36Sopenharmony_ci 0x00000000, 55562306a36Sopenharmony_ci (0x0400 << 16) | (0xc7b0 >> 2), 55662306a36Sopenharmony_ci 0x00000000, 55762306a36Sopenharmony_ci (0x0400 << 16) | (0xc7b4 >> 2), 55862306a36Sopenharmony_ci 0x00000000, 55962306a36Sopenharmony_ci (0x0e00 << 16) | (0x9100 >> 2), 56062306a36Sopenharmony_ci 0x00000000, 56162306a36Sopenharmony_ci (0x0e00 << 16) | (0x3c010 >> 2), 56262306a36Sopenharmony_ci 0x00000000, 56362306a36Sopenharmony_ci (0x0e00 << 16) | (0x92a8 >> 2), 56462306a36Sopenharmony_ci 0x00000000, 56562306a36Sopenharmony_ci (0x0e00 << 16) | (0x92ac >> 2), 56662306a36Sopenharmony_ci 0x00000000, 56762306a36Sopenharmony_ci (0x0e00 << 16) | (0x92b4 >> 2), 56862306a36Sopenharmony_ci 0x00000000, 56962306a36Sopenharmony_ci (0x0e00 << 16) | (0x92b8 >> 2), 57062306a36Sopenharmony_ci 0x00000000, 57162306a36Sopenharmony_ci (0x0e00 << 16) | (0x92bc >> 2), 57262306a36Sopenharmony_ci 0x00000000, 57362306a36Sopenharmony_ci (0x0e00 << 16) | (0x92c0 >> 2), 57462306a36Sopenharmony_ci 0x00000000, 57562306a36Sopenharmony_ci (0x0e00 << 16) | (0x92c4 >> 2), 57662306a36Sopenharmony_ci 0x00000000, 57762306a36Sopenharmony_ci (0x0e00 << 16) | (0x92c8 >> 2), 57862306a36Sopenharmony_ci 0x00000000, 57962306a36Sopenharmony_ci (0x0e00 << 16) | (0x92cc >> 2), 58062306a36Sopenharmony_ci 0x00000000, 58162306a36Sopenharmony_ci (0x0e00 << 16) | (0x92d0 >> 2), 58262306a36Sopenharmony_ci 0x00000000, 58362306a36Sopenharmony_ci (0x0e00 << 16) | (0x8c00 >> 2), 58462306a36Sopenharmony_ci 0x00000000, 58562306a36Sopenharmony_ci (0x0e00 << 16) | (0x8c04 >> 2), 58662306a36Sopenharmony_ci 0x00000000, 58762306a36Sopenharmony_ci (0x0e00 << 16) | (0x8c20 >> 2), 58862306a36Sopenharmony_ci 0x00000000, 58962306a36Sopenharmony_ci (0x0e00 << 16) | (0x8c38 >> 2), 59062306a36Sopenharmony_ci 0x00000000, 59162306a36Sopenharmony_ci (0x0e00 << 16) | (0x8c3c >> 2), 59262306a36Sopenharmony_ci 0x00000000, 59362306a36Sopenharmony_ci (0x0e00 << 16) | (0xae00 >> 2), 59462306a36Sopenharmony_ci 0x00000000, 59562306a36Sopenharmony_ci (0x0e00 << 16) | (0x9604 >> 2), 59662306a36Sopenharmony_ci 0x00000000, 59762306a36Sopenharmony_ci (0x0e00 << 16) | (0xac08 >> 2), 59862306a36Sopenharmony_ci 0x00000000, 59962306a36Sopenharmony_ci (0x0e00 << 16) | (0xac0c >> 2), 60062306a36Sopenharmony_ci 0x00000000, 60162306a36Sopenharmony_ci (0x0e00 << 16) | (0xac10 >> 2), 60262306a36Sopenharmony_ci 0x00000000, 60362306a36Sopenharmony_ci (0x0e00 << 16) | (0xac14 >> 2), 60462306a36Sopenharmony_ci 0x00000000, 60562306a36Sopenharmony_ci (0x0e00 << 16) | (0xac58 >> 2), 60662306a36Sopenharmony_ci 0x00000000, 60762306a36Sopenharmony_ci (0x0e00 << 16) | (0xac68 >> 2), 60862306a36Sopenharmony_ci 0x00000000, 60962306a36Sopenharmony_ci (0x0e00 << 16) | (0xac6c >> 2), 61062306a36Sopenharmony_ci 0x00000000, 61162306a36Sopenharmony_ci (0x0e00 << 16) | (0xac70 >> 2), 61262306a36Sopenharmony_ci 0x00000000, 61362306a36Sopenharmony_ci (0x0e00 << 16) | (0xac74 >> 2), 61462306a36Sopenharmony_ci 0x00000000, 61562306a36Sopenharmony_ci (0x0e00 << 16) | (0xac78 >> 2), 61662306a36Sopenharmony_ci 0x00000000, 61762306a36Sopenharmony_ci (0x0e00 << 16) | (0xac7c >> 2), 61862306a36Sopenharmony_ci 0x00000000, 61962306a36Sopenharmony_ci (0x0e00 << 16) | (0xac80 >> 2), 62062306a36Sopenharmony_ci 0x00000000, 62162306a36Sopenharmony_ci (0x0e00 << 16) | (0xac84 >> 2), 62262306a36Sopenharmony_ci 0x00000000, 62362306a36Sopenharmony_ci (0x0e00 << 16) | (0xac88 >> 2), 62462306a36Sopenharmony_ci 0x00000000, 62562306a36Sopenharmony_ci (0x0e00 << 16) | (0xac8c >> 2), 62662306a36Sopenharmony_ci 0x00000000, 62762306a36Sopenharmony_ci (0x0e00 << 16) | (0x970c >> 2), 62862306a36Sopenharmony_ci 0x00000000, 62962306a36Sopenharmony_ci (0x0e00 << 16) | (0x9714 >> 2), 63062306a36Sopenharmony_ci 0x00000000, 63162306a36Sopenharmony_ci (0x0e00 << 16) | (0x9718 >> 2), 63262306a36Sopenharmony_ci 0x00000000, 63362306a36Sopenharmony_ci (0x0e00 << 16) | (0x971c >> 2), 63462306a36Sopenharmony_ci 0x00000000, 63562306a36Sopenharmony_ci (0x0e00 << 16) | (0x31068 >> 2), 63662306a36Sopenharmony_ci 0x00000000, 63762306a36Sopenharmony_ci (0x4e00 << 16) | (0x31068 >> 2), 63862306a36Sopenharmony_ci 0x00000000, 63962306a36Sopenharmony_ci (0x5e00 << 16) | (0x31068 >> 2), 64062306a36Sopenharmony_ci 0x00000000, 64162306a36Sopenharmony_ci (0x6e00 << 16) | (0x31068 >> 2), 64262306a36Sopenharmony_ci 0x00000000, 64362306a36Sopenharmony_ci (0x7e00 << 16) | (0x31068 >> 2), 64462306a36Sopenharmony_ci 0x00000000, 64562306a36Sopenharmony_ci (0x8e00 << 16) | (0x31068 >> 2), 64662306a36Sopenharmony_ci 0x00000000, 64762306a36Sopenharmony_ci (0x9e00 << 16) | (0x31068 >> 2), 64862306a36Sopenharmony_ci 0x00000000, 64962306a36Sopenharmony_ci (0xae00 << 16) | (0x31068 >> 2), 65062306a36Sopenharmony_ci 0x00000000, 65162306a36Sopenharmony_ci (0xbe00 << 16) | (0x31068 >> 2), 65262306a36Sopenharmony_ci 0x00000000, 65362306a36Sopenharmony_ci (0x0e00 << 16) | (0xcd10 >> 2), 65462306a36Sopenharmony_ci 0x00000000, 65562306a36Sopenharmony_ci (0x0e00 << 16) | (0xcd14 >> 2), 65662306a36Sopenharmony_ci 0x00000000, 65762306a36Sopenharmony_ci (0x0e00 << 16) | (0x88b0 >> 2), 65862306a36Sopenharmony_ci 0x00000000, 65962306a36Sopenharmony_ci (0x0e00 << 16) | (0x88b4 >> 2), 66062306a36Sopenharmony_ci 0x00000000, 66162306a36Sopenharmony_ci (0x0e00 << 16) | (0x88b8 >> 2), 66262306a36Sopenharmony_ci 0x00000000, 66362306a36Sopenharmony_ci (0x0e00 << 16) | (0x88bc >> 2), 66462306a36Sopenharmony_ci 0x00000000, 66562306a36Sopenharmony_ci (0x0400 << 16) | (0x89c0 >> 2), 66662306a36Sopenharmony_ci 0x00000000, 66762306a36Sopenharmony_ci (0x0e00 << 16) | (0x88c4 >> 2), 66862306a36Sopenharmony_ci 0x00000000, 66962306a36Sopenharmony_ci (0x0e00 << 16) | (0x88c8 >> 2), 67062306a36Sopenharmony_ci 0x00000000, 67162306a36Sopenharmony_ci (0x0e00 << 16) | (0x88d0 >> 2), 67262306a36Sopenharmony_ci 0x00000000, 67362306a36Sopenharmony_ci (0x0e00 << 16) | (0x88d4 >> 2), 67462306a36Sopenharmony_ci 0x00000000, 67562306a36Sopenharmony_ci (0x0e00 << 16) | (0x88d8 >> 2), 67662306a36Sopenharmony_ci 0x00000000, 67762306a36Sopenharmony_ci (0x0e00 << 16) | (0x8980 >> 2), 67862306a36Sopenharmony_ci 0x00000000, 67962306a36Sopenharmony_ci (0x0e00 << 16) | (0x30938 >> 2), 68062306a36Sopenharmony_ci 0x00000000, 68162306a36Sopenharmony_ci (0x0e00 << 16) | (0x3093c >> 2), 68262306a36Sopenharmony_ci 0x00000000, 68362306a36Sopenharmony_ci (0x0e00 << 16) | (0x30940 >> 2), 68462306a36Sopenharmony_ci 0x00000000, 68562306a36Sopenharmony_ci (0x0e00 << 16) | (0x89a0 >> 2), 68662306a36Sopenharmony_ci 0x00000000, 68762306a36Sopenharmony_ci (0x0e00 << 16) | (0x30900 >> 2), 68862306a36Sopenharmony_ci 0x00000000, 68962306a36Sopenharmony_ci (0x0e00 << 16) | (0x30904 >> 2), 69062306a36Sopenharmony_ci 0x00000000, 69162306a36Sopenharmony_ci (0x0e00 << 16) | (0x89b4 >> 2), 69262306a36Sopenharmony_ci 0x00000000, 69362306a36Sopenharmony_ci (0x0e00 << 16) | (0x3c210 >> 2), 69462306a36Sopenharmony_ci 0x00000000, 69562306a36Sopenharmony_ci (0x0e00 << 16) | (0x3c214 >> 2), 69662306a36Sopenharmony_ci 0x00000000, 69762306a36Sopenharmony_ci (0x0e00 << 16) | (0x3c218 >> 2), 69862306a36Sopenharmony_ci 0x00000000, 69962306a36Sopenharmony_ci (0x0e00 << 16) | (0x8904 >> 2), 70062306a36Sopenharmony_ci 0x00000000, 70162306a36Sopenharmony_ci 0x5, 70262306a36Sopenharmony_ci (0x0e00 << 16) | (0x8c28 >> 2), 70362306a36Sopenharmony_ci (0x0e00 << 16) | (0x8c2c >> 2), 70462306a36Sopenharmony_ci (0x0e00 << 16) | (0x8c30 >> 2), 70562306a36Sopenharmony_ci (0x0e00 << 16) | (0x8c34 >> 2), 70662306a36Sopenharmony_ci (0x0e00 << 16) | (0x9600 >> 2), 70762306a36Sopenharmony_ci}; 70862306a36Sopenharmony_ci 70962306a36Sopenharmony_cistatic const u32 kalindi_rlc_save_restore_register_list[] = 71062306a36Sopenharmony_ci{ 71162306a36Sopenharmony_ci (0x0e00 << 16) | (0xc12c >> 2), 71262306a36Sopenharmony_ci 0x00000000, 71362306a36Sopenharmony_ci (0x0e00 << 16) | (0xc140 >> 2), 71462306a36Sopenharmony_ci 0x00000000, 71562306a36Sopenharmony_ci (0x0e00 << 16) | (0xc150 >> 2), 71662306a36Sopenharmony_ci 0x00000000, 71762306a36Sopenharmony_ci (0x0e00 << 16) | (0xc15c >> 2), 71862306a36Sopenharmony_ci 0x00000000, 71962306a36Sopenharmony_ci (0x0e00 << 16) | (0xc168 >> 2), 72062306a36Sopenharmony_ci 0x00000000, 72162306a36Sopenharmony_ci (0x0e00 << 16) | (0xc170 >> 2), 72262306a36Sopenharmony_ci 0x00000000, 72362306a36Sopenharmony_ci (0x0e00 << 16) | (0xc204 >> 2), 72462306a36Sopenharmony_ci 0x00000000, 72562306a36Sopenharmony_ci (0x0e00 << 16) | (0xc2b4 >> 2), 72662306a36Sopenharmony_ci 0x00000000, 72762306a36Sopenharmony_ci (0x0e00 << 16) | (0xc2b8 >> 2), 72862306a36Sopenharmony_ci 0x00000000, 72962306a36Sopenharmony_ci (0x0e00 << 16) | (0xc2bc >> 2), 73062306a36Sopenharmony_ci 0x00000000, 73162306a36Sopenharmony_ci (0x0e00 << 16) | (0xc2c0 >> 2), 73262306a36Sopenharmony_ci 0x00000000, 73362306a36Sopenharmony_ci (0x0e00 << 16) | (0x8228 >> 2), 73462306a36Sopenharmony_ci 0x00000000, 73562306a36Sopenharmony_ci (0x0e00 << 16) | (0x829c >> 2), 73662306a36Sopenharmony_ci 0x00000000, 73762306a36Sopenharmony_ci (0x0e00 << 16) | (0x869c >> 2), 73862306a36Sopenharmony_ci 0x00000000, 73962306a36Sopenharmony_ci (0x0600 << 16) | (0x98f4 >> 2), 74062306a36Sopenharmony_ci 0x00000000, 74162306a36Sopenharmony_ci (0x0e00 << 16) | (0x98f8 >> 2), 74262306a36Sopenharmony_ci 0x00000000, 74362306a36Sopenharmony_ci (0x0e00 << 16) | (0x9900 >> 2), 74462306a36Sopenharmony_ci 0x00000000, 74562306a36Sopenharmony_ci (0x0e00 << 16) | (0xc260 >> 2), 74662306a36Sopenharmony_ci 0x00000000, 74762306a36Sopenharmony_ci (0x0e00 << 16) | (0x90e8 >> 2), 74862306a36Sopenharmony_ci 0x00000000, 74962306a36Sopenharmony_ci (0x0e00 << 16) | (0x3c000 >> 2), 75062306a36Sopenharmony_ci 0x00000000, 75162306a36Sopenharmony_ci (0x0e00 << 16) | (0x3c00c >> 2), 75262306a36Sopenharmony_ci 0x00000000, 75362306a36Sopenharmony_ci (0x0e00 << 16) | (0x8c1c >> 2), 75462306a36Sopenharmony_ci 0x00000000, 75562306a36Sopenharmony_ci (0x0e00 << 16) | (0x9700 >> 2), 75662306a36Sopenharmony_ci 0x00000000, 75762306a36Sopenharmony_ci (0x0e00 << 16) | (0xcd20 >> 2), 75862306a36Sopenharmony_ci 0x00000000, 75962306a36Sopenharmony_ci (0x4e00 << 16) | (0xcd20 >> 2), 76062306a36Sopenharmony_ci 0x00000000, 76162306a36Sopenharmony_ci (0x5e00 << 16) | (0xcd20 >> 2), 76262306a36Sopenharmony_ci 0x00000000, 76362306a36Sopenharmony_ci (0x6e00 << 16) | (0xcd20 >> 2), 76462306a36Sopenharmony_ci 0x00000000, 76562306a36Sopenharmony_ci (0x7e00 << 16) | (0xcd20 >> 2), 76662306a36Sopenharmony_ci 0x00000000, 76762306a36Sopenharmony_ci (0x0e00 << 16) | (0x89bc >> 2), 76862306a36Sopenharmony_ci 0x00000000, 76962306a36Sopenharmony_ci (0x0e00 << 16) | (0x8900 >> 2), 77062306a36Sopenharmony_ci 0x00000000, 77162306a36Sopenharmony_ci 0x3, 77262306a36Sopenharmony_ci (0x0e00 << 16) | (0xc130 >> 2), 77362306a36Sopenharmony_ci 0x00000000, 77462306a36Sopenharmony_ci (0x0e00 << 16) | (0xc134 >> 2), 77562306a36Sopenharmony_ci 0x00000000, 77662306a36Sopenharmony_ci (0x0e00 << 16) | (0xc1fc >> 2), 77762306a36Sopenharmony_ci 0x00000000, 77862306a36Sopenharmony_ci (0x0e00 << 16) | (0xc208 >> 2), 77962306a36Sopenharmony_ci 0x00000000, 78062306a36Sopenharmony_ci (0x0e00 << 16) | (0xc264 >> 2), 78162306a36Sopenharmony_ci 0x00000000, 78262306a36Sopenharmony_ci (0x0e00 << 16) | (0xc268 >> 2), 78362306a36Sopenharmony_ci 0x00000000, 78462306a36Sopenharmony_ci (0x0e00 << 16) | (0xc26c >> 2), 78562306a36Sopenharmony_ci 0x00000000, 78662306a36Sopenharmony_ci (0x0e00 << 16) | (0xc270 >> 2), 78762306a36Sopenharmony_ci 0x00000000, 78862306a36Sopenharmony_ci (0x0e00 << 16) | (0xc274 >> 2), 78962306a36Sopenharmony_ci 0x00000000, 79062306a36Sopenharmony_ci (0x0e00 << 16) | (0xc28c >> 2), 79162306a36Sopenharmony_ci 0x00000000, 79262306a36Sopenharmony_ci (0x0e00 << 16) | (0xc290 >> 2), 79362306a36Sopenharmony_ci 0x00000000, 79462306a36Sopenharmony_ci (0x0e00 << 16) | (0xc294 >> 2), 79562306a36Sopenharmony_ci 0x00000000, 79662306a36Sopenharmony_ci (0x0e00 << 16) | (0xc298 >> 2), 79762306a36Sopenharmony_ci 0x00000000, 79862306a36Sopenharmony_ci (0x0e00 << 16) | (0xc2a0 >> 2), 79962306a36Sopenharmony_ci 0x00000000, 80062306a36Sopenharmony_ci (0x0e00 << 16) | (0xc2a4 >> 2), 80162306a36Sopenharmony_ci 0x00000000, 80262306a36Sopenharmony_ci (0x0e00 << 16) | (0xc2a8 >> 2), 80362306a36Sopenharmony_ci 0x00000000, 80462306a36Sopenharmony_ci (0x0e00 << 16) | (0xc2ac >> 2), 80562306a36Sopenharmony_ci 0x00000000, 80662306a36Sopenharmony_ci (0x0e00 << 16) | (0x301d0 >> 2), 80762306a36Sopenharmony_ci 0x00000000, 80862306a36Sopenharmony_ci (0x0e00 << 16) | (0x30238 >> 2), 80962306a36Sopenharmony_ci 0x00000000, 81062306a36Sopenharmony_ci (0x0e00 << 16) | (0x30250 >> 2), 81162306a36Sopenharmony_ci 0x00000000, 81262306a36Sopenharmony_ci (0x0e00 << 16) | (0x30254 >> 2), 81362306a36Sopenharmony_ci 0x00000000, 81462306a36Sopenharmony_ci (0x0e00 << 16) | (0x30258 >> 2), 81562306a36Sopenharmony_ci 0x00000000, 81662306a36Sopenharmony_ci (0x0e00 << 16) | (0x3025c >> 2), 81762306a36Sopenharmony_ci 0x00000000, 81862306a36Sopenharmony_ci (0x4e00 << 16) | (0xc900 >> 2), 81962306a36Sopenharmony_ci 0x00000000, 82062306a36Sopenharmony_ci (0x5e00 << 16) | (0xc900 >> 2), 82162306a36Sopenharmony_ci 0x00000000, 82262306a36Sopenharmony_ci (0x6e00 << 16) | (0xc900 >> 2), 82362306a36Sopenharmony_ci 0x00000000, 82462306a36Sopenharmony_ci (0x7e00 << 16) | (0xc900 >> 2), 82562306a36Sopenharmony_ci 0x00000000, 82662306a36Sopenharmony_ci (0x4e00 << 16) | (0xc904 >> 2), 82762306a36Sopenharmony_ci 0x00000000, 82862306a36Sopenharmony_ci (0x5e00 << 16) | (0xc904 >> 2), 82962306a36Sopenharmony_ci 0x00000000, 83062306a36Sopenharmony_ci (0x6e00 << 16) | (0xc904 >> 2), 83162306a36Sopenharmony_ci 0x00000000, 83262306a36Sopenharmony_ci (0x7e00 << 16) | (0xc904 >> 2), 83362306a36Sopenharmony_ci 0x00000000, 83462306a36Sopenharmony_ci (0x4e00 << 16) | (0xc908 >> 2), 83562306a36Sopenharmony_ci 0x00000000, 83662306a36Sopenharmony_ci (0x5e00 << 16) | (0xc908 >> 2), 83762306a36Sopenharmony_ci 0x00000000, 83862306a36Sopenharmony_ci (0x6e00 << 16) | (0xc908 >> 2), 83962306a36Sopenharmony_ci 0x00000000, 84062306a36Sopenharmony_ci (0x7e00 << 16) | (0xc908 >> 2), 84162306a36Sopenharmony_ci 0x00000000, 84262306a36Sopenharmony_ci (0x4e00 << 16) | (0xc90c >> 2), 84362306a36Sopenharmony_ci 0x00000000, 84462306a36Sopenharmony_ci (0x5e00 << 16) | (0xc90c >> 2), 84562306a36Sopenharmony_ci 0x00000000, 84662306a36Sopenharmony_ci (0x6e00 << 16) | (0xc90c >> 2), 84762306a36Sopenharmony_ci 0x00000000, 84862306a36Sopenharmony_ci (0x7e00 << 16) | (0xc90c >> 2), 84962306a36Sopenharmony_ci 0x00000000, 85062306a36Sopenharmony_ci (0x4e00 << 16) | (0xc910 >> 2), 85162306a36Sopenharmony_ci 0x00000000, 85262306a36Sopenharmony_ci (0x5e00 << 16) | (0xc910 >> 2), 85362306a36Sopenharmony_ci 0x00000000, 85462306a36Sopenharmony_ci (0x6e00 << 16) | (0xc910 >> 2), 85562306a36Sopenharmony_ci 0x00000000, 85662306a36Sopenharmony_ci (0x7e00 << 16) | (0xc910 >> 2), 85762306a36Sopenharmony_ci 0x00000000, 85862306a36Sopenharmony_ci (0x0e00 << 16) | (0xc99c >> 2), 85962306a36Sopenharmony_ci 0x00000000, 86062306a36Sopenharmony_ci (0x0e00 << 16) | (0x9834 >> 2), 86162306a36Sopenharmony_ci 0x00000000, 86262306a36Sopenharmony_ci (0x0000 << 16) | (0x30f00 >> 2), 86362306a36Sopenharmony_ci 0x00000000, 86462306a36Sopenharmony_ci (0x0000 << 16) | (0x30f04 >> 2), 86562306a36Sopenharmony_ci 0x00000000, 86662306a36Sopenharmony_ci (0x0000 << 16) | (0x30f08 >> 2), 86762306a36Sopenharmony_ci 0x00000000, 86862306a36Sopenharmony_ci (0x0000 << 16) | (0x30f0c >> 2), 86962306a36Sopenharmony_ci 0x00000000, 87062306a36Sopenharmony_ci (0x0600 << 16) | (0x9b7c >> 2), 87162306a36Sopenharmony_ci 0x00000000, 87262306a36Sopenharmony_ci (0x0e00 << 16) | (0x8a14 >> 2), 87362306a36Sopenharmony_ci 0x00000000, 87462306a36Sopenharmony_ci (0x0e00 << 16) | (0x8a18 >> 2), 87562306a36Sopenharmony_ci 0x00000000, 87662306a36Sopenharmony_ci (0x0600 << 16) | (0x30a00 >> 2), 87762306a36Sopenharmony_ci 0x00000000, 87862306a36Sopenharmony_ci (0x0e00 << 16) | (0x8bf0 >> 2), 87962306a36Sopenharmony_ci 0x00000000, 88062306a36Sopenharmony_ci (0x0e00 << 16) | (0x8bcc >> 2), 88162306a36Sopenharmony_ci 0x00000000, 88262306a36Sopenharmony_ci (0x0e00 << 16) | (0x8b24 >> 2), 88362306a36Sopenharmony_ci 0x00000000, 88462306a36Sopenharmony_ci (0x0e00 << 16) | (0x30a04 >> 2), 88562306a36Sopenharmony_ci 0x00000000, 88662306a36Sopenharmony_ci (0x0600 << 16) | (0x30a10 >> 2), 88762306a36Sopenharmony_ci 0x00000000, 88862306a36Sopenharmony_ci (0x0600 << 16) | (0x30a14 >> 2), 88962306a36Sopenharmony_ci 0x00000000, 89062306a36Sopenharmony_ci (0x0600 << 16) | (0x30a18 >> 2), 89162306a36Sopenharmony_ci 0x00000000, 89262306a36Sopenharmony_ci (0x0600 << 16) | (0x30a2c >> 2), 89362306a36Sopenharmony_ci 0x00000000, 89462306a36Sopenharmony_ci (0x0e00 << 16) | (0xc700 >> 2), 89562306a36Sopenharmony_ci 0x00000000, 89662306a36Sopenharmony_ci (0x0e00 << 16) | (0xc704 >> 2), 89762306a36Sopenharmony_ci 0x00000000, 89862306a36Sopenharmony_ci (0x0e00 << 16) | (0xc708 >> 2), 89962306a36Sopenharmony_ci 0x00000000, 90062306a36Sopenharmony_ci (0x0e00 << 16) | (0xc768 >> 2), 90162306a36Sopenharmony_ci 0x00000000, 90262306a36Sopenharmony_ci (0x0400 << 16) | (0xc770 >> 2), 90362306a36Sopenharmony_ci 0x00000000, 90462306a36Sopenharmony_ci (0x0400 << 16) | (0xc774 >> 2), 90562306a36Sopenharmony_ci 0x00000000, 90662306a36Sopenharmony_ci (0x0400 << 16) | (0xc798 >> 2), 90762306a36Sopenharmony_ci 0x00000000, 90862306a36Sopenharmony_ci (0x0400 << 16) | (0xc79c >> 2), 90962306a36Sopenharmony_ci 0x00000000, 91062306a36Sopenharmony_ci (0x0e00 << 16) | (0x9100 >> 2), 91162306a36Sopenharmony_ci 0x00000000, 91262306a36Sopenharmony_ci (0x0e00 << 16) | (0x3c010 >> 2), 91362306a36Sopenharmony_ci 0x00000000, 91462306a36Sopenharmony_ci (0x0e00 << 16) | (0x8c00 >> 2), 91562306a36Sopenharmony_ci 0x00000000, 91662306a36Sopenharmony_ci (0x0e00 << 16) | (0x8c04 >> 2), 91762306a36Sopenharmony_ci 0x00000000, 91862306a36Sopenharmony_ci (0x0e00 << 16) | (0x8c20 >> 2), 91962306a36Sopenharmony_ci 0x00000000, 92062306a36Sopenharmony_ci (0x0e00 << 16) | (0x8c38 >> 2), 92162306a36Sopenharmony_ci 0x00000000, 92262306a36Sopenharmony_ci (0x0e00 << 16) | (0x8c3c >> 2), 92362306a36Sopenharmony_ci 0x00000000, 92462306a36Sopenharmony_ci (0x0e00 << 16) | (0xae00 >> 2), 92562306a36Sopenharmony_ci 0x00000000, 92662306a36Sopenharmony_ci (0x0e00 << 16) | (0x9604 >> 2), 92762306a36Sopenharmony_ci 0x00000000, 92862306a36Sopenharmony_ci (0x0e00 << 16) | (0xac08 >> 2), 92962306a36Sopenharmony_ci 0x00000000, 93062306a36Sopenharmony_ci (0x0e00 << 16) | (0xac0c >> 2), 93162306a36Sopenharmony_ci 0x00000000, 93262306a36Sopenharmony_ci (0x0e00 << 16) | (0xac10 >> 2), 93362306a36Sopenharmony_ci 0x00000000, 93462306a36Sopenharmony_ci (0x0e00 << 16) | (0xac14 >> 2), 93562306a36Sopenharmony_ci 0x00000000, 93662306a36Sopenharmony_ci (0x0e00 << 16) | (0xac58 >> 2), 93762306a36Sopenharmony_ci 0x00000000, 93862306a36Sopenharmony_ci (0x0e00 << 16) | (0xac68 >> 2), 93962306a36Sopenharmony_ci 0x00000000, 94062306a36Sopenharmony_ci (0x0e00 << 16) | (0xac6c >> 2), 94162306a36Sopenharmony_ci 0x00000000, 94262306a36Sopenharmony_ci (0x0e00 << 16) | (0xac70 >> 2), 94362306a36Sopenharmony_ci 0x00000000, 94462306a36Sopenharmony_ci (0x0e00 << 16) | (0xac74 >> 2), 94562306a36Sopenharmony_ci 0x00000000, 94662306a36Sopenharmony_ci (0x0e00 << 16) | (0xac78 >> 2), 94762306a36Sopenharmony_ci 0x00000000, 94862306a36Sopenharmony_ci (0x0e00 << 16) | (0xac7c >> 2), 94962306a36Sopenharmony_ci 0x00000000, 95062306a36Sopenharmony_ci (0x0e00 << 16) | (0xac80 >> 2), 95162306a36Sopenharmony_ci 0x00000000, 95262306a36Sopenharmony_ci (0x0e00 << 16) | (0xac84 >> 2), 95362306a36Sopenharmony_ci 0x00000000, 95462306a36Sopenharmony_ci (0x0e00 << 16) | (0xac88 >> 2), 95562306a36Sopenharmony_ci 0x00000000, 95662306a36Sopenharmony_ci (0x0e00 << 16) | (0xac8c >> 2), 95762306a36Sopenharmony_ci 0x00000000, 95862306a36Sopenharmony_ci (0x0e00 << 16) | (0x970c >> 2), 95962306a36Sopenharmony_ci 0x00000000, 96062306a36Sopenharmony_ci (0x0e00 << 16) | (0x9714 >> 2), 96162306a36Sopenharmony_ci 0x00000000, 96262306a36Sopenharmony_ci (0x0e00 << 16) | (0x9718 >> 2), 96362306a36Sopenharmony_ci 0x00000000, 96462306a36Sopenharmony_ci (0x0e00 << 16) | (0x971c >> 2), 96562306a36Sopenharmony_ci 0x00000000, 96662306a36Sopenharmony_ci (0x0e00 << 16) | (0x31068 >> 2), 96762306a36Sopenharmony_ci 0x00000000, 96862306a36Sopenharmony_ci (0x4e00 << 16) | (0x31068 >> 2), 96962306a36Sopenharmony_ci 0x00000000, 97062306a36Sopenharmony_ci (0x5e00 << 16) | (0x31068 >> 2), 97162306a36Sopenharmony_ci 0x00000000, 97262306a36Sopenharmony_ci (0x6e00 << 16) | (0x31068 >> 2), 97362306a36Sopenharmony_ci 0x00000000, 97462306a36Sopenharmony_ci (0x7e00 << 16) | (0x31068 >> 2), 97562306a36Sopenharmony_ci 0x00000000, 97662306a36Sopenharmony_ci (0x0e00 << 16) | (0xcd10 >> 2), 97762306a36Sopenharmony_ci 0x00000000, 97862306a36Sopenharmony_ci (0x0e00 << 16) | (0xcd14 >> 2), 97962306a36Sopenharmony_ci 0x00000000, 98062306a36Sopenharmony_ci (0x0e00 << 16) | (0x88b0 >> 2), 98162306a36Sopenharmony_ci 0x00000000, 98262306a36Sopenharmony_ci (0x0e00 << 16) | (0x88b4 >> 2), 98362306a36Sopenharmony_ci 0x00000000, 98462306a36Sopenharmony_ci (0x0e00 << 16) | (0x88b8 >> 2), 98562306a36Sopenharmony_ci 0x00000000, 98662306a36Sopenharmony_ci (0x0e00 << 16) | (0x88bc >> 2), 98762306a36Sopenharmony_ci 0x00000000, 98862306a36Sopenharmony_ci (0x0400 << 16) | (0x89c0 >> 2), 98962306a36Sopenharmony_ci 0x00000000, 99062306a36Sopenharmony_ci (0x0e00 << 16) | (0x88c4 >> 2), 99162306a36Sopenharmony_ci 0x00000000, 99262306a36Sopenharmony_ci (0x0e00 << 16) | (0x88c8 >> 2), 99362306a36Sopenharmony_ci 0x00000000, 99462306a36Sopenharmony_ci (0x0e00 << 16) | (0x88d0 >> 2), 99562306a36Sopenharmony_ci 0x00000000, 99662306a36Sopenharmony_ci (0x0e00 << 16) | (0x88d4 >> 2), 99762306a36Sopenharmony_ci 0x00000000, 99862306a36Sopenharmony_ci (0x0e00 << 16) | (0x88d8 >> 2), 99962306a36Sopenharmony_ci 0x00000000, 100062306a36Sopenharmony_ci (0x0e00 << 16) | (0x8980 >> 2), 100162306a36Sopenharmony_ci 0x00000000, 100262306a36Sopenharmony_ci (0x0e00 << 16) | (0x30938 >> 2), 100362306a36Sopenharmony_ci 0x00000000, 100462306a36Sopenharmony_ci (0x0e00 << 16) | (0x3093c >> 2), 100562306a36Sopenharmony_ci 0x00000000, 100662306a36Sopenharmony_ci (0x0e00 << 16) | (0x30940 >> 2), 100762306a36Sopenharmony_ci 0x00000000, 100862306a36Sopenharmony_ci (0x0e00 << 16) | (0x89a0 >> 2), 100962306a36Sopenharmony_ci 0x00000000, 101062306a36Sopenharmony_ci (0x0e00 << 16) | (0x30900 >> 2), 101162306a36Sopenharmony_ci 0x00000000, 101262306a36Sopenharmony_ci (0x0e00 << 16) | (0x30904 >> 2), 101362306a36Sopenharmony_ci 0x00000000, 101462306a36Sopenharmony_ci (0x0e00 << 16) | (0x89b4 >> 2), 101562306a36Sopenharmony_ci 0x00000000, 101662306a36Sopenharmony_ci (0x0e00 << 16) | (0x3e1fc >> 2), 101762306a36Sopenharmony_ci 0x00000000, 101862306a36Sopenharmony_ci (0x0e00 << 16) | (0x3c210 >> 2), 101962306a36Sopenharmony_ci 0x00000000, 102062306a36Sopenharmony_ci (0x0e00 << 16) | (0x3c214 >> 2), 102162306a36Sopenharmony_ci 0x00000000, 102262306a36Sopenharmony_ci (0x0e00 << 16) | (0x3c218 >> 2), 102362306a36Sopenharmony_ci 0x00000000, 102462306a36Sopenharmony_ci (0x0e00 << 16) | (0x8904 >> 2), 102562306a36Sopenharmony_ci 0x00000000, 102662306a36Sopenharmony_ci 0x5, 102762306a36Sopenharmony_ci (0x0e00 << 16) | (0x8c28 >> 2), 102862306a36Sopenharmony_ci (0x0e00 << 16) | (0x8c2c >> 2), 102962306a36Sopenharmony_ci (0x0e00 << 16) | (0x8c30 >> 2), 103062306a36Sopenharmony_ci (0x0e00 << 16) | (0x8c34 >> 2), 103162306a36Sopenharmony_ci (0x0e00 << 16) | (0x9600 >> 2), 103262306a36Sopenharmony_ci}; 103362306a36Sopenharmony_ci 103462306a36Sopenharmony_cistatic const u32 bonaire_golden_spm_registers[] = 103562306a36Sopenharmony_ci{ 103662306a36Sopenharmony_ci 0x30800, 0xe0ffffff, 0xe0000000 103762306a36Sopenharmony_ci}; 103862306a36Sopenharmony_ci 103962306a36Sopenharmony_cistatic const u32 bonaire_golden_common_registers[] = 104062306a36Sopenharmony_ci{ 104162306a36Sopenharmony_ci 0xc770, 0xffffffff, 0x00000800, 104262306a36Sopenharmony_ci 0xc774, 0xffffffff, 0x00000800, 104362306a36Sopenharmony_ci 0xc798, 0xffffffff, 0x00007fbf, 104462306a36Sopenharmony_ci 0xc79c, 0xffffffff, 0x00007faf 104562306a36Sopenharmony_ci}; 104662306a36Sopenharmony_ci 104762306a36Sopenharmony_cistatic const u32 bonaire_golden_registers[] = 104862306a36Sopenharmony_ci{ 104962306a36Sopenharmony_ci 0x3354, 0x00000333, 0x00000333, 105062306a36Sopenharmony_ci 0x3350, 0x000c0fc0, 0x00040200, 105162306a36Sopenharmony_ci 0x9a10, 0x00010000, 0x00058208, 105262306a36Sopenharmony_ci 0x3c000, 0xffff1fff, 0x00140000, 105362306a36Sopenharmony_ci 0x3c200, 0xfdfc0fff, 0x00000100, 105462306a36Sopenharmony_ci 0x3c234, 0x40000000, 0x40000200, 105562306a36Sopenharmony_ci 0x9830, 0xffffffff, 0x00000000, 105662306a36Sopenharmony_ci 0x9834, 0xf00fffff, 0x00000400, 105762306a36Sopenharmony_ci 0x9838, 0x0002021c, 0x00020200, 105862306a36Sopenharmony_ci 0xc78, 0x00000080, 0x00000000, 105962306a36Sopenharmony_ci 0x5bb0, 0x000000f0, 0x00000070, 106062306a36Sopenharmony_ci 0x5bc0, 0xf0311fff, 0x80300000, 106162306a36Sopenharmony_ci 0x98f8, 0x73773777, 0x12010001, 106262306a36Sopenharmony_ci 0x350c, 0x00810000, 0x408af000, 106362306a36Sopenharmony_ci 0x7030, 0x31000111, 0x00000011, 106462306a36Sopenharmony_ci 0x2f48, 0x73773777, 0x12010001, 106562306a36Sopenharmony_ci 0x220c, 0x00007fb6, 0x0021a1b1, 106662306a36Sopenharmony_ci 0x2210, 0x00007fb6, 0x002021b1, 106762306a36Sopenharmony_ci 0x2180, 0x00007fb6, 0x00002191, 106862306a36Sopenharmony_ci 0x2218, 0x00007fb6, 0x002121b1, 106962306a36Sopenharmony_ci 0x221c, 0x00007fb6, 0x002021b1, 107062306a36Sopenharmony_ci 0x21dc, 0x00007fb6, 0x00002191, 107162306a36Sopenharmony_ci 0x21e0, 0x00007fb6, 0x00002191, 107262306a36Sopenharmony_ci 0x3628, 0x0000003f, 0x0000000a, 107362306a36Sopenharmony_ci 0x362c, 0x0000003f, 0x0000000a, 107462306a36Sopenharmony_ci 0x2ae4, 0x00073ffe, 0x000022a2, 107562306a36Sopenharmony_ci 0x240c, 0x000007ff, 0x00000000, 107662306a36Sopenharmony_ci 0x8a14, 0xf000003f, 0x00000007, 107762306a36Sopenharmony_ci 0x8bf0, 0x00002001, 0x00000001, 107862306a36Sopenharmony_ci 0x8b24, 0xffffffff, 0x00ffffff, 107962306a36Sopenharmony_ci 0x30a04, 0x0000ff0f, 0x00000000, 108062306a36Sopenharmony_ci 0x28a4c, 0x07ffffff, 0x06000000, 108162306a36Sopenharmony_ci 0x4d8, 0x00000fff, 0x00000100, 108262306a36Sopenharmony_ci 0x3e78, 0x00000001, 0x00000002, 108362306a36Sopenharmony_ci 0x9100, 0x03000000, 0x0362c688, 108462306a36Sopenharmony_ci 0x8c00, 0x000000ff, 0x00000001, 108562306a36Sopenharmony_ci 0xe40, 0x00001fff, 0x00001fff, 108662306a36Sopenharmony_ci 0x9060, 0x0000007f, 0x00000020, 108762306a36Sopenharmony_ci 0x9508, 0x00010000, 0x00010000, 108862306a36Sopenharmony_ci 0xac14, 0x000003ff, 0x000000f3, 108962306a36Sopenharmony_ci 0xac0c, 0xffffffff, 0x00001032 109062306a36Sopenharmony_ci}; 109162306a36Sopenharmony_ci 109262306a36Sopenharmony_cistatic const u32 bonaire_mgcg_cgcg_init[] = 109362306a36Sopenharmony_ci{ 109462306a36Sopenharmony_ci 0xc420, 0xffffffff, 0xfffffffc, 109562306a36Sopenharmony_ci 0x30800, 0xffffffff, 0xe0000000, 109662306a36Sopenharmony_ci 0x3c2a0, 0xffffffff, 0x00000100, 109762306a36Sopenharmony_ci 0x3c208, 0xffffffff, 0x00000100, 109862306a36Sopenharmony_ci 0x3c2c0, 0xffffffff, 0xc0000100, 109962306a36Sopenharmony_ci 0x3c2c8, 0xffffffff, 0xc0000100, 110062306a36Sopenharmony_ci 0x3c2c4, 0xffffffff, 0xc0000100, 110162306a36Sopenharmony_ci 0x55e4, 0xffffffff, 0x00600100, 110262306a36Sopenharmony_ci 0x3c280, 0xffffffff, 0x00000100, 110362306a36Sopenharmony_ci 0x3c214, 0xffffffff, 0x06000100, 110462306a36Sopenharmony_ci 0x3c220, 0xffffffff, 0x00000100, 110562306a36Sopenharmony_ci 0x3c218, 0xffffffff, 0x06000100, 110662306a36Sopenharmony_ci 0x3c204, 0xffffffff, 0x00000100, 110762306a36Sopenharmony_ci 0x3c2e0, 0xffffffff, 0x00000100, 110862306a36Sopenharmony_ci 0x3c224, 0xffffffff, 0x00000100, 110962306a36Sopenharmony_ci 0x3c200, 0xffffffff, 0x00000100, 111062306a36Sopenharmony_ci 0x3c230, 0xffffffff, 0x00000100, 111162306a36Sopenharmony_ci 0x3c234, 0xffffffff, 0x00000100, 111262306a36Sopenharmony_ci 0x3c250, 0xffffffff, 0x00000100, 111362306a36Sopenharmony_ci 0x3c254, 0xffffffff, 0x00000100, 111462306a36Sopenharmony_ci 0x3c258, 0xffffffff, 0x00000100, 111562306a36Sopenharmony_ci 0x3c25c, 0xffffffff, 0x00000100, 111662306a36Sopenharmony_ci 0x3c260, 0xffffffff, 0x00000100, 111762306a36Sopenharmony_ci 0x3c27c, 0xffffffff, 0x00000100, 111862306a36Sopenharmony_ci 0x3c278, 0xffffffff, 0x00000100, 111962306a36Sopenharmony_ci 0x3c210, 0xffffffff, 0x06000100, 112062306a36Sopenharmony_ci 0x3c290, 0xffffffff, 0x00000100, 112162306a36Sopenharmony_ci 0x3c274, 0xffffffff, 0x00000100, 112262306a36Sopenharmony_ci 0x3c2b4, 0xffffffff, 0x00000100, 112362306a36Sopenharmony_ci 0x3c2b0, 0xffffffff, 0x00000100, 112462306a36Sopenharmony_ci 0x3c270, 0xffffffff, 0x00000100, 112562306a36Sopenharmony_ci 0x30800, 0xffffffff, 0xe0000000, 112662306a36Sopenharmony_ci 0x3c020, 0xffffffff, 0x00010000, 112762306a36Sopenharmony_ci 0x3c024, 0xffffffff, 0x00030002, 112862306a36Sopenharmony_ci 0x3c028, 0xffffffff, 0x00040007, 112962306a36Sopenharmony_ci 0x3c02c, 0xffffffff, 0x00060005, 113062306a36Sopenharmony_ci 0x3c030, 0xffffffff, 0x00090008, 113162306a36Sopenharmony_ci 0x3c034, 0xffffffff, 0x00010000, 113262306a36Sopenharmony_ci 0x3c038, 0xffffffff, 0x00030002, 113362306a36Sopenharmony_ci 0x3c03c, 0xffffffff, 0x00040007, 113462306a36Sopenharmony_ci 0x3c040, 0xffffffff, 0x00060005, 113562306a36Sopenharmony_ci 0x3c044, 0xffffffff, 0x00090008, 113662306a36Sopenharmony_ci 0x3c048, 0xffffffff, 0x00010000, 113762306a36Sopenharmony_ci 0x3c04c, 0xffffffff, 0x00030002, 113862306a36Sopenharmony_ci 0x3c050, 0xffffffff, 0x00040007, 113962306a36Sopenharmony_ci 0x3c054, 0xffffffff, 0x00060005, 114062306a36Sopenharmony_ci 0x3c058, 0xffffffff, 0x00090008, 114162306a36Sopenharmony_ci 0x3c05c, 0xffffffff, 0x00010000, 114262306a36Sopenharmony_ci 0x3c060, 0xffffffff, 0x00030002, 114362306a36Sopenharmony_ci 0x3c064, 0xffffffff, 0x00040007, 114462306a36Sopenharmony_ci 0x3c068, 0xffffffff, 0x00060005, 114562306a36Sopenharmony_ci 0x3c06c, 0xffffffff, 0x00090008, 114662306a36Sopenharmony_ci 0x3c070, 0xffffffff, 0x00010000, 114762306a36Sopenharmony_ci 0x3c074, 0xffffffff, 0x00030002, 114862306a36Sopenharmony_ci 0x3c078, 0xffffffff, 0x00040007, 114962306a36Sopenharmony_ci 0x3c07c, 0xffffffff, 0x00060005, 115062306a36Sopenharmony_ci 0x3c080, 0xffffffff, 0x00090008, 115162306a36Sopenharmony_ci 0x3c084, 0xffffffff, 0x00010000, 115262306a36Sopenharmony_ci 0x3c088, 0xffffffff, 0x00030002, 115362306a36Sopenharmony_ci 0x3c08c, 0xffffffff, 0x00040007, 115462306a36Sopenharmony_ci 0x3c090, 0xffffffff, 0x00060005, 115562306a36Sopenharmony_ci 0x3c094, 0xffffffff, 0x00090008, 115662306a36Sopenharmony_ci 0x3c098, 0xffffffff, 0x00010000, 115762306a36Sopenharmony_ci 0x3c09c, 0xffffffff, 0x00030002, 115862306a36Sopenharmony_ci 0x3c0a0, 0xffffffff, 0x00040007, 115962306a36Sopenharmony_ci 0x3c0a4, 0xffffffff, 0x00060005, 116062306a36Sopenharmony_ci 0x3c0a8, 0xffffffff, 0x00090008, 116162306a36Sopenharmony_ci 0x3c000, 0xffffffff, 0x96e00200, 116262306a36Sopenharmony_ci 0x8708, 0xffffffff, 0x00900100, 116362306a36Sopenharmony_ci 0xc424, 0xffffffff, 0x0020003f, 116462306a36Sopenharmony_ci 0x38, 0xffffffff, 0x0140001c, 116562306a36Sopenharmony_ci 0x3c, 0x000f0000, 0x000f0000, 116662306a36Sopenharmony_ci 0x220, 0xffffffff, 0xC060000C, 116762306a36Sopenharmony_ci 0x224, 0xc0000fff, 0x00000100, 116862306a36Sopenharmony_ci 0xf90, 0xffffffff, 0x00000100, 116962306a36Sopenharmony_ci 0xf98, 0x00000101, 0x00000000, 117062306a36Sopenharmony_ci 0x20a8, 0xffffffff, 0x00000104, 117162306a36Sopenharmony_ci 0x55e4, 0xff000fff, 0x00000100, 117262306a36Sopenharmony_ci 0x30cc, 0xc0000fff, 0x00000104, 117362306a36Sopenharmony_ci 0xc1e4, 0x00000001, 0x00000001, 117462306a36Sopenharmony_ci 0xd00c, 0xff000ff0, 0x00000100, 117562306a36Sopenharmony_ci 0xd80c, 0xff000ff0, 0x00000100 117662306a36Sopenharmony_ci}; 117762306a36Sopenharmony_ci 117862306a36Sopenharmony_cistatic const u32 spectre_golden_spm_registers[] = 117962306a36Sopenharmony_ci{ 118062306a36Sopenharmony_ci 0x30800, 0xe0ffffff, 0xe0000000 118162306a36Sopenharmony_ci}; 118262306a36Sopenharmony_ci 118362306a36Sopenharmony_cistatic const u32 spectre_golden_common_registers[] = 118462306a36Sopenharmony_ci{ 118562306a36Sopenharmony_ci 0xc770, 0xffffffff, 0x00000800, 118662306a36Sopenharmony_ci 0xc774, 0xffffffff, 0x00000800, 118762306a36Sopenharmony_ci 0xc798, 0xffffffff, 0x00007fbf, 118862306a36Sopenharmony_ci 0xc79c, 0xffffffff, 0x00007faf 118962306a36Sopenharmony_ci}; 119062306a36Sopenharmony_ci 119162306a36Sopenharmony_cistatic const u32 spectre_golden_registers[] = 119262306a36Sopenharmony_ci{ 119362306a36Sopenharmony_ci 0x3c000, 0xffff1fff, 0x96940200, 119462306a36Sopenharmony_ci 0x3c00c, 0xffff0001, 0xff000000, 119562306a36Sopenharmony_ci 0x3c200, 0xfffc0fff, 0x00000100, 119662306a36Sopenharmony_ci 0x6ed8, 0x00010101, 0x00010000, 119762306a36Sopenharmony_ci 0x9834, 0xf00fffff, 0x00000400, 119862306a36Sopenharmony_ci 0x9838, 0xfffffffc, 0x00020200, 119962306a36Sopenharmony_ci 0x5bb0, 0x000000f0, 0x00000070, 120062306a36Sopenharmony_ci 0x5bc0, 0xf0311fff, 0x80300000, 120162306a36Sopenharmony_ci 0x98f8, 0x73773777, 0x12010001, 120262306a36Sopenharmony_ci 0x9b7c, 0x00ff0000, 0x00fc0000, 120362306a36Sopenharmony_ci 0x2f48, 0x73773777, 0x12010001, 120462306a36Sopenharmony_ci 0x8a14, 0xf000003f, 0x00000007, 120562306a36Sopenharmony_ci 0x8b24, 0xffffffff, 0x00ffffff, 120662306a36Sopenharmony_ci 0x28350, 0x3f3f3fff, 0x00000082, 120762306a36Sopenharmony_ci 0x28354, 0x0000003f, 0x00000000, 120862306a36Sopenharmony_ci 0x3e78, 0x00000001, 0x00000002, 120962306a36Sopenharmony_ci 0x913c, 0xffff03df, 0x00000004, 121062306a36Sopenharmony_ci 0xc768, 0x00000008, 0x00000008, 121162306a36Sopenharmony_ci 0x8c00, 0x000008ff, 0x00000800, 121262306a36Sopenharmony_ci 0x9508, 0x00010000, 0x00010000, 121362306a36Sopenharmony_ci 0xac0c, 0xffffffff, 0x54763210, 121462306a36Sopenharmony_ci 0x214f8, 0x01ff01ff, 0x00000002, 121562306a36Sopenharmony_ci 0x21498, 0x007ff800, 0x00200000, 121662306a36Sopenharmony_ci 0x2015c, 0xffffffff, 0x00000f40, 121762306a36Sopenharmony_ci 0x30934, 0xffffffff, 0x00000001 121862306a36Sopenharmony_ci}; 121962306a36Sopenharmony_ci 122062306a36Sopenharmony_cistatic const u32 spectre_mgcg_cgcg_init[] = 122162306a36Sopenharmony_ci{ 122262306a36Sopenharmony_ci 0xc420, 0xffffffff, 0xfffffffc, 122362306a36Sopenharmony_ci 0x30800, 0xffffffff, 0xe0000000, 122462306a36Sopenharmony_ci 0x3c2a0, 0xffffffff, 0x00000100, 122562306a36Sopenharmony_ci 0x3c208, 0xffffffff, 0x00000100, 122662306a36Sopenharmony_ci 0x3c2c0, 0xffffffff, 0x00000100, 122762306a36Sopenharmony_ci 0x3c2c8, 0xffffffff, 0x00000100, 122862306a36Sopenharmony_ci 0x3c2c4, 0xffffffff, 0x00000100, 122962306a36Sopenharmony_ci 0x55e4, 0xffffffff, 0x00600100, 123062306a36Sopenharmony_ci 0x3c280, 0xffffffff, 0x00000100, 123162306a36Sopenharmony_ci 0x3c214, 0xffffffff, 0x06000100, 123262306a36Sopenharmony_ci 0x3c220, 0xffffffff, 0x00000100, 123362306a36Sopenharmony_ci 0x3c218, 0xffffffff, 0x06000100, 123462306a36Sopenharmony_ci 0x3c204, 0xffffffff, 0x00000100, 123562306a36Sopenharmony_ci 0x3c2e0, 0xffffffff, 0x00000100, 123662306a36Sopenharmony_ci 0x3c224, 0xffffffff, 0x00000100, 123762306a36Sopenharmony_ci 0x3c200, 0xffffffff, 0x00000100, 123862306a36Sopenharmony_ci 0x3c230, 0xffffffff, 0x00000100, 123962306a36Sopenharmony_ci 0x3c234, 0xffffffff, 0x00000100, 124062306a36Sopenharmony_ci 0x3c250, 0xffffffff, 0x00000100, 124162306a36Sopenharmony_ci 0x3c254, 0xffffffff, 0x00000100, 124262306a36Sopenharmony_ci 0x3c258, 0xffffffff, 0x00000100, 124362306a36Sopenharmony_ci 0x3c25c, 0xffffffff, 0x00000100, 124462306a36Sopenharmony_ci 0x3c260, 0xffffffff, 0x00000100, 124562306a36Sopenharmony_ci 0x3c27c, 0xffffffff, 0x00000100, 124662306a36Sopenharmony_ci 0x3c278, 0xffffffff, 0x00000100, 124762306a36Sopenharmony_ci 0x3c210, 0xffffffff, 0x06000100, 124862306a36Sopenharmony_ci 0x3c290, 0xffffffff, 0x00000100, 124962306a36Sopenharmony_ci 0x3c274, 0xffffffff, 0x00000100, 125062306a36Sopenharmony_ci 0x3c2b4, 0xffffffff, 0x00000100, 125162306a36Sopenharmony_ci 0x3c2b0, 0xffffffff, 0x00000100, 125262306a36Sopenharmony_ci 0x3c270, 0xffffffff, 0x00000100, 125362306a36Sopenharmony_ci 0x30800, 0xffffffff, 0xe0000000, 125462306a36Sopenharmony_ci 0x3c020, 0xffffffff, 0x00010000, 125562306a36Sopenharmony_ci 0x3c024, 0xffffffff, 0x00030002, 125662306a36Sopenharmony_ci 0x3c028, 0xffffffff, 0x00040007, 125762306a36Sopenharmony_ci 0x3c02c, 0xffffffff, 0x00060005, 125862306a36Sopenharmony_ci 0x3c030, 0xffffffff, 0x00090008, 125962306a36Sopenharmony_ci 0x3c034, 0xffffffff, 0x00010000, 126062306a36Sopenharmony_ci 0x3c038, 0xffffffff, 0x00030002, 126162306a36Sopenharmony_ci 0x3c03c, 0xffffffff, 0x00040007, 126262306a36Sopenharmony_ci 0x3c040, 0xffffffff, 0x00060005, 126362306a36Sopenharmony_ci 0x3c044, 0xffffffff, 0x00090008, 126462306a36Sopenharmony_ci 0x3c048, 0xffffffff, 0x00010000, 126562306a36Sopenharmony_ci 0x3c04c, 0xffffffff, 0x00030002, 126662306a36Sopenharmony_ci 0x3c050, 0xffffffff, 0x00040007, 126762306a36Sopenharmony_ci 0x3c054, 0xffffffff, 0x00060005, 126862306a36Sopenharmony_ci 0x3c058, 0xffffffff, 0x00090008, 126962306a36Sopenharmony_ci 0x3c05c, 0xffffffff, 0x00010000, 127062306a36Sopenharmony_ci 0x3c060, 0xffffffff, 0x00030002, 127162306a36Sopenharmony_ci 0x3c064, 0xffffffff, 0x00040007, 127262306a36Sopenharmony_ci 0x3c068, 0xffffffff, 0x00060005, 127362306a36Sopenharmony_ci 0x3c06c, 0xffffffff, 0x00090008, 127462306a36Sopenharmony_ci 0x3c070, 0xffffffff, 0x00010000, 127562306a36Sopenharmony_ci 0x3c074, 0xffffffff, 0x00030002, 127662306a36Sopenharmony_ci 0x3c078, 0xffffffff, 0x00040007, 127762306a36Sopenharmony_ci 0x3c07c, 0xffffffff, 0x00060005, 127862306a36Sopenharmony_ci 0x3c080, 0xffffffff, 0x00090008, 127962306a36Sopenharmony_ci 0x3c084, 0xffffffff, 0x00010000, 128062306a36Sopenharmony_ci 0x3c088, 0xffffffff, 0x00030002, 128162306a36Sopenharmony_ci 0x3c08c, 0xffffffff, 0x00040007, 128262306a36Sopenharmony_ci 0x3c090, 0xffffffff, 0x00060005, 128362306a36Sopenharmony_ci 0x3c094, 0xffffffff, 0x00090008, 128462306a36Sopenharmony_ci 0x3c098, 0xffffffff, 0x00010000, 128562306a36Sopenharmony_ci 0x3c09c, 0xffffffff, 0x00030002, 128662306a36Sopenharmony_ci 0x3c0a0, 0xffffffff, 0x00040007, 128762306a36Sopenharmony_ci 0x3c0a4, 0xffffffff, 0x00060005, 128862306a36Sopenharmony_ci 0x3c0a8, 0xffffffff, 0x00090008, 128962306a36Sopenharmony_ci 0x3c0ac, 0xffffffff, 0x00010000, 129062306a36Sopenharmony_ci 0x3c0b0, 0xffffffff, 0x00030002, 129162306a36Sopenharmony_ci 0x3c0b4, 0xffffffff, 0x00040007, 129262306a36Sopenharmony_ci 0x3c0b8, 0xffffffff, 0x00060005, 129362306a36Sopenharmony_ci 0x3c0bc, 0xffffffff, 0x00090008, 129462306a36Sopenharmony_ci 0x3c000, 0xffffffff, 0x96e00200, 129562306a36Sopenharmony_ci 0x8708, 0xffffffff, 0x00900100, 129662306a36Sopenharmony_ci 0xc424, 0xffffffff, 0x0020003f, 129762306a36Sopenharmony_ci 0x38, 0xffffffff, 0x0140001c, 129862306a36Sopenharmony_ci 0x3c, 0x000f0000, 0x000f0000, 129962306a36Sopenharmony_ci 0x220, 0xffffffff, 0xC060000C, 130062306a36Sopenharmony_ci 0x224, 0xc0000fff, 0x00000100, 130162306a36Sopenharmony_ci 0xf90, 0xffffffff, 0x00000100, 130262306a36Sopenharmony_ci 0xf98, 0x00000101, 0x00000000, 130362306a36Sopenharmony_ci 0x20a8, 0xffffffff, 0x00000104, 130462306a36Sopenharmony_ci 0x55e4, 0xff000fff, 0x00000100, 130562306a36Sopenharmony_ci 0x30cc, 0xc0000fff, 0x00000104, 130662306a36Sopenharmony_ci 0xc1e4, 0x00000001, 0x00000001, 130762306a36Sopenharmony_ci 0xd00c, 0xff000ff0, 0x00000100, 130862306a36Sopenharmony_ci 0xd80c, 0xff000ff0, 0x00000100 130962306a36Sopenharmony_ci}; 131062306a36Sopenharmony_ci 131162306a36Sopenharmony_cistatic const u32 kalindi_golden_spm_registers[] = 131262306a36Sopenharmony_ci{ 131362306a36Sopenharmony_ci 0x30800, 0xe0ffffff, 0xe0000000 131462306a36Sopenharmony_ci}; 131562306a36Sopenharmony_ci 131662306a36Sopenharmony_cistatic const u32 kalindi_golden_common_registers[] = 131762306a36Sopenharmony_ci{ 131862306a36Sopenharmony_ci 0xc770, 0xffffffff, 0x00000800, 131962306a36Sopenharmony_ci 0xc774, 0xffffffff, 0x00000800, 132062306a36Sopenharmony_ci 0xc798, 0xffffffff, 0x00007fbf, 132162306a36Sopenharmony_ci 0xc79c, 0xffffffff, 0x00007faf 132262306a36Sopenharmony_ci}; 132362306a36Sopenharmony_ci 132462306a36Sopenharmony_cistatic const u32 kalindi_golden_registers[] = 132562306a36Sopenharmony_ci{ 132662306a36Sopenharmony_ci 0x3c000, 0xffffdfff, 0x6e944040, 132762306a36Sopenharmony_ci 0x55e4, 0xff607fff, 0xfc000100, 132862306a36Sopenharmony_ci 0x3c220, 0xff000fff, 0x00000100, 132962306a36Sopenharmony_ci 0x3c224, 0xff000fff, 0x00000100, 133062306a36Sopenharmony_ci 0x3c200, 0xfffc0fff, 0x00000100, 133162306a36Sopenharmony_ci 0x6ed8, 0x00010101, 0x00010000, 133262306a36Sopenharmony_ci 0x9830, 0xffffffff, 0x00000000, 133362306a36Sopenharmony_ci 0x9834, 0xf00fffff, 0x00000400, 133462306a36Sopenharmony_ci 0x5bb0, 0x000000f0, 0x00000070, 133562306a36Sopenharmony_ci 0x5bc0, 0xf0311fff, 0x80300000, 133662306a36Sopenharmony_ci 0x98f8, 0x73773777, 0x12010001, 133762306a36Sopenharmony_ci 0x98fc, 0xffffffff, 0x00000010, 133862306a36Sopenharmony_ci 0x9b7c, 0x00ff0000, 0x00fc0000, 133962306a36Sopenharmony_ci 0x8030, 0x00001f0f, 0x0000100a, 134062306a36Sopenharmony_ci 0x2f48, 0x73773777, 0x12010001, 134162306a36Sopenharmony_ci 0x2408, 0x000fffff, 0x000c007f, 134262306a36Sopenharmony_ci 0x8a14, 0xf000003f, 0x00000007, 134362306a36Sopenharmony_ci 0x8b24, 0x3fff3fff, 0x00ffcfff, 134462306a36Sopenharmony_ci 0x30a04, 0x0000ff0f, 0x00000000, 134562306a36Sopenharmony_ci 0x28a4c, 0x07ffffff, 0x06000000, 134662306a36Sopenharmony_ci 0x4d8, 0x00000fff, 0x00000100, 134762306a36Sopenharmony_ci 0x3e78, 0x00000001, 0x00000002, 134862306a36Sopenharmony_ci 0xc768, 0x00000008, 0x00000008, 134962306a36Sopenharmony_ci 0x8c00, 0x000000ff, 0x00000003, 135062306a36Sopenharmony_ci 0x214f8, 0x01ff01ff, 0x00000002, 135162306a36Sopenharmony_ci 0x21498, 0x007ff800, 0x00200000, 135262306a36Sopenharmony_ci 0x2015c, 0xffffffff, 0x00000f40, 135362306a36Sopenharmony_ci 0x88c4, 0x001f3ae3, 0x00000082, 135462306a36Sopenharmony_ci 0x88d4, 0x0000001f, 0x00000010, 135562306a36Sopenharmony_ci 0x30934, 0xffffffff, 0x00000000 135662306a36Sopenharmony_ci}; 135762306a36Sopenharmony_ci 135862306a36Sopenharmony_cistatic const u32 kalindi_mgcg_cgcg_init[] = 135962306a36Sopenharmony_ci{ 136062306a36Sopenharmony_ci 0xc420, 0xffffffff, 0xfffffffc, 136162306a36Sopenharmony_ci 0x30800, 0xffffffff, 0xe0000000, 136262306a36Sopenharmony_ci 0x3c2a0, 0xffffffff, 0x00000100, 136362306a36Sopenharmony_ci 0x3c208, 0xffffffff, 0x00000100, 136462306a36Sopenharmony_ci 0x3c2c0, 0xffffffff, 0x00000100, 136562306a36Sopenharmony_ci 0x3c2c8, 0xffffffff, 0x00000100, 136662306a36Sopenharmony_ci 0x3c2c4, 0xffffffff, 0x00000100, 136762306a36Sopenharmony_ci 0x55e4, 0xffffffff, 0x00600100, 136862306a36Sopenharmony_ci 0x3c280, 0xffffffff, 0x00000100, 136962306a36Sopenharmony_ci 0x3c214, 0xffffffff, 0x06000100, 137062306a36Sopenharmony_ci 0x3c220, 0xffffffff, 0x00000100, 137162306a36Sopenharmony_ci 0x3c218, 0xffffffff, 0x06000100, 137262306a36Sopenharmony_ci 0x3c204, 0xffffffff, 0x00000100, 137362306a36Sopenharmony_ci 0x3c2e0, 0xffffffff, 0x00000100, 137462306a36Sopenharmony_ci 0x3c224, 0xffffffff, 0x00000100, 137562306a36Sopenharmony_ci 0x3c200, 0xffffffff, 0x00000100, 137662306a36Sopenharmony_ci 0x3c230, 0xffffffff, 0x00000100, 137762306a36Sopenharmony_ci 0x3c234, 0xffffffff, 0x00000100, 137862306a36Sopenharmony_ci 0x3c250, 0xffffffff, 0x00000100, 137962306a36Sopenharmony_ci 0x3c254, 0xffffffff, 0x00000100, 138062306a36Sopenharmony_ci 0x3c258, 0xffffffff, 0x00000100, 138162306a36Sopenharmony_ci 0x3c25c, 0xffffffff, 0x00000100, 138262306a36Sopenharmony_ci 0x3c260, 0xffffffff, 0x00000100, 138362306a36Sopenharmony_ci 0x3c27c, 0xffffffff, 0x00000100, 138462306a36Sopenharmony_ci 0x3c278, 0xffffffff, 0x00000100, 138562306a36Sopenharmony_ci 0x3c210, 0xffffffff, 0x06000100, 138662306a36Sopenharmony_ci 0x3c290, 0xffffffff, 0x00000100, 138762306a36Sopenharmony_ci 0x3c274, 0xffffffff, 0x00000100, 138862306a36Sopenharmony_ci 0x3c2b4, 0xffffffff, 0x00000100, 138962306a36Sopenharmony_ci 0x3c2b0, 0xffffffff, 0x00000100, 139062306a36Sopenharmony_ci 0x3c270, 0xffffffff, 0x00000100, 139162306a36Sopenharmony_ci 0x30800, 0xffffffff, 0xe0000000, 139262306a36Sopenharmony_ci 0x3c020, 0xffffffff, 0x00010000, 139362306a36Sopenharmony_ci 0x3c024, 0xffffffff, 0x00030002, 139462306a36Sopenharmony_ci 0x3c028, 0xffffffff, 0x00040007, 139562306a36Sopenharmony_ci 0x3c02c, 0xffffffff, 0x00060005, 139662306a36Sopenharmony_ci 0x3c030, 0xffffffff, 0x00090008, 139762306a36Sopenharmony_ci 0x3c034, 0xffffffff, 0x00010000, 139862306a36Sopenharmony_ci 0x3c038, 0xffffffff, 0x00030002, 139962306a36Sopenharmony_ci 0x3c03c, 0xffffffff, 0x00040007, 140062306a36Sopenharmony_ci 0x3c040, 0xffffffff, 0x00060005, 140162306a36Sopenharmony_ci 0x3c044, 0xffffffff, 0x00090008, 140262306a36Sopenharmony_ci 0x3c000, 0xffffffff, 0x96e00200, 140362306a36Sopenharmony_ci 0x8708, 0xffffffff, 0x00900100, 140462306a36Sopenharmony_ci 0xc424, 0xffffffff, 0x0020003f, 140562306a36Sopenharmony_ci 0x38, 0xffffffff, 0x0140001c, 140662306a36Sopenharmony_ci 0x3c, 0x000f0000, 0x000f0000, 140762306a36Sopenharmony_ci 0x220, 0xffffffff, 0xC060000C, 140862306a36Sopenharmony_ci 0x224, 0xc0000fff, 0x00000100, 140962306a36Sopenharmony_ci 0x20a8, 0xffffffff, 0x00000104, 141062306a36Sopenharmony_ci 0x55e4, 0xff000fff, 0x00000100, 141162306a36Sopenharmony_ci 0x30cc, 0xc0000fff, 0x00000104, 141262306a36Sopenharmony_ci 0xc1e4, 0x00000001, 0x00000001, 141362306a36Sopenharmony_ci 0xd00c, 0xff000ff0, 0x00000100, 141462306a36Sopenharmony_ci 0xd80c, 0xff000ff0, 0x00000100 141562306a36Sopenharmony_ci}; 141662306a36Sopenharmony_ci 141762306a36Sopenharmony_cistatic const u32 hawaii_golden_spm_registers[] = 141862306a36Sopenharmony_ci{ 141962306a36Sopenharmony_ci 0x30800, 0xe0ffffff, 0xe0000000 142062306a36Sopenharmony_ci}; 142162306a36Sopenharmony_ci 142262306a36Sopenharmony_cistatic const u32 hawaii_golden_common_registers[] = 142362306a36Sopenharmony_ci{ 142462306a36Sopenharmony_ci 0x30800, 0xffffffff, 0xe0000000, 142562306a36Sopenharmony_ci 0x28350, 0xffffffff, 0x3a00161a, 142662306a36Sopenharmony_ci 0x28354, 0xffffffff, 0x0000002e, 142762306a36Sopenharmony_ci 0x9a10, 0xffffffff, 0x00018208, 142862306a36Sopenharmony_ci 0x98f8, 0xffffffff, 0x12011003 142962306a36Sopenharmony_ci}; 143062306a36Sopenharmony_ci 143162306a36Sopenharmony_cistatic const u32 hawaii_golden_registers[] = 143262306a36Sopenharmony_ci{ 143362306a36Sopenharmony_ci 0x3354, 0x00000333, 0x00000333, 143462306a36Sopenharmony_ci 0x9a10, 0x00010000, 0x00058208, 143562306a36Sopenharmony_ci 0x9830, 0xffffffff, 0x00000000, 143662306a36Sopenharmony_ci 0x9834, 0xf00fffff, 0x00000400, 143762306a36Sopenharmony_ci 0x9838, 0x0002021c, 0x00020200, 143862306a36Sopenharmony_ci 0xc78, 0x00000080, 0x00000000, 143962306a36Sopenharmony_ci 0x5bb0, 0x000000f0, 0x00000070, 144062306a36Sopenharmony_ci 0x5bc0, 0xf0311fff, 0x80300000, 144162306a36Sopenharmony_ci 0x350c, 0x00810000, 0x408af000, 144262306a36Sopenharmony_ci 0x7030, 0x31000111, 0x00000011, 144362306a36Sopenharmony_ci 0x2f48, 0x73773777, 0x12010001, 144462306a36Sopenharmony_ci 0x2120, 0x0000007f, 0x0000001b, 144562306a36Sopenharmony_ci 0x21dc, 0x00007fb6, 0x00002191, 144662306a36Sopenharmony_ci 0x3628, 0x0000003f, 0x0000000a, 144762306a36Sopenharmony_ci 0x362c, 0x0000003f, 0x0000000a, 144862306a36Sopenharmony_ci 0x2ae4, 0x00073ffe, 0x000022a2, 144962306a36Sopenharmony_ci 0x240c, 0x000007ff, 0x00000000, 145062306a36Sopenharmony_ci 0x8bf0, 0x00002001, 0x00000001, 145162306a36Sopenharmony_ci 0x8b24, 0xffffffff, 0x00ffffff, 145262306a36Sopenharmony_ci 0x30a04, 0x0000ff0f, 0x00000000, 145362306a36Sopenharmony_ci 0x28a4c, 0x07ffffff, 0x06000000, 145462306a36Sopenharmony_ci 0x3e78, 0x00000001, 0x00000002, 145562306a36Sopenharmony_ci 0xc768, 0x00000008, 0x00000008, 145662306a36Sopenharmony_ci 0xc770, 0x00000f00, 0x00000800, 145762306a36Sopenharmony_ci 0xc774, 0x00000f00, 0x00000800, 145862306a36Sopenharmony_ci 0xc798, 0x00ffffff, 0x00ff7fbf, 145962306a36Sopenharmony_ci 0xc79c, 0x00ffffff, 0x00ff7faf, 146062306a36Sopenharmony_ci 0x8c00, 0x000000ff, 0x00000800, 146162306a36Sopenharmony_ci 0xe40, 0x00001fff, 0x00001fff, 146262306a36Sopenharmony_ci 0x9060, 0x0000007f, 0x00000020, 146362306a36Sopenharmony_ci 0x9508, 0x00010000, 0x00010000, 146462306a36Sopenharmony_ci 0xae00, 0x00100000, 0x000ff07c, 146562306a36Sopenharmony_ci 0xac14, 0x000003ff, 0x0000000f, 146662306a36Sopenharmony_ci 0xac10, 0xffffffff, 0x7564fdec, 146762306a36Sopenharmony_ci 0xac0c, 0xffffffff, 0x3120b9a8, 146862306a36Sopenharmony_ci 0xac08, 0x20000000, 0x0f9c0000 146962306a36Sopenharmony_ci}; 147062306a36Sopenharmony_ci 147162306a36Sopenharmony_cistatic const u32 hawaii_mgcg_cgcg_init[] = 147262306a36Sopenharmony_ci{ 147362306a36Sopenharmony_ci 0xc420, 0xffffffff, 0xfffffffd, 147462306a36Sopenharmony_ci 0x30800, 0xffffffff, 0xe0000000, 147562306a36Sopenharmony_ci 0x3c2a0, 0xffffffff, 0x00000100, 147662306a36Sopenharmony_ci 0x3c208, 0xffffffff, 0x00000100, 147762306a36Sopenharmony_ci 0x3c2c0, 0xffffffff, 0x00000100, 147862306a36Sopenharmony_ci 0x3c2c8, 0xffffffff, 0x00000100, 147962306a36Sopenharmony_ci 0x3c2c4, 0xffffffff, 0x00000100, 148062306a36Sopenharmony_ci 0x55e4, 0xffffffff, 0x00200100, 148162306a36Sopenharmony_ci 0x3c280, 0xffffffff, 0x00000100, 148262306a36Sopenharmony_ci 0x3c214, 0xffffffff, 0x06000100, 148362306a36Sopenharmony_ci 0x3c220, 0xffffffff, 0x00000100, 148462306a36Sopenharmony_ci 0x3c218, 0xffffffff, 0x06000100, 148562306a36Sopenharmony_ci 0x3c204, 0xffffffff, 0x00000100, 148662306a36Sopenharmony_ci 0x3c2e0, 0xffffffff, 0x00000100, 148762306a36Sopenharmony_ci 0x3c224, 0xffffffff, 0x00000100, 148862306a36Sopenharmony_ci 0x3c200, 0xffffffff, 0x00000100, 148962306a36Sopenharmony_ci 0x3c230, 0xffffffff, 0x00000100, 149062306a36Sopenharmony_ci 0x3c234, 0xffffffff, 0x00000100, 149162306a36Sopenharmony_ci 0x3c250, 0xffffffff, 0x00000100, 149262306a36Sopenharmony_ci 0x3c254, 0xffffffff, 0x00000100, 149362306a36Sopenharmony_ci 0x3c258, 0xffffffff, 0x00000100, 149462306a36Sopenharmony_ci 0x3c25c, 0xffffffff, 0x00000100, 149562306a36Sopenharmony_ci 0x3c260, 0xffffffff, 0x00000100, 149662306a36Sopenharmony_ci 0x3c27c, 0xffffffff, 0x00000100, 149762306a36Sopenharmony_ci 0x3c278, 0xffffffff, 0x00000100, 149862306a36Sopenharmony_ci 0x3c210, 0xffffffff, 0x06000100, 149962306a36Sopenharmony_ci 0x3c290, 0xffffffff, 0x00000100, 150062306a36Sopenharmony_ci 0x3c274, 0xffffffff, 0x00000100, 150162306a36Sopenharmony_ci 0x3c2b4, 0xffffffff, 0x00000100, 150262306a36Sopenharmony_ci 0x3c2b0, 0xffffffff, 0x00000100, 150362306a36Sopenharmony_ci 0x3c270, 0xffffffff, 0x00000100, 150462306a36Sopenharmony_ci 0x30800, 0xffffffff, 0xe0000000, 150562306a36Sopenharmony_ci 0x3c020, 0xffffffff, 0x00010000, 150662306a36Sopenharmony_ci 0x3c024, 0xffffffff, 0x00030002, 150762306a36Sopenharmony_ci 0x3c028, 0xffffffff, 0x00040007, 150862306a36Sopenharmony_ci 0x3c02c, 0xffffffff, 0x00060005, 150962306a36Sopenharmony_ci 0x3c030, 0xffffffff, 0x00090008, 151062306a36Sopenharmony_ci 0x3c034, 0xffffffff, 0x00010000, 151162306a36Sopenharmony_ci 0x3c038, 0xffffffff, 0x00030002, 151262306a36Sopenharmony_ci 0x3c03c, 0xffffffff, 0x00040007, 151362306a36Sopenharmony_ci 0x3c040, 0xffffffff, 0x00060005, 151462306a36Sopenharmony_ci 0x3c044, 0xffffffff, 0x00090008, 151562306a36Sopenharmony_ci 0x3c048, 0xffffffff, 0x00010000, 151662306a36Sopenharmony_ci 0x3c04c, 0xffffffff, 0x00030002, 151762306a36Sopenharmony_ci 0x3c050, 0xffffffff, 0x00040007, 151862306a36Sopenharmony_ci 0x3c054, 0xffffffff, 0x00060005, 151962306a36Sopenharmony_ci 0x3c058, 0xffffffff, 0x00090008, 152062306a36Sopenharmony_ci 0x3c05c, 0xffffffff, 0x00010000, 152162306a36Sopenharmony_ci 0x3c060, 0xffffffff, 0x00030002, 152262306a36Sopenharmony_ci 0x3c064, 0xffffffff, 0x00040007, 152362306a36Sopenharmony_ci 0x3c068, 0xffffffff, 0x00060005, 152462306a36Sopenharmony_ci 0x3c06c, 0xffffffff, 0x00090008, 152562306a36Sopenharmony_ci 0x3c070, 0xffffffff, 0x00010000, 152662306a36Sopenharmony_ci 0x3c074, 0xffffffff, 0x00030002, 152762306a36Sopenharmony_ci 0x3c078, 0xffffffff, 0x00040007, 152862306a36Sopenharmony_ci 0x3c07c, 0xffffffff, 0x00060005, 152962306a36Sopenharmony_ci 0x3c080, 0xffffffff, 0x00090008, 153062306a36Sopenharmony_ci 0x3c084, 0xffffffff, 0x00010000, 153162306a36Sopenharmony_ci 0x3c088, 0xffffffff, 0x00030002, 153262306a36Sopenharmony_ci 0x3c08c, 0xffffffff, 0x00040007, 153362306a36Sopenharmony_ci 0x3c090, 0xffffffff, 0x00060005, 153462306a36Sopenharmony_ci 0x3c094, 0xffffffff, 0x00090008, 153562306a36Sopenharmony_ci 0x3c098, 0xffffffff, 0x00010000, 153662306a36Sopenharmony_ci 0x3c09c, 0xffffffff, 0x00030002, 153762306a36Sopenharmony_ci 0x3c0a0, 0xffffffff, 0x00040007, 153862306a36Sopenharmony_ci 0x3c0a4, 0xffffffff, 0x00060005, 153962306a36Sopenharmony_ci 0x3c0a8, 0xffffffff, 0x00090008, 154062306a36Sopenharmony_ci 0x3c0ac, 0xffffffff, 0x00010000, 154162306a36Sopenharmony_ci 0x3c0b0, 0xffffffff, 0x00030002, 154262306a36Sopenharmony_ci 0x3c0b4, 0xffffffff, 0x00040007, 154362306a36Sopenharmony_ci 0x3c0b8, 0xffffffff, 0x00060005, 154462306a36Sopenharmony_ci 0x3c0bc, 0xffffffff, 0x00090008, 154562306a36Sopenharmony_ci 0x3c0c0, 0xffffffff, 0x00010000, 154662306a36Sopenharmony_ci 0x3c0c4, 0xffffffff, 0x00030002, 154762306a36Sopenharmony_ci 0x3c0c8, 0xffffffff, 0x00040007, 154862306a36Sopenharmony_ci 0x3c0cc, 0xffffffff, 0x00060005, 154962306a36Sopenharmony_ci 0x3c0d0, 0xffffffff, 0x00090008, 155062306a36Sopenharmony_ci 0x3c0d4, 0xffffffff, 0x00010000, 155162306a36Sopenharmony_ci 0x3c0d8, 0xffffffff, 0x00030002, 155262306a36Sopenharmony_ci 0x3c0dc, 0xffffffff, 0x00040007, 155362306a36Sopenharmony_ci 0x3c0e0, 0xffffffff, 0x00060005, 155462306a36Sopenharmony_ci 0x3c0e4, 0xffffffff, 0x00090008, 155562306a36Sopenharmony_ci 0x3c0e8, 0xffffffff, 0x00010000, 155662306a36Sopenharmony_ci 0x3c0ec, 0xffffffff, 0x00030002, 155762306a36Sopenharmony_ci 0x3c0f0, 0xffffffff, 0x00040007, 155862306a36Sopenharmony_ci 0x3c0f4, 0xffffffff, 0x00060005, 155962306a36Sopenharmony_ci 0x3c0f8, 0xffffffff, 0x00090008, 156062306a36Sopenharmony_ci 0xc318, 0xffffffff, 0x00020200, 156162306a36Sopenharmony_ci 0x3350, 0xffffffff, 0x00000200, 156262306a36Sopenharmony_ci 0x15c0, 0xffffffff, 0x00000400, 156362306a36Sopenharmony_ci 0x55e8, 0xffffffff, 0x00000000, 156462306a36Sopenharmony_ci 0x2f50, 0xffffffff, 0x00000902, 156562306a36Sopenharmony_ci 0x3c000, 0xffffffff, 0x96940200, 156662306a36Sopenharmony_ci 0x8708, 0xffffffff, 0x00900100, 156762306a36Sopenharmony_ci 0xc424, 0xffffffff, 0x0020003f, 156862306a36Sopenharmony_ci 0x38, 0xffffffff, 0x0140001c, 156962306a36Sopenharmony_ci 0x3c, 0x000f0000, 0x000f0000, 157062306a36Sopenharmony_ci 0x220, 0xffffffff, 0xc060000c, 157162306a36Sopenharmony_ci 0x224, 0xc0000fff, 0x00000100, 157262306a36Sopenharmony_ci 0xf90, 0xffffffff, 0x00000100, 157362306a36Sopenharmony_ci 0xf98, 0x00000101, 0x00000000, 157462306a36Sopenharmony_ci 0x20a8, 0xffffffff, 0x00000104, 157562306a36Sopenharmony_ci 0x55e4, 0xff000fff, 0x00000100, 157662306a36Sopenharmony_ci 0x30cc, 0xc0000fff, 0x00000104, 157762306a36Sopenharmony_ci 0xc1e4, 0x00000001, 0x00000001, 157862306a36Sopenharmony_ci 0xd00c, 0xff000ff0, 0x00000100, 157962306a36Sopenharmony_ci 0xd80c, 0xff000ff0, 0x00000100 158062306a36Sopenharmony_ci}; 158162306a36Sopenharmony_ci 158262306a36Sopenharmony_cistatic const u32 godavari_golden_registers[] = 158362306a36Sopenharmony_ci{ 158462306a36Sopenharmony_ci 0x55e4, 0xff607fff, 0xfc000100, 158562306a36Sopenharmony_ci 0x6ed8, 0x00010101, 0x00010000, 158662306a36Sopenharmony_ci 0x9830, 0xffffffff, 0x00000000, 158762306a36Sopenharmony_ci 0x98302, 0xf00fffff, 0x00000400, 158862306a36Sopenharmony_ci 0x6130, 0xffffffff, 0x00010000, 158962306a36Sopenharmony_ci 0x5bb0, 0x000000f0, 0x00000070, 159062306a36Sopenharmony_ci 0x5bc0, 0xf0311fff, 0x80300000, 159162306a36Sopenharmony_ci 0x98f8, 0x73773777, 0x12010001, 159262306a36Sopenharmony_ci 0x98fc, 0xffffffff, 0x00000010, 159362306a36Sopenharmony_ci 0x8030, 0x00001f0f, 0x0000100a, 159462306a36Sopenharmony_ci 0x2f48, 0x73773777, 0x12010001, 159562306a36Sopenharmony_ci 0x2408, 0x000fffff, 0x000c007f, 159662306a36Sopenharmony_ci 0x8a14, 0xf000003f, 0x00000007, 159762306a36Sopenharmony_ci 0x8b24, 0xffffffff, 0x00ff0fff, 159862306a36Sopenharmony_ci 0x30a04, 0x0000ff0f, 0x00000000, 159962306a36Sopenharmony_ci 0x28a4c, 0x07ffffff, 0x06000000, 160062306a36Sopenharmony_ci 0x4d8, 0x00000fff, 0x00000100, 160162306a36Sopenharmony_ci 0xd014, 0x00010000, 0x00810001, 160262306a36Sopenharmony_ci 0xd814, 0x00010000, 0x00810001, 160362306a36Sopenharmony_ci 0x3e78, 0x00000001, 0x00000002, 160462306a36Sopenharmony_ci 0xc768, 0x00000008, 0x00000008, 160562306a36Sopenharmony_ci 0xc770, 0x00000f00, 0x00000800, 160662306a36Sopenharmony_ci 0xc774, 0x00000f00, 0x00000800, 160762306a36Sopenharmony_ci 0xc798, 0x00ffffff, 0x00ff7fbf, 160862306a36Sopenharmony_ci 0xc79c, 0x00ffffff, 0x00ff7faf, 160962306a36Sopenharmony_ci 0x8c00, 0x000000ff, 0x00000001, 161062306a36Sopenharmony_ci 0x214f8, 0x01ff01ff, 0x00000002, 161162306a36Sopenharmony_ci 0x21498, 0x007ff800, 0x00200000, 161262306a36Sopenharmony_ci 0x2015c, 0xffffffff, 0x00000f40, 161362306a36Sopenharmony_ci 0x88c4, 0x001f3ae3, 0x00000082, 161462306a36Sopenharmony_ci 0x88d4, 0x0000001f, 0x00000010, 161562306a36Sopenharmony_ci 0x30934, 0xffffffff, 0x00000000 161662306a36Sopenharmony_ci}; 161762306a36Sopenharmony_ci 161862306a36Sopenharmony_ci 161962306a36Sopenharmony_cistatic void cik_init_golden_registers(struct radeon_device *rdev) 162062306a36Sopenharmony_ci{ 162162306a36Sopenharmony_ci switch (rdev->family) { 162262306a36Sopenharmony_ci case CHIP_BONAIRE: 162362306a36Sopenharmony_ci radeon_program_register_sequence(rdev, 162462306a36Sopenharmony_ci bonaire_mgcg_cgcg_init, 162562306a36Sopenharmony_ci (const u32)ARRAY_SIZE(bonaire_mgcg_cgcg_init)); 162662306a36Sopenharmony_ci radeon_program_register_sequence(rdev, 162762306a36Sopenharmony_ci bonaire_golden_registers, 162862306a36Sopenharmony_ci (const u32)ARRAY_SIZE(bonaire_golden_registers)); 162962306a36Sopenharmony_ci radeon_program_register_sequence(rdev, 163062306a36Sopenharmony_ci bonaire_golden_common_registers, 163162306a36Sopenharmony_ci (const u32)ARRAY_SIZE(bonaire_golden_common_registers)); 163262306a36Sopenharmony_ci radeon_program_register_sequence(rdev, 163362306a36Sopenharmony_ci bonaire_golden_spm_registers, 163462306a36Sopenharmony_ci (const u32)ARRAY_SIZE(bonaire_golden_spm_registers)); 163562306a36Sopenharmony_ci break; 163662306a36Sopenharmony_ci case CHIP_KABINI: 163762306a36Sopenharmony_ci radeon_program_register_sequence(rdev, 163862306a36Sopenharmony_ci kalindi_mgcg_cgcg_init, 163962306a36Sopenharmony_ci (const u32)ARRAY_SIZE(kalindi_mgcg_cgcg_init)); 164062306a36Sopenharmony_ci radeon_program_register_sequence(rdev, 164162306a36Sopenharmony_ci kalindi_golden_registers, 164262306a36Sopenharmony_ci (const u32)ARRAY_SIZE(kalindi_golden_registers)); 164362306a36Sopenharmony_ci radeon_program_register_sequence(rdev, 164462306a36Sopenharmony_ci kalindi_golden_common_registers, 164562306a36Sopenharmony_ci (const u32)ARRAY_SIZE(kalindi_golden_common_registers)); 164662306a36Sopenharmony_ci radeon_program_register_sequence(rdev, 164762306a36Sopenharmony_ci kalindi_golden_spm_registers, 164862306a36Sopenharmony_ci (const u32)ARRAY_SIZE(kalindi_golden_spm_registers)); 164962306a36Sopenharmony_ci break; 165062306a36Sopenharmony_ci case CHIP_MULLINS: 165162306a36Sopenharmony_ci radeon_program_register_sequence(rdev, 165262306a36Sopenharmony_ci kalindi_mgcg_cgcg_init, 165362306a36Sopenharmony_ci (const u32)ARRAY_SIZE(kalindi_mgcg_cgcg_init)); 165462306a36Sopenharmony_ci radeon_program_register_sequence(rdev, 165562306a36Sopenharmony_ci godavari_golden_registers, 165662306a36Sopenharmony_ci (const u32)ARRAY_SIZE(godavari_golden_registers)); 165762306a36Sopenharmony_ci radeon_program_register_sequence(rdev, 165862306a36Sopenharmony_ci kalindi_golden_common_registers, 165962306a36Sopenharmony_ci (const u32)ARRAY_SIZE(kalindi_golden_common_registers)); 166062306a36Sopenharmony_ci radeon_program_register_sequence(rdev, 166162306a36Sopenharmony_ci kalindi_golden_spm_registers, 166262306a36Sopenharmony_ci (const u32)ARRAY_SIZE(kalindi_golden_spm_registers)); 166362306a36Sopenharmony_ci break; 166462306a36Sopenharmony_ci case CHIP_KAVERI: 166562306a36Sopenharmony_ci radeon_program_register_sequence(rdev, 166662306a36Sopenharmony_ci spectre_mgcg_cgcg_init, 166762306a36Sopenharmony_ci (const u32)ARRAY_SIZE(spectre_mgcg_cgcg_init)); 166862306a36Sopenharmony_ci radeon_program_register_sequence(rdev, 166962306a36Sopenharmony_ci spectre_golden_registers, 167062306a36Sopenharmony_ci (const u32)ARRAY_SIZE(spectre_golden_registers)); 167162306a36Sopenharmony_ci radeon_program_register_sequence(rdev, 167262306a36Sopenharmony_ci spectre_golden_common_registers, 167362306a36Sopenharmony_ci (const u32)ARRAY_SIZE(spectre_golden_common_registers)); 167462306a36Sopenharmony_ci radeon_program_register_sequence(rdev, 167562306a36Sopenharmony_ci spectre_golden_spm_registers, 167662306a36Sopenharmony_ci (const u32)ARRAY_SIZE(spectre_golden_spm_registers)); 167762306a36Sopenharmony_ci break; 167862306a36Sopenharmony_ci case CHIP_HAWAII: 167962306a36Sopenharmony_ci radeon_program_register_sequence(rdev, 168062306a36Sopenharmony_ci hawaii_mgcg_cgcg_init, 168162306a36Sopenharmony_ci (const u32)ARRAY_SIZE(hawaii_mgcg_cgcg_init)); 168262306a36Sopenharmony_ci radeon_program_register_sequence(rdev, 168362306a36Sopenharmony_ci hawaii_golden_registers, 168462306a36Sopenharmony_ci (const u32)ARRAY_SIZE(hawaii_golden_registers)); 168562306a36Sopenharmony_ci radeon_program_register_sequence(rdev, 168662306a36Sopenharmony_ci hawaii_golden_common_registers, 168762306a36Sopenharmony_ci (const u32)ARRAY_SIZE(hawaii_golden_common_registers)); 168862306a36Sopenharmony_ci radeon_program_register_sequence(rdev, 168962306a36Sopenharmony_ci hawaii_golden_spm_registers, 169062306a36Sopenharmony_ci (const u32)ARRAY_SIZE(hawaii_golden_spm_registers)); 169162306a36Sopenharmony_ci break; 169262306a36Sopenharmony_ci default: 169362306a36Sopenharmony_ci break; 169462306a36Sopenharmony_ci } 169562306a36Sopenharmony_ci} 169662306a36Sopenharmony_ci 169762306a36Sopenharmony_ci/** 169862306a36Sopenharmony_ci * cik_get_xclk - get the xclk 169962306a36Sopenharmony_ci * 170062306a36Sopenharmony_ci * @rdev: radeon_device pointer 170162306a36Sopenharmony_ci * 170262306a36Sopenharmony_ci * Returns the reference clock used by the gfx engine 170362306a36Sopenharmony_ci * (CIK). 170462306a36Sopenharmony_ci */ 170562306a36Sopenharmony_ciu32 cik_get_xclk(struct radeon_device *rdev) 170662306a36Sopenharmony_ci{ 170762306a36Sopenharmony_ci u32 reference_clock = rdev->clock.spll.reference_freq; 170862306a36Sopenharmony_ci 170962306a36Sopenharmony_ci if (rdev->flags & RADEON_IS_IGP) { 171062306a36Sopenharmony_ci if (RREG32_SMC(GENERAL_PWRMGT) & GPU_COUNTER_CLK) 171162306a36Sopenharmony_ci return reference_clock / 2; 171262306a36Sopenharmony_ci } else { 171362306a36Sopenharmony_ci if (RREG32_SMC(CG_CLKPIN_CNTL) & XTALIN_DIVIDE) 171462306a36Sopenharmony_ci return reference_clock / 4; 171562306a36Sopenharmony_ci } 171662306a36Sopenharmony_ci return reference_clock; 171762306a36Sopenharmony_ci} 171862306a36Sopenharmony_ci 171962306a36Sopenharmony_ci/** 172062306a36Sopenharmony_ci * cik_mm_rdoorbell - read a doorbell dword 172162306a36Sopenharmony_ci * 172262306a36Sopenharmony_ci * @rdev: radeon_device pointer 172362306a36Sopenharmony_ci * @index: doorbell index 172462306a36Sopenharmony_ci * 172562306a36Sopenharmony_ci * Returns the value in the doorbell aperture at the 172662306a36Sopenharmony_ci * requested doorbell index (CIK). 172762306a36Sopenharmony_ci */ 172862306a36Sopenharmony_ciu32 cik_mm_rdoorbell(struct radeon_device *rdev, u32 index) 172962306a36Sopenharmony_ci{ 173062306a36Sopenharmony_ci if (index < rdev->doorbell.num_doorbells) { 173162306a36Sopenharmony_ci return readl(rdev->doorbell.ptr + index); 173262306a36Sopenharmony_ci } else { 173362306a36Sopenharmony_ci DRM_ERROR("reading beyond doorbell aperture: 0x%08x!\n", index); 173462306a36Sopenharmony_ci return 0; 173562306a36Sopenharmony_ci } 173662306a36Sopenharmony_ci} 173762306a36Sopenharmony_ci 173862306a36Sopenharmony_ci/** 173962306a36Sopenharmony_ci * cik_mm_wdoorbell - write a doorbell dword 174062306a36Sopenharmony_ci * 174162306a36Sopenharmony_ci * @rdev: radeon_device pointer 174262306a36Sopenharmony_ci * @index: doorbell index 174362306a36Sopenharmony_ci * @v: value to write 174462306a36Sopenharmony_ci * 174562306a36Sopenharmony_ci * Writes @v to the doorbell aperture at the 174662306a36Sopenharmony_ci * requested doorbell index (CIK). 174762306a36Sopenharmony_ci */ 174862306a36Sopenharmony_civoid cik_mm_wdoorbell(struct radeon_device *rdev, u32 index, u32 v) 174962306a36Sopenharmony_ci{ 175062306a36Sopenharmony_ci if (index < rdev->doorbell.num_doorbells) { 175162306a36Sopenharmony_ci writel(v, rdev->doorbell.ptr + index); 175262306a36Sopenharmony_ci } else { 175362306a36Sopenharmony_ci DRM_ERROR("writing beyond doorbell aperture: 0x%08x!\n", index); 175462306a36Sopenharmony_ci } 175562306a36Sopenharmony_ci} 175662306a36Sopenharmony_ci 175762306a36Sopenharmony_ci#define BONAIRE_IO_MC_REGS_SIZE 36 175862306a36Sopenharmony_ci 175962306a36Sopenharmony_cistatic const u32 bonaire_io_mc_regs[BONAIRE_IO_MC_REGS_SIZE][2] = 176062306a36Sopenharmony_ci{ 176162306a36Sopenharmony_ci {0x00000070, 0x04400000}, 176262306a36Sopenharmony_ci {0x00000071, 0x80c01803}, 176362306a36Sopenharmony_ci {0x00000072, 0x00004004}, 176462306a36Sopenharmony_ci {0x00000073, 0x00000100}, 176562306a36Sopenharmony_ci {0x00000074, 0x00ff0000}, 176662306a36Sopenharmony_ci {0x00000075, 0x34000000}, 176762306a36Sopenharmony_ci {0x00000076, 0x08000014}, 176862306a36Sopenharmony_ci {0x00000077, 0x00cc08ec}, 176962306a36Sopenharmony_ci {0x00000078, 0x00000400}, 177062306a36Sopenharmony_ci {0x00000079, 0x00000000}, 177162306a36Sopenharmony_ci {0x0000007a, 0x04090000}, 177262306a36Sopenharmony_ci {0x0000007c, 0x00000000}, 177362306a36Sopenharmony_ci {0x0000007e, 0x4408a8e8}, 177462306a36Sopenharmony_ci {0x0000007f, 0x00000304}, 177562306a36Sopenharmony_ci {0x00000080, 0x00000000}, 177662306a36Sopenharmony_ci {0x00000082, 0x00000001}, 177762306a36Sopenharmony_ci {0x00000083, 0x00000002}, 177862306a36Sopenharmony_ci {0x00000084, 0xf3e4f400}, 177962306a36Sopenharmony_ci {0x00000085, 0x052024e3}, 178062306a36Sopenharmony_ci {0x00000087, 0x00000000}, 178162306a36Sopenharmony_ci {0x00000088, 0x01000000}, 178262306a36Sopenharmony_ci {0x0000008a, 0x1c0a0000}, 178362306a36Sopenharmony_ci {0x0000008b, 0xff010000}, 178462306a36Sopenharmony_ci {0x0000008d, 0xffffefff}, 178562306a36Sopenharmony_ci {0x0000008e, 0xfff3efff}, 178662306a36Sopenharmony_ci {0x0000008f, 0xfff3efbf}, 178762306a36Sopenharmony_ci {0x00000092, 0xf7ffffff}, 178862306a36Sopenharmony_ci {0x00000093, 0xffffff7f}, 178962306a36Sopenharmony_ci {0x00000095, 0x00101101}, 179062306a36Sopenharmony_ci {0x00000096, 0x00000fff}, 179162306a36Sopenharmony_ci {0x00000097, 0x00116fff}, 179262306a36Sopenharmony_ci {0x00000098, 0x60010000}, 179362306a36Sopenharmony_ci {0x00000099, 0x10010000}, 179462306a36Sopenharmony_ci {0x0000009a, 0x00006000}, 179562306a36Sopenharmony_ci {0x0000009b, 0x00001000}, 179662306a36Sopenharmony_ci {0x0000009f, 0x00b48000} 179762306a36Sopenharmony_ci}; 179862306a36Sopenharmony_ci 179962306a36Sopenharmony_ci#define HAWAII_IO_MC_REGS_SIZE 22 180062306a36Sopenharmony_ci 180162306a36Sopenharmony_cistatic const u32 hawaii_io_mc_regs[HAWAII_IO_MC_REGS_SIZE][2] = 180262306a36Sopenharmony_ci{ 180362306a36Sopenharmony_ci {0x0000007d, 0x40000000}, 180462306a36Sopenharmony_ci {0x0000007e, 0x40180304}, 180562306a36Sopenharmony_ci {0x0000007f, 0x0000ff00}, 180662306a36Sopenharmony_ci {0x00000081, 0x00000000}, 180762306a36Sopenharmony_ci {0x00000083, 0x00000800}, 180862306a36Sopenharmony_ci {0x00000086, 0x00000000}, 180962306a36Sopenharmony_ci {0x00000087, 0x00000100}, 181062306a36Sopenharmony_ci {0x00000088, 0x00020100}, 181162306a36Sopenharmony_ci {0x00000089, 0x00000000}, 181262306a36Sopenharmony_ci {0x0000008b, 0x00040000}, 181362306a36Sopenharmony_ci {0x0000008c, 0x00000100}, 181462306a36Sopenharmony_ci {0x0000008e, 0xff010000}, 181562306a36Sopenharmony_ci {0x00000090, 0xffffefff}, 181662306a36Sopenharmony_ci {0x00000091, 0xfff3efff}, 181762306a36Sopenharmony_ci {0x00000092, 0xfff3efbf}, 181862306a36Sopenharmony_ci {0x00000093, 0xf7ffffff}, 181962306a36Sopenharmony_ci {0x00000094, 0xffffff7f}, 182062306a36Sopenharmony_ci {0x00000095, 0x00000fff}, 182162306a36Sopenharmony_ci {0x00000096, 0x00116fff}, 182262306a36Sopenharmony_ci {0x00000097, 0x60010000}, 182362306a36Sopenharmony_ci {0x00000098, 0x10010000}, 182462306a36Sopenharmony_ci {0x0000009f, 0x00c79000} 182562306a36Sopenharmony_ci}; 182662306a36Sopenharmony_ci 182762306a36Sopenharmony_ci 182862306a36Sopenharmony_ci/** 182962306a36Sopenharmony_ci * cik_srbm_select - select specific register instances 183062306a36Sopenharmony_ci * 183162306a36Sopenharmony_ci * @rdev: radeon_device pointer 183262306a36Sopenharmony_ci * @me: selected ME (micro engine) 183362306a36Sopenharmony_ci * @pipe: pipe 183462306a36Sopenharmony_ci * @queue: queue 183562306a36Sopenharmony_ci * @vmid: VMID 183662306a36Sopenharmony_ci * 183762306a36Sopenharmony_ci * Switches the currently active registers instances. Some 183862306a36Sopenharmony_ci * registers are instanced per VMID, others are instanced per 183962306a36Sopenharmony_ci * me/pipe/queue combination. 184062306a36Sopenharmony_ci */ 184162306a36Sopenharmony_cistatic void cik_srbm_select(struct radeon_device *rdev, 184262306a36Sopenharmony_ci u32 me, u32 pipe, u32 queue, u32 vmid) 184362306a36Sopenharmony_ci{ 184462306a36Sopenharmony_ci u32 srbm_gfx_cntl = (PIPEID(pipe & 0x3) | 184562306a36Sopenharmony_ci MEID(me & 0x3) | 184662306a36Sopenharmony_ci VMID(vmid & 0xf) | 184762306a36Sopenharmony_ci QUEUEID(queue & 0x7)); 184862306a36Sopenharmony_ci WREG32(SRBM_GFX_CNTL, srbm_gfx_cntl); 184962306a36Sopenharmony_ci} 185062306a36Sopenharmony_ci 185162306a36Sopenharmony_ci/* ucode loading */ 185262306a36Sopenharmony_ci/** 185362306a36Sopenharmony_ci * ci_mc_load_microcode - load MC ucode into the hw 185462306a36Sopenharmony_ci * 185562306a36Sopenharmony_ci * @rdev: radeon_device pointer 185662306a36Sopenharmony_ci * 185762306a36Sopenharmony_ci * Load the GDDR MC ucode into the hw (CIK). 185862306a36Sopenharmony_ci * Returns 0 on success, error on failure. 185962306a36Sopenharmony_ci */ 186062306a36Sopenharmony_ciint ci_mc_load_microcode(struct radeon_device *rdev) 186162306a36Sopenharmony_ci{ 186262306a36Sopenharmony_ci const __be32 *fw_data = NULL; 186362306a36Sopenharmony_ci const __le32 *new_fw_data = NULL; 186462306a36Sopenharmony_ci u32 running, tmp; 186562306a36Sopenharmony_ci u32 *io_mc_regs = NULL; 186662306a36Sopenharmony_ci const __le32 *new_io_mc_regs = NULL; 186762306a36Sopenharmony_ci int i, regs_size, ucode_size; 186862306a36Sopenharmony_ci 186962306a36Sopenharmony_ci if (!rdev->mc_fw) 187062306a36Sopenharmony_ci return -EINVAL; 187162306a36Sopenharmony_ci 187262306a36Sopenharmony_ci if (rdev->new_fw) { 187362306a36Sopenharmony_ci const struct mc_firmware_header_v1_0 *hdr = 187462306a36Sopenharmony_ci (const struct mc_firmware_header_v1_0 *)rdev->mc_fw->data; 187562306a36Sopenharmony_ci 187662306a36Sopenharmony_ci radeon_ucode_print_mc_hdr(&hdr->header); 187762306a36Sopenharmony_ci 187862306a36Sopenharmony_ci regs_size = le32_to_cpu(hdr->io_debug_size_bytes) / (4 * 2); 187962306a36Sopenharmony_ci new_io_mc_regs = (const __le32 *) 188062306a36Sopenharmony_ci (rdev->mc_fw->data + le32_to_cpu(hdr->io_debug_array_offset_bytes)); 188162306a36Sopenharmony_ci ucode_size = le32_to_cpu(hdr->header.ucode_size_bytes) / 4; 188262306a36Sopenharmony_ci new_fw_data = (const __le32 *) 188362306a36Sopenharmony_ci (rdev->mc_fw->data + le32_to_cpu(hdr->header.ucode_array_offset_bytes)); 188462306a36Sopenharmony_ci } else { 188562306a36Sopenharmony_ci ucode_size = rdev->mc_fw->size / 4; 188662306a36Sopenharmony_ci 188762306a36Sopenharmony_ci switch (rdev->family) { 188862306a36Sopenharmony_ci case CHIP_BONAIRE: 188962306a36Sopenharmony_ci io_mc_regs = (u32 *)&bonaire_io_mc_regs; 189062306a36Sopenharmony_ci regs_size = BONAIRE_IO_MC_REGS_SIZE; 189162306a36Sopenharmony_ci break; 189262306a36Sopenharmony_ci case CHIP_HAWAII: 189362306a36Sopenharmony_ci io_mc_regs = (u32 *)&hawaii_io_mc_regs; 189462306a36Sopenharmony_ci regs_size = HAWAII_IO_MC_REGS_SIZE; 189562306a36Sopenharmony_ci break; 189662306a36Sopenharmony_ci default: 189762306a36Sopenharmony_ci return -EINVAL; 189862306a36Sopenharmony_ci } 189962306a36Sopenharmony_ci fw_data = (const __be32 *)rdev->mc_fw->data; 190062306a36Sopenharmony_ci } 190162306a36Sopenharmony_ci 190262306a36Sopenharmony_ci running = RREG32(MC_SEQ_SUP_CNTL) & RUN_MASK; 190362306a36Sopenharmony_ci 190462306a36Sopenharmony_ci if (running == 0) { 190562306a36Sopenharmony_ci /* reset the engine and set to writable */ 190662306a36Sopenharmony_ci WREG32(MC_SEQ_SUP_CNTL, 0x00000008); 190762306a36Sopenharmony_ci WREG32(MC_SEQ_SUP_CNTL, 0x00000010); 190862306a36Sopenharmony_ci 190962306a36Sopenharmony_ci /* load mc io regs */ 191062306a36Sopenharmony_ci for (i = 0; i < regs_size; i++) { 191162306a36Sopenharmony_ci if (rdev->new_fw) { 191262306a36Sopenharmony_ci WREG32(MC_SEQ_IO_DEBUG_INDEX, le32_to_cpup(new_io_mc_regs++)); 191362306a36Sopenharmony_ci WREG32(MC_SEQ_IO_DEBUG_DATA, le32_to_cpup(new_io_mc_regs++)); 191462306a36Sopenharmony_ci } else { 191562306a36Sopenharmony_ci WREG32(MC_SEQ_IO_DEBUG_INDEX, io_mc_regs[(i << 1)]); 191662306a36Sopenharmony_ci WREG32(MC_SEQ_IO_DEBUG_DATA, io_mc_regs[(i << 1) + 1]); 191762306a36Sopenharmony_ci } 191862306a36Sopenharmony_ci } 191962306a36Sopenharmony_ci 192062306a36Sopenharmony_ci tmp = RREG32(MC_SEQ_MISC0); 192162306a36Sopenharmony_ci if ((rdev->pdev->device == 0x6649) && ((tmp & 0xff00) == 0x5600)) { 192262306a36Sopenharmony_ci WREG32(MC_SEQ_IO_DEBUG_INDEX, 5); 192362306a36Sopenharmony_ci WREG32(MC_SEQ_IO_DEBUG_DATA, 0x00000023); 192462306a36Sopenharmony_ci WREG32(MC_SEQ_IO_DEBUG_INDEX, 9); 192562306a36Sopenharmony_ci WREG32(MC_SEQ_IO_DEBUG_DATA, 0x000001f0); 192662306a36Sopenharmony_ci } 192762306a36Sopenharmony_ci 192862306a36Sopenharmony_ci /* load the MC ucode */ 192962306a36Sopenharmony_ci for (i = 0; i < ucode_size; i++) { 193062306a36Sopenharmony_ci if (rdev->new_fw) 193162306a36Sopenharmony_ci WREG32(MC_SEQ_SUP_PGM, le32_to_cpup(new_fw_data++)); 193262306a36Sopenharmony_ci else 193362306a36Sopenharmony_ci WREG32(MC_SEQ_SUP_PGM, be32_to_cpup(fw_data++)); 193462306a36Sopenharmony_ci } 193562306a36Sopenharmony_ci 193662306a36Sopenharmony_ci /* put the engine back into the active state */ 193762306a36Sopenharmony_ci WREG32(MC_SEQ_SUP_CNTL, 0x00000008); 193862306a36Sopenharmony_ci WREG32(MC_SEQ_SUP_CNTL, 0x00000004); 193962306a36Sopenharmony_ci WREG32(MC_SEQ_SUP_CNTL, 0x00000001); 194062306a36Sopenharmony_ci 194162306a36Sopenharmony_ci /* wait for training to complete */ 194262306a36Sopenharmony_ci for (i = 0; i < rdev->usec_timeout; i++) { 194362306a36Sopenharmony_ci if (RREG32(MC_SEQ_TRAIN_WAKEUP_CNTL) & TRAIN_DONE_D0) 194462306a36Sopenharmony_ci break; 194562306a36Sopenharmony_ci udelay(1); 194662306a36Sopenharmony_ci } 194762306a36Sopenharmony_ci for (i = 0; i < rdev->usec_timeout; i++) { 194862306a36Sopenharmony_ci if (RREG32(MC_SEQ_TRAIN_WAKEUP_CNTL) & TRAIN_DONE_D1) 194962306a36Sopenharmony_ci break; 195062306a36Sopenharmony_ci udelay(1); 195162306a36Sopenharmony_ci } 195262306a36Sopenharmony_ci } 195362306a36Sopenharmony_ci 195462306a36Sopenharmony_ci return 0; 195562306a36Sopenharmony_ci} 195662306a36Sopenharmony_ci 195762306a36Sopenharmony_ci/** 195862306a36Sopenharmony_ci * cik_init_microcode - load ucode images from disk 195962306a36Sopenharmony_ci * 196062306a36Sopenharmony_ci * @rdev: radeon_device pointer 196162306a36Sopenharmony_ci * 196262306a36Sopenharmony_ci * Use the firmware interface to load the ucode images into 196362306a36Sopenharmony_ci * the driver (not loaded into hw). 196462306a36Sopenharmony_ci * Returns 0 on success, error on failure. 196562306a36Sopenharmony_ci */ 196662306a36Sopenharmony_cistatic int cik_init_microcode(struct radeon_device *rdev) 196762306a36Sopenharmony_ci{ 196862306a36Sopenharmony_ci const char *chip_name; 196962306a36Sopenharmony_ci const char *new_chip_name; 197062306a36Sopenharmony_ci size_t pfp_req_size, me_req_size, ce_req_size, 197162306a36Sopenharmony_ci mec_req_size, rlc_req_size, mc_req_size = 0, 197262306a36Sopenharmony_ci sdma_req_size, smc_req_size = 0, mc2_req_size = 0; 197362306a36Sopenharmony_ci char fw_name[30]; 197462306a36Sopenharmony_ci int new_fw = 0; 197562306a36Sopenharmony_ci int err; 197662306a36Sopenharmony_ci int num_fw; 197762306a36Sopenharmony_ci bool new_smc = false; 197862306a36Sopenharmony_ci 197962306a36Sopenharmony_ci DRM_DEBUG("\n"); 198062306a36Sopenharmony_ci 198162306a36Sopenharmony_ci switch (rdev->family) { 198262306a36Sopenharmony_ci case CHIP_BONAIRE: 198362306a36Sopenharmony_ci chip_name = "BONAIRE"; 198462306a36Sopenharmony_ci if ((rdev->pdev->revision == 0x80) || 198562306a36Sopenharmony_ci (rdev->pdev->revision == 0x81) || 198662306a36Sopenharmony_ci (rdev->pdev->device == 0x665f)) 198762306a36Sopenharmony_ci new_smc = true; 198862306a36Sopenharmony_ci new_chip_name = "bonaire"; 198962306a36Sopenharmony_ci pfp_req_size = CIK_PFP_UCODE_SIZE * 4; 199062306a36Sopenharmony_ci me_req_size = CIK_ME_UCODE_SIZE * 4; 199162306a36Sopenharmony_ci ce_req_size = CIK_CE_UCODE_SIZE * 4; 199262306a36Sopenharmony_ci mec_req_size = CIK_MEC_UCODE_SIZE * 4; 199362306a36Sopenharmony_ci rlc_req_size = BONAIRE_RLC_UCODE_SIZE * 4; 199462306a36Sopenharmony_ci mc_req_size = BONAIRE_MC_UCODE_SIZE * 4; 199562306a36Sopenharmony_ci mc2_req_size = BONAIRE_MC2_UCODE_SIZE * 4; 199662306a36Sopenharmony_ci sdma_req_size = CIK_SDMA_UCODE_SIZE * 4; 199762306a36Sopenharmony_ci smc_req_size = ALIGN(BONAIRE_SMC_UCODE_SIZE, 4); 199862306a36Sopenharmony_ci num_fw = 8; 199962306a36Sopenharmony_ci break; 200062306a36Sopenharmony_ci case CHIP_HAWAII: 200162306a36Sopenharmony_ci chip_name = "HAWAII"; 200262306a36Sopenharmony_ci if (rdev->pdev->revision == 0x80) 200362306a36Sopenharmony_ci new_smc = true; 200462306a36Sopenharmony_ci new_chip_name = "hawaii"; 200562306a36Sopenharmony_ci pfp_req_size = CIK_PFP_UCODE_SIZE * 4; 200662306a36Sopenharmony_ci me_req_size = CIK_ME_UCODE_SIZE * 4; 200762306a36Sopenharmony_ci ce_req_size = CIK_CE_UCODE_SIZE * 4; 200862306a36Sopenharmony_ci mec_req_size = CIK_MEC_UCODE_SIZE * 4; 200962306a36Sopenharmony_ci rlc_req_size = BONAIRE_RLC_UCODE_SIZE * 4; 201062306a36Sopenharmony_ci mc_req_size = HAWAII_MC_UCODE_SIZE * 4; 201162306a36Sopenharmony_ci mc2_req_size = HAWAII_MC2_UCODE_SIZE * 4; 201262306a36Sopenharmony_ci sdma_req_size = CIK_SDMA_UCODE_SIZE * 4; 201362306a36Sopenharmony_ci smc_req_size = ALIGN(HAWAII_SMC_UCODE_SIZE, 4); 201462306a36Sopenharmony_ci num_fw = 8; 201562306a36Sopenharmony_ci break; 201662306a36Sopenharmony_ci case CHIP_KAVERI: 201762306a36Sopenharmony_ci chip_name = "KAVERI"; 201862306a36Sopenharmony_ci new_chip_name = "kaveri"; 201962306a36Sopenharmony_ci pfp_req_size = CIK_PFP_UCODE_SIZE * 4; 202062306a36Sopenharmony_ci me_req_size = CIK_ME_UCODE_SIZE * 4; 202162306a36Sopenharmony_ci ce_req_size = CIK_CE_UCODE_SIZE * 4; 202262306a36Sopenharmony_ci mec_req_size = CIK_MEC_UCODE_SIZE * 4; 202362306a36Sopenharmony_ci rlc_req_size = KV_RLC_UCODE_SIZE * 4; 202462306a36Sopenharmony_ci sdma_req_size = CIK_SDMA_UCODE_SIZE * 4; 202562306a36Sopenharmony_ci num_fw = 7; 202662306a36Sopenharmony_ci break; 202762306a36Sopenharmony_ci case CHIP_KABINI: 202862306a36Sopenharmony_ci chip_name = "KABINI"; 202962306a36Sopenharmony_ci new_chip_name = "kabini"; 203062306a36Sopenharmony_ci pfp_req_size = CIK_PFP_UCODE_SIZE * 4; 203162306a36Sopenharmony_ci me_req_size = CIK_ME_UCODE_SIZE * 4; 203262306a36Sopenharmony_ci ce_req_size = CIK_CE_UCODE_SIZE * 4; 203362306a36Sopenharmony_ci mec_req_size = CIK_MEC_UCODE_SIZE * 4; 203462306a36Sopenharmony_ci rlc_req_size = KB_RLC_UCODE_SIZE * 4; 203562306a36Sopenharmony_ci sdma_req_size = CIK_SDMA_UCODE_SIZE * 4; 203662306a36Sopenharmony_ci num_fw = 6; 203762306a36Sopenharmony_ci break; 203862306a36Sopenharmony_ci case CHIP_MULLINS: 203962306a36Sopenharmony_ci chip_name = "MULLINS"; 204062306a36Sopenharmony_ci new_chip_name = "mullins"; 204162306a36Sopenharmony_ci pfp_req_size = CIK_PFP_UCODE_SIZE * 4; 204262306a36Sopenharmony_ci me_req_size = CIK_ME_UCODE_SIZE * 4; 204362306a36Sopenharmony_ci ce_req_size = CIK_CE_UCODE_SIZE * 4; 204462306a36Sopenharmony_ci mec_req_size = CIK_MEC_UCODE_SIZE * 4; 204562306a36Sopenharmony_ci rlc_req_size = ML_RLC_UCODE_SIZE * 4; 204662306a36Sopenharmony_ci sdma_req_size = CIK_SDMA_UCODE_SIZE * 4; 204762306a36Sopenharmony_ci num_fw = 6; 204862306a36Sopenharmony_ci break; 204962306a36Sopenharmony_ci default: BUG(); 205062306a36Sopenharmony_ci } 205162306a36Sopenharmony_ci 205262306a36Sopenharmony_ci DRM_INFO("Loading %s Microcode\n", new_chip_name); 205362306a36Sopenharmony_ci 205462306a36Sopenharmony_ci snprintf(fw_name, sizeof(fw_name), "radeon/%s_pfp.bin", new_chip_name); 205562306a36Sopenharmony_ci err = request_firmware(&rdev->pfp_fw, fw_name, rdev->dev); 205662306a36Sopenharmony_ci if (err) { 205762306a36Sopenharmony_ci snprintf(fw_name, sizeof(fw_name), "radeon/%s_pfp.bin", chip_name); 205862306a36Sopenharmony_ci err = request_firmware(&rdev->pfp_fw, fw_name, rdev->dev); 205962306a36Sopenharmony_ci if (err) 206062306a36Sopenharmony_ci goto out; 206162306a36Sopenharmony_ci if (rdev->pfp_fw->size != pfp_req_size) { 206262306a36Sopenharmony_ci pr_err("cik_cp: Bogus length %zu in firmware \"%s\"\n", 206362306a36Sopenharmony_ci rdev->pfp_fw->size, fw_name); 206462306a36Sopenharmony_ci err = -EINVAL; 206562306a36Sopenharmony_ci goto out; 206662306a36Sopenharmony_ci } 206762306a36Sopenharmony_ci } else { 206862306a36Sopenharmony_ci err = radeon_ucode_validate(rdev->pfp_fw); 206962306a36Sopenharmony_ci if (err) { 207062306a36Sopenharmony_ci pr_err("cik_fw: validation failed for firmware \"%s\"\n", 207162306a36Sopenharmony_ci fw_name); 207262306a36Sopenharmony_ci goto out; 207362306a36Sopenharmony_ci } else { 207462306a36Sopenharmony_ci new_fw++; 207562306a36Sopenharmony_ci } 207662306a36Sopenharmony_ci } 207762306a36Sopenharmony_ci 207862306a36Sopenharmony_ci snprintf(fw_name, sizeof(fw_name), "radeon/%s_me.bin", new_chip_name); 207962306a36Sopenharmony_ci err = request_firmware(&rdev->me_fw, fw_name, rdev->dev); 208062306a36Sopenharmony_ci if (err) { 208162306a36Sopenharmony_ci snprintf(fw_name, sizeof(fw_name), "radeon/%s_me.bin", chip_name); 208262306a36Sopenharmony_ci err = request_firmware(&rdev->me_fw, fw_name, rdev->dev); 208362306a36Sopenharmony_ci if (err) 208462306a36Sopenharmony_ci goto out; 208562306a36Sopenharmony_ci if (rdev->me_fw->size != me_req_size) { 208662306a36Sopenharmony_ci pr_err("cik_cp: Bogus length %zu in firmware \"%s\"\n", 208762306a36Sopenharmony_ci rdev->me_fw->size, fw_name); 208862306a36Sopenharmony_ci err = -EINVAL; 208962306a36Sopenharmony_ci } 209062306a36Sopenharmony_ci } else { 209162306a36Sopenharmony_ci err = radeon_ucode_validate(rdev->me_fw); 209262306a36Sopenharmony_ci if (err) { 209362306a36Sopenharmony_ci pr_err("cik_fw: validation failed for firmware \"%s\"\n", 209462306a36Sopenharmony_ci fw_name); 209562306a36Sopenharmony_ci goto out; 209662306a36Sopenharmony_ci } else { 209762306a36Sopenharmony_ci new_fw++; 209862306a36Sopenharmony_ci } 209962306a36Sopenharmony_ci } 210062306a36Sopenharmony_ci 210162306a36Sopenharmony_ci snprintf(fw_name, sizeof(fw_name), "radeon/%s_ce.bin", new_chip_name); 210262306a36Sopenharmony_ci err = request_firmware(&rdev->ce_fw, fw_name, rdev->dev); 210362306a36Sopenharmony_ci if (err) { 210462306a36Sopenharmony_ci snprintf(fw_name, sizeof(fw_name), "radeon/%s_ce.bin", chip_name); 210562306a36Sopenharmony_ci err = request_firmware(&rdev->ce_fw, fw_name, rdev->dev); 210662306a36Sopenharmony_ci if (err) 210762306a36Sopenharmony_ci goto out; 210862306a36Sopenharmony_ci if (rdev->ce_fw->size != ce_req_size) { 210962306a36Sopenharmony_ci pr_err("cik_cp: Bogus length %zu in firmware \"%s\"\n", 211062306a36Sopenharmony_ci rdev->ce_fw->size, fw_name); 211162306a36Sopenharmony_ci err = -EINVAL; 211262306a36Sopenharmony_ci } 211362306a36Sopenharmony_ci } else { 211462306a36Sopenharmony_ci err = radeon_ucode_validate(rdev->ce_fw); 211562306a36Sopenharmony_ci if (err) { 211662306a36Sopenharmony_ci pr_err("cik_fw: validation failed for firmware \"%s\"\n", 211762306a36Sopenharmony_ci fw_name); 211862306a36Sopenharmony_ci goto out; 211962306a36Sopenharmony_ci } else { 212062306a36Sopenharmony_ci new_fw++; 212162306a36Sopenharmony_ci } 212262306a36Sopenharmony_ci } 212362306a36Sopenharmony_ci 212462306a36Sopenharmony_ci snprintf(fw_name, sizeof(fw_name), "radeon/%s_mec.bin", new_chip_name); 212562306a36Sopenharmony_ci err = request_firmware(&rdev->mec_fw, fw_name, rdev->dev); 212662306a36Sopenharmony_ci if (err) { 212762306a36Sopenharmony_ci snprintf(fw_name, sizeof(fw_name), "radeon/%s_mec.bin", chip_name); 212862306a36Sopenharmony_ci err = request_firmware(&rdev->mec_fw, fw_name, rdev->dev); 212962306a36Sopenharmony_ci if (err) 213062306a36Sopenharmony_ci goto out; 213162306a36Sopenharmony_ci if (rdev->mec_fw->size != mec_req_size) { 213262306a36Sopenharmony_ci pr_err("cik_cp: Bogus length %zu in firmware \"%s\"\n", 213362306a36Sopenharmony_ci rdev->mec_fw->size, fw_name); 213462306a36Sopenharmony_ci err = -EINVAL; 213562306a36Sopenharmony_ci } 213662306a36Sopenharmony_ci } else { 213762306a36Sopenharmony_ci err = radeon_ucode_validate(rdev->mec_fw); 213862306a36Sopenharmony_ci if (err) { 213962306a36Sopenharmony_ci pr_err("cik_fw: validation failed for firmware \"%s\"\n", 214062306a36Sopenharmony_ci fw_name); 214162306a36Sopenharmony_ci goto out; 214262306a36Sopenharmony_ci } else { 214362306a36Sopenharmony_ci new_fw++; 214462306a36Sopenharmony_ci } 214562306a36Sopenharmony_ci } 214662306a36Sopenharmony_ci 214762306a36Sopenharmony_ci if (rdev->family == CHIP_KAVERI) { 214862306a36Sopenharmony_ci snprintf(fw_name, sizeof(fw_name), "radeon/%s_mec2.bin", new_chip_name); 214962306a36Sopenharmony_ci err = request_firmware(&rdev->mec2_fw, fw_name, rdev->dev); 215062306a36Sopenharmony_ci if (err) { 215162306a36Sopenharmony_ci goto out; 215262306a36Sopenharmony_ci } else { 215362306a36Sopenharmony_ci err = radeon_ucode_validate(rdev->mec2_fw); 215462306a36Sopenharmony_ci if (err) { 215562306a36Sopenharmony_ci goto out; 215662306a36Sopenharmony_ci } else { 215762306a36Sopenharmony_ci new_fw++; 215862306a36Sopenharmony_ci } 215962306a36Sopenharmony_ci } 216062306a36Sopenharmony_ci } 216162306a36Sopenharmony_ci 216262306a36Sopenharmony_ci snprintf(fw_name, sizeof(fw_name), "radeon/%s_rlc.bin", new_chip_name); 216362306a36Sopenharmony_ci err = request_firmware(&rdev->rlc_fw, fw_name, rdev->dev); 216462306a36Sopenharmony_ci if (err) { 216562306a36Sopenharmony_ci snprintf(fw_name, sizeof(fw_name), "radeon/%s_rlc.bin", chip_name); 216662306a36Sopenharmony_ci err = request_firmware(&rdev->rlc_fw, fw_name, rdev->dev); 216762306a36Sopenharmony_ci if (err) 216862306a36Sopenharmony_ci goto out; 216962306a36Sopenharmony_ci if (rdev->rlc_fw->size != rlc_req_size) { 217062306a36Sopenharmony_ci pr_err("cik_rlc: Bogus length %zu in firmware \"%s\"\n", 217162306a36Sopenharmony_ci rdev->rlc_fw->size, fw_name); 217262306a36Sopenharmony_ci err = -EINVAL; 217362306a36Sopenharmony_ci } 217462306a36Sopenharmony_ci } else { 217562306a36Sopenharmony_ci err = radeon_ucode_validate(rdev->rlc_fw); 217662306a36Sopenharmony_ci if (err) { 217762306a36Sopenharmony_ci pr_err("cik_fw: validation failed for firmware \"%s\"\n", 217862306a36Sopenharmony_ci fw_name); 217962306a36Sopenharmony_ci goto out; 218062306a36Sopenharmony_ci } else { 218162306a36Sopenharmony_ci new_fw++; 218262306a36Sopenharmony_ci } 218362306a36Sopenharmony_ci } 218462306a36Sopenharmony_ci 218562306a36Sopenharmony_ci snprintf(fw_name, sizeof(fw_name), "radeon/%s_sdma.bin", new_chip_name); 218662306a36Sopenharmony_ci err = request_firmware(&rdev->sdma_fw, fw_name, rdev->dev); 218762306a36Sopenharmony_ci if (err) { 218862306a36Sopenharmony_ci snprintf(fw_name, sizeof(fw_name), "radeon/%s_sdma.bin", chip_name); 218962306a36Sopenharmony_ci err = request_firmware(&rdev->sdma_fw, fw_name, rdev->dev); 219062306a36Sopenharmony_ci if (err) 219162306a36Sopenharmony_ci goto out; 219262306a36Sopenharmony_ci if (rdev->sdma_fw->size != sdma_req_size) { 219362306a36Sopenharmony_ci pr_err("cik_sdma: Bogus length %zu in firmware \"%s\"\n", 219462306a36Sopenharmony_ci rdev->sdma_fw->size, fw_name); 219562306a36Sopenharmony_ci err = -EINVAL; 219662306a36Sopenharmony_ci } 219762306a36Sopenharmony_ci } else { 219862306a36Sopenharmony_ci err = radeon_ucode_validate(rdev->sdma_fw); 219962306a36Sopenharmony_ci if (err) { 220062306a36Sopenharmony_ci pr_err("cik_fw: validation failed for firmware \"%s\"\n", 220162306a36Sopenharmony_ci fw_name); 220262306a36Sopenharmony_ci goto out; 220362306a36Sopenharmony_ci } else { 220462306a36Sopenharmony_ci new_fw++; 220562306a36Sopenharmony_ci } 220662306a36Sopenharmony_ci } 220762306a36Sopenharmony_ci 220862306a36Sopenharmony_ci /* No SMC, MC ucode on APUs */ 220962306a36Sopenharmony_ci if (!(rdev->flags & RADEON_IS_IGP)) { 221062306a36Sopenharmony_ci snprintf(fw_name, sizeof(fw_name), "radeon/%s_mc.bin", new_chip_name); 221162306a36Sopenharmony_ci err = request_firmware(&rdev->mc_fw, fw_name, rdev->dev); 221262306a36Sopenharmony_ci if (err) { 221362306a36Sopenharmony_ci snprintf(fw_name, sizeof(fw_name), "radeon/%s_mc2.bin", chip_name); 221462306a36Sopenharmony_ci err = request_firmware(&rdev->mc_fw, fw_name, rdev->dev); 221562306a36Sopenharmony_ci if (err) { 221662306a36Sopenharmony_ci snprintf(fw_name, sizeof(fw_name), "radeon/%s_mc.bin", chip_name); 221762306a36Sopenharmony_ci err = request_firmware(&rdev->mc_fw, fw_name, rdev->dev); 221862306a36Sopenharmony_ci if (err) 221962306a36Sopenharmony_ci goto out; 222062306a36Sopenharmony_ci } 222162306a36Sopenharmony_ci if ((rdev->mc_fw->size != mc_req_size) && 222262306a36Sopenharmony_ci (rdev->mc_fw->size != mc2_req_size)){ 222362306a36Sopenharmony_ci pr_err("cik_mc: Bogus length %zu in firmware \"%s\"\n", 222462306a36Sopenharmony_ci rdev->mc_fw->size, fw_name); 222562306a36Sopenharmony_ci err = -EINVAL; 222662306a36Sopenharmony_ci } 222762306a36Sopenharmony_ci DRM_INFO("%s: %zu bytes\n", fw_name, rdev->mc_fw->size); 222862306a36Sopenharmony_ci } else { 222962306a36Sopenharmony_ci err = radeon_ucode_validate(rdev->mc_fw); 223062306a36Sopenharmony_ci if (err) { 223162306a36Sopenharmony_ci pr_err("cik_fw: validation failed for firmware \"%s\"\n", 223262306a36Sopenharmony_ci fw_name); 223362306a36Sopenharmony_ci goto out; 223462306a36Sopenharmony_ci } else { 223562306a36Sopenharmony_ci new_fw++; 223662306a36Sopenharmony_ci } 223762306a36Sopenharmony_ci } 223862306a36Sopenharmony_ci 223962306a36Sopenharmony_ci if (new_smc) 224062306a36Sopenharmony_ci snprintf(fw_name, sizeof(fw_name), "radeon/%s_k_smc.bin", new_chip_name); 224162306a36Sopenharmony_ci else 224262306a36Sopenharmony_ci snprintf(fw_name, sizeof(fw_name), "radeon/%s_smc.bin", new_chip_name); 224362306a36Sopenharmony_ci err = request_firmware(&rdev->smc_fw, fw_name, rdev->dev); 224462306a36Sopenharmony_ci if (err) { 224562306a36Sopenharmony_ci snprintf(fw_name, sizeof(fw_name), "radeon/%s_smc.bin", chip_name); 224662306a36Sopenharmony_ci err = request_firmware(&rdev->smc_fw, fw_name, rdev->dev); 224762306a36Sopenharmony_ci if (err) { 224862306a36Sopenharmony_ci pr_err("smc: error loading firmware \"%s\"\n", 224962306a36Sopenharmony_ci fw_name); 225062306a36Sopenharmony_ci release_firmware(rdev->smc_fw); 225162306a36Sopenharmony_ci rdev->smc_fw = NULL; 225262306a36Sopenharmony_ci err = 0; 225362306a36Sopenharmony_ci } else if (rdev->smc_fw->size != smc_req_size) { 225462306a36Sopenharmony_ci pr_err("cik_smc: Bogus length %zu in firmware \"%s\"\n", 225562306a36Sopenharmony_ci rdev->smc_fw->size, fw_name); 225662306a36Sopenharmony_ci err = -EINVAL; 225762306a36Sopenharmony_ci } 225862306a36Sopenharmony_ci } else { 225962306a36Sopenharmony_ci err = radeon_ucode_validate(rdev->smc_fw); 226062306a36Sopenharmony_ci if (err) { 226162306a36Sopenharmony_ci pr_err("cik_fw: validation failed for firmware \"%s\"\n", 226262306a36Sopenharmony_ci fw_name); 226362306a36Sopenharmony_ci goto out; 226462306a36Sopenharmony_ci } else { 226562306a36Sopenharmony_ci new_fw++; 226662306a36Sopenharmony_ci } 226762306a36Sopenharmony_ci } 226862306a36Sopenharmony_ci } 226962306a36Sopenharmony_ci 227062306a36Sopenharmony_ci if (new_fw == 0) { 227162306a36Sopenharmony_ci rdev->new_fw = false; 227262306a36Sopenharmony_ci } else if (new_fw < num_fw) { 227362306a36Sopenharmony_ci pr_err("ci_fw: mixing new and old firmware!\n"); 227462306a36Sopenharmony_ci err = -EINVAL; 227562306a36Sopenharmony_ci } else { 227662306a36Sopenharmony_ci rdev->new_fw = true; 227762306a36Sopenharmony_ci } 227862306a36Sopenharmony_ci 227962306a36Sopenharmony_ciout: 228062306a36Sopenharmony_ci if (err) { 228162306a36Sopenharmony_ci if (err != -EINVAL) 228262306a36Sopenharmony_ci pr_err("cik_cp: Failed to load firmware \"%s\"\n", 228362306a36Sopenharmony_ci fw_name); 228462306a36Sopenharmony_ci release_firmware(rdev->pfp_fw); 228562306a36Sopenharmony_ci rdev->pfp_fw = NULL; 228662306a36Sopenharmony_ci release_firmware(rdev->me_fw); 228762306a36Sopenharmony_ci rdev->me_fw = NULL; 228862306a36Sopenharmony_ci release_firmware(rdev->ce_fw); 228962306a36Sopenharmony_ci rdev->ce_fw = NULL; 229062306a36Sopenharmony_ci release_firmware(rdev->mec_fw); 229162306a36Sopenharmony_ci rdev->mec_fw = NULL; 229262306a36Sopenharmony_ci release_firmware(rdev->mec2_fw); 229362306a36Sopenharmony_ci rdev->mec2_fw = NULL; 229462306a36Sopenharmony_ci release_firmware(rdev->rlc_fw); 229562306a36Sopenharmony_ci rdev->rlc_fw = NULL; 229662306a36Sopenharmony_ci release_firmware(rdev->sdma_fw); 229762306a36Sopenharmony_ci rdev->sdma_fw = NULL; 229862306a36Sopenharmony_ci release_firmware(rdev->mc_fw); 229962306a36Sopenharmony_ci rdev->mc_fw = NULL; 230062306a36Sopenharmony_ci release_firmware(rdev->smc_fw); 230162306a36Sopenharmony_ci rdev->smc_fw = NULL; 230262306a36Sopenharmony_ci } 230362306a36Sopenharmony_ci return err; 230462306a36Sopenharmony_ci} 230562306a36Sopenharmony_ci 230662306a36Sopenharmony_ci/* 230762306a36Sopenharmony_ci * Core functions 230862306a36Sopenharmony_ci */ 230962306a36Sopenharmony_ci/** 231062306a36Sopenharmony_ci * cik_tiling_mode_table_init - init the hw tiling table 231162306a36Sopenharmony_ci * 231262306a36Sopenharmony_ci * @rdev: radeon_device pointer 231362306a36Sopenharmony_ci * 231462306a36Sopenharmony_ci * Starting with SI, the tiling setup is done globally in a 231562306a36Sopenharmony_ci * set of 32 tiling modes. Rather than selecting each set of 231662306a36Sopenharmony_ci * parameters per surface as on older asics, we just select 231762306a36Sopenharmony_ci * which index in the tiling table we want to use, and the 231862306a36Sopenharmony_ci * surface uses those parameters (CIK). 231962306a36Sopenharmony_ci */ 232062306a36Sopenharmony_cistatic void cik_tiling_mode_table_init(struct radeon_device *rdev) 232162306a36Sopenharmony_ci{ 232262306a36Sopenharmony_ci u32 *tile = rdev->config.cik.tile_mode_array; 232362306a36Sopenharmony_ci u32 *macrotile = rdev->config.cik.macrotile_mode_array; 232462306a36Sopenharmony_ci const u32 num_tile_mode_states = 232562306a36Sopenharmony_ci ARRAY_SIZE(rdev->config.cik.tile_mode_array); 232662306a36Sopenharmony_ci const u32 num_secondary_tile_mode_states = 232762306a36Sopenharmony_ci ARRAY_SIZE(rdev->config.cik.macrotile_mode_array); 232862306a36Sopenharmony_ci u32 reg_offset, split_equal_to_row_size; 232962306a36Sopenharmony_ci u32 num_pipe_configs; 233062306a36Sopenharmony_ci u32 num_rbs = rdev->config.cik.max_backends_per_se * 233162306a36Sopenharmony_ci rdev->config.cik.max_shader_engines; 233262306a36Sopenharmony_ci 233362306a36Sopenharmony_ci switch (rdev->config.cik.mem_row_size_in_kb) { 233462306a36Sopenharmony_ci case 1: 233562306a36Sopenharmony_ci split_equal_to_row_size = ADDR_SURF_TILE_SPLIT_1KB; 233662306a36Sopenharmony_ci break; 233762306a36Sopenharmony_ci case 2: 233862306a36Sopenharmony_ci default: 233962306a36Sopenharmony_ci split_equal_to_row_size = ADDR_SURF_TILE_SPLIT_2KB; 234062306a36Sopenharmony_ci break; 234162306a36Sopenharmony_ci case 4: 234262306a36Sopenharmony_ci split_equal_to_row_size = ADDR_SURF_TILE_SPLIT_4KB; 234362306a36Sopenharmony_ci break; 234462306a36Sopenharmony_ci } 234562306a36Sopenharmony_ci 234662306a36Sopenharmony_ci num_pipe_configs = rdev->config.cik.max_tile_pipes; 234762306a36Sopenharmony_ci if (num_pipe_configs > 8) 234862306a36Sopenharmony_ci num_pipe_configs = 16; 234962306a36Sopenharmony_ci 235062306a36Sopenharmony_ci for (reg_offset = 0; reg_offset < num_tile_mode_states; reg_offset++) 235162306a36Sopenharmony_ci tile[reg_offset] = 0; 235262306a36Sopenharmony_ci for (reg_offset = 0; reg_offset < num_secondary_tile_mode_states; reg_offset++) 235362306a36Sopenharmony_ci macrotile[reg_offset] = 0; 235462306a36Sopenharmony_ci 235562306a36Sopenharmony_ci switch(num_pipe_configs) { 235662306a36Sopenharmony_ci case 16: 235762306a36Sopenharmony_ci tile[0] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | 235862306a36Sopenharmony_ci MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING) | 235962306a36Sopenharmony_ci PIPE_CONFIG(ADDR_SURF_P16_32x32_16x16) | 236062306a36Sopenharmony_ci TILE_SPLIT(ADDR_SURF_TILE_SPLIT_64B)); 236162306a36Sopenharmony_ci tile[1] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | 236262306a36Sopenharmony_ci MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING) | 236362306a36Sopenharmony_ci PIPE_CONFIG(ADDR_SURF_P16_32x32_16x16) | 236462306a36Sopenharmony_ci TILE_SPLIT(ADDR_SURF_TILE_SPLIT_128B)); 236562306a36Sopenharmony_ci tile[2] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | 236662306a36Sopenharmony_ci MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING) | 236762306a36Sopenharmony_ci PIPE_CONFIG(ADDR_SURF_P16_32x32_16x16) | 236862306a36Sopenharmony_ci TILE_SPLIT(ADDR_SURF_TILE_SPLIT_256B)); 236962306a36Sopenharmony_ci tile[3] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | 237062306a36Sopenharmony_ci MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING) | 237162306a36Sopenharmony_ci PIPE_CONFIG(ADDR_SURF_P16_32x32_16x16) | 237262306a36Sopenharmony_ci TILE_SPLIT(ADDR_SURF_TILE_SPLIT_512B)); 237362306a36Sopenharmony_ci tile[4] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | 237462306a36Sopenharmony_ci MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING) | 237562306a36Sopenharmony_ci PIPE_CONFIG(ADDR_SURF_P16_32x32_16x16) | 237662306a36Sopenharmony_ci TILE_SPLIT(split_equal_to_row_size)); 237762306a36Sopenharmony_ci tile[5] = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) | 237862306a36Sopenharmony_ci PIPE_CONFIG(ADDR_SURF_P16_32x32_16x16) | 237962306a36Sopenharmony_ci MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING)); 238062306a36Sopenharmony_ci tile[6] = (ARRAY_MODE(ARRAY_PRT_2D_TILED_THIN1) | 238162306a36Sopenharmony_ci MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING) | 238262306a36Sopenharmony_ci PIPE_CONFIG(ADDR_SURF_P16_32x32_16x16) | 238362306a36Sopenharmony_ci TILE_SPLIT(ADDR_SURF_TILE_SPLIT_256B)); 238462306a36Sopenharmony_ci tile[7] = (ARRAY_MODE(ARRAY_PRT_2D_TILED_THIN1) | 238562306a36Sopenharmony_ci MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING) | 238662306a36Sopenharmony_ci PIPE_CONFIG(ADDR_SURF_P16_32x32_16x16) | 238762306a36Sopenharmony_ci TILE_SPLIT(split_equal_to_row_size)); 238862306a36Sopenharmony_ci tile[8] = (ARRAY_MODE(ARRAY_LINEAR_ALIGNED) | 238962306a36Sopenharmony_ci PIPE_CONFIG(ADDR_SURF_P16_32x32_16x16)); 239062306a36Sopenharmony_ci tile[9] = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) | 239162306a36Sopenharmony_ci PIPE_CONFIG(ADDR_SURF_P16_32x32_16x16) | 239262306a36Sopenharmony_ci MICRO_TILE_MODE_NEW(ADDR_SURF_DISPLAY_MICRO_TILING)); 239362306a36Sopenharmony_ci tile[10] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | 239462306a36Sopenharmony_ci MICRO_TILE_MODE_NEW(ADDR_SURF_DISPLAY_MICRO_TILING) | 239562306a36Sopenharmony_ci PIPE_CONFIG(ADDR_SURF_P16_32x32_16x16) | 239662306a36Sopenharmony_ci SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2)); 239762306a36Sopenharmony_ci tile[11] = (ARRAY_MODE(ARRAY_PRT_TILED_THIN1) | 239862306a36Sopenharmony_ci MICRO_TILE_MODE_NEW(ADDR_SURF_DISPLAY_MICRO_TILING) | 239962306a36Sopenharmony_ci PIPE_CONFIG(ADDR_SURF_P16_32x32_8x16) | 240062306a36Sopenharmony_ci SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2)); 240162306a36Sopenharmony_ci tile[12] = (ARRAY_MODE(ARRAY_PRT_2D_TILED_THIN1) | 240262306a36Sopenharmony_ci MICRO_TILE_MODE_NEW(ADDR_SURF_DISPLAY_MICRO_TILING) | 240362306a36Sopenharmony_ci PIPE_CONFIG(ADDR_SURF_P16_32x32_16x16) | 240462306a36Sopenharmony_ci SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2)); 240562306a36Sopenharmony_ci tile[13] = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) | 240662306a36Sopenharmony_ci PIPE_CONFIG(ADDR_SURF_P16_32x32_16x16) | 240762306a36Sopenharmony_ci MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING)); 240862306a36Sopenharmony_ci tile[14] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | 240962306a36Sopenharmony_ci MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING) | 241062306a36Sopenharmony_ci PIPE_CONFIG(ADDR_SURF_P16_32x32_16x16) | 241162306a36Sopenharmony_ci SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2)); 241262306a36Sopenharmony_ci tile[16] = (ARRAY_MODE(ARRAY_PRT_TILED_THIN1) | 241362306a36Sopenharmony_ci MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING) | 241462306a36Sopenharmony_ci PIPE_CONFIG(ADDR_SURF_P16_32x32_8x16) | 241562306a36Sopenharmony_ci SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2)); 241662306a36Sopenharmony_ci tile[17] = (ARRAY_MODE(ARRAY_PRT_2D_TILED_THIN1) | 241762306a36Sopenharmony_ci MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING) | 241862306a36Sopenharmony_ci PIPE_CONFIG(ADDR_SURF_P16_32x32_16x16) | 241962306a36Sopenharmony_ci SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2)); 242062306a36Sopenharmony_ci tile[27] = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) | 242162306a36Sopenharmony_ci PIPE_CONFIG(ADDR_SURF_P16_32x32_16x16) | 242262306a36Sopenharmony_ci MICRO_TILE_MODE_NEW(ADDR_SURF_ROTATED_MICRO_TILING)); 242362306a36Sopenharmony_ci tile[28] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | 242462306a36Sopenharmony_ci MICRO_TILE_MODE_NEW(ADDR_SURF_ROTATED_MICRO_TILING) | 242562306a36Sopenharmony_ci PIPE_CONFIG(ADDR_SURF_P16_32x32_16x16) | 242662306a36Sopenharmony_ci SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2)); 242762306a36Sopenharmony_ci tile[29] = (ARRAY_MODE(ARRAY_PRT_TILED_THIN1) | 242862306a36Sopenharmony_ci MICRO_TILE_MODE_NEW(ADDR_SURF_ROTATED_MICRO_TILING) | 242962306a36Sopenharmony_ci PIPE_CONFIG(ADDR_SURF_P16_32x32_8x16) | 243062306a36Sopenharmony_ci SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2)); 243162306a36Sopenharmony_ci tile[30] = (ARRAY_MODE(ARRAY_PRT_2D_TILED_THIN1) | 243262306a36Sopenharmony_ci MICRO_TILE_MODE_NEW(ADDR_SURF_ROTATED_MICRO_TILING) | 243362306a36Sopenharmony_ci PIPE_CONFIG(ADDR_SURF_P16_32x32_16x16) | 243462306a36Sopenharmony_ci SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2)); 243562306a36Sopenharmony_ci 243662306a36Sopenharmony_ci macrotile[0] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | 243762306a36Sopenharmony_ci BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) | 243862306a36Sopenharmony_ci MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2) | 243962306a36Sopenharmony_ci NUM_BANKS(ADDR_SURF_16_BANK)); 244062306a36Sopenharmony_ci macrotile[1] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | 244162306a36Sopenharmony_ci BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) | 244262306a36Sopenharmony_ci MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2) | 244362306a36Sopenharmony_ci NUM_BANKS(ADDR_SURF_16_BANK)); 244462306a36Sopenharmony_ci macrotile[2] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | 244562306a36Sopenharmony_ci BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) | 244662306a36Sopenharmony_ci MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1) | 244762306a36Sopenharmony_ci NUM_BANKS(ADDR_SURF_16_BANK)); 244862306a36Sopenharmony_ci macrotile[3] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | 244962306a36Sopenharmony_ci BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) | 245062306a36Sopenharmony_ci MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1) | 245162306a36Sopenharmony_ci NUM_BANKS(ADDR_SURF_16_BANK)); 245262306a36Sopenharmony_ci macrotile[4] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | 245362306a36Sopenharmony_ci BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) | 245462306a36Sopenharmony_ci MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1) | 245562306a36Sopenharmony_ci NUM_BANKS(ADDR_SURF_8_BANK)); 245662306a36Sopenharmony_ci macrotile[5] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | 245762306a36Sopenharmony_ci BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) | 245862306a36Sopenharmony_ci MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1) | 245962306a36Sopenharmony_ci NUM_BANKS(ADDR_SURF_4_BANK)); 246062306a36Sopenharmony_ci macrotile[6] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | 246162306a36Sopenharmony_ci BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) | 246262306a36Sopenharmony_ci MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1) | 246362306a36Sopenharmony_ci NUM_BANKS(ADDR_SURF_2_BANK)); 246462306a36Sopenharmony_ci macrotile[8] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | 246562306a36Sopenharmony_ci BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) | 246662306a36Sopenharmony_ci MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2) | 246762306a36Sopenharmony_ci NUM_BANKS(ADDR_SURF_16_BANK)); 246862306a36Sopenharmony_ci macrotile[9] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | 246962306a36Sopenharmony_ci BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) | 247062306a36Sopenharmony_ci MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2) | 247162306a36Sopenharmony_ci NUM_BANKS(ADDR_SURF_16_BANK)); 247262306a36Sopenharmony_ci macrotile[10] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | 247362306a36Sopenharmony_ci BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) | 247462306a36Sopenharmony_ci MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1) | 247562306a36Sopenharmony_ci NUM_BANKS(ADDR_SURF_16_BANK)); 247662306a36Sopenharmony_ci macrotile[11] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | 247762306a36Sopenharmony_ci BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) | 247862306a36Sopenharmony_ci MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1) | 247962306a36Sopenharmony_ci NUM_BANKS(ADDR_SURF_8_BANK)); 248062306a36Sopenharmony_ci macrotile[12] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | 248162306a36Sopenharmony_ci BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) | 248262306a36Sopenharmony_ci MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1) | 248362306a36Sopenharmony_ci NUM_BANKS(ADDR_SURF_4_BANK)); 248462306a36Sopenharmony_ci macrotile[13] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | 248562306a36Sopenharmony_ci BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) | 248662306a36Sopenharmony_ci MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1) | 248762306a36Sopenharmony_ci NUM_BANKS(ADDR_SURF_2_BANK)); 248862306a36Sopenharmony_ci macrotile[14] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | 248962306a36Sopenharmony_ci BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) | 249062306a36Sopenharmony_ci MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1) | 249162306a36Sopenharmony_ci NUM_BANKS(ADDR_SURF_2_BANK)); 249262306a36Sopenharmony_ci 249362306a36Sopenharmony_ci for (reg_offset = 0; reg_offset < num_tile_mode_states; reg_offset++) 249462306a36Sopenharmony_ci WREG32(GB_TILE_MODE0 + (reg_offset * 4), tile[reg_offset]); 249562306a36Sopenharmony_ci for (reg_offset = 0; reg_offset < num_secondary_tile_mode_states; reg_offset++) 249662306a36Sopenharmony_ci WREG32(GB_MACROTILE_MODE0 + (reg_offset * 4), macrotile[reg_offset]); 249762306a36Sopenharmony_ci break; 249862306a36Sopenharmony_ci 249962306a36Sopenharmony_ci case 8: 250062306a36Sopenharmony_ci tile[0] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | 250162306a36Sopenharmony_ci MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING) | 250262306a36Sopenharmony_ci PIPE_CONFIG(ADDR_SURF_P8_32x32_16x16) | 250362306a36Sopenharmony_ci TILE_SPLIT(ADDR_SURF_TILE_SPLIT_64B)); 250462306a36Sopenharmony_ci tile[1] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | 250562306a36Sopenharmony_ci MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING) | 250662306a36Sopenharmony_ci PIPE_CONFIG(ADDR_SURF_P8_32x32_16x16) | 250762306a36Sopenharmony_ci TILE_SPLIT(ADDR_SURF_TILE_SPLIT_128B)); 250862306a36Sopenharmony_ci tile[2] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | 250962306a36Sopenharmony_ci MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING) | 251062306a36Sopenharmony_ci PIPE_CONFIG(ADDR_SURF_P8_32x32_16x16) | 251162306a36Sopenharmony_ci TILE_SPLIT(ADDR_SURF_TILE_SPLIT_256B)); 251262306a36Sopenharmony_ci tile[3] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | 251362306a36Sopenharmony_ci MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING) | 251462306a36Sopenharmony_ci PIPE_CONFIG(ADDR_SURF_P8_32x32_16x16) | 251562306a36Sopenharmony_ci TILE_SPLIT(ADDR_SURF_TILE_SPLIT_512B)); 251662306a36Sopenharmony_ci tile[4] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | 251762306a36Sopenharmony_ci MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING) | 251862306a36Sopenharmony_ci PIPE_CONFIG(ADDR_SURF_P8_32x32_16x16) | 251962306a36Sopenharmony_ci TILE_SPLIT(split_equal_to_row_size)); 252062306a36Sopenharmony_ci tile[5] = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) | 252162306a36Sopenharmony_ci PIPE_CONFIG(ADDR_SURF_P8_32x32_16x16) | 252262306a36Sopenharmony_ci MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING)); 252362306a36Sopenharmony_ci tile[6] = (ARRAY_MODE(ARRAY_PRT_2D_TILED_THIN1) | 252462306a36Sopenharmony_ci MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING) | 252562306a36Sopenharmony_ci PIPE_CONFIG(ADDR_SURF_P8_32x32_16x16) | 252662306a36Sopenharmony_ci TILE_SPLIT(ADDR_SURF_TILE_SPLIT_256B)); 252762306a36Sopenharmony_ci tile[7] = (ARRAY_MODE(ARRAY_PRT_2D_TILED_THIN1) | 252862306a36Sopenharmony_ci MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING) | 252962306a36Sopenharmony_ci PIPE_CONFIG(ADDR_SURF_P8_32x32_16x16) | 253062306a36Sopenharmony_ci TILE_SPLIT(split_equal_to_row_size)); 253162306a36Sopenharmony_ci tile[8] = (ARRAY_MODE(ARRAY_LINEAR_ALIGNED) | 253262306a36Sopenharmony_ci PIPE_CONFIG(ADDR_SURF_P8_32x32_16x16)); 253362306a36Sopenharmony_ci tile[9] = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) | 253462306a36Sopenharmony_ci PIPE_CONFIG(ADDR_SURF_P8_32x32_16x16) | 253562306a36Sopenharmony_ci MICRO_TILE_MODE_NEW(ADDR_SURF_DISPLAY_MICRO_TILING)); 253662306a36Sopenharmony_ci tile[10] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | 253762306a36Sopenharmony_ci MICRO_TILE_MODE_NEW(ADDR_SURF_DISPLAY_MICRO_TILING) | 253862306a36Sopenharmony_ci PIPE_CONFIG(ADDR_SURF_P8_32x32_16x16) | 253962306a36Sopenharmony_ci SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2)); 254062306a36Sopenharmony_ci tile[11] = (ARRAY_MODE(ARRAY_PRT_TILED_THIN1) | 254162306a36Sopenharmony_ci MICRO_TILE_MODE_NEW(ADDR_SURF_DISPLAY_MICRO_TILING) | 254262306a36Sopenharmony_ci PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) | 254362306a36Sopenharmony_ci SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2)); 254462306a36Sopenharmony_ci tile[12] = (ARRAY_MODE(ARRAY_PRT_2D_TILED_THIN1) | 254562306a36Sopenharmony_ci MICRO_TILE_MODE_NEW(ADDR_SURF_DISPLAY_MICRO_TILING) | 254662306a36Sopenharmony_ci PIPE_CONFIG(ADDR_SURF_P8_32x32_16x16) | 254762306a36Sopenharmony_ci SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2)); 254862306a36Sopenharmony_ci tile[13] = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) | 254962306a36Sopenharmony_ci PIPE_CONFIG(ADDR_SURF_P8_32x32_16x16) | 255062306a36Sopenharmony_ci MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING)); 255162306a36Sopenharmony_ci tile[14] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | 255262306a36Sopenharmony_ci MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING) | 255362306a36Sopenharmony_ci PIPE_CONFIG(ADDR_SURF_P8_32x32_16x16) | 255462306a36Sopenharmony_ci SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2)); 255562306a36Sopenharmony_ci tile[16] = (ARRAY_MODE(ARRAY_PRT_TILED_THIN1) | 255662306a36Sopenharmony_ci MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING) | 255762306a36Sopenharmony_ci PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) | 255862306a36Sopenharmony_ci SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2)); 255962306a36Sopenharmony_ci tile[17] = (ARRAY_MODE(ARRAY_PRT_2D_TILED_THIN1) | 256062306a36Sopenharmony_ci MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING) | 256162306a36Sopenharmony_ci PIPE_CONFIG(ADDR_SURF_P8_32x32_16x16) | 256262306a36Sopenharmony_ci SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2)); 256362306a36Sopenharmony_ci tile[27] = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) | 256462306a36Sopenharmony_ci PIPE_CONFIG(ADDR_SURF_P8_32x32_16x16) | 256562306a36Sopenharmony_ci MICRO_TILE_MODE_NEW(ADDR_SURF_ROTATED_MICRO_TILING)); 256662306a36Sopenharmony_ci tile[28] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | 256762306a36Sopenharmony_ci MICRO_TILE_MODE_NEW(ADDR_SURF_ROTATED_MICRO_TILING) | 256862306a36Sopenharmony_ci PIPE_CONFIG(ADDR_SURF_P8_32x32_16x16) | 256962306a36Sopenharmony_ci SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2)); 257062306a36Sopenharmony_ci tile[29] = (ARRAY_MODE(ARRAY_PRT_TILED_THIN1) | 257162306a36Sopenharmony_ci MICRO_TILE_MODE_NEW(ADDR_SURF_ROTATED_MICRO_TILING) | 257262306a36Sopenharmony_ci PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) | 257362306a36Sopenharmony_ci SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2)); 257462306a36Sopenharmony_ci tile[30] = (ARRAY_MODE(ARRAY_PRT_2D_TILED_THIN1) | 257562306a36Sopenharmony_ci MICRO_TILE_MODE_NEW(ADDR_SURF_ROTATED_MICRO_TILING) | 257662306a36Sopenharmony_ci PIPE_CONFIG(ADDR_SURF_P8_32x32_16x16) | 257762306a36Sopenharmony_ci SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2)); 257862306a36Sopenharmony_ci 257962306a36Sopenharmony_ci macrotile[0] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | 258062306a36Sopenharmony_ci BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) | 258162306a36Sopenharmony_ci MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4) | 258262306a36Sopenharmony_ci NUM_BANKS(ADDR_SURF_16_BANK)); 258362306a36Sopenharmony_ci macrotile[1] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | 258462306a36Sopenharmony_ci BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) | 258562306a36Sopenharmony_ci MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2) | 258662306a36Sopenharmony_ci NUM_BANKS(ADDR_SURF_16_BANK)); 258762306a36Sopenharmony_ci macrotile[2] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | 258862306a36Sopenharmony_ci BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) | 258962306a36Sopenharmony_ci MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2) | 259062306a36Sopenharmony_ci NUM_BANKS(ADDR_SURF_16_BANK)); 259162306a36Sopenharmony_ci macrotile[3] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | 259262306a36Sopenharmony_ci BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) | 259362306a36Sopenharmony_ci MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2) | 259462306a36Sopenharmony_ci NUM_BANKS(ADDR_SURF_16_BANK)); 259562306a36Sopenharmony_ci macrotile[4] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | 259662306a36Sopenharmony_ci BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) | 259762306a36Sopenharmony_ci MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1) | 259862306a36Sopenharmony_ci NUM_BANKS(ADDR_SURF_8_BANK)); 259962306a36Sopenharmony_ci macrotile[5] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | 260062306a36Sopenharmony_ci BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) | 260162306a36Sopenharmony_ci MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1) | 260262306a36Sopenharmony_ci NUM_BANKS(ADDR_SURF_4_BANK)); 260362306a36Sopenharmony_ci macrotile[6] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | 260462306a36Sopenharmony_ci BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) | 260562306a36Sopenharmony_ci MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1) | 260662306a36Sopenharmony_ci NUM_BANKS(ADDR_SURF_2_BANK)); 260762306a36Sopenharmony_ci macrotile[8] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | 260862306a36Sopenharmony_ci BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_8) | 260962306a36Sopenharmony_ci MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4) | 261062306a36Sopenharmony_ci NUM_BANKS(ADDR_SURF_16_BANK)); 261162306a36Sopenharmony_ci macrotile[9] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | 261262306a36Sopenharmony_ci BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) | 261362306a36Sopenharmony_ci MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4) | 261462306a36Sopenharmony_ci NUM_BANKS(ADDR_SURF_16_BANK)); 261562306a36Sopenharmony_ci macrotile[10] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | 261662306a36Sopenharmony_ci BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) | 261762306a36Sopenharmony_ci MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2) | 261862306a36Sopenharmony_ci NUM_BANKS(ADDR_SURF_16_BANK)); 261962306a36Sopenharmony_ci macrotile[11] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | 262062306a36Sopenharmony_ci BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) | 262162306a36Sopenharmony_ci MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2) | 262262306a36Sopenharmony_ci NUM_BANKS(ADDR_SURF_16_BANK)); 262362306a36Sopenharmony_ci macrotile[12] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | 262462306a36Sopenharmony_ci BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) | 262562306a36Sopenharmony_ci MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1) | 262662306a36Sopenharmony_ci NUM_BANKS(ADDR_SURF_8_BANK)); 262762306a36Sopenharmony_ci macrotile[13] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | 262862306a36Sopenharmony_ci BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) | 262962306a36Sopenharmony_ci MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1) | 263062306a36Sopenharmony_ci NUM_BANKS(ADDR_SURF_4_BANK)); 263162306a36Sopenharmony_ci macrotile[14] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | 263262306a36Sopenharmony_ci BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) | 263362306a36Sopenharmony_ci MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1) | 263462306a36Sopenharmony_ci NUM_BANKS(ADDR_SURF_2_BANK)); 263562306a36Sopenharmony_ci 263662306a36Sopenharmony_ci for (reg_offset = 0; reg_offset < num_tile_mode_states; reg_offset++) 263762306a36Sopenharmony_ci WREG32(GB_TILE_MODE0 + (reg_offset * 4), tile[reg_offset]); 263862306a36Sopenharmony_ci for (reg_offset = 0; reg_offset < num_secondary_tile_mode_states; reg_offset++) 263962306a36Sopenharmony_ci WREG32(GB_MACROTILE_MODE0 + (reg_offset * 4), macrotile[reg_offset]); 264062306a36Sopenharmony_ci break; 264162306a36Sopenharmony_ci 264262306a36Sopenharmony_ci case 4: 264362306a36Sopenharmony_ci if (num_rbs == 4) { 264462306a36Sopenharmony_ci tile[0] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | 264562306a36Sopenharmony_ci MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING) | 264662306a36Sopenharmony_ci PIPE_CONFIG(ADDR_SURF_P4_16x16) | 264762306a36Sopenharmony_ci TILE_SPLIT(ADDR_SURF_TILE_SPLIT_64B)); 264862306a36Sopenharmony_ci tile[1] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | 264962306a36Sopenharmony_ci MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING) | 265062306a36Sopenharmony_ci PIPE_CONFIG(ADDR_SURF_P4_16x16) | 265162306a36Sopenharmony_ci TILE_SPLIT(ADDR_SURF_TILE_SPLIT_128B)); 265262306a36Sopenharmony_ci tile[2] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | 265362306a36Sopenharmony_ci MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING) | 265462306a36Sopenharmony_ci PIPE_CONFIG(ADDR_SURF_P4_16x16) | 265562306a36Sopenharmony_ci TILE_SPLIT(ADDR_SURF_TILE_SPLIT_256B)); 265662306a36Sopenharmony_ci tile[3] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | 265762306a36Sopenharmony_ci MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING) | 265862306a36Sopenharmony_ci PIPE_CONFIG(ADDR_SURF_P4_16x16) | 265962306a36Sopenharmony_ci TILE_SPLIT(ADDR_SURF_TILE_SPLIT_512B)); 266062306a36Sopenharmony_ci tile[4] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | 266162306a36Sopenharmony_ci MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING) | 266262306a36Sopenharmony_ci PIPE_CONFIG(ADDR_SURF_P4_16x16) | 266362306a36Sopenharmony_ci TILE_SPLIT(split_equal_to_row_size)); 266462306a36Sopenharmony_ci tile[5] = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) | 266562306a36Sopenharmony_ci PIPE_CONFIG(ADDR_SURF_P4_16x16) | 266662306a36Sopenharmony_ci MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING)); 266762306a36Sopenharmony_ci tile[6] = (ARRAY_MODE(ARRAY_PRT_2D_TILED_THIN1) | 266862306a36Sopenharmony_ci MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING) | 266962306a36Sopenharmony_ci PIPE_CONFIG(ADDR_SURF_P4_16x16) | 267062306a36Sopenharmony_ci TILE_SPLIT(ADDR_SURF_TILE_SPLIT_256B)); 267162306a36Sopenharmony_ci tile[7] = (ARRAY_MODE(ARRAY_PRT_2D_TILED_THIN1) | 267262306a36Sopenharmony_ci MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING) | 267362306a36Sopenharmony_ci PIPE_CONFIG(ADDR_SURF_P4_16x16) | 267462306a36Sopenharmony_ci TILE_SPLIT(split_equal_to_row_size)); 267562306a36Sopenharmony_ci tile[8] = (ARRAY_MODE(ARRAY_LINEAR_ALIGNED) | 267662306a36Sopenharmony_ci PIPE_CONFIG(ADDR_SURF_P4_16x16)); 267762306a36Sopenharmony_ci tile[9] = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) | 267862306a36Sopenharmony_ci PIPE_CONFIG(ADDR_SURF_P4_16x16) | 267962306a36Sopenharmony_ci MICRO_TILE_MODE_NEW(ADDR_SURF_DISPLAY_MICRO_TILING)); 268062306a36Sopenharmony_ci tile[10] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | 268162306a36Sopenharmony_ci MICRO_TILE_MODE_NEW(ADDR_SURF_DISPLAY_MICRO_TILING) | 268262306a36Sopenharmony_ci PIPE_CONFIG(ADDR_SURF_P4_16x16) | 268362306a36Sopenharmony_ci SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2)); 268462306a36Sopenharmony_ci tile[11] = (ARRAY_MODE(ARRAY_PRT_TILED_THIN1) | 268562306a36Sopenharmony_ci MICRO_TILE_MODE_NEW(ADDR_SURF_DISPLAY_MICRO_TILING) | 268662306a36Sopenharmony_ci PIPE_CONFIG(ADDR_SURF_P4_8x16) | 268762306a36Sopenharmony_ci SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2)); 268862306a36Sopenharmony_ci tile[12] = (ARRAY_MODE(ARRAY_PRT_2D_TILED_THIN1) | 268962306a36Sopenharmony_ci MICRO_TILE_MODE_NEW(ADDR_SURF_DISPLAY_MICRO_TILING) | 269062306a36Sopenharmony_ci PIPE_CONFIG(ADDR_SURF_P4_16x16) | 269162306a36Sopenharmony_ci SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2)); 269262306a36Sopenharmony_ci tile[13] = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) | 269362306a36Sopenharmony_ci PIPE_CONFIG(ADDR_SURF_P4_16x16) | 269462306a36Sopenharmony_ci MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING)); 269562306a36Sopenharmony_ci tile[14] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | 269662306a36Sopenharmony_ci MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING) | 269762306a36Sopenharmony_ci PIPE_CONFIG(ADDR_SURF_P4_16x16) | 269862306a36Sopenharmony_ci SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2)); 269962306a36Sopenharmony_ci tile[16] = (ARRAY_MODE(ARRAY_PRT_TILED_THIN1) | 270062306a36Sopenharmony_ci MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING) | 270162306a36Sopenharmony_ci PIPE_CONFIG(ADDR_SURF_P4_8x16) | 270262306a36Sopenharmony_ci SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2)); 270362306a36Sopenharmony_ci tile[17] = (ARRAY_MODE(ARRAY_PRT_2D_TILED_THIN1) | 270462306a36Sopenharmony_ci MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING) | 270562306a36Sopenharmony_ci PIPE_CONFIG(ADDR_SURF_P4_16x16) | 270662306a36Sopenharmony_ci SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2)); 270762306a36Sopenharmony_ci tile[27] = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) | 270862306a36Sopenharmony_ci PIPE_CONFIG(ADDR_SURF_P4_16x16) | 270962306a36Sopenharmony_ci MICRO_TILE_MODE_NEW(ADDR_SURF_ROTATED_MICRO_TILING)); 271062306a36Sopenharmony_ci tile[28] = (ARRAY_MODE(ARRAY_PRT_2D_TILED_THIN1) | 271162306a36Sopenharmony_ci MICRO_TILE_MODE_NEW(ADDR_SURF_ROTATED_MICRO_TILING) | 271262306a36Sopenharmony_ci PIPE_CONFIG(ADDR_SURF_P4_16x16) | 271362306a36Sopenharmony_ci SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2)); 271462306a36Sopenharmony_ci tile[29] = (ARRAY_MODE(ARRAY_PRT_TILED_THIN1) | 271562306a36Sopenharmony_ci MICRO_TILE_MODE_NEW(ADDR_SURF_ROTATED_MICRO_TILING) | 271662306a36Sopenharmony_ci PIPE_CONFIG(ADDR_SURF_P4_8x16) | 271762306a36Sopenharmony_ci SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2)); 271862306a36Sopenharmony_ci tile[30] = (ARRAY_MODE(ARRAY_PRT_2D_TILED_THIN1) | 271962306a36Sopenharmony_ci MICRO_TILE_MODE_NEW(ADDR_SURF_ROTATED_MICRO_TILING) | 272062306a36Sopenharmony_ci PIPE_CONFIG(ADDR_SURF_P4_16x16) | 272162306a36Sopenharmony_ci SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2)); 272262306a36Sopenharmony_ci 272362306a36Sopenharmony_ci } else if (num_rbs < 4) { 272462306a36Sopenharmony_ci tile[0] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | 272562306a36Sopenharmony_ci MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING) | 272662306a36Sopenharmony_ci PIPE_CONFIG(ADDR_SURF_P4_8x16) | 272762306a36Sopenharmony_ci TILE_SPLIT(ADDR_SURF_TILE_SPLIT_64B)); 272862306a36Sopenharmony_ci tile[1] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | 272962306a36Sopenharmony_ci MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING) | 273062306a36Sopenharmony_ci PIPE_CONFIG(ADDR_SURF_P4_8x16) | 273162306a36Sopenharmony_ci TILE_SPLIT(ADDR_SURF_TILE_SPLIT_128B)); 273262306a36Sopenharmony_ci tile[2] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | 273362306a36Sopenharmony_ci MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING) | 273462306a36Sopenharmony_ci PIPE_CONFIG(ADDR_SURF_P4_8x16) | 273562306a36Sopenharmony_ci TILE_SPLIT(ADDR_SURF_TILE_SPLIT_256B)); 273662306a36Sopenharmony_ci tile[3] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | 273762306a36Sopenharmony_ci MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING) | 273862306a36Sopenharmony_ci PIPE_CONFIG(ADDR_SURF_P4_8x16) | 273962306a36Sopenharmony_ci TILE_SPLIT(ADDR_SURF_TILE_SPLIT_512B)); 274062306a36Sopenharmony_ci tile[4] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | 274162306a36Sopenharmony_ci MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING) | 274262306a36Sopenharmony_ci PIPE_CONFIG(ADDR_SURF_P4_8x16) | 274362306a36Sopenharmony_ci TILE_SPLIT(split_equal_to_row_size)); 274462306a36Sopenharmony_ci tile[5] = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) | 274562306a36Sopenharmony_ci PIPE_CONFIG(ADDR_SURF_P4_8x16) | 274662306a36Sopenharmony_ci MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING)); 274762306a36Sopenharmony_ci tile[6] = (ARRAY_MODE(ARRAY_PRT_2D_TILED_THIN1) | 274862306a36Sopenharmony_ci MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING) | 274962306a36Sopenharmony_ci PIPE_CONFIG(ADDR_SURF_P4_8x16) | 275062306a36Sopenharmony_ci TILE_SPLIT(ADDR_SURF_TILE_SPLIT_256B)); 275162306a36Sopenharmony_ci tile[7] = (ARRAY_MODE(ARRAY_PRT_2D_TILED_THIN1) | 275262306a36Sopenharmony_ci MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING) | 275362306a36Sopenharmony_ci PIPE_CONFIG(ADDR_SURF_P4_8x16) | 275462306a36Sopenharmony_ci TILE_SPLIT(split_equal_to_row_size)); 275562306a36Sopenharmony_ci tile[8] = (ARRAY_MODE(ARRAY_LINEAR_ALIGNED) | 275662306a36Sopenharmony_ci PIPE_CONFIG(ADDR_SURF_P4_8x16)); 275762306a36Sopenharmony_ci tile[9] = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) | 275862306a36Sopenharmony_ci PIPE_CONFIG(ADDR_SURF_P4_8x16) | 275962306a36Sopenharmony_ci MICRO_TILE_MODE_NEW(ADDR_SURF_DISPLAY_MICRO_TILING)); 276062306a36Sopenharmony_ci tile[10] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | 276162306a36Sopenharmony_ci MICRO_TILE_MODE_NEW(ADDR_SURF_DISPLAY_MICRO_TILING) | 276262306a36Sopenharmony_ci PIPE_CONFIG(ADDR_SURF_P4_8x16) | 276362306a36Sopenharmony_ci SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2)); 276462306a36Sopenharmony_ci tile[11] = (ARRAY_MODE(ARRAY_PRT_TILED_THIN1) | 276562306a36Sopenharmony_ci MICRO_TILE_MODE_NEW(ADDR_SURF_DISPLAY_MICRO_TILING) | 276662306a36Sopenharmony_ci PIPE_CONFIG(ADDR_SURF_P4_8x16) | 276762306a36Sopenharmony_ci SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2)); 276862306a36Sopenharmony_ci tile[12] = (ARRAY_MODE(ARRAY_PRT_2D_TILED_THIN1) | 276962306a36Sopenharmony_ci MICRO_TILE_MODE_NEW(ADDR_SURF_DISPLAY_MICRO_TILING) | 277062306a36Sopenharmony_ci PIPE_CONFIG(ADDR_SURF_P4_8x16) | 277162306a36Sopenharmony_ci SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2)); 277262306a36Sopenharmony_ci tile[13] = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) | 277362306a36Sopenharmony_ci PIPE_CONFIG(ADDR_SURF_P4_8x16) | 277462306a36Sopenharmony_ci MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING)); 277562306a36Sopenharmony_ci tile[14] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | 277662306a36Sopenharmony_ci MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING) | 277762306a36Sopenharmony_ci PIPE_CONFIG(ADDR_SURF_P4_8x16) | 277862306a36Sopenharmony_ci SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2)); 277962306a36Sopenharmony_ci tile[16] = (ARRAY_MODE(ARRAY_PRT_TILED_THIN1) | 278062306a36Sopenharmony_ci MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING) | 278162306a36Sopenharmony_ci PIPE_CONFIG(ADDR_SURF_P4_8x16) | 278262306a36Sopenharmony_ci SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2)); 278362306a36Sopenharmony_ci tile[17] = (ARRAY_MODE(ARRAY_PRT_2D_TILED_THIN1) | 278462306a36Sopenharmony_ci MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING) | 278562306a36Sopenharmony_ci PIPE_CONFIG(ADDR_SURF_P4_8x16) | 278662306a36Sopenharmony_ci SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2)); 278762306a36Sopenharmony_ci tile[27] = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) | 278862306a36Sopenharmony_ci PIPE_CONFIG(ADDR_SURF_P4_8x16) | 278962306a36Sopenharmony_ci MICRO_TILE_MODE_NEW(ADDR_SURF_ROTATED_MICRO_TILING)); 279062306a36Sopenharmony_ci tile[28] = (ARRAY_MODE(ARRAY_PRT_2D_TILED_THIN1) | 279162306a36Sopenharmony_ci MICRO_TILE_MODE_NEW(ADDR_SURF_ROTATED_MICRO_TILING) | 279262306a36Sopenharmony_ci PIPE_CONFIG(ADDR_SURF_P4_8x16) | 279362306a36Sopenharmony_ci SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2)); 279462306a36Sopenharmony_ci tile[29] = (ARRAY_MODE(ARRAY_PRT_TILED_THIN1) | 279562306a36Sopenharmony_ci MICRO_TILE_MODE_NEW(ADDR_SURF_ROTATED_MICRO_TILING) | 279662306a36Sopenharmony_ci PIPE_CONFIG(ADDR_SURF_P4_8x16) | 279762306a36Sopenharmony_ci SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2)); 279862306a36Sopenharmony_ci tile[30] = (ARRAY_MODE(ARRAY_PRT_2D_TILED_THIN1) | 279962306a36Sopenharmony_ci MICRO_TILE_MODE_NEW(ADDR_SURF_ROTATED_MICRO_TILING) | 280062306a36Sopenharmony_ci PIPE_CONFIG(ADDR_SURF_P4_8x16) | 280162306a36Sopenharmony_ci SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2)); 280262306a36Sopenharmony_ci } 280362306a36Sopenharmony_ci 280462306a36Sopenharmony_ci macrotile[0] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | 280562306a36Sopenharmony_ci BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) | 280662306a36Sopenharmony_ci MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4) | 280762306a36Sopenharmony_ci NUM_BANKS(ADDR_SURF_16_BANK)); 280862306a36Sopenharmony_ci macrotile[1] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | 280962306a36Sopenharmony_ci BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) | 281062306a36Sopenharmony_ci MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4) | 281162306a36Sopenharmony_ci NUM_BANKS(ADDR_SURF_16_BANK)); 281262306a36Sopenharmony_ci macrotile[2] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | 281362306a36Sopenharmony_ci BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) | 281462306a36Sopenharmony_ci MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2) | 281562306a36Sopenharmony_ci NUM_BANKS(ADDR_SURF_16_BANK)); 281662306a36Sopenharmony_ci macrotile[3] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | 281762306a36Sopenharmony_ci BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) | 281862306a36Sopenharmony_ci MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2) | 281962306a36Sopenharmony_ci NUM_BANKS(ADDR_SURF_16_BANK)); 282062306a36Sopenharmony_ci macrotile[4] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | 282162306a36Sopenharmony_ci BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) | 282262306a36Sopenharmony_ci MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2) | 282362306a36Sopenharmony_ci NUM_BANKS(ADDR_SURF_16_BANK)); 282462306a36Sopenharmony_ci macrotile[5] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | 282562306a36Sopenharmony_ci BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) | 282662306a36Sopenharmony_ci MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2) | 282762306a36Sopenharmony_ci NUM_BANKS(ADDR_SURF_8_BANK)); 282862306a36Sopenharmony_ci macrotile[6] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | 282962306a36Sopenharmony_ci BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) | 283062306a36Sopenharmony_ci MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1) | 283162306a36Sopenharmony_ci NUM_BANKS(ADDR_SURF_4_BANK)); 283262306a36Sopenharmony_ci macrotile[8] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_2) | 283362306a36Sopenharmony_ci BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_8) | 283462306a36Sopenharmony_ci MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4) | 283562306a36Sopenharmony_ci NUM_BANKS(ADDR_SURF_16_BANK)); 283662306a36Sopenharmony_ci macrotile[9] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_2) | 283762306a36Sopenharmony_ci BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) | 283862306a36Sopenharmony_ci MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4) | 283962306a36Sopenharmony_ci NUM_BANKS(ADDR_SURF_16_BANK)); 284062306a36Sopenharmony_ci macrotile[10] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | 284162306a36Sopenharmony_ci BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) | 284262306a36Sopenharmony_ci MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4) | 284362306a36Sopenharmony_ci NUM_BANKS(ADDR_SURF_16_BANK)); 284462306a36Sopenharmony_ci macrotile[11] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | 284562306a36Sopenharmony_ci BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) | 284662306a36Sopenharmony_ci MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4) | 284762306a36Sopenharmony_ci NUM_BANKS(ADDR_SURF_16_BANK)); 284862306a36Sopenharmony_ci macrotile[12] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | 284962306a36Sopenharmony_ci BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) | 285062306a36Sopenharmony_ci MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2) | 285162306a36Sopenharmony_ci NUM_BANKS(ADDR_SURF_16_BANK)); 285262306a36Sopenharmony_ci macrotile[13] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | 285362306a36Sopenharmony_ci BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) | 285462306a36Sopenharmony_ci MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2) | 285562306a36Sopenharmony_ci NUM_BANKS(ADDR_SURF_8_BANK)); 285662306a36Sopenharmony_ci macrotile[14] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | 285762306a36Sopenharmony_ci BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) | 285862306a36Sopenharmony_ci MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1) | 285962306a36Sopenharmony_ci NUM_BANKS(ADDR_SURF_4_BANK)); 286062306a36Sopenharmony_ci 286162306a36Sopenharmony_ci for (reg_offset = 0; reg_offset < num_tile_mode_states; reg_offset++) 286262306a36Sopenharmony_ci WREG32(GB_TILE_MODE0 + (reg_offset * 4), tile[reg_offset]); 286362306a36Sopenharmony_ci for (reg_offset = 0; reg_offset < num_secondary_tile_mode_states; reg_offset++) 286462306a36Sopenharmony_ci WREG32(GB_MACROTILE_MODE0 + (reg_offset * 4), macrotile[reg_offset]); 286562306a36Sopenharmony_ci break; 286662306a36Sopenharmony_ci 286762306a36Sopenharmony_ci case 2: 286862306a36Sopenharmony_ci tile[0] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | 286962306a36Sopenharmony_ci MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING) | 287062306a36Sopenharmony_ci PIPE_CONFIG(ADDR_SURF_P2) | 287162306a36Sopenharmony_ci TILE_SPLIT(ADDR_SURF_TILE_SPLIT_64B)); 287262306a36Sopenharmony_ci tile[1] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | 287362306a36Sopenharmony_ci MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING) | 287462306a36Sopenharmony_ci PIPE_CONFIG(ADDR_SURF_P2) | 287562306a36Sopenharmony_ci TILE_SPLIT(ADDR_SURF_TILE_SPLIT_128B)); 287662306a36Sopenharmony_ci tile[2] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | 287762306a36Sopenharmony_ci MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING) | 287862306a36Sopenharmony_ci PIPE_CONFIG(ADDR_SURF_P2) | 287962306a36Sopenharmony_ci TILE_SPLIT(ADDR_SURF_TILE_SPLIT_256B)); 288062306a36Sopenharmony_ci tile[3] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | 288162306a36Sopenharmony_ci MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING) | 288262306a36Sopenharmony_ci PIPE_CONFIG(ADDR_SURF_P2) | 288362306a36Sopenharmony_ci TILE_SPLIT(ADDR_SURF_TILE_SPLIT_512B)); 288462306a36Sopenharmony_ci tile[4] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | 288562306a36Sopenharmony_ci MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING) | 288662306a36Sopenharmony_ci PIPE_CONFIG(ADDR_SURF_P2) | 288762306a36Sopenharmony_ci TILE_SPLIT(split_equal_to_row_size)); 288862306a36Sopenharmony_ci tile[5] = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) | 288962306a36Sopenharmony_ci PIPE_CONFIG(ADDR_SURF_P2) | 289062306a36Sopenharmony_ci MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING)); 289162306a36Sopenharmony_ci tile[6] = (ARRAY_MODE(ARRAY_PRT_2D_TILED_THIN1) | 289262306a36Sopenharmony_ci MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING) | 289362306a36Sopenharmony_ci PIPE_CONFIG(ADDR_SURF_P2) | 289462306a36Sopenharmony_ci TILE_SPLIT(ADDR_SURF_TILE_SPLIT_256B)); 289562306a36Sopenharmony_ci tile[7] = (ARRAY_MODE(ARRAY_PRT_2D_TILED_THIN1) | 289662306a36Sopenharmony_ci MICRO_TILE_MODE_NEW(ADDR_SURF_DEPTH_MICRO_TILING) | 289762306a36Sopenharmony_ci PIPE_CONFIG(ADDR_SURF_P2) | 289862306a36Sopenharmony_ci TILE_SPLIT(split_equal_to_row_size)); 289962306a36Sopenharmony_ci tile[8] = ARRAY_MODE(ARRAY_LINEAR_ALIGNED) | 290062306a36Sopenharmony_ci PIPE_CONFIG(ADDR_SURF_P2); 290162306a36Sopenharmony_ci tile[9] = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) | 290262306a36Sopenharmony_ci MICRO_TILE_MODE_NEW(ADDR_SURF_DISPLAY_MICRO_TILING) | 290362306a36Sopenharmony_ci PIPE_CONFIG(ADDR_SURF_P2)); 290462306a36Sopenharmony_ci tile[10] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | 290562306a36Sopenharmony_ci MICRO_TILE_MODE_NEW(ADDR_SURF_DISPLAY_MICRO_TILING) | 290662306a36Sopenharmony_ci PIPE_CONFIG(ADDR_SURF_P2) | 290762306a36Sopenharmony_ci SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2)); 290862306a36Sopenharmony_ci tile[11] = (ARRAY_MODE(ARRAY_PRT_TILED_THIN1) | 290962306a36Sopenharmony_ci MICRO_TILE_MODE_NEW(ADDR_SURF_DISPLAY_MICRO_TILING) | 291062306a36Sopenharmony_ci PIPE_CONFIG(ADDR_SURF_P2) | 291162306a36Sopenharmony_ci SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2)); 291262306a36Sopenharmony_ci tile[12] = (ARRAY_MODE(ARRAY_PRT_2D_TILED_THIN1) | 291362306a36Sopenharmony_ci MICRO_TILE_MODE_NEW(ADDR_SURF_DISPLAY_MICRO_TILING) | 291462306a36Sopenharmony_ci PIPE_CONFIG(ADDR_SURF_P2) | 291562306a36Sopenharmony_ci SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2)); 291662306a36Sopenharmony_ci tile[13] = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) | 291762306a36Sopenharmony_ci PIPE_CONFIG(ADDR_SURF_P2) | 291862306a36Sopenharmony_ci MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING)); 291962306a36Sopenharmony_ci tile[14] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) | 292062306a36Sopenharmony_ci MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING) | 292162306a36Sopenharmony_ci PIPE_CONFIG(ADDR_SURF_P2) | 292262306a36Sopenharmony_ci SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2)); 292362306a36Sopenharmony_ci tile[16] = (ARRAY_MODE(ARRAY_PRT_TILED_THIN1) | 292462306a36Sopenharmony_ci MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING) | 292562306a36Sopenharmony_ci PIPE_CONFIG(ADDR_SURF_P2) | 292662306a36Sopenharmony_ci SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2)); 292762306a36Sopenharmony_ci tile[17] = (ARRAY_MODE(ARRAY_PRT_2D_TILED_THIN1) | 292862306a36Sopenharmony_ci MICRO_TILE_MODE_NEW(ADDR_SURF_THIN_MICRO_TILING) | 292962306a36Sopenharmony_ci PIPE_CONFIG(ADDR_SURF_P2) | 293062306a36Sopenharmony_ci SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2)); 293162306a36Sopenharmony_ci tile[27] = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) | 293262306a36Sopenharmony_ci MICRO_TILE_MODE_NEW(ADDR_SURF_ROTATED_MICRO_TILING) | 293362306a36Sopenharmony_ci PIPE_CONFIG(ADDR_SURF_P2)); 293462306a36Sopenharmony_ci tile[28] = (ARRAY_MODE(ARRAY_PRT_2D_TILED_THIN1) | 293562306a36Sopenharmony_ci MICRO_TILE_MODE_NEW(ADDR_SURF_ROTATED_MICRO_TILING) | 293662306a36Sopenharmony_ci PIPE_CONFIG(ADDR_SURF_P2) | 293762306a36Sopenharmony_ci SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2)); 293862306a36Sopenharmony_ci tile[29] = (ARRAY_MODE(ARRAY_PRT_TILED_THIN1) | 293962306a36Sopenharmony_ci MICRO_TILE_MODE_NEW(ADDR_SURF_ROTATED_MICRO_TILING) | 294062306a36Sopenharmony_ci PIPE_CONFIG(ADDR_SURF_P2) | 294162306a36Sopenharmony_ci SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2)); 294262306a36Sopenharmony_ci tile[30] = (ARRAY_MODE(ARRAY_PRT_2D_TILED_THIN1) | 294362306a36Sopenharmony_ci MICRO_TILE_MODE_NEW(ADDR_SURF_ROTATED_MICRO_TILING) | 294462306a36Sopenharmony_ci PIPE_CONFIG(ADDR_SURF_P2) | 294562306a36Sopenharmony_ci SAMPLE_SPLIT(ADDR_SURF_SAMPLE_SPLIT_2)); 294662306a36Sopenharmony_ci 294762306a36Sopenharmony_ci macrotile[0] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_2) | 294862306a36Sopenharmony_ci BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) | 294962306a36Sopenharmony_ci MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4) | 295062306a36Sopenharmony_ci NUM_BANKS(ADDR_SURF_16_BANK)); 295162306a36Sopenharmony_ci macrotile[1] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_2) | 295262306a36Sopenharmony_ci BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) | 295362306a36Sopenharmony_ci MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4) | 295462306a36Sopenharmony_ci NUM_BANKS(ADDR_SURF_16_BANK)); 295562306a36Sopenharmony_ci macrotile[2] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | 295662306a36Sopenharmony_ci BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) | 295762306a36Sopenharmony_ci MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4) | 295862306a36Sopenharmony_ci NUM_BANKS(ADDR_SURF_16_BANK)); 295962306a36Sopenharmony_ci macrotile[3] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | 296062306a36Sopenharmony_ci BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) | 296162306a36Sopenharmony_ci MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4) | 296262306a36Sopenharmony_ci NUM_BANKS(ADDR_SURF_16_BANK)); 296362306a36Sopenharmony_ci macrotile[4] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | 296462306a36Sopenharmony_ci BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) | 296562306a36Sopenharmony_ci MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4) | 296662306a36Sopenharmony_ci NUM_BANKS(ADDR_SURF_16_BANK)); 296762306a36Sopenharmony_ci macrotile[5] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | 296862306a36Sopenharmony_ci BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) | 296962306a36Sopenharmony_ci MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4) | 297062306a36Sopenharmony_ci NUM_BANKS(ADDR_SURF_16_BANK)); 297162306a36Sopenharmony_ci macrotile[6] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | 297262306a36Sopenharmony_ci BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) | 297362306a36Sopenharmony_ci MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2) | 297462306a36Sopenharmony_ci NUM_BANKS(ADDR_SURF_8_BANK)); 297562306a36Sopenharmony_ci macrotile[8] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_4) | 297662306a36Sopenharmony_ci BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_8) | 297762306a36Sopenharmony_ci MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4) | 297862306a36Sopenharmony_ci NUM_BANKS(ADDR_SURF_16_BANK)); 297962306a36Sopenharmony_ci macrotile[9] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_4) | 298062306a36Sopenharmony_ci BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) | 298162306a36Sopenharmony_ci MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4) | 298262306a36Sopenharmony_ci NUM_BANKS(ADDR_SURF_16_BANK)); 298362306a36Sopenharmony_ci macrotile[10] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_2) | 298462306a36Sopenharmony_ci BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) | 298562306a36Sopenharmony_ci MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4) | 298662306a36Sopenharmony_ci NUM_BANKS(ADDR_SURF_16_BANK)); 298762306a36Sopenharmony_ci macrotile[11] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_2) | 298862306a36Sopenharmony_ci BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) | 298962306a36Sopenharmony_ci MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4) | 299062306a36Sopenharmony_ci NUM_BANKS(ADDR_SURF_16_BANK)); 299162306a36Sopenharmony_ci macrotile[12] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | 299262306a36Sopenharmony_ci BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) | 299362306a36Sopenharmony_ci MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4) | 299462306a36Sopenharmony_ci NUM_BANKS(ADDR_SURF_16_BANK)); 299562306a36Sopenharmony_ci macrotile[13] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | 299662306a36Sopenharmony_ci BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) | 299762306a36Sopenharmony_ci MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4) | 299862306a36Sopenharmony_ci NUM_BANKS(ADDR_SURF_16_BANK)); 299962306a36Sopenharmony_ci macrotile[14] = (BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) | 300062306a36Sopenharmony_ci BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) | 300162306a36Sopenharmony_ci MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2) | 300262306a36Sopenharmony_ci NUM_BANKS(ADDR_SURF_8_BANK)); 300362306a36Sopenharmony_ci 300462306a36Sopenharmony_ci for (reg_offset = 0; reg_offset < num_tile_mode_states; reg_offset++) 300562306a36Sopenharmony_ci WREG32(GB_TILE_MODE0 + (reg_offset * 4), tile[reg_offset]); 300662306a36Sopenharmony_ci for (reg_offset = 0; reg_offset < num_secondary_tile_mode_states; reg_offset++) 300762306a36Sopenharmony_ci WREG32(GB_MACROTILE_MODE0 + (reg_offset * 4), macrotile[reg_offset]); 300862306a36Sopenharmony_ci break; 300962306a36Sopenharmony_ci 301062306a36Sopenharmony_ci default: 301162306a36Sopenharmony_ci DRM_ERROR("unknown num pipe config: 0x%x\n", num_pipe_configs); 301262306a36Sopenharmony_ci } 301362306a36Sopenharmony_ci} 301462306a36Sopenharmony_ci 301562306a36Sopenharmony_ci/** 301662306a36Sopenharmony_ci * cik_select_se_sh - select which SE, SH to address 301762306a36Sopenharmony_ci * 301862306a36Sopenharmony_ci * @rdev: radeon_device pointer 301962306a36Sopenharmony_ci * @se_num: shader engine to address 302062306a36Sopenharmony_ci * @sh_num: sh block to address 302162306a36Sopenharmony_ci * 302262306a36Sopenharmony_ci * Select which SE, SH combinations to address. Certain 302362306a36Sopenharmony_ci * registers are instanced per SE or SH. 0xffffffff means 302462306a36Sopenharmony_ci * broadcast to all SEs or SHs (CIK). 302562306a36Sopenharmony_ci */ 302662306a36Sopenharmony_cistatic void cik_select_se_sh(struct radeon_device *rdev, 302762306a36Sopenharmony_ci u32 se_num, u32 sh_num) 302862306a36Sopenharmony_ci{ 302962306a36Sopenharmony_ci u32 data = INSTANCE_BROADCAST_WRITES; 303062306a36Sopenharmony_ci 303162306a36Sopenharmony_ci if ((se_num == 0xffffffff) && (sh_num == 0xffffffff)) 303262306a36Sopenharmony_ci data |= SH_BROADCAST_WRITES | SE_BROADCAST_WRITES; 303362306a36Sopenharmony_ci else if (se_num == 0xffffffff) 303462306a36Sopenharmony_ci data |= SE_BROADCAST_WRITES | SH_INDEX(sh_num); 303562306a36Sopenharmony_ci else if (sh_num == 0xffffffff) 303662306a36Sopenharmony_ci data |= SH_BROADCAST_WRITES | SE_INDEX(se_num); 303762306a36Sopenharmony_ci else 303862306a36Sopenharmony_ci data |= SH_INDEX(sh_num) | SE_INDEX(se_num); 303962306a36Sopenharmony_ci WREG32(GRBM_GFX_INDEX, data); 304062306a36Sopenharmony_ci} 304162306a36Sopenharmony_ci 304262306a36Sopenharmony_ci/** 304362306a36Sopenharmony_ci * cik_create_bitmask - create a bitmask 304462306a36Sopenharmony_ci * 304562306a36Sopenharmony_ci * @bit_width: length of the mask 304662306a36Sopenharmony_ci * 304762306a36Sopenharmony_ci * create a variable length bit mask (CIK). 304862306a36Sopenharmony_ci * Returns the bitmask. 304962306a36Sopenharmony_ci */ 305062306a36Sopenharmony_cistatic u32 cik_create_bitmask(u32 bit_width) 305162306a36Sopenharmony_ci{ 305262306a36Sopenharmony_ci u32 i, mask = 0; 305362306a36Sopenharmony_ci 305462306a36Sopenharmony_ci for (i = 0; i < bit_width; i++) { 305562306a36Sopenharmony_ci mask <<= 1; 305662306a36Sopenharmony_ci mask |= 1; 305762306a36Sopenharmony_ci } 305862306a36Sopenharmony_ci return mask; 305962306a36Sopenharmony_ci} 306062306a36Sopenharmony_ci 306162306a36Sopenharmony_ci/** 306262306a36Sopenharmony_ci * cik_get_rb_disabled - computes the mask of disabled RBs 306362306a36Sopenharmony_ci * 306462306a36Sopenharmony_ci * @rdev: radeon_device pointer 306562306a36Sopenharmony_ci * @max_rb_num_per_se: max RBs (render backends) per SE (shader engine) for the asic 306662306a36Sopenharmony_ci * @sh_per_se: number of SH blocks per SE for the asic 306762306a36Sopenharmony_ci * 306862306a36Sopenharmony_ci * Calculates the bitmask of disabled RBs (CIK). 306962306a36Sopenharmony_ci * Returns the disabled RB bitmask. 307062306a36Sopenharmony_ci */ 307162306a36Sopenharmony_cistatic u32 cik_get_rb_disabled(struct radeon_device *rdev, 307262306a36Sopenharmony_ci u32 max_rb_num_per_se, 307362306a36Sopenharmony_ci u32 sh_per_se) 307462306a36Sopenharmony_ci{ 307562306a36Sopenharmony_ci u32 data, mask; 307662306a36Sopenharmony_ci 307762306a36Sopenharmony_ci data = RREG32(CC_RB_BACKEND_DISABLE); 307862306a36Sopenharmony_ci if (data & 1) 307962306a36Sopenharmony_ci data &= BACKEND_DISABLE_MASK; 308062306a36Sopenharmony_ci else 308162306a36Sopenharmony_ci data = 0; 308262306a36Sopenharmony_ci data |= RREG32(GC_USER_RB_BACKEND_DISABLE); 308362306a36Sopenharmony_ci 308462306a36Sopenharmony_ci data >>= BACKEND_DISABLE_SHIFT; 308562306a36Sopenharmony_ci 308662306a36Sopenharmony_ci mask = cik_create_bitmask(max_rb_num_per_se / sh_per_se); 308762306a36Sopenharmony_ci 308862306a36Sopenharmony_ci return data & mask; 308962306a36Sopenharmony_ci} 309062306a36Sopenharmony_ci 309162306a36Sopenharmony_ci/** 309262306a36Sopenharmony_ci * cik_setup_rb - setup the RBs on the asic 309362306a36Sopenharmony_ci * 309462306a36Sopenharmony_ci * @rdev: radeon_device pointer 309562306a36Sopenharmony_ci * @se_num: number of SEs (shader engines) for the asic 309662306a36Sopenharmony_ci * @sh_per_se: number of SH blocks per SE for the asic 309762306a36Sopenharmony_ci * @max_rb_num_per_se: max RBs (render backends) per SE for the asic 309862306a36Sopenharmony_ci * 309962306a36Sopenharmony_ci * Configures per-SE/SH RB registers (CIK). 310062306a36Sopenharmony_ci */ 310162306a36Sopenharmony_cistatic void cik_setup_rb(struct radeon_device *rdev, 310262306a36Sopenharmony_ci u32 se_num, u32 sh_per_se, 310362306a36Sopenharmony_ci u32 max_rb_num_per_se) 310462306a36Sopenharmony_ci{ 310562306a36Sopenharmony_ci int i, j; 310662306a36Sopenharmony_ci u32 data, mask; 310762306a36Sopenharmony_ci u32 disabled_rbs = 0; 310862306a36Sopenharmony_ci u32 enabled_rbs = 0; 310962306a36Sopenharmony_ci 311062306a36Sopenharmony_ci for (i = 0; i < se_num; i++) { 311162306a36Sopenharmony_ci for (j = 0; j < sh_per_se; j++) { 311262306a36Sopenharmony_ci cik_select_se_sh(rdev, i, j); 311362306a36Sopenharmony_ci data = cik_get_rb_disabled(rdev, max_rb_num_per_se, sh_per_se); 311462306a36Sopenharmony_ci if (rdev->family == CHIP_HAWAII) 311562306a36Sopenharmony_ci disabled_rbs |= data << ((i * sh_per_se + j) * HAWAII_RB_BITMAP_WIDTH_PER_SH); 311662306a36Sopenharmony_ci else 311762306a36Sopenharmony_ci disabled_rbs |= data << ((i * sh_per_se + j) * CIK_RB_BITMAP_WIDTH_PER_SH); 311862306a36Sopenharmony_ci } 311962306a36Sopenharmony_ci } 312062306a36Sopenharmony_ci cik_select_se_sh(rdev, 0xffffffff, 0xffffffff); 312162306a36Sopenharmony_ci 312262306a36Sopenharmony_ci mask = 1; 312362306a36Sopenharmony_ci for (i = 0; i < max_rb_num_per_se * se_num; i++) { 312462306a36Sopenharmony_ci if (!(disabled_rbs & mask)) 312562306a36Sopenharmony_ci enabled_rbs |= mask; 312662306a36Sopenharmony_ci mask <<= 1; 312762306a36Sopenharmony_ci } 312862306a36Sopenharmony_ci 312962306a36Sopenharmony_ci rdev->config.cik.backend_enable_mask = enabled_rbs; 313062306a36Sopenharmony_ci 313162306a36Sopenharmony_ci for (i = 0; i < se_num; i++) { 313262306a36Sopenharmony_ci cik_select_se_sh(rdev, i, 0xffffffff); 313362306a36Sopenharmony_ci data = 0; 313462306a36Sopenharmony_ci for (j = 0; j < sh_per_se; j++) { 313562306a36Sopenharmony_ci switch (enabled_rbs & 3) { 313662306a36Sopenharmony_ci case 0: 313762306a36Sopenharmony_ci if (j == 0) 313862306a36Sopenharmony_ci data |= PKR_MAP(RASTER_CONFIG_RB_MAP_3); 313962306a36Sopenharmony_ci else 314062306a36Sopenharmony_ci data |= PKR_MAP(RASTER_CONFIG_RB_MAP_0); 314162306a36Sopenharmony_ci break; 314262306a36Sopenharmony_ci case 1: 314362306a36Sopenharmony_ci data |= (RASTER_CONFIG_RB_MAP_0 << (i * sh_per_se + j) * 2); 314462306a36Sopenharmony_ci break; 314562306a36Sopenharmony_ci case 2: 314662306a36Sopenharmony_ci data |= (RASTER_CONFIG_RB_MAP_3 << (i * sh_per_se + j) * 2); 314762306a36Sopenharmony_ci break; 314862306a36Sopenharmony_ci case 3: 314962306a36Sopenharmony_ci default: 315062306a36Sopenharmony_ci data |= (RASTER_CONFIG_RB_MAP_2 << (i * sh_per_se + j) * 2); 315162306a36Sopenharmony_ci break; 315262306a36Sopenharmony_ci } 315362306a36Sopenharmony_ci enabled_rbs >>= 2; 315462306a36Sopenharmony_ci } 315562306a36Sopenharmony_ci WREG32(PA_SC_RASTER_CONFIG, data); 315662306a36Sopenharmony_ci } 315762306a36Sopenharmony_ci cik_select_se_sh(rdev, 0xffffffff, 0xffffffff); 315862306a36Sopenharmony_ci} 315962306a36Sopenharmony_ci 316062306a36Sopenharmony_ci/** 316162306a36Sopenharmony_ci * cik_gpu_init - setup the 3D engine 316262306a36Sopenharmony_ci * 316362306a36Sopenharmony_ci * @rdev: radeon_device pointer 316462306a36Sopenharmony_ci * 316562306a36Sopenharmony_ci * Configures the 3D engine and tiling configuration 316662306a36Sopenharmony_ci * registers so that the 3D engine is usable. 316762306a36Sopenharmony_ci */ 316862306a36Sopenharmony_cistatic void cik_gpu_init(struct radeon_device *rdev) 316962306a36Sopenharmony_ci{ 317062306a36Sopenharmony_ci u32 gb_addr_config = RREG32(GB_ADDR_CONFIG); 317162306a36Sopenharmony_ci u32 mc_arb_ramcfg; 317262306a36Sopenharmony_ci u32 hdp_host_path_cntl; 317362306a36Sopenharmony_ci u32 tmp; 317462306a36Sopenharmony_ci int i, j; 317562306a36Sopenharmony_ci 317662306a36Sopenharmony_ci switch (rdev->family) { 317762306a36Sopenharmony_ci case CHIP_BONAIRE: 317862306a36Sopenharmony_ci rdev->config.cik.max_shader_engines = 2; 317962306a36Sopenharmony_ci rdev->config.cik.max_tile_pipes = 4; 318062306a36Sopenharmony_ci rdev->config.cik.max_cu_per_sh = 7; 318162306a36Sopenharmony_ci rdev->config.cik.max_sh_per_se = 1; 318262306a36Sopenharmony_ci rdev->config.cik.max_backends_per_se = 2; 318362306a36Sopenharmony_ci rdev->config.cik.max_texture_channel_caches = 4; 318462306a36Sopenharmony_ci rdev->config.cik.max_gprs = 256; 318562306a36Sopenharmony_ci rdev->config.cik.max_gs_threads = 32; 318662306a36Sopenharmony_ci rdev->config.cik.max_hw_contexts = 8; 318762306a36Sopenharmony_ci 318862306a36Sopenharmony_ci rdev->config.cik.sc_prim_fifo_size_frontend = 0x20; 318962306a36Sopenharmony_ci rdev->config.cik.sc_prim_fifo_size_backend = 0x100; 319062306a36Sopenharmony_ci rdev->config.cik.sc_hiz_tile_fifo_size = 0x30; 319162306a36Sopenharmony_ci rdev->config.cik.sc_earlyz_tile_fifo_size = 0x130; 319262306a36Sopenharmony_ci gb_addr_config = BONAIRE_GB_ADDR_CONFIG_GOLDEN; 319362306a36Sopenharmony_ci break; 319462306a36Sopenharmony_ci case CHIP_HAWAII: 319562306a36Sopenharmony_ci rdev->config.cik.max_shader_engines = 4; 319662306a36Sopenharmony_ci rdev->config.cik.max_tile_pipes = 16; 319762306a36Sopenharmony_ci rdev->config.cik.max_cu_per_sh = 11; 319862306a36Sopenharmony_ci rdev->config.cik.max_sh_per_se = 1; 319962306a36Sopenharmony_ci rdev->config.cik.max_backends_per_se = 4; 320062306a36Sopenharmony_ci rdev->config.cik.max_texture_channel_caches = 16; 320162306a36Sopenharmony_ci rdev->config.cik.max_gprs = 256; 320262306a36Sopenharmony_ci rdev->config.cik.max_gs_threads = 32; 320362306a36Sopenharmony_ci rdev->config.cik.max_hw_contexts = 8; 320462306a36Sopenharmony_ci 320562306a36Sopenharmony_ci rdev->config.cik.sc_prim_fifo_size_frontend = 0x20; 320662306a36Sopenharmony_ci rdev->config.cik.sc_prim_fifo_size_backend = 0x100; 320762306a36Sopenharmony_ci rdev->config.cik.sc_hiz_tile_fifo_size = 0x30; 320862306a36Sopenharmony_ci rdev->config.cik.sc_earlyz_tile_fifo_size = 0x130; 320962306a36Sopenharmony_ci gb_addr_config = HAWAII_GB_ADDR_CONFIG_GOLDEN; 321062306a36Sopenharmony_ci break; 321162306a36Sopenharmony_ci case CHIP_KAVERI: 321262306a36Sopenharmony_ci rdev->config.cik.max_shader_engines = 1; 321362306a36Sopenharmony_ci rdev->config.cik.max_tile_pipes = 4; 321462306a36Sopenharmony_ci rdev->config.cik.max_cu_per_sh = 8; 321562306a36Sopenharmony_ci rdev->config.cik.max_backends_per_se = 2; 321662306a36Sopenharmony_ci rdev->config.cik.max_sh_per_se = 1; 321762306a36Sopenharmony_ci rdev->config.cik.max_texture_channel_caches = 4; 321862306a36Sopenharmony_ci rdev->config.cik.max_gprs = 256; 321962306a36Sopenharmony_ci rdev->config.cik.max_gs_threads = 16; 322062306a36Sopenharmony_ci rdev->config.cik.max_hw_contexts = 8; 322162306a36Sopenharmony_ci 322262306a36Sopenharmony_ci rdev->config.cik.sc_prim_fifo_size_frontend = 0x20; 322362306a36Sopenharmony_ci rdev->config.cik.sc_prim_fifo_size_backend = 0x100; 322462306a36Sopenharmony_ci rdev->config.cik.sc_hiz_tile_fifo_size = 0x30; 322562306a36Sopenharmony_ci rdev->config.cik.sc_earlyz_tile_fifo_size = 0x130; 322662306a36Sopenharmony_ci gb_addr_config = BONAIRE_GB_ADDR_CONFIG_GOLDEN; 322762306a36Sopenharmony_ci break; 322862306a36Sopenharmony_ci case CHIP_KABINI: 322962306a36Sopenharmony_ci case CHIP_MULLINS: 323062306a36Sopenharmony_ci default: 323162306a36Sopenharmony_ci rdev->config.cik.max_shader_engines = 1; 323262306a36Sopenharmony_ci rdev->config.cik.max_tile_pipes = 2; 323362306a36Sopenharmony_ci rdev->config.cik.max_cu_per_sh = 2; 323462306a36Sopenharmony_ci rdev->config.cik.max_sh_per_se = 1; 323562306a36Sopenharmony_ci rdev->config.cik.max_backends_per_se = 1; 323662306a36Sopenharmony_ci rdev->config.cik.max_texture_channel_caches = 2; 323762306a36Sopenharmony_ci rdev->config.cik.max_gprs = 256; 323862306a36Sopenharmony_ci rdev->config.cik.max_gs_threads = 16; 323962306a36Sopenharmony_ci rdev->config.cik.max_hw_contexts = 8; 324062306a36Sopenharmony_ci 324162306a36Sopenharmony_ci rdev->config.cik.sc_prim_fifo_size_frontend = 0x20; 324262306a36Sopenharmony_ci rdev->config.cik.sc_prim_fifo_size_backend = 0x100; 324362306a36Sopenharmony_ci rdev->config.cik.sc_hiz_tile_fifo_size = 0x30; 324462306a36Sopenharmony_ci rdev->config.cik.sc_earlyz_tile_fifo_size = 0x130; 324562306a36Sopenharmony_ci gb_addr_config = BONAIRE_GB_ADDR_CONFIG_GOLDEN; 324662306a36Sopenharmony_ci break; 324762306a36Sopenharmony_ci } 324862306a36Sopenharmony_ci 324962306a36Sopenharmony_ci /* Initialize HDP */ 325062306a36Sopenharmony_ci for (i = 0, j = 0; i < 32; i++, j += 0x18) { 325162306a36Sopenharmony_ci WREG32((0x2c14 + j), 0x00000000); 325262306a36Sopenharmony_ci WREG32((0x2c18 + j), 0x00000000); 325362306a36Sopenharmony_ci WREG32((0x2c1c + j), 0x00000000); 325462306a36Sopenharmony_ci WREG32((0x2c20 + j), 0x00000000); 325562306a36Sopenharmony_ci WREG32((0x2c24 + j), 0x00000000); 325662306a36Sopenharmony_ci } 325762306a36Sopenharmony_ci 325862306a36Sopenharmony_ci WREG32(GRBM_CNTL, GRBM_READ_TIMEOUT(0xff)); 325962306a36Sopenharmony_ci WREG32(SRBM_INT_CNTL, 0x1); 326062306a36Sopenharmony_ci WREG32(SRBM_INT_ACK, 0x1); 326162306a36Sopenharmony_ci 326262306a36Sopenharmony_ci WREG32(BIF_FB_EN, FB_READ_EN | FB_WRITE_EN); 326362306a36Sopenharmony_ci 326462306a36Sopenharmony_ci RREG32(MC_SHARED_CHMAP); 326562306a36Sopenharmony_ci mc_arb_ramcfg = RREG32(MC_ARB_RAMCFG); 326662306a36Sopenharmony_ci 326762306a36Sopenharmony_ci rdev->config.cik.num_tile_pipes = rdev->config.cik.max_tile_pipes; 326862306a36Sopenharmony_ci rdev->config.cik.mem_max_burst_length_bytes = 256; 326962306a36Sopenharmony_ci tmp = (mc_arb_ramcfg & NOOFCOLS_MASK) >> NOOFCOLS_SHIFT; 327062306a36Sopenharmony_ci rdev->config.cik.mem_row_size_in_kb = (4 * (1 << (8 + tmp))) / 1024; 327162306a36Sopenharmony_ci if (rdev->config.cik.mem_row_size_in_kb > 4) 327262306a36Sopenharmony_ci rdev->config.cik.mem_row_size_in_kb = 4; 327362306a36Sopenharmony_ci /* XXX use MC settings? */ 327462306a36Sopenharmony_ci rdev->config.cik.shader_engine_tile_size = 32; 327562306a36Sopenharmony_ci rdev->config.cik.num_gpus = 1; 327662306a36Sopenharmony_ci rdev->config.cik.multi_gpu_tile_size = 64; 327762306a36Sopenharmony_ci 327862306a36Sopenharmony_ci /* fix up row size */ 327962306a36Sopenharmony_ci gb_addr_config &= ~ROW_SIZE_MASK; 328062306a36Sopenharmony_ci switch (rdev->config.cik.mem_row_size_in_kb) { 328162306a36Sopenharmony_ci case 1: 328262306a36Sopenharmony_ci default: 328362306a36Sopenharmony_ci gb_addr_config |= ROW_SIZE(0); 328462306a36Sopenharmony_ci break; 328562306a36Sopenharmony_ci case 2: 328662306a36Sopenharmony_ci gb_addr_config |= ROW_SIZE(1); 328762306a36Sopenharmony_ci break; 328862306a36Sopenharmony_ci case 4: 328962306a36Sopenharmony_ci gb_addr_config |= ROW_SIZE(2); 329062306a36Sopenharmony_ci break; 329162306a36Sopenharmony_ci } 329262306a36Sopenharmony_ci 329362306a36Sopenharmony_ci /* setup tiling info dword. gb_addr_config is not adequate since it does 329462306a36Sopenharmony_ci * not have bank info, so create a custom tiling dword. 329562306a36Sopenharmony_ci * bits 3:0 num_pipes 329662306a36Sopenharmony_ci * bits 7:4 num_banks 329762306a36Sopenharmony_ci * bits 11:8 group_size 329862306a36Sopenharmony_ci * bits 15:12 row_size 329962306a36Sopenharmony_ci */ 330062306a36Sopenharmony_ci rdev->config.cik.tile_config = 0; 330162306a36Sopenharmony_ci switch (rdev->config.cik.num_tile_pipes) { 330262306a36Sopenharmony_ci case 1: 330362306a36Sopenharmony_ci rdev->config.cik.tile_config |= (0 << 0); 330462306a36Sopenharmony_ci break; 330562306a36Sopenharmony_ci case 2: 330662306a36Sopenharmony_ci rdev->config.cik.tile_config |= (1 << 0); 330762306a36Sopenharmony_ci break; 330862306a36Sopenharmony_ci case 4: 330962306a36Sopenharmony_ci rdev->config.cik.tile_config |= (2 << 0); 331062306a36Sopenharmony_ci break; 331162306a36Sopenharmony_ci case 8: 331262306a36Sopenharmony_ci default: 331362306a36Sopenharmony_ci /* XXX what about 12? */ 331462306a36Sopenharmony_ci rdev->config.cik.tile_config |= (3 << 0); 331562306a36Sopenharmony_ci break; 331662306a36Sopenharmony_ci } 331762306a36Sopenharmony_ci rdev->config.cik.tile_config |= 331862306a36Sopenharmony_ci ((mc_arb_ramcfg & NOOFBANK_MASK) >> NOOFBANK_SHIFT) << 4; 331962306a36Sopenharmony_ci rdev->config.cik.tile_config |= 332062306a36Sopenharmony_ci ((gb_addr_config & PIPE_INTERLEAVE_SIZE_MASK) >> PIPE_INTERLEAVE_SIZE_SHIFT) << 8; 332162306a36Sopenharmony_ci rdev->config.cik.tile_config |= 332262306a36Sopenharmony_ci ((gb_addr_config & ROW_SIZE_MASK) >> ROW_SIZE_SHIFT) << 12; 332362306a36Sopenharmony_ci 332462306a36Sopenharmony_ci WREG32(GB_ADDR_CONFIG, gb_addr_config); 332562306a36Sopenharmony_ci WREG32(HDP_ADDR_CONFIG, gb_addr_config); 332662306a36Sopenharmony_ci WREG32(DMIF_ADDR_CALC, gb_addr_config); 332762306a36Sopenharmony_ci WREG32(SDMA0_TILING_CONFIG + SDMA0_REGISTER_OFFSET, gb_addr_config & 0x70); 332862306a36Sopenharmony_ci WREG32(SDMA0_TILING_CONFIG + SDMA1_REGISTER_OFFSET, gb_addr_config & 0x70); 332962306a36Sopenharmony_ci WREG32(UVD_UDEC_ADDR_CONFIG, gb_addr_config); 333062306a36Sopenharmony_ci WREG32(UVD_UDEC_DB_ADDR_CONFIG, gb_addr_config); 333162306a36Sopenharmony_ci WREG32(UVD_UDEC_DBW_ADDR_CONFIG, gb_addr_config); 333262306a36Sopenharmony_ci 333362306a36Sopenharmony_ci cik_tiling_mode_table_init(rdev); 333462306a36Sopenharmony_ci 333562306a36Sopenharmony_ci cik_setup_rb(rdev, rdev->config.cik.max_shader_engines, 333662306a36Sopenharmony_ci rdev->config.cik.max_sh_per_se, 333762306a36Sopenharmony_ci rdev->config.cik.max_backends_per_se); 333862306a36Sopenharmony_ci 333962306a36Sopenharmony_ci rdev->config.cik.active_cus = 0; 334062306a36Sopenharmony_ci for (i = 0; i < rdev->config.cik.max_shader_engines; i++) { 334162306a36Sopenharmony_ci for (j = 0; j < rdev->config.cik.max_sh_per_se; j++) { 334262306a36Sopenharmony_ci rdev->config.cik.active_cus += 334362306a36Sopenharmony_ci hweight32(cik_get_cu_active_bitmap(rdev, i, j)); 334462306a36Sopenharmony_ci } 334562306a36Sopenharmony_ci } 334662306a36Sopenharmony_ci 334762306a36Sopenharmony_ci /* set HW defaults for 3D engine */ 334862306a36Sopenharmony_ci WREG32(CP_MEQ_THRESHOLDS, MEQ1_START(0x30) | MEQ2_START(0x60)); 334962306a36Sopenharmony_ci 335062306a36Sopenharmony_ci WREG32(SX_DEBUG_1, 0x20); 335162306a36Sopenharmony_ci 335262306a36Sopenharmony_ci WREG32(TA_CNTL_AUX, 0x00010000); 335362306a36Sopenharmony_ci 335462306a36Sopenharmony_ci tmp = RREG32(SPI_CONFIG_CNTL); 335562306a36Sopenharmony_ci tmp |= 0x03000000; 335662306a36Sopenharmony_ci WREG32(SPI_CONFIG_CNTL, tmp); 335762306a36Sopenharmony_ci 335862306a36Sopenharmony_ci WREG32(SQ_CONFIG, 1); 335962306a36Sopenharmony_ci 336062306a36Sopenharmony_ci WREG32(DB_DEBUG, 0); 336162306a36Sopenharmony_ci 336262306a36Sopenharmony_ci tmp = RREG32(DB_DEBUG2) & ~0xf00fffff; 336362306a36Sopenharmony_ci tmp |= 0x00000400; 336462306a36Sopenharmony_ci WREG32(DB_DEBUG2, tmp); 336562306a36Sopenharmony_ci 336662306a36Sopenharmony_ci tmp = RREG32(DB_DEBUG3) & ~0x0002021c; 336762306a36Sopenharmony_ci tmp |= 0x00020200; 336862306a36Sopenharmony_ci WREG32(DB_DEBUG3, tmp); 336962306a36Sopenharmony_ci 337062306a36Sopenharmony_ci tmp = RREG32(CB_HW_CONTROL) & ~0x00010000; 337162306a36Sopenharmony_ci tmp |= 0x00018208; 337262306a36Sopenharmony_ci WREG32(CB_HW_CONTROL, tmp); 337362306a36Sopenharmony_ci 337462306a36Sopenharmony_ci WREG32(SPI_CONFIG_CNTL_1, VTX_DONE_DELAY(4)); 337562306a36Sopenharmony_ci 337662306a36Sopenharmony_ci WREG32(PA_SC_FIFO_SIZE, (SC_FRONTEND_PRIM_FIFO_SIZE(rdev->config.cik.sc_prim_fifo_size_frontend) | 337762306a36Sopenharmony_ci SC_BACKEND_PRIM_FIFO_SIZE(rdev->config.cik.sc_prim_fifo_size_backend) | 337862306a36Sopenharmony_ci SC_HIZ_TILE_FIFO_SIZE(rdev->config.cik.sc_hiz_tile_fifo_size) | 337962306a36Sopenharmony_ci SC_EARLYZ_TILE_FIFO_SIZE(rdev->config.cik.sc_earlyz_tile_fifo_size))); 338062306a36Sopenharmony_ci 338162306a36Sopenharmony_ci WREG32(VGT_NUM_INSTANCES, 1); 338262306a36Sopenharmony_ci 338362306a36Sopenharmony_ci WREG32(CP_PERFMON_CNTL, 0); 338462306a36Sopenharmony_ci 338562306a36Sopenharmony_ci WREG32(SQ_CONFIG, 0); 338662306a36Sopenharmony_ci 338762306a36Sopenharmony_ci WREG32(PA_SC_FORCE_EOV_MAX_CNTS, (FORCE_EOV_MAX_CLK_CNT(4095) | 338862306a36Sopenharmony_ci FORCE_EOV_MAX_REZ_CNT(255))); 338962306a36Sopenharmony_ci 339062306a36Sopenharmony_ci WREG32(VGT_CACHE_INVALIDATION, CACHE_INVALIDATION(VC_AND_TC) | 339162306a36Sopenharmony_ci AUTO_INVLD_EN(ES_AND_GS_AUTO)); 339262306a36Sopenharmony_ci 339362306a36Sopenharmony_ci WREG32(VGT_GS_VERTEX_REUSE, 16); 339462306a36Sopenharmony_ci WREG32(PA_SC_LINE_STIPPLE_STATE, 0); 339562306a36Sopenharmony_ci 339662306a36Sopenharmony_ci tmp = RREG32(HDP_MISC_CNTL); 339762306a36Sopenharmony_ci tmp |= HDP_FLUSH_INVALIDATE_CACHE; 339862306a36Sopenharmony_ci WREG32(HDP_MISC_CNTL, tmp); 339962306a36Sopenharmony_ci 340062306a36Sopenharmony_ci hdp_host_path_cntl = RREG32(HDP_HOST_PATH_CNTL); 340162306a36Sopenharmony_ci WREG32(HDP_HOST_PATH_CNTL, hdp_host_path_cntl); 340262306a36Sopenharmony_ci 340362306a36Sopenharmony_ci WREG32(PA_CL_ENHANCE, CLIP_VTX_REORDER_ENA | NUM_CLIP_SEQ(3)); 340462306a36Sopenharmony_ci WREG32(PA_SC_ENHANCE, ENABLE_PA_SC_OUT_OF_ORDER); 340562306a36Sopenharmony_ci 340662306a36Sopenharmony_ci udelay(50); 340762306a36Sopenharmony_ci} 340862306a36Sopenharmony_ci 340962306a36Sopenharmony_ci/* 341062306a36Sopenharmony_ci * GPU scratch registers helpers function. 341162306a36Sopenharmony_ci */ 341262306a36Sopenharmony_ci/** 341362306a36Sopenharmony_ci * cik_scratch_init - setup driver info for CP scratch regs 341462306a36Sopenharmony_ci * 341562306a36Sopenharmony_ci * @rdev: radeon_device pointer 341662306a36Sopenharmony_ci * 341762306a36Sopenharmony_ci * Set up the number and offset of the CP scratch registers. 341862306a36Sopenharmony_ci * NOTE: use of CP scratch registers is a legacy inferface and 341962306a36Sopenharmony_ci * is not used by default on newer asics (r6xx+). On newer asics, 342062306a36Sopenharmony_ci * memory buffers are used for fences rather than scratch regs. 342162306a36Sopenharmony_ci */ 342262306a36Sopenharmony_cistatic void cik_scratch_init(struct radeon_device *rdev) 342362306a36Sopenharmony_ci{ 342462306a36Sopenharmony_ci int i; 342562306a36Sopenharmony_ci 342662306a36Sopenharmony_ci rdev->scratch.num_reg = 7; 342762306a36Sopenharmony_ci rdev->scratch.reg_base = SCRATCH_REG0; 342862306a36Sopenharmony_ci for (i = 0; i < rdev->scratch.num_reg; i++) { 342962306a36Sopenharmony_ci rdev->scratch.free[i] = true; 343062306a36Sopenharmony_ci rdev->scratch.reg[i] = rdev->scratch.reg_base + (i * 4); 343162306a36Sopenharmony_ci } 343262306a36Sopenharmony_ci} 343362306a36Sopenharmony_ci 343462306a36Sopenharmony_ci/** 343562306a36Sopenharmony_ci * cik_ring_test - basic gfx ring test 343662306a36Sopenharmony_ci * 343762306a36Sopenharmony_ci * @rdev: radeon_device pointer 343862306a36Sopenharmony_ci * @ring: radeon_ring structure holding ring information 343962306a36Sopenharmony_ci * 344062306a36Sopenharmony_ci * Allocate a scratch register and write to it using the gfx ring (CIK). 344162306a36Sopenharmony_ci * Provides a basic gfx ring test to verify that the ring is working. 344262306a36Sopenharmony_ci * Used by cik_cp_gfx_resume(); 344362306a36Sopenharmony_ci * Returns 0 on success, error on failure. 344462306a36Sopenharmony_ci */ 344562306a36Sopenharmony_ciint cik_ring_test(struct radeon_device *rdev, struct radeon_ring *ring) 344662306a36Sopenharmony_ci{ 344762306a36Sopenharmony_ci uint32_t scratch; 344862306a36Sopenharmony_ci uint32_t tmp = 0; 344962306a36Sopenharmony_ci unsigned i; 345062306a36Sopenharmony_ci int r; 345162306a36Sopenharmony_ci 345262306a36Sopenharmony_ci r = radeon_scratch_get(rdev, &scratch); 345362306a36Sopenharmony_ci if (r) { 345462306a36Sopenharmony_ci DRM_ERROR("radeon: cp failed to get scratch reg (%d).\n", r); 345562306a36Sopenharmony_ci return r; 345662306a36Sopenharmony_ci } 345762306a36Sopenharmony_ci WREG32(scratch, 0xCAFEDEAD); 345862306a36Sopenharmony_ci r = radeon_ring_lock(rdev, ring, 3); 345962306a36Sopenharmony_ci if (r) { 346062306a36Sopenharmony_ci DRM_ERROR("radeon: cp failed to lock ring %d (%d).\n", ring->idx, r); 346162306a36Sopenharmony_ci radeon_scratch_free(rdev, scratch); 346262306a36Sopenharmony_ci return r; 346362306a36Sopenharmony_ci } 346462306a36Sopenharmony_ci radeon_ring_write(ring, PACKET3(PACKET3_SET_UCONFIG_REG, 1)); 346562306a36Sopenharmony_ci radeon_ring_write(ring, ((scratch - PACKET3_SET_UCONFIG_REG_START) >> 2)); 346662306a36Sopenharmony_ci radeon_ring_write(ring, 0xDEADBEEF); 346762306a36Sopenharmony_ci radeon_ring_unlock_commit(rdev, ring, false); 346862306a36Sopenharmony_ci 346962306a36Sopenharmony_ci for (i = 0; i < rdev->usec_timeout; i++) { 347062306a36Sopenharmony_ci tmp = RREG32(scratch); 347162306a36Sopenharmony_ci if (tmp == 0xDEADBEEF) 347262306a36Sopenharmony_ci break; 347362306a36Sopenharmony_ci udelay(1); 347462306a36Sopenharmony_ci } 347562306a36Sopenharmony_ci if (i < rdev->usec_timeout) { 347662306a36Sopenharmony_ci DRM_INFO("ring test on %d succeeded in %d usecs\n", ring->idx, i); 347762306a36Sopenharmony_ci } else { 347862306a36Sopenharmony_ci DRM_ERROR("radeon: ring %d test failed (scratch(0x%04X)=0x%08X)\n", 347962306a36Sopenharmony_ci ring->idx, scratch, tmp); 348062306a36Sopenharmony_ci r = -EINVAL; 348162306a36Sopenharmony_ci } 348262306a36Sopenharmony_ci radeon_scratch_free(rdev, scratch); 348362306a36Sopenharmony_ci return r; 348462306a36Sopenharmony_ci} 348562306a36Sopenharmony_ci 348662306a36Sopenharmony_ci/** 348762306a36Sopenharmony_ci * cik_hdp_flush_cp_ring_emit - emit an hdp flush on the cp 348862306a36Sopenharmony_ci * 348962306a36Sopenharmony_ci * @rdev: radeon_device pointer 349062306a36Sopenharmony_ci * @ridx: radeon ring index 349162306a36Sopenharmony_ci * 349262306a36Sopenharmony_ci * Emits an hdp flush on the cp. 349362306a36Sopenharmony_ci */ 349462306a36Sopenharmony_cistatic void cik_hdp_flush_cp_ring_emit(struct radeon_device *rdev, 349562306a36Sopenharmony_ci int ridx) 349662306a36Sopenharmony_ci{ 349762306a36Sopenharmony_ci struct radeon_ring *ring = &rdev->ring[ridx]; 349862306a36Sopenharmony_ci u32 ref_and_mask; 349962306a36Sopenharmony_ci 350062306a36Sopenharmony_ci switch (ring->idx) { 350162306a36Sopenharmony_ci case CAYMAN_RING_TYPE_CP1_INDEX: 350262306a36Sopenharmony_ci case CAYMAN_RING_TYPE_CP2_INDEX: 350362306a36Sopenharmony_ci default: 350462306a36Sopenharmony_ci switch (ring->me) { 350562306a36Sopenharmony_ci case 0: 350662306a36Sopenharmony_ci ref_and_mask = CP2 << ring->pipe; 350762306a36Sopenharmony_ci break; 350862306a36Sopenharmony_ci case 1: 350962306a36Sopenharmony_ci ref_and_mask = CP6 << ring->pipe; 351062306a36Sopenharmony_ci break; 351162306a36Sopenharmony_ci default: 351262306a36Sopenharmony_ci return; 351362306a36Sopenharmony_ci } 351462306a36Sopenharmony_ci break; 351562306a36Sopenharmony_ci case RADEON_RING_TYPE_GFX_INDEX: 351662306a36Sopenharmony_ci ref_and_mask = CP0; 351762306a36Sopenharmony_ci break; 351862306a36Sopenharmony_ci } 351962306a36Sopenharmony_ci 352062306a36Sopenharmony_ci radeon_ring_write(ring, PACKET3(PACKET3_WAIT_REG_MEM, 5)); 352162306a36Sopenharmony_ci radeon_ring_write(ring, (WAIT_REG_MEM_OPERATION(1) | /* write, wait, write */ 352262306a36Sopenharmony_ci WAIT_REG_MEM_FUNCTION(3) | /* == */ 352362306a36Sopenharmony_ci WAIT_REG_MEM_ENGINE(1))); /* pfp */ 352462306a36Sopenharmony_ci radeon_ring_write(ring, GPU_HDP_FLUSH_REQ >> 2); 352562306a36Sopenharmony_ci radeon_ring_write(ring, GPU_HDP_FLUSH_DONE >> 2); 352662306a36Sopenharmony_ci radeon_ring_write(ring, ref_and_mask); 352762306a36Sopenharmony_ci radeon_ring_write(ring, ref_and_mask); 352862306a36Sopenharmony_ci radeon_ring_write(ring, 0x20); /* poll interval */ 352962306a36Sopenharmony_ci} 353062306a36Sopenharmony_ci 353162306a36Sopenharmony_ci/** 353262306a36Sopenharmony_ci * cik_fence_gfx_ring_emit - emit a fence on the gfx ring 353362306a36Sopenharmony_ci * 353462306a36Sopenharmony_ci * @rdev: radeon_device pointer 353562306a36Sopenharmony_ci * @fence: radeon fence object 353662306a36Sopenharmony_ci * 353762306a36Sopenharmony_ci * Emits a fence sequnce number on the gfx ring and flushes 353862306a36Sopenharmony_ci * GPU caches. 353962306a36Sopenharmony_ci */ 354062306a36Sopenharmony_civoid cik_fence_gfx_ring_emit(struct radeon_device *rdev, 354162306a36Sopenharmony_ci struct radeon_fence *fence) 354262306a36Sopenharmony_ci{ 354362306a36Sopenharmony_ci struct radeon_ring *ring = &rdev->ring[fence->ring]; 354462306a36Sopenharmony_ci u64 addr = rdev->fence_drv[fence->ring].gpu_addr; 354562306a36Sopenharmony_ci 354662306a36Sopenharmony_ci /* Workaround for cache flush problems. First send a dummy EOP 354762306a36Sopenharmony_ci * event down the pipe with seq one below. 354862306a36Sopenharmony_ci */ 354962306a36Sopenharmony_ci radeon_ring_write(ring, PACKET3(PACKET3_EVENT_WRITE_EOP, 4)); 355062306a36Sopenharmony_ci radeon_ring_write(ring, (EOP_TCL1_ACTION_EN | 355162306a36Sopenharmony_ci EOP_TC_ACTION_EN | 355262306a36Sopenharmony_ci EVENT_TYPE(CACHE_FLUSH_AND_INV_TS_EVENT) | 355362306a36Sopenharmony_ci EVENT_INDEX(5))); 355462306a36Sopenharmony_ci radeon_ring_write(ring, addr & 0xfffffffc); 355562306a36Sopenharmony_ci radeon_ring_write(ring, (upper_32_bits(addr) & 0xffff) | 355662306a36Sopenharmony_ci DATA_SEL(1) | INT_SEL(0)); 355762306a36Sopenharmony_ci radeon_ring_write(ring, fence->seq - 1); 355862306a36Sopenharmony_ci radeon_ring_write(ring, 0); 355962306a36Sopenharmony_ci 356062306a36Sopenharmony_ci /* Then send the real EOP event down the pipe. */ 356162306a36Sopenharmony_ci radeon_ring_write(ring, PACKET3(PACKET3_EVENT_WRITE_EOP, 4)); 356262306a36Sopenharmony_ci radeon_ring_write(ring, (EOP_TCL1_ACTION_EN | 356362306a36Sopenharmony_ci EOP_TC_ACTION_EN | 356462306a36Sopenharmony_ci EVENT_TYPE(CACHE_FLUSH_AND_INV_TS_EVENT) | 356562306a36Sopenharmony_ci EVENT_INDEX(5))); 356662306a36Sopenharmony_ci radeon_ring_write(ring, addr & 0xfffffffc); 356762306a36Sopenharmony_ci radeon_ring_write(ring, (upper_32_bits(addr) & 0xffff) | DATA_SEL(1) | INT_SEL(2)); 356862306a36Sopenharmony_ci radeon_ring_write(ring, fence->seq); 356962306a36Sopenharmony_ci radeon_ring_write(ring, 0); 357062306a36Sopenharmony_ci} 357162306a36Sopenharmony_ci 357262306a36Sopenharmony_ci/** 357362306a36Sopenharmony_ci * cik_fence_compute_ring_emit - emit a fence on the compute ring 357462306a36Sopenharmony_ci * 357562306a36Sopenharmony_ci * @rdev: radeon_device pointer 357662306a36Sopenharmony_ci * @fence: radeon fence object 357762306a36Sopenharmony_ci * 357862306a36Sopenharmony_ci * Emits a fence sequnce number on the compute ring and flushes 357962306a36Sopenharmony_ci * GPU caches. 358062306a36Sopenharmony_ci */ 358162306a36Sopenharmony_civoid cik_fence_compute_ring_emit(struct radeon_device *rdev, 358262306a36Sopenharmony_ci struct radeon_fence *fence) 358362306a36Sopenharmony_ci{ 358462306a36Sopenharmony_ci struct radeon_ring *ring = &rdev->ring[fence->ring]; 358562306a36Sopenharmony_ci u64 addr = rdev->fence_drv[fence->ring].gpu_addr; 358662306a36Sopenharmony_ci 358762306a36Sopenharmony_ci /* RELEASE_MEM - flush caches, send int */ 358862306a36Sopenharmony_ci radeon_ring_write(ring, PACKET3(PACKET3_RELEASE_MEM, 5)); 358962306a36Sopenharmony_ci radeon_ring_write(ring, (EOP_TCL1_ACTION_EN | 359062306a36Sopenharmony_ci EOP_TC_ACTION_EN | 359162306a36Sopenharmony_ci EVENT_TYPE(CACHE_FLUSH_AND_INV_TS_EVENT) | 359262306a36Sopenharmony_ci EVENT_INDEX(5))); 359362306a36Sopenharmony_ci radeon_ring_write(ring, DATA_SEL(1) | INT_SEL(2)); 359462306a36Sopenharmony_ci radeon_ring_write(ring, addr & 0xfffffffc); 359562306a36Sopenharmony_ci radeon_ring_write(ring, upper_32_bits(addr)); 359662306a36Sopenharmony_ci radeon_ring_write(ring, fence->seq); 359762306a36Sopenharmony_ci radeon_ring_write(ring, 0); 359862306a36Sopenharmony_ci} 359962306a36Sopenharmony_ci 360062306a36Sopenharmony_ci/** 360162306a36Sopenharmony_ci * cik_semaphore_ring_emit - emit a semaphore on the CP ring 360262306a36Sopenharmony_ci * 360362306a36Sopenharmony_ci * @rdev: radeon_device pointer 360462306a36Sopenharmony_ci * @ring: radeon ring buffer object 360562306a36Sopenharmony_ci * @semaphore: radeon semaphore object 360662306a36Sopenharmony_ci * @emit_wait: Is this a semaphore wait? 360762306a36Sopenharmony_ci * 360862306a36Sopenharmony_ci * Emits a semaphore signal/wait packet to the CP ring and prevents the PFP 360962306a36Sopenharmony_ci * from running ahead of semaphore waits. 361062306a36Sopenharmony_ci */ 361162306a36Sopenharmony_cibool cik_semaphore_ring_emit(struct radeon_device *rdev, 361262306a36Sopenharmony_ci struct radeon_ring *ring, 361362306a36Sopenharmony_ci struct radeon_semaphore *semaphore, 361462306a36Sopenharmony_ci bool emit_wait) 361562306a36Sopenharmony_ci{ 361662306a36Sopenharmony_ci uint64_t addr = semaphore->gpu_addr; 361762306a36Sopenharmony_ci unsigned sel = emit_wait ? PACKET3_SEM_SEL_WAIT : PACKET3_SEM_SEL_SIGNAL; 361862306a36Sopenharmony_ci 361962306a36Sopenharmony_ci radeon_ring_write(ring, PACKET3(PACKET3_MEM_SEMAPHORE, 1)); 362062306a36Sopenharmony_ci radeon_ring_write(ring, lower_32_bits(addr)); 362162306a36Sopenharmony_ci radeon_ring_write(ring, (upper_32_bits(addr) & 0xffff) | sel); 362262306a36Sopenharmony_ci 362362306a36Sopenharmony_ci if (emit_wait && ring->idx == RADEON_RING_TYPE_GFX_INDEX) { 362462306a36Sopenharmony_ci /* Prevent the PFP from running ahead of the semaphore wait */ 362562306a36Sopenharmony_ci radeon_ring_write(ring, PACKET3(PACKET3_PFP_SYNC_ME, 0)); 362662306a36Sopenharmony_ci radeon_ring_write(ring, 0x0); 362762306a36Sopenharmony_ci } 362862306a36Sopenharmony_ci 362962306a36Sopenharmony_ci return true; 363062306a36Sopenharmony_ci} 363162306a36Sopenharmony_ci 363262306a36Sopenharmony_ci/** 363362306a36Sopenharmony_ci * cik_copy_cpdma - copy pages using the CP DMA engine 363462306a36Sopenharmony_ci * 363562306a36Sopenharmony_ci * @rdev: radeon_device pointer 363662306a36Sopenharmony_ci * @src_offset: src GPU address 363762306a36Sopenharmony_ci * @dst_offset: dst GPU address 363862306a36Sopenharmony_ci * @num_gpu_pages: number of GPU pages to xfer 363962306a36Sopenharmony_ci * @resv: reservation object to sync to 364062306a36Sopenharmony_ci * 364162306a36Sopenharmony_ci * Copy GPU paging using the CP DMA engine (CIK+). 364262306a36Sopenharmony_ci * Used by the radeon ttm implementation to move pages if 364362306a36Sopenharmony_ci * registered as the asic copy callback. 364462306a36Sopenharmony_ci */ 364562306a36Sopenharmony_cistruct radeon_fence *cik_copy_cpdma(struct radeon_device *rdev, 364662306a36Sopenharmony_ci uint64_t src_offset, uint64_t dst_offset, 364762306a36Sopenharmony_ci unsigned num_gpu_pages, 364862306a36Sopenharmony_ci struct dma_resv *resv) 364962306a36Sopenharmony_ci{ 365062306a36Sopenharmony_ci struct radeon_fence *fence; 365162306a36Sopenharmony_ci struct radeon_sync sync; 365262306a36Sopenharmony_ci int ring_index = rdev->asic->copy.blit_ring_index; 365362306a36Sopenharmony_ci struct radeon_ring *ring = &rdev->ring[ring_index]; 365462306a36Sopenharmony_ci u32 size_in_bytes, cur_size_in_bytes, control; 365562306a36Sopenharmony_ci int i, num_loops; 365662306a36Sopenharmony_ci int r = 0; 365762306a36Sopenharmony_ci 365862306a36Sopenharmony_ci radeon_sync_create(&sync); 365962306a36Sopenharmony_ci 366062306a36Sopenharmony_ci size_in_bytes = (num_gpu_pages << RADEON_GPU_PAGE_SHIFT); 366162306a36Sopenharmony_ci num_loops = DIV_ROUND_UP(size_in_bytes, 0x1fffff); 366262306a36Sopenharmony_ci r = radeon_ring_lock(rdev, ring, num_loops * 7 + 18); 366362306a36Sopenharmony_ci if (r) { 366462306a36Sopenharmony_ci DRM_ERROR("radeon: moving bo (%d).\n", r); 366562306a36Sopenharmony_ci radeon_sync_free(rdev, &sync, NULL); 366662306a36Sopenharmony_ci return ERR_PTR(r); 366762306a36Sopenharmony_ci } 366862306a36Sopenharmony_ci 366962306a36Sopenharmony_ci radeon_sync_resv(rdev, &sync, resv, false); 367062306a36Sopenharmony_ci radeon_sync_rings(rdev, &sync, ring->idx); 367162306a36Sopenharmony_ci 367262306a36Sopenharmony_ci for (i = 0; i < num_loops; i++) { 367362306a36Sopenharmony_ci cur_size_in_bytes = size_in_bytes; 367462306a36Sopenharmony_ci if (cur_size_in_bytes > 0x1fffff) 367562306a36Sopenharmony_ci cur_size_in_bytes = 0x1fffff; 367662306a36Sopenharmony_ci size_in_bytes -= cur_size_in_bytes; 367762306a36Sopenharmony_ci control = 0; 367862306a36Sopenharmony_ci if (size_in_bytes == 0) 367962306a36Sopenharmony_ci control |= PACKET3_DMA_DATA_CP_SYNC; 368062306a36Sopenharmony_ci radeon_ring_write(ring, PACKET3(PACKET3_DMA_DATA, 5)); 368162306a36Sopenharmony_ci radeon_ring_write(ring, control); 368262306a36Sopenharmony_ci radeon_ring_write(ring, lower_32_bits(src_offset)); 368362306a36Sopenharmony_ci radeon_ring_write(ring, upper_32_bits(src_offset)); 368462306a36Sopenharmony_ci radeon_ring_write(ring, lower_32_bits(dst_offset)); 368562306a36Sopenharmony_ci radeon_ring_write(ring, upper_32_bits(dst_offset)); 368662306a36Sopenharmony_ci radeon_ring_write(ring, cur_size_in_bytes); 368762306a36Sopenharmony_ci src_offset += cur_size_in_bytes; 368862306a36Sopenharmony_ci dst_offset += cur_size_in_bytes; 368962306a36Sopenharmony_ci } 369062306a36Sopenharmony_ci 369162306a36Sopenharmony_ci r = radeon_fence_emit(rdev, &fence, ring->idx); 369262306a36Sopenharmony_ci if (r) { 369362306a36Sopenharmony_ci radeon_ring_unlock_undo(rdev, ring); 369462306a36Sopenharmony_ci radeon_sync_free(rdev, &sync, NULL); 369562306a36Sopenharmony_ci return ERR_PTR(r); 369662306a36Sopenharmony_ci } 369762306a36Sopenharmony_ci 369862306a36Sopenharmony_ci radeon_ring_unlock_commit(rdev, ring, false); 369962306a36Sopenharmony_ci radeon_sync_free(rdev, &sync, fence); 370062306a36Sopenharmony_ci 370162306a36Sopenharmony_ci return fence; 370262306a36Sopenharmony_ci} 370362306a36Sopenharmony_ci 370462306a36Sopenharmony_ci/* 370562306a36Sopenharmony_ci * IB stuff 370662306a36Sopenharmony_ci */ 370762306a36Sopenharmony_ci/** 370862306a36Sopenharmony_ci * cik_ring_ib_execute - emit an IB (Indirect Buffer) on the gfx ring 370962306a36Sopenharmony_ci * 371062306a36Sopenharmony_ci * @rdev: radeon_device pointer 371162306a36Sopenharmony_ci * @ib: radeon indirect buffer object 371262306a36Sopenharmony_ci * 371362306a36Sopenharmony_ci * Emits a DE (drawing engine) or CE (constant engine) IB 371462306a36Sopenharmony_ci * on the gfx ring. IBs are usually generated by userspace 371562306a36Sopenharmony_ci * acceleration drivers and submitted to the kernel for 371662306a36Sopenharmony_ci * scheduling on the ring. This function schedules the IB 371762306a36Sopenharmony_ci * on the gfx ring for execution by the GPU. 371862306a36Sopenharmony_ci */ 371962306a36Sopenharmony_civoid cik_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib) 372062306a36Sopenharmony_ci{ 372162306a36Sopenharmony_ci struct radeon_ring *ring = &rdev->ring[ib->ring]; 372262306a36Sopenharmony_ci unsigned vm_id = ib->vm ? ib->vm->ids[ib->ring].id : 0; 372362306a36Sopenharmony_ci u32 header, control = INDIRECT_BUFFER_VALID; 372462306a36Sopenharmony_ci 372562306a36Sopenharmony_ci if (ib->is_const_ib) { 372662306a36Sopenharmony_ci /* set switch buffer packet before const IB */ 372762306a36Sopenharmony_ci radeon_ring_write(ring, PACKET3(PACKET3_SWITCH_BUFFER, 0)); 372862306a36Sopenharmony_ci radeon_ring_write(ring, 0); 372962306a36Sopenharmony_ci 373062306a36Sopenharmony_ci header = PACKET3(PACKET3_INDIRECT_BUFFER_CONST, 2); 373162306a36Sopenharmony_ci } else { 373262306a36Sopenharmony_ci u32 next_rptr; 373362306a36Sopenharmony_ci if (ring->rptr_save_reg) { 373462306a36Sopenharmony_ci next_rptr = ring->wptr + 3 + 4; 373562306a36Sopenharmony_ci radeon_ring_write(ring, PACKET3(PACKET3_SET_UCONFIG_REG, 1)); 373662306a36Sopenharmony_ci radeon_ring_write(ring, ((ring->rptr_save_reg - 373762306a36Sopenharmony_ci PACKET3_SET_UCONFIG_REG_START) >> 2)); 373862306a36Sopenharmony_ci radeon_ring_write(ring, next_rptr); 373962306a36Sopenharmony_ci } else if (rdev->wb.enabled) { 374062306a36Sopenharmony_ci next_rptr = ring->wptr + 5 + 4; 374162306a36Sopenharmony_ci radeon_ring_write(ring, PACKET3(PACKET3_WRITE_DATA, 3)); 374262306a36Sopenharmony_ci radeon_ring_write(ring, WRITE_DATA_DST_SEL(1)); 374362306a36Sopenharmony_ci radeon_ring_write(ring, ring->next_rptr_gpu_addr & 0xfffffffc); 374462306a36Sopenharmony_ci radeon_ring_write(ring, upper_32_bits(ring->next_rptr_gpu_addr)); 374562306a36Sopenharmony_ci radeon_ring_write(ring, next_rptr); 374662306a36Sopenharmony_ci } 374762306a36Sopenharmony_ci 374862306a36Sopenharmony_ci header = PACKET3(PACKET3_INDIRECT_BUFFER, 2); 374962306a36Sopenharmony_ci } 375062306a36Sopenharmony_ci 375162306a36Sopenharmony_ci control |= ib->length_dw | (vm_id << 24); 375262306a36Sopenharmony_ci 375362306a36Sopenharmony_ci radeon_ring_write(ring, header); 375462306a36Sopenharmony_ci radeon_ring_write(ring, (ib->gpu_addr & 0xFFFFFFFC)); 375562306a36Sopenharmony_ci radeon_ring_write(ring, upper_32_bits(ib->gpu_addr) & 0xFFFF); 375662306a36Sopenharmony_ci radeon_ring_write(ring, control); 375762306a36Sopenharmony_ci} 375862306a36Sopenharmony_ci 375962306a36Sopenharmony_ci/** 376062306a36Sopenharmony_ci * cik_ib_test - basic gfx ring IB test 376162306a36Sopenharmony_ci * 376262306a36Sopenharmony_ci * @rdev: radeon_device pointer 376362306a36Sopenharmony_ci * @ring: radeon_ring structure holding ring information 376462306a36Sopenharmony_ci * 376562306a36Sopenharmony_ci * Allocate an IB and execute it on the gfx ring (CIK). 376662306a36Sopenharmony_ci * Provides a basic gfx ring test to verify that IBs are working. 376762306a36Sopenharmony_ci * Returns 0 on success, error on failure. 376862306a36Sopenharmony_ci */ 376962306a36Sopenharmony_ciint cik_ib_test(struct radeon_device *rdev, struct radeon_ring *ring) 377062306a36Sopenharmony_ci{ 377162306a36Sopenharmony_ci struct radeon_ib ib; 377262306a36Sopenharmony_ci uint32_t scratch; 377362306a36Sopenharmony_ci uint32_t tmp = 0; 377462306a36Sopenharmony_ci unsigned i; 377562306a36Sopenharmony_ci int r; 377662306a36Sopenharmony_ci 377762306a36Sopenharmony_ci r = radeon_scratch_get(rdev, &scratch); 377862306a36Sopenharmony_ci if (r) { 377962306a36Sopenharmony_ci DRM_ERROR("radeon: failed to get scratch reg (%d).\n", r); 378062306a36Sopenharmony_ci return r; 378162306a36Sopenharmony_ci } 378262306a36Sopenharmony_ci WREG32(scratch, 0xCAFEDEAD); 378362306a36Sopenharmony_ci r = radeon_ib_get(rdev, ring->idx, &ib, NULL, 256); 378462306a36Sopenharmony_ci if (r) { 378562306a36Sopenharmony_ci DRM_ERROR("radeon: failed to get ib (%d).\n", r); 378662306a36Sopenharmony_ci radeon_scratch_free(rdev, scratch); 378762306a36Sopenharmony_ci return r; 378862306a36Sopenharmony_ci } 378962306a36Sopenharmony_ci ib.ptr[0] = PACKET3(PACKET3_SET_UCONFIG_REG, 1); 379062306a36Sopenharmony_ci ib.ptr[1] = ((scratch - PACKET3_SET_UCONFIG_REG_START) >> 2); 379162306a36Sopenharmony_ci ib.ptr[2] = 0xDEADBEEF; 379262306a36Sopenharmony_ci ib.length_dw = 3; 379362306a36Sopenharmony_ci r = radeon_ib_schedule(rdev, &ib, NULL, false); 379462306a36Sopenharmony_ci if (r) { 379562306a36Sopenharmony_ci radeon_scratch_free(rdev, scratch); 379662306a36Sopenharmony_ci radeon_ib_free(rdev, &ib); 379762306a36Sopenharmony_ci DRM_ERROR("radeon: failed to schedule ib (%d).\n", r); 379862306a36Sopenharmony_ci return r; 379962306a36Sopenharmony_ci } 380062306a36Sopenharmony_ci r = radeon_fence_wait_timeout(ib.fence, false, usecs_to_jiffies( 380162306a36Sopenharmony_ci RADEON_USEC_IB_TEST_TIMEOUT)); 380262306a36Sopenharmony_ci if (r < 0) { 380362306a36Sopenharmony_ci DRM_ERROR("radeon: fence wait failed (%d).\n", r); 380462306a36Sopenharmony_ci radeon_scratch_free(rdev, scratch); 380562306a36Sopenharmony_ci radeon_ib_free(rdev, &ib); 380662306a36Sopenharmony_ci return r; 380762306a36Sopenharmony_ci } else if (r == 0) { 380862306a36Sopenharmony_ci DRM_ERROR("radeon: fence wait timed out.\n"); 380962306a36Sopenharmony_ci radeon_scratch_free(rdev, scratch); 381062306a36Sopenharmony_ci radeon_ib_free(rdev, &ib); 381162306a36Sopenharmony_ci return -ETIMEDOUT; 381262306a36Sopenharmony_ci } 381362306a36Sopenharmony_ci r = 0; 381462306a36Sopenharmony_ci for (i = 0; i < rdev->usec_timeout; i++) { 381562306a36Sopenharmony_ci tmp = RREG32(scratch); 381662306a36Sopenharmony_ci if (tmp == 0xDEADBEEF) 381762306a36Sopenharmony_ci break; 381862306a36Sopenharmony_ci udelay(1); 381962306a36Sopenharmony_ci } 382062306a36Sopenharmony_ci if (i < rdev->usec_timeout) { 382162306a36Sopenharmony_ci DRM_INFO("ib test on ring %d succeeded in %u usecs\n", ib.fence->ring, i); 382262306a36Sopenharmony_ci } else { 382362306a36Sopenharmony_ci DRM_ERROR("radeon: ib test failed (scratch(0x%04X)=0x%08X)\n", 382462306a36Sopenharmony_ci scratch, tmp); 382562306a36Sopenharmony_ci r = -EINVAL; 382662306a36Sopenharmony_ci } 382762306a36Sopenharmony_ci radeon_scratch_free(rdev, scratch); 382862306a36Sopenharmony_ci radeon_ib_free(rdev, &ib); 382962306a36Sopenharmony_ci return r; 383062306a36Sopenharmony_ci} 383162306a36Sopenharmony_ci 383262306a36Sopenharmony_ci/* 383362306a36Sopenharmony_ci * CP. 383462306a36Sopenharmony_ci * On CIK, gfx and compute now have independant command processors. 383562306a36Sopenharmony_ci * 383662306a36Sopenharmony_ci * GFX 383762306a36Sopenharmony_ci * Gfx consists of a single ring and can process both gfx jobs and 383862306a36Sopenharmony_ci * compute jobs. The gfx CP consists of three microengines (ME): 383962306a36Sopenharmony_ci * PFP - Pre-Fetch Parser 384062306a36Sopenharmony_ci * ME - Micro Engine 384162306a36Sopenharmony_ci * CE - Constant Engine 384262306a36Sopenharmony_ci * The PFP and ME make up what is considered the Drawing Engine (DE). 384362306a36Sopenharmony_ci * The CE is an asynchronous engine used for updating buffer desciptors 384462306a36Sopenharmony_ci * used by the DE so that they can be loaded into cache in parallel 384562306a36Sopenharmony_ci * while the DE is processing state update packets. 384662306a36Sopenharmony_ci * 384762306a36Sopenharmony_ci * Compute 384862306a36Sopenharmony_ci * The compute CP consists of two microengines (ME): 384962306a36Sopenharmony_ci * MEC1 - Compute MicroEngine 1 385062306a36Sopenharmony_ci * MEC2 - Compute MicroEngine 2 385162306a36Sopenharmony_ci * Each MEC supports 4 compute pipes and each pipe supports 8 queues. 385262306a36Sopenharmony_ci * The queues are exposed to userspace and are programmed directly 385362306a36Sopenharmony_ci * by the compute runtime. 385462306a36Sopenharmony_ci */ 385562306a36Sopenharmony_ci/** 385662306a36Sopenharmony_ci * cik_cp_gfx_enable - enable/disable the gfx CP MEs 385762306a36Sopenharmony_ci * 385862306a36Sopenharmony_ci * @rdev: radeon_device pointer 385962306a36Sopenharmony_ci * @enable: enable or disable the MEs 386062306a36Sopenharmony_ci * 386162306a36Sopenharmony_ci * Halts or unhalts the gfx MEs. 386262306a36Sopenharmony_ci */ 386362306a36Sopenharmony_cistatic void cik_cp_gfx_enable(struct radeon_device *rdev, bool enable) 386462306a36Sopenharmony_ci{ 386562306a36Sopenharmony_ci if (enable) 386662306a36Sopenharmony_ci WREG32(CP_ME_CNTL, 0); 386762306a36Sopenharmony_ci else { 386862306a36Sopenharmony_ci if (rdev->asic->copy.copy_ring_index == RADEON_RING_TYPE_GFX_INDEX) 386962306a36Sopenharmony_ci radeon_ttm_set_active_vram_size(rdev, rdev->mc.visible_vram_size); 387062306a36Sopenharmony_ci WREG32(CP_ME_CNTL, (CP_ME_HALT | CP_PFP_HALT | CP_CE_HALT)); 387162306a36Sopenharmony_ci rdev->ring[RADEON_RING_TYPE_GFX_INDEX].ready = false; 387262306a36Sopenharmony_ci } 387362306a36Sopenharmony_ci udelay(50); 387462306a36Sopenharmony_ci} 387562306a36Sopenharmony_ci 387662306a36Sopenharmony_ci/** 387762306a36Sopenharmony_ci * cik_cp_gfx_load_microcode - load the gfx CP ME ucode 387862306a36Sopenharmony_ci * 387962306a36Sopenharmony_ci * @rdev: radeon_device pointer 388062306a36Sopenharmony_ci * 388162306a36Sopenharmony_ci * Loads the gfx PFP, ME, and CE ucode. 388262306a36Sopenharmony_ci * Returns 0 for success, -EINVAL if the ucode is not available. 388362306a36Sopenharmony_ci */ 388462306a36Sopenharmony_cistatic int cik_cp_gfx_load_microcode(struct radeon_device *rdev) 388562306a36Sopenharmony_ci{ 388662306a36Sopenharmony_ci int i; 388762306a36Sopenharmony_ci 388862306a36Sopenharmony_ci if (!rdev->me_fw || !rdev->pfp_fw || !rdev->ce_fw) 388962306a36Sopenharmony_ci return -EINVAL; 389062306a36Sopenharmony_ci 389162306a36Sopenharmony_ci cik_cp_gfx_enable(rdev, false); 389262306a36Sopenharmony_ci 389362306a36Sopenharmony_ci if (rdev->new_fw) { 389462306a36Sopenharmony_ci const struct gfx_firmware_header_v1_0 *pfp_hdr = 389562306a36Sopenharmony_ci (const struct gfx_firmware_header_v1_0 *)rdev->pfp_fw->data; 389662306a36Sopenharmony_ci const struct gfx_firmware_header_v1_0 *ce_hdr = 389762306a36Sopenharmony_ci (const struct gfx_firmware_header_v1_0 *)rdev->ce_fw->data; 389862306a36Sopenharmony_ci const struct gfx_firmware_header_v1_0 *me_hdr = 389962306a36Sopenharmony_ci (const struct gfx_firmware_header_v1_0 *)rdev->me_fw->data; 390062306a36Sopenharmony_ci const __le32 *fw_data; 390162306a36Sopenharmony_ci u32 fw_size; 390262306a36Sopenharmony_ci 390362306a36Sopenharmony_ci radeon_ucode_print_gfx_hdr(&pfp_hdr->header); 390462306a36Sopenharmony_ci radeon_ucode_print_gfx_hdr(&ce_hdr->header); 390562306a36Sopenharmony_ci radeon_ucode_print_gfx_hdr(&me_hdr->header); 390662306a36Sopenharmony_ci 390762306a36Sopenharmony_ci /* PFP */ 390862306a36Sopenharmony_ci fw_data = (const __le32 *) 390962306a36Sopenharmony_ci (rdev->pfp_fw->data + le32_to_cpu(pfp_hdr->header.ucode_array_offset_bytes)); 391062306a36Sopenharmony_ci fw_size = le32_to_cpu(pfp_hdr->header.ucode_size_bytes) / 4; 391162306a36Sopenharmony_ci WREG32(CP_PFP_UCODE_ADDR, 0); 391262306a36Sopenharmony_ci for (i = 0; i < fw_size; i++) 391362306a36Sopenharmony_ci WREG32(CP_PFP_UCODE_DATA, le32_to_cpup(fw_data++)); 391462306a36Sopenharmony_ci WREG32(CP_PFP_UCODE_ADDR, le32_to_cpu(pfp_hdr->header.ucode_version)); 391562306a36Sopenharmony_ci 391662306a36Sopenharmony_ci /* CE */ 391762306a36Sopenharmony_ci fw_data = (const __le32 *) 391862306a36Sopenharmony_ci (rdev->ce_fw->data + le32_to_cpu(ce_hdr->header.ucode_array_offset_bytes)); 391962306a36Sopenharmony_ci fw_size = le32_to_cpu(ce_hdr->header.ucode_size_bytes) / 4; 392062306a36Sopenharmony_ci WREG32(CP_CE_UCODE_ADDR, 0); 392162306a36Sopenharmony_ci for (i = 0; i < fw_size; i++) 392262306a36Sopenharmony_ci WREG32(CP_CE_UCODE_DATA, le32_to_cpup(fw_data++)); 392362306a36Sopenharmony_ci WREG32(CP_CE_UCODE_ADDR, le32_to_cpu(ce_hdr->header.ucode_version)); 392462306a36Sopenharmony_ci 392562306a36Sopenharmony_ci /* ME */ 392662306a36Sopenharmony_ci fw_data = (const __be32 *) 392762306a36Sopenharmony_ci (rdev->me_fw->data + le32_to_cpu(me_hdr->header.ucode_array_offset_bytes)); 392862306a36Sopenharmony_ci fw_size = le32_to_cpu(me_hdr->header.ucode_size_bytes) / 4; 392962306a36Sopenharmony_ci WREG32(CP_ME_RAM_WADDR, 0); 393062306a36Sopenharmony_ci for (i = 0; i < fw_size; i++) 393162306a36Sopenharmony_ci WREG32(CP_ME_RAM_DATA, le32_to_cpup(fw_data++)); 393262306a36Sopenharmony_ci WREG32(CP_ME_RAM_WADDR, le32_to_cpu(me_hdr->header.ucode_version)); 393362306a36Sopenharmony_ci WREG32(CP_ME_RAM_RADDR, le32_to_cpu(me_hdr->header.ucode_version)); 393462306a36Sopenharmony_ci } else { 393562306a36Sopenharmony_ci const __be32 *fw_data; 393662306a36Sopenharmony_ci 393762306a36Sopenharmony_ci /* PFP */ 393862306a36Sopenharmony_ci fw_data = (const __be32 *)rdev->pfp_fw->data; 393962306a36Sopenharmony_ci WREG32(CP_PFP_UCODE_ADDR, 0); 394062306a36Sopenharmony_ci for (i = 0; i < CIK_PFP_UCODE_SIZE; i++) 394162306a36Sopenharmony_ci WREG32(CP_PFP_UCODE_DATA, be32_to_cpup(fw_data++)); 394262306a36Sopenharmony_ci WREG32(CP_PFP_UCODE_ADDR, 0); 394362306a36Sopenharmony_ci 394462306a36Sopenharmony_ci /* CE */ 394562306a36Sopenharmony_ci fw_data = (const __be32 *)rdev->ce_fw->data; 394662306a36Sopenharmony_ci WREG32(CP_CE_UCODE_ADDR, 0); 394762306a36Sopenharmony_ci for (i = 0; i < CIK_CE_UCODE_SIZE; i++) 394862306a36Sopenharmony_ci WREG32(CP_CE_UCODE_DATA, be32_to_cpup(fw_data++)); 394962306a36Sopenharmony_ci WREG32(CP_CE_UCODE_ADDR, 0); 395062306a36Sopenharmony_ci 395162306a36Sopenharmony_ci /* ME */ 395262306a36Sopenharmony_ci fw_data = (const __be32 *)rdev->me_fw->data; 395362306a36Sopenharmony_ci WREG32(CP_ME_RAM_WADDR, 0); 395462306a36Sopenharmony_ci for (i = 0; i < CIK_ME_UCODE_SIZE; i++) 395562306a36Sopenharmony_ci WREG32(CP_ME_RAM_DATA, be32_to_cpup(fw_data++)); 395662306a36Sopenharmony_ci WREG32(CP_ME_RAM_WADDR, 0); 395762306a36Sopenharmony_ci } 395862306a36Sopenharmony_ci 395962306a36Sopenharmony_ci return 0; 396062306a36Sopenharmony_ci} 396162306a36Sopenharmony_ci 396262306a36Sopenharmony_ci/** 396362306a36Sopenharmony_ci * cik_cp_gfx_start - start the gfx ring 396462306a36Sopenharmony_ci * 396562306a36Sopenharmony_ci * @rdev: radeon_device pointer 396662306a36Sopenharmony_ci * 396762306a36Sopenharmony_ci * Enables the ring and loads the clear state context and other 396862306a36Sopenharmony_ci * packets required to init the ring. 396962306a36Sopenharmony_ci * Returns 0 for success, error for failure. 397062306a36Sopenharmony_ci */ 397162306a36Sopenharmony_cistatic int cik_cp_gfx_start(struct radeon_device *rdev) 397262306a36Sopenharmony_ci{ 397362306a36Sopenharmony_ci struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]; 397462306a36Sopenharmony_ci int r, i; 397562306a36Sopenharmony_ci 397662306a36Sopenharmony_ci /* init the CP */ 397762306a36Sopenharmony_ci WREG32(CP_MAX_CONTEXT, rdev->config.cik.max_hw_contexts - 1); 397862306a36Sopenharmony_ci WREG32(CP_ENDIAN_SWAP, 0); 397962306a36Sopenharmony_ci WREG32(CP_DEVICE_ID, 1); 398062306a36Sopenharmony_ci 398162306a36Sopenharmony_ci cik_cp_gfx_enable(rdev, true); 398262306a36Sopenharmony_ci 398362306a36Sopenharmony_ci r = radeon_ring_lock(rdev, ring, cik_default_size + 17); 398462306a36Sopenharmony_ci if (r) { 398562306a36Sopenharmony_ci DRM_ERROR("radeon: cp failed to lock ring (%d).\n", r); 398662306a36Sopenharmony_ci return r; 398762306a36Sopenharmony_ci } 398862306a36Sopenharmony_ci 398962306a36Sopenharmony_ci /* init the CE partitions. CE only used for gfx on CIK */ 399062306a36Sopenharmony_ci radeon_ring_write(ring, PACKET3(PACKET3_SET_BASE, 2)); 399162306a36Sopenharmony_ci radeon_ring_write(ring, PACKET3_BASE_INDEX(CE_PARTITION_BASE)); 399262306a36Sopenharmony_ci radeon_ring_write(ring, 0x8000); 399362306a36Sopenharmony_ci radeon_ring_write(ring, 0x8000); 399462306a36Sopenharmony_ci 399562306a36Sopenharmony_ci /* setup clear context state */ 399662306a36Sopenharmony_ci radeon_ring_write(ring, PACKET3(PACKET3_PREAMBLE_CNTL, 0)); 399762306a36Sopenharmony_ci radeon_ring_write(ring, PACKET3_PREAMBLE_BEGIN_CLEAR_STATE); 399862306a36Sopenharmony_ci 399962306a36Sopenharmony_ci radeon_ring_write(ring, PACKET3(PACKET3_CONTEXT_CONTROL, 1)); 400062306a36Sopenharmony_ci radeon_ring_write(ring, 0x80000000); 400162306a36Sopenharmony_ci radeon_ring_write(ring, 0x80000000); 400262306a36Sopenharmony_ci 400362306a36Sopenharmony_ci for (i = 0; i < cik_default_size; i++) 400462306a36Sopenharmony_ci radeon_ring_write(ring, cik_default_state[i]); 400562306a36Sopenharmony_ci 400662306a36Sopenharmony_ci radeon_ring_write(ring, PACKET3(PACKET3_PREAMBLE_CNTL, 0)); 400762306a36Sopenharmony_ci radeon_ring_write(ring, PACKET3_PREAMBLE_END_CLEAR_STATE); 400862306a36Sopenharmony_ci 400962306a36Sopenharmony_ci /* set clear context state */ 401062306a36Sopenharmony_ci radeon_ring_write(ring, PACKET3(PACKET3_CLEAR_STATE, 0)); 401162306a36Sopenharmony_ci radeon_ring_write(ring, 0); 401262306a36Sopenharmony_ci 401362306a36Sopenharmony_ci radeon_ring_write(ring, PACKET3(PACKET3_SET_CONTEXT_REG, 2)); 401462306a36Sopenharmony_ci radeon_ring_write(ring, 0x00000316); 401562306a36Sopenharmony_ci radeon_ring_write(ring, 0x0000000e); /* VGT_VERTEX_REUSE_BLOCK_CNTL */ 401662306a36Sopenharmony_ci radeon_ring_write(ring, 0x00000010); /* VGT_OUT_DEALLOC_CNTL */ 401762306a36Sopenharmony_ci 401862306a36Sopenharmony_ci radeon_ring_unlock_commit(rdev, ring, false); 401962306a36Sopenharmony_ci 402062306a36Sopenharmony_ci return 0; 402162306a36Sopenharmony_ci} 402262306a36Sopenharmony_ci 402362306a36Sopenharmony_ci/** 402462306a36Sopenharmony_ci * cik_cp_gfx_fini - stop the gfx ring 402562306a36Sopenharmony_ci * 402662306a36Sopenharmony_ci * @rdev: radeon_device pointer 402762306a36Sopenharmony_ci * 402862306a36Sopenharmony_ci * Stop the gfx ring and tear down the driver ring 402962306a36Sopenharmony_ci * info. 403062306a36Sopenharmony_ci */ 403162306a36Sopenharmony_cistatic void cik_cp_gfx_fini(struct radeon_device *rdev) 403262306a36Sopenharmony_ci{ 403362306a36Sopenharmony_ci cik_cp_gfx_enable(rdev, false); 403462306a36Sopenharmony_ci radeon_ring_fini(rdev, &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]); 403562306a36Sopenharmony_ci} 403662306a36Sopenharmony_ci 403762306a36Sopenharmony_ci/** 403862306a36Sopenharmony_ci * cik_cp_gfx_resume - setup the gfx ring buffer registers 403962306a36Sopenharmony_ci * 404062306a36Sopenharmony_ci * @rdev: radeon_device pointer 404162306a36Sopenharmony_ci * 404262306a36Sopenharmony_ci * Program the location and size of the gfx ring buffer 404362306a36Sopenharmony_ci * and test it to make sure it's working. 404462306a36Sopenharmony_ci * Returns 0 for success, error for failure. 404562306a36Sopenharmony_ci */ 404662306a36Sopenharmony_cistatic int cik_cp_gfx_resume(struct radeon_device *rdev) 404762306a36Sopenharmony_ci{ 404862306a36Sopenharmony_ci struct radeon_ring *ring; 404962306a36Sopenharmony_ci u32 tmp; 405062306a36Sopenharmony_ci u32 rb_bufsz; 405162306a36Sopenharmony_ci u64 rb_addr; 405262306a36Sopenharmony_ci int r; 405362306a36Sopenharmony_ci 405462306a36Sopenharmony_ci WREG32(CP_SEM_WAIT_TIMER, 0x0); 405562306a36Sopenharmony_ci if (rdev->family != CHIP_HAWAII) 405662306a36Sopenharmony_ci WREG32(CP_SEM_INCOMPLETE_TIMER_CNTL, 0x0); 405762306a36Sopenharmony_ci 405862306a36Sopenharmony_ci /* Set the write pointer delay */ 405962306a36Sopenharmony_ci WREG32(CP_RB_WPTR_DELAY, 0); 406062306a36Sopenharmony_ci 406162306a36Sopenharmony_ci /* set the RB to use vmid 0 */ 406262306a36Sopenharmony_ci WREG32(CP_RB_VMID, 0); 406362306a36Sopenharmony_ci 406462306a36Sopenharmony_ci WREG32(SCRATCH_ADDR, ((rdev->wb.gpu_addr + RADEON_WB_SCRATCH_OFFSET) >> 8) & 0xFFFFFFFF); 406562306a36Sopenharmony_ci 406662306a36Sopenharmony_ci /* ring 0 - compute and gfx */ 406762306a36Sopenharmony_ci /* Set ring buffer size */ 406862306a36Sopenharmony_ci ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]; 406962306a36Sopenharmony_ci rb_bufsz = order_base_2(ring->ring_size / 8); 407062306a36Sopenharmony_ci tmp = (order_base_2(RADEON_GPU_PAGE_SIZE/8) << 8) | rb_bufsz; 407162306a36Sopenharmony_ci#ifdef __BIG_ENDIAN 407262306a36Sopenharmony_ci tmp |= BUF_SWAP_32BIT; 407362306a36Sopenharmony_ci#endif 407462306a36Sopenharmony_ci WREG32(CP_RB0_CNTL, tmp); 407562306a36Sopenharmony_ci 407662306a36Sopenharmony_ci /* Initialize the ring buffer's read and write pointers */ 407762306a36Sopenharmony_ci WREG32(CP_RB0_CNTL, tmp | RB_RPTR_WR_ENA); 407862306a36Sopenharmony_ci ring->wptr = 0; 407962306a36Sopenharmony_ci WREG32(CP_RB0_WPTR, ring->wptr); 408062306a36Sopenharmony_ci 408162306a36Sopenharmony_ci /* set the wb address wether it's enabled or not */ 408262306a36Sopenharmony_ci WREG32(CP_RB0_RPTR_ADDR, (rdev->wb.gpu_addr + RADEON_WB_CP_RPTR_OFFSET) & 0xFFFFFFFC); 408362306a36Sopenharmony_ci WREG32(CP_RB0_RPTR_ADDR_HI, upper_32_bits(rdev->wb.gpu_addr + RADEON_WB_CP_RPTR_OFFSET) & 0xFF); 408462306a36Sopenharmony_ci 408562306a36Sopenharmony_ci /* scratch register shadowing is no longer supported */ 408662306a36Sopenharmony_ci WREG32(SCRATCH_UMSK, 0); 408762306a36Sopenharmony_ci 408862306a36Sopenharmony_ci if (!rdev->wb.enabled) 408962306a36Sopenharmony_ci tmp |= RB_NO_UPDATE; 409062306a36Sopenharmony_ci 409162306a36Sopenharmony_ci mdelay(1); 409262306a36Sopenharmony_ci WREG32(CP_RB0_CNTL, tmp); 409362306a36Sopenharmony_ci 409462306a36Sopenharmony_ci rb_addr = ring->gpu_addr >> 8; 409562306a36Sopenharmony_ci WREG32(CP_RB0_BASE, rb_addr); 409662306a36Sopenharmony_ci WREG32(CP_RB0_BASE_HI, upper_32_bits(rb_addr)); 409762306a36Sopenharmony_ci 409862306a36Sopenharmony_ci /* start the ring */ 409962306a36Sopenharmony_ci cik_cp_gfx_start(rdev); 410062306a36Sopenharmony_ci rdev->ring[RADEON_RING_TYPE_GFX_INDEX].ready = true; 410162306a36Sopenharmony_ci r = radeon_ring_test(rdev, RADEON_RING_TYPE_GFX_INDEX, &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]); 410262306a36Sopenharmony_ci if (r) { 410362306a36Sopenharmony_ci rdev->ring[RADEON_RING_TYPE_GFX_INDEX].ready = false; 410462306a36Sopenharmony_ci return r; 410562306a36Sopenharmony_ci } 410662306a36Sopenharmony_ci 410762306a36Sopenharmony_ci if (rdev->asic->copy.copy_ring_index == RADEON_RING_TYPE_GFX_INDEX) 410862306a36Sopenharmony_ci radeon_ttm_set_active_vram_size(rdev, rdev->mc.real_vram_size); 410962306a36Sopenharmony_ci 411062306a36Sopenharmony_ci return 0; 411162306a36Sopenharmony_ci} 411262306a36Sopenharmony_ci 411362306a36Sopenharmony_ciu32 cik_gfx_get_rptr(struct radeon_device *rdev, 411462306a36Sopenharmony_ci struct radeon_ring *ring) 411562306a36Sopenharmony_ci{ 411662306a36Sopenharmony_ci u32 rptr; 411762306a36Sopenharmony_ci 411862306a36Sopenharmony_ci if (rdev->wb.enabled) 411962306a36Sopenharmony_ci rptr = rdev->wb.wb[ring->rptr_offs/4]; 412062306a36Sopenharmony_ci else 412162306a36Sopenharmony_ci rptr = RREG32(CP_RB0_RPTR); 412262306a36Sopenharmony_ci 412362306a36Sopenharmony_ci return rptr; 412462306a36Sopenharmony_ci} 412562306a36Sopenharmony_ci 412662306a36Sopenharmony_ciu32 cik_gfx_get_wptr(struct radeon_device *rdev, 412762306a36Sopenharmony_ci struct radeon_ring *ring) 412862306a36Sopenharmony_ci{ 412962306a36Sopenharmony_ci return RREG32(CP_RB0_WPTR); 413062306a36Sopenharmony_ci} 413162306a36Sopenharmony_ci 413262306a36Sopenharmony_civoid cik_gfx_set_wptr(struct radeon_device *rdev, 413362306a36Sopenharmony_ci struct radeon_ring *ring) 413462306a36Sopenharmony_ci{ 413562306a36Sopenharmony_ci WREG32(CP_RB0_WPTR, ring->wptr); 413662306a36Sopenharmony_ci (void)RREG32(CP_RB0_WPTR); 413762306a36Sopenharmony_ci} 413862306a36Sopenharmony_ci 413962306a36Sopenharmony_ciu32 cik_compute_get_rptr(struct radeon_device *rdev, 414062306a36Sopenharmony_ci struct radeon_ring *ring) 414162306a36Sopenharmony_ci{ 414262306a36Sopenharmony_ci u32 rptr; 414362306a36Sopenharmony_ci 414462306a36Sopenharmony_ci if (rdev->wb.enabled) { 414562306a36Sopenharmony_ci rptr = rdev->wb.wb[ring->rptr_offs/4]; 414662306a36Sopenharmony_ci } else { 414762306a36Sopenharmony_ci mutex_lock(&rdev->srbm_mutex); 414862306a36Sopenharmony_ci cik_srbm_select(rdev, ring->me, ring->pipe, ring->queue, 0); 414962306a36Sopenharmony_ci rptr = RREG32(CP_HQD_PQ_RPTR); 415062306a36Sopenharmony_ci cik_srbm_select(rdev, 0, 0, 0, 0); 415162306a36Sopenharmony_ci mutex_unlock(&rdev->srbm_mutex); 415262306a36Sopenharmony_ci } 415362306a36Sopenharmony_ci 415462306a36Sopenharmony_ci return rptr; 415562306a36Sopenharmony_ci} 415662306a36Sopenharmony_ci 415762306a36Sopenharmony_ciu32 cik_compute_get_wptr(struct radeon_device *rdev, 415862306a36Sopenharmony_ci struct radeon_ring *ring) 415962306a36Sopenharmony_ci{ 416062306a36Sopenharmony_ci u32 wptr; 416162306a36Sopenharmony_ci 416262306a36Sopenharmony_ci if (rdev->wb.enabled) { 416362306a36Sopenharmony_ci /* XXX check if swapping is necessary on BE */ 416462306a36Sopenharmony_ci wptr = rdev->wb.wb[ring->wptr_offs/4]; 416562306a36Sopenharmony_ci } else { 416662306a36Sopenharmony_ci mutex_lock(&rdev->srbm_mutex); 416762306a36Sopenharmony_ci cik_srbm_select(rdev, ring->me, ring->pipe, ring->queue, 0); 416862306a36Sopenharmony_ci wptr = RREG32(CP_HQD_PQ_WPTR); 416962306a36Sopenharmony_ci cik_srbm_select(rdev, 0, 0, 0, 0); 417062306a36Sopenharmony_ci mutex_unlock(&rdev->srbm_mutex); 417162306a36Sopenharmony_ci } 417262306a36Sopenharmony_ci 417362306a36Sopenharmony_ci return wptr; 417462306a36Sopenharmony_ci} 417562306a36Sopenharmony_ci 417662306a36Sopenharmony_civoid cik_compute_set_wptr(struct radeon_device *rdev, 417762306a36Sopenharmony_ci struct radeon_ring *ring) 417862306a36Sopenharmony_ci{ 417962306a36Sopenharmony_ci /* XXX check if swapping is necessary on BE */ 418062306a36Sopenharmony_ci rdev->wb.wb[ring->wptr_offs/4] = ring->wptr; 418162306a36Sopenharmony_ci WDOORBELL32(ring->doorbell_index, ring->wptr); 418262306a36Sopenharmony_ci} 418362306a36Sopenharmony_ci 418462306a36Sopenharmony_cistatic void cik_compute_stop(struct radeon_device *rdev, 418562306a36Sopenharmony_ci struct radeon_ring *ring) 418662306a36Sopenharmony_ci{ 418762306a36Sopenharmony_ci u32 j, tmp; 418862306a36Sopenharmony_ci 418962306a36Sopenharmony_ci cik_srbm_select(rdev, ring->me, ring->pipe, ring->queue, 0); 419062306a36Sopenharmony_ci /* Disable wptr polling. */ 419162306a36Sopenharmony_ci tmp = RREG32(CP_PQ_WPTR_POLL_CNTL); 419262306a36Sopenharmony_ci tmp &= ~WPTR_POLL_EN; 419362306a36Sopenharmony_ci WREG32(CP_PQ_WPTR_POLL_CNTL, tmp); 419462306a36Sopenharmony_ci /* Disable HQD. */ 419562306a36Sopenharmony_ci if (RREG32(CP_HQD_ACTIVE) & 1) { 419662306a36Sopenharmony_ci WREG32(CP_HQD_DEQUEUE_REQUEST, 1); 419762306a36Sopenharmony_ci for (j = 0; j < rdev->usec_timeout; j++) { 419862306a36Sopenharmony_ci if (!(RREG32(CP_HQD_ACTIVE) & 1)) 419962306a36Sopenharmony_ci break; 420062306a36Sopenharmony_ci udelay(1); 420162306a36Sopenharmony_ci } 420262306a36Sopenharmony_ci WREG32(CP_HQD_DEQUEUE_REQUEST, 0); 420362306a36Sopenharmony_ci WREG32(CP_HQD_PQ_RPTR, 0); 420462306a36Sopenharmony_ci WREG32(CP_HQD_PQ_WPTR, 0); 420562306a36Sopenharmony_ci } 420662306a36Sopenharmony_ci cik_srbm_select(rdev, 0, 0, 0, 0); 420762306a36Sopenharmony_ci} 420862306a36Sopenharmony_ci 420962306a36Sopenharmony_ci/** 421062306a36Sopenharmony_ci * cik_cp_compute_enable - enable/disable the compute CP MEs 421162306a36Sopenharmony_ci * 421262306a36Sopenharmony_ci * @rdev: radeon_device pointer 421362306a36Sopenharmony_ci * @enable: enable or disable the MEs 421462306a36Sopenharmony_ci * 421562306a36Sopenharmony_ci * Halts or unhalts the compute MEs. 421662306a36Sopenharmony_ci */ 421762306a36Sopenharmony_cistatic void cik_cp_compute_enable(struct radeon_device *rdev, bool enable) 421862306a36Sopenharmony_ci{ 421962306a36Sopenharmony_ci if (enable) 422062306a36Sopenharmony_ci WREG32(CP_MEC_CNTL, 0); 422162306a36Sopenharmony_ci else { 422262306a36Sopenharmony_ci /* 422362306a36Sopenharmony_ci * To make hibernation reliable we need to clear compute ring 422462306a36Sopenharmony_ci * configuration before halting the compute ring. 422562306a36Sopenharmony_ci */ 422662306a36Sopenharmony_ci mutex_lock(&rdev->srbm_mutex); 422762306a36Sopenharmony_ci cik_compute_stop(rdev,&rdev->ring[CAYMAN_RING_TYPE_CP1_INDEX]); 422862306a36Sopenharmony_ci cik_compute_stop(rdev,&rdev->ring[CAYMAN_RING_TYPE_CP2_INDEX]); 422962306a36Sopenharmony_ci mutex_unlock(&rdev->srbm_mutex); 423062306a36Sopenharmony_ci 423162306a36Sopenharmony_ci WREG32(CP_MEC_CNTL, (MEC_ME1_HALT | MEC_ME2_HALT)); 423262306a36Sopenharmony_ci rdev->ring[CAYMAN_RING_TYPE_CP1_INDEX].ready = false; 423362306a36Sopenharmony_ci rdev->ring[CAYMAN_RING_TYPE_CP2_INDEX].ready = false; 423462306a36Sopenharmony_ci } 423562306a36Sopenharmony_ci udelay(50); 423662306a36Sopenharmony_ci} 423762306a36Sopenharmony_ci 423862306a36Sopenharmony_ci/** 423962306a36Sopenharmony_ci * cik_cp_compute_load_microcode - load the compute CP ME ucode 424062306a36Sopenharmony_ci * 424162306a36Sopenharmony_ci * @rdev: radeon_device pointer 424262306a36Sopenharmony_ci * 424362306a36Sopenharmony_ci * Loads the compute MEC1&2 ucode. 424462306a36Sopenharmony_ci * Returns 0 for success, -EINVAL if the ucode is not available. 424562306a36Sopenharmony_ci */ 424662306a36Sopenharmony_cistatic int cik_cp_compute_load_microcode(struct radeon_device *rdev) 424762306a36Sopenharmony_ci{ 424862306a36Sopenharmony_ci int i; 424962306a36Sopenharmony_ci 425062306a36Sopenharmony_ci if (!rdev->mec_fw) 425162306a36Sopenharmony_ci return -EINVAL; 425262306a36Sopenharmony_ci 425362306a36Sopenharmony_ci cik_cp_compute_enable(rdev, false); 425462306a36Sopenharmony_ci 425562306a36Sopenharmony_ci if (rdev->new_fw) { 425662306a36Sopenharmony_ci const struct gfx_firmware_header_v1_0 *mec_hdr = 425762306a36Sopenharmony_ci (const struct gfx_firmware_header_v1_0 *)rdev->mec_fw->data; 425862306a36Sopenharmony_ci const __le32 *fw_data; 425962306a36Sopenharmony_ci u32 fw_size; 426062306a36Sopenharmony_ci 426162306a36Sopenharmony_ci radeon_ucode_print_gfx_hdr(&mec_hdr->header); 426262306a36Sopenharmony_ci 426362306a36Sopenharmony_ci /* MEC1 */ 426462306a36Sopenharmony_ci fw_data = (const __le32 *) 426562306a36Sopenharmony_ci (rdev->mec_fw->data + le32_to_cpu(mec_hdr->header.ucode_array_offset_bytes)); 426662306a36Sopenharmony_ci fw_size = le32_to_cpu(mec_hdr->header.ucode_size_bytes) / 4; 426762306a36Sopenharmony_ci WREG32(CP_MEC_ME1_UCODE_ADDR, 0); 426862306a36Sopenharmony_ci for (i = 0; i < fw_size; i++) 426962306a36Sopenharmony_ci WREG32(CP_MEC_ME1_UCODE_DATA, le32_to_cpup(fw_data++)); 427062306a36Sopenharmony_ci WREG32(CP_MEC_ME1_UCODE_ADDR, le32_to_cpu(mec_hdr->header.ucode_version)); 427162306a36Sopenharmony_ci 427262306a36Sopenharmony_ci /* MEC2 */ 427362306a36Sopenharmony_ci if (rdev->family == CHIP_KAVERI) { 427462306a36Sopenharmony_ci const struct gfx_firmware_header_v1_0 *mec2_hdr = 427562306a36Sopenharmony_ci (const struct gfx_firmware_header_v1_0 *)rdev->mec2_fw->data; 427662306a36Sopenharmony_ci 427762306a36Sopenharmony_ci fw_data = (const __le32 *) 427862306a36Sopenharmony_ci (rdev->mec2_fw->data + 427962306a36Sopenharmony_ci le32_to_cpu(mec2_hdr->header.ucode_array_offset_bytes)); 428062306a36Sopenharmony_ci fw_size = le32_to_cpu(mec2_hdr->header.ucode_size_bytes) / 4; 428162306a36Sopenharmony_ci WREG32(CP_MEC_ME2_UCODE_ADDR, 0); 428262306a36Sopenharmony_ci for (i = 0; i < fw_size; i++) 428362306a36Sopenharmony_ci WREG32(CP_MEC_ME2_UCODE_DATA, le32_to_cpup(fw_data++)); 428462306a36Sopenharmony_ci WREG32(CP_MEC_ME2_UCODE_ADDR, le32_to_cpu(mec2_hdr->header.ucode_version)); 428562306a36Sopenharmony_ci } 428662306a36Sopenharmony_ci } else { 428762306a36Sopenharmony_ci const __be32 *fw_data; 428862306a36Sopenharmony_ci 428962306a36Sopenharmony_ci /* MEC1 */ 429062306a36Sopenharmony_ci fw_data = (const __be32 *)rdev->mec_fw->data; 429162306a36Sopenharmony_ci WREG32(CP_MEC_ME1_UCODE_ADDR, 0); 429262306a36Sopenharmony_ci for (i = 0; i < CIK_MEC_UCODE_SIZE; i++) 429362306a36Sopenharmony_ci WREG32(CP_MEC_ME1_UCODE_DATA, be32_to_cpup(fw_data++)); 429462306a36Sopenharmony_ci WREG32(CP_MEC_ME1_UCODE_ADDR, 0); 429562306a36Sopenharmony_ci 429662306a36Sopenharmony_ci if (rdev->family == CHIP_KAVERI) { 429762306a36Sopenharmony_ci /* MEC2 */ 429862306a36Sopenharmony_ci fw_data = (const __be32 *)rdev->mec_fw->data; 429962306a36Sopenharmony_ci WREG32(CP_MEC_ME2_UCODE_ADDR, 0); 430062306a36Sopenharmony_ci for (i = 0; i < CIK_MEC_UCODE_SIZE; i++) 430162306a36Sopenharmony_ci WREG32(CP_MEC_ME2_UCODE_DATA, be32_to_cpup(fw_data++)); 430262306a36Sopenharmony_ci WREG32(CP_MEC_ME2_UCODE_ADDR, 0); 430362306a36Sopenharmony_ci } 430462306a36Sopenharmony_ci } 430562306a36Sopenharmony_ci 430662306a36Sopenharmony_ci return 0; 430762306a36Sopenharmony_ci} 430862306a36Sopenharmony_ci 430962306a36Sopenharmony_ci/** 431062306a36Sopenharmony_ci * cik_cp_compute_start - start the compute queues 431162306a36Sopenharmony_ci * 431262306a36Sopenharmony_ci * @rdev: radeon_device pointer 431362306a36Sopenharmony_ci * 431462306a36Sopenharmony_ci * Enable the compute queues. 431562306a36Sopenharmony_ci * Returns 0 for success, error for failure. 431662306a36Sopenharmony_ci */ 431762306a36Sopenharmony_cistatic int cik_cp_compute_start(struct radeon_device *rdev) 431862306a36Sopenharmony_ci{ 431962306a36Sopenharmony_ci cik_cp_compute_enable(rdev, true); 432062306a36Sopenharmony_ci 432162306a36Sopenharmony_ci return 0; 432262306a36Sopenharmony_ci} 432362306a36Sopenharmony_ci 432462306a36Sopenharmony_ci/** 432562306a36Sopenharmony_ci * cik_cp_compute_fini - stop the compute queues 432662306a36Sopenharmony_ci * 432762306a36Sopenharmony_ci * @rdev: radeon_device pointer 432862306a36Sopenharmony_ci * 432962306a36Sopenharmony_ci * Stop the compute queues and tear down the driver queue 433062306a36Sopenharmony_ci * info. 433162306a36Sopenharmony_ci */ 433262306a36Sopenharmony_cistatic void cik_cp_compute_fini(struct radeon_device *rdev) 433362306a36Sopenharmony_ci{ 433462306a36Sopenharmony_ci int i, idx, r; 433562306a36Sopenharmony_ci 433662306a36Sopenharmony_ci cik_cp_compute_enable(rdev, false); 433762306a36Sopenharmony_ci 433862306a36Sopenharmony_ci for (i = 0; i < 2; i++) { 433962306a36Sopenharmony_ci if (i == 0) 434062306a36Sopenharmony_ci idx = CAYMAN_RING_TYPE_CP1_INDEX; 434162306a36Sopenharmony_ci else 434262306a36Sopenharmony_ci idx = CAYMAN_RING_TYPE_CP2_INDEX; 434362306a36Sopenharmony_ci 434462306a36Sopenharmony_ci if (rdev->ring[idx].mqd_obj) { 434562306a36Sopenharmony_ci r = radeon_bo_reserve(rdev->ring[idx].mqd_obj, false); 434662306a36Sopenharmony_ci if (unlikely(r != 0)) 434762306a36Sopenharmony_ci dev_warn(rdev->dev, "(%d) reserve MQD bo failed\n", r); 434862306a36Sopenharmony_ci 434962306a36Sopenharmony_ci radeon_bo_unpin(rdev->ring[idx].mqd_obj); 435062306a36Sopenharmony_ci radeon_bo_unreserve(rdev->ring[idx].mqd_obj); 435162306a36Sopenharmony_ci 435262306a36Sopenharmony_ci radeon_bo_unref(&rdev->ring[idx].mqd_obj); 435362306a36Sopenharmony_ci rdev->ring[idx].mqd_obj = NULL; 435462306a36Sopenharmony_ci } 435562306a36Sopenharmony_ci } 435662306a36Sopenharmony_ci} 435762306a36Sopenharmony_ci 435862306a36Sopenharmony_cistatic void cik_mec_fini(struct radeon_device *rdev) 435962306a36Sopenharmony_ci{ 436062306a36Sopenharmony_ci int r; 436162306a36Sopenharmony_ci 436262306a36Sopenharmony_ci if (rdev->mec.hpd_eop_obj) { 436362306a36Sopenharmony_ci r = radeon_bo_reserve(rdev->mec.hpd_eop_obj, false); 436462306a36Sopenharmony_ci if (unlikely(r != 0)) 436562306a36Sopenharmony_ci dev_warn(rdev->dev, "(%d) reserve HPD EOP bo failed\n", r); 436662306a36Sopenharmony_ci radeon_bo_unpin(rdev->mec.hpd_eop_obj); 436762306a36Sopenharmony_ci radeon_bo_unreserve(rdev->mec.hpd_eop_obj); 436862306a36Sopenharmony_ci 436962306a36Sopenharmony_ci radeon_bo_unref(&rdev->mec.hpd_eop_obj); 437062306a36Sopenharmony_ci rdev->mec.hpd_eop_obj = NULL; 437162306a36Sopenharmony_ci } 437262306a36Sopenharmony_ci} 437362306a36Sopenharmony_ci 437462306a36Sopenharmony_ci#define MEC_HPD_SIZE 2048 437562306a36Sopenharmony_ci 437662306a36Sopenharmony_cistatic int cik_mec_init(struct radeon_device *rdev) 437762306a36Sopenharmony_ci{ 437862306a36Sopenharmony_ci int r; 437962306a36Sopenharmony_ci u32 *hpd; 438062306a36Sopenharmony_ci 438162306a36Sopenharmony_ci /* 438262306a36Sopenharmony_ci * KV: 2 MEC, 4 Pipes/MEC, 8 Queues/Pipe - 64 Queues total 438362306a36Sopenharmony_ci * CI/KB: 1 MEC, 4 Pipes/MEC, 8 Queues/Pipe - 32 Queues total 438462306a36Sopenharmony_ci */ 438562306a36Sopenharmony_ci if (rdev->family == CHIP_KAVERI) 438662306a36Sopenharmony_ci rdev->mec.num_mec = 2; 438762306a36Sopenharmony_ci else 438862306a36Sopenharmony_ci rdev->mec.num_mec = 1; 438962306a36Sopenharmony_ci rdev->mec.num_pipe = 4; 439062306a36Sopenharmony_ci rdev->mec.num_queue = rdev->mec.num_mec * rdev->mec.num_pipe * 8; 439162306a36Sopenharmony_ci 439262306a36Sopenharmony_ci if (rdev->mec.hpd_eop_obj == NULL) { 439362306a36Sopenharmony_ci r = radeon_bo_create(rdev, 439462306a36Sopenharmony_ci rdev->mec.num_mec *rdev->mec.num_pipe * MEC_HPD_SIZE * 2, 439562306a36Sopenharmony_ci PAGE_SIZE, true, 439662306a36Sopenharmony_ci RADEON_GEM_DOMAIN_GTT, 0, NULL, NULL, 439762306a36Sopenharmony_ci &rdev->mec.hpd_eop_obj); 439862306a36Sopenharmony_ci if (r) { 439962306a36Sopenharmony_ci dev_warn(rdev->dev, "(%d) create HDP EOP bo failed\n", r); 440062306a36Sopenharmony_ci return r; 440162306a36Sopenharmony_ci } 440262306a36Sopenharmony_ci } 440362306a36Sopenharmony_ci 440462306a36Sopenharmony_ci r = radeon_bo_reserve(rdev->mec.hpd_eop_obj, false); 440562306a36Sopenharmony_ci if (unlikely(r != 0)) { 440662306a36Sopenharmony_ci cik_mec_fini(rdev); 440762306a36Sopenharmony_ci return r; 440862306a36Sopenharmony_ci } 440962306a36Sopenharmony_ci r = radeon_bo_pin(rdev->mec.hpd_eop_obj, RADEON_GEM_DOMAIN_GTT, 441062306a36Sopenharmony_ci &rdev->mec.hpd_eop_gpu_addr); 441162306a36Sopenharmony_ci if (r) { 441262306a36Sopenharmony_ci dev_warn(rdev->dev, "(%d) pin HDP EOP bo failed\n", r); 441362306a36Sopenharmony_ci cik_mec_fini(rdev); 441462306a36Sopenharmony_ci return r; 441562306a36Sopenharmony_ci } 441662306a36Sopenharmony_ci r = radeon_bo_kmap(rdev->mec.hpd_eop_obj, (void **)&hpd); 441762306a36Sopenharmony_ci if (r) { 441862306a36Sopenharmony_ci dev_warn(rdev->dev, "(%d) map HDP EOP bo failed\n", r); 441962306a36Sopenharmony_ci cik_mec_fini(rdev); 442062306a36Sopenharmony_ci return r; 442162306a36Sopenharmony_ci } 442262306a36Sopenharmony_ci 442362306a36Sopenharmony_ci /* clear memory. Not sure if this is required or not */ 442462306a36Sopenharmony_ci memset(hpd, 0, rdev->mec.num_mec *rdev->mec.num_pipe * MEC_HPD_SIZE * 2); 442562306a36Sopenharmony_ci 442662306a36Sopenharmony_ci radeon_bo_kunmap(rdev->mec.hpd_eop_obj); 442762306a36Sopenharmony_ci radeon_bo_unreserve(rdev->mec.hpd_eop_obj); 442862306a36Sopenharmony_ci 442962306a36Sopenharmony_ci return 0; 443062306a36Sopenharmony_ci} 443162306a36Sopenharmony_ci 443262306a36Sopenharmony_cistruct hqd_registers 443362306a36Sopenharmony_ci{ 443462306a36Sopenharmony_ci u32 cp_mqd_base_addr; 443562306a36Sopenharmony_ci u32 cp_mqd_base_addr_hi; 443662306a36Sopenharmony_ci u32 cp_hqd_active; 443762306a36Sopenharmony_ci u32 cp_hqd_vmid; 443862306a36Sopenharmony_ci u32 cp_hqd_persistent_state; 443962306a36Sopenharmony_ci u32 cp_hqd_pipe_priority; 444062306a36Sopenharmony_ci u32 cp_hqd_queue_priority; 444162306a36Sopenharmony_ci u32 cp_hqd_quantum; 444262306a36Sopenharmony_ci u32 cp_hqd_pq_base; 444362306a36Sopenharmony_ci u32 cp_hqd_pq_base_hi; 444462306a36Sopenharmony_ci u32 cp_hqd_pq_rptr; 444562306a36Sopenharmony_ci u32 cp_hqd_pq_rptr_report_addr; 444662306a36Sopenharmony_ci u32 cp_hqd_pq_rptr_report_addr_hi; 444762306a36Sopenharmony_ci u32 cp_hqd_pq_wptr_poll_addr; 444862306a36Sopenharmony_ci u32 cp_hqd_pq_wptr_poll_addr_hi; 444962306a36Sopenharmony_ci u32 cp_hqd_pq_doorbell_control; 445062306a36Sopenharmony_ci u32 cp_hqd_pq_wptr; 445162306a36Sopenharmony_ci u32 cp_hqd_pq_control; 445262306a36Sopenharmony_ci u32 cp_hqd_ib_base_addr; 445362306a36Sopenharmony_ci u32 cp_hqd_ib_base_addr_hi; 445462306a36Sopenharmony_ci u32 cp_hqd_ib_rptr; 445562306a36Sopenharmony_ci u32 cp_hqd_ib_control; 445662306a36Sopenharmony_ci u32 cp_hqd_iq_timer; 445762306a36Sopenharmony_ci u32 cp_hqd_iq_rptr; 445862306a36Sopenharmony_ci u32 cp_hqd_dequeue_request; 445962306a36Sopenharmony_ci u32 cp_hqd_dma_offload; 446062306a36Sopenharmony_ci u32 cp_hqd_sema_cmd; 446162306a36Sopenharmony_ci u32 cp_hqd_msg_type; 446262306a36Sopenharmony_ci u32 cp_hqd_atomic0_preop_lo; 446362306a36Sopenharmony_ci u32 cp_hqd_atomic0_preop_hi; 446462306a36Sopenharmony_ci u32 cp_hqd_atomic1_preop_lo; 446562306a36Sopenharmony_ci u32 cp_hqd_atomic1_preop_hi; 446662306a36Sopenharmony_ci u32 cp_hqd_hq_scheduler0; 446762306a36Sopenharmony_ci u32 cp_hqd_hq_scheduler1; 446862306a36Sopenharmony_ci u32 cp_mqd_control; 446962306a36Sopenharmony_ci}; 447062306a36Sopenharmony_ci 447162306a36Sopenharmony_cistruct bonaire_mqd 447262306a36Sopenharmony_ci{ 447362306a36Sopenharmony_ci u32 header; 447462306a36Sopenharmony_ci u32 dispatch_initiator; 447562306a36Sopenharmony_ci u32 dimensions[3]; 447662306a36Sopenharmony_ci u32 start_idx[3]; 447762306a36Sopenharmony_ci u32 num_threads[3]; 447862306a36Sopenharmony_ci u32 pipeline_stat_enable; 447962306a36Sopenharmony_ci u32 perf_counter_enable; 448062306a36Sopenharmony_ci u32 pgm[2]; 448162306a36Sopenharmony_ci u32 tba[2]; 448262306a36Sopenharmony_ci u32 tma[2]; 448362306a36Sopenharmony_ci u32 pgm_rsrc[2]; 448462306a36Sopenharmony_ci u32 vmid; 448562306a36Sopenharmony_ci u32 resource_limits; 448662306a36Sopenharmony_ci u32 static_thread_mgmt01[2]; 448762306a36Sopenharmony_ci u32 tmp_ring_size; 448862306a36Sopenharmony_ci u32 static_thread_mgmt23[2]; 448962306a36Sopenharmony_ci u32 restart[3]; 449062306a36Sopenharmony_ci u32 thread_trace_enable; 449162306a36Sopenharmony_ci u32 reserved1; 449262306a36Sopenharmony_ci u32 user_data[16]; 449362306a36Sopenharmony_ci u32 vgtcs_invoke_count[2]; 449462306a36Sopenharmony_ci struct hqd_registers queue_state; 449562306a36Sopenharmony_ci u32 dequeue_cntr; 449662306a36Sopenharmony_ci u32 interrupt_queue[64]; 449762306a36Sopenharmony_ci}; 449862306a36Sopenharmony_ci 449962306a36Sopenharmony_ci/** 450062306a36Sopenharmony_ci * cik_cp_compute_resume - setup the compute queue registers 450162306a36Sopenharmony_ci * 450262306a36Sopenharmony_ci * @rdev: radeon_device pointer 450362306a36Sopenharmony_ci * 450462306a36Sopenharmony_ci * Program the compute queues and test them to make sure they 450562306a36Sopenharmony_ci * are working. 450662306a36Sopenharmony_ci * Returns 0 for success, error for failure. 450762306a36Sopenharmony_ci */ 450862306a36Sopenharmony_cistatic int cik_cp_compute_resume(struct radeon_device *rdev) 450962306a36Sopenharmony_ci{ 451062306a36Sopenharmony_ci int r, i, j, idx; 451162306a36Sopenharmony_ci u32 tmp; 451262306a36Sopenharmony_ci bool use_doorbell = true; 451362306a36Sopenharmony_ci u64 hqd_gpu_addr; 451462306a36Sopenharmony_ci u64 mqd_gpu_addr; 451562306a36Sopenharmony_ci u64 eop_gpu_addr; 451662306a36Sopenharmony_ci u64 wb_gpu_addr; 451762306a36Sopenharmony_ci u32 *buf; 451862306a36Sopenharmony_ci struct bonaire_mqd *mqd; 451962306a36Sopenharmony_ci 452062306a36Sopenharmony_ci r = cik_cp_compute_start(rdev); 452162306a36Sopenharmony_ci if (r) 452262306a36Sopenharmony_ci return r; 452362306a36Sopenharmony_ci 452462306a36Sopenharmony_ci /* fix up chicken bits */ 452562306a36Sopenharmony_ci tmp = RREG32(CP_CPF_DEBUG); 452662306a36Sopenharmony_ci tmp |= (1 << 23); 452762306a36Sopenharmony_ci WREG32(CP_CPF_DEBUG, tmp); 452862306a36Sopenharmony_ci 452962306a36Sopenharmony_ci /* init the pipes */ 453062306a36Sopenharmony_ci mutex_lock(&rdev->srbm_mutex); 453162306a36Sopenharmony_ci 453262306a36Sopenharmony_ci for (i = 0; i < (rdev->mec.num_pipe * rdev->mec.num_mec); ++i) { 453362306a36Sopenharmony_ci int me = (i < 4) ? 1 : 2; 453462306a36Sopenharmony_ci int pipe = (i < 4) ? i : (i - 4); 453562306a36Sopenharmony_ci 453662306a36Sopenharmony_ci cik_srbm_select(rdev, me, pipe, 0, 0); 453762306a36Sopenharmony_ci 453862306a36Sopenharmony_ci eop_gpu_addr = rdev->mec.hpd_eop_gpu_addr + (i * MEC_HPD_SIZE * 2) ; 453962306a36Sopenharmony_ci /* write the EOP addr */ 454062306a36Sopenharmony_ci WREG32(CP_HPD_EOP_BASE_ADDR, eop_gpu_addr >> 8); 454162306a36Sopenharmony_ci WREG32(CP_HPD_EOP_BASE_ADDR_HI, upper_32_bits(eop_gpu_addr) >> 8); 454262306a36Sopenharmony_ci 454362306a36Sopenharmony_ci /* set the VMID assigned */ 454462306a36Sopenharmony_ci WREG32(CP_HPD_EOP_VMID, 0); 454562306a36Sopenharmony_ci 454662306a36Sopenharmony_ci /* set the EOP size, register value is 2^(EOP_SIZE+1) dwords */ 454762306a36Sopenharmony_ci tmp = RREG32(CP_HPD_EOP_CONTROL); 454862306a36Sopenharmony_ci tmp &= ~EOP_SIZE_MASK; 454962306a36Sopenharmony_ci tmp |= order_base_2(MEC_HPD_SIZE / 8); 455062306a36Sopenharmony_ci WREG32(CP_HPD_EOP_CONTROL, tmp); 455162306a36Sopenharmony_ci 455262306a36Sopenharmony_ci } 455362306a36Sopenharmony_ci cik_srbm_select(rdev, 0, 0, 0, 0); 455462306a36Sopenharmony_ci mutex_unlock(&rdev->srbm_mutex); 455562306a36Sopenharmony_ci 455662306a36Sopenharmony_ci /* init the queues. Just two for now. */ 455762306a36Sopenharmony_ci for (i = 0; i < 2; i++) { 455862306a36Sopenharmony_ci if (i == 0) 455962306a36Sopenharmony_ci idx = CAYMAN_RING_TYPE_CP1_INDEX; 456062306a36Sopenharmony_ci else 456162306a36Sopenharmony_ci idx = CAYMAN_RING_TYPE_CP2_INDEX; 456262306a36Sopenharmony_ci 456362306a36Sopenharmony_ci if (rdev->ring[idx].mqd_obj == NULL) { 456462306a36Sopenharmony_ci r = radeon_bo_create(rdev, 456562306a36Sopenharmony_ci sizeof(struct bonaire_mqd), 456662306a36Sopenharmony_ci PAGE_SIZE, true, 456762306a36Sopenharmony_ci RADEON_GEM_DOMAIN_GTT, 0, NULL, 456862306a36Sopenharmony_ci NULL, &rdev->ring[idx].mqd_obj); 456962306a36Sopenharmony_ci if (r) { 457062306a36Sopenharmony_ci dev_warn(rdev->dev, "(%d) create MQD bo failed\n", r); 457162306a36Sopenharmony_ci return r; 457262306a36Sopenharmony_ci } 457362306a36Sopenharmony_ci } 457462306a36Sopenharmony_ci 457562306a36Sopenharmony_ci r = radeon_bo_reserve(rdev->ring[idx].mqd_obj, false); 457662306a36Sopenharmony_ci if (unlikely(r != 0)) { 457762306a36Sopenharmony_ci cik_cp_compute_fini(rdev); 457862306a36Sopenharmony_ci return r; 457962306a36Sopenharmony_ci } 458062306a36Sopenharmony_ci r = radeon_bo_pin(rdev->ring[idx].mqd_obj, RADEON_GEM_DOMAIN_GTT, 458162306a36Sopenharmony_ci &mqd_gpu_addr); 458262306a36Sopenharmony_ci if (r) { 458362306a36Sopenharmony_ci dev_warn(rdev->dev, "(%d) pin MQD bo failed\n", r); 458462306a36Sopenharmony_ci cik_cp_compute_fini(rdev); 458562306a36Sopenharmony_ci return r; 458662306a36Sopenharmony_ci } 458762306a36Sopenharmony_ci r = radeon_bo_kmap(rdev->ring[idx].mqd_obj, (void **)&buf); 458862306a36Sopenharmony_ci if (r) { 458962306a36Sopenharmony_ci dev_warn(rdev->dev, "(%d) map MQD bo failed\n", r); 459062306a36Sopenharmony_ci cik_cp_compute_fini(rdev); 459162306a36Sopenharmony_ci return r; 459262306a36Sopenharmony_ci } 459362306a36Sopenharmony_ci 459462306a36Sopenharmony_ci /* init the mqd struct */ 459562306a36Sopenharmony_ci memset(buf, 0, sizeof(struct bonaire_mqd)); 459662306a36Sopenharmony_ci 459762306a36Sopenharmony_ci mqd = (struct bonaire_mqd *)buf; 459862306a36Sopenharmony_ci mqd->header = 0xC0310800; 459962306a36Sopenharmony_ci mqd->static_thread_mgmt01[0] = 0xffffffff; 460062306a36Sopenharmony_ci mqd->static_thread_mgmt01[1] = 0xffffffff; 460162306a36Sopenharmony_ci mqd->static_thread_mgmt23[0] = 0xffffffff; 460262306a36Sopenharmony_ci mqd->static_thread_mgmt23[1] = 0xffffffff; 460362306a36Sopenharmony_ci 460462306a36Sopenharmony_ci mutex_lock(&rdev->srbm_mutex); 460562306a36Sopenharmony_ci cik_srbm_select(rdev, rdev->ring[idx].me, 460662306a36Sopenharmony_ci rdev->ring[idx].pipe, 460762306a36Sopenharmony_ci rdev->ring[idx].queue, 0); 460862306a36Sopenharmony_ci 460962306a36Sopenharmony_ci /* disable wptr polling */ 461062306a36Sopenharmony_ci tmp = RREG32(CP_PQ_WPTR_POLL_CNTL); 461162306a36Sopenharmony_ci tmp &= ~WPTR_POLL_EN; 461262306a36Sopenharmony_ci WREG32(CP_PQ_WPTR_POLL_CNTL, tmp); 461362306a36Sopenharmony_ci 461462306a36Sopenharmony_ci /* enable doorbell? */ 461562306a36Sopenharmony_ci mqd->queue_state.cp_hqd_pq_doorbell_control = 461662306a36Sopenharmony_ci RREG32(CP_HQD_PQ_DOORBELL_CONTROL); 461762306a36Sopenharmony_ci if (use_doorbell) 461862306a36Sopenharmony_ci mqd->queue_state.cp_hqd_pq_doorbell_control |= DOORBELL_EN; 461962306a36Sopenharmony_ci else 462062306a36Sopenharmony_ci mqd->queue_state.cp_hqd_pq_doorbell_control &= ~DOORBELL_EN; 462162306a36Sopenharmony_ci WREG32(CP_HQD_PQ_DOORBELL_CONTROL, 462262306a36Sopenharmony_ci mqd->queue_state.cp_hqd_pq_doorbell_control); 462362306a36Sopenharmony_ci 462462306a36Sopenharmony_ci /* disable the queue if it's active */ 462562306a36Sopenharmony_ci mqd->queue_state.cp_hqd_dequeue_request = 0; 462662306a36Sopenharmony_ci mqd->queue_state.cp_hqd_pq_rptr = 0; 462762306a36Sopenharmony_ci mqd->queue_state.cp_hqd_pq_wptr= 0; 462862306a36Sopenharmony_ci if (RREG32(CP_HQD_ACTIVE) & 1) { 462962306a36Sopenharmony_ci WREG32(CP_HQD_DEQUEUE_REQUEST, 1); 463062306a36Sopenharmony_ci for (j = 0; j < rdev->usec_timeout; j++) { 463162306a36Sopenharmony_ci if (!(RREG32(CP_HQD_ACTIVE) & 1)) 463262306a36Sopenharmony_ci break; 463362306a36Sopenharmony_ci udelay(1); 463462306a36Sopenharmony_ci } 463562306a36Sopenharmony_ci WREG32(CP_HQD_DEQUEUE_REQUEST, mqd->queue_state.cp_hqd_dequeue_request); 463662306a36Sopenharmony_ci WREG32(CP_HQD_PQ_RPTR, mqd->queue_state.cp_hqd_pq_rptr); 463762306a36Sopenharmony_ci WREG32(CP_HQD_PQ_WPTR, mqd->queue_state.cp_hqd_pq_wptr); 463862306a36Sopenharmony_ci } 463962306a36Sopenharmony_ci 464062306a36Sopenharmony_ci /* set the pointer to the MQD */ 464162306a36Sopenharmony_ci mqd->queue_state.cp_mqd_base_addr = mqd_gpu_addr & 0xfffffffc; 464262306a36Sopenharmony_ci mqd->queue_state.cp_mqd_base_addr_hi = upper_32_bits(mqd_gpu_addr); 464362306a36Sopenharmony_ci WREG32(CP_MQD_BASE_ADDR, mqd->queue_state.cp_mqd_base_addr); 464462306a36Sopenharmony_ci WREG32(CP_MQD_BASE_ADDR_HI, mqd->queue_state.cp_mqd_base_addr_hi); 464562306a36Sopenharmony_ci /* set MQD vmid to 0 */ 464662306a36Sopenharmony_ci mqd->queue_state.cp_mqd_control = RREG32(CP_MQD_CONTROL); 464762306a36Sopenharmony_ci mqd->queue_state.cp_mqd_control &= ~MQD_VMID_MASK; 464862306a36Sopenharmony_ci WREG32(CP_MQD_CONTROL, mqd->queue_state.cp_mqd_control); 464962306a36Sopenharmony_ci 465062306a36Sopenharmony_ci /* set the pointer to the HQD, this is similar CP_RB0_BASE/_HI */ 465162306a36Sopenharmony_ci hqd_gpu_addr = rdev->ring[idx].gpu_addr >> 8; 465262306a36Sopenharmony_ci mqd->queue_state.cp_hqd_pq_base = hqd_gpu_addr; 465362306a36Sopenharmony_ci mqd->queue_state.cp_hqd_pq_base_hi = upper_32_bits(hqd_gpu_addr); 465462306a36Sopenharmony_ci WREG32(CP_HQD_PQ_BASE, mqd->queue_state.cp_hqd_pq_base); 465562306a36Sopenharmony_ci WREG32(CP_HQD_PQ_BASE_HI, mqd->queue_state.cp_hqd_pq_base_hi); 465662306a36Sopenharmony_ci 465762306a36Sopenharmony_ci /* set up the HQD, this is similar to CP_RB0_CNTL */ 465862306a36Sopenharmony_ci mqd->queue_state.cp_hqd_pq_control = RREG32(CP_HQD_PQ_CONTROL); 465962306a36Sopenharmony_ci mqd->queue_state.cp_hqd_pq_control &= 466062306a36Sopenharmony_ci ~(QUEUE_SIZE_MASK | RPTR_BLOCK_SIZE_MASK); 466162306a36Sopenharmony_ci 466262306a36Sopenharmony_ci mqd->queue_state.cp_hqd_pq_control |= 466362306a36Sopenharmony_ci order_base_2(rdev->ring[idx].ring_size / 8); 466462306a36Sopenharmony_ci mqd->queue_state.cp_hqd_pq_control |= 466562306a36Sopenharmony_ci (order_base_2(RADEON_GPU_PAGE_SIZE/8) << 8); 466662306a36Sopenharmony_ci#ifdef __BIG_ENDIAN 466762306a36Sopenharmony_ci mqd->queue_state.cp_hqd_pq_control |= BUF_SWAP_32BIT; 466862306a36Sopenharmony_ci#endif 466962306a36Sopenharmony_ci mqd->queue_state.cp_hqd_pq_control &= 467062306a36Sopenharmony_ci ~(UNORD_DISPATCH | ROQ_PQ_IB_FLIP | PQ_VOLATILE); 467162306a36Sopenharmony_ci mqd->queue_state.cp_hqd_pq_control |= 467262306a36Sopenharmony_ci PRIV_STATE | KMD_QUEUE; /* assuming kernel queue control */ 467362306a36Sopenharmony_ci WREG32(CP_HQD_PQ_CONTROL, mqd->queue_state.cp_hqd_pq_control); 467462306a36Sopenharmony_ci 467562306a36Sopenharmony_ci /* only used if CP_PQ_WPTR_POLL_CNTL.WPTR_POLL_EN=1 */ 467662306a36Sopenharmony_ci if (i == 0) 467762306a36Sopenharmony_ci wb_gpu_addr = rdev->wb.gpu_addr + CIK_WB_CP1_WPTR_OFFSET; 467862306a36Sopenharmony_ci else 467962306a36Sopenharmony_ci wb_gpu_addr = rdev->wb.gpu_addr + CIK_WB_CP2_WPTR_OFFSET; 468062306a36Sopenharmony_ci mqd->queue_state.cp_hqd_pq_wptr_poll_addr = wb_gpu_addr & 0xfffffffc; 468162306a36Sopenharmony_ci mqd->queue_state.cp_hqd_pq_wptr_poll_addr_hi = upper_32_bits(wb_gpu_addr) & 0xffff; 468262306a36Sopenharmony_ci WREG32(CP_HQD_PQ_WPTR_POLL_ADDR, mqd->queue_state.cp_hqd_pq_wptr_poll_addr); 468362306a36Sopenharmony_ci WREG32(CP_HQD_PQ_WPTR_POLL_ADDR_HI, 468462306a36Sopenharmony_ci mqd->queue_state.cp_hqd_pq_wptr_poll_addr_hi); 468562306a36Sopenharmony_ci 468662306a36Sopenharmony_ci /* set the wb address wether it's enabled or not */ 468762306a36Sopenharmony_ci if (i == 0) 468862306a36Sopenharmony_ci wb_gpu_addr = rdev->wb.gpu_addr + RADEON_WB_CP1_RPTR_OFFSET; 468962306a36Sopenharmony_ci else 469062306a36Sopenharmony_ci wb_gpu_addr = rdev->wb.gpu_addr + RADEON_WB_CP2_RPTR_OFFSET; 469162306a36Sopenharmony_ci mqd->queue_state.cp_hqd_pq_rptr_report_addr = wb_gpu_addr & 0xfffffffc; 469262306a36Sopenharmony_ci mqd->queue_state.cp_hqd_pq_rptr_report_addr_hi = 469362306a36Sopenharmony_ci upper_32_bits(wb_gpu_addr) & 0xffff; 469462306a36Sopenharmony_ci WREG32(CP_HQD_PQ_RPTR_REPORT_ADDR, 469562306a36Sopenharmony_ci mqd->queue_state.cp_hqd_pq_rptr_report_addr); 469662306a36Sopenharmony_ci WREG32(CP_HQD_PQ_RPTR_REPORT_ADDR_HI, 469762306a36Sopenharmony_ci mqd->queue_state.cp_hqd_pq_rptr_report_addr_hi); 469862306a36Sopenharmony_ci 469962306a36Sopenharmony_ci /* enable the doorbell if requested */ 470062306a36Sopenharmony_ci if (use_doorbell) { 470162306a36Sopenharmony_ci mqd->queue_state.cp_hqd_pq_doorbell_control = 470262306a36Sopenharmony_ci RREG32(CP_HQD_PQ_DOORBELL_CONTROL); 470362306a36Sopenharmony_ci mqd->queue_state.cp_hqd_pq_doorbell_control &= ~DOORBELL_OFFSET_MASK; 470462306a36Sopenharmony_ci mqd->queue_state.cp_hqd_pq_doorbell_control |= 470562306a36Sopenharmony_ci DOORBELL_OFFSET(rdev->ring[idx].doorbell_index); 470662306a36Sopenharmony_ci mqd->queue_state.cp_hqd_pq_doorbell_control |= DOORBELL_EN; 470762306a36Sopenharmony_ci mqd->queue_state.cp_hqd_pq_doorbell_control &= 470862306a36Sopenharmony_ci ~(DOORBELL_SOURCE | DOORBELL_HIT); 470962306a36Sopenharmony_ci 471062306a36Sopenharmony_ci } else { 471162306a36Sopenharmony_ci mqd->queue_state.cp_hqd_pq_doorbell_control = 0; 471262306a36Sopenharmony_ci } 471362306a36Sopenharmony_ci WREG32(CP_HQD_PQ_DOORBELL_CONTROL, 471462306a36Sopenharmony_ci mqd->queue_state.cp_hqd_pq_doorbell_control); 471562306a36Sopenharmony_ci 471662306a36Sopenharmony_ci /* read and write pointers, similar to CP_RB0_WPTR/_RPTR */ 471762306a36Sopenharmony_ci rdev->ring[idx].wptr = 0; 471862306a36Sopenharmony_ci mqd->queue_state.cp_hqd_pq_wptr = rdev->ring[idx].wptr; 471962306a36Sopenharmony_ci WREG32(CP_HQD_PQ_WPTR, mqd->queue_state.cp_hqd_pq_wptr); 472062306a36Sopenharmony_ci mqd->queue_state.cp_hqd_pq_rptr = RREG32(CP_HQD_PQ_RPTR); 472162306a36Sopenharmony_ci 472262306a36Sopenharmony_ci /* set the vmid for the queue */ 472362306a36Sopenharmony_ci mqd->queue_state.cp_hqd_vmid = 0; 472462306a36Sopenharmony_ci WREG32(CP_HQD_VMID, mqd->queue_state.cp_hqd_vmid); 472562306a36Sopenharmony_ci 472662306a36Sopenharmony_ci /* activate the queue */ 472762306a36Sopenharmony_ci mqd->queue_state.cp_hqd_active = 1; 472862306a36Sopenharmony_ci WREG32(CP_HQD_ACTIVE, mqd->queue_state.cp_hqd_active); 472962306a36Sopenharmony_ci 473062306a36Sopenharmony_ci cik_srbm_select(rdev, 0, 0, 0, 0); 473162306a36Sopenharmony_ci mutex_unlock(&rdev->srbm_mutex); 473262306a36Sopenharmony_ci 473362306a36Sopenharmony_ci radeon_bo_kunmap(rdev->ring[idx].mqd_obj); 473462306a36Sopenharmony_ci radeon_bo_unreserve(rdev->ring[idx].mqd_obj); 473562306a36Sopenharmony_ci 473662306a36Sopenharmony_ci rdev->ring[idx].ready = true; 473762306a36Sopenharmony_ci r = radeon_ring_test(rdev, idx, &rdev->ring[idx]); 473862306a36Sopenharmony_ci if (r) 473962306a36Sopenharmony_ci rdev->ring[idx].ready = false; 474062306a36Sopenharmony_ci } 474162306a36Sopenharmony_ci 474262306a36Sopenharmony_ci return 0; 474362306a36Sopenharmony_ci} 474462306a36Sopenharmony_ci 474562306a36Sopenharmony_cistatic void cik_cp_enable(struct radeon_device *rdev, bool enable) 474662306a36Sopenharmony_ci{ 474762306a36Sopenharmony_ci cik_cp_gfx_enable(rdev, enable); 474862306a36Sopenharmony_ci cik_cp_compute_enable(rdev, enable); 474962306a36Sopenharmony_ci} 475062306a36Sopenharmony_ci 475162306a36Sopenharmony_cistatic int cik_cp_load_microcode(struct radeon_device *rdev) 475262306a36Sopenharmony_ci{ 475362306a36Sopenharmony_ci int r; 475462306a36Sopenharmony_ci 475562306a36Sopenharmony_ci r = cik_cp_gfx_load_microcode(rdev); 475662306a36Sopenharmony_ci if (r) 475762306a36Sopenharmony_ci return r; 475862306a36Sopenharmony_ci r = cik_cp_compute_load_microcode(rdev); 475962306a36Sopenharmony_ci if (r) 476062306a36Sopenharmony_ci return r; 476162306a36Sopenharmony_ci 476262306a36Sopenharmony_ci return 0; 476362306a36Sopenharmony_ci} 476462306a36Sopenharmony_ci 476562306a36Sopenharmony_cistatic void cik_cp_fini(struct radeon_device *rdev) 476662306a36Sopenharmony_ci{ 476762306a36Sopenharmony_ci cik_cp_gfx_fini(rdev); 476862306a36Sopenharmony_ci cik_cp_compute_fini(rdev); 476962306a36Sopenharmony_ci} 477062306a36Sopenharmony_ci 477162306a36Sopenharmony_cistatic int cik_cp_resume(struct radeon_device *rdev) 477262306a36Sopenharmony_ci{ 477362306a36Sopenharmony_ci int r; 477462306a36Sopenharmony_ci 477562306a36Sopenharmony_ci cik_enable_gui_idle_interrupt(rdev, false); 477662306a36Sopenharmony_ci 477762306a36Sopenharmony_ci r = cik_cp_load_microcode(rdev); 477862306a36Sopenharmony_ci if (r) 477962306a36Sopenharmony_ci return r; 478062306a36Sopenharmony_ci 478162306a36Sopenharmony_ci r = cik_cp_gfx_resume(rdev); 478262306a36Sopenharmony_ci if (r) 478362306a36Sopenharmony_ci return r; 478462306a36Sopenharmony_ci r = cik_cp_compute_resume(rdev); 478562306a36Sopenharmony_ci if (r) 478662306a36Sopenharmony_ci return r; 478762306a36Sopenharmony_ci 478862306a36Sopenharmony_ci cik_enable_gui_idle_interrupt(rdev, true); 478962306a36Sopenharmony_ci 479062306a36Sopenharmony_ci return 0; 479162306a36Sopenharmony_ci} 479262306a36Sopenharmony_ci 479362306a36Sopenharmony_cistatic void cik_print_gpu_status_regs(struct radeon_device *rdev) 479462306a36Sopenharmony_ci{ 479562306a36Sopenharmony_ci dev_info(rdev->dev, " GRBM_STATUS=0x%08X\n", 479662306a36Sopenharmony_ci RREG32(GRBM_STATUS)); 479762306a36Sopenharmony_ci dev_info(rdev->dev, " GRBM_STATUS2=0x%08X\n", 479862306a36Sopenharmony_ci RREG32(GRBM_STATUS2)); 479962306a36Sopenharmony_ci dev_info(rdev->dev, " GRBM_STATUS_SE0=0x%08X\n", 480062306a36Sopenharmony_ci RREG32(GRBM_STATUS_SE0)); 480162306a36Sopenharmony_ci dev_info(rdev->dev, " GRBM_STATUS_SE1=0x%08X\n", 480262306a36Sopenharmony_ci RREG32(GRBM_STATUS_SE1)); 480362306a36Sopenharmony_ci dev_info(rdev->dev, " GRBM_STATUS_SE2=0x%08X\n", 480462306a36Sopenharmony_ci RREG32(GRBM_STATUS_SE2)); 480562306a36Sopenharmony_ci dev_info(rdev->dev, " GRBM_STATUS_SE3=0x%08X\n", 480662306a36Sopenharmony_ci RREG32(GRBM_STATUS_SE3)); 480762306a36Sopenharmony_ci dev_info(rdev->dev, " SRBM_STATUS=0x%08X\n", 480862306a36Sopenharmony_ci RREG32(SRBM_STATUS)); 480962306a36Sopenharmony_ci dev_info(rdev->dev, " SRBM_STATUS2=0x%08X\n", 481062306a36Sopenharmony_ci RREG32(SRBM_STATUS2)); 481162306a36Sopenharmony_ci dev_info(rdev->dev, " SDMA0_STATUS_REG = 0x%08X\n", 481262306a36Sopenharmony_ci RREG32(SDMA0_STATUS_REG + SDMA0_REGISTER_OFFSET)); 481362306a36Sopenharmony_ci dev_info(rdev->dev, " SDMA1_STATUS_REG = 0x%08X\n", 481462306a36Sopenharmony_ci RREG32(SDMA0_STATUS_REG + SDMA1_REGISTER_OFFSET)); 481562306a36Sopenharmony_ci dev_info(rdev->dev, " CP_STAT = 0x%08x\n", RREG32(CP_STAT)); 481662306a36Sopenharmony_ci dev_info(rdev->dev, " CP_STALLED_STAT1 = 0x%08x\n", 481762306a36Sopenharmony_ci RREG32(CP_STALLED_STAT1)); 481862306a36Sopenharmony_ci dev_info(rdev->dev, " CP_STALLED_STAT2 = 0x%08x\n", 481962306a36Sopenharmony_ci RREG32(CP_STALLED_STAT2)); 482062306a36Sopenharmony_ci dev_info(rdev->dev, " CP_STALLED_STAT3 = 0x%08x\n", 482162306a36Sopenharmony_ci RREG32(CP_STALLED_STAT3)); 482262306a36Sopenharmony_ci dev_info(rdev->dev, " CP_CPF_BUSY_STAT = 0x%08x\n", 482362306a36Sopenharmony_ci RREG32(CP_CPF_BUSY_STAT)); 482462306a36Sopenharmony_ci dev_info(rdev->dev, " CP_CPF_STALLED_STAT1 = 0x%08x\n", 482562306a36Sopenharmony_ci RREG32(CP_CPF_STALLED_STAT1)); 482662306a36Sopenharmony_ci dev_info(rdev->dev, " CP_CPF_STATUS = 0x%08x\n", RREG32(CP_CPF_STATUS)); 482762306a36Sopenharmony_ci dev_info(rdev->dev, " CP_CPC_BUSY_STAT = 0x%08x\n", RREG32(CP_CPC_BUSY_STAT)); 482862306a36Sopenharmony_ci dev_info(rdev->dev, " CP_CPC_STALLED_STAT1 = 0x%08x\n", 482962306a36Sopenharmony_ci RREG32(CP_CPC_STALLED_STAT1)); 483062306a36Sopenharmony_ci dev_info(rdev->dev, " CP_CPC_STATUS = 0x%08x\n", RREG32(CP_CPC_STATUS)); 483162306a36Sopenharmony_ci} 483262306a36Sopenharmony_ci 483362306a36Sopenharmony_ci/** 483462306a36Sopenharmony_ci * cik_gpu_check_soft_reset - check which blocks are busy 483562306a36Sopenharmony_ci * 483662306a36Sopenharmony_ci * @rdev: radeon_device pointer 483762306a36Sopenharmony_ci * 483862306a36Sopenharmony_ci * Check which blocks are busy and return the relevant reset 483962306a36Sopenharmony_ci * mask to be used by cik_gpu_soft_reset(). 484062306a36Sopenharmony_ci * Returns a mask of the blocks to be reset. 484162306a36Sopenharmony_ci */ 484262306a36Sopenharmony_ciu32 cik_gpu_check_soft_reset(struct radeon_device *rdev) 484362306a36Sopenharmony_ci{ 484462306a36Sopenharmony_ci u32 reset_mask = 0; 484562306a36Sopenharmony_ci u32 tmp; 484662306a36Sopenharmony_ci 484762306a36Sopenharmony_ci /* GRBM_STATUS */ 484862306a36Sopenharmony_ci tmp = RREG32(GRBM_STATUS); 484962306a36Sopenharmony_ci if (tmp & (PA_BUSY | SC_BUSY | 485062306a36Sopenharmony_ci BCI_BUSY | SX_BUSY | 485162306a36Sopenharmony_ci TA_BUSY | VGT_BUSY | 485262306a36Sopenharmony_ci DB_BUSY | CB_BUSY | 485362306a36Sopenharmony_ci GDS_BUSY | SPI_BUSY | 485462306a36Sopenharmony_ci IA_BUSY | IA_BUSY_NO_DMA)) 485562306a36Sopenharmony_ci reset_mask |= RADEON_RESET_GFX; 485662306a36Sopenharmony_ci 485762306a36Sopenharmony_ci if (tmp & (CP_BUSY | CP_COHERENCY_BUSY)) 485862306a36Sopenharmony_ci reset_mask |= RADEON_RESET_CP; 485962306a36Sopenharmony_ci 486062306a36Sopenharmony_ci /* GRBM_STATUS2 */ 486162306a36Sopenharmony_ci tmp = RREG32(GRBM_STATUS2); 486262306a36Sopenharmony_ci if (tmp & RLC_BUSY) 486362306a36Sopenharmony_ci reset_mask |= RADEON_RESET_RLC; 486462306a36Sopenharmony_ci 486562306a36Sopenharmony_ci /* SDMA0_STATUS_REG */ 486662306a36Sopenharmony_ci tmp = RREG32(SDMA0_STATUS_REG + SDMA0_REGISTER_OFFSET); 486762306a36Sopenharmony_ci if (!(tmp & SDMA_IDLE)) 486862306a36Sopenharmony_ci reset_mask |= RADEON_RESET_DMA; 486962306a36Sopenharmony_ci 487062306a36Sopenharmony_ci /* SDMA1_STATUS_REG */ 487162306a36Sopenharmony_ci tmp = RREG32(SDMA0_STATUS_REG + SDMA1_REGISTER_OFFSET); 487262306a36Sopenharmony_ci if (!(tmp & SDMA_IDLE)) 487362306a36Sopenharmony_ci reset_mask |= RADEON_RESET_DMA1; 487462306a36Sopenharmony_ci 487562306a36Sopenharmony_ci /* SRBM_STATUS2 */ 487662306a36Sopenharmony_ci tmp = RREG32(SRBM_STATUS2); 487762306a36Sopenharmony_ci if (tmp & SDMA_BUSY) 487862306a36Sopenharmony_ci reset_mask |= RADEON_RESET_DMA; 487962306a36Sopenharmony_ci 488062306a36Sopenharmony_ci if (tmp & SDMA1_BUSY) 488162306a36Sopenharmony_ci reset_mask |= RADEON_RESET_DMA1; 488262306a36Sopenharmony_ci 488362306a36Sopenharmony_ci /* SRBM_STATUS */ 488462306a36Sopenharmony_ci tmp = RREG32(SRBM_STATUS); 488562306a36Sopenharmony_ci 488662306a36Sopenharmony_ci if (tmp & IH_BUSY) 488762306a36Sopenharmony_ci reset_mask |= RADEON_RESET_IH; 488862306a36Sopenharmony_ci 488962306a36Sopenharmony_ci if (tmp & SEM_BUSY) 489062306a36Sopenharmony_ci reset_mask |= RADEON_RESET_SEM; 489162306a36Sopenharmony_ci 489262306a36Sopenharmony_ci if (tmp & GRBM_RQ_PENDING) 489362306a36Sopenharmony_ci reset_mask |= RADEON_RESET_GRBM; 489462306a36Sopenharmony_ci 489562306a36Sopenharmony_ci if (tmp & VMC_BUSY) 489662306a36Sopenharmony_ci reset_mask |= RADEON_RESET_VMC; 489762306a36Sopenharmony_ci 489862306a36Sopenharmony_ci if (tmp & (MCB_BUSY | MCB_NON_DISPLAY_BUSY | 489962306a36Sopenharmony_ci MCC_BUSY | MCD_BUSY)) 490062306a36Sopenharmony_ci reset_mask |= RADEON_RESET_MC; 490162306a36Sopenharmony_ci 490262306a36Sopenharmony_ci if (evergreen_is_display_hung(rdev)) 490362306a36Sopenharmony_ci reset_mask |= RADEON_RESET_DISPLAY; 490462306a36Sopenharmony_ci 490562306a36Sopenharmony_ci /* Skip MC reset as it's mostly likely not hung, just busy */ 490662306a36Sopenharmony_ci if (reset_mask & RADEON_RESET_MC) { 490762306a36Sopenharmony_ci DRM_DEBUG("MC busy: 0x%08X, clearing.\n", reset_mask); 490862306a36Sopenharmony_ci reset_mask &= ~RADEON_RESET_MC; 490962306a36Sopenharmony_ci } 491062306a36Sopenharmony_ci 491162306a36Sopenharmony_ci return reset_mask; 491262306a36Sopenharmony_ci} 491362306a36Sopenharmony_ci 491462306a36Sopenharmony_ci/** 491562306a36Sopenharmony_ci * cik_gpu_soft_reset - soft reset GPU 491662306a36Sopenharmony_ci * 491762306a36Sopenharmony_ci * @rdev: radeon_device pointer 491862306a36Sopenharmony_ci * @reset_mask: mask of which blocks to reset 491962306a36Sopenharmony_ci * 492062306a36Sopenharmony_ci * Soft reset the blocks specified in @reset_mask. 492162306a36Sopenharmony_ci */ 492262306a36Sopenharmony_cistatic void cik_gpu_soft_reset(struct radeon_device *rdev, u32 reset_mask) 492362306a36Sopenharmony_ci{ 492462306a36Sopenharmony_ci struct evergreen_mc_save save; 492562306a36Sopenharmony_ci u32 grbm_soft_reset = 0, srbm_soft_reset = 0; 492662306a36Sopenharmony_ci u32 tmp; 492762306a36Sopenharmony_ci 492862306a36Sopenharmony_ci if (reset_mask == 0) 492962306a36Sopenharmony_ci return; 493062306a36Sopenharmony_ci 493162306a36Sopenharmony_ci dev_info(rdev->dev, "GPU softreset: 0x%08X\n", reset_mask); 493262306a36Sopenharmony_ci 493362306a36Sopenharmony_ci cik_print_gpu_status_regs(rdev); 493462306a36Sopenharmony_ci dev_info(rdev->dev, " VM_CONTEXT1_PROTECTION_FAULT_ADDR 0x%08X\n", 493562306a36Sopenharmony_ci RREG32(VM_CONTEXT1_PROTECTION_FAULT_ADDR)); 493662306a36Sopenharmony_ci dev_info(rdev->dev, " VM_CONTEXT1_PROTECTION_FAULT_STATUS 0x%08X\n", 493762306a36Sopenharmony_ci RREG32(VM_CONTEXT1_PROTECTION_FAULT_STATUS)); 493862306a36Sopenharmony_ci 493962306a36Sopenharmony_ci /* disable CG/PG */ 494062306a36Sopenharmony_ci cik_fini_pg(rdev); 494162306a36Sopenharmony_ci cik_fini_cg(rdev); 494262306a36Sopenharmony_ci 494362306a36Sopenharmony_ci /* stop the rlc */ 494462306a36Sopenharmony_ci cik_rlc_stop(rdev); 494562306a36Sopenharmony_ci 494662306a36Sopenharmony_ci /* Disable GFX parsing/prefetching */ 494762306a36Sopenharmony_ci WREG32(CP_ME_CNTL, CP_ME_HALT | CP_PFP_HALT | CP_CE_HALT); 494862306a36Sopenharmony_ci 494962306a36Sopenharmony_ci /* Disable MEC parsing/prefetching */ 495062306a36Sopenharmony_ci WREG32(CP_MEC_CNTL, MEC_ME1_HALT | MEC_ME2_HALT); 495162306a36Sopenharmony_ci 495262306a36Sopenharmony_ci if (reset_mask & RADEON_RESET_DMA) { 495362306a36Sopenharmony_ci /* sdma0 */ 495462306a36Sopenharmony_ci tmp = RREG32(SDMA0_ME_CNTL + SDMA0_REGISTER_OFFSET); 495562306a36Sopenharmony_ci tmp |= SDMA_HALT; 495662306a36Sopenharmony_ci WREG32(SDMA0_ME_CNTL + SDMA0_REGISTER_OFFSET, tmp); 495762306a36Sopenharmony_ci } 495862306a36Sopenharmony_ci if (reset_mask & RADEON_RESET_DMA1) { 495962306a36Sopenharmony_ci /* sdma1 */ 496062306a36Sopenharmony_ci tmp = RREG32(SDMA0_ME_CNTL + SDMA1_REGISTER_OFFSET); 496162306a36Sopenharmony_ci tmp |= SDMA_HALT; 496262306a36Sopenharmony_ci WREG32(SDMA0_ME_CNTL + SDMA1_REGISTER_OFFSET, tmp); 496362306a36Sopenharmony_ci } 496462306a36Sopenharmony_ci 496562306a36Sopenharmony_ci evergreen_mc_stop(rdev, &save); 496662306a36Sopenharmony_ci if (evergreen_mc_wait_for_idle(rdev)) { 496762306a36Sopenharmony_ci dev_warn(rdev->dev, "Wait for MC idle timedout !\n"); 496862306a36Sopenharmony_ci } 496962306a36Sopenharmony_ci 497062306a36Sopenharmony_ci if (reset_mask & (RADEON_RESET_GFX | RADEON_RESET_COMPUTE | RADEON_RESET_CP)) 497162306a36Sopenharmony_ci grbm_soft_reset = SOFT_RESET_CP | SOFT_RESET_GFX; 497262306a36Sopenharmony_ci 497362306a36Sopenharmony_ci if (reset_mask & RADEON_RESET_CP) { 497462306a36Sopenharmony_ci grbm_soft_reset |= SOFT_RESET_CP; 497562306a36Sopenharmony_ci 497662306a36Sopenharmony_ci srbm_soft_reset |= SOFT_RESET_GRBM; 497762306a36Sopenharmony_ci } 497862306a36Sopenharmony_ci 497962306a36Sopenharmony_ci if (reset_mask & RADEON_RESET_DMA) 498062306a36Sopenharmony_ci srbm_soft_reset |= SOFT_RESET_SDMA; 498162306a36Sopenharmony_ci 498262306a36Sopenharmony_ci if (reset_mask & RADEON_RESET_DMA1) 498362306a36Sopenharmony_ci srbm_soft_reset |= SOFT_RESET_SDMA1; 498462306a36Sopenharmony_ci 498562306a36Sopenharmony_ci if (reset_mask & RADEON_RESET_DISPLAY) 498662306a36Sopenharmony_ci srbm_soft_reset |= SOFT_RESET_DC; 498762306a36Sopenharmony_ci 498862306a36Sopenharmony_ci if (reset_mask & RADEON_RESET_RLC) 498962306a36Sopenharmony_ci grbm_soft_reset |= SOFT_RESET_RLC; 499062306a36Sopenharmony_ci 499162306a36Sopenharmony_ci if (reset_mask & RADEON_RESET_SEM) 499262306a36Sopenharmony_ci srbm_soft_reset |= SOFT_RESET_SEM; 499362306a36Sopenharmony_ci 499462306a36Sopenharmony_ci if (reset_mask & RADEON_RESET_IH) 499562306a36Sopenharmony_ci srbm_soft_reset |= SOFT_RESET_IH; 499662306a36Sopenharmony_ci 499762306a36Sopenharmony_ci if (reset_mask & RADEON_RESET_GRBM) 499862306a36Sopenharmony_ci srbm_soft_reset |= SOFT_RESET_GRBM; 499962306a36Sopenharmony_ci 500062306a36Sopenharmony_ci if (reset_mask & RADEON_RESET_VMC) 500162306a36Sopenharmony_ci srbm_soft_reset |= SOFT_RESET_VMC; 500262306a36Sopenharmony_ci 500362306a36Sopenharmony_ci if (!(rdev->flags & RADEON_IS_IGP)) { 500462306a36Sopenharmony_ci if (reset_mask & RADEON_RESET_MC) 500562306a36Sopenharmony_ci srbm_soft_reset |= SOFT_RESET_MC; 500662306a36Sopenharmony_ci } 500762306a36Sopenharmony_ci 500862306a36Sopenharmony_ci if (grbm_soft_reset) { 500962306a36Sopenharmony_ci tmp = RREG32(GRBM_SOFT_RESET); 501062306a36Sopenharmony_ci tmp |= grbm_soft_reset; 501162306a36Sopenharmony_ci dev_info(rdev->dev, "GRBM_SOFT_RESET=0x%08X\n", tmp); 501262306a36Sopenharmony_ci WREG32(GRBM_SOFT_RESET, tmp); 501362306a36Sopenharmony_ci tmp = RREG32(GRBM_SOFT_RESET); 501462306a36Sopenharmony_ci 501562306a36Sopenharmony_ci udelay(50); 501662306a36Sopenharmony_ci 501762306a36Sopenharmony_ci tmp &= ~grbm_soft_reset; 501862306a36Sopenharmony_ci WREG32(GRBM_SOFT_RESET, tmp); 501962306a36Sopenharmony_ci tmp = RREG32(GRBM_SOFT_RESET); 502062306a36Sopenharmony_ci } 502162306a36Sopenharmony_ci 502262306a36Sopenharmony_ci if (srbm_soft_reset) { 502362306a36Sopenharmony_ci tmp = RREG32(SRBM_SOFT_RESET); 502462306a36Sopenharmony_ci tmp |= srbm_soft_reset; 502562306a36Sopenharmony_ci dev_info(rdev->dev, "SRBM_SOFT_RESET=0x%08X\n", tmp); 502662306a36Sopenharmony_ci WREG32(SRBM_SOFT_RESET, tmp); 502762306a36Sopenharmony_ci tmp = RREG32(SRBM_SOFT_RESET); 502862306a36Sopenharmony_ci 502962306a36Sopenharmony_ci udelay(50); 503062306a36Sopenharmony_ci 503162306a36Sopenharmony_ci tmp &= ~srbm_soft_reset; 503262306a36Sopenharmony_ci WREG32(SRBM_SOFT_RESET, tmp); 503362306a36Sopenharmony_ci tmp = RREG32(SRBM_SOFT_RESET); 503462306a36Sopenharmony_ci } 503562306a36Sopenharmony_ci 503662306a36Sopenharmony_ci /* Wait a little for things to settle down */ 503762306a36Sopenharmony_ci udelay(50); 503862306a36Sopenharmony_ci 503962306a36Sopenharmony_ci evergreen_mc_resume(rdev, &save); 504062306a36Sopenharmony_ci udelay(50); 504162306a36Sopenharmony_ci 504262306a36Sopenharmony_ci cik_print_gpu_status_regs(rdev); 504362306a36Sopenharmony_ci} 504462306a36Sopenharmony_ci 504562306a36Sopenharmony_cistruct kv_reset_save_regs { 504662306a36Sopenharmony_ci u32 gmcon_reng_execute; 504762306a36Sopenharmony_ci u32 gmcon_misc; 504862306a36Sopenharmony_ci u32 gmcon_misc3; 504962306a36Sopenharmony_ci}; 505062306a36Sopenharmony_ci 505162306a36Sopenharmony_cistatic void kv_save_regs_for_reset(struct radeon_device *rdev, 505262306a36Sopenharmony_ci struct kv_reset_save_regs *save) 505362306a36Sopenharmony_ci{ 505462306a36Sopenharmony_ci save->gmcon_reng_execute = RREG32(GMCON_RENG_EXECUTE); 505562306a36Sopenharmony_ci save->gmcon_misc = RREG32(GMCON_MISC); 505662306a36Sopenharmony_ci save->gmcon_misc3 = RREG32(GMCON_MISC3); 505762306a36Sopenharmony_ci 505862306a36Sopenharmony_ci WREG32(GMCON_RENG_EXECUTE, save->gmcon_reng_execute & ~RENG_EXECUTE_ON_PWR_UP); 505962306a36Sopenharmony_ci WREG32(GMCON_MISC, save->gmcon_misc & ~(RENG_EXECUTE_ON_REG_UPDATE | 506062306a36Sopenharmony_ci STCTRL_STUTTER_EN)); 506162306a36Sopenharmony_ci} 506262306a36Sopenharmony_ci 506362306a36Sopenharmony_cistatic void kv_restore_regs_for_reset(struct radeon_device *rdev, 506462306a36Sopenharmony_ci struct kv_reset_save_regs *save) 506562306a36Sopenharmony_ci{ 506662306a36Sopenharmony_ci int i; 506762306a36Sopenharmony_ci 506862306a36Sopenharmony_ci WREG32(GMCON_PGFSM_WRITE, 0); 506962306a36Sopenharmony_ci WREG32(GMCON_PGFSM_CONFIG, 0x200010ff); 507062306a36Sopenharmony_ci 507162306a36Sopenharmony_ci for (i = 0; i < 5; i++) 507262306a36Sopenharmony_ci WREG32(GMCON_PGFSM_WRITE, 0); 507362306a36Sopenharmony_ci 507462306a36Sopenharmony_ci WREG32(GMCON_PGFSM_WRITE, 0); 507562306a36Sopenharmony_ci WREG32(GMCON_PGFSM_CONFIG, 0x300010ff); 507662306a36Sopenharmony_ci 507762306a36Sopenharmony_ci for (i = 0; i < 5; i++) 507862306a36Sopenharmony_ci WREG32(GMCON_PGFSM_WRITE, 0); 507962306a36Sopenharmony_ci 508062306a36Sopenharmony_ci WREG32(GMCON_PGFSM_WRITE, 0x210000); 508162306a36Sopenharmony_ci WREG32(GMCON_PGFSM_CONFIG, 0xa00010ff); 508262306a36Sopenharmony_ci 508362306a36Sopenharmony_ci for (i = 0; i < 5; i++) 508462306a36Sopenharmony_ci WREG32(GMCON_PGFSM_WRITE, 0); 508562306a36Sopenharmony_ci 508662306a36Sopenharmony_ci WREG32(GMCON_PGFSM_WRITE, 0x21003); 508762306a36Sopenharmony_ci WREG32(GMCON_PGFSM_CONFIG, 0xb00010ff); 508862306a36Sopenharmony_ci 508962306a36Sopenharmony_ci for (i = 0; i < 5; i++) 509062306a36Sopenharmony_ci WREG32(GMCON_PGFSM_WRITE, 0); 509162306a36Sopenharmony_ci 509262306a36Sopenharmony_ci WREG32(GMCON_PGFSM_WRITE, 0x2b00); 509362306a36Sopenharmony_ci WREG32(GMCON_PGFSM_CONFIG, 0xc00010ff); 509462306a36Sopenharmony_ci 509562306a36Sopenharmony_ci for (i = 0; i < 5; i++) 509662306a36Sopenharmony_ci WREG32(GMCON_PGFSM_WRITE, 0); 509762306a36Sopenharmony_ci 509862306a36Sopenharmony_ci WREG32(GMCON_PGFSM_WRITE, 0); 509962306a36Sopenharmony_ci WREG32(GMCON_PGFSM_CONFIG, 0xd00010ff); 510062306a36Sopenharmony_ci 510162306a36Sopenharmony_ci for (i = 0; i < 5; i++) 510262306a36Sopenharmony_ci WREG32(GMCON_PGFSM_WRITE, 0); 510362306a36Sopenharmony_ci 510462306a36Sopenharmony_ci WREG32(GMCON_PGFSM_WRITE, 0x420000); 510562306a36Sopenharmony_ci WREG32(GMCON_PGFSM_CONFIG, 0x100010ff); 510662306a36Sopenharmony_ci 510762306a36Sopenharmony_ci for (i = 0; i < 5; i++) 510862306a36Sopenharmony_ci WREG32(GMCON_PGFSM_WRITE, 0); 510962306a36Sopenharmony_ci 511062306a36Sopenharmony_ci WREG32(GMCON_PGFSM_WRITE, 0x120202); 511162306a36Sopenharmony_ci WREG32(GMCON_PGFSM_CONFIG, 0x500010ff); 511262306a36Sopenharmony_ci 511362306a36Sopenharmony_ci for (i = 0; i < 5; i++) 511462306a36Sopenharmony_ci WREG32(GMCON_PGFSM_WRITE, 0); 511562306a36Sopenharmony_ci 511662306a36Sopenharmony_ci WREG32(GMCON_PGFSM_WRITE, 0x3e3e36); 511762306a36Sopenharmony_ci WREG32(GMCON_PGFSM_CONFIG, 0x600010ff); 511862306a36Sopenharmony_ci 511962306a36Sopenharmony_ci for (i = 0; i < 5; i++) 512062306a36Sopenharmony_ci WREG32(GMCON_PGFSM_WRITE, 0); 512162306a36Sopenharmony_ci 512262306a36Sopenharmony_ci WREG32(GMCON_PGFSM_WRITE, 0x373f3e); 512362306a36Sopenharmony_ci WREG32(GMCON_PGFSM_CONFIG, 0x700010ff); 512462306a36Sopenharmony_ci 512562306a36Sopenharmony_ci for (i = 0; i < 5; i++) 512662306a36Sopenharmony_ci WREG32(GMCON_PGFSM_WRITE, 0); 512762306a36Sopenharmony_ci 512862306a36Sopenharmony_ci WREG32(GMCON_PGFSM_WRITE, 0x3e1332); 512962306a36Sopenharmony_ci WREG32(GMCON_PGFSM_CONFIG, 0xe00010ff); 513062306a36Sopenharmony_ci 513162306a36Sopenharmony_ci WREG32(GMCON_MISC3, save->gmcon_misc3); 513262306a36Sopenharmony_ci WREG32(GMCON_MISC, save->gmcon_misc); 513362306a36Sopenharmony_ci WREG32(GMCON_RENG_EXECUTE, save->gmcon_reng_execute); 513462306a36Sopenharmony_ci} 513562306a36Sopenharmony_ci 513662306a36Sopenharmony_cistatic void cik_gpu_pci_config_reset(struct radeon_device *rdev) 513762306a36Sopenharmony_ci{ 513862306a36Sopenharmony_ci struct evergreen_mc_save save; 513962306a36Sopenharmony_ci struct kv_reset_save_regs kv_save = { 0 }; 514062306a36Sopenharmony_ci u32 tmp, i; 514162306a36Sopenharmony_ci 514262306a36Sopenharmony_ci dev_info(rdev->dev, "GPU pci config reset\n"); 514362306a36Sopenharmony_ci 514462306a36Sopenharmony_ci /* disable dpm? */ 514562306a36Sopenharmony_ci 514662306a36Sopenharmony_ci /* disable cg/pg */ 514762306a36Sopenharmony_ci cik_fini_pg(rdev); 514862306a36Sopenharmony_ci cik_fini_cg(rdev); 514962306a36Sopenharmony_ci 515062306a36Sopenharmony_ci /* Disable GFX parsing/prefetching */ 515162306a36Sopenharmony_ci WREG32(CP_ME_CNTL, CP_ME_HALT | CP_PFP_HALT | CP_CE_HALT); 515262306a36Sopenharmony_ci 515362306a36Sopenharmony_ci /* Disable MEC parsing/prefetching */ 515462306a36Sopenharmony_ci WREG32(CP_MEC_CNTL, MEC_ME1_HALT | MEC_ME2_HALT); 515562306a36Sopenharmony_ci 515662306a36Sopenharmony_ci /* sdma0 */ 515762306a36Sopenharmony_ci tmp = RREG32(SDMA0_ME_CNTL + SDMA0_REGISTER_OFFSET); 515862306a36Sopenharmony_ci tmp |= SDMA_HALT; 515962306a36Sopenharmony_ci WREG32(SDMA0_ME_CNTL + SDMA0_REGISTER_OFFSET, tmp); 516062306a36Sopenharmony_ci /* sdma1 */ 516162306a36Sopenharmony_ci tmp = RREG32(SDMA0_ME_CNTL + SDMA1_REGISTER_OFFSET); 516262306a36Sopenharmony_ci tmp |= SDMA_HALT; 516362306a36Sopenharmony_ci WREG32(SDMA0_ME_CNTL + SDMA1_REGISTER_OFFSET, tmp); 516462306a36Sopenharmony_ci /* XXX other engines? */ 516562306a36Sopenharmony_ci 516662306a36Sopenharmony_ci /* halt the rlc, disable cp internal ints */ 516762306a36Sopenharmony_ci cik_rlc_stop(rdev); 516862306a36Sopenharmony_ci 516962306a36Sopenharmony_ci udelay(50); 517062306a36Sopenharmony_ci 517162306a36Sopenharmony_ci /* disable mem access */ 517262306a36Sopenharmony_ci evergreen_mc_stop(rdev, &save); 517362306a36Sopenharmony_ci if (evergreen_mc_wait_for_idle(rdev)) { 517462306a36Sopenharmony_ci dev_warn(rdev->dev, "Wait for MC idle timed out !\n"); 517562306a36Sopenharmony_ci } 517662306a36Sopenharmony_ci 517762306a36Sopenharmony_ci if (rdev->flags & RADEON_IS_IGP) 517862306a36Sopenharmony_ci kv_save_regs_for_reset(rdev, &kv_save); 517962306a36Sopenharmony_ci 518062306a36Sopenharmony_ci /* disable BM */ 518162306a36Sopenharmony_ci pci_clear_master(rdev->pdev); 518262306a36Sopenharmony_ci /* reset */ 518362306a36Sopenharmony_ci radeon_pci_config_reset(rdev); 518462306a36Sopenharmony_ci 518562306a36Sopenharmony_ci udelay(100); 518662306a36Sopenharmony_ci 518762306a36Sopenharmony_ci /* wait for asic to come out of reset */ 518862306a36Sopenharmony_ci for (i = 0; i < rdev->usec_timeout; i++) { 518962306a36Sopenharmony_ci if (RREG32(CONFIG_MEMSIZE) != 0xffffffff) 519062306a36Sopenharmony_ci break; 519162306a36Sopenharmony_ci udelay(1); 519262306a36Sopenharmony_ci } 519362306a36Sopenharmony_ci 519462306a36Sopenharmony_ci /* does asic init need to be run first??? */ 519562306a36Sopenharmony_ci if (rdev->flags & RADEON_IS_IGP) 519662306a36Sopenharmony_ci kv_restore_regs_for_reset(rdev, &kv_save); 519762306a36Sopenharmony_ci} 519862306a36Sopenharmony_ci 519962306a36Sopenharmony_ci/** 520062306a36Sopenharmony_ci * cik_asic_reset - soft reset GPU 520162306a36Sopenharmony_ci * 520262306a36Sopenharmony_ci * @rdev: radeon_device pointer 520362306a36Sopenharmony_ci * @hard: force hard reset 520462306a36Sopenharmony_ci * 520562306a36Sopenharmony_ci * Look up which blocks are hung and attempt 520662306a36Sopenharmony_ci * to reset them. 520762306a36Sopenharmony_ci * Returns 0 for success. 520862306a36Sopenharmony_ci */ 520962306a36Sopenharmony_ciint cik_asic_reset(struct radeon_device *rdev, bool hard) 521062306a36Sopenharmony_ci{ 521162306a36Sopenharmony_ci u32 reset_mask; 521262306a36Sopenharmony_ci 521362306a36Sopenharmony_ci if (hard) { 521462306a36Sopenharmony_ci cik_gpu_pci_config_reset(rdev); 521562306a36Sopenharmony_ci return 0; 521662306a36Sopenharmony_ci } 521762306a36Sopenharmony_ci 521862306a36Sopenharmony_ci reset_mask = cik_gpu_check_soft_reset(rdev); 521962306a36Sopenharmony_ci 522062306a36Sopenharmony_ci if (reset_mask) 522162306a36Sopenharmony_ci r600_set_bios_scratch_engine_hung(rdev, true); 522262306a36Sopenharmony_ci 522362306a36Sopenharmony_ci /* try soft reset */ 522462306a36Sopenharmony_ci cik_gpu_soft_reset(rdev, reset_mask); 522562306a36Sopenharmony_ci 522662306a36Sopenharmony_ci reset_mask = cik_gpu_check_soft_reset(rdev); 522762306a36Sopenharmony_ci 522862306a36Sopenharmony_ci /* try pci config reset */ 522962306a36Sopenharmony_ci if (reset_mask && radeon_hard_reset) 523062306a36Sopenharmony_ci cik_gpu_pci_config_reset(rdev); 523162306a36Sopenharmony_ci 523262306a36Sopenharmony_ci reset_mask = cik_gpu_check_soft_reset(rdev); 523362306a36Sopenharmony_ci 523462306a36Sopenharmony_ci if (!reset_mask) 523562306a36Sopenharmony_ci r600_set_bios_scratch_engine_hung(rdev, false); 523662306a36Sopenharmony_ci 523762306a36Sopenharmony_ci return 0; 523862306a36Sopenharmony_ci} 523962306a36Sopenharmony_ci 524062306a36Sopenharmony_ci/** 524162306a36Sopenharmony_ci * cik_gfx_is_lockup - check if the 3D engine is locked up 524262306a36Sopenharmony_ci * 524362306a36Sopenharmony_ci * @rdev: radeon_device pointer 524462306a36Sopenharmony_ci * @ring: radeon_ring structure holding ring information 524562306a36Sopenharmony_ci * 524662306a36Sopenharmony_ci * Check if the 3D engine is locked up (CIK). 524762306a36Sopenharmony_ci * Returns true if the engine is locked, false if not. 524862306a36Sopenharmony_ci */ 524962306a36Sopenharmony_cibool cik_gfx_is_lockup(struct radeon_device *rdev, struct radeon_ring *ring) 525062306a36Sopenharmony_ci{ 525162306a36Sopenharmony_ci u32 reset_mask = cik_gpu_check_soft_reset(rdev); 525262306a36Sopenharmony_ci 525362306a36Sopenharmony_ci if (!(reset_mask & (RADEON_RESET_GFX | 525462306a36Sopenharmony_ci RADEON_RESET_COMPUTE | 525562306a36Sopenharmony_ci RADEON_RESET_CP))) { 525662306a36Sopenharmony_ci radeon_ring_lockup_update(rdev, ring); 525762306a36Sopenharmony_ci return false; 525862306a36Sopenharmony_ci } 525962306a36Sopenharmony_ci return radeon_ring_test_lockup(rdev, ring); 526062306a36Sopenharmony_ci} 526162306a36Sopenharmony_ci 526262306a36Sopenharmony_ci/* MC */ 526362306a36Sopenharmony_ci/** 526462306a36Sopenharmony_ci * cik_mc_program - program the GPU memory controller 526562306a36Sopenharmony_ci * 526662306a36Sopenharmony_ci * @rdev: radeon_device pointer 526762306a36Sopenharmony_ci * 526862306a36Sopenharmony_ci * Set the location of vram, gart, and AGP in the GPU's 526962306a36Sopenharmony_ci * physical address space (CIK). 527062306a36Sopenharmony_ci */ 527162306a36Sopenharmony_cistatic void cik_mc_program(struct radeon_device *rdev) 527262306a36Sopenharmony_ci{ 527362306a36Sopenharmony_ci struct evergreen_mc_save save; 527462306a36Sopenharmony_ci u32 tmp; 527562306a36Sopenharmony_ci int i, j; 527662306a36Sopenharmony_ci 527762306a36Sopenharmony_ci /* Initialize HDP */ 527862306a36Sopenharmony_ci for (i = 0, j = 0; i < 32; i++, j += 0x18) { 527962306a36Sopenharmony_ci WREG32((0x2c14 + j), 0x00000000); 528062306a36Sopenharmony_ci WREG32((0x2c18 + j), 0x00000000); 528162306a36Sopenharmony_ci WREG32((0x2c1c + j), 0x00000000); 528262306a36Sopenharmony_ci WREG32((0x2c20 + j), 0x00000000); 528362306a36Sopenharmony_ci WREG32((0x2c24 + j), 0x00000000); 528462306a36Sopenharmony_ci } 528562306a36Sopenharmony_ci WREG32(HDP_REG_COHERENCY_FLUSH_CNTL, 0); 528662306a36Sopenharmony_ci 528762306a36Sopenharmony_ci evergreen_mc_stop(rdev, &save); 528862306a36Sopenharmony_ci if (radeon_mc_wait_for_idle(rdev)) { 528962306a36Sopenharmony_ci dev_warn(rdev->dev, "Wait for MC idle timedout !\n"); 529062306a36Sopenharmony_ci } 529162306a36Sopenharmony_ci /* Lockout access through VGA aperture*/ 529262306a36Sopenharmony_ci WREG32(VGA_HDP_CONTROL, VGA_MEMORY_DISABLE); 529362306a36Sopenharmony_ci /* Update configuration */ 529462306a36Sopenharmony_ci WREG32(MC_VM_SYSTEM_APERTURE_LOW_ADDR, 529562306a36Sopenharmony_ci rdev->mc.vram_start >> 12); 529662306a36Sopenharmony_ci WREG32(MC_VM_SYSTEM_APERTURE_HIGH_ADDR, 529762306a36Sopenharmony_ci rdev->mc.vram_end >> 12); 529862306a36Sopenharmony_ci WREG32(MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR, 529962306a36Sopenharmony_ci rdev->vram_scratch.gpu_addr >> 12); 530062306a36Sopenharmony_ci tmp = ((rdev->mc.vram_end >> 24) & 0xFFFF) << 16; 530162306a36Sopenharmony_ci tmp |= ((rdev->mc.vram_start >> 24) & 0xFFFF); 530262306a36Sopenharmony_ci WREG32(MC_VM_FB_LOCATION, tmp); 530362306a36Sopenharmony_ci /* XXX double check these! */ 530462306a36Sopenharmony_ci WREG32(HDP_NONSURFACE_BASE, (rdev->mc.vram_start >> 8)); 530562306a36Sopenharmony_ci WREG32(HDP_NONSURFACE_INFO, (2 << 7) | (1 << 30)); 530662306a36Sopenharmony_ci WREG32(HDP_NONSURFACE_SIZE, 0x3FFFFFFF); 530762306a36Sopenharmony_ci WREG32(MC_VM_AGP_BASE, 0); 530862306a36Sopenharmony_ci WREG32(MC_VM_AGP_TOP, 0x0FFFFFFF); 530962306a36Sopenharmony_ci WREG32(MC_VM_AGP_BOT, 0x0FFFFFFF); 531062306a36Sopenharmony_ci if (radeon_mc_wait_for_idle(rdev)) { 531162306a36Sopenharmony_ci dev_warn(rdev->dev, "Wait for MC idle timedout !\n"); 531262306a36Sopenharmony_ci } 531362306a36Sopenharmony_ci evergreen_mc_resume(rdev, &save); 531462306a36Sopenharmony_ci /* we need to own VRAM, so turn off the VGA renderer here 531562306a36Sopenharmony_ci * to stop it overwriting our objects */ 531662306a36Sopenharmony_ci rv515_vga_render_disable(rdev); 531762306a36Sopenharmony_ci} 531862306a36Sopenharmony_ci 531962306a36Sopenharmony_ci/** 532062306a36Sopenharmony_ci * cik_mc_init - initialize the memory controller driver params 532162306a36Sopenharmony_ci * 532262306a36Sopenharmony_ci * @rdev: radeon_device pointer 532362306a36Sopenharmony_ci * 532462306a36Sopenharmony_ci * Look up the amount of vram, vram width, and decide how to place 532562306a36Sopenharmony_ci * vram and gart within the GPU's physical address space (CIK). 532662306a36Sopenharmony_ci * Returns 0 for success. 532762306a36Sopenharmony_ci */ 532862306a36Sopenharmony_cistatic int cik_mc_init(struct radeon_device *rdev) 532962306a36Sopenharmony_ci{ 533062306a36Sopenharmony_ci u32 tmp; 533162306a36Sopenharmony_ci int chansize, numchan; 533262306a36Sopenharmony_ci 533362306a36Sopenharmony_ci /* Get VRAM informations */ 533462306a36Sopenharmony_ci rdev->mc.vram_is_ddr = true; 533562306a36Sopenharmony_ci tmp = RREG32(MC_ARB_RAMCFG); 533662306a36Sopenharmony_ci if (tmp & CHANSIZE_MASK) { 533762306a36Sopenharmony_ci chansize = 64; 533862306a36Sopenharmony_ci } else { 533962306a36Sopenharmony_ci chansize = 32; 534062306a36Sopenharmony_ci } 534162306a36Sopenharmony_ci tmp = RREG32(MC_SHARED_CHMAP); 534262306a36Sopenharmony_ci switch ((tmp & NOOFCHAN_MASK) >> NOOFCHAN_SHIFT) { 534362306a36Sopenharmony_ci case 0: 534462306a36Sopenharmony_ci default: 534562306a36Sopenharmony_ci numchan = 1; 534662306a36Sopenharmony_ci break; 534762306a36Sopenharmony_ci case 1: 534862306a36Sopenharmony_ci numchan = 2; 534962306a36Sopenharmony_ci break; 535062306a36Sopenharmony_ci case 2: 535162306a36Sopenharmony_ci numchan = 4; 535262306a36Sopenharmony_ci break; 535362306a36Sopenharmony_ci case 3: 535462306a36Sopenharmony_ci numchan = 8; 535562306a36Sopenharmony_ci break; 535662306a36Sopenharmony_ci case 4: 535762306a36Sopenharmony_ci numchan = 3; 535862306a36Sopenharmony_ci break; 535962306a36Sopenharmony_ci case 5: 536062306a36Sopenharmony_ci numchan = 6; 536162306a36Sopenharmony_ci break; 536262306a36Sopenharmony_ci case 6: 536362306a36Sopenharmony_ci numchan = 10; 536462306a36Sopenharmony_ci break; 536562306a36Sopenharmony_ci case 7: 536662306a36Sopenharmony_ci numchan = 12; 536762306a36Sopenharmony_ci break; 536862306a36Sopenharmony_ci case 8: 536962306a36Sopenharmony_ci numchan = 16; 537062306a36Sopenharmony_ci break; 537162306a36Sopenharmony_ci } 537262306a36Sopenharmony_ci rdev->mc.vram_width = numchan * chansize; 537362306a36Sopenharmony_ci /* Could aper size report 0 ? */ 537462306a36Sopenharmony_ci rdev->mc.aper_base = pci_resource_start(rdev->pdev, 0); 537562306a36Sopenharmony_ci rdev->mc.aper_size = pci_resource_len(rdev->pdev, 0); 537662306a36Sopenharmony_ci /* size in MB on si */ 537762306a36Sopenharmony_ci rdev->mc.mc_vram_size = RREG32(CONFIG_MEMSIZE) * 1024ULL * 1024ULL; 537862306a36Sopenharmony_ci rdev->mc.real_vram_size = RREG32(CONFIG_MEMSIZE) * 1024ULL * 1024ULL; 537962306a36Sopenharmony_ci rdev->mc.visible_vram_size = rdev->mc.aper_size; 538062306a36Sopenharmony_ci si_vram_gtt_location(rdev, &rdev->mc); 538162306a36Sopenharmony_ci radeon_update_bandwidth_info(rdev); 538262306a36Sopenharmony_ci 538362306a36Sopenharmony_ci return 0; 538462306a36Sopenharmony_ci} 538562306a36Sopenharmony_ci 538662306a36Sopenharmony_ci/* 538762306a36Sopenharmony_ci * GART 538862306a36Sopenharmony_ci * VMID 0 is the physical GPU addresses as used by the kernel. 538962306a36Sopenharmony_ci * VMIDs 1-15 are used for userspace clients and are handled 539062306a36Sopenharmony_ci * by the radeon vm/hsa code. 539162306a36Sopenharmony_ci */ 539262306a36Sopenharmony_ci/** 539362306a36Sopenharmony_ci * cik_pcie_gart_tlb_flush - gart tlb flush callback 539462306a36Sopenharmony_ci * 539562306a36Sopenharmony_ci * @rdev: radeon_device pointer 539662306a36Sopenharmony_ci * 539762306a36Sopenharmony_ci * Flush the TLB for the VMID 0 page table (CIK). 539862306a36Sopenharmony_ci */ 539962306a36Sopenharmony_civoid cik_pcie_gart_tlb_flush(struct radeon_device *rdev) 540062306a36Sopenharmony_ci{ 540162306a36Sopenharmony_ci /* flush hdp cache */ 540262306a36Sopenharmony_ci WREG32(HDP_MEM_COHERENCY_FLUSH_CNTL, 0); 540362306a36Sopenharmony_ci 540462306a36Sopenharmony_ci /* bits 0-15 are the VM contexts0-15 */ 540562306a36Sopenharmony_ci WREG32(VM_INVALIDATE_REQUEST, 0x1); 540662306a36Sopenharmony_ci} 540762306a36Sopenharmony_ci 540862306a36Sopenharmony_ci/** 540962306a36Sopenharmony_ci * cik_pcie_gart_enable - gart enable 541062306a36Sopenharmony_ci * 541162306a36Sopenharmony_ci * @rdev: radeon_device pointer 541262306a36Sopenharmony_ci * 541362306a36Sopenharmony_ci * This sets up the TLBs, programs the page tables for VMID0, 541462306a36Sopenharmony_ci * sets up the hw for VMIDs 1-15 which are allocated on 541562306a36Sopenharmony_ci * demand, and sets up the global locations for the LDS, GDS, 541662306a36Sopenharmony_ci * and GPUVM for FSA64 clients (CIK). 541762306a36Sopenharmony_ci * Returns 0 for success, errors for failure. 541862306a36Sopenharmony_ci */ 541962306a36Sopenharmony_cistatic int cik_pcie_gart_enable(struct radeon_device *rdev) 542062306a36Sopenharmony_ci{ 542162306a36Sopenharmony_ci int r, i; 542262306a36Sopenharmony_ci 542362306a36Sopenharmony_ci if (rdev->gart.robj == NULL) { 542462306a36Sopenharmony_ci dev_err(rdev->dev, "No VRAM object for PCIE GART.\n"); 542562306a36Sopenharmony_ci return -EINVAL; 542662306a36Sopenharmony_ci } 542762306a36Sopenharmony_ci r = radeon_gart_table_vram_pin(rdev); 542862306a36Sopenharmony_ci if (r) 542962306a36Sopenharmony_ci return r; 543062306a36Sopenharmony_ci /* Setup TLB control */ 543162306a36Sopenharmony_ci WREG32(MC_VM_MX_L1_TLB_CNTL, 543262306a36Sopenharmony_ci (0xA << 7) | 543362306a36Sopenharmony_ci ENABLE_L1_TLB | 543462306a36Sopenharmony_ci ENABLE_L1_FRAGMENT_PROCESSING | 543562306a36Sopenharmony_ci SYSTEM_ACCESS_MODE_NOT_IN_SYS | 543662306a36Sopenharmony_ci ENABLE_ADVANCED_DRIVER_MODEL | 543762306a36Sopenharmony_ci SYSTEM_APERTURE_UNMAPPED_ACCESS_PASS_THRU); 543862306a36Sopenharmony_ci /* Setup L2 cache */ 543962306a36Sopenharmony_ci WREG32(VM_L2_CNTL, ENABLE_L2_CACHE | 544062306a36Sopenharmony_ci ENABLE_L2_FRAGMENT_PROCESSING | 544162306a36Sopenharmony_ci ENABLE_L2_PTE_CACHE_LRU_UPDATE_BY_WRITE | 544262306a36Sopenharmony_ci ENABLE_L2_PDE0_CACHE_LRU_UPDATE_BY_WRITE | 544362306a36Sopenharmony_ci EFFECTIVE_L2_QUEUE_SIZE(7) | 544462306a36Sopenharmony_ci CONTEXT1_IDENTITY_ACCESS_MODE(1)); 544562306a36Sopenharmony_ci WREG32(VM_L2_CNTL2, INVALIDATE_ALL_L1_TLBS | INVALIDATE_L2_CACHE); 544662306a36Sopenharmony_ci WREG32(VM_L2_CNTL3, L2_CACHE_BIGK_ASSOCIATIVITY | 544762306a36Sopenharmony_ci BANK_SELECT(4) | 544862306a36Sopenharmony_ci L2_CACHE_BIGK_FRAGMENT_SIZE(4)); 544962306a36Sopenharmony_ci /* setup context0 */ 545062306a36Sopenharmony_ci WREG32(VM_CONTEXT0_PAGE_TABLE_START_ADDR, rdev->mc.gtt_start >> 12); 545162306a36Sopenharmony_ci WREG32(VM_CONTEXT0_PAGE_TABLE_END_ADDR, rdev->mc.gtt_end >> 12); 545262306a36Sopenharmony_ci WREG32(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR, rdev->gart.table_addr >> 12); 545362306a36Sopenharmony_ci WREG32(VM_CONTEXT0_PROTECTION_FAULT_DEFAULT_ADDR, 545462306a36Sopenharmony_ci (u32)(rdev->dummy_page.addr >> 12)); 545562306a36Sopenharmony_ci WREG32(VM_CONTEXT0_CNTL2, 0); 545662306a36Sopenharmony_ci WREG32(VM_CONTEXT0_CNTL, (ENABLE_CONTEXT | PAGE_TABLE_DEPTH(0) | 545762306a36Sopenharmony_ci RANGE_PROTECTION_FAULT_ENABLE_DEFAULT)); 545862306a36Sopenharmony_ci 545962306a36Sopenharmony_ci WREG32(0x15D4, 0); 546062306a36Sopenharmony_ci WREG32(0x15D8, 0); 546162306a36Sopenharmony_ci WREG32(0x15DC, 0); 546262306a36Sopenharmony_ci 546362306a36Sopenharmony_ci /* restore context1-15 */ 546462306a36Sopenharmony_ci /* set vm size, must be a multiple of 4 */ 546562306a36Sopenharmony_ci WREG32(VM_CONTEXT1_PAGE_TABLE_START_ADDR, 0); 546662306a36Sopenharmony_ci WREG32(VM_CONTEXT1_PAGE_TABLE_END_ADDR, rdev->vm_manager.max_pfn - 1); 546762306a36Sopenharmony_ci for (i = 1; i < 16; i++) { 546862306a36Sopenharmony_ci if (i < 8) 546962306a36Sopenharmony_ci WREG32(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR + (i << 2), 547062306a36Sopenharmony_ci rdev->vm_manager.saved_table_addr[i]); 547162306a36Sopenharmony_ci else 547262306a36Sopenharmony_ci WREG32(VM_CONTEXT8_PAGE_TABLE_BASE_ADDR + ((i - 8) << 2), 547362306a36Sopenharmony_ci rdev->vm_manager.saved_table_addr[i]); 547462306a36Sopenharmony_ci } 547562306a36Sopenharmony_ci 547662306a36Sopenharmony_ci /* enable context1-15 */ 547762306a36Sopenharmony_ci WREG32(VM_CONTEXT1_PROTECTION_FAULT_DEFAULT_ADDR, 547862306a36Sopenharmony_ci (u32)(rdev->dummy_page.addr >> 12)); 547962306a36Sopenharmony_ci WREG32(VM_CONTEXT1_CNTL2, 4); 548062306a36Sopenharmony_ci WREG32(VM_CONTEXT1_CNTL, ENABLE_CONTEXT | PAGE_TABLE_DEPTH(1) | 548162306a36Sopenharmony_ci PAGE_TABLE_BLOCK_SIZE(radeon_vm_block_size - 9) | 548262306a36Sopenharmony_ci RANGE_PROTECTION_FAULT_ENABLE_INTERRUPT | 548362306a36Sopenharmony_ci RANGE_PROTECTION_FAULT_ENABLE_DEFAULT | 548462306a36Sopenharmony_ci DUMMY_PAGE_PROTECTION_FAULT_ENABLE_INTERRUPT | 548562306a36Sopenharmony_ci DUMMY_PAGE_PROTECTION_FAULT_ENABLE_DEFAULT | 548662306a36Sopenharmony_ci PDE0_PROTECTION_FAULT_ENABLE_INTERRUPT | 548762306a36Sopenharmony_ci PDE0_PROTECTION_FAULT_ENABLE_DEFAULT | 548862306a36Sopenharmony_ci VALID_PROTECTION_FAULT_ENABLE_INTERRUPT | 548962306a36Sopenharmony_ci VALID_PROTECTION_FAULT_ENABLE_DEFAULT | 549062306a36Sopenharmony_ci READ_PROTECTION_FAULT_ENABLE_INTERRUPT | 549162306a36Sopenharmony_ci READ_PROTECTION_FAULT_ENABLE_DEFAULT | 549262306a36Sopenharmony_ci WRITE_PROTECTION_FAULT_ENABLE_INTERRUPT | 549362306a36Sopenharmony_ci WRITE_PROTECTION_FAULT_ENABLE_DEFAULT); 549462306a36Sopenharmony_ci 549562306a36Sopenharmony_ci if (rdev->family == CHIP_KAVERI) { 549662306a36Sopenharmony_ci u32 tmp = RREG32(CHUB_CONTROL); 549762306a36Sopenharmony_ci tmp &= ~BYPASS_VM; 549862306a36Sopenharmony_ci WREG32(CHUB_CONTROL, tmp); 549962306a36Sopenharmony_ci } 550062306a36Sopenharmony_ci 550162306a36Sopenharmony_ci /* XXX SH_MEM regs */ 550262306a36Sopenharmony_ci /* where to put LDS, scratch, GPUVM in FSA64 space */ 550362306a36Sopenharmony_ci mutex_lock(&rdev->srbm_mutex); 550462306a36Sopenharmony_ci for (i = 0; i < 16; i++) { 550562306a36Sopenharmony_ci cik_srbm_select(rdev, 0, 0, 0, i); 550662306a36Sopenharmony_ci /* CP and shaders */ 550762306a36Sopenharmony_ci WREG32(SH_MEM_CONFIG, SH_MEM_CONFIG_GFX_DEFAULT); 550862306a36Sopenharmony_ci WREG32(SH_MEM_APE1_BASE, 1); 550962306a36Sopenharmony_ci WREG32(SH_MEM_APE1_LIMIT, 0); 551062306a36Sopenharmony_ci WREG32(SH_MEM_BASES, 0); 551162306a36Sopenharmony_ci /* SDMA GFX */ 551262306a36Sopenharmony_ci WREG32(SDMA0_GFX_VIRTUAL_ADDR + SDMA0_REGISTER_OFFSET, 0); 551362306a36Sopenharmony_ci WREG32(SDMA0_GFX_APE1_CNTL + SDMA0_REGISTER_OFFSET, 0); 551462306a36Sopenharmony_ci WREG32(SDMA0_GFX_VIRTUAL_ADDR + SDMA1_REGISTER_OFFSET, 0); 551562306a36Sopenharmony_ci WREG32(SDMA0_GFX_APE1_CNTL + SDMA1_REGISTER_OFFSET, 0); 551662306a36Sopenharmony_ci /* XXX SDMA RLC - todo */ 551762306a36Sopenharmony_ci } 551862306a36Sopenharmony_ci cik_srbm_select(rdev, 0, 0, 0, 0); 551962306a36Sopenharmony_ci mutex_unlock(&rdev->srbm_mutex); 552062306a36Sopenharmony_ci 552162306a36Sopenharmony_ci cik_pcie_gart_tlb_flush(rdev); 552262306a36Sopenharmony_ci DRM_INFO("PCIE GART of %uM enabled (table at 0x%016llX).\n", 552362306a36Sopenharmony_ci (unsigned)(rdev->mc.gtt_size >> 20), 552462306a36Sopenharmony_ci (unsigned long long)rdev->gart.table_addr); 552562306a36Sopenharmony_ci rdev->gart.ready = true; 552662306a36Sopenharmony_ci return 0; 552762306a36Sopenharmony_ci} 552862306a36Sopenharmony_ci 552962306a36Sopenharmony_ci/** 553062306a36Sopenharmony_ci * cik_pcie_gart_disable - gart disable 553162306a36Sopenharmony_ci * 553262306a36Sopenharmony_ci * @rdev: radeon_device pointer 553362306a36Sopenharmony_ci * 553462306a36Sopenharmony_ci * This disables all VM page table (CIK). 553562306a36Sopenharmony_ci */ 553662306a36Sopenharmony_cistatic void cik_pcie_gart_disable(struct radeon_device *rdev) 553762306a36Sopenharmony_ci{ 553862306a36Sopenharmony_ci unsigned i; 553962306a36Sopenharmony_ci 554062306a36Sopenharmony_ci for (i = 1; i < 16; ++i) { 554162306a36Sopenharmony_ci uint32_t reg; 554262306a36Sopenharmony_ci if (i < 8) 554362306a36Sopenharmony_ci reg = VM_CONTEXT0_PAGE_TABLE_BASE_ADDR + (i << 2); 554462306a36Sopenharmony_ci else 554562306a36Sopenharmony_ci reg = VM_CONTEXT8_PAGE_TABLE_BASE_ADDR + ((i - 8) << 2); 554662306a36Sopenharmony_ci rdev->vm_manager.saved_table_addr[i] = RREG32(reg); 554762306a36Sopenharmony_ci } 554862306a36Sopenharmony_ci 554962306a36Sopenharmony_ci /* Disable all tables */ 555062306a36Sopenharmony_ci WREG32(VM_CONTEXT0_CNTL, 0); 555162306a36Sopenharmony_ci WREG32(VM_CONTEXT1_CNTL, 0); 555262306a36Sopenharmony_ci /* Setup TLB control */ 555362306a36Sopenharmony_ci WREG32(MC_VM_MX_L1_TLB_CNTL, SYSTEM_ACCESS_MODE_NOT_IN_SYS | 555462306a36Sopenharmony_ci SYSTEM_APERTURE_UNMAPPED_ACCESS_PASS_THRU); 555562306a36Sopenharmony_ci /* Setup L2 cache */ 555662306a36Sopenharmony_ci WREG32(VM_L2_CNTL, 555762306a36Sopenharmony_ci ENABLE_L2_FRAGMENT_PROCESSING | 555862306a36Sopenharmony_ci ENABLE_L2_PTE_CACHE_LRU_UPDATE_BY_WRITE | 555962306a36Sopenharmony_ci ENABLE_L2_PDE0_CACHE_LRU_UPDATE_BY_WRITE | 556062306a36Sopenharmony_ci EFFECTIVE_L2_QUEUE_SIZE(7) | 556162306a36Sopenharmony_ci CONTEXT1_IDENTITY_ACCESS_MODE(1)); 556262306a36Sopenharmony_ci WREG32(VM_L2_CNTL2, 0); 556362306a36Sopenharmony_ci WREG32(VM_L2_CNTL3, L2_CACHE_BIGK_ASSOCIATIVITY | 556462306a36Sopenharmony_ci L2_CACHE_BIGK_FRAGMENT_SIZE(6)); 556562306a36Sopenharmony_ci radeon_gart_table_vram_unpin(rdev); 556662306a36Sopenharmony_ci} 556762306a36Sopenharmony_ci 556862306a36Sopenharmony_ci/** 556962306a36Sopenharmony_ci * cik_pcie_gart_fini - vm fini callback 557062306a36Sopenharmony_ci * 557162306a36Sopenharmony_ci * @rdev: radeon_device pointer 557262306a36Sopenharmony_ci * 557362306a36Sopenharmony_ci * Tears down the driver GART/VM setup (CIK). 557462306a36Sopenharmony_ci */ 557562306a36Sopenharmony_cistatic void cik_pcie_gart_fini(struct radeon_device *rdev) 557662306a36Sopenharmony_ci{ 557762306a36Sopenharmony_ci cik_pcie_gart_disable(rdev); 557862306a36Sopenharmony_ci radeon_gart_table_vram_free(rdev); 557962306a36Sopenharmony_ci radeon_gart_fini(rdev); 558062306a36Sopenharmony_ci} 558162306a36Sopenharmony_ci 558262306a36Sopenharmony_ci/* vm parser */ 558362306a36Sopenharmony_ci/** 558462306a36Sopenharmony_ci * cik_ib_parse - vm ib_parse callback 558562306a36Sopenharmony_ci * 558662306a36Sopenharmony_ci * @rdev: radeon_device pointer 558762306a36Sopenharmony_ci * @ib: indirect buffer pointer 558862306a36Sopenharmony_ci * 558962306a36Sopenharmony_ci * CIK uses hw IB checking so this is a nop (CIK). 559062306a36Sopenharmony_ci */ 559162306a36Sopenharmony_ciint cik_ib_parse(struct radeon_device *rdev, struct radeon_ib *ib) 559262306a36Sopenharmony_ci{ 559362306a36Sopenharmony_ci return 0; 559462306a36Sopenharmony_ci} 559562306a36Sopenharmony_ci 559662306a36Sopenharmony_ci/* 559762306a36Sopenharmony_ci * vm 559862306a36Sopenharmony_ci * VMID 0 is the physical GPU addresses as used by the kernel. 559962306a36Sopenharmony_ci * VMIDs 1-15 are used for userspace clients and are handled 560062306a36Sopenharmony_ci * by the radeon vm/hsa code. 560162306a36Sopenharmony_ci */ 560262306a36Sopenharmony_ci/** 560362306a36Sopenharmony_ci * cik_vm_init - cik vm init callback 560462306a36Sopenharmony_ci * 560562306a36Sopenharmony_ci * @rdev: radeon_device pointer 560662306a36Sopenharmony_ci * 560762306a36Sopenharmony_ci * Inits cik specific vm parameters (number of VMs, base of vram for 560862306a36Sopenharmony_ci * VMIDs 1-15) (CIK). 560962306a36Sopenharmony_ci * Returns 0 for success. 561062306a36Sopenharmony_ci */ 561162306a36Sopenharmony_ciint cik_vm_init(struct radeon_device *rdev) 561262306a36Sopenharmony_ci{ 561362306a36Sopenharmony_ci /* 561462306a36Sopenharmony_ci * number of VMs 561562306a36Sopenharmony_ci * VMID 0 is reserved for System 561662306a36Sopenharmony_ci * radeon graphics/compute will use VMIDs 1-15 561762306a36Sopenharmony_ci */ 561862306a36Sopenharmony_ci rdev->vm_manager.nvm = 16; 561962306a36Sopenharmony_ci /* base offset of vram pages */ 562062306a36Sopenharmony_ci if (rdev->flags & RADEON_IS_IGP) { 562162306a36Sopenharmony_ci u64 tmp = RREG32(MC_VM_FB_OFFSET); 562262306a36Sopenharmony_ci tmp <<= 22; 562362306a36Sopenharmony_ci rdev->vm_manager.vram_base_offset = tmp; 562462306a36Sopenharmony_ci } else 562562306a36Sopenharmony_ci rdev->vm_manager.vram_base_offset = 0; 562662306a36Sopenharmony_ci 562762306a36Sopenharmony_ci return 0; 562862306a36Sopenharmony_ci} 562962306a36Sopenharmony_ci 563062306a36Sopenharmony_ci/** 563162306a36Sopenharmony_ci * cik_vm_fini - cik vm fini callback 563262306a36Sopenharmony_ci * 563362306a36Sopenharmony_ci * @rdev: radeon_device pointer 563462306a36Sopenharmony_ci * 563562306a36Sopenharmony_ci * Tear down any asic specific VM setup (CIK). 563662306a36Sopenharmony_ci */ 563762306a36Sopenharmony_civoid cik_vm_fini(struct radeon_device *rdev) 563862306a36Sopenharmony_ci{ 563962306a36Sopenharmony_ci} 564062306a36Sopenharmony_ci 564162306a36Sopenharmony_ci/** 564262306a36Sopenharmony_ci * cik_vm_decode_fault - print human readable fault info 564362306a36Sopenharmony_ci * 564462306a36Sopenharmony_ci * @rdev: radeon_device pointer 564562306a36Sopenharmony_ci * @status: VM_CONTEXT1_PROTECTION_FAULT_STATUS register value 564662306a36Sopenharmony_ci * @addr: VM_CONTEXT1_PROTECTION_FAULT_ADDR register value 564762306a36Sopenharmony_ci * @mc_client: VM_CONTEXT1_PROTECTION_FAULT_MCCLIENT register value 564862306a36Sopenharmony_ci * 564962306a36Sopenharmony_ci * Print human readable fault information (CIK). 565062306a36Sopenharmony_ci */ 565162306a36Sopenharmony_cistatic void cik_vm_decode_fault(struct radeon_device *rdev, 565262306a36Sopenharmony_ci u32 status, u32 addr, u32 mc_client) 565362306a36Sopenharmony_ci{ 565462306a36Sopenharmony_ci u32 mc_id; 565562306a36Sopenharmony_ci u32 vmid = (status & FAULT_VMID_MASK) >> FAULT_VMID_SHIFT; 565662306a36Sopenharmony_ci u32 protections = (status & PROTECTIONS_MASK) >> PROTECTIONS_SHIFT; 565762306a36Sopenharmony_ci char block[5] = { mc_client >> 24, (mc_client >> 16) & 0xff, 565862306a36Sopenharmony_ci (mc_client >> 8) & 0xff, mc_client & 0xff, 0 }; 565962306a36Sopenharmony_ci 566062306a36Sopenharmony_ci if (rdev->family == CHIP_HAWAII) 566162306a36Sopenharmony_ci mc_id = (status & HAWAII_MEMORY_CLIENT_ID_MASK) >> MEMORY_CLIENT_ID_SHIFT; 566262306a36Sopenharmony_ci else 566362306a36Sopenharmony_ci mc_id = (status & MEMORY_CLIENT_ID_MASK) >> MEMORY_CLIENT_ID_SHIFT; 566462306a36Sopenharmony_ci 566562306a36Sopenharmony_ci printk("VM fault (0x%02x, vmid %d) at page %u, %s from '%s' (0x%08x) (%d)\n", 566662306a36Sopenharmony_ci protections, vmid, addr, 566762306a36Sopenharmony_ci (status & MEMORY_CLIENT_RW_MASK) ? "write" : "read", 566862306a36Sopenharmony_ci block, mc_client, mc_id); 566962306a36Sopenharmony_ci} 567062306a36Sopenharmony_ci 567162306a36Sopenharmony_ci/* 567262306a36Sopenharmony_ci * cik_vm_flush - cik vm flush using the CP 567362306a36Sopenharmony_ci * 567462306a36Sopenharmony_ci * Update the page table base and flush the VM TLB 567562306a36Sopenharmony_ci * using the CP (CIK). 567662306a36Sopenharmony_ci */ 567762306a36Sopenharmony_civoid cik_vm_flush(struct radeon_device *rdev, struct radeon_ring *ring, 567862306a36Sopenharmony_ci unsigned vm_id, uint64_t pd_addr) 567962306a36Sopenharmony_ci{ 568062306a36Sopenharmony_ci int usepfp = (ring->idx == RADEON_RING_TYPE_GFX_INDEX); 568162306a36Sopenharmony_ci 568262306a36Sopenharmony_ci radeon_ring_write(ring, PACKET3(PACKET3_WRITE_DATA, 3)); 568362306a36Sopenharmony_ci radeon_ring_write(ring, (WRITE_DATA_ENGINE_SEL(usepfp) | 568462306a36Sopenharmony_ci WRITE_DATA_DST_SEL(0))); 568562306a36Sopenharmony_ci if (vm_id < 8) { 568662306a36Sopenharmony_ci radeon_ring_write(ring, 568762306a36Sopenharmony_ci (VM_CONTEXT0_PAGE_TABLE_BASE_ADDR + (vm_id << 2)) >> 2); 568862306a36Sopenharmony_ci } else { 568962306a36Sopenharmony_ci radeon_ring_write(ring, 569062306a36Sopenharmony_ci (VM_CONTEXT8_PAGE_TABLE_BASE_ADDR + ((vm_id - 8) << 2)) >> 2); 569162306a36Sopenharmony_ci } 569262306a36Sopenharmony_ci radeon_ring_write(ring, 0); 569362306a36Sopenharmony_ci radeon_ring_write(ring, pd_addr >> 12); 569462306a36Sopenharmony_ci 569562306a36Sopenharmony_ci /* update SH_MEM_* regs */ 569662306a36Sopenharmony_ci radeon_ring_write(ring, PACKET3(PACKET3_WRITE_DATA, 3)); 569762306a36Sopenharmony_ci radeon_ring_write(ring, (WRITE_DATA_ENGINE_SEL(usepfp) | 569862306a36Sopenharmony_ci WRITE_DATA_DST_SEL(0))); 569962306a36Sopenharmony_ci radeon_ring_write(ring, SRBM_GFX_CNTL >> 2); 570062306a36Sopenharmony_ci radeon_ring_write(ring, 0); 570162306a36Sopenharmony_ci radeon_ring_write(ring, VMID(vm_id)); 570262306a36Sopenharmony_ci 570362306a36Sopenharmony_ci radeon_ring_write(ring, PACKET3(PACKET3_WRITE_DATA, 6)); 570462306a36Sopenharmony_ci radeon_ring_write(ring, (WRITE_DATA_ENGINE_SEL(usepfp) | 570562306a36Sopenharmony_ci WRITE_DATA_DST_SEL(0))); 570662306a36Sopenharmony_ci radeon_ring_write(ring, SH_MEM_BASES >> 2); 570762306a36Sopenharmony_ci radeon_ring_write(ring, 0); 570862306a36Sopenharmony_ci 570962306a36Sopenharmony_ci radeon_ring_write(ring, 0); /* SH_MEM_BASES */ 571062306a36Sopenharmony_ci radeon_ring_write(ring, SH_MEM_CONFIG_GFX_DEFAULT); /* SH_MEM_CONFIG */ 571162306a36Sopenharmony_ci radeon_ring_write(ring, 1); /* SH_MEM_APE1_BASE */ 571262306a36Sopenharmony_ci radeon_ring_write(ring, 0); /* SH_MEM_APE1_LIMIT */ 571362306a36Sopenharmony_ci 571462306a36Sopenharmony_ci radeon_ring_write(ring, PACKET3(PACKET3_WRITE_DATA, 3)); 571562306a36Sopenharmony_ci radeon_ring_write(ring, (WRITE_DATA_ENGINE_SEL(usepfp) | 571662306a36Sopenharmony_ci WRITE_DATA_DST_SEL(0))); 571762306a36Sopenharmony_ci radeon_ring_write(ring, SRBM_GFX_CNTL >> 2); 571862306a36Sopenharmony_ci radeon_ring_write(ring, 0); 571962306a36Sopenharmony_ci radeon_ring_write(ring, VMID(0)); 572062306a36Sopenharmony_ci 572162306a36Sopenharmony_ci /* HDP flush */ 572262306a36Sopenharmony_ci cik_hdp_flush_cp_ring_emit(rdev, ring->idx); 572362306a36Sopenharmony_ci 572462306a36Sopenharmony_ci /* bits 0-15 are the VM contexts0-15 */ 572562306a36Sopenharmony_ci radeon_ring_write(ring, PACKET3(PACKET3_WRITE_DATA, 3)); 572662306a36Sopenharmony_ci radeon_ring_write(ring, (WRITE_DATA_ENGINE_SEL(usepfp) | 572762306a36Sopenharmony_ci WRITE_DATA_DST_SEL(0))); 572862306a36Sopenharmony_ci radeon_ring_write(ring, VM_INVALIDATE_REQUEST >> 2); 572962306a36Sopenharmony_ci radeon_ring_write(ring, 0); 573062306a36Sopenharmony_ci radeon_ring_write(ring, 1 << vm_id); 573162306a36Sopenharmony_ci 573262306a36Sopenharmony_ci /* wait for the invalidate to complete */ 573362306a36Sopenharmony_ci radeon_ring_write(ring, PACKET3(PACKET3_WAIT_REG_MEM, 5)); 573462306a36Sopenharmony_ci radeon_ring_write(ring, (WAIT_REG_MEM_OPERATION(0) | /* wait */ 573562306a36Sopenharmony_ci WAIT_REG_MEM_FUNCTION(0) | /* always */ 573662306a36Sopenharmony_ci WAIT_REG_MEM_ENGINE(0))); /* me */ 573762306a36Sopenharmony_ci radeon_ring_write(ring, VM_INVALIDATE_REQUEST >> 2); 573862306a36Sopenharmony_ci radeon_ring_write(ring, 0); 573962306a36Sopenharmony_ci radeon_ring_write(ring, 0); /* ref */ 574062306a36Sopenharmony_ci radeon_ring_write(ring, 0); /* mask */ 574162306a36Sopenharmony_ci radeon_ring_write(ring, 0x20); /* poll interval */ 574262306a36Sopenharmony_ci 574362306a36Sopenharmony_ci /* compute doesn't have PFP */ 574462306a36Sopenharmony_ci if (usepfp) { 574562306a36Sopenharmony_ci /* sync PFP to ME, otherwise we might get invalid PFP reads */ 574662306a36Sopenharmony_ci radeon_ring_write(ring, PACKET3(PACKET3_PFP_SYNC_ME, 0)); 574762306a36Sopenharmony_ci radeon_ring_write(ring, 0x0); 574862306a36Sopenharmony_ci } 574962306a36Sopenharmony_ci} 575062306a36Sopenharmony_ci 575162306a36Sopenharmony_ci/* 575262306a36Sopenharmony_ci * RLC 575362306a36Sopenharmony_ci * The RLC is a multi-purpose microengine that handles a 575462306a36Sopenharmony_ci * variety of functions, the most important of which is 575562306a36Sopenharmony_ci * the interrupt controller. 575662306a36Sopenharmony_ci */ 575762306a36Sopenharmony_cistatic void cik_enable_gui_idle_interrupt(struct radeon_device *rdev, 575862306a36Sopenharmony_ci bool enable) 575962306a36Sopenharmony_ci{ 576062306a36Sopenharmony_ci u32 tmp = RREG32(CP_INT_CNTL_RING0); 576162306a36Sopenharmony_ci 576262306a36Sopenharmony_ci if (enable) 576362306a36Sopenharmony_ci tmp |= (CNTX_BUSY_INT_ENABLE | CNTX_EMPTY_INT_ENABLE); 576462306a36Sopenharmony_ci else 576562306a36Sopenharmony_ci tmp &= ~(CNTX_BUSY_INT_ENABLE | CNTX_EMPTY_INT_ENABLE); 576662306a36Sopenharmony_ci WREG32(CP_INT_CNTL_RING0, tmp); 576762306a36Sopenharmony_ci} 576862306a36Sopenharmony_ci 576962306a36Sopenharmony_cistatic void cik_enable_lbpw(struct radeon_device *rdev, bool enable) 577062306a36Sopenharmony_ci{ 577162306a36Sopenharmony_ci u32 tmp; 577262306a36Sopenharmony_ci 577362306a36Sopenharmony_ci tmp = RREG32(RLC_LB_CNTL); 577462306a36Sopenharmony_ci if (enable) 577562306a36Sopenharmony_ci tmp |= LOAD_BALANCE_ENABLE; 577662306a36Sopenharmony_ci else 577762306a36Sopenharmony_ci tmp &= ~LOAD_BALANCE_ENABLE; 577862306a36Sopenharmony_ci WREG32(RLC_LB_CNTL, tmp); 577962306a36Sopenharmony_ci} 578062306a36Sopenharmony_ci 578162306a36Sopenharmony_cistatic void cik_wait_for_rlc_serdes(struct radeon_device *rdev) 578262306a36Sopenharmony_ci{ 578362306a36Sopenharmony_ci u32 i, j, k; 578462306a36Sopenharmony_ci u32 mask; 578562306a36Sopenharmony_ci 578662306a36Sopenharmony_ci for (i = 0; i < rdev->config.cik.max_shader_engines; i++) { 578762306a36Sopenharmony_ci for (j = 0; j < rdev->config.cik.max_sh_per_se; j++) { 578862306a36Sopenharmony_ci cik_select_se_sh(rdev, i, j); 578962306a36Sopenharmony_ci for (k = 0; k < rdev->usec_timeout; k++) { 579062306a36Sopenharmony_ci if (RREG32(RLC_SERDES_CU_MASTER_BUSY) == 0) 579162306a36Sopenharmony_ci break; 579262306a36Sopenharmony_ci udelay(1); 579362306a36Sopenharmony_ci } 579462306a36Sopenharmony_ci } 579562306a36Sopenharmony_ci } 579662306a36Sopenharmony_ci cik_select_se_sh(rdev, 0xffffffff, 0xffffffff); 579762306a36Sopenharmony_ci 579862306a36Sopenharmony_ci mask = SE_MASTER_BUSY_MASK | GC_MASTER_BUSY | TC0_MASTER_BUSY | TC1_MASTER_BUSY; 579962306a36Sopenharmony_ci for (k = 0; k < rdev->usec_timeout; k++) { 580062306a36Sopenharmony_ci if ((RREG32(RLC_SERDES_NONCU_MASTER_BUSY) & mask) == 0) 580162306a36Sopenharmony_ci break; 580262306a36Sopenharmony_ci udelay(1); 580362306a36Sopenharmony_ci } 580462306a36Sopenharmony_ci} 580562306a36Sopenharmony_ci 580662306a36Sopenharmony_cistatic void cik_update_rlc(struct radeon_device *rdev, u32 rlc) 580762306a36Sopenharmony_ci{ 580862306a36Sopenharmony_ci u32 tmp; 580962306a36Sopenharmony_ci 581062306a36Sopenharmony_ci tmp = RREG32(RLC_CNTL); 581162306a36Sopenharmony_ci if (tmp != rlc) 581262306a36Sopenharmony_ci WREG32(RLC_CNTL, rlc); 581362306a36Sopenharmony_ci} 581462306a36Sopenharmony_ci 581562306a36Sopenharmony_cistatic u32 cik_halt_rlc(struct radeon_device *rdev) 581662306a36Sopenharmony_ci{ 581762306a36Sopenharmony_ci u32 data, orig; 581862306a36Sopenharmony_ci 581962306a36Sopenharmony_ci orig = data = RREG32(RLC_CNTL); 582062306a36Sopenharmony_ci 582162306a36Sopenharmony_ci if (data & RLC_ENABLE) { 582262306a36Sopenharmony_ci u32 i; 582362306a36Sopenharmony_ci 582462306a36Sopenharmony_ci data &= ~RLC_ENABLE; 582562306a36Sopenharmony_ci WREG32(RLC_CNTL, data); 582662306a36Sopenharmony_ci 582762306a36Sopenharmony_ci for (i = 0; i < rdev->usec_timeout; i++) { 582862306a36Sopenharmony_ci if ((RREG32(RLC_GPM_STAT) & RLC_GPM_BUSY) == 0) 582962306a36Sopenharmony_ci break; 583062306a36Sopenharmony_ci udelay(1); 583162306a36Sopenharmony_ci } 583262306a36Sopenharmony_ci 583362306a36Sopenharmony_ci cik_wait_for_rlc_serdes(rdev); 583462306a36Sopenharmony_ci } 583562306a36Sopenharmony_ci 583662306a36Sopenharmony_ci return orig; 583762306a36Sopenharmony_ci} 583862306a36Sopenharmony_ci 583962306a36Sopenharmony_civoid cik_enter_rlc_safe_mode(struct radeon_device *rdev) 584062306a36Sopenharmony_ci{ 584162306a36Sopenharmony_ci u32 tmp, i, mask; 584262306a36Sopenharmony_ci 584362306a36Sopenharmony_ci tmp = REQ | MESSAGE(MSG_ENTER_RLC_SAFE_MODE); 584462306a36Sopenharmony_ci WREG32(RLC_GPR_REG2, tmp); 584562306a36Sopenharmony_ci 584662306a36Sopenharmony_ci mask = GFX_POWER_STATUS | GFX_CLOCK_STATUS; 584762306a36Sopenharmony_ci for (i = 0; i < rdev->usec_timeout; i++) { 584862306a36Sopenharmony_ci if ((RREG32(RLC_GPM_STAT) & mask) == mask) 584962306a36Sopenharmony_ci break; 585062306a36Sopenharmony_ci udelay(1); 585162306a36Sopenharmony_ci } 585262306a36Sopenharmony_ci 585362306a36Sopenharmony_ci for (i = 0; i < rdev->usec_timeout; i++) { 585462306a36Sopenharmony_ci if ((RREG32(RLC_GPR_REG2) & REQ) == 0) 585562306a36Sopenharmony_ci break; 585662306a36Sopenharmony_ci udelay(1); 585762306a36Sopenharmony_ci } 585862306a36Sopenharmony_ci} 585962306a36Sopenharmony_ci 586062306a36Sopenharmony_civoid cik_exit_rlc_safe_mode(struct radeon_device *rdev) 586162306a36Sopenharmony_ci{ 586262306a36Sopenharmony_ci u32 tmp; 586362306a36Sopenharmony_ci 586462306a36Sopenharmony_ci tmp = REQ | MESSAGE(MSG_EXIT_RLC_SAFE_MODE); 586562306a36Sopenharmony_ci WREG32(RLC_GPR_REG2, tmp); 586662306a36Sopenharmony_ci} 586762306a36Sopenharmony_ci 586862306a36Sopenharmony_ci/** 586962306a36Sopenharmony_ci * cik_rlc_stop - stop the RLC ME 587062306a36Sopenharmony_ci * 587162306a36Sopenharmony_ci * @rdev: radeon_device pointer 587262306a36Sopenharmony_ci * 587362306a36Sopenharmony_ci * Halt the RLC ME (MicroEngine) (CIK). 587462306a36Sopenharmony_ci */ 587562306a36Sopenharmony_cistatic void cik_rlc_stop(struct radeon_device *rdev) 587662306a36Sopenharmony_ci{ 587762306a36Sopenharmony_ci WREG32(RLC_CNTL, 0); 587862306a36Sopenharmony_ci 587962306a36Sopenharmony_ci cik_enable_gui_idle_interrupt(rdev, false); 588062306a36Sopenharmony_ci 588162306a36Sopenharmony_ci cik_wait_for_rlc_serdes(rdev); 588262306a36Sopenharmony_ci} 588362306a36Sopenharmony_ci 588462306a36Sopenharmony_ci/** 588562306a36Sopenharmony_ci * cik_rlc_start - start the RLC ME 588662306a36Sopenharmony_ci * 588762306a36Sopenharmony_ci * @rdev: radeon_device pointer 588862306a36Sopenharmony_ci * 588962306a36Sopenharmony_ci * Unhalt the RLC ME (MicroEngine) (CIK). 589062306a36Sopenharmony_ci */ 589162306a36Sopenharmony_cistatic void cik_rlc_start(struct radeon_device *rdev) 589262306a36Sopenharmony_ci{ 589362306a36Sopenharmony_ci WREG32(RLC_CNTL, RLC_ENABLE); 589462306a36Sopenharmony_ci 589562306a36Sopenharmony_ci cik_enable_gui_idle_interrupt(rdev, true); 589662306a36Sopenharmony_ci 589762306a36Sopenharmony_ci udelay(50); 589862306a36Sopenharmony_ci} 589962306a36Sopenharmony_ci 590062306a36Sopenharmony_ci/** 590162306a36Sopenharmony_ci * cik_rlc_resume - setup the RLC hw 590262306a36Sopenharmony_ci * 590362306a36Sopenharmony_ci * @rdev: radeon_device pointer 590462306a36Sopenharmony_ci * 590562306a36Sopenharmony_ci * Initialize the RLC registers, load the ucode, 590662306a36Sopenharmony_ci * and start the RLC (CIK). 590762306a36Sopenharmony_ci * Returns 0 for success, -EINVAL if the ucode is not available. 590862306a36Sopenharmony_ci */ 590962306a36Sopenharmony_cistatic int cik_rlc_resume(struct radeon_device *rdev) 591062306a36Sopenharmony_ci{ 591162306a36Sopenharmony_ci u32 i, size, tmp; 591262306a36Sopenharmony_ci 591362306a36Sopenharmony_ci if (!rdev->rlc_fw) 591462306a36Sopenharmony_ci return -EINVAL; 591562306a36Sopenharmony_ci 591662306a36Sopenharmony_ci cik_rlc_stop(rdev); 591762306a36Sopenharmony_ci 591862306a36Sopenharmony_ci /* disable CG */ 591962306a36Sopenharmony_ci tmp = RREG32(RLC_CGCG_CGLS_CTRL) & 0xfffffffc; 592062306a36Sopenharmony_ci WREG32(RLC_CGCG_CGLS_CTRL, tmp); 592162306a36Sopenharmony_ci 592262306a36Sopenharmony_ci si_rlc_reset(rdev); 592362306a36Sopenharmony_ci 592462306a36Sopenharmony_ci cik_init_pg(rdev); 592562306a36Sopenharmony_ci 592662306a36Sopenharmony_ci cik_init_cg(rdev); 592762306a36Sopenharmony_ci 592862306a36Sopenharmony_ci WREG32(RLC_LB_CNTR_INIT, 0); 592962306a36Sopenharmony_ci WREG32(RLC_LB_CNTR_MAX, 0x00008000); 593062306a36Sopenharmony_ci 593162306a36Sopenharmony_ci cik_select_se_sh(rdev, 0xffffffff, 0xffffffff); 593262306a36Sopenharmony_ci WREG32(RLC_LB_INIT_CU_MASK, 0xffffffff); 593362306a36Sopenharmony_ci WREG32(RLC_LB_PARAMS, 0x00600408); 593462306a36Sopenharmony_ci WREG32(RLC_LB_CNTL, 0x80000004); 593562306a36Sopenharmony_ci 593662306a36Sopenharmony_ci WREG32(RLC_MC_CNTL, 0); 593762306a36Sopenharmony_ci WREG32(RLC_UCODE_CNTL, 0); 593862306a36Sopenharmony_ci 593962306a36Sopenharmony_ci if (rdev->new_fw) { 594062306a36Sopenharmony_ci const struct rlc_firmware_header_v1_0 *hdr = 594162306a36Sopenharmony_ci (const struct rlc_firmware_header_v1_0 *)rdev->rlc_fw->data; 594262306a36Sopenharmony_ci const __le32 *fw_data = (const __le32 *) 594362306a36Sopenharmony_ci (rdev->rlc_fw->data + le32_to_cpu(hdr->header.ucode_array_offset_bytes)); 594462306a36Sopenharmony_ci 594562306a36Sopenharmony_ci radeon_ucode_print_rlc_hdr(&hdr->header); 594662306a36Sopenharmony_ci 594762306a36Sopenharmony_ci size = le32_to_cpu(hdr->header.ucode_size_bytes) / 4; 594862306a36Sopenharmony_ci WREG32(RLC_GPM_UCODE_ADDR, 0); 594962306a36Sopenharmony_ci for (i = 0; i < size; i++) 595062306a36Sopenharmony_ci WREG32(RLC_GPM_UCODE_DATA, le32_to_cpup(fw_data++)); 595162306a36Sopenharmony_ci WREG32(RLC_GPM_UCODE_ADDR, le32_to_cpu(hdr->header.ucode_version)); 595262306a36Sopenharmony_ci } else { 595362306a36Sopenharmony_ci const __be32 *fw_data; 595462306a36Sopenharmony_ci 595562306a36Sopenharmony_ci switch (rdev->family) { 595662306a36Sopenharmony_ci case CHIP_BONAIRE: 595762306a36Sopenharmony_ci case CHIP_HAWAII: 595862306a36Sopenharmony_ci default: 595962306a36Sopenharmony_ci size = BONAIRE_RLC_UCODE_SIZE; 596062306a36Sopenharmony_ci break; 596162306a36Sopenharmony_ci case CHIP_KAVERI: 596262306a36Sopenharmony_ci size = KV_RLC_UCODE_SIZE; 596362306a36Sopenharmony_ci break; 596462306a36Sopenharmony_ci case CHIP_KABINI: 596562306a36Sopenharmony_ci size = KB_RLC_UCODE_SIZE; 596662306a36Sopenharmony_ci break; 596762306a36Sopenharmony_ci case CHIP_MULLINS: 596862306a36Sopenharmony_ci size = ML_RLC_UCODE_SIZE; 596962306a36Sopenharmony_ci break; 597062306a36Sopenharmony_ci } 597162306a36Sopenharmony_ci 597262306a36Sopenharmony_ci fw_data = (const __be32 *)rdev->rlc_fw->data; 597362306a36Sopenharmony_ci WREG32(RLC_GPM_UCODE_ADDR, 0); 597462306a36Sopenharmony_ci for (i = 0; i < size; i++) 597562306a36Sopenharmony_ci WREG32(RLC_GPM_UCODE_DATA, be32_to_cpup(fw_data++)); 597662306a36Sopenharmony_ci WREG32(RLC_GPM_UCODE_ADDR, 0); 597762306a36Sopenharmony_ci } 597862306a36Sopenharmony_ci 597962306a36Sopenharmony_ci /* XXX - find out what chips support lbpw */ 598062306a36Sopenharmony_ci cik_enable_lbpw(rdev, false); 598162306a36Sopenharmony_ci 598262306a36Sopenharmony_ci if (rdev->family == CHIP_BONAIRE) 598362306a36Sopenharmony_ci WREG32(RLC_DRIVER_DMA_STATUS, 0); 598462306a36Sopenharmony_ci 598562306a36Sopenharmony_ci cik_rlc_start(rdev); 598662306a36Sopenharmony_ci 598762306a36Sopenharmony_ci return 0; 598862306a36Sopenharmony_ci} 598962306a36Sopenharmony_ci 599062306a36Sopenharmony_cistatic void cik_enable_cgcg(struct radeon_device *rdev, bool enable) 599162306a36Sopenharmony_ci{ 599262306a36Sopenharmony_ci u32 data, orig, tmp, tmp2; 599362306a36Sopenharmony_ci 599462306a36Sopenharmony_ci orig = data = RREG32(RLC_CGCG_CGLS_CTRL); 599562306a36Sopenharmony_ci 599662306a36Sopenharmony_ci if (enable && (rdev->cg_flags & RADEON_CG_SUPPORT_GFX_CGCG)) { 599762306a36Sopenharmony_ci cik_enable_gui_idle_interrupt(rdev, true); 599862306a36Sopenharmony_ci 599962306a36Sopenharmony_ci tmp = cik_halt_rlc(rdev); 600062306a36Sopenharmony_ci 600162306a36Sopenharmony_ci cik_select_se_sh(rdev, 0xffffffff, 0xffffffff); 600262306a36Sopenharmony_ci WREG32(RLC_SERDES_WR_CU_MASTER_MASK, 0xffffffff); 600362306a36Sopenharmony_ci WREG32(RLC_SERDES_WR_NONCU_MASTER_MASK, 0xffffffff); 600462306a36Sopenharmony_ci tmp2 = BPM_ADDR_MASK | CGCG_OVERRIDE_0 | CGLS_ENABLE; 600562306a36Sopenharmony_ci WREG32(RLC_SERDES_WR_CTRL, tmp2); 600662306a36Sopenharmony_ci 600762306a36Sopenharmony_ci cik_update_rlc(rdev, tmp); 600862306a36Sopenharmony_ci 600962306a36Sopenharmony_ci data |= CGCG_EN | CGLS_EN; 601062306a36Sopenharmony_ci } else { 601162306a36Sopenharmony_ci cik_enable_gui_idle_interrupt(rdev, false); 601262306a36Sopenharmony_ci 601362306a36Sopenharmony_ci RREG32(CB_CGTT_SCLK_CTRL); 601462306a36Sopenharmony_ci RREG32(CB_CGTT_SCLK_CTRL); 601562306a36Sopenharmony_ci RREG32(CB_CGTT_SCLK_CTRL); 601662306a36Sopenharmony_ci RREG32(CB_CGTT_SCLK_CTRL); 601762306a36Sopenharmony_ci 601862306a36Sopenharmony_ci data &= ~(CGCG_EN | CGLS_EN); 601962306a36Sopenharmony_ci } 602062306a36Sopenharmony_ci 602162306a36Sopenharmony_ci if (orig != data) 602262306a36Sopenharmony_ci WREG32(RLC_CGCG_CGLS_CTRL, data); 602362306a36Sopenharmony_ci 602462306a36Sopenharmony_ci} 602562306a36Sopenharmony_ci 602662306a36Sopenharmony_cistatic void cik_enable_mgcg(struct radeon_device *rdev, bool enable) 602762306a36Sopenharmony_ci{ 602862306a36Sopenharmony_ci u32 data, orig, tmp = 0; 602962306a36Sopenharmony_ci 603062306a36Sopenharmony_ci if (enable && (rdev->cg_flags & RADEON_CG_SUPPORT_GFX_MGCG)) { 603162306a36Sopenharmony_ci if (rdev->cg_flags & RADEON_CG_SUPPORT_GFX_MGLS) { 603262306a36Sopenharmony_ci if (rdev->cg_flags & RADEON_CG_SUPPORT_GFX_CP_LS) { 603362306a36Sopenharmony_ci orig = data = RREG32(CP_MEM_SLP_CNTL); 603462306a36Sopenharmony_ci data |= CP_MEM_LS_EN; 603562306a36Sopenharmony_ci if (orig != data) 603662306a36Sopenharmony_ci WREG32(CP_MEM_SLP_CNTL, data); 603762306a36Sopenharmony_ci } 603862306a36Sopenharmony_ci } 603962306a36Sopenharmony_ci 604062306a36Sopenharmony_ci orig = data = RREG32(RLC_CGTT_MGCG_OVERRIDE); 604162306a36Sopenharmony_ci data |= 0x00000001; 604262306a36Sopenharmony_ci data &= 0xfffffffd; 604362306a36Sopenharmony_ci if (orig != data) 604462306a36Sopenharmony_ci WREG32(RLC_CGTT_MGCG_OVERRIDE, data); 604562306a36Sopenharmony_ci 604662306a36Sopenharmony_ci tmp = cik_halt_rlc(rdev); 604762306a36Sopenharmony_ci 604862306a36Sopenharmony_ci cik_select_se_sh(rdev, 0xffffffff, 0xffffffff); 604962306a36Sopenharmony_ci WREG32(RLC_SERDES_WR_CU_MASTER_MASK, 0xffffffff); 605062306a36Sopenharmony_ci WREG32(RLC_SERDES_WR_NONCU_MASTER_MASK, 0xffffffff); 605162306a36Sopenharmony_ci data = BPM_ADDR_MASK | MGCG_OVERRIDE_0; 605262306a36Sopenharmony_ci WREG32(RLC_SERDES_WR_CTRL, data); 605362306a36Sopenharmony_ci 605462306a36Sopenharmony_ci cik_update_rlc(rdev, tmp); 605562306a36Sopenharmony_ci 605662306a36Sopenharmony_ci if (rdev->cg_flags & RADEON_CG_SUPPORT_GFX_CGTS) { 605762306a36Sopenharmony_ci orig = data = RREG32(CGTS_SM_CTRL_REG); 605862306a36Sopenharmony_ci data &= ~SM_MODE_MASK; 605962306a36Sopenharmony_ci data |= SM_MODE(0x2); 606062306a36Sopenharmony_ci data |= SM_MODE_ENABLE; 606162306a36Sopenharmony_ci data &= ~CGTS_OVERRIDE; 606262306a36Sopenharmony_ci if ((rdev->cg_flags & RADEON_CG_SUPPORT_GFX_MGLS) && 606362306a36Sopenharmony_ci (rdev->cg_flags & RADEON_CG_SUPPORT_GFX_CGTS_LS)) 606462306a36Sopenharmony_ci data &= ~CGTS_LS_OVERRIDE; 606562306a36Sopenharmony_ci data &= ~ON_MONITOR_ADD_MASK; 606662306a36Sopenharmony_ci data |= ON_MONITOR_ADD_EN; 606762306a36Sopenharmony_ci data |= ON_MONITOR_ADD(0x96); 606862306a36Sopenharmony_ci if (orig != data) 606962306a36Sopenharmony_ci WREG32(CGTS_SM_CTRL_REG, data); 607062306a36Sopenharmony_ci } 607162306a36Sopenharmony_ci } else { 607262306a36Sopenharmony_ci orig = data = RREG32(RLC_CGTT_MGCG_OVERRIDE); 607362306a36Sopenharmony_ci data |= 0x00000003; 607462306a36Sopenharmony_ci if (orig != data) 607562306a36Sopenharmony_ci WREG32(RLC_CGTT_MGCG_OVERRIDE, data); 607662306a36Sopenharmony_ci 607762306a36Sopenharmony_ci data = RREG32(RLC_MEM_SLP_CNTL); 607862306a36Sopenharmony_ci if (data & RLC_MEM_LS_EN) { 607962306a36Sopenharmony_ci data &= ~RLC_MEM_LS_EN; 608062306a36Sopenharmony_ci WREG32(RLC_MEM_SLP_CNTL, data); 608162306a36Sopenharmony_ci } 608262306a36Sopenharmony_ci 608362306a36Sopenharmony_ci data = RREG32(CP_MEM_SLP_CNTL); 608462306a36Sopenharmony_ci if (data & CP_MEM_LS_EN) { 608562306a36Sopenharmony_ci data &= ~CP_MEM_LS_EN; 608662306a36Sopenharmony_ci WREG32(CP_MEM_SLP_CNTL, data); 608762306a36Sopenharmony_ci } 608862306a36Sopenharmony_ci 608962306a36Sopenharmony_ci orig = data = RREG32(CGTS_SM_CTRL_REG); 609062306a36Sopenharmony_ci data |= CGTS_OVERRIDE | CGTS_LS_OVERRIDE; 609162306a36Sopenharmony_ci if (orig != data) 609262306a36Sopenharmony_ci WREG32(CGTS_SM_CTRL_REG, data); 609362306a36Sopenharmony_ci 609462306a36Sopenharmony_ci tmp = cik_halt_rlc(rdev); 609562306a36Sopenharmony_ci 609662306a36Sopenharmony_ci cik_select_se_sh(rdev, 0xffffffff, 0xffffffff); 609762306a36Sopenharmony_ci WREG32(RLC_SERDES_WR_CU_MASTER_MASK, 0xffffffff); 609862306a36Sopenharmony_ci WREG32(RLC_SERDES_WR_NONCU_MASTER_MASK, 0xffffffff); 609962306a36Sopenharmony_ci data = BPM_ADDR_MASK | MGCG_OVERRIDE_1; 610062306a36Sopenharmony_ci WREG32(RLC_SERDES_WR_CTRL, data); 610162306a36Sopenharmony_ci 610262306a36Sopenharmony_ci cik_update_rlc(rdev, tmp); 610362306a36Sopenharmony_ci } 610462306a36Sopenharmony_ci} 610562306a36Sopenharmony_ci 610662306a36Sopenharmony_cistatic const u32 mc_cg_registers[] = 610762306a36Sopenharmony_ci{ 610862306a36Sopenharmony_ci MC_HUB_MISC_HUB_CG, 610962306a36Sopenharmony_ci MC_HUB_MISC_SIP_CG, 611062306a36Sopenharmony_ci MC_HUB_MISC_VM_CG, 611162306a36Sopenharmony_ci MC_XPB_CLK_GAT, 611262306a36Sopenharmony_ci ATC_MISC_CG, 611362306a36Sopenharmony_ci MC_CITF_MISC_WR_CG, 611462306a36Sopenharmony_ci MC_CITF_MISC_RD_CG, 611562306a36Sopenharmony_ci MC_CITF_MISC_VM_CG, 611662306a36Sopenharmony_ci VM_L2_CG, 611762306a36Sopenharmony_ci}; 611862306a36Sopenharmony_ci 611962306a36Sopenharmony_cistatic void cik_enable_mc_ls(struct radeon_device *rdev, 612062306a36Sopenharmony_ci bool enable) 612162306a36Sopenharmony_ci{ 612262306a36Sopenharmony_ci int i; 612362306a36Sopenharmony_ci u32 orig, data; 612462306a36Sopenharmony_ci 612562306a36Sopenharmony_ci for (i = 0; i < ARRAY_SIZE(mc_cg_registers); i++) { 612662306a36Sopenharmony_ci orig = data = RREG32(mc_cg_registers[i]); 612762306a36Sopenharmony_ci if (enable && (rdev->cg_flags & RADEON_CG_SUPPORT_MC_LS)) 612862306a36Sopenharmony_ci data |= MC_LS_ENABLE; 612962306a36Sopenharmony_ci else 613062306a36Sopenharmony_ci data &= ~MC_LS_ENABLE; 613162306a36Sopenharmony_ci if (data != orig) 613262306a36Sopenharmony_ci WREG32(mc_cg_registers[i], data); 613362306a36Sopenharmony_ci } 613462306a36Sopenharmony_ci} 613562306a36Sopenharmony_ci 613662306a36Sopenharmony_cistatic void cik_enable_mc_mgcg(struct radeon_device *rdev, 613762306a36Sopenharmony_ci bool enable) 613862306a36Sopenharmony_ci{ 613962306a36Sopenharmony_ci int i; 614062306a36Sopenharmony_ci u32 orig, data; 614162306a36Sopenharmony_ci 614262306a36Sopenharmony_ci for (i = 0; i < ARRAY_SIZE(mc_cg_registers); i++) { 614362306a36Sopenharmony_ci orig = data = RREG32(mc_cg_registers[i]); 614462306a36Sopenharmony_ci if (enable && (rdev->cg_flags & RADEON_CG_SUPPORT_MC_MGCG)) 614562306a36Sopenharmony_ci data |= MC_CG_ENABLE; 614662306a36Sopenharmony_ci else 614762306a36Sopenharmony_ci data &= ~MC_CG_ENABLE; 614862306a36Sopenharmony_ci if (data != orig) 614962306a36Sopenharmony_ci WREG32(mc_cg_registers[i], data); 615062306a36Sopenharmony_ci } 615162306a36Sopenharmony_ci} 615262306a36Sopenharmony_ci 615362306a36Sopenharmony_cistatic void cik_enable_sdma_mgcg(struct radeon_device *rdev, 615462306a36Sopenharmony_ci bool enable) 615562306a36Sopenharmony_ci{ 615662306a36Sopenharmony_ci u32 orig, data; 615762306a36Sopenharmony_ci 615862306a36Sopenharmony_ci if (enable && (rdev->cg_flags & RADEON_CG_SUPPORT_SDMA_MGCG)) { 615962306a36Sopenharmony_ci WREG32(SDMA0_CLK_CTRL + SDMA0_REGISTER_OFFSET, 0x00000100); 616062306a36Sopenharmony_ci WREG32(SDMA0_CLK_CTRL + SDMA1_REGISTER_OFFSET, 0x00000100); 616162306a36Sopenharmony_ci } else { 616262306a36Sopenharmony_ci orig = data = RREG32(SDMA0_CLK_CTRL + SDMA0_REGISTER_OFFSET); 616362306a36Sopenharmony_ci data |= 0xff000000; 616462306a36Sopenharmony_ci if (data != orig) 616562306a36Sopenharmony_ci WREG32(SDMA0_CLK_CTRL + SDMA0_REGISTER_OFFSET, data); 616662306a36Sopenharmony_ci 616762306a36Sopenharmony_ci orig = data = RREG32(SDMA0_CLK_CTRL + SDMA1_REGISTER_OFFSET); 616862306a36Sopenharmony_ci data |= 0xff000000; 616962306a36Sopenharmony_ci if (data != orig) 617062306a36Sopenharmony_ci WREG32(SDMA0_CLK_CTRL + SDMA1_REGISTER_OFFSET, data); 617162306a36Sopenharmony_ci } 617262306a36Sopenharmony_ci} 617362306a36Sopenharmony_ci 617462306a36Sopenharmony_cistatic void cik_enable_sdma_mgls(struct radeon_device *rdev, 617562306a36Sopenharmony_ci bool enable) 617662306a36Sopenharmony_ci{ 617762306a36Sopenharmony_ci u32 orig, data; 617862306a36Sopenharmony_ci 617962306a36Sopenharmony_ci if (enable && (rdev->cg_flags & RADEON_CG_SUPPORT_SDMA_LS)) { 618062306a36Sopenharmony_ci orig = data = RREG32(SDMA0_POWER_CNTL + SDMA0_REGISTER_OFFSET); 618162306a36Sopenharmony_ci data |= 0x100; 618262306a36Sopenharmony_ci if (orig != data) 618362306a36Sopenharmony_ci WREG32(SDMA0_POWER_CNTL + SDMA0_REGISTER_OFFSET, data); 618462306a36Sopenharmony_ci 618562306a36Sopenharmony_ci orig = data = RREG32(SDMA0_POWER_CNTL + SDMA1_REGISTER_OFFSET); 618662306a36Sopenharmony_ci data |= 0x100; 618762306a36Sopenharmony_ci if (orig != data) 618862306a36Sopenharmony_ci WREG32(SDMA0_POWER_CNTL + SDMA1_REGISTER_OFFSET, data); 618962306a36Sopenharmony_ci } else { 619062306a36Sopenharmony_ci orig = data = RREG32(SDMA0_POWER_CNTL + SDMA0_REGISTER_OFFSET); 619162306a36Sopenharmony_ci data &= ~0x100; 619262306a36Sopenharmony_ci if (orig != data) 619362306a36Sopenharmony_ci WREG32(SDMA0_POWER_CNTL + SDMA0_REGISTER_OFFSET, data); 619462306a36Sopenharmony_ci 619562306a36Sopenharmony_ci orig = data = RREG32(SDMA0_POWER_CNTL + SDMA1_REGISTER_OFFSET); 619662306a36Sopenharmony_ci data &= ~0x100; 619762306a36Sopenharmony_ci if (orig != data) 619862306a36Sopenharmony_ci WREG32(SDMA0_POWER_CNTL + SDMA1_REGISTER_OFFSET, data); 619962306a36Sopenharmony_ci } 620062306a36Sopenharmony_ci} 620162306a36Sopenharmony_ci 620262306a36Sopenharmony_cistatic void cik_enable_uvd_mgcg(struct radeon_device *rdev, 620362306a36Sopenharmony_ci bool enable) 620462306a36Sopenharmony_ci{ 620562306a36Sopenharmony_ci u32 orig, data; 620662306a36Sopenharmony_ci 620762306a36Sopenharmony_ci if (enable && (rdev->cg_flags & RADEON_CG_SUPPORT_UVD_MGCG)) { 620862306a36Sopenharmony_ci data = RREG32_UVD_CTX(UVD_CGC_MEM_CTRL); 620962306a36Sopenharmony_ci data = 0xfff; 621062306a36Sopenharmony_ci WREG32_UVD_CTX(UVD_CGC_MEM_CTRL, data); 621162306a36Sopenharmony_ci 621262306a36Sopenharmony_ci orig = data = RREG32(UVD_CGC_CTRL); 621362306a36Sopenharmony_ci data |= DCM; 621462306a36Sopenharmony_ci if (orig != data) 621562306a36Sopenharmony_ci WREG32(UVD_CGC_CTRL, data); 621662306a36Sopenharmony_ci } else { 621762306a36Sopenharmony_ci data = RREG32_UVD_CTX(UVD_CGC_MEM_CTRL); 621862306a36Sopenharmony_ci data &= ~0xfff; 621962306a36Sopenharmony_ci WREG32_UVD_CTX(UVD_CGC_MEM_CTRL, data); 622062306a36Sopenharmony_ci 622162306a36Sopenharmony_ci orig = data = RREG32(UVD_CGC_CTRL); 622262306a36Sopenharmony_ci data &= ~DCM; 622362306a36Sopenharmony_ci if (orig != data) 622462306a36Sopenharmony_ci WREG32(UVD_CGC_CTRL, data); 622562306a36Sopenharmony_ci } 622662306a36Sopenharmony_ci} 622762306a36Sopenharmony_ci 622862306a36Sopenharmony_cistatic void cik_enable_bif_mgls(struct radeon_device *rdev, 622962306a36Sopenharmony_ci bool enable) 623062306a36Sopenharmony_ci{ 623162306a36Sopenharmony_ci u32 orig, data; 623262306a36Sopenharmony_ci 623362306a36Sopenharmony_ci orig = data = RREG32_PCIE_PORT(PCIE_CNTL2); 623462306a36Sopenharmony_ci 623562306a36Sopenharmony_ci if (enable && (rdev->cg_flags & RADEON_CG_SUPPORT_BIF_LS)) 623662306a36Sopenharmony_ci data |= SLV_MEM_LS_EN | MST_MEM_LS_EN | 623762306a36Sopenharmony_ci REPLAY_MEM_LS_EN | SLV_MEM_AGGRESSIVE_LS_EN; 623862306a36Sopenharmony_ci else 623962306a36Sopenharmony_ci data &= ~(SLV_MEM_LS_EN | MST_MEM_LS_EN | 624062306a36Sopenharmony_ci REPLAY_MEM_LS_EN | SLV_MEM_AGGRESSIVE_LS_EN); 624162306a36Sopenharmony_ci 624262306a36Sopenharmony_ci if (orig != data) 624362306a36Sopenharmony_ci WREG32_PCIE_PORT(PCIE_CNTL2, data); 624462306a36Sopenharmony_ci} 624562306a36Sopenharmony_ci 624662306a36Sopenharmony_cistatic void cik_enable_hdp_mgcg(struct radeon_device *rdev, 624762306a36Sopenharmony_ci bool enable) 624862306a36Sopenharmony_ci{ 624962306a36Sopenharmony_ci u32 orig, data; 625062306a36Sopenharmony_ci 625162306a36Sopenharmony_ci orig = data = RREG32(HDP_HOST_PATH_CNTL); 625262306a36Sopenharmony_ci 625362306a36Sopenharmony_ci if (enable && (rdev->cg_flags & RADEON_CG_SUPPORT_HDP_MGCG)) 625462306a36Sopenharmony_ci data &= ~CLOCK_GATING_DIS; 625562306a36Sopenharmony_ci else 625662306a36Sopenharmony_ci data |= CLOCK_GATING_DIS; 625762306a36Sopenharmony_ci 625862306a36Sopenharmony_ci if (orig != data) 625962306a36Sopenharmony_ci WREG32(HDP_HOST_PATH_CNTL, data); 626062306a36Sopenharmony_ci} 626162306a36Sopenharmony_ci 626262306a36Sopenharmony_cistatic void cik_enable_hdp_ls(struct radeon_device *rdev, 626362306a36Sopenharmony_ci bool enable) 626462306a36Sopenharmony_ci{ 626562306a36Sopenharmony_ci u32 orig, data; 626662306a36Sopenharmony_ci 626762306a36Sopenharmony_ci orig = data = RREG32(HDP_MEM_POWER_LS); 626862306a36Sopenharmony_ci 626962306a36Sopenharmony_ci if (enable && (rdev->cg_flags & RADEON_CG_SUPPORT_HDP_LS)) 627062306a36Sopenharmony_ci data |= HDP_LS_ENABLE; 627162306a36Sopenharmony_ci else 627262306a36Sopenharmony_ci data &= ~HDP_LS_ENABLE; 627362306a36Sopenharmony_ci 627462306a36Sopenharmony_ci if (orig != data) 627562306a36Sopenharmony_ci WREG32(HDP_MEM_POWER_LS, data); 627662306a36Sopenharmony_ci} 627762306a36Sopenharmony_ci 627862306a36Sopenharmony_civoid cik_update_cg(struct radeon_device *rdev, 627962306a36Sopenharmony_ci u32 block, bool enable) 628062306a36Sopenharmony_ci{ 628162306a36Sopenharmony_ci 628262306a36Sopenharmony_ci if (block & RADEON_CG_BLOCK_GFX) { 628362306a36Sopenharmony_ci cik_enable_gui_idle_interrupt(rdev, false); 628462306a36Sopenharmony_ci /* order matters! */ 628562306a36Sopenharmony_ci if (enable) { 628662306a36Sopenharmony_ci cik_enable_mgcg(rdev, true); 628762306a36Sopenharmony_ci cik_enable_cgcg(rdev, true); 628862306a36Sopenharmony_ci } else { 628962306a36Sopenharmony_ci cik_enable_cgcg(rdev, false); 629062306a36Sopenharmony_ci cik_enable_mgcg(rdev, false); 629162306a36Sopenharmony_ci } 629262306a36Sopenharmony_ci cik_enable_gui_idle_interrupt(rdev, true); 629362306a36Sopenharmony_ci } 629462306a36Sopenharmony_ci 629562306a36Sopenharmony_ci if (block & RADEON_CG_BLOCK_MC) { 629662306a36Sopenharmony_ci if (!(rdev->flags & RADEON_IS_IGP)) { 629762306a36Sopenharmony_ci cik_enable_mc_mgcg(rdev, enable); 629862306a36Sopenharmony_ci cik_enable_mc_ls(rdev, enable); 629962306a36Sopenharmony_ci } 630062306a36Sopenharmony_ci } 630162306a36Sopenharmony_ci 630262306a36Sopenharmony_ci if (block & RADEON_CG_BLOCK_SDMA) { 630362306a36Sopenharmony_ci cik_enable_sdma_mgcg(rdev, enable); 630462306a36Sopenharmony_ci cik_enable_sdma_mgls(rdev, enable); 630562306a36Sopenharmony_ci } 630662306a36Sopenharmony_ci 630762306a36Sopenharmony_ci if (block & RADEON_CG_BLOCK_BIF) { 630862306a36Sopenharmony_ci cik_enable_bif_mgls(rdev, enable); 630962306a36Sopenharmony_ci } 631062306a36Sopenharmony_ci 631162306a36Sopenharmony_ci if (block & RADEON_CG_BLOCK_UVD) { 631262306a36Sopenharmony_ci if (rdev->has_uvd) 631362306a36Sopenharmony_ci cik_enable_uvd_mgcg(rdev, enable); 631462306a36Sopenharmony_ci } 631562306a36Sopenharmony_ci 631662306a36Sopenharmony_ci if (block & RADEON_CG_BLOCK_HDP) { 631762306a36Sopenharmony_ci cik_enable_hdp_mgcg(rdev, enable); 631862306a36Sopenharmony_ci cik_enable_hdp_ls(rdev, enable); 631962306a36Sopenharmony_ci } 632062306a36Sopenharmony_ci 632162306a36Sopenharmony_ci if (block & RADEON_CG_BLOCK_VCE) { 632262306a36Sopenharmony_ci vce_v2_0_enable_mgcg(rdev, enable); 632362306a36Sopenharmony_ci } 632462306a36Sopenharmony_ci} 632562306a36Sopenharmony_ci 632662306a36Sopenharmony_cistatic void cik_init_cg(struct radeon_device *rdev) 632762306a36Sopenharmony_ci{ 632862306a36Sopenharmony_ci 632962306a36Sopenharmony_ci cik_update_cg(rdev, RADEON_CG_BLOCK_GFX, true); 633062306a36Sopenharmony_ci 633162306a36Sopenharmony_ci if (rdev->has_uvd) 633262306a36Sopenharmony_ci si_init_uvd_internal_cg(rdev); 633362306a36Sopenharmony_ci 633462306a36Sopenharmony_ci cik_update_cg(rdev, (RADEON_CG_BLOCK_MC | 633562306a36Sopenharmony_ci RADEON_CG_BLOCK_SDMA | 633662306a36Sopenharmony_ci RADEON_CG_BLOCK_BIF | 633762306a36Sopenharmony_ci RADEON_CG_BLOCK_UVD | 633862306a36Sopenharmony_ci RADEON_CG_BLOCK_HDP), true); 633962306a36Sopenharmony_ci} 634062306a36Sopenharmony_ci 634162306a36Sopenharmony_cistatic void cik_fini_cg(struct radeon_device *rdev) 634262306a36Sopenharmony_ci{ 634362306a36Sopenharmony_ci cik_update_cg(rdev, (RADEON_CG_BLOCK_MC | 634462306a36Sopenharmony_ci RADEON_CG_BLOCK_SDMA | 634562306a36Sopenharmony_ci RADEON_CG_BLOCK_BIF | 634662306a36Sopenharmony_ci RADEON_CG_BLOCK_UVD | 634762306a36Sopenharmony_ci RADEON_CG_BLOCK_HDP), false); 634862306a36Sopenharmony_ci 634962306a36Sopenharmony_ci cik_update_cg(rdev, RADEON_CG_BLOCK_GFX, false); 635062306a36Sopenharmony_ci} 635162306a36Sopenharmony_ci 635262306a36Sopenharmony_cistatic void cik_enable_sck_slowdown_on_pu(struct radeon_device *rdev, 635362306a36Sopenharmony_ci bool enable) 635462306a36Sopenharmony_ci{ 635562306a36Sopenharmony_ci u32 data, orig; 635662306a36Sopenharmony_ci 635762306a36Sopenharmony_ci orig = data = RREG32(RLC_PG_CNTL); 635862306a36Sopenharmony_ci if (enable && (rdev->pg_flags & RADEON_PG_SUPPORT_RLC_SMU_HS)) 635962306a36Sopenharmony_ci data |= SMU_CLK_SLOWDOWN_ON_PU_ENABLE; 636062306a36Sopenharmony_ci else 636162306a36Sopenharmony_ci data &= ~SMU_CLK_SLOWDOWN_ON_PU_ENABLE; 636262306a36Sopenharmony_ci if (orig != data) 636362306a36Sopenharmony_ci WREG32(RLC_PG_CNTL, data); 636462306a36Sopenharmony_ci} 636562306a36Sopenharmony_ci 636662306a36Sopenharmony_cistatic void cik_enable_sck_slowdown_on_pd(struct radeon_device *rdev, 636762306a36Sopenharmony_ci bool enable) 636862306a36Sopenharmony_ci{ 636962306a36Sopenharmony_ci u32 data, orig; 637062306a36Sopenharmony_ci 637162306a36Sopenharmony_ci orig = data = RREG32(RLC_PG_CNTL); 637262306a36Sopenharmony_ci if (enable && (rdev->pg_flags & RADEON_PG_SUPPORT_RLC_SMU_HS)) 637362306a36Sopenharmony_ci data |= SMU_CLK_SLOWDOWN_ON_PD_ENABLE; 637462306a36Sopenharmony_ci else 637562306a36Sopenharmony_ci data &= ~SMU_CLK_SLOWDOWN_ON_PD_ENABLE; 637662306a36Sopenharmony_ci if (orig != data) 637762306a36Sopenharmony_ci WREG32(RLC_PG_CNTL, data); 637862306a36Sopenharmony_ci} 637962306a36Sopenharmony_ci 638062306a36Sopenharmony_cistatic void cik_enable_cp_pg(struct radeon_device *rdev, bool enable) 638162306a36Sopenharmony_ci{ 638262306a36Sopenharmony_ci u32 data, orig; 638362306a36Sopenharmony_ci 638462306a36Sopenharmony_ci orig = data = RREG32(RLC_PG_CNTL); 638562306a36Sopenharmony_ci if (enable && (rdev->pg_flags & RADEON_PG_SUPPORT_CP)) 638662306a36Sopenharmony_ci data &= ~DISABLE_CP_PG; 638762306a36Sopenharmony_ci else 638862306a36Sopenharmony_ci data |= DISABLE_CP_PG; 638962306a36Sopenharmony_ci if (orig != data) 639062306a36Sopenharmony_ci WREG32(RLC_PG_CNTL, data); 639162306a36Sopenharmony_ci} 639262306a36Sopenharmony_ci 639362306a36Sopenharmony_cistatic void cik_enable_gds_pg(struct radeon_device *rdev, bool enable) 639462306a36Sopenharmony_ci{ 639562306a36Sopenharmony_ci u32 data, orig; 639662306a36Sopenharmony_ci 639762306a36Sopenharmony_ci orig = data = RREG32(RLC_PG_CNTL); 639862306a36Sopenharmony_ci if (enable && (rdev->pg_flags & RADEON_PG_SUPPORT_GDS)) 639962306a36Sopenharmony_ci data &= ~DISABLE_GDS_PG; 640062306a36Sopenharmony_ci else 640162306a36Sopenharmony_ci data |= DISABLE_GDS_PG; 640262306a36Sopenharmony_ci if (orig != data) 640362306a36Sopenharmony_ci WREG32(RLC_PG_CNTL, data); 640462306a36Sopenharmony_ci} 640562306a36Sopenharmony_ci 640662306a36Sopenharmony_ci#define CP_ME_TABLE_SIZE 96 640762306a36Sopenharmony_ci#define CP_ME_TABLE_OFFSET 2048 640862306a36Sopenharmony_ci#define CP_MEC_TABLE_OFFSET 4096 640962306a36Sopenharmony_ci 641062306a36Sopenharmony_civoid cik_init_cp_pg_table(struct radeon_device *rdev) 641162306a36Sopenharmony_ci{ 641262306a36Sopenharmony_ci volatile u32 *dst_ptr; 641362306a36Sopenharmony_ci int me, i, max_me = 4; 641462306a36Sopenharmony_ci u32 bo_offset = 0; 641562306a36Sopenharmony_ci u32 table_offset, table_size; 641662306a36Sopenharmony_ci 641762306a36Sopenharmony_ci if (rdev->family == CHIP_KAVERI) 641862306a36Sopenharmony_ci max_me = 5; 641962306a36Sopenharmony_ci 642062306a36Sopenharmony_ci if (rdev->rlc.cp_table_ptr == NULL) 642162306a36Sopenharmony_ci return; 642262306a36Sopenharmony_ci 642362306a36Sopenharmony_ci /* write the cp table buffer */ 642462306a36Sopenharmony_ci dst_ptr = rdev->rlc.cp_table_ptr; 642562306a36Sopenharmony_ci for (me = 0; me < max_me; me++) { 642662306a36Sopenharmony_ci if (rdev->new_fw) { 642762306a36Sopenharmony_ci const __le32 *fw_data; 642862306a36Sopenharmony_ci const struct gfx_firmware_header_v1_0 *hdr; 642962306a36Sopenharmony_ci 643062306a36Sopenharmony_ci if (me == 0) { 643162306a36Sopenharmony_ci hdr = (const struct gfx_firmware_header_v1_0 *)rdev->ce_fw->data; 643262306a36Sopenharmony_ci fw_data = (const __le32 *) 643362306a36Sopenharmony_ci (rdev->ce_fw->data + le32_to_cpu(hdr->header.ucode_array_offset_bytes)); 643462306a36Sopenharmony_ci table_offset = le32_to_cpu(hdr->jt_offset); 643562306a36Sopenharmony_ci table_size = le32_to_cpu(hdr->jt_size); 643662306a36Sopenharmony_ci } else if (me == 1) { 643762306a36Sopenharmony_ci hdr = (const struct gfx_firmware_header_v1_0 *)rdev->pfp_fw->data; 643862306a36Sopenharmony_ci fw_data = (const __le32 *) 643962306a36Sopenharmony_ci (rdev->pfp_fw->data + le32_to_cpu(hdr->header.ucode_array_offset_bytes)); 644062306a36Sopenharmony_ci table_offset = le32_to_cpu(hdr->jt_offset); 644162306a36Sopenharmony_ci table_size = le32_to_cpu(hdr->jt_size); 644262306a36Sopenharmony_ci } else if (me == 2) { 644362306a36Sopenharmony_ci hdr = (const struct gfx_firmware_header_v1_0 *)rdev->me_fw->data; 644462306a36Sopenharmony_ci fw_data = (const __le32 *) 644562306a36Sopenharmony_ci (rdev->me_fw->data + le32_to_cpu(hdr->header.ucode_array_offset_bytes)); 644662306a36Sopenharmony_ci table_offset = le32_to_cpu(hdr->jt_offset); 644762306a36Sopenharmony_ci table_size = le32_to_cpu(hdr->jt_size); 644862306a36Sopenharmony_ci } else if (me == 3) { 644962306a36Sopenharmony_ci hdr = (const struct gfx_firmware_header_v1_0 *)rdev->mec_fw->data; 645062306a36Sopenharmony_ci fw_data = (const __le32 *) 645162306a36Sopenharmony_ci (rdev->mec_fw->data + le32_to_cpu(hdr->header.ucode_array_offset_bytes)); 645262306a36Sopenharmony_ci table_offset = le32_to_cpu(hdr->jt_offset); 645362306a36Sopenharmony_ci table_size = le32_to_cpu(hdr->jt_size); 645462306a36Sopenharmony_ci } else { 645562306a36Sopenharmony_ci hdr = (const struct gfx_firmware_header_v1_0 *)rdev->mec2_fw->data; 645662306a36Sopenharmony_ci fw_data = (const __le32 *) 645762306a36Sopenharmony_ci (rdev->mec2_fw->data + le32_to_cpu(hdr->header.ucode_array_offset_bytes)); 645862306a36Sopenharmony_ci table_offset = le32_to_cpu(hdr->jt_offset); 645962306a36Sopenharmony_ci table_size = le32_to_cpu(hdr->jt_size); 646062306a36Sopenharmony_ci } 646162306a36Sopenharmony_ci 646262306a36Sopenharmony_ci for (i = 0; i < table_size; i ++) { 646362306a36Sopenharmony_ci dst_ptr[bo_offset + i] = 646462306a36Sopenharmony_ci cpu_to_le32(le32_to_cpu(fw_data[table_offset + i])); 646562306a36Sopenharmony_ci } 646662306a36Sopenharmony_ci bo_offset += table_size; 646762306a36Sopenharmony_ci } else { 646862306a36Sopenharmony_ci const __be32 *fw_data; 646962306a36Sopenharmony_ci table_size = CP_ME_TABLE_SIZE; 647062306a36Sopenharmony_ci 647162306a36Sopenharmony_ci if (me == 0) { 647262306a36Sopenharmony_ci fw_data = (const __be32 *)rdev->ce_fw->data; 647362306a36Sopenharmony_ci table_offset = CP_ME_TABLE_OFFSET; 647462306a36Sopenharmony_ci } else if (me == 1) { 647562306a36Sopenharmony_ci fw_data = (const __be32 *)rdev->pfp_fw->data; 647662306a36Sopenharmony_ci table_offset = CP_ME_TABLE_OFFSET; 647762306a36Sopenharmony_ci } else if (me == 2) { 647862306a36Sopenharmony_ci fw_data = (const __be32 *)rdev->me_fw->data; 647962306a36Sopenharmony_ci table_offset = CP_ME_TABLE_OFFSET; 648062306a36Sopenharmony_ci } else { 648162306a36Sopenharmony_ci fw_data = (const __be32 *)rdev->mec_fw->data; 648262306a36Sopenharmony_ci table_offset = CP_MEC_TABLE_OFFSET; 648362306a36Sopenharmony_ci } 648462306a36Sopenharmony_ci 648562306a36Sopenharmony_ci for (i = 0; i < table_size; i ++) { 648662306a36Sopenharmony_ci dst_ptr[bo_offset + i] = 648762306a36Sopenharmony_ci cpu_to_le32(be32_to_cpu(fw_data[table_offset + i])); 648862306a36Sopenharmony_ci } 648962306a36Sopenharmony_ci bo_offset += table_size; 649062306a36Sopenharmony_ci } 649162306a36Sopenharmony_ci } 649262306a36Sopenharmony_ci} 649362306a36Sopenharmony_ci 649462306a36Sopenharmony_cistatic void cik_enable_gfx_cgpg(struct radeon_device *rdev, 649562306a36Sopenharmony_ci bool enable) 649662306a36Sopenharmony_ci{ 649762306a36Sopenharmony_ci u32 data, orig; 649862306a36Sopenharmony_ci 649962306a36Sopenharmony_ci if (enable && (rdev->pg_flags & RADEON_PG_SUPPORT_GFX_PG)) { 650062306a36Sopenharmony_ci orig = data = RREG32(RLC_PG_CNTL); 650162306a36Sopenharmony_ci data |= GFX_PG_ENABLE; 650262306a36Sopenharmony_ci if (orig != data) 650362306a36Sopenharmony_ci WREG32(RLC_PG_CNTL, data); 650462306a36Sopenharmony_ci 650562306a36Sopenharmony_ci orig = data = RREG32(RLC_AUTO_PG_CTRL); 650662306a36Sopenharmony_ci data |= AUTO_PG_EN; 650762306a36Sopenharmony_ci if (orig != data) 650862306a36Sopenharmony_ci WREG32(RLC_AUTO_PG_CTRL, data); 650962306a36Sopenharmony_ci } else { 651062306a36Sopenharmony_ci orig = data = RREG32(RLC_PG_CNTL); 651162306a36Sopenharmony_ci data &= ~GFX_PG_ENABLE; 651262306a36Sopenharmony_ci if (orig != data) 651362306a36Sopenharmony_ci WREG32(RLC_PG_CNTL, data); 651462306a36Sopenharmony_ci 651562306a36Sopenharmony_ci orig = data = RREG32(RLC_AUTO_PG_CTRL); 651662306a36Sopenharmony_ci data &= ~AUTO_PG_EN; 651762306a36Sopenharmony_ci if (orig != data) 651862306a36Sopenharmony_ci WREG32(RLC_AUTO_PG_CTRL, data); 651962306a36Sopenharmony_ci 652062306a36Sopenharmony_ci data = RREG32(DB_RENDER_CONTROL); 652162306a36Sopenharmony_ci } 652262306a36Sopenharmony_ci} 652362306a36Sopenharmony_ci 652462306a36Sopenharmony_cistatic u32 cik_get_cu_active_bitmap(struct radeon_device *rdev, u32 se, u32 sh) 652562306a36Sopenharmony_ci{ 652662306a36Sopenharmony_ci u32 mask = 0, tmp, tmp1; 652762306a36Sopenharmony_ci int i; 652862306a36Sopenharmony_ci 652962306a36Sopenharmony_ci cik_select_se_sh(rdev, se, sh); 653062306a36Sopenharmony_ci tmp = RREG32(CC_GC_SHADER_ARRAY_CONFIG); 653162306a36Sopenharmony_ci tmp1 = RREG32(GC_USER_SHADER_ARRAY_CONFIG); 653262306a36Sopenharmony_ci cik_select_se_sh(rdev, 0xffffffff, 0xffffffff); 653362306a36Sopenharmony_ci 653462306a36Sopenharmony_ci tmp &= 0xffff0000; 653562306a36Sopenharmony_ci 653662306a36Sopenharmony_ci tmp |= tmp1; 653762306a36Sopenharmony_ci tmp >>= 16; 653862306a36Sopenharmony_ci 653962306a36Sopenharmony_ci for (i = 0; i < rdev->config.cik.max_cu_per_sh; i ++) { 654062306a36Sopenharmony_ci mask <<= 1; 654162306a36Sopenharmony_ci mask |= 1; 654262306a36Sopenharmony_ci } 654362306a36Sopenharmony_ci 654462306a36Sopenharmony_ci return (~tmp) & mask; 654562306a36Sopenharmony_ci} 654662306a36Sopenharmony_ci 654762306a36Sopenharmony_cistatic void cik_init_ao_cu_mask(struct radeon_device *rdev) 654862306a36Sopenharmony_ci{ 654962306a36Sopenharmony_ci u32 i, j, k, active_cu_number = 0; 655062306a36Sopenharmony_ci u32 mask, counter, cu_bitmap; 655162306a36Sopenharmony_ci u32 tmp = 0; 655262306a36Sopenharmony_ci 655362306a36Sopenharmony_ci for (i = 0; i < rdev->config.cik.max_shader_engines; i++) { 655462306a36Sopenharmony_ci for (j = 0; j < rdev->config.cik.max_sh_per_se; j++) { 655562306a36Sopenharmony_ci mask = 1; 655662306a36Sopenharmony_ci cu_bitmap = 0; 655762306a36Sopenharmony_ci counter = 0; 655862306a36Sopenharmony_ci for (k = 0; k < rdev->config.cik.max_cu_per_sh; k ++) { 655962306a36Sopenharmony_ci if (cik_get_cu_active_bitmap(rdev, i, j) & mask) { 656062306a36Sopenharmony_ci if (counter < 2) 656162306a36Sopenharmony_ci cu_bitmap |= mask; 656262306a36Sopenharmony_ci counter ++; 656362306a36Sopenharmony_ci } 656462306a36Sopenharmony_ci mask <<= 1; 656562306a36Sopenharmony_ci } 656662306a36Sopenharmony_ci 656762306a36Sopenharmony_ci active_cu_number += counter; 656862306a36Sopenharmony_ci tmp |= (cu_bitmap << (i * 16 + j * 8)); 656962306a36Sopenharmony_ci } 657062306a36Sopenharmony_ci } 657162306a36Sopenharmony_ci 657262306a36Sopenharmony_ci WREG32(RLC_PG_AO_CU_MASK, tmp); 657362306a36Sopenharmony_ci 657462306a36Sopenharmony_ci tmp = RREG32(RLC_MAX_PG_CU); 657562306a36Sopenharmony_ci tmp &= ~MAX_PU_CU_MASK; 657662306a36Sopenharmony_ci tmp |= MAX_PU_CU(active_cu_number); 657762306a36Sopenharmony_ci WREG32(RLC_MAX_PG_CU, tmp); 657862306a36Sopenharmony_ci} 657962306a36Sopenharmony_ci 658062306a36Sopenharmony_cistatic void cik_enable_gfx_static_mgpg(struct radeon_device *rdev, 658162306a36Sopenharmony_ci bool enable) 658262306a36Sopenharmony_ci{ 658362306a36Sopenharmony_ci u32 data, orig; 658462306a36Sopenharmony_ci 658562306a36Sopenharmony_ci orig = data = RREG32(RLC_PG_CNTL); 658662306a36Sopenharmony_ci if (enable && (rdev->pg_flags & RADEON_PG_SUPPORT_GFX_SMG)) 658762306a36Sopenharmony_ci data |= STATIC_PER_CU_PG_ENABLE; 658862306a36Sopenharmony_ci else 658962306a36Sopenharmony_ci data &= ~STATIC_PER_CU_PG_ENABLE; 659062306a36Sopenharmony_ci if (orig != data) 659162306a36Sopenharmony_ci WREG32(RLC_PG_CNTL, data); 659262306a36Sopenharmony_ci} 659362306a36Sopenharmony_ci 659462306a36Sopenharmony_cistatic void cik_enable_gfx_dynamic_mgpg(struct radeon_device *rdev, 659562306a36Sopenharmony_ci bool enable) 659662306a36Sopenharmony_ci{ 659762306a36Sopenharmony_ci u32 data, orig; 659862306a36Sopenharmony_ci 659962306a36Sopenharmony_ci orig = data = RREG32(RLC_PG_CNTL); 660062306a36Sopenharmony_ci if (enable && (rdev->pg_flags & RADEON_PG_SUPPORT_GFX_DMG)) 660162306a36Sopenharmony_ci data |= DYN_PER_CU_PG_ENABLE; 660262306a36Sopenharmony_ci else 660362306a36Sopenharmony_ci data &= ~DYN_PER_CU_PG_ENABLE; 660462306a36Sopenharmony_ci if (orig != data) 660562306a36Sopenharmony_ci WREG32(RLC_PG_CNTL, data); 660662306a36Sopenharmony_ci} 660762306a36Sopenharmony_ci 660862306a36Sopenharmony_ci#define RLC_SAVE_AND_RESTORE_STARTING_OFFSET 0x90 660962306a36Sopenharmony_ci#define RLC_CLEAR_STATE_DESCRIPTOR_OFFSET 0x3D 661062306a36Sopenharmony_ci 661162306a36Sopenharmony_cistatic void cik_init_gfx_cgpg(struct radeon_device *rdev) 661262306a36Sopenharmony_ci{ 661362306a36Sopenharmony_ci u32 data, orig; 661462306a36Sopenharmony_ci u32 i; 661562306a36Sopenharmony_ci 661662306a36Sopenharmony_ci if (rdev->rlc.cs_data) { 661762306a36Sopenharmony_ci WREG32(RLC_GPM_SCRATCH_ADDR, RLC_CLEAR_STATE_DESCRIPTOR_OFFSET); 661862306a36Sopenharmony_ci WREG32(RLC_GPM_SCRATCH_DATA, upper_32_bits(rdev->rlc.clear_state_gpu_addr)); 661962306a36Sopenharmony_ci WREG32(RLC_GPM_SCRATCH_DATA, lower_32_bits(rdev->rlc.clear_state_gpu_addr)); 662062306a36Sopenharmony_ci WREG32(RLC_GPM_SCRATCH_DATA, rdev->rlc.clear_state_size); 662162306a36Sopenharmony_ci } else { 662262306a36Sopenharmony_ci WREG32(RLC_GPM_SCRATCH_ADDR, RLC_CLEAR_STATE_DESCRIPTOR_OFFSET); 662362306a36Sopenharmony_ci for (i = 0; i < 3; i++) 662462306a36Sopenharmony_ci WREG32(RLC_GPM_SCRATCH_DATA, 0); 662562306a36Sopenharmony_ci } 662662306a36Sopenharmony_ci if (rdev->rlc.reg_list) { 662762306a36Sopenharmony_ci WREG32(RLC_GPM_SCRATCH_ADDR, RLC_SAVE_AND_RESTORE_STARTING_OFFSET); 662862306a36Sopenharmony_ci for (i = 0; i < rdev->rlc.reg_list_size; i++) 662962306a36Sopenharmony_ci WREG32(RLC_GPM_SCRATCH_DATA, rdev->rlc.reg_list[i]); 663062306a36Sopenharmony_ci } 663162306a36Sopenharmony_ci 663262306a36Sopenharmony_ci orig = data = RREG32(RLC_PG_CNTL); 663362306a36Sopenharmony_ci data |= GFX_PG_SRC; 663462306a36Sopenharmony_ci if (orig != data) 663562306a36Sopenharmony_ci WREG32(RLC_PG_CNTL, data); 663662306a36Sopenharmony_ci 663762306a36Sopenharmony_ci WREG32(RLC_SAVE_AND_RESTORE_BASE, rdev->rlc.save_restore_gpu_addr >> 8); 663862306a36Sopenharmony_ci WREG32(RLC_CP_TABLE_RESTORE, rdev->rlc.cp_table_gpu_addr >> 8); 663962306a36Sopenharmony_ci 664062306a36Sopenharmony_ci data = RREG32(CP_RB_WPTR_POLL_CNTL); 664162306a36Sopenharmony_ci data &= ~IDLE_POLL_COUNT_MASK; 664262306a36Sopenharmony_ci data |= IDLE_POLL_COUNT(0x60); 664362306a36Sopenharmony_ci WREG32(CP_RB_WPTR_POLL_CNTL, data); 664462306a36Sopenharmony_ci 664562306a36Sopenharmony_ci data = 0x10101010; 664662306a36Sopenharmony_ci WREG32(RLC_PG_DELAY, data); 664762306a36Sopenharmony_ci 664862306a36Sopenharmony_ci data = RREG32(RLC_PG_DELAY_2); 664962306a36Sopenharmony_ci data &= ~0xff; 665062306a36Sopenharmony_ci data |= 0x3; 665162306a36Sopenharmony_ci WREG32(RLC_PG_DELAY_2, data); 665262306a36Sopenharmony_ci 665362306a36Sopenharmony_ci data = RREG32(RLC_AUTO_PG_CTRL); 665462306a36Sopenharmony_ci data &= ~GRBM_REG_SGIT_MASK; 665562306a36Sopenharmony_ci data |= GRBM_REG_SGIT(0x700); 665662306a36Sopenharmony_ci WREG32(RLC_AUTO_PG_CTRL, data); 665762306a36Sopenharmony_ci 665862306a36Sopenharmony_ci} 665962306a36Sopenharmony_ci 666062306a36Sopenharmony_cistatic void cik_update_gfx_pg(struct radeon_device *rdev, bool enable) 666162306a36Sopenharmony_ci{ 666262306a36Sopenharmony_ci cik_enable_gfx_cgpg(rdev, enable); 666362306a36Sopenharmony_ci cik_enable_gfx_static_mgpg(rdev, enable); 666462306a36Sopenharmony_ci cik_enable_gfx_dynamic_mgpg(rdev, enable); 666562306a36Sopenharmony_ci} 666662306a36Sopenharmony_ci 666762306a36Sopenharmony_ciu32 cik_get_csb_size(struct radeon_device *rdev) 666862306a36Sopenharmony_ci{ 666962306a36Sopenharmony_ci u32 count = 0; 667062306a36Sopenharmony_ci const struct cs_section_def *sect = NULL; 667162306a36Sopenharmony_ci const struct cs_extent_def *ext = NULL; 667262306a36Sopenharmony_ci 667362306a36Sopenharmony_ci if (rdev->rlc.cs_data == NULL) 667462306a36Sopenharmony_ci return 0; 667562306a36Sopenharmony_ci 667662306a36Sopenharmony_ci /* begin clear state */ 667762306a36Sopenharmony_ci count += 2; 667862306a36Sopenharmony_ci /* context control state */ 667962306a36Sopenharmony_ci count += 3; 668062306a36Sopenharmony_ci 668162306a36Sopenharmony_ci for (sect = rdev->rlc.cs_data; sect->section != NULL; ++sect) { 668262306a36Sopenharmony_ci for (ext = sect->section; ext->extent != NULL; ++ext) { 668362306a36Sopenharmony_ci if (sect->id == SECT_CONTEXT) 668462306a36Sopenharmony_ci count += 2 + ext->reg_count; 668562306a36Sopenharmony_ci else 668662306a36Sopenharmony_ci return 0; 668762306a36Sopenharmony_ci } 668862306a36Sopenharmony_ci } 668962306a36Sopenharmony_ci /* pa_sc_raster_config/pa_sc_raster_config1 */ 669062306a36Sopenharmony_ci count += 4; 669162306a36Sopenharmony_ci /* end clear state */ 669262306a36Sopenharmony_ci count += 2; 669362306a36Sopenharmony_ci /* clear state */ 669462306a36Sopenharmony_ci count += 2; 669562306a36Sopenharmony_ci 669662306a36Sopenharmony_ci return count; 669762306a36Sopenharmony_ci} 669862306a36Sopenharmony_ci 669962306a36Sopenharmony_civoid cik_get_csb_buffer(struct radeon_device *rdev, volatile u32 *buffer) 670062306a36Sopenharmony_ci{ 670162306a36Sopenharmony_ci u32 count = 0, i; 670262306a36Sopenharmony_ci const struct cs_section_def *sect = NULL; 670362306a36Sopenharmony_ci const struct cs_extent_def *ext = NULL; 670462306a36Sopenharmony_ci 670562306a36Sopenharmony_ci if (rdev->rlc.cs_data == NULL) 670662306a36Sopenharmony_ci return; 670762306a36Sopenharmony_ci if (buffer == NULL) 670862306a36Sopenharmony_ci return; 670962306a36Sopenharmony_ci 671062306a36Sopenharmony_ci buffer[count++] = cpu_to_le32(PACKET3(PACKET3_PREAMBLE_CNTL, 0)); 671162306a36Sopenharmony_ci buffer[count++] = cpu_to_le32(PACKET3_PREAMBLE_BEGIN_CLEAR_STATE); 671262306a36Sopenharmony_ci 671362306a36Sopenharmony_ci buffer[count++] = cpu_to_le32(PACKET3(PACKET3_CONTEXT_CONTROL, 1)); 671462306a36Sopenharmony_ci buffer[count++] = cpu_to_le32(0x80000000); 671562306a36Sopenharmony_ci buffer[count++] = cpu_to_le32(0x80000000); 671662306a36Sopenharmony_ci 671762306a36Sopenharmony_ci for (sect = rdev->rlc.cs_data; sect->section != NULL; ++sect) { 671862306a36Sopenharmony_ci for (ext = sect->section; ext->extent != NULL; ++ext) { 671962306a36Sopenharmony_ci if (sect->id == SECT_CONTEXT) { 672062306a36Sopenharmony_ci buffer[count++] = 672162306a36Sopenharmony_ci cpu_to_le32(PACKET3(PACKET3_SET_CONTEXT_REG, ext->reg_count)); 672262306a36Sopenharmony_ci buffer[count++] = cpu_to_le32(ext->reg_index - 0xa000); 672362306a36Sopenharmony_ci for (i = 0; i < ext->reg_count; i++) 672462306a36Sopenharmony_ci buffer[count++] = cpu_to_le32(ext->extent[i]); 672562306a36Sopenharmony_ci } else { 672662306a36Sopenharmony_ci return; 672762306a36Sopenharmony_ci } 672862306a36Sopenharmony_ci } 672962306a36Sopenharmony_ci } 673062306a36Sopenharmony_ci 673162306a36Sopenharmony_ci buffer[count++] = cpu_to_le32(PACKET3(PACKET3_SET_CONTEXT_REG, 2)); 673262306a36Sopenharmony_ci buffer[count++] = cpu_to_le32(PA_SC_RASTER_CONFIG - PACKET3_SET_CONTEXT_REG_START); 673362306a36Sopenharmony_ci switch (rdev->family) { 673462306a36Sopenharmony_ci case CHIP_BONAIRE: 673562306a36Sopenharmony_ci buffer[count++] = cpu_to_le32(0x16000012); 673662306a36Sopenharmony_ci buffer[count++] = cpu_to_le32(0x00000000); 673762306a36Sopenharmony_ci break; 673862306a36Sopenharmony_ci case CHIP_KAVERI: 673962306a36Sopenharmony_ci buffer[count++] = cpu_to_le32(0x00000000); /* XXX */ 674062306a36Sopenharmony_ci buffer[count++] = cpu_to_le32(0x00000000); 674162306a36Sopenharmony_ci break; 674262306a36Sopenharmony_ci case CHIP_KABINI: 674362306a36Sopenharmony_ci case CHIP_MULLINS: 674462306a36Sopenharmony_ci buffer[count++] = cpu_to_le32(0x00000000); /* XXX */ 674562306a36Sopenharmony_ci buffer[count++] = cpu_to_le32(0x00000000); 674662306a36Sopenharmony_ci break; 674762306a36Sopenharmony_ci case CHIP_HAWAII: 674862306a36Sopenharmony_ci buffer[count++] = cpu_to_le32(0x3a00161a); 674962306a36Sopenharmony_ci buffer[count++] = cpu_to_le32(0x0000002e); 675062306a36Sopenharmony_ci break; 675162306a36Sopenharmony_ci default: 675262306a36Sopenharmony_ci buffer[count++] = cpu_to_le32(0x00000000); 675362306a36Sopenharmony_ci buffer[count++] = cpu_to_le32(0x00000000); 675462306a36Sopenharmony_ci break; 675562306a36Sopenharmony_ci } 675662306a36Sopenharmony_ci 675762306a36Sopenharmony_ci buffer[count++] = cpu_to_le32(PACKET3(PACKET3_PREAMBLE_CNTL, 0)); 675862306a36Sopenharmony_ci buffer[count++] = cpu_to_le32(PACKET3_PREAMBLE_END_CLEAR_STATE); 675962306a36Sopenharmony_ci 676062306a36Sopenharmony_ci buffer[count++] = cpu_to_le32(PACKET3(PACKET3_CLEAR_STATE, 0)); 676162306a36Sopenharmony_ci buffer[count++] = cpu_to_le32(0); 676262306a36Sopenharmony_ci} 676362306a36Sopenharmony_ci 676462306a36Sopenharmony_cistatic void cik_init_pg(struct radeon_device *rdev) 676562306a36Sopenharmony_ci{ 676662306a36Sopenharmony_ci if (rdev->pg_flags) { 676762306a36Sopenharmony_ci cik_enable_sck_slowdown_on_pu(rdev, true); 676862306a36Sopenharmony_ci cik_enable_sck_slowdown_on_pd(rdev, true); 676962306a36Sopenharmony_ci if (rdev->pg_flags & RADEON_PG_SUPPORT_GFX_PG) { 677062306a36Sopenharmony_ci cik_init_gfx_cgpg(rdev); 677162306a36Sopenharmony_ci cik_enable_cp_pg(rdev, true); 677262306a36Sopenharmony_ci cik_enable_gds_pg(rdev, true); 677362306a36Sopenharmony_ci } 677462306a36Sopenharmony_ci cik_init_ao_cu_mask(rdev); 677562306a36Sopenharmony_ci cik_update_gfx_pg(rdev, true); 677662306a36Sopenharmony_ci } 677762306a36Sopenharmony_ci} 677862306a36Sopenharmony_ci 677962306a36Sopenharmony_cistatic void cik_fini_pg(struct radeon_device *rdev) 678062306a36Sopenharmony_ci{ 678162306a36Sopenharmony_ci if (rdev->pg_flags) { 678262306a36Sopenharmony_ci cik_update_gfx_pg(rdev, false); 678362306a36Sopenharmony_ci if (rdev->pg_flags & RADEON_PG_SUPPORT_GFX_PG) { 678462306a36Sopenharmony_ci cik_enable_cp_pg(rdev, false); 678562306a36Sopenharmony_ci cik_enable_gds_pg(rdev, false); 678662306a36Sopenharmony_ci } 678762306a36Sopenharmony_ci } 678862306a36Sopenharmony_ci} 678962306a36Sopenharmony_ci 679062306a36Sopenharmony_ci/* 679162306a36Sopenharmony_ci * Interrupts 679262306a36Sopenharmony_ci * Starting with r6xx, interrupts are handled via a ring buffer. 679362306a36Sopenharmony_ci * Ring buffers are areas of GPU accessible memory that the GPU 679462306a36Sopenharmony_ci * writes interrupt vectors into and the host reads vectors out of. 679562306a36Sopenharmony_ci * There is a rptr (read pointer) that determines where the 679662306a36Sopenharmony_ci * host is currently reading, and a wptr (write pointer) 679762306a36Sopenharmony_ci * which determines where the GPU has written. When the 679862306a36Sopenharmony_ci * pointers are equal, the ring is idle. When the GPU 679962306a36Sopenharmony_ci * writes vectors to the ring buffer, it increments the 680062306a36Sopenharmony_ci * wptr. When there is an interrupt, the host then starts 680162306a36Sopenharmony_ci * fetching commands and processing them until the pointers are 680262306a36Sopenharmony_ci * equal again at which point it updates the rptr. 680362306a36Sopenharmony_ci */ 680462306a36Sopenharmony_ci 680562306a36Sopenharmony_ci/** 680662306a36Sopenharmony_ci * cik_enable_interrupts - Enable the interrupt ring buffer 680762306a36Sopenharmony_ci * 680862306a36Sopenharmony_ci * @rdev: radeon_device pointer 680962306a36Sopenharmony_ci * 681062306a36Sopenharmony_ci * Enable the interrupt ring buffer (CIK). 681162306a36Sopenharmony_ci */ 681262306a36Sopenharmony_cistatic void cik_enable_interrupts(struct radeon_device *rdev) 681362306a36Sopenharmony_ci{ 681462306a36Sopenharmony_ci u32 ih_cntl = RREG32(IH_CNTL); 681562306a36Sopenharmony_ci u32 ih_rb_cntl = RREG32(IH_RB_CNTL); 681662306a36Sopenharmony_ci 681762306a36Sopenharmony_ci ih_cntl |= ENABLE_INTR; 681862306a36Sopenharmony_ci ih_rb_cntl |= IH_RB_ENABLE; 681962306a36Sopenharmony_ci WREG32(IH_CNTL, ih_cntl); 682062306a36Sopenharmony_ci WREG32(IH_RB_CNTL, ih_rb_cntl); 682162306a36Sopenharmony_ci rdev->ih.enabled = true; 682262306a36Sopenharmony_ci} 682362306a36Sopenharmony_ci 682462306a36Sopenharmony_ci/** 682562306a36Sopenharmony_ci * cik_disable_interrupts - Disable the interrupt ring buffer 682662306a36Sopenharmony_ci * 682762306a36Sopenharmony_ci * @rdev: radeon_device pointer 682862306a36Sopenharmony_ci * 682962306a36Sopenharmony_ci * Disable the interrupt ring buffer (CIK). 683062306a36Sopenharmony_ci */ 683162306a36Sopenharmony_cistatic void cik_disable_interrupts(struct radeon_device *rdev) 683262306a36Sopenharmony_ci{ 683362306a36Sopenharmony_ci u32 ih_rb_cntl = RREG32(IH_RB_CNTL); 683462306a36Sopenharmony_ci u32 ih_cntl = RREG32(IH_CNTL); 683562306a36Sopenharmony_ci 683662306a36Sopenharmony_ci ih_rb_cntl &= ~IH_RB_ENABLE; 683762306a36Sopenharmony_ci ih_cntl &= ~ENABLE_INTR; 683862306a36Sopenharmony_ci WREG32(IH_RB_CNTL, ih_rb_cntl); 683962306a36Sopenharmony_ci WREG32(IH_CNTL, ih_cntl); 684062306a36Sopenharmony_ci /* set rptr, wptr to 0 */ 684162306a36Sopenharmony_ci WREG32(IH_RB_RPTR, 0); 684262306a36Sopenharmony_ci WREG32(IH_RB_WPTR, 0); 684362306a36Sopenharmony_ci rdev->ih.enabled = false; 684462306a36Sopenharmony_ci rdev->ih.rptr = 0; 684562306a36Sopenharmony_ci} 684662306a36Sopenharmony_ci 684762306a36Sopenharmony_ci/** 684862306a36Sopenharmony_ci * cik_disable_interrupt_state - Disable all interrupt sources 684962306a36Sopenharmony_ci * 685062306a36Sopenharmony_ci * @rdev: radeon_device pointer 685162306a36Sopenharmony_ci * 685262306a36Sopenharmony_ci * Clear all interrupt enable bits used by the driver (CIK). 685362306a36Sopenharmony_ci */ 685462306a36Sopenharmony_cistatic void cik_disable_interrupt_state(struct radeon_device *rdev) 685562306a36Sopenharmony_ci{ 685662306a36Sopenharmony_ci u32 tmp; 685762306a36Sopenharmony_ci 685862306a36Sopenharmony_ci /* gfx ring */ 685962306a36Sopenharmony_ci tmp = RREG32(CP_INT_CNTL_RING0) & 686062306a36Sopenharmony_ci (CNTX_BUSY_INT_ENABLE | CNTX_EMPTY_INT_ENABLE); 686162306a36Sopenharmony_ci WREG32(CP_INT_CNTL_RING0, tmp); 686262306a36Sopenharmony_ci /* sdma */ 686362306a36Sopenharmony_ci tmp = RREG32(SDMA0_CNTL + SDMA0_REGISTER_OFFSET) & ~TRAP_ENABLE; 686462306a36Sopenharmony_ci WREG32(SDMA0_CNTL + SDMA0_REGISTER_OFFSET, tmp); 686562306a36Sopenharmony_ci tmp = RREG32(SDMA0_CNTL + SDMA1_REGISTER_OFFSET) & ~TRAP_ENABLE; 686662306a36Sopenharmony_ci WREG32(SDMA0_CNTL + SDMA1_REGISTER_OFFSET, tmp); 686762306a36Sopenharmony_ci /* compute queues */ 686862306a36Sopenharmony_ci WREG32(CP_ME1_PIPE0_INT_CNTL, 0); 686962306a36Sopenharmony_ci WREG32(CP_ME1_PIPE1_INT_CNTL, 0); 687062306a36Sopenharmony_ci WREG32(CP_ME1_PIPE2_INT_CNTL, 0); 687162306a36Sopenharmony_ci WREG32(CP_ME1_PIPE3_INT_CNTL, 0); 687262306a36Sopenharmony_ci WREG32(CP_ME2_PIPE0_INT_CNTL, 0); 687362306a36Sopenharmony_ci WREG32(CP_ME2_PIPE1_INT_CNTL, 0); 687462306a36Sopenharmony_ci WREG32(CP_ME2_PIPE2_INT_CNTL, 0); 687562306a36Sopenharmony_ci WREG32(CP_ME2_PIPE3_INT_CNTL, 0); 687662306a36Sopenharmony_ci /* grbm */ 687762306a36Sopenharmony_ci WREG32(GRBM_INT_CNTL, 0); 687862306a36Sopenharmony_ci /* SRBM */ 687962306a36Sopenharmony_ci WREG32(SRBM_INT_CNTL, 0); 688062306a36Sopenharmony_ci /* vline/vblank, etc. */ 688162306a36Sopenharmony_ci WREG32(LB_INTERRUPT_MASK + EVERGREEN_CRTC0_REGISTER_OFFSET, 0); 688262306a36Sopenharmony_ci WREG32(LB_INTERRUPT_MASK + EVERGREEN_CRTC1_REGISTER_OFFSET, 0); 688362306a36Sopenharmony_ci if (rdev->num_crtc >= 4) { 688462306a36Sopenharmony_ci WREG32(LB_INTERRUPT_MASK + EVERGREEN_CRTC2_REGISTER_OFFSET, 0); 688562306a36Sopenharmony_ci WREG32(LB_INTERRUPT_MASK + EVERGREEN_CRTC3_REGISTER_OFFSET, 0); 688662306a36Sopenharmony_ci } 688762306a36Sopenharmony_ci if (rdev->num_crtc >= 6) { 688862306a36Sopenharmony_ci WREG32(LB_INTERRUPT_MASK + EVERGREEN_CRTC4_REGISTER_OFFSET, 0); 688962306a36Sopenharmony_ci WREG32(LB_INTERRUPT_MASK + EVERGREEN_CRTC5_REGISTER_OFFSET, 0); 689062306a36Sopenharmony_ci } 689162306a36Sopenharmony_ci /* pflip */ 689262306a36Sopenharmony_ci if (rdev->num_crtc >= 2) { 689362306a36Sopenharmony_ci WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC0_REGISTER_OFFSET, 0); 689462306a36Sopenharmony_ci WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC1_REGISTER_OFFSET, 0); 689562306a36Sopenharmony_ci } 689662306a36Sopenharmony_ci if (rdev->num_crtc >= 4) { 689762306a36Sopenharmony_ci WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC2_REGISTER_OFFSET, 0); 689862306a36Sopenharmony_ci WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC3_REGISTER_OFFSET, 0); 689962306a36Sopenharmony_ci } 690062306a36Sopenharmony_ci if (rdev->num_crtc >= 6) { 690162306a36Sopenharmony_ci WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC4_REGISTER_OFFSET, 0); 690262306a36Sopenharmony_ci WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC5_REGISTER_OFFSET, 0); 690362306a36Sopenharmony_ci } 690462306a36Sopenharmony_ci 690562306a36Sopenharmony_ci /* dac hotplug */ 690662306a36Sopenharmony_ci WREG32(DAC_AUTODETECT_INT_CONTROL, 0); 690762306a36Sopenharmony_ci 690862306a36Sopenharmony_ci /* digital hotplug */ 690962306a36Sopenharmony_ci tmp = RREG32(DC_HPD1_INT_CONTROL) & DC_HPDx_INT_POLARITY; 691062306a36Sopenharmony_ci WREG32(DC_HPD1_INT_CONTROL, tmp); 691162306a36Sopenharmony_ci tmp = RREG32(DC_HPD2_INT_CONTROL) & DC_HPDx_INT_POLARITY; 691262306a36Sopenharmony_ci WREG32(DC_HPD2_INT_CONTROL, tmp); 691362306a36Sopenharmony_ci tmp = RREG32(DC_HPD3_INT_CONTROL) & DC_HPDx_INT_POLARITY; 691462306a36Sopenharmony_ci WREG32(DC_HPD3_INT_CONTROL, tmp); 691562306a36Sopenharmony_ci tmp = RREG32(DC_HPD4_INT_CONTROL) & DC_HPDx_INT_POLARITY; 691662306a36Sopenharmony_ci WREG32(DC_HPD4_INT_CONTROL, tmp); 691762306a36Sopenharmony_ci tmp = RREG32(DC_HPD5_INT_CONTROL) & DC_HPDx_INT_POLARITY; 691862306a36Sopenharmony_ci WREG32(DC_HPD5_INT_CONTROL, tmp); 691962306a36Sopenharmony_ci tmp = RREG32(DC_HPD6_INT_CONTROL) & DC_HPDx_INT_POLARITY; 692062306a36Sopenharmony_ci WREG32(DC_HPD6_INT_CONTROL, tmp); 692162306a36Sopenharmony_ci 692262306a36Sopenharmony_ci} 692362306a36Sopenharmony_ci 692462306a36Sopenharmony_ci/** 692562306a36Sopenharmony_ci * cik_irq_init - init and enable the interrupt ring 692662306a36Sopenharmony_ci * 692762306a36Sopenharmony_ci * @rdev: radeon_device pointer 692862306a36Sopenharmony_ci * 692962306a36Sopenharmony_ci * Allocate a ring buffer for the interrupt controller, 693062306a36Sopenharmony_ci * enable the RLC, disable interrupts, enable the IH 693162306a36Sopenharmony_ci * ring buffer and enable it (CIK). 693262306a36Sopenharmony_ci * Called at device load and reume. 693362306a36Sopenharmony_ci * Returns 0 for success, errors for failure. 693462306a36Sopenharmony_ci */ 693562306a36Sopenharmony_cistatic int cik_irq_init(struct radeon_device *rdev) 693662306a36Sopenharmony_ci{ 693762306a36Sopenharmony_ci int ret = 0; 693862306a36Sopenharmony_ci int rb_bufsz; 693962306a36Sopenharmony_ci u32 interrupt_cntl, ih_cntl, ih_rb_cntl; 694062306a36Sopenharmony_ci 694162306a36Sopenharmony_ci /* allocate ring */ 694262306a36Sopenharmony_ci ret = r600_ih_ring_alloc(rdev); 694362306a36Sopenharmony_ci if (ret) 694462306a36Sopenharmony_ci return ret; 694562306a36Sopenharmony_ci 694662306a36Sopenharmony_ci /* disable irqs */ 694762306a36Sopenharmony_ci cik_disable_interrupts(rdev); 694862306a36Sopenharmony_ci 694962306a36Sopenharmony_ci /* init rlc */ 695062306a36Sopenharmony_ci ret = cik_rlc_resume(rdev); 695162306a36Sopenharmony_ci if (ret) { 695262306a36Sopenharmony_ci r600_ih_ring_fini(rdev); 695362306a36Sopenharmony_ci return ret; 695462306a36Sopenharmony_ci } 695562306a36Sopenharmony_ci 695662306a36Sopenharmony_ci /* setup interrupt control */ 695762306a36Sopenharmony_ci /* set dummy read address to dummy page address */ 695862306a36Sopenharmony_ci WREG32(INTERRUPT_CNTL2, rdev->dummy_page.addr >> 8); 695962306a36Sopenharmony_ci interrupt_cntl = RREG32(INTERRUPT_CNTL); 696062306a36Sopenharmony_ci /* IH_DUMMY_RD_OVERRIDE=0 - dummy read disabled with msi, enabled without msi 696162306a36Sopenharmony_ci * IH_DUMMY_RD_OVERRIDE=1 - dummy read controlled by IH_DUMMY_RD_EN 696262306a36Sopenharmony_ci */ 696362306a36Sopenharmony_ci interrupt_cntl &= ~IH_DUMMY_RD_OVERRIDE; 696462306a36Sopenharmony_ci /* IH_REQ_NONSNOOP_EN=1 if ring is in non-cacheable memory, e.g., vram */ 696562306a36Sopenharmony_ci interrupt_cntl &= ~IH_REQ_NONSNOOP_EN; 696662306a36Sopenharmony_ci WREG32(INTERRUPT_CNTL, interrupt_cntl); 696762306a36Sopenharmony_ci 696862306a36Sopenharmony_ci WREG32(IH_RB_BASE, rdev->ih.gpu_addr >> 8); 696962306a36Sopenharmony_ci rb_bufsz = order_base_2(rdev->ih.ring_size / 4); 697062306a36Sopenharmony_ci 697162306a36Sopenharmony_ci ih_rb_cntl = (IH_WPTR_OVERFLOW_ENABLE | 697262306a36Sopenharmony_ci IH_WPTR_OVERFLOW_CLEAR | 697362306a36Sopenharmony_ci (rb_bufsz << 1)); 697462306a36Sopenharmony_ci 697562306a36Sopenharmony_ci if (rdev->wb.enabled) 697662306a36Sopenharmony_ci ih_rb_cntl |= IH_WPTR_WRITEBACK_ENABLE; 697762306a36Sopenharmony_ci 697862306a36Sopenharmony_ci /* set the writeback address whether it's enabled or not */ 697962306a36Sopenharmony_ci WREG32(IH_RB_WPTR_ADDR_LO, (rdev->wb.gpu_addr + R600_WB_IH_WPTR_OFFSET) & 0xFFFFFFFC); 698062306a36Sopenharmony_ci WREG32(IH_RB_WPTR_ADDR_HI, upper_32_bits(rdev->wb.gpu_addr + R600_WB_IH_WPTR_OFFSET) & 0xFF); 698162306a36Sopenharmony_ci 698262306a36Sopenharmony_ci WREG32(IH_RB_CNTL, ih_rb_cntl); 698362306a36Sopenharmony_ci 698462306a36Sopenharmony_ci /* set rptr, wptr to 0 */ 698562306a36Sopenharmony_ci WREG32(IH_RB_RPTR, 0); 698662306a36Sopenharmony_ci WREG32(IH_RB_WPTR, 0); 698762306a36Sopenharmony_ci 698862306a36Sopenharmony_ci /* Default settings for IH_CNTL (disabled at first) */ 698962306a36Sopenharmony_ci ih_cntl = MC_WRREQ_CREDIT(0x10) | MC_WR_CLEAN_CNT(0x10) | MC_VMID(0); 699062306a36Sopenharmony_ci /* RPTR_REARM only works if msi's are enabled */ 699162306a36Sopenharmony_ci if (rdev->msi_enabled) 699262306a36Sopenharmony_ci ih_cntl |= RPTR_REARM; 699362306a36Sopenharmony_ci WREG32(IH_CNTL, ih_cntl); 699462306a36Sopenharmony_ci 699562306a36Sopenharmony_ci /* force the active interrupt state to all disabled */ 699662306a36Sopenharmony_ci cik_disable_interrupt_state(rdev); 699762306a36Sopenharmony_ci 699862306a36Sopenharmony_ci pci_set_master(rdev->pdev); 699962306a36Sopenharmony_ci 700062306a36Sopenharmony_ci /* enable irqs */ 700162306a36Sopenharmony_ci cik_enable_interrupts(rdev); 700262306a36Sopenharmony_ci 700362306a36Sopenharmony_ci return ret; 700462306a36Sopenharmony_ci} 700562306a36Sopenharmony_ci 700662306a36Sopenharmony_ci/** 700762306a36Sopenharmony_ci * cik_irq_set - enable/disable interrupt sources 700862306a36Sopenharmony_ci * 700962306a36Sopenharmony_ci * @rdev: radeon_device pointer 701062306a36Sopenharmony_ci * 701162306a36Sopenharmony_ci * Enable interrupt sources on the GPU (vblanks, hpd, 701262306a36Sopenharmony_ci * etc.) (CIK). 701362306a36Sopenharmony_ci * Returns 0 for success, errors for failure. 701462306a36Sopenharmony_ci */ 701562306a36Sopenharmony_ciint cik_irq_set(struct radeon_device *rdev) 701662306a36Sopenharmony_ci{ 701762306a36Sopenharmony_ci u32 cp_int_cntl; 701862306a36Sopenharmony_ci u32 cp_m1p0, cp_m1p1, cp_m1p2, cp_m1p3; 701962306a36Sopenharmony_ci u32 cp_m2p0, cp_m2p1, cp_m2p2, cp_m2p3; 702062306a36Sopenharmony_ci u32 crtc1 = 0, crtc2 = 0, crtc3 = 0, crtc4 = 0, crtc5 = 0, crtc6 = 0; 702162306a36Sopenharmony_ci u32 hpd1, hpd2, hpd3, hpd4, hpd5, hpd6; 702262306a36Sopenharmony_ci u32 grbm_int_cntl = 0; 702362306a36Sopenharmony_ci u32 dma_cntl, dma_cntl1; 702462306a36Sopenharmony_ci 702562306a36Sopenharmony_ci if (!rdev->irq.installed) { 702662306a36Sopenharmony_ci WARN(1, "Can't enable IRQ/MSI because no handler is installed\n"); 702762306a36Sopenharmony_ci return -EINVAL; 702862306a36Sopenharmony_ci } 702962306a36Sopenharmony_ci /* don't enable anything if the ih is disabled */ 703062306a36Sopenharmony_ci if (!rdev->ih.enabled) { 703162306a36Sopenharmony_ci cik_disable_interrupts(rdev); 703262306a36Sopenharmony_ci /* force the active interrupt state to all disabled */ 703362306a36Sopenharmony_ci cik_disable_interrupt_state(rdev); 703462306a36Sopenharmony_ci return 0; 703562306a36Sopenharmony_ci } 703662306a36Sopenharmony_ci 703762306a36Sopenharmony_ci cp_int_cntl = RREG32(CP_INT_CNTL_RING0) & 703862306a36Sopenharmony_ci (CNTX_BUSY_INT_ENABLE | CNTX_EMPTY_INT_ENABLE); 703962306a36Sopenharmony_ci cp_int_cntl |= PRIV_INSTR_INT_ENABLE | PRIV_REG_INT_ENABLE; 704062306a36Sopenharmony_ci 704162306a36Sopenharmony_ci hpd1 = RREG32(DC_HPD1_INT_CONTROL) & ~(DC_HPDx_INT_EN | DC_HPDx_RX_INT_EN); 704262306a36Sopenharmony_ci hpd2 = RREG32(DC_HPD2_INT_CONTROL) & ~(DC_HPDx_INT_EN | DC_HPDx_RX_INT_EN); 704362306a36Sopenharmony_ci hpd3 = RREG32(DC_HPD3_INT_CONTROL) & ~(DC_HPDx_INT_EN | DC_HPDx_RX_INT_EN); 704462306a36Sopenharmony_ci hpd4 = RREG32(DC_HPD4_INT_CONTROL) & ~(DC_HPDx_INT_EN | DC_HPDx_RX_INT_EN); 704562306a36Sopenharmony_ci hpd5 = RREG32(DC_HPD5_INT_CONTROL) & ~(DC_HPDx_INT_EN | DC_HPDx_RX_INT_EN); 704662306a36Sopenharmony_ci hpd6 = RREG32(DC_HPD6_INT_CONTROL) & ~(DC_HPDx_INT_EN | DC_HPDx_RX_INT_EN); 704762306a36Sopenharmony_ci 704862306a36Sopenharmony_ci dma_cntl = RREG32(SDMA0_CNTL + SDMA0_REGISTER_OFFSET) & ~TRAP_ENABLE; 704962306a36Sopenharmony_ci dma_cntl1 = RREG32(SDMA0_CNTL + SDMA1_REGISTER_OFFSET) & ~TRAP_ENABLE; 705062306a36Sopenharmony_ci 705162306a36Sopenharmony_ci cp_m1p0 = RREG32(CP_ME1_PIPE0_INT_CNTL) & ~TIME_STAMP_INT_ENABLE; 705262306a36Sopenharmony_ci cp_m1p1 = RREG32(CP_ME1_PIPE1_INT_CNTL) & ~TIME_STAMP_INT_ENABLE; 705362306a36Sopenharmony_ci cp_m1p2 = RREG32(CP_ME1_PIPE2_INT_CNTL) & ~TIME_STAMP_INT_ENABLE; 705462306a36Sopenharmony_ci cp_m1p3 = RREG32(CP_ME1_PIPE3_INT_CNTL) & ~TIME_STAMP_INT_ENABLE; 705562306a36Sopenharmony_ci cp_m2p0 = RREG32(CP_ME2_PIPE0_INT_CNTL) & ~TIME_STAMP_INT_ENABLE; 705662306a36Sopenharmony_ci cp_m2p1 = RREG32(CP_ME2_PIPE1_INT_CNTL) & ~TIME_STAMP_INT_ENABLE; 705762306a36Sopenharmony_ci cp_m2p2 = RREG32(CP_ME2_PIPE2_INT_CNTL) & ~TIME_STAMP_INT_ENABLE; 705862306a36Sopenharmony_ci cp_m2p3 = RREG32(CP_ME2_PIPE3_INT_CNTL) & ~TIME_STAMP_INT_ENABLE; 705962306a36Sopenharmony_ci 706062306a36Sopenharmony_ci /* enable CP interrupts on all rings */ 706162306a36Sopenharmony_ci if (atomic_read(&rdev->irq.ring_int[RADEON_RING_TYPE_GFX_INDEX])) { 706262306a36Sopenharmony_ci DRM_DEBUG("cik_irq_set: sw int gfx\n"); 706362306a36Sopenharmony_ci cp_int_cntl |= TIME_STAMP_INT_ENABLE; 706462306a36Sopenharmony_ci } 706562306a36Sopenharmony_ci if (atomic_read(&rdev->irq.ring_int[CAYMAN_RING_TYPE_CP1_INDEX])) { 706662306a36Sopenharmony_ci struct radeon_ring *ring = &rdev->ring[CAYMAN_RING_TYPE_CP1_INDEX]; 706762306a36Sopenharmony_ci DRM_DEBUG("si_irq_set: sw int cp1\n"); 706862306a36Sopenharmony_ci if (ring->me == 1) { 706962306a36Sopenharmony_ci switch (ring->pipe) { 707062306a36Sopenharmony_ci case 0: 707162306a36Sopenharmony_ci cp_m1p0 |= TIME_STAMP_INT_ENABLE; 707262306a36Sopenharmony_ci break; 707362306a36Sopenharmony_ci case 1: 707462306a36Sopenharmony_ci cp_m1p1 |= TIME_STAMP_INT_ENABLE; 707562306a36Sopenharmony_ci break; 707662306a36Sopenharmony_ci case 2: 707762306a36Sopenharmony_ci cp_m1p2 |= TIME_STAMP_INT_ENABLE; 707862306a36Sopenharmony_ci break; 707962306a36Sopenharmony_ci case 3: 708062306a36Sopenharmony_ci cp_m1p2 |= TIME_STAMP_INT_ENABLE; 708162306a36Sopenharmony_ci break; 708262306a36Sopenharmony_ci default: 708362306a36Sopenharmony_ci DRM_DEBUG("si_irq_set: sw int cp1 invalid pipe %d\n", ring->pipe); 708462306a36Sopenharmony_ci break; 708562306a36Sopenharmony_ci } 708662306a36Sopenharmony_ci } else if (ring->me == 2) { 708762306a36Sopenharmony_ci switch (ring->pipe) { 708862306a36Sopenharmony_ci case 0: 708962306a36Sopenharmony_ci cp_m2p0 |= TIME_STAMP_INT_ENABLE; 709062306a36Sopenharmony_ci break; 709162306a36Sopenharmony_ci case 1: 709262306a36Sopenharmony_ci cp_m2p1 |= TIME_STAMP_INT_ENABLE; 709362306a36Sopenharmony_ci break; 709462306a36Sopenharmony_ci case 2: 709562306a36Sopenharmony_ci cp_m2p2 |= TIME_STAMP_INT_ENABLE; 709662306a36Sopenharmony_ci break; 709762306a36Sopenharmony_ci case 3: 709862306a36Sopenharmony_ci cp_m2p2 |= TIME_STAMP_INT_ENABLE; 709962306a36Sopenharmony_ci break; 710062306a36Sopenharmony_ci default: 710162306a36Sopenharmony_ci DRM_DEBUG("si_irq_set: sw int cp1 invalid pipe %d\n", ring->pipe); 710262306a36Sopenharmony_ci break; 710362306a36Sopenharmony_ci } 710462306a36Sopenharmony_ci } else { 710562306a36Sopenharmony_ci DRM_DEBUG("si_irq_set: sw int cp1 invalid me %d\n", ring->me); 710662306a36Sopenharmony_ci } 710762306a36Sopenharmony_ci } 710862306a36Sopenharmony_ci if (atomic_read(&rdev->irq.ring_int[CAYMAN_RING_TYPE_CP2_INDEX])) { 710962306a36Sopenharmony_ci struct radeon_ring *ring = &rdev->ring[CAYMAN_RING_TYPE_CP2_INDEX]; 711062306a36Sopenharmony_ci DRM_DEBUG("si_irq_set: sw int cp2\n"); 711162306a36Sopenharmony_ci if (ring->me == 1) { 711262306a36Sopenharmony_ci switch (ring->pipe) { 711362306a36Sopenharmony_ci case 0: 711462306a36Sopenharmony_ci cp_m1p0 |= TIME_STAMP_INT_ENABLE; 711562306a36Sopenharmony_ci break; 711662306a36Sopenharmony_ci case 1: 711762306a36Sopenharmony_ci cp_m1p1 |= TIME_STAMP_INT_ENABLE; 711862306a36Sopenharmony_ci break; 711962306a36Sopenharmony_ci case 2: 712062306a36Sopenharmony_ci cp_m1p2 |= TIME_STAMP_INT_ENABLE; 712162306a36Sopenharmony_ci break; 712262306a36Sopenharmony_ci case 3: 712362306a36Sopenharmony_ci cp_m1p2 |= TIME_STAMP_INT_ENABLE; 712462306a36Sopenharmony_ci break; 712562306a36Sopenharmony_ci default: 712662306a36Sopenharmony_ci DRM_DEBUG("si_irq_set: sw int cp2 invalid pipe %d\n", ring->pipe); 712762306a36Sopenharmony_ci break; 712862306a36Sopenharmony_ci } 712962306a36Sopenharmony_ci } else if (ring->me == 2) { 713062306a36Sopenharmony_ci switch (ring->pipe) { 713162306a36Sopenharmony_ci case 0: 713262306a36Sopenharmony_ci cp_m2p0 |= TIME_STAMP_INT_ENABLE; 713362306a36Sopenharmony_ci break; 713462306a36Sopenharmony_ci case 1: 713562306a36Sopenharmony_ci cp_m2p1 |= TIME_STAMP_INT_ENABLE; 713662306a36Sopenharmony_ci break; 713762306a36Sopenharmony_ci case 2: 713862306a36Sopenharmony_ci cp_m2p2 |= TIME_STAMP_INT_ENABLE; 713962306a36Sopenharmony_ci break; 714062306a36Sopenharmony_ci case 3: 714162306a36Sopenharmony_ci cp_m2p2 |= TIME_STAMP_INT_ENABLE; 714262306a36Sopenharmony_ci break; 714362306a36Sopenharmony_ci default: 714462306a36Sopenharmony_ci DRM_DEBUG("si_irq_set: sw int cp2 invalid pipe %d\n", ring->pipe); 714562306a36Sopenharmony_ci break; 714662306a36Sopenharmony_ci } 714762306a36Sopenharmony_ci } else { 714862306a36Sopenharmony_ci DRM_DEBUG("si_irq_set: sw int cp2 invalid me %d\n", ring->me); 714962306a36Sopenharmony_ci } 715062306a36Sopenharmony_ci } 715162306a36Sopenharmony_ci 715262306a36Sopenharmony_ci if (atomic_read(&rdev->irq.ring_int[R600_RING_TYPE_DMA_INDEX])) { 715362306a36Sopenharmony_ci DRM_DEBUG("cik_irq_set: sw int dma\n"); 715462306a36Sopenharmony_ci dma_cntl |= TRAP_ENABLE; 715562306a36Sopenharmony_ci } 715662306a36Sopenharmony_ci 715762306a36Sopenharmony_ci if (atomic_read(&rdev->irq.ring_int[CAYMAN_RING_TYPE_DMA1_INDEX])) { 715862306a36Sopenharmony_ci DRM_DEBUG("cik_irq_set: sw int dma1\n"); 715962306a36Sopenharmony_ci dma_cntl1 |= TRAP_ENABLE; 716062306a36Sopenharmony_ci } 716162306a36Sopenharmony_ci 716262306a36Sopenharmony_ci if (rdev->irq.crtc_vblank_int[0] || 716362306a36Sopenharmony_ci atomic_read(&rdev->irq.pflip[0])) { 716462306a36Sopenharmony_ci DRM_DEBUG("cik_irq_set: vblank 0\n"); 716562306a36Sopenharmony_ci crtc1 |= VBLANK_INTERRUPT_MASK; 716662306a36Sopenharmony_ci } 716762306a36Sopenharmony_ci if (rdev->irq.crtc_vblank_int[1] || 716862306a36Sopenharmony_ci atomic_read(&rdev->irq.pflip[1])) { 716962306a36Sopenharmony_ci DRM_DEBUG("cik_irq_set: vblank 1\n"); 717062306a36Sopenharmony_ci crtc2 |= VBLANK_INTERRUPT_MASK; 717162306a36Sopenharmony_ci } 717262306a36Sopenharmony_ci if (rdev->irq.crtc_vblank_int[2] || 717362306a36Sopenharmony_ci atomic_read(&rdev->irq.pflip[2])) { 717462306a36Sopenharmony_ci DRM_DEBUG("cik_irq_set: vblank 2\n"); 717562306a36Sopenharmony_ci crtc3 |= VBLANK_INTERRUPT_MASK; 717662306a36Sopenharmony_ci } 717762306a36Sopenharmony_ci if (rdev->irq.crtc_vblank_int[3] || 717862306a36Sopenharmony_ci atomic_read(&rdev->irq.pflip[3])) { 717962306a36Sopenharmony_ci DRM_DEBUG("cik_irq_set: vblank 3\n"); 718062306a36Sopenharmony_ci crtc4 |= VBLANK_INTERRUPT_MASK; 718162306a36Sopenharmony_ci } 718262306a36Sopenharmony_ci if (rdev->irq.crtc_vblank_int[4] || 718362306a36Sopenharmony_ci atomic_read(&rdev->irq.pflip[4])) { 718462306a36Sopenharmony_ci DRM_DEBUG("cik_irq_set: vblank 4\n"); 718562306a36Sopenharmony_ci crtc5 |= VBLANK_INTERRUPT_MASK; 718662306a36Sopenharmony_ci } 718762306a36Sopenharmony_ci if (rdev->irq.crtc_vblank_int[5] || 718862306a36Sopenharmony_ci atomic_read(&rdev->irq.pflip[5])) { 718962306a36Sopenharmony_ci DRM_DEBUG("cik_irq_set: vblank 5\n"); 719062306a36Sopenharmony_ci crtc6 |= VBLANK_INTERRUPT_MASK; 719162306a36Sopenharmony_ci } 719262306a36Sopenharmony_ci if (rdev->irq.hpd[0]) { 719362306a36Sopenharmony_ci DRM_DEBUG("cik_irq_set: hpd 1\n"); 719462306a36Sopenharmony_ci hpd1 |= DC_HPDx_INT_EN | DC_HPDx_RX_INT_EN; 719562306a36Sopenharmony_ci } 719662306a36Sopenharmony_ci if (rdev->irq.hpd[1]) { 719762306a36Sopenharmony_ci DRM_DEBUG("cik_irq_set: hpd 2\n"); 719862306a36Sopenharmony_ci hpd2 |= DC_HPDx_INT_EN | DC_HPDx_RX_INT_EN; 719962306a36Sopenharmony_ci } 720062306a36Sopenharmony_ci if (rdev->irq.hpd[2]) { 720162306a36Sopenharmony_ci DRM_DEBUG("cik_irq_set: hpd 3\n"); 720262306a36Sopenharmony_ci hpd3 |= DC_HPDx_INT_EN | DC_HPDx_RX_INT_EN; 720362306a36Sopenharmony_ci } 720462306a36Sopenharmony_ci if (rdev->irq.hpd[3]) { 720562306a36Sopenharmony_ci DRM_DEBUG("cik_irq_set: hpd 4\n"); 720662306a36Sopenharmony_ci hpd4 |= DC_HPDx_INT_EN | DC_HPDx_RX_INT_EN; 720762306a36Sopenharmony_ci } 720862306a36Sopenharmony_ci if (rdev->irq.hpd[4]) { 720962306a36Sopenharmony_ci DRM_DEBUG("cik_irq_set: hpd 5\n"); 721062306a36Sopenharmony_ci hpd5 |= DC_HPDx_INT_EN | DC_HPDx_RX_INT_EN; 721162306a36Sopenharmony_ci } 721262306a36Sopenharmony_ci if (rdev->irq.hpd[5]) { 721362306a36Sopenharmony_ci DRM_DEBUG("cik_irq_set: hpd 6\n"); 721462306a36Sopenharmony_ci hpd6 |= DC_HPDx_INT_EN | DC_HPDx_RX_INT_EN; 721562306a36Sopenharmony_ci } 721662306a36Sopenharmony_ci 721762306a36Sopenharmony_ci WREG32(CP_INT_CNTL_RING0, cp_int_cntl); 721862306a36Sopenharmony_ci 721962306a36Sopenharmony_ci WREG32(SDMA0_CNTL + SDMA0_REGISTER_OFFSET, dma_cntl); 722062306a36Sopenharmony_ci WREG32(SDMA0_CNTL + SDMA1_REGISTER_OFFSET, dma_cntl1); 722162306a36Sopenharmony_ci 722262306a36Sopenharmony_ci WREG32(CP_ME1_PIPE0_INT_CNTL, cp_m1p0); 722362306a36Sopenharmony_ci WREG32(CP_ME1_PIPE1_INT_CNTL, cp_m1p1); 722462306a36Sopenharmony_ci WREG32(CP_ME1_PIPE2_INT_CNTL, cp_m1p2); 722562306a36Sopenharmony_ci WREG32(CP_ME1_PIPE3_INT_CNTL, cp_m1p3); 722662306a36Sopenharmony_ci WREG32(CP_ME2_PIPE0_INT_CNTL, cp_m2p0); 722762306a36Sopenharmony_ci WREG32(CP_ME2_PIPE1_INT_CNTL, cp_m2p1); 722862306a36Sopenharmony_ci WREG32(CP_ME2_PIPE2_INT_CNTL, cp_m2p2); 722962306a36Sopenharmony_ci WREG32(CP_ME2_PIPE3_INT_CNTL, cp_m2p3); 723062306a36Sopenharmony_ci 723162306a36Sopenharmony_ci WREG32(GRBM_INT_CNTL, grbm_int_cntl); 723262306a36Sopenharmony_ci 723362306a36Sopenharmony_ci WREG32(LB_INTERRUPT_MASK + EVERGREEN_CRTC0_REGISTER_OFFSET, crtc1); 723462306a36Sopenharmony_ci WREG32(LB_INTERRUPT_MASK + EVERGREEN_CRTC1_REGISTER_OFFSET, crtc2); 723562306a36Sopenharmony_ci if (rdev->num_crtc >= 4) { 723662306a36Sopenharmony_ci WREG32(LB_INTERRUPT_MASK + EVERGREEN_CRTC2_REGISTER_OFFSET, crtc3); 723762306a36Sopenharmony_ci WREG32(LB_INTERRUPT_MASK + EVERGREEN_CRTC3_REGISTER_OFFSET, crtc4); 723862306a36Sopenharmony_ci } 723962306a36Sopenharmony_ci if (rdev->num_crtc >= 6) { 724062306a36Sopenharmony_ci WREG32(LB_INTERRUPT_MASK + EVERGREEN_CRTC4_REGISTER_OFFSET, crtc5); 724162306a36Sopenharmony_ci WREG32(LB_INTERRUPT_MASK + EVERGREEN_CRTC5_REGISTER_OFFSET, crtc6); 724262306a36Sopenharmony_ci } 724362306a36Sopenharmony_ci 724462306a36Sopenharmony_ci if (rdev->num_crtc >= 2) { 724562306a36Sopenharmony_ci WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC0_REGISTER_OFFSET, 724662306a36Sopenharmony_ci GRPH_PFLIP_INT_MASK); 724762306a36Sopenharmony_ci WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC1_REGISTER_OFFSET, 724862306a36Sopenharmony_ci GRPH_PFLIP_INT_MASK); 724962306a36Sopenharmony_ci } 725062306a36Sopenharmony_ci if (rdev->num_crtc >= 4) { 725162306a36Sopenharmony_ci WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC2_REGISTER_OFFSET, 725262306a36Sopenharmony_ci GRPH_PFLIP_INT_MASK); 725362306a36Sopenharmony_ci WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC3_REGISTER_OFFSET, 725462306a36Sopenharmony_ci GRPH_PFLIP_INT_MASK); 725562306a36Sopenharmony_ci } 725662306a36Sopenharmony_ci if (rdev->num_crtc >= 6) { 725762306a36Sopenharmony_ci WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC4_REGISTER_OFFSET, 725862306a36Sopenharmony_ci GRPH_PFLIP_INT_MASK); 725962306a36Sopenharmony_ci WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC5_REGISTER_OFFSET, 726062306a36Sopenharmony_ci GRPH_PFLIP_INT_MASK); 726162306a36Sopenharmony_ci } 726262306a36Sopenharmony_ci 726362306a36Sopenharmony_ci WREG32(DC_HPD1_INT_CONTROL, hpd1); 726462306a36Sopenharmony_ci WREG32(DC_HPD2_INT_CONTROL, hpd2); 726562306a36Sopenharmony_ci WREG32(DC_HPD3_INT_CONTROL, hpd3); 726662306a36Sopenharmony_ci WREG32(DC_HPD4_INT_CONTROL, hpd4); 726762306a36Sopenharmony_ci WREG32(DC_HPD5_INT_CONTROL, hpd5); 726862306a36Sopenharmony_ci WREG32(DC_HPD6_INT_CONTROL, hpd6); 726962306a36Sopenharmony_ci 727062306a36Sopenharmony_ci /* posting read */ 727162306a36Sopenharmony_ci RREG32(SRBM_STATUS); 727262306a36Sopenharmony_ci 727362306a36Sopenharmony_ci return 0; 727462306a36Sopenharmony_ci} 727562306a36Sopenharmony_ci 727662306a36Sopenharmony_ci/** 727762306a36Sopenharmony_ci * cik_irq_ack - ack interrupt sources 727862306a36Sopenharmony_ci * 727962306a36Sopenharmony_ci * @rdev: radeon_device pointer 728062306a36Sopenharmony_ci * 728162306a36Sopenharmony_ci * Ack interrupt sources on the GPU (vblanks, hpd, 728262306a36Sopenharmony_ci * etc.) (CIK). Certain interrupts sources are sw 728362306a36Sopenharmony_ci * generated and do not require an explicit ack. 728462306a36Sopenharmony_ci */ 728562306a36Sopenharmony_cistatic inline void cik_irq_ack(struct radeon_device *rdev) 728662306a36Sopenharmony_ci{ 728762306a36Sopenharmony_ci u32 tmp; 728862306a36Sopenharmony_ci 728962306a36Sopenharmony_ci rdev->irq.stat_regs.cik.disp_int = RREG32(DISP_INTERRUPT_STATUS); 729062306a36Sopenharmony_ci rdev->irq.stat_regs.cik.disp_int_cont = RREG32(DISP_INTERRUPT_STATUS_CONTINUE); 729162306a36Sopenharmony_ci rdev->irq.stat_regs.cik.disp_int_cont2 = RREG32(DISP_INTERRUPT_STATUS_CONTINUE2); 729262306a36Sopenharmony_ci rdev->irq.stat_regs.cik.disp_int_cont3 = RREG32(DISP_INTERRUPT_STATUS_CONTINUE3); 729362306a36Sopenharmony_ci rdev->irq.stat_regs.cik.disp_int_cont4 = RREG32(DISP_INTERRUPT_STATUS_CONTINUE4); 729462306a36Sopenharmony_ci rdev->irq.stat_regs.cik.disp_int_cont5 = RREG32(DISP_INTERRUPT_STATUS_CONTINUE5); 729562306a36Sopenharmony_ci rdev->irq.stat_regs.cik.disp_int_cont6 = RREG32(DISP_INTERRUPT_STATUS_CONTINUE6); 729662306a36Sopenharmony_ci 729762306a36Sopenharmony_ci rdev->irq.stat_regs.cik.d1grph_int = RREG32(GRPH_INT_STATUS + 729862306a36Sopenharmony_ci EVERGREEN_CRTC0_REGISTER_OFFSET); 729962306a36Sopenharmony_ci rdev->irq.stat_regs.cik.d2grph_int = RREG32(GRPH_INT_STATUS + 730062306a36Sopenharmony_ci EVERGREEN_CRTC1_REGISTER_OFFSET); 730162306a36Sopenharmony_ci if (rdev->num_crtc >= 4) { 730262306a36Sopenharmony_ci rdev->irq.stat_regs.cik.d3grph_int = RREG32(GRPH_INT_STATUS + 730362306a36Sopenharmony_ci EVERGREEN_CRTC2_REGISTER_OFFSET); 730462306a36Sopenharmony_ci rdev->irq.stat_regs.cik.d4grph_int = RREG32(GRPH_INT_STATUS + 730562306a36Sopenharmony_ci EVERGREEN_CRTC3_REGISTER_OFFSET); 730662306a36Sopenharmony_ci } 730762306a36Sopenharmony_ci if (rdev->num_crtc >= 6) { 730862306a36Sopenharmony_ci rdev->irq.stat_regs.cik.d5grph_int = RREG32(GRPH_INT_STATUS + 730962306a36Sopenharmony_ci EVERGREEN_CRTC4_REGISTER_OFFSET); 731062306a36Sopenharmony_ci rdev->irq.stat_regs.cik.d6grph_int = RREG32(GRPH_INT_STATUS + 731162306a36Sopenharmony_ci EVERGREEN_CRTC5_REGISTER_OFFSET); 731262306a36Sopenharmony_ci } 731362306a36Sopenharmony_ci 731462306a36Sopenharmony_ci if (rdev->irq.stat_regs.cik.d1grph_int & GRPH_PFLIP_INT_OCCURRED) 731562306a36Sopenharmony_ci WREG32(GRPH_INT_STATUS + EVERGREEN_CRTC0_REGISTER_OFFSET, 731662306a36Sopenharmony_ci GRPH_PFLIP_INT_CLEAR); 731762306a36Sopenharmony_ci if (rdev->irq.stat_regs.cik.d2grph_int & GRPH_PFLIP_INT_OCCURRED) 731862306a36Sopenharmony_ci WREG32(GRPH_INT_STATUS + EVERGREEN_CRTC1_REGISTER_OFFSET, 731962306a36Sopenharmony_ci GRPH_PFLIP_INT_CLEAR); 732062306a36Sopenharmony_ci if (rdev->irq.stat_regs.cik.disp_int & LB_D1_VBLANK_INTERRUPT) 732162306a36Sopenharmony_ci WREG32(LB_VBLANK_STATUS + EVERGREEN_CRTC0_REGISTER_OFFSET, VBLANK_ACK); 732262306a36Sopenharmony_ci if (rdev->irq.stat_regs.cik.disp_int & LB_D1_VLINE_INTERRUPT) 732362306a36Sopenharmony_ci WREG32(LB_VLINE_STATUS + EVERGREEN_CRTC0_REGISTER_OFFSET, VLINE_ACK); 732462306a36Sopenharmony_ci if (rdev->irq.stat_regs.cik.disp_int_cont & LB_D2_VBLANK_INTERRUPT) 732562306a36Sopenharmony_ci WREG32(LB_VBLANK_STATUS + EVERGREEN_CRTC1_REGISTER_OFFSET, VBLANK_ACK); 732662306a36Sopenharmony_ci if (rdev->irq.stat_regs.cik.disp_int_cont & LB_D2_VLINE_INTERRUPT) 732762306a36Sopenharmony_ci WREG32(LB_VLINE_STATUS + EVERGREEN_CRTC1_REGISTER_OFFSET, VLINE_ACK); 732862306a36Sopenharmony_ci 732962306a36Sopenharmony_ci if (rdev->num_crtc >= 4) { 733062306a36Sopenharmony_ci if (rdev->irq.stat_regs.cik.d3grph_int & GRPH_PFLIP_INT_OCCURRED) 733162306a36Sopenharmony_ci WREG32(GRPH_INT_STATUS + EVERGREEN_CRTC2_REGISTER_OFFSET, 733262306a36Sopenharmony_ci GRPH_PFLIP_INT_CLEAR); 733362306a36Sopenharmony_ci if (rdev->irq.stat_regs.cik.d4grph_int & GRPH_PFLIP_INT_OCCURRED) 733462306a36Sopenharmony_ci WREG32(GRPH_INT_STATUS + EVERGREEN_CRTC3_REGISTER_OFFSET, 733562306a36Sopenharmony_ci GRPH_PFLIP_INT_CLEAR); 733662306a36Sopenharmony_ci if (rdev->irq.stat_regs.cik.disp_int_cont2 & LB_D3_VBLANK_INTERRUPT) 733762306a36Sopenharmony_ci WREG32(LB_VBLANK_STATUS + EVERGREEN_CRTC2_REGISTER_OFFSET, VBLANK_ACK); 733862306a36Sopenharmony_ci if (rdev->irq.stat_regs.cik.disp_int_cont2 & LB_D3_VLINE_INTERRUPT) 733962306a36Sopenharmony_ci WREG32(LB_VLINE_STATUS + EVERGREEN_CRTC2_REGISTER_OFFSET, VLINE_ACK); 734062306a36Sopenharmony_ci if (rdev->irq.stat_regs.cik.disp_int_cont3 & LB_D4_VBLANK_INTERRUPT) 734162306a36Sopenharmony_ci WREG32(LB_VBLANK_STATUS + EVERGREEN_CRTC3_REGISTER_OFFSET, VBLANK_ACK); 734262306a36Sopenharmony_ci if (rdev->irq.stat_regs.cik.disp_int_cont3 & LB_D4_VLINE_INTERRUPT) 734362306a36Sopenharmony_ci WREG32(LB_VLINE_STATUS + EVERGREEN_CRTC3_REGISTER_OFFSET, VLINE_ACK); 734462306a36Sopenharmony_ci } 734562306a36Sopenharmony_ci 734662306a36Sopenharmony_ci if (rdev->num_crtc >= 6) { 734762306a36Sopenharmony_ci if (rdev->irq.stat_regs.cik.d5grph_int & GRPH_PFLIP_INT_OCCURRED) 734862306a36Sopenharmony_ci WREG32(GRPH_INT_STATUS + EVERGREEN_CRTC4_REGISTER_OFFSET, 734962306a36Sopenharmony_ci GRPH_PFLIP_INT_CLEAR); 735062306a36Sopenharmony_ci if (rdev->irq.stat_regs.cik.d6grph_int & GRPH_PFLIP_INT_OCCURRED) 735162306a36Sopenharmony_ci WREG32(GRPH_INT_STATUS + EVERGREEN_CRTC5_REGISTER_OFFSET, 735262306a36Sopenharmony_ci GRPH_PFLIP_INT_CLEAR); 735362306a36Sopenharmony_ci if (rdev->irq.stat_regs.cik.disp_int_cont4 & LB_D5_VBLANK_INTERRUPT) 735462306a36Sopenharmony_ci WREG32(LB_VBLANK_STATUS + EVERGREEN_CRTC4_REGISTER_OFFSET, VBLANK_ACK); 735562306a36Sopenharmony_ci if (rdev->irq.stat_regs.cik.disp_int_cont4 & LB_D5_VLINE_INTERRUPT) 735662306a36Sopenharmony_ci WREG32(LB_VLINE_STATUS + EVERGREEN_CRTC4_REGISTER_OFFSET, VLINE_ACK); 735762306a36Sopenharmony_ci if (rdev->irq.stat_regs.cik.disp_int_cont5 & LB_D6_VBLANK_INTERRUPT) 735862306a36Sopenharmony_ci WREG32(LB_VBLANK_STATUS + EVERGREEN_CRTC5_REGISTER_OFFSET, VBLANK_ACK); 735962306a36Sopenharmony_ci if (rdev->irq.stat_regs.cik.disp_int_cont5 & LB_D6_VLINE_INTERRUPT) 736062306a36Sopenharmony_ci WREG32(LB_VLINE_STATUS + EVERGREEN_CRTC5_REGISTER_OFFSET, VLINE_ACK); 736162306a36Sopenharmony_ci } 736262306a36Sopenharmony_ci 736362306a36Sopenharmony_ci if (rdev->irq.stat_regs.cik.disp_int & DC_HPD1_INTERRUPT) { 736462306a36Sopenharmony_ci tmp = RREG32(DC_HPD1_INT_CONTROL); 736562306a36Sopenharmony_ci tmp |= DC_HPDx_INT_ACK; 736662306a36Sopenharmony_ci WREG32(DC_HPD1_INT_CONTROL, tmp); 736762306a36Sopenharmony_ci } 736862306a36Sopenharmony_ci if (rdev->irq.stat_regs.cik.disp_int_cont & DC_HPD2_INTERRUPT) { 736962306a36Sopenharmony_ci tmp = RREG32(DC_HPD2_INT_CONTROL); 737062306a36Sopenharmony_ci tmp |= DC_HPDx_INT_ACK; 737162306a36Sopenharmony_ci WREG32(DC_HPD2_INT_CONTROL, tmp); 737262306a36Sopenharmony_ci } 737362306a36Sopenharmony_ci if (rdev->irq.stat_regs.cik.disp_int_cont2 & DC_HPD3_INTERRUPT) { 737462306a36Sopenharmony_ci tmp = RREG32(DC_HPD3_INT_CONTROL); 737562306a36Sopenharmony_ci tmp |= DC_HPDx_INT_ACK; 737662306a36Sopenharmony_ci WREG32(DC_HPD3_INT_CONTROL, tmp); 737762306a36Sopenharmony_ci } 737862306a36Sopenharmony_ci if (rdev->irq.stat_regs.cik.disp_int_cont3 & DC_HPD4_INTERRUPT) { 737962306a36Sopenharmony_ci tmp = RREG32(DC_HPD4_INT_CONTROL); 738062306a36Sopenharmony_ci tmp |= DC_HPDx_INT_ACK; 738162306a36Sopenharmony_ci WREG32(DC_HPD4_INT_CONTROL, tmp); 738262306a36Sopenharmony_ci } 738362306a36Sopenharmony_ci if (rdev->irq.stat_regs.cik.disp_int_cont4 & DC_HPD5_INTERRUPT) { 738462306a36Sopenharmony_ci tmp = RREG32(DC_HPD5_INT_CONTROL); 738562306a36Sopenharmony_ci tmp |= DC_HPDx_INT_ACK; 738662306a36Sopenharmony_ci WREG32(DC_HPD5_INT_CONTROL, tmp); 738762306a36Sopenharmony_ci } 738862306a36Sopenharmony_ci if (rdev->irq.stat_regs.cik.disp_int_cont5 & DC_HPD6_INTERRUPT) { 738962306a36Sopenharmony_ci tmp = RREG32(DC_HPD6_INT_CONTROL); 739062306a36Sopenharmony_ci tmp |= DC_HPDx_INT_ACK; 739162306a36Sopenharmony_ci WREG32(DC_HPD6_INT_CONTROL, tmp); 739262306a36Sopenharmony_ci } 739362306a36Sopenharmony_ci if (rdev->irq.stat_regs.cik.disp_int & DC_HPD1_RX_INTERRUPT) { 739462306a36Sopenharmony_ci tmp = RREG32(DC_HPD1_INT_CONTROL); 739562306a36Sopenharmony_ci tmp |= DC_HPDx_RX_INT_ACK; 739662306a36Sopenharmony_ci WREG32(DC_HPD1_INT_CONTROL, tmp); 739762306a36Sopenharmony_ci } 739862306a36Sopenharmony_ci if (rdev->irq.stat_regs.cik.disp_int_cont & DC_HPD2_RX_INTERRUPT) { 739962306a36Sopenharmony_ci tmp = RREG32(DC_HPD2_INT_CONTROL); 740062306a36Sopenharmony_ci tmp |= DC_HPDx_RX_INT_ACK; 740162306a36Sopenharmony_ci WREG32(DC_HPD2_INT_CONTROL, tmp); 740262306a36Sopenharmony_ci } 740362306a36Sopenharmony_ci if (rdev->irq.stat_regs.cik.disp_int_cont2 & DC_HPD3_RX_INTERRUPT) { 740462306a36Sopenharmony_ci tmp = RREG32(DC_HPD3_INT_CONTROL); 740562306a36Sopenharmony_ci tmp |= DC_HPDx_RX_INT_ACK; 740662306a36Sopenharmony_ci WREG32(DC_HPD3_INT_CONTROL, tmp); 740762306a36Sopenharmony_ci } 740862306a36Sopenharmony_ci if (rdev->irq.stat_regs.cik.disp_int_cont3 & DC_HPD4_RX_INTERRUPT) { 740962306a36Sopenharmony_ci tmp = RREG32(DC_HPD4_INT_CONTROL); 741062306a36Sopenharmony_ci tmp |= DC_HPDx_RX_INT_ACK; 741162306a36Sopenharmony_ci WREG32(DC_HPD4_INT_CONTROL, tmp); 741262306a36Sopenharmony_ci } 741362306a36Sopenharmony_ci if (rdev->irq.stat_regs.cik.disp_int_cont4 & DC_HPD5_RX_INTERRUPT) { 741462306a36Sopenharmony_ci tmp = RREG32(DC_HPD5_INT_CONTROL); 741562306a36Sopenharmony_ci tmp |= DC_HPDx_RX_INT_ACK; 741662306a36Sopenharmony_ci WREG32(DC_HPD5_INT_CONTROL, tmp); 741762306a36Sopenharmony_ci } 741862306a36Sopenharmony_ci if (rdev->irq.stat_regs.cik.disp_int_cont5 & DC_HPD6_RX_INTERRUPT) { 741962306a36Sopenharmony_ci tmp = RREG32(DC_HPD6_INT_CONTROL); 742062306a36Sopenharmony_ci tmp |= DC_HPDx_RX_INT_ACK; 742162306a36Sopenharmony_ci WREG32(DC_HPD6_INT_CONTROL, tmp); 742262306a36Sopenharmony_ci } 742362306a36Sopenharmony_ci} 742462306a36Sopenharmony_ci 742562306a36Sopenharmony_ci/** 742662306a36Sopenharmony_ci * cik_irq_disable - disable interrupts 742762306a36Sopenharmony_ci * 742862306a36Sopenharmony_ci * @rdev: radeon_device pointer 742962306a36Sopenharmony_ci * 743062306a36Sopenharmony_ci * Disable interrupts on the hw (CIK). 743162306a36Sopenharmony_ci */ 743262306a36Sopenharmony_cistatic void cik_irq_disable(struct radeon_device *rdev) 743362306a36Sopenharmony_ci{ 743462306a36Sopenharmony_ci cik_disable_interrupts(rdev); 743562306a36Sopenharmony_ci /* Wait and acknowledge irq */ 743662306a36Sopenharmony_ci mdelay(1); 743762306a36Sopenharmony_ci cik_irq_ack(rdev); 743862306a36Sopenharmony_ci cik_disable_interrupt_state(rdev); 743962306a36Sopenharmony_ci} 744062306a36Sopenharmony_ci 744162306a36Sopenharmony_ci/** 744262306a36Sopenharmony_ci * cik_irq_suspend - disable interrupts for suspend 744362306a36Sopenharmony_ci * 744462306a36Sopenharmony_ci * @rdev: radeon_device pointer 744562306a36Sopenharmony_ci * 744662306a36Sopenharmony_ci * Disable interrupts and stop the RLC (CIK). 744762306a36Sopenharmony_ci * Used for suspend. 744862306a36Sopenharmony_ci */ 744962306a36Sopenharmony_cistatic void cik_irq_suspend(struct radeon_device *rdev) 745062306a36Sopenharmony_ci{ 745162306a36Sopenharmony_ci cik_irq_disable(rdev); 745262306a36Sopenharmony_ci cik_rlc_stop(rdev); 745362306a36Sopenharmony_ci} 745462306a36Sopenharmony_ci 745562306a36Sopenharmony_ci/** 745662306a36Sopenharmony_ci * cik_irq_fini - tear down interrupt support 745762306a36Sopenharmony_ci * 745862306a36Sopenharmony_ci * @rdev: radeon_device pointer 745962306a36Sopenharmony_ci * 746062306a36Sopenharmony_ci * Disable interrupts on the hw and free the IH ring 746162306a36Sopenharmony_ci * buffer (CIK). 746262306a36Sopenharmony_ci * Used for driver unload. 746362306a36Sopenharmony_ci */ 746462306a36Sopenharmony_cistatic void cik_irq_fini(struct radeon_device *rdev) 746562306a36Sopenharmony_ci{ 746662306a36Sopenharmony_ci cik_irq_suspend(rdev); 746762306a36Sopenharmony_ci r600_ih_ring_fini(rdev); 746862306a36Sopenharmony_ci} 746962306a36Sopenharmony_ci 747062306a36Sopenharmony_ci/** 747162306a36Sopenharmony_ci * cik_get_ih_wptr - get the IH ring buffer wptr 747262306a36Sopenharmony_ci * 747362306a36Sopenharmony_ci * @rdev: radeon_device pointer 747462306a36Sopenharmony_ci * 747562306a36Sopenharmony_ci * Get the IH ring buffer wptr from either the register 747662306a36Sopenharmony_ci * or the writeback memory buffer (CIK). Also check for 747762306a36Sopenharmony_ci * ring buffer overflow and deal with it. 747862306a36Sopenharmony_ci * Used by cik_irq_process(). 747962306a36Sopenharmony_ci * Returns the value of the wptr. 748062306a36Sopenharmony_ci */ 748162306a36Sopenharmony_cistatic inline u32 cik_get_ih_wptr(struct radeon_device *rdev) 748262306a36Sopenharmony_ci{ 748362306a36Sopenharmony_ci u32 wptr, tmp; 748462306a36Sopenharmony_ci 748562306a36Sopenharmony_ci if (rdev->wb.enabled) 748662306a36Sopenharmony_ci wptr = le32_to_cpu(rdev->wb.wb[R600_WB_IH_WPTR_OFFSET/4]); 748762306a36Sopenharmony_ci else 748862306a36Sopenharmony_ci wptr = RREG32(IH_RB_WPTR); 748962306a36Sopenharmony_ci 749062306a36Sopenharmony_ci if (wptr & RB_OVERFLOW) { 749162306a36Sopenharmony_ci wptr &= ~RB_OVERFLOW; 749262306a36Sopenharmony_ci /* When a ring buffer overflow happen start parsing interrupt 749362306a36Sopenharmony_ci * from the last not overwritten vector (wptr + 16). Hopefully 749462306a36Sopenharmony_ci * this should allow us to catchup. 749562306a36Sopenharmony_ci */ 749662306a36Sopenharmony_ci dev_warn(rdev->dev, "IH ring buffer overflow (0x%08X, 0x%08X, 0x%08X)\n", 749762306a36Sopenharmony_ci wptr, rdev->ih.rptr, (wptr + 16) & rdev->ih.ptr_mask); 749862306a36Sopenharmony_ci rdev->ih.rptr = (wptr + 16) & rdev->ih.ptr_mask; 749962306a36Sopenharmony_ci tmp = RREG32(IH_RB_CNTL); 750062306a36Sopenharmony_ci tmp |= IH_WPTR_OVERFLOW_CLEAR; 750162306a36Sopenharmony_ci WREG32(IH_RB_CNTL, tmp); 750262306a36Sopenharmony_ci } 750362306a36Sopenharmony_ci return (wptr & rdev->ih.ptr_mask); 750462306a36Sopenharmony_ci} 750562306a36Sopenharmony_ci 750662306a36Sopenharmony_ci/* CIK IV Ring 750762306a36Sopenharmony_ci * Each IV ring entry is 128 bits: 750862306a36Sopenharmony_ci * [7:0] - interrupt source id 750962306a36Sopenharmony_ci * [31:8] - reserved 751062306a36Sopenharmony_ci * [59:32] - interrupt source data 751162306a36Sopenharmony_ci * [63:60] - reserved 751262306a36Sopenharmony_ci * [71:64] - RINGID 751362306a36Sopenharmony_ci * CP: 751462306a36Sopenharmony_ci * ME_ID [1:0], PIPE_ID[1:0], QUEUE_ID[2:0] 751562306a36Sopenharmony_ci * QUEUE_ID - for compute, which of the 8 queues owned by the dispatcher 751662306a36Sopenharmony_ci * - for gfx, hw shader state (0=PS...5=LS, 6=CS) 751762306a36Sopenharmony_ci * ME_ID - 0 = gfx, 1 = first 4 CS pipes, 2 = second 4 CS pipes 751862306a36Sopenharmony_ci * PIPE_ID - ME0 0=3D 751962306a36Sopenharmony_ci * - ME1&2 compute dispatcher (4 pipes each) 752062306a36Sopenharmony_ci * SDMA: 752162306a36Sopenharmony_ci * INSTANCE_ID [1:0], QUEUE_ID[1:0] 752262306a36Sopenharmony_ci * INSTANCE_ID - 0 = sdma0, 1 = sdma1 752362306a36Sopenharmony_ci * QUEUE_ID - 0 = gfx, 1 = rlc0, 2 = rlc1 752462306a36Sopenharmony_ci * [79:72] - VMID 752562306a36Sopenharmony_ci * [95:80] - PASID 752662306a36Sopenharmony_ci * [127:96] - reserved 752762306a36Sopenharmony_ci */ 752862306a36Sopenharmony_ci/** 752962306a36Sopenharmony_ci * cik_irq_process - interrupt handler 753062306a36Sopenharmony_ci * 753162306a36Sopenharmony_ci * @rdev: radeon_device pointer 753262306a36Sopenharmony_ci * 753362306a36Sopenharmony_ci * Interrupt hander (CIK). Walk the IH ring, 753462306a36Sopenharmony_ci * ack interrupts and schedule work to handle 753562306a36Sopenharmony_ci * interrupt events. 753662306a36Sopenharmony_ci * Returns irq process return code. 753762306a36Sopenharmony_ci */ 753862306a36Sopenharmony_ciint cik_irq_process(struct radeon_device *rdev) 753962306a36Sopenharmony_ci{ 754062306a36Sopenharmony_ci struct radeon_ring *cp1_ring = &rdev->ring[CAYMAN_RING_TYPE_CP1_INDEX]; 754162306a36Sopenharmony_ci struct radeon_ring *cp2_ring = &rdev->ring[CAYMAN_RING_TYPE_CP2_INDEX]; 754262306a36Sopenharmony_ci u32 wptr; 754362306a36Sopenharmony_ci u32 rptr; 754462306a36Sopenharmony_ci u32 src_id, src_data, ring_id; 754562306a36Sopenharmony_ci u8 me_id, pipe_id, queue_id; 754662306a36Sopenharmony_ci u32 ring_index; 754762306a36Sopenharmony_ci bool queue_hotplug = false; 754862306a36Sopenharmony_ci bool queue_dp = false; 754962306a36Sopenharmony_ci bool queue_reset = false; 755062306a36Sopenharmony_ci u32 addr, status, mc_client; 755162306a36Sopenharmony_ci bool queue_thermal = false; 755262306a36Sopenharmony_ci 755362306a36Sopenharmony_ci if (!rdev->ih.enabled || rdev->shutdown) 755462306a36Sopenharmony_ci return IRQ_NONE; 755562306a36Sopenharmony_ci 755662306a36Sopenharmony_ci wptr = cik_get_ih_wptr(rdev); 755762306a36Sopenharmony_ci 755862306a36Sopenharmony_cirestart_ih: 755962306a36Sopenharmony_ci /* is somebody else already processing irqs? */ 756062306a36Sopenharmony_ci if (atomic_xchg(&rdev->ih.lock, 1)) 756162306a36Sopenharmony_ci return IRQ_NONE; 756262306a36Sopenharmony_ci 756362306a36Sopenharmony_ci rptr = rdev->ih.rptr; 756462306a36Sopenharmony_ci DRM_DEBUG("cik_irq_process start: rptr %d, wptr %d\n", rptr, wptr); 756562306a36Sopenharmony_ci 756662306a36Sopenharmony_ci /* Order reading of wptr vs. reading of IH ring data */ 756762306a36Sopenharmony_ci rmb(); 756862306a36Sopenharmony_ci 756962306a36Sopenharmony_ci /* display interrupts */ 757062306a36Sopenharmony_ci cik_irq_ack(rdev); 757162306a36Sopenharmony_ci 757262306a36Sopenharmony_ci while (rptr != wptr) { 757362306a36Sopenharmony_ci /* wptr/rptr are in bytes! */ 757462306a36Sopenharmony_ci ring_index = rptr / 4; 757562306a36Sopenharmony_ci 757662306a36Sopenharmony_ci src_id = le32_to_cpu(rdev->ih.ring[ring_index]) & 0xff; 757762306a36Sopenharmony_ci src_data = le32_to_cpu(rdev->ih.ring[ring_index + 1]) & 0xfffffff; 757862306a36Sopenharmony_ci ring_id = le32_to_cpu(rdev->ih.ring[ring_index + 2]) & 0xff; 757962306a36Sopenharmony_ci 758062306a36Sopenharmony_ci switch (src_id) { 758162306a36Sopenharmony_ci case 1: /* D1 vblank/vline */ 758262306a36Sopenharmony_ci switch (src_data) { 758362306a36Sopenharmony_ci case 0: /* D1 vblank */ 758462306a36Sopenharmony_ci if (!(rdev->irq.stat_regs.cik.disp_int & LB_D1_VBLANK_INTERRUPT)) 758562306a36Sopenharmony_ci DRM_DEBUG("IH: IH event w/o asserted irq bit?\n"); 758662306a36Sopenharmony_ci 758762306a36Sopenharmony_ci if (rdev->irq.crtc_vblank_int[0]) { 758862306a36Sopenharmony_ci drm_handle_vblank(rdev->ddev, 0); 758962306a36Sopenharmony_ci rdev->pm.vblank_sync = true; 759062306a36Sopenharmony_ci wake_up(&rdev->irq.vblank_queue); 759162306a36Sopenharmony_ci } 759262306a36Sopenharmony_ci if (atomic_read(&rdev->irq.pflip[0])) 759362306a36Sopenharmony_ci radeon_crtc_handle_vblank(rdev, 0); 759462306a36Sopenharmony_ci rdev->irq.stat_regs.cik.disp_int &= ~LB_D1_VBLANK_INTERRUPT; 759562306a36Sopenharmony_ci DRM_DEBUG("IH: D1 vblank\n"); 759662306a36Sopenharmony_ci 759762306a36Sopenharmony_ci break; 759862306a36Sopenharmony_ci case 1: /* D1 vline */ 759962306a36Sopenharmony_ci if (!(rdev->irq.stat_regs.cik.disp_int & LB_D1_VLINE_INTERRUPT)) 760062306a36Sopenharmony_ci DRM_DEBUG("IH: IH event w/o asserted irq bit?\n"); 760162306a36Sopenharmony_ci 760262306a36Sopenharmony_ci rdev->irq.stat_regs.cik.disp_int &= ~LB_D1_VLINE_INTERRUPT; 760362306a36Sopenharmony_ci DRM_DEBUG("IH: D1 vline\n"); 760462306a36Sopenharmony_ci 760562306a36Sopenharmony_ci break; 760662306a36Sopenharmony_ci default: 760762306a36Sopenharmony_ci DRM_DEBUG("Unhandled interrupt: %d %d\n", src_id, src_data); 760862306a36Sopenharmony_ci break; 760962306a36Sopenharmony_ci } 761062306a36Sopenharmony_ci break; 761162306a36Sopenharmony_ci case 2: /* D2 vblank/vline */ 761262306a36Sopenharmony_ci switch (src_data) { 761362306a36Sopenharmony_ci case 0: /* D2 vblank */ 761462306a36Sopenharmony_ci if (!(rdev->irq.stat_regs.cik.disp_int_cont & LB_D2_VBLANK_INTERRUPT)) 761562306a36Sopenharmony_ci DRM_DEBUG("IH: IH event w/o asserted irq bit?\n"); 761662306a36Sopenharmony_ci 761762306a36Sopenharmony_ci if (rdev->irq.crtc_vblank_int[1]) { 761862306a36Sopenharmony_ci drm_handle_vblank(rdev->ddev, 1); 761962306a36Sopenharmony_ci rdev->pm.vblank_sync = true; 762062306a36Sopenharmony_ci wake_up(&rdev->irq.vblank_queue); 762162306a36Sopenharmony_ci } 762262306a36Sopenharmony_ci if (atomic_read(&rdev->irq.pflip[1])) 762362306a36Sopenharmony_ci radeon_crtc_handle_vblank(rdev, 1); 762462306a36Sopenharmony_ci rdev->irq.stat_regs.cik.disp_int_cont &= ~LB_D2_VBLANK_INTERRUPT; 762562306a36Sopenharmony_ci DRM_DEBUG("IH: D2 vblank\n"); 762662306a36Sopenharmony_ci 762762306a36Sopenharmony_ci break; 762862306a36Sopenharmony_ci case 1: /* D2 vline */ 762962306a36Sopenharmony_ci if (!(rdev->irq.stat_regs.cik.disp_int_cont & LB_D2_VLINE_INTERRUPT)) 763062306a36Sopenharmony_ci DRM_DEBUG("IH: IH event w/o asserted irq bit?\n"); 763162306a36Sopenharmony_ci 763262306a36Sopenharmony_ci rdev->irq.stat_regs.cik.disp_int_cont &= ~LB_D2_VLINE_INTERRUPT; 763362306a36Sopenharmony_ci DRM_DEBUG("IH: D2 vline\n"); 763462306a36Sopenharmony_ci 763562306a36Sopenharmony_ci break; 763662306a36Sopenharmony_ci default: 763762306a36Sopenharmony_ci DRM_DEBUG("Unhandled interrupt: %d %d\n", src_id, src_data); 763862306a36Sopenharmony_ci break; 763962306a36Sopenharmony_ci } 764062306a36Sopenharmony_ci break; 764162306a36Sopenharmony_ci case 3: /* D3 vblank/vline */ 764262306a36Sopenharmony_ci switch (src_data) { 764362306a36Sopenharmony_ci case 0: /* D3 vblank */ 764462306a36Sopenharmony_ci if (!(rdev->irq.stat_regs.cik.disp_int_cont2 & LB_D3_VBLANK_INTERRUPT)) 764562306a36Sopenharmony_ci DRM_DEBUG("IH: IH event w/o asserted irq bit?\n"); 764662306a36Sopenharmony_ci 764762306a36Sopenharmony_ci if (rdev->irq.crtc_vblank_int[2]) { 764862306a36Sopenharmony_ci drm_handle_vblank(rdev->ddev, 2); 764962306a36Sopenharmony_ci rdev->pm.vblank_sync = true; 765062306a36Sopenharmony_ci wake_up(&rdev->irq.vblank_queue); 765162306a36Sopenharmony_ci } 765262306a36Sopenharmony_ci if (atomic_read(&rdev->irq.pflip[2])) 765362306a36Sopenharmony_ci radeon_crtc_handle_vblank(rdev, 2); 765462306a36Sopenharmony_ci rdev->irq.stat_regs.cik.disp_int_cont2 &= ~LB_D3_VBLANK_INTERRUPT; 765562306a36Sopenharmony_ci DRM_DEBUG("IH: D3 vblank\n"); 765662306a36Sopenharmony_ci 765762306a36Sopenharmony_ci break; 765862306a36Sopenharmony_ci case 1: /* D3 vline */ 765962306a36Sopenharmony_ci if (!(rdev->irq.stat_regs.cik.disp_int_cont2 & LB_D3_VLINE_INTERRUPT)) 766062306a36Sopenharmony_ci DRM_DEBUG("IH: IH event w/o asserted irq bit?\n"); 766162306a36Sopenharmony_ci 766262306a36Sopenharmony_ci rdev->irq.stat_regs.cik.disp_int_cont2 &= ~LB_D3_VLINE_INTERRUPT; 766362306a36Sopenharmony_ci DRM_DEBUG("IH: D3 vline\n"); 766462306a36Sopenharmony_ci 766562306a36Sopenharmony_ci break; 766662306a36Sopenharmony_ci default: 766762306a36Sopenharmony_ci DRM_DEBUG("Unhandled interrupt: %d %d\n", src_id, src_data); 766862306a36Sopenharmony_ci break; 766962306a36Sopenharmony_ci } 767062306a36Sopenharmony_ci break; 767162306a36Sopenharmony_ci case 4: /* D4 vblank/vline */ 767262306a36Sopenharmony_ci switch (src_data) { 767362306a36Sopenharmony_ci case 0: /* D4 vblank */ 767462306a36Sopenharmony_ci if (!(rdev->irq.stat_regs.cik.disp_int_cont3 & LB_D4_VBLANK_INTERRUPT)) 767562306a36Sopenharmony_ci DRM_DEBUG("IH: IH event w/o asserted irq bit?\n"); 767662306a36Sopenharmony_ci 767762306a36Sopenharmony_ci if (rdev->irq.crtc_vblank_int[3]) { 767862306a36Sopenharmony_ci drm_handle_vblank(rdev->ddev, 3); 767962306a36Sopenharmony_ci rdev->pm.vblank_sync = true; 768062306a36Sopenharmony_ci wake_up(&rdev->irq.vblank_queue); 768162306a36Sopenharmony_ci } 768262306a36Sopenharmony_ci if (atomic_read(&rdev->irq.pflip[3])) 768362306a36Sopenharmony_ci radeon_crtc_handle_vblank(rdev, 3); 768462306a36Sopenharmony_ci rdev->irq.stat_regs.cik.disp_int_cont3 &= ~LB_D4_VBLANK_INTERRUPT; 768562306a36Sopenharmony_ci DRM_DEBUG("IH: D4 vblank\n"); 768662306a36Sopenharmony_ci 768762306a36Sopenharmony_ci break; 768862306a36Sopenharmony_ci case 1: /* D4 vline */ 768962306a36Sopenharmony_ci if (!(rdev->irq.stat_regs.cik.disp_int_cont3 & LB_D4_VLINE_INTERRUPT)) 769062306a36Sopenharmony_ci DRM_DEBUG("IH: IH event w/o asserted irq bit?\n"); 769162306a36Sopenharmony_ci 769262306a36Sopenharmony_ci rdev->irq.stat_regs.cik.disp_int_cont3 &= ~LB_D4_VLINE_INTERRUPT; 769362306a36Sopenharmony_ci DRM_DEBUG("IH: D4 vline\n"); 769462306a36Sopenharmony_ci 769562306a36Sopenharmony_ci break; 769662306a36Sopenharmony_ci default: 769762306a36Sopenharmony_ci DRM_DEBUG("Unhandled interrupt: %d %d\n", src_id, src_data); 769862306a36Sopenharmony_ci break; 769962306a36Sopenharmony_ci } 770062306a36Sopenharmony_ci break; 770162306a36Sopenharmony_ci case 5: /* D5 vblank/vline */ 770262306a36Sopenharmony_ci switch (src_data) { 770362306a36Sopenharmony_ci case 0: /* D5 vblank */ 770462306a36Sopenharmony_ci if (!(rdev->irq.stat_regs.cik.disp_int_cont4 & LB_D5_VBLANK_INTERRUPT)) 770562306a36Sopenharmony_ci DRM_DEBUG("IH: IH event w/o asserted irq bit?\n"); 770662306a36Sopenharmony_ci 770762306a36Sopenharmony_ci if (rdev->irq.crtc_vblank_int[4]) { 770862306a36Sopenharmony_ci drm_handle_vblank(rdev->ddev, 4); 770962306a36Sopenharmony_ci rdev->pm.vblank_sync = true; 771062306a36Sopenharmony_ci wake_up(&rdev->irq.vblank_queue); 771162306a36Sopenharmony_ci } 771262306a36Sopenharmony_ci if (atomic_read(&rdev->irq.pflip[4])) 771362306a36Sopenharmony_ci radeon_crtc_handle_vblank(rdev, 4); 771462306a36Sopenharmony_ci rdev->irq.stat_regs.cik.disp_int_cont4 &= ~LB_D5_VBLANK_INTERRUPT; 771562306a36Sopenharmony_ci DRM_DEBUG("IH: D5 vblank\n"); 771662306a36Sopenharmony_ci 771762306a36Sopenharmony_ci break; 771862306a36Sopenharmony_ci case 1: /* D5 vline */ 771962306a36Sopenharmony_ci if (!(rdev->irq.stat_regs.cik.disp_int_cont4 & LB_D5_VLINE_INTERRUPT)) 772062306a36Sopenharmony_ci DRM_DEBUG("IH: IH event w/o asserted irq bit?\n"); 772162306a36Sopenharmony_ci 772262306a36Sopenharmony_ci rdev->irq.stat_regs.cik.disp_int_cont4 &= ~LB_D5_VLINE_INTERRUPT; 772362306a36Sopenharmony_ci DRM_DEBUG("IH: D5 vline\n"); 772462306a36Sopenharmony_ci 772562306a36Sopenharmony_ci break; 772662306a36Sopenharmony_ci default: 772762306a36Sopenharmony_ci DRM_DEBUG("Unhandled interrupt: %d %d\n", src_id, src_data); 772862306a36Sopenharmony_ci break; 772962306a36Sopenharmony_ci } 773062306a36Sopenharmony_ci break; 773162306a36Sopenharmony_ci case 6: /* D6 vblank/vline */ 773262306a36Sopenharmony_ci switch (src_data) { 773362306a36Sopenharmony_ci case 0: /* D6 vblank */ 773462306a36Sopenharmony_ci if (!(rdev->irq.stat_regs.cik.disp_int_cont5 & LB_D6_VBLANK_INTERRUPT)) 773562306a36Sopenharmony_ci DRM_DEBUG("IH: IH event w/o asserted irq bit?\n"); 773662306a36Sopenharmony_ci 773762306a36Sopenharmony_ci if (rdev->irq.crtc_vblank_int[5]) { 773862306a36Sopenharmony_ci drm_handle_vblank(rdev->ddev, 5); 773962306a36Sopenharmony_ci rdev->pm.vblank_sync = true; 774062306a36Sopenharmony_ci wake_up(&rdev->irq.vblank_queue); 774162306a36Sopenharmony_ci } 774262306a36Sopenharmony_ci if (atomic_read(&rdev->irq.pflip[5])) 774362306a36Sopenharmony_ci radeon_crtc_handle_vblank(rdev, 5); 774462306a36Sopenharmony_ci rdev->irq.stat_regs.cik.disp_int_cont5 &= ~LB_D6_VBLANK_INTERRUPT; 774562306a36Sopenharmony_ci DRM_DEBUG("IH: D6 vblank\n"); 774662306a36Sopenharmony_ci 774762306a36Sopenharmony_ci break; 774862306a36Sopenharmony_ci case 1: /* D6 vline */ 774962306a36Sopenharmony_ci if (!(rdev->irq.stat_regs.cik.disp_int_cont5 & LB_D6_VLINE_INTERRUPT)) 775062306a36Sopenharmony_ci DRM_DEBUG("IH: IH event w/o asserted irq bit?\n"); 775162306a36Sopenharmony_ci 775262306a36Sopenharmony_ci rdev->irq.stat_regs.cik.disp_int_cont5 &= ~LB_D6_VLINE_INTERRUPT; 775362306a36Sopenharmony_ci DRM_DEBUG("IH: D6 vline\n"); 775462306a36Sopenharmony_ci 775562306a36Sopenharmony_ci break; 775662306a36Sopenharmony_ci default: 775762306a36Sopenharmony_ci DRM_DEBUG("Unhandled interrupt: %d %d\n", src_id, src_data); 775862306a36Sopenharmony_ci break; 775962306a36Sopenharmony_ci } 776062306a36Sopenharmony_ci break; 776162306a36Sopenharmony_ci case 8: /* D1 page flip */ 776262306a36Sopenharmony_ci case 10: /* D2 page flip */ 776362306a36Sopenharmony_ci case 12: /* D3 page flip */ 776462306a36Sopenharmony_ci case 14: /* D4 page flip */ 776562306a36Sopenharmony_ci case 16: /* D5 page flip */ 776662306a36Sopenharmony_ci case 18: /* D6 page flip */ 776762306a36Sopenharmony_ci DRM_DEBUG("IH: D%d flip\n", ((src_id - 8) >> 1) + 1); 776862306a36Sopenharmony_ci if (radeon_use_pflipirq > 0) 776962306a36Sopenharmony_ci radeon_crtc_handle_flip(rdev, (src_id - 8) >> 1); 777062306a36Sopenharmony_ci break; 777162306a36Sopenharmony_ci case 42: /* HPD hotplug */ 777262306a36Sopenharmony_ci switch (src_data) { 777362306a36Sopenharmony_ci case 0: 777462306a36Sopenharmony_ci if (!(rdev->irq.stat_regs.cik.disp_int & DC_HPD1_INTERRUPT)) 777562306a36Sopenharmony_ci DRM_DEBUG("IH: IH event w/o asserted irq bit?\n"); 777662306a36Sopenharmony_ci 777762306a36Sopenharmony_ci rdev->irq.stat_regs.cik.disp_int &= ~DC_HPD1_INTERRUPT; 777862306a36Sopenharmony_ci queue_hotplug = true; 777962306a36Sopenharmony_ci DRM_DEBUG("IH: HPD1\n"); 778062306a36Sopenharmony_ci 778162306a36Sopenharmony_ci break; 778262306a36Sopenharmony_ci case 1: 778362306a36Sopenharmony_ci if (!(rdev->irq.stat_regs.cik.disp_int_cont & DC_HPD2_INTERRUPT)) 778462306a36Sopenharmony_ci DRM_DEBUG("IH: IH event w/o asserted irq bit?\n"); 778562306a36Sopenharmony_ci 778662306a36Sopenharmony_ci rdev->irq.stat_regs.cik.disp_int_cont &= ~DC_HPD2_INTERRUPT; 778762306a36Sopenharmony_ci queue_hotplug = true; 778862306a36Sopenharmony_ci DRM_DEBUG("IH: HPD2\n"); 778962306a36Sopenharmony_ci 779062306a36Sopenharmony_ci break; 779162306a36Sopenharmony_ci case 2: 779262306a36Sopenharmony_ci if (!(rdev->irq.stat_regs.cik.disp_int_cont2 & DC_HPD3_INTERRUPT)) 779362306a36Sopenharmony_ci DRM_DEBUG("IH: IH event w/o asserted irq bit?\n"); 779462306a36Sopenharmony_ci 779562306a36Sopenharmony_ci rdev->irq.stat_regs.cik.disp_int_cont2 &= ~DC_HPD3_INTERRUPT; 779662306a36Sopenharmony_ci queue_hotplug = true; 779762306a36Sopenharmony_ci DRM_DEBUG("IH: HPD3\n"); 779862306a36Sopenharmony_ci 779962306a36Sopenharmony_ci break; 780062306a36Sopenharmony_ci case 3: 780162306a36Sopenharmony_ci if (!(rdev->irq.stat_regs.cik.disp_int_cont3 & DC_HPD4_INTERRUPT)) 780262306a36Sopenharmony_ci DRM_DEBUG("IH: IH event w/o asserted irq bit?\n"); 780362306a36Sopenharmony_ci 780462306a36Sopenharmony_ci rdev->irq.stat_regs.cik.disp_int_cont3 &= ~DC_HPD4_INTERRUPT; 780562306a36Sopenharmony_ci queue_hotplug = true; 780662306a36Sopenharmony_ci DRM_DEBUG("IH: HPD4\n"); 780762306a36Sopenharmony_ci 780862306a36Sopenharmony_ci break; 780962306a36Sopenharmony_ci case 4: 781062306a36Sopenharmony_ci if (!(rdev->irq.stat_regs.cik.disp_int_cont4 & DC_HPD5_INTERRUPT)) 781162306a36Sopenharmony_ci DRM_DEBUG("IH: IH event w/o asserted irq bit?\n"); 781262306a36Sopenharmony_ci 781362306a36Sopenharmony_ci rdev->irq.stat_regs.cik.disp_int_cont4 &= ~DC_HPD5_INTERRUPT; 781462306a36Sopenharmony_ci queue_hotplug = true; 781562306a36Sopenharmony_ci DRM_DEBUG("IH: HPD5\n"); 781662306a36Sopenharmony_ci 781762306a36Sopenharmony_ci break; 781862306a36Sopenharmony_ci case 5: 781962306a36Sopenharmony_ci if (!(rdev->irq.stat_regs.cik.disp_int_cont5 & DC_HPD6_INTERRUPT)) 782062306a36Sopenharmony_ci DRM_DEBUG("IH: IH event w/o asserted irq bit?\n"); 782162306a36Sopenharmony_ci 782262306a36Sopenharmony_ci rdev->irq.stat_regs.cik.disp_int_cont5 &= ~DC_HPD6_INTERRUPT; 782362306a36Sopenharmony_ci queue_hotplug = true; 782462306a36Sopenharmony_ci DRM_DEBUG("IH: HPD6\n"); 782562306a36Sopenharmony_ci 782662306a36Sopenharmony_ci break; 782762306a36Sopenharmony_ci case 6: 782862306a36Sopenharmony_ci if (!(rdev->irq.stat_regs.cik.disp_int & DC_HPD1_RX_INTERRUPT)) 782962306a36Sopenharmony_ci DRM_DEBUG("IH: IH event w/o asserted irq bit?\n"); 783062306a36Sopenharmony_ci 783162306a36Sopenharmony_ci rdev->irq.stat_regs.cik.disp_int &= ~DC_HPD1_RX_INTERRUPT; 783262306a36Sopenharmony_ci queue_dp = true; 783362306a36Sopenharmony_ci DRM_DEBUG("IH: HPD_RX 1\n"); 783462306a36Sopenharmony_ci 783562306a36Sopenharmony_ci break; 783662306a36Sopenharmony_ci case 7: 783762306a36Sopenharmony_ci if (!(rdev->irq.stat_regs.cik.disp_int_cont & DC_HPD2_RX_INTERRUPT)) 783862306a36Sopenharmony_ci DRM_DEBUG("IH: IH event w/o asserted irq bit?\n"); 783962306a36Sopenharmony_ci 784062306a36Sopenharmony_ci rdev->irq.stat_regs.cik.disp_int_cont &= ~DC_HPD2_RX_INTERRUPT; 784162306a36Sopenharmony_ci queue_dp = true; 784262306a36Sopenharmony_ci DRM_DEBUG("IH: HPD_RX 2\n"); 784362306a36Sopenharmony_ci 784462306a36Sopenharmony_ci break; 784562306a36Sopenharmony_ci case 8: 784662306a36Sopenharmony_ci if (!(rdev->irq.stat_regs.cik.disp_int_cont2 & DC_HPD3_RX_INTERRUPT)) 784762306a36Sopenharmony_ci DRM_DEBUG("IH: IH event w/o asserted irq bit?\n"); 784862306a36Sopenharmony_ci 784962306a36Sopenharmony_ci rdev->irq.stat_regs.cik.disp_int_cont2 &= ~DC_HPD3_RX_INTERRUPT; 785062306a36Sopenharmony_ci queue_dp = true; 785162306a36Sopenharmony_ci DRM_DEBUG("IH: HPD_RX 3\n"); 785262306a36Sopenharmony_ci 785362306a36Sopenharmony_ci break; 785462306a36Sopenharmony_ci case 9: 785562306a36Sopenharmony_ci if (!(rdev->irq.stat_regs.cik.disp_int_cont3 & DC_HPD4_RX_INTERRUPT)) 785662306a36Sopenharmony_ci DRM_DEBUG("IH: IH event w/o asserted irq bit?\n"); 785762306a36Sopenharmony_ci 785862306a36Sopenharmony_ci rdev->irq.stat_regs.cik.disp_int_cont3 &= ~DC_HPD4_RX_INTERRUPT; 785962306a36Sopenharmony_ci queue_dp = true; 786062306a36Sopenharmony_ci DRM_DEBUG("IH: HPD_RX 4\n"); 786162306a36Sopenharmony_ci 786262306a36Sopenharmony_ci break; 786362306a36Sopenharmony_ci case 10: 786462306a36Sopenharmony_ci if (!(rdev->irq.stat_regs.cik.disp_int_cont4 & DC_HPD5_RX_INTERRUPT)) 786562306a36Sopenharmony_ci DRM_DEBUG("IH: IH event w/o asserted irq bit?\n"); 786662306a36Sopenharmony_ci 786762306a36Sopenharmony_ci rdev->irq.stat_regs.cik.disp_int_cont4 &= ~DC_HPD5_RX_INTERRUPT; 786862306a36Sopenharmony_ci queue_dp = true; 786962306a36Sopenharmony_ci DRM_DEBUG("IH: HPD_RX 5\n"); 787062306a36Sopenharmony_ci 787162306a36Sopenharmony_ci break; 787262306a36Sopenharmony_ci case 11: 787362306a36Sopenharmony_ci if (!(rdev->irq.stat_regs.cik.disp_int_cont5 & DC_HPD6_RX_INTERRUPT)) 787462306a36Sopenharmony_ci DRM_DEBUG("IH: IH event w/o asserted irq bit?\n"); 787562306a36Sopenharmony_ci 787662306a36Sopenharmony_ci rdev->irq.stat_regs.cik.disp_int_cont5 &= ~DC_HPD6_RX_INTERRUPT; 787762306a36Sopenharmony_ci queue_dp = true; 787862306a36Sopenharmony_ci DRM_DEBUG("IH: HPD_RX 6\n"); 787962306a36Sopenharmony_ci 788062306a36Sopenharmony_ci break; 788162306a36Sopenharmony_ci default: 788262306a36Sopenharmony_ci DRM_DEBUG("Unhandled interrupt: %d %d\n", src_id, src_data); 788362306a36Sopenharmony_ci break; 788462306a36Sopenharmony_ci } 788562306a36Sopenharmony_ci break; 788662306a36Sopenharmony_ci case 96: 788762306a36Sopenharmony_ci DRM_ERROR("SRBM_READ_ERROR: 0x%x\n", RREG32(SRBM_READ_ERROR)); 788862306a36Sopenharmony_ci WREG32(SRBM_INT_ACK, 0x1); 788962306a36Sopenharmony_ci break; 789062306a36Sopenharmony_ci case 124: /* UVD */ 789162306a36Sopenharmony_ci DRM_DEBUG("IH: UVD int: 0x%08x\n", src_data); 789262306a36Sopenharmony_ci radeon_fence_process(rdev, R600_RING_TYPE_UVD_INDEX); 789362306a36Sopenharmony_ci break; 789462306a36Sopenharmony_ci case 146: 789562306a36Sopenharmony_ci case 147: 789662306a36Sopenharmony_ci addr = RREG32(VM_CONTEXT1_PROTECTION_FAULT_ADDR); 789762306a36Sopenharmony_ci status = RREG32(VM_CONTEXT1_PROTECTION_FAULT_STATUS); 789862306a36Sopenharmony_ci mc_client = RREG32(VM_CONTEXT1_PROTECTION_FAULT_MCCLIENT); 789962306a36Sopenharmony_ci /* reset addr and status */ 790062306a36Sopenharmony_ci WREG32_P(VM_CONTEXT1_CNTL2, 1, ~1); 790162306a36Sopenharmony_ci if (addr == 0x0 && status == 0x0) 790262306a36Sopenharmony_ci break; 790362306a36Sopenharmony_ci dev_err(rdev->dev, "GPU fault detected: %d 0x%08x\n", src_id, src_data); 790462306a36Sopenharmony_ci dev_err(rdev->dev, " VM_CONTEXT1_PROTECTION_FAULT_ADDR 0x%08X\n", 790562306a36Sopenharmony_ci addr); 790662306a36Sopenharmony_ci dev_err(rdev->dev, " VM_CONTEXT1_PROTECTION_FAULT_STATUS 0x%08X\n", 790762306a36Sopenharmony_ci status); 790862306a36Sopenharmony_ci cik_vm_decode_fault(rdev, status, addr, mc_client); 790962306a36Sopenharmony_ci break; 791062306a36Sopenharmony_ci case 167: /* VCE */ 791162306a36Sopenharmony_ci DRM_DEBUG("IH: VCE int: 0x%08x\n", src_data); 791262306a36Sopenharmony_ci switch (src_data) { 791362306a36Sopenharmony_ci case 0: 791462306a36Sopenharmony_ci radeon_fence_process(rdev, TN_RING_TYPE_VCE1_INDEX); 791562306a36Sopenharmony_ci break; 791662306a36Sopenharmony_ci case 1: 791762306a36Sopenharmony_ci radeon_fence_process(rdev, TN_RING_TYPE_VCE2_INDEX); 791862306a36Sopenharmony_ci break; 791962306a36Sopenharmony_ci default: 792062306a36Sopenharmony_ci DRM_ERROR("Unhandled interrupt: %d %d\n", src_id, src_data); 792162306a36Sopenharmony_ci break; 792262306a36Sopenharmony_ci } 792362306a36Sopenharmony_ci break; 792462306a36Sopenharmony_ci case 176: /* GFX RB CP_INT */ 792562306a36Sopenharmony_ci case 177: /* GFX IB CP_INT */ 792662306a36Sopenharmony_ci radeon_fence_process(rdev, RADEON_RING_TYPE_GFX_INDEX); 792762306a36Sopenharmony_ci break; 792862306a36Sopenharmony_ci case 181: /* CP EOP event */ 792962306a36Sopenharmony_ci DRM_DEBUG("IH: CP EOP\n"); 793062306a36Sopenharmony_ci /* XXX check the bitfield order! */ 793162306a36Sopenharmony_ci me_id = (ring_id & 0x60) >> 5; 793262306a36Sopenharmony_ci pipe_id = (ring_id & 0x18) >> 3; 793362306a36Sopenharmony_ci queue_id = (ring_id & 0x7) >> 0; 793462306a36Sopenharmony_ci switch (me_id) { 793562306a36Sopenharmony_ci case 0: 793662306a36Sopenharmony_ci radeon_fence_process(rdev, RADEON_RING_TYPE_GFX_INDEX); 793762306a36Sopenharmony_ci break; 793862306a36Sopenharmony_ci case 1: 793962306a36Sopenharmony_ci case 2: 794062306a36Sopenharmony_ci if ((cp1_ring->me == me_id) & (cp1_ring->pipe == pipe_id)) 794162306a36Sopenharmony_ci radeon_fence_process(rdev, CAYMAN_RING_TYPE_CP1_INDEX); 794262306a36Sopenharmony_ci if ((cp2_ring->me == me_id) & (cp2_ring->pipe == pipe_id)) 794362306a36Sopenharmony_ci radeon_fence_process(rdev, CAYMAN_RING_TYPE_CP2_INDEX); 794462306a36Sopenharmony_ci break; 794562306a36Sopenharmony_ci } 794662306a36Sopenharmony_ci break; 794762306a36Sopenharmony_ci case 184: /* CP Privileged reg access */ 794862306a36Sopenharmony_ci DRM_ERROR("Illegal register access in command stream\n"); 794962306a36Sopenharmony_ci /* XXX check the bitfield order! */ 795062306a36Sopenharmony_ci me_id = (ring_id & 0x60) >> 5; 795162306a36Sopenharmony_ci switch (me_id) { 795262306a36Sopenharmony_ci case 0: 795362306a36Sopenharmony_ci /* This results in a full GPU reset, but all we need to do is soft 795462306a36Sopenharmony_ci * reset the CP for gfx 795562306a36Sopenharmony_ci */ 795662306a36Sopenharmony_ci queue_reset = true; 795762306a36Sopenharmony_ci break; 795862306a36Sopenharmony_ci case 1: 795962306a36Sopenharmony_ci /* XXX compute */ 796062306a36Sopenharmony_ci queue_reset = true; 796162306a36Sopenharmony_ci break; 796262306a36Sopenharmony_ci case 2: 796362306a36Sopenharmony_ci /* XXX compute */ 796462306a36Sopenharmony_ci queue_reset = true; 796562306a36Sopenharmony_ci break; 796662306a36Sopenharmony_ci } 796762306a36Sopenharmony_ci break; 796862306a36Sopenharmony_ci case 185: /* CP Privileged inst */ 796962306a36Sopenharmony_ci DRM_ERROR("Illegal instruction in command stream\n"); 797062306a36Sopenharmony_ci /* XXX check the bitfield order! */ 797162306a36Sopenharmony_ci me_id = (ring_id & 0x60) >> 5; 797262306a36Sopenharmony_ci switch (me_id) { 797362306a36Sopenharmony_ci case 0: 797462306a36Sopenharmony_ci /* This results in a full GPU reset, but all we need to do is soft 797562306a36Sopenharmony_ci * reset the CP for gfx 797662306a36Sopenharmony_ci */ 797762306a36Sopenharmony_ci queue_reset = true; 797862306a36Sopenharmony_ci break; 797962306a36Sopenharmony_ci case 1: 798062306a36Sopenharmony_ci /* XXX compute */ 798162306a36Sopenharmony_ci queue_reset = true; 798262306a36Sopenharmony_ci break; 798362306a36Sopenharmony_ci case 2: 798462306a36Sopenharmony_ci /* XXX compute */ 798562306a36Sopenharmony_ci queue_reset = true; 798662306a36Sopenharmony_ci break; 798762306a36Sopenharmony_ci } 798862306a36Sopenharmony_ci break; 798962306a36Sopenharmony_ci case 224: /* SDMA trap event */ 799062306a36Sopenharmony_ci /* XXX check the bitfield order! */ 799162306a36Sopenharmony_ci me_id = (ring_id & 0x3) >> 0; 799262306a36Sopenharmony_ci queue_id = (ring_id & 0xc) >> 2; 799362306a36Sopenharmony_ci DRM_DEBUG("IH: SDMA trap\n"); 799462306a36Sopenharmony_ci switch (me_id) { 799562306a36Sopenharmony_ci case 0: 799662306a36Sopenharmony_ci switch (queue_id) { 799762306a36Sopenharmony_ci case 0: 799862306a36Sopenharmony_ci radeon_fence_process(rdev, R600_RING_TYPE_DMA_INDEX); 799962306a36Sopenharmony_ci break; 800062306a36Sopenharmony_ci case 1: 800162306a36Sopenharmony_ci /* XXX compute */ 800262306a36Sopenharmony_ci break; 800362306a36Sopenharmony_ci case 2: 800462306a36Sopenharmony_ci /* XXX compute */ 800562306a36Sopenharmony_ci break; 800662306a36Sopenharmony_ci } 800762306a36Sopenharmony_ci break; 800862306a36Sopenharmony_ci case 1: 800962306a36Sopenharmony_ci switch (queue_id) { 801062306a36Sopenharmony_ci case 0: 801162306a36Sopenharmony_ci radeon_fence_process(rdev, CAYMAN_RING_TYPE_DMA1_INDEX); 801262306a36Sopenharmony_ci break; 801362306a36Sopenharmony_ci case 1: 801462306a36Sopenharmony_ci /* XXX compute */ 801562306a36Sopenharmony_ci break; 801662306a36Sopenharmony_ci case 2: 801762306a36Sopenharmony_ci /* XXX compute */ 801862306a36Sopenharmony_ci break; 801962306a36Sopenharmony_ci } 802062306a36Sopenharmony_ci break; 802162306a36Sopenharmony_ci } 802262306a36Sopenharmony_ci break; 802362306a36Sopenharmony_ci case 230: /* thermal low to high */ 802462306a36Sopenharmony_ci DRM_DEBUG("IH: thermal low to high\n"); 802562306a36Sopenharmony_ci rdev->pm.dpm.thermal.high_to_low = false; 802662306a36Sopenharmony_ci queue_thermal = true; 802762306a36Sopenharmony_ci break; 802862306a36Sopenharmony_ci case 231: /* thermal high to low */ 802962306a36Sopenharmony_ci DRM_DEBUG("IH: thermal high to low\n"); 803062306a36Sopenharmony_ci rdev->pm.dpm.thermal.high_to_low = true; 803162306a36Sopenharmony_ci queue_thermal = true; 803262306a36Sopenharmony_ci break; 803362306a36Sopenharmony_ci case 233: /* GUI IDLE */ 803462306a36Sopenharmony_ci DRM_DEBUG("IH: GUI idle\n"); 803562306a36Sopenharmony_ci break; 803662306a36Sopenharmony_ci case 241: /* SDMA Privileged inst */ 803762306a36Sopenharmony_ci case 247: /* SDMA Privileged inst */ 803862306a36Sopenharmony_ci DRM_ERROR("Illegal instruction in SDMA command stream\n"); 803962306a36Sopenharmony_ci /* XXX check the bitfield order! */ 804062306a36Sopenharmony_ci me_id = (ring_id & 0x3) >> 0; 804162306a36Sopenharmony_ci queue_id = (ring_id & 0xc) >> 2; 804262306a36Sopenharmony_ci switch (me_id) { 804362306a36Sopenharmony_ci case 0: 804462306a36Sopenharmony_ci switch (queue_id) { 804562306a36Sopenharmony_ci case 0: 804662306a36Sopenharmony_ci queue_reset = true; 804762306a36Sopenharmony_ci break; 804862306a36Sopenharmony_ci case 1: 804962306a36Sopenharmony_ci /* XXX compute */ 805062306a36Sopenharmony_ci queue_reset = true; 805162306a36Sopenharmony_ci break; 805262306a36Sopenharmony_ci case 2: 805362306a36Sopenharmony_ci /* XXX compute */ 805462306a36Sopenharmony_ci queue_reset = true; 805562306a36Sopenharmony_ci break; 805662306a36Sopenharmony_ci } 805762306a36Sopenharmony_ci break; 805862306a36Sopenharmony_ci case 1: 805962306a36Sopenharmony_ci switch (queue_id) { 806062306a36Sopenharmony_ci case 0: 806162306a36Sopenharmony_ci queue_reset = true; 806262306a36Sopenharmony_ci break; 806362306a36Sopenharmony_ci case 1: 806462306a36Sopenharmony_ci /* XXX compute */ 806562306a36Sopenharmony_ci queue_reset = true; 806662306a36Sopenharmony_ci break; 806762306a36Sopenharmony_ci case 2: 806862306a36Sopenharmony_ci /* XXX compute */ 806962306a36Sopenharmony_ci queue_reset = true; 807062306a36Sopenharmony_ci break; 807162306a36Sopenharmony_ci } 807262306a36Sopenharmony_ci break; 807362306a36Sopenharmony_ci } 807462306a36Sopenharmony_ci break; 807562306a36Sopenharmony_ci default: 807662306a36Sopenharmony_ci DRM_DEBUG("Unhandled interrupt: %d %d\n", src_id, src_data); 807762306a36Sopenharmony_ci break; 807862306a36Sopenharmony_ci } 807962306a36Sopenharmony_ci 808062306a36Sopenharmony_ci /* wptr/rptr are in bytes! */ 808162306a36Sopenharmony_ci rptr += 16; 808262306a36Sopenharmony_ci rptr &= rdev->ih.ptr_mask; 808362306a36Sopenharmony_ci WREG32(IH_RB_RPTR, rptr); 808462306a36Sopenharmony_ci } 808562306a36Sopenharmony_ci if (queue_dp) 808662306a36Sopenharmony_ci schedule_work(&rdev->dp_work); 808762306a36Sopenharmony_ci if (queue_hotplug) 808862306a36Sopenharmony_ci schedule_delayed_work(&rdev->hotplug_work, 0); 808962306a36Sopenharmony_ci if (queue_reset) { 809062306a36Sopenharmony_ci rdev->needs_reset = true; 809162306a36Sopenharmony_ci wake_up_all(&rdev->fence_queue); 809262306a36Sopenharmony_ci } 809362306a36Sopenharmony_ci if (queue_thermal) 809462306a36Sopenharmony_ci schedule_work(&rdev->pm.dpm.thermal.work); 809562306a36Sopenharmony_ci rdev->ih.rptr = rptr; 809662306a36Sopenharmony_ci atomic_set(&rdev->ih.lock, 0); 809762306a36Sopenharmony_ci 809862306a36Sopenharmony_ci /* make sure wptr hasn't changed while processing */ 809962306a36Sopenharmony_ci wptr = cik_get_ih_wptr(rdev); 810062306a36Sopenharmony_ci if (wptr != rptr) 810162306a36Sopenharmony_ci goto restart_ih; 810262306a36Sopenharmony_ci 810362306a36Sopenharmony_ci return IRQ_HANDLED; 810462306a36Sopenharmony_ci} 810562306a36Sopenharmony_ci 810662306a36Sopenharmony_ci/* 810762306a36Sopenharmony_ci * startup/shutdown callbacks 810862306a36Sopenharmony_ci */ 810962306a36Sopenharmony_cistatic void cik_uvd_init(struct radeon_device *rdev) 811062306a36Sopenharmony_ci{ 811162306a36Sopenharmony_ci int r; 811262306a36Sopenharmony_ci 811362306a36Sopenharmony_ci if (!rdev->has_uvd) 811462306a36Sopenharmony_ci return; 811562306a36Sopenharmony_ci 811662306a36Sopenharmony_ci r = radeon_uvd_init(rdev); 811762306a36Sopenharmony_ci if (r) { 811862306a36Sopenharmony_ci dev_err(rdev->dev, "failed UVD (%d) init.\n", r); 811962306a36Sopenharmony_ci /* 812062306a36Sopenharmony_ci * At this point rdev->uvd.vcpu_bo is NULL which trickles down 812162306a36Sopenharmony_ci * to early fails cik_uvd_start() and thus nothing happens 812262306a36Sopenharmony_ci * there. So it is pointless to try to go through that code 812362306a36Sopenharmony_ci * hence why we disable uvd here. 812462306a36Sopenharmony_ci */ 812562306a36Sopenharmony_ci rdev->has_uvd = false; 812662306a36Sopenharmony_ci return; 812762306a36Sopenharmony_ci } 812862306a36Sopenharmony_ci rdev->ring[R600_RING_TYPE_UVD_INDEX].ring_obj = NULL; 812962306a36Sopenharmony_ci r600_ring_init(rdev, &rdev->ring[R600_RING_TYPE_UVD_INDEX], 4096); 813062306a36Sopenharmony_ci} 813162306a36Sopenharmony_ci 813262306a36Sopenharmony_cistatic void cik_uvd_start(struct radeon_device *rdev) 813362306a36Sopenharmony_ci{ 813462306a36Sopenharmony_ci int r; 813562306a36Sopenharmony_ci 813662306a36Sopenharmony_ci if (!rdev->has_uvd) 813762306a36Sopenharmony_ci return; 813862306a36Sopenharmony_ci 813962306a36Sopenharmony_ci r = radeon_uvd_resume(rdev); 814062306a36Sopenharmony_ci if (r) { 814162306a36Sopenharmony_ci dev_err(rdev->dev, "failed UVD resume (%d).\n", r); 814262306a36Sopenharmony_ci goto error; 814362306a36Sopenharmony_ci } 814462306a36Sopenharmony_ci r = uvd_v4_2_resume(rdev); 814562306a36Sopenharmony_ci if (r) { 814662306a36Sopenharmony_ci dev_err(rdev->dev, "failed UVD 4.2 resume (%d).\n", r); 814762306a36Sopenharmony_ci goto error; 814862306a36Sopenharmony_ci } 814962306a36Sopenharmony_ci r = radeon_fence_driver_start_ring(rdev, R600_RING_TYPE_UVD_INDEX); 815062306a36Sopenharmony_ci if (r) { 815162306a36Sopenharmony_ci dev_err(rdev->dev, "failed initializing UVD fences (%d).\n", r); 815262306a36Sopenharmony_ci goto error; 815362306a36Sopenharmony_ci } 815462306a36Sopenharmony_ci return; 815562306a36Sopenharmony_ci 815662306a36Sopenharmony_cierror: 815762306a36Sopenharmony_ci rdev->ring[R600_RING_TYPE_UVD_INDEX].ring_size = 0; 815862306a36Sopenharmony_ci} 815962306a36Sopenharmony_ci 816062306a36Sopenharmony_cistatic void cik_uvd_resume(struct radeon_device *rdev) 816162306a36Sopenharmony_ci{ 816262306a36Sopenharmony_ci struct radeon_ring *ring; 816362306a36Sopenharmony_ci int r; 816462306a36Sopenharmony_ci 816562306a36Sopenharmony_ci if (!rdev->has_uvd || !rdev->ring[R600_RING_TYPE_UVD_INDEX].ring_size) 816662306a36Sopenharmony_ci return; 816762306a36Sopenharmony_ci 816862306a36Sopenharmony_ci ring = &rdev->ring[R600_RING_TYPE_UVD_INDEX]; 816962306a36Sopenharmony_ci r = radeon_ring_init(rdev, ring, ring->ring_size, 0, PACKET0(UVD_NO_OP, 0)); 817062306a36Sopenharmony_ci if (r) { 817162306a36Sopenharmony_ci dev_err(rdev->dev, "failed initializing UVD ring (%d).\n", r); 817262306a36Sopenharmony_ci return; 817362306a36Sopenharmony_ci } 817462306a36Sopenharmony_ci r = uvd_v1_0_init(rdev); 817562306a36Sopenharmony_ci if (r) { 817662306a36Sopenharmony_ci dev_err(rdev->dev, "failed initializing UVD (%d).\n", r); 817762306a36Sopenharmony_ci return; 817862306a36Sopenharmony_ci } 817962306a36Sopenharmony_ci} 818062306a36Sopenharmony_ci 818162306a36Sopenharmony_cistatic void cik_vce_init(struct radeon_device *rdev) 818262306a36Sopenharmony_ci{ 818362306a36Sopenharmony_ci int r; 818462306a36Sopenharmony_ci 818562306a36Sopenharmony_ci if (!rdev->has_vce) 818662306a36Sopenharmony_ci return; 818762306a36Sopenharmony_ci 818862306a36Sopenharmony_ci r = radeon_vce_init(rdev); 818962306a36Sopenharmony_ci if (r) { 819062306a36Sopenharmony_ci dev_err(rdev->dev, "failed VCE (%d) init.\n", r); 819162306a36Sopenharmony_ci /* 819262306a36Sopenharmony_ci * At this point rdev->vce.vcpu_bo is NULL which trickles down 819362306a36Sopenharmony_ci * to early fails cik_vce_start() and thus nothing happens 819462306a36Sopenharmony_ci * there. So it is pointless to try to go through that code 819562306a36Sopenharmony_ci * hence why we disable vce here. 819662306a36Sopenharmony_ci */ 819762306a36Sopenharmony_ci rdev->has_vce = false; 819862306a36Sopenharmony_ci return; 819962306a36Sopenharmony_ci } 820062306a36Sopenharmony_ci rdev->ring[TN_RING_TYPE_VCE1_INDEX].ring_obj = NULL; 820162306a36Sopenharmony_ci r600_ring_init(rdev, &rdev->ring[TN_RING_TYPE_VCE1_INDEX], 4096); 820262306a36Sopenharmony_ci rdev->ring[TN_RING_TYPE_VCE2_INDEX].ring_obj = NULL; 820362306a36Sopenharmony_ci r600_ring_init(rdev, &rdev->ring[TN_RING_TYPE_VCE2_INDEX], 4096); 820462306a36Sopenharmony_ci} 820562306a36Sopenharmony_ci 820662306a36Sopenharmony_cistatic void cik_vce_start(struct radeon_device *rdev) 820762306a36Sopenharmony_ci{ 820862306a36Sopenharmony_ci int r; 820962306a36Sopenharmony_ci 821062306a36Sopenharmony_ci if (!rdev->has_vce) 821162306a36Sopenharmony_ci return; 821262306a36Sopenharmony_ci 821362306a36Sopenharmony_ci r = radeon_vce_resume(rdev); 821462306a36Sopenharmony_ci if (r) { 821562306a36Sopenharmony_ci dev_err(rdev->dev, "failed VCE resume (%d).\n", r); 821662306a36Sopenharmony_ci goto error; 821762306a36Sopenharmony_ci } 821862306a36Sopenharmony_ci r = vce_v2_0_resume(rdev); 821962306a36Sopenharmony_ci if (r) { 822062306a36Sopenharmony_ci dev_err(rdev->dev, "failed VCE resume (%d).\n", r); 822162306a36Sopenharmony_ci goto error; 822262306a36Sopenharmony_ci } 822362306a36Sopenharmony_ci r = radeon_fence_driver_start_ring(rdev, TN_RING_TYPE_VCE1_INDEX); 822462306a36Sopenharmony_ci if (r) { 822562306a36Sopenharmony_ci dev_err(rdev->dev, "failed initializing VCE1 fences (%d).\n", r); 822662306a36Sopenharmony_ci goto error; 822762306a36Sopenharmony_ci } 822862306a36Sopenharmony_ci r = radeon_fence_driver_start_ring(rdev, TN_RING_TYPE_VCE2_INDEX); 822962306a36Sopenharmony_ci if (r) { 823062306a36Sopenharmony_ci dev_err(rdev->dev, "failed initializing VCE2 fences (%d).\n", r); 823162306a36Sopenharmony_ci goto error; 823262306a36Sopenharmony_ci } 823362306a36Sopenharmony_ci return; 823462306a36Sopenharmony_ci 823562306a36Sopenharmony_cierror: 823662306a36Sopenharmony_ci rdev->ring[TN_RING_TYPE_VCE1_INDEX].ring_size = 0; 823762306a36Sopenharmony_ci rdev->ring[TN_RING_TYPE_VCE2_INDEX].ring_size = 0; 823862306a36Sopenharmony_ci} 823962306a36Sopenharmony_ci 824062306a36Sopenharmony_cistatic void cik_vce_resume(struct radeon_device *rdev) 824162306a36Sopenharmony_ci{ 824262306a36Sopenharmony_ci struct radeon_ring *ring; 824362306a36Sopenharmony_ci int r; 824462306a36Sopenharmony_ci 824562306a36Sopenharmony_ci if (!rdev->has_vce || !rdev->ring[TN_RING_TYPE_VCE1_INDEX].ring_size) 824662306a36Sopenharmony_ci return; 824762306a36Sopenharmony_ci 824862306a36Sopenharmony_ci ring = &rdev->ring[TN_RING_TYPE_VCE1_INDEX]; 824962306a36Sopenharmony_ci r = radeon_ring_init(rdev, ring, ring->ring_size, 0, VCE_CMD_NO_OP); 825062306a36Sopenharmony_ci if (r) { 825162306a36Sopenharmony_ci dev_err(rdev->dev, "failed initializing VCE1 ring (%d).\n", r); 825262306a36Sopenharmony_ci return; 825362306a36Sopenharmony_ci } 825462306a36Sopenharmony_ci ring = &rdev->ring[TN_RING_TYPE_VCE2_INDEX]; 825562306a36Sopenharmony_ci r = radeon_ring_init(rdev, ring, ring->ring_size, 0, VCE_CMD_NO_OP); 825662306a36Sopenharmony_ci if (r) { 825762306a36Sopenharmony_ci dev_err(rdev->dev, "failed initializing VCE1 ring (%d).\n", r); 825862306a36Sopenharmony_ci return; 825962306a36Sopenharmony_ci } 826062306a36Sopenharmony_ci r = vce_v1_0_init(rdev); 826162306a36Sopenharmony_ci if (r) { 826262306a36Sopenharmony_ci dev_err(rdev->dev, "failed initializing VCE (%d).\n", r); 826362306a36Sopenharmony_ci return; 826462306a36Sopenharmony_ci } 826562306a36Sopenharmony_ci} 826662306a36Sopenharmony_ci 826762306a36Sopenharmony_ci/** 826862306a36Sopenharmony_ci * cik_startup - program the asic to a functional state 826962306a36Sopenharmony_ci * 827062306a36Sopenharmony_ci * @rdev: radeon_device pointer 827162306a36Sopenharmony_ci * 827262306a36Sopenharmony_ci * Programs the asic to a functional state (CIK). 827362306a36Sopenharmony_ci * Called by cik_init() and cik_resume(). 827462306a36Sopenharmony_ci * Returns 0 for success, error for failure. 827562306a36Sopenharmony_ci */ 827662306a36Sopenharmony_cistatic int cik_startup(struct radeon_device *rdev) 827762306a36Sopenharmony_ci{ 827862306a36Sopenharmony_ci struct radeon_ring *ring; 827962306a36Sopenharmony_ci u32 nop; 828062306a36Sopenharmony_ci int r; 828162306a36Sopenharmony_ci 828262306a36Sopenharmony_ci /* enable pcie gen2/3 link */ 828362306a36Sopenharmony_ci cik_pcie_gen3_enable(rdev); 828462306a36Sopenharmony_ci /* enable aspm */ 828562306a36Sopenharmony_ci cik_program_aspm(rdev); 828662306a36Sopenharmony_ci 828762306a36Sopenharmony_ci /* scratch needs to be initialized before MC */ 828862306a36Sopenharmony_ci r = r600_vram_scratch_init(rdev); 828962306a36Sopenharmony_ci if (r) 829062306a36Sopenharmony_ci return r; 829162306a36Sopenharmony_ci 829262306a36Sopenharmony_ci cik_mc_program(rdev); 829362306a36Sopenharmony_ci 829462306a36Sopenharmony_ci if (!(rdev->flags & RADEON_IS_IGP) && !rdev->pm.dpm_enabled) { 829562306a36Sopenharmony_ci r = ci_mc_load_microcode(rdev); 829662306a36Sopenharmony_ci if (r) { 829762306a36Sopenharmony_ci DRM_ERROR("Failed to load MC firmware!\n"); 829862306a36Sopenharmony_ci return r; 829962306a36Sopenharmony_ci } 830062306a36Sopenharmony_ci } 830162306a36Sopenharmony_ci 830262306a36Sopenharmony_ci r = cik_pcie_gart_enable(rdev); 830362306a36Sopenharmony_ci if (r) 830462306a36Sopenharmony_ci return r; 830562306a36Sopenharmony_ci cik_gpu_init(rdev); 830662306a36Sopenharmony_ci 830762306a36Sopenharmony_ci /* allocate rlc buffers */ 830862306a36Sopenharmony_ci if (rdev->flags & RADEON_IS_IGP) { 830962306a36Sopenharmony_ci if (rdev->family == CHIP_KAVERI) { 831062306a36Sopenharmony_ci rdev->rlc.reg_list = spectre_rlc_save_restore_register_list; 831162306a36Sopenharmony_ci rdev->rlc.reg_list_size = 831262306a36Sopenharmony_ci (u32)ARRAY_SIZE(spectre_rlc_save_restore_register_list); 831362306a36Sopenharmony_ci } else { 831462306a36Sopenharmony_ci rdev->rlc.reg_list = kalindi_rlc_save_restore_register_list; 831562306a36Sopenharmony_ci rdev->rlc.reg_list_size = 831662306a36Sopenharmony_ci (u32)ARRAY_SIZE(kalindi_rlc_save_restore_register_list); 831762306a36Sopenharmony_ci } 831862306a36Sopenharmony_ci } 831962306a36Sopenharmony_ci rdev->rlc.cs_data = ci_cs_data; 832062306a36Sopenharmony_ci rdev->rlc.cp_table_size = ALIGN(CP_ME_TABLE_SIZE * 5 * 4, 2048); /* CP JT */ 832162306a36Sopenharmony_ci rdev->rlc.cp_table_size += 64 * 1024; /* GDS */ 832262306a36Sopenharmony_ci r = sumo_rlc_init(rdev); 832362306a36Sopenharmony_ci if (r) { 832462306a36Sopenharmony_ci DRM_ERROR("Failed to init rlc BOs!\n"); 832562306a36Sopenharmony_ci return r; 832662306a36Sopenharmony_ci } 832762306a36Sopenharmony_ci 832862306a36Sopenharmony_ci /* allocate wb buffer */ 832962306a36Sopenharmony_ci r = radeon_wb_init(rdev); 833062306a36Sopenharmony_ci if (r) 833162306a36Sopenharmony_ci return r; 833262306a36Sopenharmony_ci 833362306a36Sopenharmony_ci /* allocate mec buffers */ 833462306a36Sopenharmony_ci r = cik_mec_init(rdev); 833562306a36Sopenharmony_ci if (r) { 833662306a36Sopenharmony_ci DRM_ERROR("Failed to init MEC BOs!\n"); 833762306a36Sopenharmony_ci return r; 833862306a36Sopenharmony_ci } 833962306a36Sopenharmony_ci 834062306a36Sopenharmony_ci r = radeon_fence_driver_start_ring(rdev, RADEON_RING_TYPE_GFX_INDEX); 834162306a36Sopenharmony_ci if (r) { 834262306a36Sopenharmony_ci dev_err(rdev->dev, "failed initializing CP fences (%d).\n", r); 834362306a36Sopenharmony_ci return r; 834462306a36Sopenharmony_ci } 834562306a36Sopenharmony_ci 834662306a36Sopenharmony_ci r = radeon_fence_driver_start_ring(rdev, CAYMAN_RING_TYPE_CP1_INDEX); 834762306a36Sopenharmony_ci if (r) { 834862306a36Sopenharmony_ci dev_err(rdev->dev, "failed initializing CP fences (%d).\n", r); 834962306a36Sopenharmony_ci return r; 835062306a36Sopenharmony_ci } 835162306a36Sopenharmony_ci 835262306a36Sopenharmony_ci r = radeon_fence_driver_start_ring(rdev, CAYMAN_RING_TYPE_CP2_INDEX); 835362306a36Sopenharmony_ci if (r) { 835462306a36Sopenharmony_ci dev_err(rdev->dev, "failed initializing CP fences (%d).\n", r); 835562306a36Sopenharmony_ci return r; 835662306a36Sopenharmony_ci } 835762306a36Sopenharmony_ci 835862306a36Sopenharmony_ci r = radeon_fence_driver_start_ring(rdev, R600_RING_TYPE_DMA_INDEX); 835962306a36Sopenharmony_ci if (r) { 836062306a36Sopenharmony_ci dev_err(rdev->dev, "failed initializing DMA fences (%d).\n", r); 836162306a36Sopenharmony_ci return r; 836262306a36Sopenharmony_ci } 836362306a36Sopenharmony_ci 836462306a36Sopenharmony_ci r = radeon_fence_driver_start_ring(rdev, CAYMAN_RING_TYPE_DMA1_INDEX); 836562306a36Sopenharmony_ci if (r) { 836662306a36Sopenharmony_ci dev_err(rdev->dev, "failed initializing DMA fences (%d).\n", r); 836762306a36Sopenharmony_ci return r; 836862306a36Sopenharmony_ci } 836962306a36Sopenharmony_ci 837062306a36Sopenharmony_ci cik_uvd_start(rdev); 837162306a36Sopenharmony_ci cik_vce_start(rdev); 837262306a36Sopenharmony_ci 837362306a36Sopenharmony_ci /* Enable IRQ */ 837462306a36Sopenharmony_ci if (!rdev->irq.installed) { 837562306a36Sopenharmony_ci r = radeon_irq_kms_init(rdev); 837662306a36Sopenharmony_ci if (r) 837762306a36Sopenharmony_ci return r; 837862306a36Sopenharmony_ci } 837962306a36Sopenharmony_ci 838062306a36Sopenharmony_ci r = cik_irq_init(rdev); 838162306a36Sopenharmony_ci if (r) { 838262306a36Sopenharmony_ci DRM_ERROR("radeon: IH init failed (%d).\n", r); 838362306a36Sopenharmony_ci radeon_irq_kms_fini(rdev); 838462306a36Sopenharmony_ci return r; 838562306a36Sopenharmony_ci } 838662306a36Sopenharmony_ci cik_irq_set(rdev); 838762306a36Sopenharmony_ci 838862306a36Sopenharmony_ci if (rdev->family == CHIP_HAWAII) { 838962306a36Sopenharmony_ci if (rdev->new_fw) 839062306a36Sopenharmony_ci nop = PACKET3(PACKET3_NOP, 0x3FFF); 839162306a36Sopenharmony_ci else 839262306a36Sopenharmony_ci nop = RADEON_CP_PACKET2; 839362306a36Sopenharmony_ci } else { 839462306a36Sopenharmony_ci nop = PACKET3(PACKET3_NOP, 0x3FFF); 839562306a36Sopenharmony_ci } 839662306a36Sopenharmony_ci 839762306a36Sopenharmony_ci ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]; 839862306a36Sopenharmony_ci r = radeon_ring_init(rdev, ring, ring->ring_size, RADEON_WB_CP_RPTR_OFFSET, 839962306a36Sopenharmony_ci nop); 840062306a36Sopenharmony_ci if (r) 840162306a36Sopenharmony_ci return r; 840262306a36Sopenharmony_ci 840362306a36Sopenharmony_ci /* set up the compute queues */ 840462306a36Sopenharmony_ci /* type-2 packets are deprecated on MEC, use type-3 instead */ 840562306a36Sopenharmony_ci ring = &rdev->ring[CAYMAN_RING_TYPE_CP1_INDEX]; 840662306a36Sopenharmony_ci r = radeon_ring_init(rdev, ring, ring->ring_size, RADEON_WB_CP1_RPTR_OFFSET, 840762306a36Sopenharmony_ci nop); 840862306a36Sopenharmony_ci if (r) 840962306a36Sopenharmony_ci return r; 841062306a36Sopenharmony_ci ring->me = 1; /* first MEC */ 841162306a36Sopenharmony_ci ring->pipe = 0; /* first pipe */ 841262306a36Sopenharmony_ci ring->queue = 0; /* first queue */ 841362306a36Sopenharmony_ci ring->wptr_offs = CIK_WB_CP1_WPTR_OFFSET; 841462306a36Sopenharmony_ci 841562306a36Sopenharmony_ci /* type-2 packets are deprecated on MEC, use type-3 instead */ 841662306a36Sopenharmony_ci ring = &rdev->ring[CAYMAN_RING_TYPE_CP2_INDEX]; 841762306a36Sopenharmony_ci r = radeon_ring_init(rdev, ring, ring->ring_size, RADEON_WB_CP2_RPTR_OFFSET, 841862306a36Sopenharmony_ci nop); 841962306a36Sopenharmony_ci if (r) 842062306a36Sopenharmony_ci return r; 842162306a36Sopenharmony_ci /* dGPU only have 1 MEC */ 842262306a36Sopenharmony_ci ring->me = 1; /* first MEC */ 842362306a36Sopenharmony_ci ring->pipe = 0; /* first pipe */ 842462306a36Sopenharmony_ci ring->queue = 1; /* second queue */ 842562306a36Sopenharmony_ci ring->wptr_offs = CIK_WB_CP2_WPTR_OFFSET; 842662306a36Sopenharmony_ci 842762306a36Sopenharmony_ci ring = &rdev->ring[R600_RING_TYPE_DMA_INDEX]; 842862306a36Sopenharmony_ci r = radeon_ring_init(rdev, ring, ring->ring_size, R600_WB_DMA_RPTR_OFFSET, 842962306a36Sopenharmony_ci SDMA_PACKET(SDMA_OPCODE_NOP, 0, 0)); 843062306a36Sopenharmony_ci if (r) 843162306a36Sopenharmony_ci return r; 843262306a36Sopenharmony_ci 843362306a36Sopenharmony_ci ring = &rdev->ring[CAYMAN_RING_TYPE_DMA1_INDEX]; 843462306a36Sopenharmony_ci r = radeon_ring_init(rdev, ring, ring->ring_size, CAYMAN_WB_DMA1_RPTR_OFFSET, 843562306a36Sopenharmony_ci SDMA_PACKET(SDMA_OPCODE_NOP, 0, 0)); 843662306a36Sopenharmony_ci if (r) 843762306a36Sopenharmony_ci return r; 843862306a36Sopenharmony_ci 843962306a36Sopenharmony_ci r = cik_cp_resume(rdev); 844062306a36Sopenharmony_ci if (r) 844162306a36Sopenharmony_ci return r; 844262306a36Sopenharmony_ci 844362306a36Sopenharmony_ci r = cik_sdma_resume(rdev); 844462306a36Sopenharmony_ci if (r) 844562306a36Sopenharmony_ci return r; 844662306a36Sopenharmony_ci 844762306a36Sopenharmony_ci cik_uvd_resume(rdev); 844862306a36Sopenharmony_ci cik_vce_resume(rdev); 844962306a36Sopenharmony_ci 845062306a36Sopenharmony_ci r = radeon_ib_pool_init(rdev); 845162306a36Sopenharmony_ci if (r) { 845262306a36Sopenharmony_ci dev_err(rdev->dev, "IB initialization failed (%d).\n", r); 845362306a36Sopenharmony_ci return r; 845462306a36Sopenharmony_ci } 845562306a36Sopenharmony_ci 845662306a36Sopenharmony_ci r = radeon_vm_manager_init(rdev); 845762306a36Sopenharmony_ci if (r) { 845862306a36Sopenharmony_ci dev_err(rdev->dev, "vm manager initialization failed (%d).\n", r); 845962306a36Sopenharmony_ci return r; 846062306a36Sopenharmony_ci } 846162306a36Sopenharmony_ci 846262306a36Sopenharmony_ci r = radeon_audio_init(rdev); 846362306a36Sopenharmony_ci if (r) 846462306a36Sopenharmony_ci return r; 846562306a36Sopenharmony_ci 846662306a36Sopenharmony_ci return 0; 846762306a36Sopenharmony_ci} 846862306a36Sopenharmony_ci 846962306a36Sopenharmony_ci/** 847062306a36Sopenharmony_ci * cik_resume - resume the asic to a functional state 847162306a36Sopenharmony_ci * 847262306a36Sopenharmony_ci * @rdev: radeon_device pointer 847362306a36Sopenharmony_ci * 847462306a36Sopenharmony_ci * Programs the asic to a functional state (CIK). 847562306a36Sopenharmony_ci * Called at resume. 847662306a36Sopenharmony_ci * Returns 0 for success, error for failure. 847762306a36Sopenharmony_ci */ 847862306a36Sopenharmony_ciint cik_resume(struct radeon_device *rdev) 847962306a36Sopenharmony_ci{ 848062306a36Sopenharmony_ci int r; 848162306a36Sopenharmony_ci 848262306a36Sopenharmony_ci /* post card */ 848362306a36Sopenharmony_ci atom_asic_init(rdev->mode_info.atom_context); 848462306a36Sopenharmony_ci 848562306a36Sopenharmony_ci /* init golden registers */ 848662306a36Sopenharmony_ci cik_init_golden_registers(rdev); 848762306a36Sopenharmony_ci 848862306a36Sopenharmony_ci if (rdev->pm.pm_method == PM_METHOD_DPM) 848962306a36Sopenharmony_ci radeon_pm_resume(rdev); 849062306a36Sopenharmony_ci 849162306a36Sopenharmony_ci rdev->accel_working = true; 849262306a36Sopenharmony_ci r = cik_startup(rdev); 849362306a36Sopenharmony_ci if (r) { 849462306a36Sopenharmony_ci DRM_ERROR("cik startup failed on resume\n"); 849562306a36Sopenharmony_ci rdev->accel_working = false; 849662306a36Sopenharmony_ci return r; 849762306a36Sopenharmony_ci } 849862306a36Sopenharmony_ci 849962306a36Sopenharmony_ci return r; 850062306a36Sopenharmony_ci 850162306a36Sopenharmony_ci} 850262306a36Sopenharmony_ci 850362306a36Sopenharmony_ci/** 850462306a36Sopenharmony_ci * cik_suspend - suspend the asic 850562306a36Sopenharmony_ci * 850662306a36Sopenharmony_ci * @rdev: radeon_device pointer 850762306a36Sopenharmony_ci * 850862306a36Sopenharmony_ci * Bring the chip into a state suitable for suspend (CIK). 850962306a36Sopenharmony_ci * Called at suspend. 851062306a36Sopenharmony_ci * Returns 0 for success. 851162306a36Sopenharmony_ci */ 851262306a36Sopenharmony_ciint cik_suspend(struct radeon_device *rdev) 851362306a36Sopenharmony_ci{ 851462306a36Sopenharmony_ci radeon_pm_suspend(rdev); 851562306a36Sopenharmony_ci radeon_audio_fini(rdev); 851662306a36Sopenharmony_ci radeon_vm_manager_fini(rdev); 851762306a36Sopenharmony_ci cik_cp_enable(rdev, false); 851862306a36Sopenharmony_ci cik_sdma_enable(rdev, false); 851962306a36Sopenharmony_ci if (rdev->has_uvd) { 852062306a36Sopenharmony_ci radeon_uvd_suspend(rdev); 852162306a36Sopenharmony_ci uvd_v1_0_fini(rdev); 852262306a36Sopenharmony_ci } 852362306a36Sopenharmony_ci if (rdev->has_vce) 852462306a36Sopenharmony_ci radeon_vce_suspend(rdev); 852562306a36Sopenharmony_ci cik_fini_pg(rdev); 852662306a36Sopenharmony_ci cik_fini_cg(rdev); 852762306a36Sopenharmony_ci cik_irq_suspend(rdev); 852862306a36Sopenharmony_ci radeon_wb_disable(rdev); 852962306a36Sopenharmony_ci cik_pcie_gart_disable(rdev); 853062306a36Sopenharmony_ci return 0; 853162306a36Sopenharmony_ci} 853262306a36Sopenharmony_ci 853362306a36Sopenharmony_ci/* Plan is to move initialization in that function and use 853462306a36Sopenharmony_ci * helper function so that radeon_device_init pretty much 853562306a36Sopenharmony_ci * do nothing more than calling asic specific function. This 853662306a36Sopenharmony_ci * should also allow to remove a bunch of callback function 853762306a36Sopenharmony_ci * like vram_info. 853862306a36Sopenharmony_ci */ 853962306a36Sopenharmony_ci/** 854062306a36Sopenharmony_ci * cik_init - asic specific driver and hw init 854162306a36Sopenharmony_ci * 854262306a36Sopenharmony_ci * @rdev: radeon_device pointer 854362306a36Sopenharmony_ci * 854462306a36Sopenharmony_ci * Setup asic specific driver variables and program the hw 854562306a36Sopenharmony_ci * to a functional state (CIK). 854662306a36Sopenharmony_ci * Called at driver startup. 854762306a36Sopenharmony_ci * Returns 0 for success, errors for failure. 854862306a36Sopenharmony_ci */ 854962306a36Sopenharmony_ciint cik_init(struct radeon_device *rdev) 855062306a36Sopenharmony_ci{ 855162306a36Sopenharmony_ci struct radeon_ring *ring; 855262306a36Sopenharmony_ci int r; 855362306a36Sopenharmony_ci 855462306a36Sopenharmony_ci /* Read BIOS */ 855562306a36Sopenharmony_ci if (!radeon_get_bios(rdev)) { 855662306a36Sopenharmony_ci if (ASIC_IS_AVIVO(rdev)) 855762306a36Sopenharmony_ci return -EINVAL; 855862306a36Sopenharmony_ci } 855962306a36Sopenharmony_ci /* Must be an ATOMBIOS */ 856062306a36Sopenharmony_ci if (!rdev->is_atom_bios) { 856162306a36Sopenharmony_ci dev_err(rdev->dev, "Expecting atombios for cayman GPU\n"); 856262306a36Sopenharmony_ci return -EINVAL; 856362306a36Sopenharmony_ci } 856462306a36Sopenharmony_ci r = radeon_atombios_init(rdev); 856562306a36Sopenharmony_ci if (r) 856662306a36Sopenharmony_ci return r; 856762306a36Sopenharmony_ci 856862306a36Sopenharmony_ci /* Post card if necessary */ 856962306a36Sopenharmony_ci if (!radeon_card_posted(rdev)) { 857062306a36Sopenharmony_ci if (!rdev->bios) { 857162306a36Sopenharmony_ci dev_err(rdev->dev, "Card not posted and no BIOS - ignoring\n"); 857262306a36Sopenharmony_ci return -EINVAL; 857362306a36Sopenharmony_ci } 857462306a36Sopenharmony_ci DRM_INFO("GPU not posted. posting now...\n"); 857562306a36Sopenharmony_ci atom_asic_init(rdev->mode_info.atom_context); 857662306a36Sopenharmony_ci } 857762306a36Sopenharmony_ci /* init golden registers */ 857862306a36Sopenharmony_ci cik_init_golden_registers(rdev); 857962306a36Sopenharmony_ci /* Initialize scratch registers */ 858062306a36Sopenharmony_ci cik_scratch_init(rdev); 858162306a36Sopenharmony_ci /* Initialize surface registers */ 858262306a36Sopenharmony_ci radeon_surface_init(rdev); 858362306a36Sopenharmony_ci /* Initialize clocks */ 858462306a36Sopenharmony_ci radeon_get_clock_info(rdev->ddev); 858562306a36Sopenharmony_ci 858662306a36Sopenharmony_ci /* Fence driver */ 858762306a36Sopenharmony_ci radeon_fence_driver_init(rdev); 858862306a36Sopenharmony_ci 858962306a36Sopenharmony_ci /* initialize memory controller */ 859062306a36Sopenharmony_ci r = cik_mc_init(rdev); 859162306a36Sopenharmony_ci if (r) 859262306a36Sopenharmony_ci return r; 859362306a36Sopenharmony_ci /* Memory manager */ 859462306a36Sopenharmony_ci r = radeon_bo_init(rdev); 859562306a36Sopenharmony_ci if (r) 859662306a36Sopenharmony_ci return r; 859762306a36Sopenharmony_ci 859862306a36Sopenharmony_ci if (rdev->flags & RADEON_IS_IGP) { 859962306a36Sopenharmony_ci if (!rdev->me_fw || !rdev->pfp_fw || !rdev->ce_fw || 860062306a36Sopenharmony_ci !rdev->mec_fw || !rdev->sdma_fw || !rdev->rlc_fw) { 860162306a36Sopenharmony_ci r = cik_init_microcode(rdev); 860262306a36Sopenharmony_ci if (r) { 860362306a36Sopenharmony_ci DRM_ERROR("Failed to load firmware!\n"); 860462306a36Sopenharmony_ci return r; 860562306a36Sopenharmony_ci } 860662306a36Sopenharmony_ci } 860762306a36Sopenharmony_ci } else { 860862306a36Sopenharmony_ci if (!rdev->me_fw || !rdev->pfp_fw || !rdev->ce_fw || 860962306a36Sopenharmony_ci !rdev->mec_fw || !rdev->sdma_fw || !rdev->rlc_fw || 861062306a36Sopenharmony_ci !rdev->mc_fw) { 861162306a36Sopenharmony_ci r = cik_init_microcode(rdev); 861262306a36Sopenharmony_ci if (r) { 861362306a36Sopenharmony_ci DRM_ERROR("Failed to load firmware!\n"); 861462306a36Sopenharmony_ci return r; 861562306a36Sopenharmony_ci } 861662306a36Sopenharmony_ci } 861762306a36Sopenharmony_ci } 861862306a36Sopenharmony_ci 861962306a36Sopenharmony_ci /* Initialize power management */ 862062306a36Sopenharmony_ci radeon_pm_init(rdev); 862162306a36Sopenharmony_ci 862262306a36Sopenharmony_ci ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]; 862362306a36Sopenharmony_ci ring->ring_obj = NULL; 862462306a36Sopenharmony_ci r600_ring_init(rdev, ring, 1024 * 1024); 862562306a36Sopenharmony_ci 862662306a36Sopenharmony_ci ring = &rdev->ring[CAYMAN_RING_TYPE_CP1_INDEX]; 862762306a36Sopenharmony_ci ring->ring_obj = NULL; 862862306a36Sopenharmony_ci r600_ring_init(rdev, ring, 1024 * 1024); 862962306a36Sopenharmony_ci r = radeon_doorbell_get(rdev, &ring->doorbell_index); 863062306a36Sopenharmony_ci if (r) 863162306a36Sopenharmony_ci return r; 863262306a36Sopenharmony_ci 863362306a36Sopenharmony_ci ring = &rdev->ring[CAYMAN_RING_TYPE_CP2_INDEX]; 863462306a36Sopenharmony_ci ring->ring_obj = NULL; 863562306a36Sopenharmony_ci r600_ring_init(rdev, ring, 1024 * 1024); 863662306a36Sopenharmony_ci r = radeon_doorbell_get(rdev, &ring->doorbell_index); 863762306a36Sopenharmony_ci if (r) 863862306a36Sopenharmony_ci return r; 863962306a36Sopenharmony_ci 864062306a36Sopenharmony_ci ring = &rdev->ring[R600_RING_TYPE_DMA_INDEX]; 864162306a36Sopenharmony_ci ring->ring_obj = NULL; 864262306a36Sopenharmony_ci r600_ring_init(rdev, ring, 256 * 1024); 864362306a36Sopenharmony_ci 864462306a36Sopenharmony_ci ring = &rdev->ring[CAYMAN_RING_TYPE_DMA1_INDEX]; 864562306a36Sopenharmony_ci ring->ring_obj = NULL; 864662306a36Sopenharmony_ci r600_ring_init(rdev, ring, 256 * 1024); 864762306a36Sopenharmony_ci 864862306a36Sopenharmony_ci cik_uvd_init(rdev); 864962306a36Sopenharmony_ci cik_vce_init(rdev); 865062306a36Sopenharmony_ci 865162306a36Sopenharmony_ci rdev->ih.ring_obj = NULL; 865262306a36Sopenharmony_ci r600_ih_ring_init(rdev, 64 * 1024); 865362306a36Sopenharmony_ci 865462306a36Sopenharmony_ci r = r600_pcie_gart_init(rdev); 865562306a36Sopenharmony_ci if (r) 865662306a36Sopenharmony_ci return r; 865762306a36Sopenharmony_ci 865862306a36Sopenharmony_ci rdev->accel_working = true; 865962306a36Sopenharmony_ci r = cik_startup(rdev); 866062306a36Sopenharmony_ci if (r) { 866162306a36Sopenharmony_ci dev_err(rdev->dev, "disabling GPU acceleration\n"); 866262306a36Sopenharmony_ci cik_cp_fini(rdev); 866362306a36Sopenharmony_ci cik_sdma_fini(rdev); 866462306a36Sopenharmony_ci cik_irq_fini(rdev); 866562306a36Sopenharmony_ci sumo_rlc_fini(rdev); 866662306a36Sopenharmony_ci cik_mec_fini(rdev); 866762306a36Sopenharmony_ci radeon_wb_fini(rdev); 866862306a36Sopenharmony_ci radeon_ib_pool_fini(rdev); 866962306a36Sopenharmony_ci radeon_vm_manager_fini(rdev); 867062306a36Sopenharmony_ci radeon_irq_kms_fini(rdev); 867162306a36Sopenharmony_ci cik_pcie_gart_fini(rdev); 867262306a36Sopenharmony_ci rdev->accel_working = false; 867362306a36Sopenharmony_ci } 867462306a36Sopenharmony_ci 867562306a36Sopenharmony_ci /* Don't start up if the MC ucode is missing. 867662306a36Sopenharmony_ci * The default clocks and voltages before the MC ucode 867762306a36Sopenharmony_ci * is loaded are not suffient for advanced operations. 867862306a36Sopenharmony_ci */ 867962306a36Sopenharmony_ci if (!rdev->mc_fw && !(rdev->flags & RADEON_IS_IGP)) { 868062306a36Sopenharmony_ci DRM_ERROR("radeon: MC ucode required for NI+.\n"); 868162306a36Sopenharmony_ci return -EINVAL; 868262306a36Sopenharmony_ci } 868362306a36Sopenharmony_ci 868462306a36Sopenharmony_ci return 0; 868562306a36Sopenharmony_ci} 868662306a36Sopenharmony_ci 868762306a36Sopenharmony_ci/** 868862306a36Sopenharmony_ci * cik_fini - asic specific driver and hw fini 868962306a36Sopenharmony_ci * 869062306a36Sopenharmony_ci * @rdev: radeon_device pointer 869162306a36Sopenharmony_ci * 869262306a36Sopenharmony_ci * Tear down the asic specific driver variables and program the hw 869362306a36Sopenharmony_ci * to an idle state (CIK). 869462306a36Sopenharmony_ci * Called at driver unload. 869562306a36Sopenharmony_ci */ 869662306a36Sopenharmony_civoid cik_fini(struct radeon_device *rdev) 869762306a36Sopenharmony_ci{ 869862306a36Sopenharmony_ci radeon_pm_fini(rdev); 869962306a36Sopenharmony_ci cik_cp_fini(rdev); 870062306a36Sopenharmony_ci cik_sdma_fini(rdev); 870162306a36Sopenharmony_ci cik_fini_pg(rdev); 870262306a36Sopenharmony_ci cik_fini_cg(rdev); 870362306a36Sopenharmony_ci cik_irq_fini(rdev); 870462306a36Sopenharmony_ci sumo_rlc_fini(rdev); 870562306a36Sopenharmony_ci cik_mec_fini(rdev); 870662306a36Sopenharmony_ci radeon_wb_fini(rdev); 870762306a36Sopenharmony_ci radeon_vm_manager_fini(rdev); 870862306a36Sopenharmony_ci radeon_ib_pool_fini(rdev); 870962306a36Sopenharmony_ci radeon_irq_kms_fini(rdev); 871062306a36Sopenharmony_ci uvd_v1_0_fini(rdev); 871162306a36Sopenharmony_ci radeon_uvd_fini(rdev); 871262306a36Sopenharmony_ci radeon_vce_fini(rdev); 871362306a36Sopenharmony_ci cik_pcie_gart_fini(rdev); 871462306a36Sopenharmony_ci r600_vram_scratch_fini(rdev); 871562306a36Sopenharmony_ci radeon_gem_fini(rdev); 871662306a36Sopenharmony_ci radeon_fence_driver_fini(rdev); 871762306a36Sopenharmony_ci radeon_bo_fini(rdev); 871862306a36Sopenharmony_ci radeon_atombios_fini(rdev); 871962306a36Sopenharmony_ci kfree(rdev->bios); 872062306a36Sopenharmony_ci rdev->bios = NULL; 872162306a36Sopenharmony_ci} 872262306a36Sopenharmony_ci 872362306a36Sopenharmony_civoid dce8_program_fmt(struct drm_encoder *encoder) 872462306a36Sopenharmony_ci{ 872562306a36Sopenharmony_ci struct drm_device *dev = encoder->dev; 872662306a36Sopenharmony_ci struct radeon_device *rdev = dev->dev_private; 872762306a36Sopenharmony_ci struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); 872862306a36Sopenharmony_ci struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc); 872962306a36Sopenharmony_ci struct drm_connector *connector = radeon_get_connector_for_encoder(encoder); 873062306a36Sopenharmony_ci int bpc = 0; 873162306a36Sopenharmony_ci u32 tmp = 0; 873262306a36Sopenharmony_ci enum radeon_connector_dither dither = RADEON_FMT_DITHER_DISABLE; 873362306a36Sopenharmony_ci 873462306a36Sopenharmony_ci if (connector) { 873562306a36Sopenharmony_ci struct radeon_connector *radeon_connector = to_radeon_connector(connector); 873662306a36Sopenharmony_ci bpc = radeon_get_monitor_bpc(connector); 873762306a36Sopenharmony_ci dither = radeon_connector->dither; 873862306a36Sopenharmony_ci } 873962306a36Sopenharmony_ci 874062306a36Sopenharmony_ci /* LVDS/eDP FMT is set up by atom */ 874162306a36Sopenharmony_ci if (radeon_encoder->devices & ATOM_DEVICE_LCD_SUPPORT) 874262306a36Sopenharmony_ci return; 874362306a36Sopenharmony_ci 874462306a36Sopenharmony_ci /* not needed for analog */ 874562306a36Sopenharmony_ci if ((radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1) || 874662306a36Sopenharmony_ci (radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2)) 874762306a36Sopenharmony_ci return; 874862306a36Sopenharmony_ci 874962306a36Sopenharmony_ci if (bpc == 0) 875062306a36Sopenharmony_ci return; 875162306a36Sopenharmony_ci 875262306a36Sopenharmony_ci switch (bpc) { 875362306a36Sopenharmony_ci case 6: 875462306a36Sopenharmony_ci if (dither == RADEON_FMT_DITHER_ENABLE) 875562306a36Sopenharmony_ci /* XXX sort out optimal dither settings */ 875662306a36Sopenharmony_ci tmp |= (FMT_FRAME_RANDOM_ENABLE | FMT_HIGHPASS_RANDOM_ENABLE | 875762306a36Sopenharmony_ci FMT_SPATIAL_DITHER_EN | FMT_SPATIAL_DITHER_DEPTH(0)); 875862306a36Sopenharmony_ci else 875962306a36Sopenharmony_ci tmp |= (FMT_TRUNCATE_EN | FMT_TRUNCATE_DEPTH(0)); 876062306a36Sopenharmony_ci break; 876162306a36Sopenharmony_ci case 8: 876262306a36Sopenharmony_ci if (dither == RADEON_FMT_DITHER_ENABLE) 876362306a36Sopenharmony_ci /* XXX sort out optimal dither settings */ 876462306a36Sopenharmony_ci tmp |= (FMT_FRAME_RANDOM_ENABLE | FMT_HIGHPASS_RANDOM_ENABLE | 876562306a36Sopenharmony_ci FMT_RGB_RANDOM_ENABLE | 876662306a36Sopenharmony_ci FMT_SPATIAL_DITHER_EN | FMT_SPATIAL_DITHER_DEPTH(1)); 876762306a36Sopenharmony_ci else 876862306a36Sopenharmony_ci tmp |= (FMT_TRUNCATE_EN | FMT_TRUNCATE_DEPTH(1)); 876962306a36Sopenharmony_ci break; 877062306a36Sopenharmony_ci case 10: 877162306a36Sopenharmony_ci if (dither == RADEON_FMT_DITHER_ENABLE) 877262306a36Sopenharmony_ci /* XXX sort out optimal dither settings */ 877362306a36Sopenharmony_ci tmp |= (FMT_FRAME_RANDOM_ENABLE | FMT_HIGHPASS_RANDOM_ENABLE | 877462306a36Sopenharmony_ci FMT_RGB_RANDOM_ENABLE | 877562306a36Sopenharmony_ci FMT_SPATIAL_DITHER_EN | FMT_SPATIAL_DITHER_DEPTH(2)); 877662306a36Sopenharmony_ci else 877762306a36Sopenharmony_ci tmp |= (FMT_TRUNCATE_EN | FMT_TRUNCATE_DEPTH(2)); 877862306a36Sopenharmony_ci break; 877962306a36Sopenharmony_ci default: 878062306a36Sopenharmony_ci /* not needed */ 878162306a36Sopenharmony_ci break; 878262306a36Sopenharmony_ci } 878362306a36Sopenharmony_ci 878462306a36Sopenharmony_ci WREG32(FMT_BIT_DEPTH_CONTROL + radeon_crtc->crtc_offset, tmp); 878562306a36Sopenharmony_ci} 878662306a36Sopenharmony_ci 878762306a36Sopenharmony_ci/* display watermark setup */ 878862306a36Sopenharmony_ci/** 878962306a36Sopenharmony_ci * dce8_line_buffer_adjust - Set up the line buffer 879062306a36Sopenharmony_ci * 879162306a36Sopenharmony_ci * @rdev: radeon_device pointer 879262306a36Sopenharmony_ci * @radeon_crtc: the selected display controller 879362306a36Sopenharmony_ci * @mode: the current display mode on the selected display 879462306a36Sopenharmony_ci * controller 879562306a36Sopenharmony_ci * 879662306a36Sopenharmony_ci * Setup up the line buffer allocation for 879762306a36Sopenharmony_ci * the selected display controller (CIK). 879862306a36Sopenharmony_ci * Returns the line buffer size in pixels. 879962306a36Sopenharmony_ci */ 880062306a36Sopenharmony_cistatic u32 dce8_line_buffer_adjust(struct radeon_device *rdev, 880162306a36Sopenharmony_ci struct radeon_crtc *radeon_crtc, 880262306a36Sopenharmony_ci struct drm_display_mode *mode) 880362306a36Sopenharmony_ci{ 880462306a36Sopenharmony_ci u32 tmp, buffer_alloc, i; 880562306a36Sopenharmony_ci u32 pipe_offset = radeon_crtc->crtc_id * 0x20; 880662306a36Sopenharmony_ci /* 880762306a36Sopenharmony_ci * Line Buffer Setup 880862306a36Sopenharmony_ci * There are 6 line buffers, one for each display controllers. 880962306a36Sopenharmony_ci * There are 3 partitions per LB. Select the number of partitions 881062306a36Sopenharmony_ci * to enable based on the display width. For display widths larger 881162306a36Sopenharmony_ci * than 4096, you need use to use 2 display controllers and combine 881262306a36Sopenharmony_ci * them using the stereo blender. 881362306a36Sopenharmony_ci */ 881462306a36Sopenharmony_ci if (radeon_crtc->base.enabled && mode) { 881562306a36Sopenharmony_ci if (mode->crtc_hdisplay < 1920) { 881662306a36Sopenharmony_ci tmp = 1; 881762306a36Sopenharmony_ci buffer_alloc = 2; 881862306a36Sopenharmony_ci } else if (mode->crtc_hdisplay < 2560) { 881962306a36Sopenharmony_ci tmp = 2; 882062306a36Sopenharmony_ci buffer_alloc = 2; 882162306a36Sopenharmony_ci } else if (mode->crtc_hdisplay < 4096) { 882262306a36Sopenharmony_ci tmp = 0; 882362306a36Sopenharmony_ci buffer_alloc = (rdev->flags & RADEON_IS_IGP) ? 2 : 4; 882462306a36Sopenharmony_ci } else { 882562306a36Sopenharmony_ci DRM_DEBUG_KMS("Mode too big for LB!\n"); 882662306a36Sopenharmony_ci tmp = 0; 882762306a36Sopenharmony_ci buffer_alloc = (rdev->flags & RADEON_IS_IGP) ? 2 : 4; 882862306a36Sopenharmony_ci } 882962306a36Sopenharmony_ci } else { 883062306a36Sopenharmony_ci tmp = 1; 883162306a36Sopenharmony_ci buffer_alloc = 0; 883262306a36Sopenharmony_ci } 883362306a36Sopenharmony_ci 883462306a36Sopenharmony_ci WREG32(LB_MEMORY_CTRL + radeon_crtc->crtc_offset, 883562306a36Sopenharmony_ci LB_MEMORY_CONFIG(tmp) | LB_MEMORY_SIZE(0x6B0)); 883662306a36Sopenharmony_ci 883762306a36Sopenharmony_ci WREG32(PIPE0_DMIF_BUFFER_CONTROL + pipe_offset, 883862306a36Sopenharmony_ci DMIF_BUFFERS_ALLOCATED(buffer_alloc)); 883962306a36Sopenharmony_ci for (i = 0; i < rdev->usec_timeout; i++) { 884062306a36Sopenharmony_ci if (RREG32(PIPE0_DMIF_BUFFER_CONTROL + pipe_offset) & 884162306a36Sopenharmony_ci DMIF_BUFFERS_ALLOCATED_COMPLETED) 884262306a36Sopenharmony_ci break; 884362306a36Sopenharmony_ci udelay(1); 884462306a36Sopenharmony_ci } 884562306a36Sopenharmony_ci 884662306a36Sopenharmony_ci if (radeon_crtc->base.enabled && mode) { 884762306a36Sopenharmony_ci switch (tmp) { 884862306a36Sopenharmony_ci case 0: 884962306a36Sopenharmony_ci default: 885062306a36Sopenharmony_ci return 4096 * 2; 885162306a36Sopenharmony_ci case 1: 885262306a36Sopenharmony_ci return 1920 * 2; 885362306a36Sopenharmony_ci case 2: 885462306a36Sopenharmony_ci return 2560 * 2; 885562306a36Sopenharmony_ci } 885662306a36Sopenharmony_ci } 885762306a36Sopenharmony_ci 885862306a36Sopenharmony_ci /* controller not enabled, so no lb used */ 885962306a36Sopenharmony_ci return 0; 886062306a36Sopenharmony_ci} 886162306a36Sopenharmony_ci 886262306a36Sopenharmony_ci/** 886362306a36Sopenharmony_ci * cik_get_number_of_dram_channels - get the number of dram channels 886462306a36Sopenharmony_ci * 886562306a36Sopenharmony_ci * @rdev: radeon_device pointer 886662306a36Sopenharmony_ci * 886762306a36Sopenharmony_ci * Look up the number of video ram channels (CIK). 886862306a36Sopenharmony_ci * Used for display watermark bandwidth calculations 886962306a36Sopenharmony_ci * Returns the number of dram channels 887062306a36Sopenharmony_ci */ 887162306a36Sopenharmony_cistatic u32 cik_get_number_of_dram_channels(struct radeon_device *rdev) 887262306a36Sopenharmony_ci{ 887362306a36Sopenharmony_ci u32 tmp = RREG32(MC_SHARED_CHMAP); 887462306a36Sopenharmony_ci 887562306a36Sopenharmony_ci switch ((tmp & NOOFCHAN_MASK) >> NOOFCHAN_SHIFT) { 887662306a36Sopenharmony_ci case 0: 887762306a36Sopenharmony_ci default: 887862306a36Sopenharmony_ci return 1; 887962306a36Sopenharmony_ci case 1: 888062306a36Sopenharmony_ci return 2; 888162306a36Sopenharmony_ci case 2: 888262306a36Sopenharmony_ci return 4; 888362306a36Sopenharmony_ci case 3: 888462306a36Sopenharmony_ci return 8; 888562306a36Sopenharmony_ci case 4: 888662306a36Sopenharmony_ci return 3; 888762306a36Sopenharmony_ci case 5: 888862306a36Sopenharmony_ci return 6; 888962306a36Sopenharmony_ci case 6: 889062306a36Sopenharmony_ci return 10; 889162306a36Sopenharmony_ci case 7: 889262306a36Sopenharmony_ci return 12; 889362306a36Sopenharmony_ci case 8: 889462306a36Sopenharmony_ci return 16; 889562306a36Sopenharmony_ci } 889662306a36Sopenharmony_ci} 889762306a36Sopenharmony_ci 889862306a36Sopenharmony_cistruct dce8_wm_params { 889962306a36Sopenharmony_ci u32 dram_channels; /* number of dram channels */ 890062306a36Sopenharmony_ci u32 yclk; /* bandwidth per dram data pin in kHz */ 890162306a36Sopenharmony_ci u32 sclk; /* engine clock in kHz */ 890262306a36Sopenharmony_ci u32 disp_clk; /* display clock in kHz */ 890362306a36Sopenharmony_ci u32 src_width; /* viewport width */ 890462306a36Sopenharmony_ci u32 active_time; /* active display time in ns */ 890562306a36Sopenharmony_ci u32 blank_time; /* blank time in ns */ 890662306a36Sopenharmony_ci bool interlaced; /* mode is interlaced */ 890762306a36Sopenharmony_ci fixed20_12 vsc; /* vertical scale ratio */ 890862306a36Sopenharmony_ci u32 num_heads; /* number of active crtcs */ 890962306a36Sopenharmony_ci u32 bytes_per_pixel; /* bytes per pixel display + overlay */ 891062306a36Sopenharmony_ci u32 lb_size; /* line buffer allocated to pipe */ 891162306a36Sopenharmony_ci u32 vtaps; /* vertical scaler taps */ 891262306a36Sopenharmony_ci}; 891362306a36Sopenharmony_ci 891462306a36Sopenharmony_ci/** 891562306a36Sopenharmony_ci * dce8_dram_bandwidth - get the dram bandwidth 891662306a36Sopenharmony_ci * 891762306a36Sopenharmony_ci * @wm: watermark calculation data 891862306a36Sopenharmony_ci * 891962306a36Sopenharmony_ci * Calculate the raw dram bandwidth (CIK). 892062306a36Sopenharmony_ci * Used for display watermark bandwidth calculations 892162306a36Sopenharmony_ci * Returns the dram bandwidth in MBytes/s 892262306a36Sopenharmony_ci */ 892362306a36Sopenharmony_cistatic u32 dce8_dram_bandwidth(struct dce8_wm_params *wm) 892462306a36Sopenharmony_ci{ 892562306a36Sopenharmony_ci /* Calculate raw DRAM Bandwidth */ 892662306a36Sopenharmony_ci fixed20_12 dram_efficiency; /* 0.7 */ 892762306a36Sopenharmony_ci fixed20_12 yclk, dram_channels, bandwidth; 892862306a36Sopenharmony_ci fixed20_12 a; 892962306a36Sopenharmony_ci 893062306a36Sopenharmony_ci a.full = dfixed_const(1000); 893162306a36Sopenharmony_ci yclk.full = dfixed_const(wm->yclk); 893262306a36Sopenharmony_ci yclk.full = dfixed_div(yclk, a); 893362306a36Sopenharmony_ci dram_channels.full = dfixed_const(wm->dram_channels * 4); 893462306a36Sopenharmony_ci a.full = dfixed_const(10); 893562306a36Sopenharmony_ci dram_efficiency.full = dfixed_const(7); 893662306a36Sopenharmony_ci dram_efficiency.full = dfixed_div(dram_efficiency, a); 893762306a36Sopenharmony_ci bandwidth.full = dfixed_mul(dram_channels, yclk); 893862306a36Sopenharmony_ci bandwidth.full = dfixed_mul(bandwidth, dram_efficiency); 893962306a36Sopenharmony_ci 894062306a36Sopenharmony_ci return dfixed_trunc(bandwidth); 894162306a36Sopenharmony_ci} 894262306a36Sopenharmony_ci 894362306a36Sopenharmony_ci/** 894462306a36Sopenharmony_ci * dce8_dram_bandwidth_for_display - get the dram bandwidth for display 894562306a36Sopenharmony_ci * 894662306a36Sopenharmony_ci * @wm: watermark calculation data 894762306a36Sopenharmony_ci * 894862306a36Sopenharmony_ci * Calculate the dram bandwidth used for display (CIK). 894962306a36Sopenharmony_ci * Used for display watermark bandwidth calculations 895062306a36Sopenharmony_ci * Returns the dram bandwidth for display in MBytes/s 895162306a36Sopenharmony_ci */ 895262306a36Sopenharmony_cistatic u32 dce8_dram_bandwidth_for_display(struct dce8_wm_params *wm) 895362306a36Sopenharmony_ci{ 895462306a36Sopenharmony_ci /* Calculate DRAM Bandwidth and the part allocated to display. */ 895562306a36Sopenharmony_ci fixed20_12 disp_dram_allocation; /* 0.3 to 0.7 */ 895662306a36Sopenharmony_ci fixed20_12 yclk, dram_channels, bandwidth; 895762306a36Sopenharmony_ci fixed20_12 a; 895862306a36Sopenharmony_ci 895962306a36Sopenharmony_ci a.full = dfixed_const(1000); 896062306a36Sopenharmony_ci yclk.full = dfixed_const(wm->yclk); 896162306a36Sopenharmony_ci yclk.full = dfixed_div(yclk, a); 896262306a36Sopenharmony_ci dram_channels.full = dfixed_const(wm->dram_channels * 4); 896362306a36Sopenharmony_ci a.full = dfixed_const(10); 896462306a36Sopenharmony_ci disp_dram_allocation.full = dfixed_const(3); /* XXX worse case value 0.3 */ 896562306a36Sopenharmony_ci disp_dram_allocation.full = dfixed_div(disp_dram_allocation, a); 896662306a36Sopenharmony_ci bandwidth.full = dfixed_mul(dram_channels, yclk); 896762306a36Sopenharmony_ci bandwidth.full = dfixed_mul(bandwidth, disp_dram_allocation); 896862306a36Sopenharmony_ci 896962306a36Sopenharmony_ci return dfixed_trunc(bandwidth); 897062306a36Sopenharmony_ci} 897162306a36Sopenharmony_ci 897262306a36Sopenharmony_ci/** 897362306a36Sopenharmony_ci * dce8_data_return_bandwidth - get the data return bandwidth 897462306a36Sopenharmony_ci * 897562306a36Sopenharmony_ci * @wm: watermark calculation data 897662306a36Sopenharmony_ci * 897762306a36Sopenharmony_ci * Calculate the data return bandwidth used for display (CIK). 897862306a36Sopenharmony_ci * Used for display watermark bandwidth calculations 897962306a36Sopenharmony_ci * Returns the data return bandwidth in MBytes/s 898062306a36Sopenharmony_ci */ 898162306a36Sopenharmony_cistatic u32 dce8_data_return_bandwidth(struct dce8_wm_params *wm) 898262306a36Sopenharmony_ci{ 898362306a36Sopenharmony_ci /* Calculate the display Data return Bandwidth */ 898462306a36Sopenharmony_ci fixed20_12 return_efficiency; /* 0.8 */ 898562306a36Sopenharmony_ci fixed20_12 sclk, bandwidth; 898662306a36Sopenharmony_ci fixed20_12 a; 898762306a36Sopenharmony_ci 898862306a36Sopenharmony_ci a.full = dfixed_const(1000); 898962306a36Sopenharmony_ci sclk.full = dfixed_const(wm->sclk); 899062306a36Sopenharmony_ci sclk.full = dfixed_div(sclk, a); 899162306a36Sopenharmony_ci a.full = dfixed_const(10); 899262306a36Sopenharmony_ci return_efficiency.full = dfixed_const(8); 899362306a36Sopenharmony_ci return_efficiency.full = dfixed_div(return_efficiency, a); 899462306a36Sopenharmony_ci a.full = dfixed_const(32); 899562306a36Sopenharmony_ci bandwidth.full = dfixed_mul(a, sclk); 899662306a36Sopenharmony_ci bandwidth.full = dfixed_mul(bandwidth, return_efficiency); 899762306a36Sopenharmony_ci 899862306a36Sopenharmony_ci return dfixed_trunc(bandwidth); 899962306a36Sopenharmony_ci} 900062306a36Sopenharmony_ci 900162306a36Sopenharmony_ci/** 900262306a36Sopenharmony_ci * dce8_dmif_request_bandwidth - get the dmif bandwidth 900362306a36Sopenharmony_ci * 900462306a36Sopenharmony_ci * @wm: watermark calculation data 900562306a36Sopenharmony_ci * 900662306a36Sopenharmony_ci * Calculate the dmif bandwidth used for display (CIK). 900762306a36Sopenharmony_ci * Used for display watermark bandwidth calculations 900862306a36Sopenharmony_ci * Returns the dmif bandwidth in MBytes/s 900962306a36Sopenharmony_ci */ 901062306a36Sopenharmony_cistatic u32 dce8_dmif_request_bandwidth(struct dce8_wm_params *wm) 901162306a36Sopenharmony_ci{ 901262306a36Sopenharmony_ci /* Calculate the DMIF Request Bandwidth */ 901362306a36Sopenharmony_ci fixed20_12 disp_clk_request_efficiency; /* 0.8 */ 901462306a36Sopenharmony_ci fixed20_12 disp_clk, bandwidth; 901562306a36Sopenharmony_ci fixed20_12 a, b; 901662306a36Sopenharmony_ci 901762306a36Sopenharmony_ci a.full = dfixed_const(1000); 901862306a36Sopenharmony_ci disp_clk.full = dfixed_const(wm->disp_clk); 901962306a36Sopenharmony_ci disp_clk.full = dfixed_div(disp_clk, a); 902062306a36Sopenharmony_ci a.full = dfixed_const(32); 902162306a36Sopenharmony_ci b.full = dfixed_mul(a, disp_clk); 902262306a36Sopenharmony_ci 902362306a36Sopenharmony_ci a.full = dfixed_const(10); 902462306a36Sopenharmony_ci disp_clk_request_efficiency.full = dfixed_const(8); 902562306a36Sopenharmony_ci disp_clk_request_efficiency.full = dfixed_div(disp_clk_request_efficiency, a); 902662306a36Sopenharmony_ci 902762306a36Sopenharmony_ci bandwidth.full = dfixed_mul(b, disp_clk_request_efficiency); 902862306a36Sopenharmony_ci 902962306a36Sopenharmony_ci return dfixed_trunc(bandwidth); 903062306a36Sopenharmony_ci} 903162306a36Sopenharmony_ci 903262306a36Sopenharmony_ci/** 903362306a36Sopenharmony_ci * dce8_available_bandwidth - get the min available bandwidth 903462306a36Sopenharmony_ci * 903562306a36Sopenharmony_ci * @wm: watermark calculation data 903662306a36Sopenharmony_ci * 903762306a36Sopenharmony_ci * Calculate the min available bandwidth used for display (CIK). 903862306a36Sopenharmony_ci * Used for display watermark bandwidth calculations 903962306a36Sopenharmony_ci * Returns the min available bandwidth in MBytes/s 904062306a36Sopenharmony_ci */ 904162306a36Sopenharmony_cistatic u32 dce8_available_bandwidth(struct dce8_wm_params *wm) 904262306a36Sopenharmony_ci{ 904362306a36Sopenharmony_ci /* Calculate the Available bandwidth. Display can use this temporarily but not in average. */ 904462306a36Sopenharmony_ci u32 dram_bandwidth = dce8_dram_bandwidth(wm); 904562306a36Sopenharmony_ci u32 data_return_bandwidth = dce8_data_return_bandwidth(wm); 904662306a36Sopenharmony_ci u32 dmif_req_bandwidth = dce8_dmif_request_bandwidth(wm); 904762306a36Sopenharmony_ci 904862306a36Sopenharmony_ci return min(dram_bandwidth, min(data_return_bandwidth, dmif_req_bandwidth)); 904962306a36Sopenharmony_ci} 905062306a36Sopenharmony_ci 905162306a36Sopenharmony_ci/** 905262306a36Sopenharmony_ci * dce8_average_bandwidth - get the average available bandwidth 905362306a36Sopenharmony_ci * 905462306a36Sopenharmony_ci * @wm: watermark calculation data 905562306a36Sopenharmony_ci * 905662306a36Sopenharmony_ci * Calculate the average available bandwidth used for display (CIK). 905762306a36Sopenharmony_ci * Used for display watermark bandwidth calculations 905862306a36Sopenharmony_ci * Returns the average available bandwidth in MBytes/s 905962306a36Sopenharmony_ci */ 906062306a36Sopenharmony_cistatic u32 dce8_average_bandwidth(struct dce8_wm_params *wm) 906162306a36Sopenharmony_ci{ 906262306a36Sopenharmony_ci /* Calculate the display mode Average Bandwidth 906362306a36Sopenharmony_ci * DisplayMode should contain the source and destination dimensions, 906462306a36Sopenharmony_ci * timing, etc. 906562306a36Sopenharmony_ci */ 906662306a36Sopenharmony_ci fixed20_12 bpp; 906762306a36Sopenharmony_ci fixed20_12 line_time; 906862306a36Sopenharmony_ci fixed20_12 src_width; 906962306a36Sopenharmony_ci fixed20_12 bandwidth; 907062306a36Sopenharmony_ci fixed20_12 a; 907162306a36Sopenharmony_ci 907262306a36Sopenharmony_ci a.full = dfixed_const(1000); 907362306a36Sopenharmony_ci line_time.full = dfixed_const(wm->active_time + wm->blank_time); 907462306a36Sopenharmony_ci line_time.full = dfixed_div(line_time, a); 907562306a36Sopenharmony_ci bpp.full = dfixed_const(wm->bytes_per_pixel); 907662306a36Sopenharmony_ci src_width.full = dfixed_const(wm->src_width); 907762306a36Sopenharmony_ci bandwidth.full = dfixed_mul(src_width, bpp); 907862306a36Sopenharmony_ci bandwidth.full = dfixed_mul(bandwidth, wm->vsc); 907962306a36Sopenharmony_ci bandwidth.full = dfixed_div(bandwidth, line_time); 908062306a36Sopenharmony_ci 908162306a36Sopenharmony_ci return dfixed_trunc(bandwidth); 908262306a36Sopenharmony_ci} 908362306a36Sopenharmony_ci 908462306a36Sopenharmony_ci/** 908562306a36Sopenharmony_ci * dce8_latency_watermark - get the latency watermark 908662306a36Sopenharmony_ci * 908762306a36Sopenharmony_ci * @wm: watermark calculation data 908862306a36Sopenharmony_ci * 908962306a36Sopenharmony_ci * Calculate the latency watermark (CIK). 909062306a36Sopenharmony_ci * Used for display watermark bandwidth calculations 909162306a36Sopenharmony_ci * Returns the latency watermark in ns 909262306a36Sopenharmony_ci */ 909362306a36Sopenharmony_cistatic u32 dce8_latency_watermark(struct dce8_wm_params *wm) 909462306a36Sopenharmony_ci{ 909562306a36Sopenharmony_ci /* First calculate the latency in ns */ 909662306a36Sopenharmony_ci u32 mc_latency = 2000; /* 2000 ns. */ 909762306a36Sopenharmony_ci u32 available_bandwidth = dce8_available_bandwidth(wm); 909862306a36Sopenharmony_ci u32 worst_chunk_return_time = (512 * 8 * 1000) / available_bandwidth; 909962306a36Sopenharmony_ci u32 cursor_line_pair_return_time = (128 * 4 * 1000) / available_bandwidth; 910062306a36Sopenharmony_ci u32 dc_latency = 40000000 / wm->disp_clk; /* dc pipe latency */ 910162306a36Sopenharmony_ci u32 other_heads_data_return_time = ((wm->num_heads + 1) * worst_chunk_return_time) + 910262306a36Sopenharmony_ci (wm->num_heads * cursor_line_pair_return_time); 910362306a36Sopenharmony_ci u32 latency = mc_latency + other_heads_data_return_time + dc_latency; 910462306a36Sopenharmony_ci u32 max_src_lines_per_dst_line, lb_fill_bw, line_fill_time; 910562306a36Sopenharmony_ci u32 tmp, dmif_size = 12288; 910662306a36Sopenharmony_ci fixed20_12 a, b, c; 910762306a36Sopenharmony_ci 910862306a36Sopenharmony_ci if (wm->num_heads == 0) 910962306a36Sopenharmony_ci return 0; 911062306a36Sopenharmony_ci 911162306a36Sopenharmony_ci a.full = dfixed_const(2); 911262306a36Sopenharmony_ci b.full = dfixed_const(1); 911362306a36Sopenharmony_ci if ((wm->vsc.full > a.full) || 911462306a36Sopenharmony_ci ((wm->vsc.full > b.full) && (wm->vtaps >= 3)) || 911562306a36Sopenharmony_ci (wm->vtaps >= 5) || 911662306a36Sopenharmony_ci ((wm->vsc.full >= a.full) && wm->interlaced)) 911762306a36Sopenharmony_ci max_src_lines_per_dst_line = 4; 911862306a36Sopenharmony_ci else 911962306a36Sopenharmony_ci max_src_lines_per_dst_line = 2; 912062306a36Sopenharmony_ci 912162306a36Sopenharmony_ci a.full = dfixed_const(available_bandwidth); 912262306a36Sopenharmony_ci b.full = dfixed_const(wm->num_heads); 912362306a36Sopenharmony_ci a.full = dfixed_div(a, b); 912462306a36Sopenharmony_ci tmp = div_u64((u64) dmif_size * (u64) wm->disp_clk, mc_latency + 512); 912562306a36Sopenharmony_ci tmp = min(dfixed_trunc(a), tmp); 912662306a36Sopenharmony_ci 912762306a36Sopenharmony_ci lb_fill_bw = min(tmp, wm->disp_clk * wm->bytes_per_pixel / 1000); 912862306a36Sopenharmony_ci 912962306a36Sopenharmony_ci a.full = dfixed_const(max_src_lines_per_dst_line * wm->src_width * wm->bytes_per_pixel); 913062306a36Sopenharmony_ci b.full = dfixed_const(1000); 913162306a36Sopenharmony_ci c.full = dfixed_const(lb_fill_bw); 913262306a36Sopenharmony_ci b.full = dfixed_div(c, b); 913362306a36Sopenharmony_ci a.full = dfixed_div(a, b); 913462306a36Sopenharmony_ci line_fill_time = dfixed_trunc(a); 913562306a36Sopenharmony_ci 913662306a36Sopenharmony_ci if (line_fill_time < wm->active_time) 913762306a36Sopenharmony_ci return latency; 913862306a36Sopenharmony_ci else 913962306a36Sopenharmony_ci return latency + (line_fill_time - wm->active_time); 914062306a36Sopenharmony_ci 914162306a36Sopenharmony_ci} 914262306a36Sopenharmony_ci 914362306a36Sopenharmony_ci/** 914462306a36Sopenharmony_ci * dce8_average_bandwidth_vs_dram_bandwidth_for_display - check 914562306a36Sopenharmony_ci * average and available dram bandwidth 914662306a36Sopenharmony_ci * 914762306a36Sopenharmony_ci * @wm: watermark calculation data 914862306a36Sopenharmony_ci * 914962306a36Sopenharmony_ci * Check if the display average bandwidth fits in the display 915062306a36Sopenharmony_ci * dram bandwidth (CIK). 915162306a36Sopenharmony_ci * Used for display watermark bandwidth calculations 915262306a36Sopenharmony_ci * Returns true if the display fits, false if not. 915362306a36Sopenharmony_ci */ 915462306a36Sopenharmony_cistatic bool dce8_average_bandwidth_vs_dram_bandwidth_for_display(struct dce8_wm_params *wm) 915562306a36Sopenharmony_ci{ 915662306a36Sopenharmony_ci if (dce8_average_bandwidth(wm) <= 915762306a36Sopenharmony_ci (dce8_dram_bandwidth_for_display(wm) / wm->num_heads)) 915862306a36Sopenharmony_ci return true; 915962306a36Sopenharmony_ci else 916062306a36Sopenharmony_ci return false; 916162306a36Sopenharmony_ci} 916262306a36Sopenharmony_ci 916362306a36Sopenharmony_ci/** 916462306a36Sopenharmony_ci * dce8_average_bandwidth_vs_available_bandwidth - check 916562306a36Sopenharmony_ci * average and available bandwidth 916662306a36Sopenharmony_ci * 916762306a36Sopenharmony_ci * @wm: watermark calculation data 916862306a36Sopenharmony_ci * 916962306a36Sopenharmony_ci * Check if the display average bandwidth fits in the display 917062306a36Sopenharmony_ci * available bandwidth (CIK). 917162306a36Sopenharmony_ci * Used for display watermark bandwidth calculations 917262306a36Sopenharmony_ci * Returns true if the display fits, false if not. 917362306a36Sopenharmony_ci */ 917462306a36Sopenharmony_cistatic bool dce8_average_bandwidth_vs_available_bandwidth(struct dce8_wm_params *wm) 917562306a36Sopenharmony_ci{ 917662306a36Sopenharmony_ci if (dce8_average_bandwidth(wm) <= 917762306a36Sopenharmony_ci (dce8_available_bandwidth(wm) / wm->num_heads)) 917862306a36Sopenharmony_ci return true; 917962306a36Sopenharmony_ci else 918062306a36Sopenharmony_ci return false; 918162306a36Sopenharmony_ci} 918262306a36Sopenharmony_ci 918362306a36Sopenharmony_ci/** 918462306a36Sopenharmony_ci * dce8_check_latency_hiding - check latency hiding 918562306a36Sopenharmony_ci * 918662306a36Sopenharmony_ci * @wm: watermark calculation data 918762306a36Sopenharmony_ci * 918862306a36Sopenharmony_ci * Check latency hiding (CIK). 918962306a36Sopenharmony_ci * Used for display watermark bandwidth calculations 919062306a36Sopenharmony_ci * Returns true if the display fits, false if not. 919162306a36Sopenharmony_ci */ 919262306a36Sopenharmony_cistatic bool dce8_check_latency_hiding(struct dce8_wm_params *wm) 919362306a36Sopenharmony_ci{ 919462306a36Sopenharmony_ci u32 lb_partitions = wm->lb_size / wm->src_width; 919562306a36Sopenharmony_ci u32 line_time = wm->active_time + wm->blank_time; 919662306a36Sopenharmony_ci u32 latency_tolerant_lines; 919762306a36Sopenharmony_ci u32 latency_hiding; 919862306a36Sopenharmony_ci fixed20_12 a; 919962306a36Sopenharmony_ci 920062306a36Sopenharmony_ci a.full = dfixed_const(1); 920162306a36Sopenharmony_ci if (wm->vsc.full > a.full) 920262306a36Sopenharmony_ci latency_tolerant_lines = 1; 920362306a36Sopenharmony_ci else { 920462306a36Sopenharmony_ci if (lb_partitions <= (wm->vtaps + 1)) 920562306a36Sopenharmony_ci latency_tolerant_lines = 1; 920662306a36Sopenharmony_ci else 920762306a36Sopenharmony_ci latency_tolerant_lines = 2; 920862306a36Sopenharmony_ci } 920962306a36Sopenharmony_ci 921062306a36Sopenharmony_ci latency_hiding = (latency_tolerant_lines * line_time + wm->blank_time); 921162306a36Sopenharmony_ci 921262306a36Sopenharmony_ci if (dce8_latency_watermark(wm) <= latency_hiding) 921362306a36Sopenharmony_ci return true; 921462306a36Sopenharmony_ci else 921562306a36Sopenharmony_ci return false; 921662306a36Sopenharmony_ci} 921762306a36Sopenharmony_ci 921862306a36Sopenharmony_ci/** 921962306a36Sopenharmony_ci * dce8_program_watermarks - program display watermarks 922062306a36Sopenharmony_ci * 922162306a36Sopenharmony_ci * @rdev: radeon_device pointer 922262306a36Sopenharmony_ci * @radeon_crtc: the selected display controller 922362306a36Sopenharmony_ci * @lb_size: line buffer size 922462306a36Sopenharmony_ci * @num_heads: number of display controllers in use 922562306a36Sopenharmony_ci * 922662306a36Sopenharmony_ci * Calculate and program the display watermarks for the 922762306a36Sopenharmony_ci * selected display controller (CIK). 922862306a36Sopenharmony_ci */ 922962306a36Sopenharmony_cistatic void dce8_program_watermarks(struct radeon_device *rdev, 923062306a36Sopenharmony_ci struct radeon_crtc *radeon_crtc, 923162306a36Sopenharmony_ci u32 lb_size, u32 num_heads) 923262306a36Sopenharmony_ci{ 923362306a36Sopenharmony_ci struct drm_display_mode *mode = &radeon_crtc->base.mode; 923462306a36Sopenharmony_ci struct dce8_wm_params wm_low, wm_high; 923562306a36Sopenharmony_ci u32 active_time; 923662306a36Sopenharmony_ci u32 line_time = 0; 923762306a36Sopenharmony_ci u32 latency_watermark_a = 0, latency_watermark_b = 0; 923862306a36Sopenharmony_ci u32 tmp, wm_mask; 923962306a36Sopenharmony_ci 924062306a36Sopenharmony_ci if (radeon_crtc->base.enabled && num_heads && mode) { 924162306a36Sopenharmony_ci active_time = (u32) div_u64((u64)mode->crtc_hdisplay * 1000000, 924262306a36Sopenharmony_ci (u32)mode->clock); 924362306a36Sopenharmony_ci line_time = (u32) div_u64((u64)mode->crtc_htotal * 1000000, 924462306a36Sopenharmony_ci (u32)mode->clock); 924562306a36Sopenharmony_ci line_time = min(line_time, (u32)65535); 924662306a36Sopenharmony_ci 924762306a36Sopenharmony_ci /* watermark for high clocks */ 924862306a36Sopenharmony_ci if ((rdev->pm.pm_method == PM_METHOD_DPM) && 924962306a36Sopenharmony_ci rdev->pm.dpm_enabled) { 925062306a36Sopenharmony_ci wm_high.yclk = 925162306a36Sopenharmony_ci radeon_dpm_get_mclk(rdev, false) * 10; 925262306a36Sopenharmony_ci wm_high.sclk = 925362306a36Sopenharmony_ci radeon_dpm_get_sclk(rdev, false) * 10; 925462306a36Sopenharmony_ci } else { 925562306a36Sopenharmony_ci wm_high.yclk = rdev->pm.current_mclk * 10; 925662306a36Sopenharmony_ci wm_high.sclk = rdev->pm.current_sclk * 10; 925762306a36Sopenharmony_ci } 925862306a36Sopenharmony_ci 925962306a36Sopenharmony_ci wm_high.disp_clk = mode->clock; 926062306a36Sopenharmony_ci wm_high.src_width = mode->crtc_hdisplay; 926162306a36Sopenharmony_ci wm_high.active_time = active_time; 926262306a36Sopenharmony_ci wm_high.blank_time = line_time - wm_high.active_time; 926362306a36Sopenharmony_ci wm_high.interlaced = false; 926462306a36Sopenharmony_ci if (mode->flags & DRM_MODE_FLAG_INTERLACE) 926562306a36Sopenharmony_ci wm_high.interlaced = true; 926662306a36Sopenharmony_ci wm_high.vsc = radeon_crtc->vsc; 926762306a36Sopenharmony_ci wm_high.vtaps = 1; 926862306a36Sopenharmony_ci if (radeon_crtc->rmx_type != RMX_OFF) 926962306a36Sopenharmony_ci wm_high.vtaps = 2; 927062306a36Sopenharmony_ci wm_high.bytes_per_pixel = 4; /* XXX: get this from fb config */ 927162306a36Sopenharmony_ci wm_high.lb_size = lb_size; 927262306a36Sopenharmony_ci wm_high.dram_channels = cik_get_number_of_dram_channels(rdev); 927362306a36Sopenharmony_ci wm_high.num_heads = num_heads; 927462306a36Sopenharmony_ci 927562306a36Sopenharmony_ci /* set for high clocks */ 927662306a36Sopenharmony_ci latency_watermark_a = min(dce8_latency_watermark(&wm_high), (u32)65535); 927762306a36Sopenharmony_ci 927862306a36Sopenharmony_ci /* possibly force display priority to high */ 927962306a36Sopenharmony_ci /* should really do this at mode validation time... */ 928062306a36Sopenharmony_ci if (!dce8_average_bandwidth_vs_dram_bandwidth_for_display(&wm_high) || 928162306a36Sopenharmony_ci !dce8_average_bandwidth_vs_available_bandwidth(&wm_high) || 928262306a36Sopenharmony_ci !dce8_check_latency_hiding(&wm_high) || 928362306a36Sopenharmony_ci (rdev->disp_priority == 2)) { 928462306a36Sopenharmony_ci DRM_DEBUG_KMS("force priority to high\n"); 928562306a36Sopenharmony_ci } 928662306a36Sopenharmony_ci 928762306a36Sopenharmony_ci /* watermark for low clocks */ 928862306a36Sopenharmony_ci if ((rdev->pm.pm_method == PM_METHOD_DPM) && 928962306a36Sopenharmony_ci rdev->pm.dpm_enabled) { 929062306a36Sopenharmony_ci wm_low.yclk = 929162306a36Sopenharmony_ci radeon_dpm_get_mclk(rdev, true) * 10; 929262306a36Sopenharmony_ci wm_low.sclk = 929362306a36Sopenharmony_ci radeon_dpm_get_sclk(rdev, true) * 10; 929462306a36Sopenharmony_ci } else { 929562306a36Sopenharmony_ci wm_low.yclk = rdev->pm.current_mclk * 10; 929662306a36Sopenharmony_ci wm_low.sclk = rdev->pm.current_sclk * 10; 929762306a36Sopenharmony_ci } 929862306a36Sopenharmony_ci 929962306a36Sopenharmony_ci wm_low.disp_clk = mode->clock; 930062306a36Sopenharmony_ci wm_low.src_width = mode->crtc_hdisplay; 930162306a36Sopenharmony_ci wm_low.active_time = active_time; 930262306a36Sopenharmony_ci wm_low.blank_time = line_time - wm_low.active_time; 930362306a36Sopenharmony_ci wm_low.interlaced = false; 930462306a36Sopenharmony_ci if (mode->flags & DRM_MODE_FLAG_INTERLACE) 930562306a36Sopenharmony_ci wm_low.interlaced = true; 930662306a36Sopenharmony_ci wm_low.vsc = radeon_crtc->vsc; 930762306a36Sopenharmony_ci wm_low.vtaps = 1; 930862306a36Sopenharmony_ci if (radeon_crtc->rmx_type != RMX_OFF) 930962306a36Sopenharmony_ci wm_low.vtaps = 2; 931062306a36Sopenharmony_ci wm_low.bytes_per_pixel = 4; /* XXX: get this from fb config */ 931162306a36Sopenharmony_ci wm_low.lb_size = lb_size; 931262306a36Sopenharmony_ci wm_low.dram_channels = cik_get_number_of_dram_channels(rdev); 931362306a36Sopenharmony_ci wm_low.num_heads = num_heads; 931462306a36Sopenharmony_ci 931562306a36Sopenharmony_ci /* set for low clocks */ 931662306a36Sopenharmony_ci latency_watermark_b = min(dce8_latency_watermark(&wm_low), (u32)65535); 931762306a36Sopenharmony_ci 931862306a36Sopenharmony_ci /* possibly force display priority to high */ 931962306a36Sopenharmony_ci /* should really do this at mode validation time... */ 932062306a36Sopenharmony_ci if (!dce8_average_bandwidth_vs_dram_bandwidth_for_display(&wm_low) || 932162306a36Sopenharmony_ci !dce8_average_bandwidth_vs_available_bandwidth(&wm_low) || 932262306a36Sopenharmony_ci !dce8_check_latency_hiding(&wm_low) || 932362306a36Sopenharmony_ci (rdev->disp_priority == 2)) { 932462306a36Sopenharmony_ci DRM_DEBUG_KMS("force priority to high\n"); 932562306a36Sopenharmony_ci } 932662306a36Sopenharmony_ci 932762306a36Sopenharmony_ci /* Save number of lines the linebuffer leads before the scanout */ 932862306a36Sopenharmony_ci radeon_crtc->lb_vblank_lead_lines = DIV_ROUND_UP(lb_size, mode->crtc_hdisplay); 932962306a36Sopenharmony_ci } 933062306a36Sopenharmony_ci 933162306a36Sopenharmony_ci /* select wm A */ 933262306a36Sopenharmony_ci wm_mask = RREG32(DPG_WATERMARK_MASK_CONTROL + radeon_crtc->crtc_offset); 933362306a36Sopenharmony_ci tmp = wm_mask; 933462306a36Sopenharmony_ci tmp &= ~LATENCY_WATERMARK_MASK(3); 933562306a36Sopenharmony_ci tmp |= LATENCY_WATERMARK_MASK(1); 933662306a36Sopenharmony_ci WREG32(DPG_WATERMARK_MASK_CONTROL + radeon_crtc->crtc_offset, tmp); 933762306a36Sopenharmony_ci WREG32(DPG_PIPE_LATENCY_CONTROL + radeon_crtc->crtc_offset, 933862306a36Sopenharmony_ci (LATENCY_LOW_WATERMARK(latency_watermark_a) | 933962306a36Sopenharmony_ci LATENCY_HIGH_WATERMARK(line_time))); 934062306a36Sopenharmony_ci /* select wm B */ 934162306a36Sopenharmony_ci tmp = RREG32(DPG_WATERMARK_MASK_CONTROL + radeon_crtc->crtc_offset); 934262306a36Sopenharmony_ci tmp &= ~LATENCY_WATERMARK_MASK(3); 934362306a36Sopenharmony_ci tmp |= LATENCY_WATERMARK_MASK(2); 934462306a36Sopenharmony_ci WREG32(DPG_WATERMARK_MASK_CONTROL + radeon_crtc->crtc_offset, tmp); 934562306a36Sopenharmony_ci WREG32(DPG_PIPE_LATENCY_CONTROL + radeon_crtc->crtc_offset, 934662306a36Sopenharmony_ci (LATENCY_LOW_WATERMARK(latency_watermark_b) | 934762306a36Sopenharmony_ci LATENCY_HIGH_WATERMARK(line_time))); 934862306a36Sopenharmony_ci /* restore original selection */ 934962306a36Sopenharmony_ci WREG32(DPG_WATERMARK_MASK_CONTROL + radeon_crtc->crtc_offset, wm_mask); 935062306a36Sopenharmony_ci 935162306a36Sopenharmony_ci /* save values for DPM */ 935262306a36Sopenharmony_ci radeon_crtc->line_time = line_time; 935362306a36Sopenharmony_ci radeon_crtc->wm_high = latency_watermark_a; 935462306a36Sopenharmony_ci radeon_crtc->wm_low = latency_watermark_b; 935562306a36Sopenharmony_ci} 935662306a36Sopenharmony_ci 935762306a36Sopenharmony_ci/** 935862306a36Sopenharmony_ci * dce8_bandwidth_update - program display watermarks 935962306a36Sopenharmony_ci * 936062306a36Sopenharmony_ci * @rdev: radeon_device pointer 936162306a36Sopenharmony_ci * 936262306a36Sopenharmony_ci * Calculate and program the display watermarks and line 936362306a36Sopenharmony_ci * buffer allocation (CIK). 936462306a36Sopenharmony_ci */ 936562306a36Sopenharmony_civoid dce8_bandwidth_update(struct radeon_device *rdev) 936662306a36Sopenharmony_ci{ 936762306a36Sopenharmony_ci struct drm_display_mode *mode = NULL; 936862306a36Sopenharmony_ci u32 num_heads = 0, lb_size; 936962306a36Sopenharmony_ci int i; 937062306a36Sopenharmony_ci 937162306a36Sopenharmony_ci if (!rdev->mode_info.mode_config_initialized) 937262306a36Sopenharmony_ci return; 937362306a36Sopenharmony_ci 937462306a36Sopenharmony_ci radeon_update_display_priority(rdev); 937562306a36Sopenharmony_ci 937662306a36Sopenharmony_ci for (i = 0; i < rdev->num_crtc; i++) { 937762306a36Sopenharmony_ci if (rdev->mode_info.crtcs[i]->base.enabled) 937862306a36Sopenharmony_ci num_heads++; 937962306a36Sopenharmony_ci } 938062306a36Sopenharmony_ci for (i = 0; i < rdev->num_crtc; i++) { 938162306a36Sopenharmony_ci mode = &rdev->mode_info.crtcs[i]->base.mode; 938262306a36Sopenharmony_ci lb_size = dce8_line_buffer_adjust(rdev, rdev->mode_info.crtcs[i], mode); 938362306a36Sopenharmony_ci dce8_program_watermarks(rdev, rdev->mode_info.crtcs[i], lb_size, num_heads); 938462306a36Sopenharmony_ci } 938562306a36Sopenharmony_ci} 938662306a36Sopenharmony_ci 938762306a36Sopenharmony_ci/** 938862306a36Sopenharmony_ci * cik_get_gpu_clock_counter - return GPU clock counter snapshot 938962306a36Sopenharmony_ci * 939062306a36Sopenharmony_ci * @rdev: radeon_device pointer 939162306a36Sopenharmony_ci * 939262306a36Sopenharmony_ci * Fetches a GPU clock counter snapshot (SI). 939362306a36Sopenharmony_ci * Returns the 64 bit clock counter snapshot. 939462306a36Sopenharmony_ci */ 939562306a36Sopenharmony_ciuint64_t cik_get_gpu_clock_counter(struct radeon_device *rdev) 939662306a36Sopenharmony_ci{ 939762306a36Sopenharmony_ci uint64_t clock; 939862306a36Sopenharmony_ci 939962306a36Sopenharmony_ci mutex_lock(&rdev->gpu_clock_mutex); 940062306a36Sopenharmony_ci WREG32(RLC_CAPTURE_GPU_CLOCK_COUNT, 1); 940162306a36Sopenharmony_ci clock = (uint64_t)RREG32(RLC_GPU_CLOCK_COUNT_LSB) | 940262306a36Sopenharmony_ci ((uint64_t)RREG32(RLC_GPU_CLOCK_COUNT_MSB) << 32ULL); 940362306a36Sopenharmony_ci mutex_unlock(&rdev->gpu_clock_mutex); 940462306a36Sopenharmony_ci return clock; 940562306a36Sopenharmony_ci} 940662306a36Sopenharmony_ci 940762306a36Sopenharmony_cistatic int cik_set_uvd_clock(struct radeon_device *rdev, u32 clock, 940862306a36Sopenharmony_ci u32 cntl_reg, u32 status_reg) 940962306a36Sopenharmony_ci{ 941062306a36Sopenharmony_ci int r, i; 941162306a36Sopenharmony_ci struct atom_clock_dividers dividers; 941262306a36Sopenharmony_ci uint32_t tmp; 941362306a36Sopenharmony_ci 941462306a36Sopenharmony_ci r = radeon_atom_get_clock_dividers(rdev, COMPUTE_GPUCLK_INPUT_FLAG_DEFAULT_GPUCLK, 941562306a36Sopenharmony_ci clock, false, ÷rs); 941662306a36Sopenharmony_ci if (r) 941762306a36Sopenharmony_ci return r; 941862306a36Sopenharmony_ci 941962306a36Sopenharmony_ci tmp = RREG32_SMC(cntl_reg); 942062306a36Sopenharmony_ci tmp &= ~(DCLK_DIR_CNTL_EN|DCLK_DIVIDER_MASK); 942162306a36Sopenharmony_ci tmp |= dividers.post_divider; 942262306a36Sopenharmony_ci WREG32_SMC(cntl_reg, tmp); 942362306a36Sopenharmony_ci 942462306a36Sopenharmony_ci for (i = 0; i < 100; i++) { 942562306a36Sopenharmony_ci if (RREG32_SMC(status_reg) & DCLK_STATUS) 942662306a36Sopenharmony_ci break; 942762306a36Sopenharmony_ci mdelay(10); 942862306a36Sopenharmony_ci } 942962306a36Sopenharmony_ci if (i == 100) 943062306a36Sopenharmony_ci return -ETIMEDOUT; 943162306a36Sopenharmony_ci 943262306a36Sopenharmony_ci return 0; 943362306a36Sopenharmony_ci} 943462306a36Sopenharmony_ci 943562306a36Sopenharmony_ciint cik_set_uvd_clocks(struct radeon_device *rdev, u32 vclk, u32 dclk) 943662306a36Sopenharmony_ci{ 943762306a36Sopenharmony_ci int r = 0; 943862306a36Sopenharmony_ci 943962306a36Sopenharmony_ci r = cik_set_uvd_clock(rdev, vclk, CG_VCLK_CNTL, CG_VCLK_STATUS); 944062306a36Sopenharmony_ci if (r) 944162306a36Sopenharmony_ci return r; 944262306a36Sopenharmony_ci 944362306a36Sopenharmony_ci r = cik_set_uvd_clock(rdev, dclk, CG_DCLK_CNTL, CG_DCLK_STATUS); 944462306a36Sopenharmony_ci return r; 944562306a36Sopenharmony_ci} 944662306a36Sopenharmony_ci 944762306a36Sopenharmony_ciint cik_set_vce_clocks(struct radeon_device *rdev, u32 evclk, u32 ecclk) 944862306a36Sopenharmony_ci{ 944962306a36Sopenharmony_ci int r, i; 945062306a36Sopenharmony_ci struct atom_clock_dividers dividers; 945162306a36Sopenharmony_ci u32 tmp; 945262306a36Sopenharmony_ci 945362306a36Sopenharmony_ci r = radeon_atom_get_clock_dividers(rdev, COMPUTE_GPUCLK_INPUT_FLAG_DEFAULT_GPUCLK, 945462306a36Sopenharmony_ci ecclk, false, ÷rs); 945562306a36Sopenharmony_ci if (r) 945662306a36Sopenharmony_ci return r; 945762306a36Sopenharmony_ci 945862306a36Sopenharmony_ci for (i = 0; i < 100; i++) { 945962306a36Sopenharmony_ci if (RREG32_SMC(CG_ECLK_STATUS) & ECLK_STATUS) 946062306a36Sopenharmony_ci break; 946162306a36Sopenharmony_ci mdelay(10); 946262306a36Sopenharmony_ci } 946362306a36Sopenharmony_ci if (i == 100) 946462306a36Sopenharmony_ci return -ETIMEDOUT; 946562306a36Sopenharmony_ci 946662306a36Sopenharmony_ci tmp = RREG32_SMC(CG_ECLK_CNTL); 946762306a36Sopenharmony_ci tmp &= ~(ECLK_DIR_CNTL_EN|ECLK_DIVIDER_MASK); 946862306a36Sopenharmony_ci tmp |= dividers.post_divider; 946962306a36Sopenharmony_ci WREG32_SMC(CG_ECLK_CNTL, tmp); 947062306a36Sopenharmony_ci 947162306a36Sopenharmony_ci for (i = 0; i < 100; i++) { 947262306a36Sopenharmony_ci if (RREG32_SMC(CG_ECLK_STATUS) & ECLK_STATUS) 947362306a36Sopenharmony_ci break; 947462306a36Sopenharmony_ci mdelay(10); 947562306a36Sopenharmony_ci } 947662306a36Sopenharmony_ci if (i == 100) 947762306a36Sopenharmony_ci return -ETIMEDOUT; 947862306a36Sopenharmony_ci 947962306a36Sopenharmony_ci return 0; 948062306a36Sopenharmony_ci} 948162306a36Sopenharmony_ci 948262306a36Sopenharmony_cistatic void cik_pcie_gen3_enable(struct radeon_device *rdev) 948362306a36Sopenharmony_ci{ 948462306a36Sopenharmony_ci struct pci_dev *root = rdev->pdev->bus->self; 948562306a36Sopenharmony_ci enum pci_bus_speed speed_cap; 948662306a36Sopenharmony_ci u32 speed_cntl, current_data_rate; 948762306a36Sopenharmony_ci int i; 948862306a36Sopenharmony_ci u16 tmp16; 948962306a36Sopenharmony_ci 949062306a36Sopenharmony_ci if (pci_is_root_bus(rdev->pdev->bus)) 949162306a36Sopenharmony_ci return; 949262306a36Sopenharmony_ci 949362306a36Sopenharmony_ci if (radeon_pcie_gen2 == 0) 949462306a36Sopenharmony_ci return; 949562306a36Sopenharmony_ci 949662306a36Sopenharmony_ci if (rdev->flags & RADEON_IS_IGP) 949762306a36Sopenharmony_ci return; 949862306a36Sopenharmony_ci 949962306a36Sopenharmony_ci if (!(rdev->flags & RADEON_IS_PCIE)) 950062306a36Sopenharmony_ci return; 950162306a36Sopenharmony_ci 950262306a36Sopenharmony_ci speed_cap = pcie_get_speed_cap(root); 950362306a36Sopenharmony_ci if (speed_cap == PCI_SPEED_UNKNOWN) 950462306a36Sopenharmony_ci return; 950562306a36Sopenharmony_ci 950662306a36Sopenharmony_ci if ((speed_cap != PCIE_SPEED_8_0GT) && 950762306a36Sopenharmony_ci (speed_cap != PCIE_SPEED_5_0GT)) 950862306a36Sopenharmony_ci return; 950962306a36Sopenharmony_ci 951062306a36Sopenharmony_ci speed_cntl = RREG32_PCIE_PORT(PCIE_LC_SPEED_CNTL); 951162306a36Sopenharmony_ci current_data_rate = (speed_cntl & LC_CURRENT_DATA_RATE_MASK) >> 951262306a36Sopenharmony_ci LC_CURRENT_DATA_RATE_SHIFT; 951362306a36Sopenharmony_ci if (speed_cap == PCIE_SPEED_8_0GT) { 951462306a36Sopenharmony_ci if (current_data_rate == 2) { 951562306a36Sopenharmony_ci DRM_INFO("PCIE gen 3 link speeds already enabled\n"); 951662306a36Sopenharmony_ci return; 951762306a36Sopenharmony_ci } 951862306a36Sopenharmony_ci DRM_INFO("enabling PCIE gen 3 link speeds, disable with radeon.pcie_gen2=0\n"); 951962306a36Sopenharmony_ci } else if (speed_cap == PCIE_SPEED_5_0GT) { 952062306a36Sopenharmony_ci if (current_data_rate == 1) { 952162306a36Sopenharmony_ci DRM_INFO("PCIE gen 2 link speeds already enabled\n"); 952262306a36Sopenharmony_ci return; 952362306a36Sopenharmony_ci } 952462306a36Sopenharmony_ci DRM_INFO("enabling PCIE gen 2 link speeds, disable with radeon.pcie_gen2=0\n"); 952562306a36Sopenharmony_ci } 952662306a36Sopenharmony_ci 952762306a36Sopenharmony_ci if (!pci_is_pcie(root) || !pci_is_pcie(rdev->pdev)) 952862306a36Sopenharmony_ci return; 952962306a36Sopenharmony_ci 953062306a36Sopenharmony_ci if (speed_cap == PCIE_SPEED_8_0GT) { 953162306a36Sopenharmony_ci /* re-try equalization if gen3 is not already enabled */ 953262306a36Sopenharmony_ci if (current_data_rate != 2) { 953362306a36Sopenharmony_ci u16 bridge_cfg, gpu_cfg; 953462306a36Sopenharmony_ci u16 bridge_cfg2, gpu_cfg2; 953562306a36Sopenharmony_ci u32 max_lw, current_lw, tmp; 953662306a36Sopenharmony_ci 953762306a36Sopenharmony_ci pcie_capability_set_word(root, PCI_EXP_LNKCTL, PCI_EXP_LNKCTL_HAWD); 953862306a36Sopenharmony_ci pcie_capability_set_word(rdev->pdev, PCI_EXP_LNKCTL, PCI_EXP_LNKCTL_HAWD); 953962306a36Sopenharmony_ci 954062306a36Sopenharmony_ci tmp = RREG32_PCIE_PORT(PCIE_LC_STATUS1); 954162306a36Sopenharmony_ci max_lw = (tmp & LC_DETECTED_LINK_WIDTH_MASK) >> LC_DETECTED_LINK_WIDTH_SHIFT; 954262306a36Sopenharmony_ci current_lw = (tmp & LC_OPERATING_LINK_WIDTH_MASK) >> LC_OPERATING_LINK_WIDTH_SHIFT; 954362306a36Sopenharmony_ci 954462306a36Sopenharmony_ci if (current_lw < max_lw) { 954562306a36Sopenharmony_ci tmp = RREG32_PCIE_PORT(PCIE_LC_LINK_WIDTH_CNTL); 954662306a36Sopenharmony_ci if (tmp & LC_RENEGOTIATION_SUPPORT) { 954762306a36Sopenharmony_ci tmp &= ~(LC_LINK_WIDTH_MASK | LC_UPCONFIGURE_DIS); 954862306a36Sopenharmony_ci tmp |= (max_lw << LC_LINK_WIDTH_SHIFT); 954962306a36Sopenharmony_ci tmp |= LC_UPCONFIGURE_SUPPORT | LC_RENEGOTIATE_EN | LC_RECONFIG_NOW; 955062306a36Sopenharmony_ci WREG32_PCIE_PORT(PCIE_LC_LINK_WIDTH_CNTL, tmp); 955162306a36Sopenharmony_ci } 955262306a36Sopenharmony_ci } 955362306a36Sopenharmony_ci 955462306a36Sopenharmony_ci for (i = 0; i < 10; i++) { 955562306a36Sopenharmony_ci /* check status */ 955662306a36Sopenharmony_ci pcie_capability_read_word(rdev->pdev, 955762306a36Sopenharmony_ci PCI_EXP_DEVSTA, 955862306a36Sopenharmony_ci &tmp16); 955962306a36Sopenharmony_ci if (tmp16 & PCI_EXP_DEVSTA_TRPND) 956062306a36Sopenharmony_ci break; 956162306a36Sopenharmony_ci 956262306a36Sopenharmony_ci pcie_capability_read_word(root, PCI_EXP_LNKCTL, 956362306a36Sopenharmony_ci &bridge_cfg); 956462306a36Sopenharmony_ci pcie_capability_read_word(rdev->pdev, 956562306a36Sopenharmony_ci PCI_EXP_LNKCTL, 956662306a36Sopenharmony_ci &gpu_cfg); 956762306a36Sopenharmony_ci 956862306a36Sopenharmony_ci pcie_capability_read_word(root, PCI_EXP_LNKCTL2, 956962306a36Sopenharmony_ci &bridge_cfg2); 957062306a36Sopenharmony_ci pcie_capability_read_word(rdev->pdev, 957162306a36Sopenharmony_ci PCI_EXP_LNKCTL2, 957262306a36Sopenharmony_ci &gpu_cfg2); 957362306a36Sopenharmony_ci 957462306a36Sopenharmony_ci tmp = RREG32_PCIE_PORT(PCIE_LC_CNTL4); 957562306a36Sopenharmony_ci tmp |= LC_SET_QUIESCE; 957662306a36Sopenharmony_ci WREG32_PCIE_PORT(PCIE_LC_CNTL4, tmp); 957762306a36Sopenharmony_ci 957862306a36Sopenharmony_ci tmp = RREG32_PCIE_PORT(PCIE_LC_CNTL4); 957962306a36Sopenharmony_ci tmp |= LC_REDO_EQ; 958062306a36Sopenharmony_ci WREG32_PCIE_PORT(PCIE_LC_CNTL4, tmp); 958162306a36Sopenharmony_ci 958262306a36Sopenharmony_ci msleep(100); 958362306a36Sopenharmony_ci 958462306a36Sopenharmony_ci /* linkctl */ 958562306a36Sopenharmony_ci pcie_capability_clear_and_set_word(root, PCI_EXP_LNKCTL, 958662306a36Sopenharmony_ci PCI_EXP_LNKCTL_HAWD, 958762306a36Sopenharmony_ci bridge_cfg & 958862306a36Sopenharmony_ci PCI_EXP_LNKCTL_HAWD); 958962306a36Sopenharmony_ci pcie_capability_clear_and_set_word(rdev->pdev, PCI_EXP_LNKCTL, 959062306a36Sopenharmony_ci PCI_EXP_LNKCTL_HAWD, 959162306a36Sopenharmony_ci gpu_cfg & 959262306a36Sopenharmony_ci PCI_EXP_LNKCTL_HAWD); 959362306a36Sopenharmony_ci 959462306a36Sopenharmony_ci /* linkctl2 */ 959562306a36Sopenharmony_ci pcie_capability_read_word(root, PCI_EXP_LNKCTL2, 959662306a36Sopenharmony_ci &tmp16); 959762306a36Sopenharmony_ci tmp16 &= ~(PCI_EXP_LNKCTL2_ENTER_COMP | 959862306a36Sopenharmony_ci PCI_EXP_LNKCTL2_TX_MARGIN); 959962306a36Sopenharmony_ci tmp16 |= (bridge_cfg2 & 960062306a36Sopenharmony_ci (PCI_EXP_LNKCTL2_ENTER_COMP | 960162306a36Sopenharmony_ci PCI_EXP_LNKCTL2_TX_MARGIN)); 960262306a36Sopenharmony_ci pcie_capability_write_word(root, 960362306a36Sopenharmony_ci PCI_EXP_LNKCTL2, 960462306a36Sopenharmony_ci tmp16); 960562306a36Sopenharmony_ci 960662306a36Sopenharmony_ci pcie_capability_read_word(rdev->pdev, 960762306a36Sopenharmony_ci PCI_EXP_LNKCTL2, 960862306a36Sopenharmony_ci &tmp16); 960962306a36Sopenharmony_ci tmp16 &= ~(PCI_EXP_LNKCTL2_ENTER_COMP | 961062306a36Sopenharmony_ci PCI_EXP_LNKCTL2_TX_MARGIN); 961162306a36Sopenharmony_ci tmp16 |= (gpu_cfg2 & 961262306a36Sopenharmony_ci (PCI_EXP_LNKCTL2_ENTER_COMP | 961362306a36Sopenharmony_ci PCI_EXP_LNKCTL2_TX_MARGIN)); 961462306a36Sopenharmony_ci pcie_capability_write_word(rdev->pdev, 961562306a36Sopenharmony_ci PCI_EXP_LNKCTL2, 961662306a36Sopenharmony_ci tmp16); 961762306a36Sopenharmony_ci 961862306a36Sopenharmony_ci tmp = RREG32_PCIE_PORT(PCIE_LC_CNTL4); 961962306a36Sopenharmony_ci tmp &= ~LC_SET_QUIESCE; 962062306a36Sopenharmony_ci WREG32_PCIE_PORT(PCIE_LC_CNTL4, tmp); 962162306a36Sopenharmony_ci } 962262306a36Sopenharmony_ci } 962362306a36Sopenharmony_ci } 962462306a36Sopenharmony_ci 962562306a36Sopenharmony_ci /* set the link speed */ 962662306a36Sopenharmony_ci speed_cntl |= LC_FORCE_EN_SW_SPEED_CHANGE | LC_FORCE_DIS_HW_SPEED_CHANGE; 962762306a36Sopenharmony_ci speed_cntl &= ~LC_FORCE_DIS_SW_SPEED_CHANGE; 962862306a36Sopenharmony_ci WREG32_PCIE_PORT(PCIE_LC_SPEED_CNTL, speed_cntl); 962962306a36Sopenharmony_ci 963062306a36Sopenharmony_ci pcie_capability_read_word(rdev->pdev, PCI_EXP_LNKCTL2, &tmp16); 963162306a36Sopenharmony_ci tmp16 &= ~PCI_EXP_LNKCTL2_TLS; 963262306a36Sopenharmony_ci if (speed_cap == PCIE_SPEED_8_0GT) 963362306a36Sopenharmony_ci tmp16 |= PCI_EXP_LNKCTL2_TLS_8_0GT; /* gen3 */ 963462306a36Sopenharmony_ci else if (speed_cap == PCIE_SPEED_5_0GT) 963562306a36Sopenharmony_ci tmp16 |= PCI_EXP_LNKCTL2_TLS_5_0GT; /* gen2 */ 963662306a36Sopenharmony_ci else 963762306a36Sopenharmony_ci tmp16 |= PCI_EXP_LNKCTL2_TLS_2_5GT; /* gen1 */ 963862306a36Sopenharmony_ci pcie_capability_write_word(rdev->pdev, PCI_EXP_LNKCTL2, tmp16); 963962306a36Sopenharmony_ci 964062306a36Sopenharmony_ci speed_cntl = RREG32_PCIE_PORT(PCIE_LC_SPEED_CNTL); 964162306a36Sopenharmony_ci speed_cntl |= LC_INITIATE_LINK_SPEED_CHANGE; 964262306a36Sopenharmony_ci WREG32_PCIE_PORT(PCIE_LC_SPEED_CNTL, speed_cntl); 964362306a36Sopenharmony_ci 964462306a36Sopenharmony_ci for (i = 0; i < rdev->usec_timeout; i++) { 964562306a36Sopenharmony_ci speed_cntl = RREG32_PCIE_PORT(PCIE_LC_SPEED_CNTL); 964662306a36Sopenharmony_ci if ((speed_cntl & LC_INITIATE_LINK_SPEED_CHANGE) == 0) 964762306a36Sopenharmony_ci break; 964862306a36Sopenharmony_ci udelay(1); 964962306a36Sopenharmony_ci } 965062306a36Sopenharmony_ci} 965162306a36Sopenharmony_ci 965262306a36Sopenharmony_cistatic void cik_program_aspm(struct radeon_device *rdev) 965362306a36Sopenharmony_ci{ 965462306a36Sopenharmony_ci u32 data, orig; 965562306a36Sopenharmony_ci bool disable_l0s = false, disable_l1 = false, disable_plloff_in_l1 = false; 965662306a36Sopenharmony_ci bool disable_clkreq = false; 965762306a36Sopenharmony_ci 965862306a36Sopenharmony_ci if (radeon_aspm == 0) 965962306a36Sopenharmony_ci return; 966062306a36Sopenharmony_ci 966162306a36Sopenharmony_ci /* XXX double check IGPs */ 966262306a36Sopenharmony_ci if (rdev->flags & RADEON_IS_IGP) 966362306a36Sopenharmony_ci return; 966462306a36Sopenharmony_ci 966562306a36Sopenharmony_ci if (!(rdev->flags & RADEON_IS_PCIE)) 966662306a36Sopenharmony_ci return; 966762306a36Sopenharmony_ci 966862306a36Sopenharmony_ci orig = data = RREG32_PCIE_PORT(PCIE_LC_N_FTS_CNTL); 966962306a36Sopenharmony_ci data &= ~LC_XMIT_N_FTS_MASK; 967062306a36Sopenharmony_ci data |= LC_XMIT_N_FTS(0x24) | LC_XMIT_N_FTS_OVERRIDE_EN; 967162306a36Sopenharmony_ci if (orig != data) 967262306a36Sopenharmony_ci WREG32_PCIE_PORT(PCIE_LC_N_FTS_CNTL, data); 967362306a36Sopenharmony_ci 967462306a36Sopenharmony_ci orig = data = RREG32_PCIE_PORT(PCIE_LC_CNTL3); 967562306a36Sopenharmony_ci data |= LC_GO_TO_RECOVERY; 967662306a36Sopenharmony_ci if (orig != data) 967762306a36Sopenharmony_ci WREG32_PCIE_PORT(PCIE_LC_CNTL3, data); 967862306a36Sopenharmony_ci 967962306a36Sopenharmony_ci orig = data = RREG32_PCIE_PORT(PCIE_P_CNTL); 968062306a36Sopenharmony_ci data |= P_IGNORE_EDB_ERR; 968162306a36Sopenharmony_ci if (orig != data) 968262306a36Sopenharmony_ci WREG32_PCIE_PORT(PCIE_P_CNTL, data); 968362306a36Sopenharmony_ci 968462306a36Sopenharmony_ci orig = data = RREG32_PCIE_PORT(PCIE_LC_CNTL); 968562306a36Sopenharmony_ci data &= ~(LC_L0S_INACTIVITY_MASK | LC_L1_INACTIVITY_MASK); 968662306a36Sopenharmony_ci data |= LC_PMI_TO_L1_DIS; 968762306a36Sopenharmony_ci if (!disable_l0s) 968862306a36Sopenharmony_ci data |= LC_L0S_INACTIVITY(7); 968962306a36Sopenharmony_ci 969062306a36Sopenharmony_ci if (!disable_l1) { 969162306a36Sopenharmony_ci data |= LC_L1_INACTIVITY(7); 969262306a36Sopenharmony_ci data &= ~LC_PMI_TO_L1_DIS; 969362306a36Sopenharmony_ci if (orig != data) 969462306a36Sopenharmony_ci WREG32_PCIE_PORT(PCIE_LC_CNTL, data); 969562306a36Sopenharmony_ci 969662306a36Sopenharmony_ci if (!disable_plloff_in_l1) { 969762306a36Sopenharmony_ci bool clk_req_support; 969862306a36Sopenharmony_ci 969962306a36Sopenharmony_ci orig = data = RREG32_PCIE_PORT(PB0_PIF_PWRDOWN_0); 970062306a36Sopenharmony_ci data &= ~(PLL_POWER_STATE_IN_OFF_0_MASK | PLL_POWER_STATE_IN_TXS2_0_MASK); 970162306a36Sopenharmony_ci data |= PLL_POWER_STATE_IN_OFF_0(7) | PLL_POWER_STATE_IN_TXS2_0(7); 970262306a36Sopenharmony_ci if (orig != data) 970362306a36Sopenharmony_ci WREG32_PCIE_PORT(PB0_PIF_PWRDOWN_0, data); 970462306a36Sopenharmony_ci 970562306a36Sopenharmony_ci orig = data = RREG32_PCIE_PORT(PB0_PIF_PWRDOWN_1); 970662306a36Sopenharmony_ci data &= ~(PLL_POWER_STATE_IN_OFF_1_MASK | PLL_POWER_STATE_IN_TXS2_1_MASK); 970762306a36Sopenharmony_ci data |= PLL_POWER_STATE_IN_OFF_1(7) | PLL_POWER_STATE_IN_TXS2_1(7); 970862306a36Sopenharmony_ci if (orig != data) 970962306a36Sopenharmony_ci WREG32_PCIE_PORT(PB0_PIF_PWRDOWN_1, data); 971062306a36Sopenharmony_ci 971162306a36Sopenharmony_ci orig = data = RREG32_PCIE_PORT(PB1_PIF_PWRDOWN_0); 971262306a36Sopenharmony_ci data &= ~(PLL_POWER_STATE_IN_OFF_0_MASK | PLL_POWER_STATE_IN_TXS2_0_MASK); 971362306a36Sopenharmony_ci data |= PLL_POWER_STATE_IN_OFF_0(7) | PLL_POWER_STATE_IN_TXS2_0(7); 971462306a36Sopenharmony_ci if (orig != data) 971562306a36Sopenharmony_ci WREG32_PCIE_PORT(PB1_PIF_PWRDOWN_0, data); 971662306a36Sopenharmony_ci 971762306a36Sopenharmony_ci orig = data = RREG32_PCIE_PORT(PB1_PIF_PWRDOWN_1); 971862306a36Sopenharmony_ci data &= ~(PLL_POWER_STATE_IN_OFF_1_MASK | PLL_POWER_STATE_IN_TXS2_1_MASK); 971962306a36Sopenharmony_ci data |= PLL_POWER_STATE_IN_OFF_1(7) | PLL_POWER_STATE_IN_TXS2_1(7); 972062306a36Sopenharmony_ci if (orig != data) 972162306a36Sopenharmony_ci WREG32_PCIE_PORT(PB1_PIF_PWRDOWN_1, data); 972262306a36Sopenharmony_ci 972362306a36Sopenharmony_ci orig = data = RREG32_PCIE_PORT(PCIE_LC_LINK_WIDTH_CNTL); 972462306a36Sopenharmony_ci data &= ~LC_DYN_LANES_PWR_STATE_MASK; 972562306a36Sopenharmony_ci data |= LC_DYN_LANES_PWR_STATE(3); 972662306a36Sopenharmony_ci if (orig != data) 972762306a36Sopenharmony_ci WREG32_PCIE_PORT(PCIE_LC_LINK_WIDTH_CNTL, data); 972862306a36Sopenharmony_ci 972962306a36Sopenharmony_ci if (!disable_clkreq && 973062306a36Sopenharmony_ci !pci_is_root_bus(rdev->pdev->bus)) { 973162306a36Sopenharmony_ci struct pci_dev *root = rdev->pdev->bus->self; 973262306a36Sopenharmony_ci u32 lnkcap; 973362306a36Sopenharmony_ci 973462306a36Sopenharmony_ci clk_req_support = false; 973562306a36Sopenharmony_ci pcie_capability_read_dword(root, PCI_EXP_LNKCAP, &lnkcap); 973662306a36Sopenharmony_ci if (lnkcap & PCI_EXP_LNKCAP_CLKPM) 973762306a36Sopenharmony_ci clk_req_support = true; 973862306a36Sopenharmony_ci } else { 973962306a36Sopenharmony_ci clk_req_support = false; 974062306a36Sopenharmony_ci } 974162306a36Sopenharmony_ci 974262306a36Sopenharmony_ci if (clk_req_support) { 974362306a36Sopenharmony_ci orig = data = RREG32_PCIE_PORT(PCIE_LC_CNTL2); 974462306a36Sopenharmony_ci data |= LC_ALLOW_PDWN_IN_L1 | LC_ALLOW_PDWN_IN_L23; 974562306a36Sopenharmony_ci if (orig != data) 974662306a36Sopenharmony_ci WREG32_PCIE_PORT(PCIE_LC_CNTL2, data); 974762306a36Sopenharmony_ci 974862306a36Sopenharmony_ci orig = data = RREG32_SMC(THM_CLK_CNTL); 974962306a36Sopenharmony_ci data &= ~(CMON_CLK_SEL_MASK | TMON_CLK_SEL_MASK); 975062306a36Sopenharmony_ci data |= CMON_CLK_SEL(1) | TMON_CLK_SEL(1); 975162306a36Sopenharmony_ci if (orig != data) 975262306a36Sopenharmony_ci WREG32_SMC(THM_CLK_CNTL, data); 975362306a36Sopenharmony_ci 975462306a36Sopenharmony_ci orig = data = RREG32_SMC(MISC_CLK_CTRL); 975562306a36Sopenharmony_ci data &= ~(DEEP_SLEEP_CLK_SEL_MASK | ZCLK_SEL_MASK); 975662306a36Sopenharmony_ci data |= DEEP_SLEEP_CLK_SEL(1) | ZCLK_SEL(1); 975762306a36Sopenharmony_ci if (orig != data) 975862306a36Sopenharmony_ci WREG32_SMC(MISC_CLK_CTRL, data); 975962306a36Sopenharmony_ci 976062306a36Sopenharmony_ci orig = data = RREG32_SMC(CG_CLKPIN_CNTL); 976162306a36Sopenharmony_ci data &= ~BCLK_AS_XCLK; 976262306a36Sopenharmony_ci if (orig != data) 976362306a36Sopenharmony_ci WREG32_SMC(CG_CLKPIN_CNTL, data); 976462306a36Sopenharmony_ci 976562306a36Sopenharmony_ci orig = data = RREG32_SMC(CG_CLKPIN_CNTL_2); 976662306a36Sopenharmony_ci data &= ~FORCE_BIF_REFCLK_EN; 976762306a36Sopenharmony_ci if (orig != data) 976862306a36Sopenharmony_ci WREG32_SMC(CG_CLKPIN_CNTL_2, data); 976962306a36Sopenharmony_ci 977062306a36Sopenharmony_ci orig = data = RREG32_SMC(MPLL_BYPASSCLK_SEL); 977162306a36Sopenharmony_ci data &= ~MPLL_CLKOUT_SEL_MASK; 977262306a36Sopenharmony_ci data |= MPLL_CLKOUT_SEL(4); 977362306a36Sopenharmony_ci if (orig != data) 977462306a36Sopenharmony_ci WREG32_SMC(MPLL_BYPASSCLK_SEL, data); 977562306a36Sopenharmony_ci } 977662306a36Sopenharmony_ci } 977762306a36Sopenharmony_ci } else { 977862306a36Sopenharmony_ci if (orig != data) 977962306a36Sopenharmony_ci WREG32_PCIE_PORT(PCIE_LC_CNTL, data); 978062306a36Sopenharmony_ci } 978162306a36Sopenharmony_ci 978262306a36Sopenharmony_ci orig = data = RREG32_PCIE_PORT(PCIE_CNTL2); 978362306a36Sopenharmony_ci data |= SLV_MEM_LS_EN | MST_MEM_LS_EN | REPLAY_MEM_LS_EN; 978462306a36Sopenharmony_ci if (orig != data) 978562306a36Sopenharmony_ci WREG32_PCIE_PORT(PCIE_CNTL2, data); 978662306a36Sopenharmony_ci 978762306a36Sopenharmony_ci if (!disable_l0s) { 978862306a36Sopenharmony_ci data = RREG32_PCIE_PORT(PCIE_LC_N_FTS_CNTL); 978962306a36Sopenharmony_ci if((data & LC_N_FTS_MASK) == LC_N_FTS_MASK) { 979062306a36Sopenharmony_ci data = RREG32_PCIE_PORT(PCIE_LC_STATUS1); 979162306a36Sopenharmony_ci if ((data & LC_REVERSE_XMIT) && (data & LC_REVERSE_RCVR)) { 979262306a36Sopenharmony_ci orig = data = RREG32_PCIE_PORT(PCIE_LC_CNTL); 979362306a36Sopenharmony_ci data &= ~LC_L0S_INACTIVITY_MASK; 979462306a36Sopenharmony_ci if (orig != data) 979562306a36Sopenharmony_ci WREG32_PCIE_PORT(PCIE_LC_CNTL, data); 979662306a36Sopenharmony_ci } 979762306a36Sopenharmony_ci } 979862306a36Sopenharmony_ci } 979962306a36Sopenharmony_ci} 9800