xref: /kernel/linux/linux-6.6/drivers/gpu/drm/radeon/cik.c (revision 62306a36)
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, &dividers);
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, &dividers);
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