18c2ecf20Sopenharmony_ci/*
28c2ecf20Sopenharmony_ci * Copyright 2010 Advanced Micro Devices, Inc.
38c2ecf20Sopenharmony_ci *
48c2ecf20Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a
58c2ecf20Sopenharmony_ci * copy of this software and associated documentation files (the "Software"),
68c2ecf20Sopenharmony_ci * to deal in the Software without restriction, including without limitation
78c2ecf20Sopenharmony_ci * the rights to use, copy, modify, merge, publish, distribute, sublicense,
88c2ecf20Sopenharmony_ci * and/or sell copies of the Software, and to permit persons to whom the
98c2ecf20Sopenharmony_ci * Software is furnished to do so, subject to the following conditions:
108c2ecf20Sopenharmony_ci *
118c2ecf20Sopenharmony_ci * The above copyright notice and this permission notice shall be included in
128c2ecf20Sopenharmony_ci * all copies or substantial portions of the Software.
138c2ecf20Sopenharmony_ci *
148c2ecf20Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
158c2ecf20Sopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
168c2ecf20Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
178c2ecf20Sopenharmony_ci * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
188c2ecf20Sopenharmony_ci * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
198c2ecf20Sopenharmony_ci * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
208c2ecf20Sopenharmony_ci * OTHER DEALINGS IN THE SOFTWARE.
218c2ecf20Sopenharmony_ci *
228c2ecf20Sopenharmony_ci * Authors: Alex Deucher
238c2ecf20Sopenharmony_ci */
248c2ecf20Sopenharmony_ci
258c2ecf20Sopenharmony_ci#include <linux/firmware.h>
268c2ecf20Sopenharmony_ci#include <linux/pci.h>
278c2ecf20Sopenharmony_ci#include <linux/slab.h>
288c2ecf20Sopenharmony_ci
298c2ecf20Sopenharmony_ci#include <drm/drm_vblank.h>
308c2ecf20Sopenharmony_ci#include <drm/radeon_drm.h>
318c2ecf20Sopenharmony_ci
328c2ecf20Sopenharmony_ci#include "atom.h"
338c2ecf20Sopenharmony_ci#include "avivod.h"
348c2ecf20Sopenharmony_ci#include "evergreen_blit_shaders.h"
358c2ecf20Sopenharmony_ci#include "evergreen_reg.h"
368c2ecf20Sopenharmony_ci#include "evergreend.h"
378c2ecf20Sopenharmony_ci#include "radeon.h"
388c2ecf20Sopenharmony_ci#include "radeon_asic.h"
398c2ecf20Sopenharmony_ci#include "radeon_audio.h"
408c2ecf20Sopenharmony_ci#include "radeon_ucode.h"
418c2ecf20Sopenharmony_ci
428c2ecf20Sopenharmony_ci#define DC_HPDx_CONTROL(x)        (DC_HPD1_CONTROL     + (x * 0xc))
438c2ecf20Sopenharmony_ci#define DC_HPDx_INT_CONTROL(x)    (DC_HPD1_INT_CONTROL + (x * 0xc))
448c2ecf20Sopenharmony_ci#define DC_HPDx_INT_STATUS_REG(x) (DC_HPD1_INT_STATUS  + (x * 0xc))
458c2ecf20Sopenharmony_ci
468c2ecf20Sopenharmony_ci/*
478c2ecf20Sopenharmony_ci * Indirect registers accessor
488c2ecf20Sopenharmony_ci */
498c2ecf20Sopenharmony_ciu32 eg_cg_rreg(struct radeon_device *rdev, u32 reg)
508c2ecf20Sopenharmony_ci{
518c2ecf20Sopenharmony_ci	unsigned long flags;
528c2ecf20Sopenharmony_ci	u32 r;
538c2ecf20Sopenharmony_ci
548c2ecf20Sopenharmony_ci	spin_lock_irqsave(&rdev->cg_idx_lock, flags);
558c2ecf20Sopenharmony_ci	WREG32(EVERGREEN_CG_IND_ADDR, ((reg) & 0xffff));
568c2ecf20Sopenharmony_ci	r = RREG32(EVERGREEN_CG_IND_DATA);
578c2ecf20Sopenharmony_ci	spin_unlock_irqrestore(&rdev->cg_idx_lock, flags);
588c2ecf20Sopenharmony_ci	return r;
598c2ecf20Sopenharmony_ci}
608c2ecf20Sopenharmony_ci
618c2ecf20Sopenharmony_civoid eg_cg_wreg(struct radeon_device *rdev, u32 reg, u32 v)
628c2ecf20Sopenharmony_ci{
638c2ecf20Sopenharmony_ci	unsigned long flags;
648c2ecf20Sopenharmony_ci
658c2ecf20Sopenharmony_ci	spin_lock_irqsave(&rdev->cg_idx_lock, flags);
668c2ecf20Sopenharmony_ci	WREG32(EVERGREEN_CG_IND_ADDR, ((reg) & 0xffff));
678c2ecf20Sopenharmony_ci	WREG32(EVERGREEN_CG_IND_DATA, (v));
688c2ecf20Sopenharmony_ci	spin_unlock_irqrestore(&rdev->cg_idx_lock, flags);
698c2ecf20Sopenharmony_ci}
708c2ecf20Sopenharmony_ci
718c2ecf20Sopenharmony_ciu32 eg_pif_phy0_rreg(struct radeon_device *rdev, u32 reg)
728c2ecf20Sopenharmony_ci{
738c2ecf20Sopenharmony_ci	unsigned long flags;
748c2ecf20Sopenharmony_ci	u32 r;
758c2ecf20Sopenharmony_ci
768c2ecf20Sopenharmony_ci	spin_lock_irqsave(&rdev->pif_idx_lock, flags);
778c2ecf20Sopenharmony_ci	WREG32(EVERGREEN_PIF_PHY0_INDEX, ((reg) & 0xffff));
788c2ecf20Sopenharmony_ci	r = RREG32(EVERGREEN_PIF_PHY0_DATA);
798c2ecf20Sopenharmony_ci	spin_unlock_irqrestore(&rdev->pif_idx_lock, flags);
808c2ecf20Sopenharmony_ci	return r;
818c2ecf20Sopenharmony_ci}
828c2ecf20Sopenharmony_ci
838c2ecf20Sopenharmony_civoid eg_pif_phy0_wreg(struct radeon_device *rdev, u32 reg, u32 v)
848c2ecf20Sopenharmony_ci{
858c2ecf20Sopenharmony_ci	unsigned long flags;
868c2ecf20Sopenharmony_ci
878c2ecf20Sopenharmony_ci	spin_lock_irqsave(&rdev->pif_idx_lock, flags);
888c2ecf20Sopenharmony_ci	WREG32(EVERGREEN_PIF_PHY0_INDEX, ((reg) & 0xffff));
898c2ecf20Sopenharmony_ci	WREG32(EVERGREEN_PIF_PHY0_DATA, (v));
908c2ecf20Sopenharmony_ci	spin_unlock_irqrestore(&rdev->pif_idx_lock, flags);
918c2ecf20Sopenharmony_ci}
928c2ecf20Sopenharmony_ci
938c2ecf20Sopenharmony_ciu32 eg_pif_phy1_rreg(struct radeon_device *rdev, u32 reg)
948c2ecf20Sopenharmony_ci{
958c2ecf20Sopenharmony_ci	unsigned long flags;
968c2ecf20Sopenharmony_ci	u32 r;
978c2ecf20Sopenharmony_ci
988c2ecf20Sopenharmony_ci	spin_lock_irqsave(&rdev->pif_idx_lock, flags);
998c2ecf20Sopenharmony_ci	WREG32(EVERGREEN_PIF_PHY1_INDEX, ((reg) & 0xffff));
1008c2ecf20Sopenharmony_ci	r = RREG32(EVERGREEN_PIF_PHY1_DATA);
1018c2ecf20Sopenharmony_ci	spin_unlock_irqrestore(&rdev->pif_idx_lock, flags);
1028c2ecf20Sopenharmony_ci	return r;
1038c2ecf20Sopenharmony_ci}
1048c2ecf20Sopenharmony_ci
1058c2ecf20Sopenharmony_civoid eg_pif_phy1_wreg(struct radeon_device *rdev, u32 reg, u32 v)
1068c2ecf20Sopenharmony_ci{
1078c2ecf20Sopenharmony_ci	unsigned long flags;
1088c2ecf20Sopenharmony_ci
1098c2ecf20Sopenharmony_ci	spin_lock_irqsave(&rdev->pif_idx_lock, flags);
1108c2ecf20Sopenharmony_ci	WREG32(EVERGREEN_PIF_PHY1_INDEX, ((reg) & 0xffff));
1118c2ecf20Sopenharmony_ci	WREG32(EVERGREEN_PIF_PHY1_DATA, (v));
1128c2ecf20Sopenharmony_ci	spin_unlock_irqrestore(&rdev->pif_idx_lock, flags);
1138c2ecf20Sopenharmony_ci}
1148c2ecf20Sopenharmony_ci
1158c2ecf20Sopenharmony_cistatic const u32 crtc_offsets[6] =
1168c2ecf20Sopenharmony_ci{
1178c2ecf20Sopenharmony_ci	EVERGREEN_CRTC0_REGISTER_OFFSET,
1188c2ecf20Sopenharmony_ci	EVERGREEN_CRTC1_REGISTER_OFFSET,
1198c2ecf20Sopenharmony_ci	EVERGREEN_CRTC2_REGISTER_OFFSET,
1208c2ecf20Sopenharmony_ci	EVERGREEN_CRTC3_REGISTER_OFFSET,
1218c2ecf20Sopenharmony_ci	EVERGREEN_CRTC4_REGISTER_OFFSET,
1228c2ecf20Sopenharmony_ci	EVERGREEN_CRTC5_REGISTER_OFFSET
1238c2ecf20Sopenharmony_ci};
1248c2ecf20Sopenharmony_ci
1258c2ecf20Sopenharmony_ci#include "clearstate_evergreen.h"
1268c2ecf20Sopenharmony_ci
1278c2ecf20Sopenharmony_cistatic const u32 sumo_rlc_save_restore_register_list[] =
1288c2ecf20Sopenharmony_ci{
1298c2ecf20Sopenharmony_ci	0x98fc,
1308c2ecf20Sopenharmony_ci	0x9830,
1318c2ecf20Sopenharmony_ci	0x9834,
1328c2ecf20Sopenharmony_ci	0x9838,
1338c2ecf20Sopenharmony_ci	0x9870,
1348c2ecf20Sopenharmony_ci	0x9874,
1358c2ecf20Sopenharmony_ci	0x8a14,
1368c2ecf20Sopenharmony_ci	0x8b24,
1378c2ecf20Sopenharmony_ci	0x8bcc,
1388c2ecf20Sopenharmony_ci	0x8b10,
1398c2ecf20Sopenharmony_ci	0x8d00,
1408c2ecf20Sopenharmony_ci	0x8d04,
1418c2ecf20Sopenharmony_ci	0x8c00,
1428c2ecf20Sopenharmony_ci	0x8c04,
1438c2ecf20Sopenharmony_ci	0x8c08,
1448c2ecf20Sopenharmony_ci	0x8c0c,
1458c2ecf20Sopenharmony_ci	0x8d8c,
1468c2ecf20Sopenharmony_ci	0x8c20,
1478c2ecf20Sopenharmony_ci	0x8c24,
1488c2ecf20Sopenharmony_ci	0x8c28,
1498c2ecf20Sopenharmony_ci	0x8c18,
1508c2ecf20Sopenharmony_ci	0x8c1c,
1518c2ecf20Sopenharmony_ci	0x8cf0,
1528c2ecf20Sopenharmony_ci	0x8e2c,
1538c2ecf20Sopenharmony_ci	0x8e38,
1548c2ecf20Sopenharmony_ci	0x8c30,
1558c2ecf20Sopenharmony_ci	0x9508,
1568c2ecf20Sopenharmony_ci	0x9688,
1578c2ecf20Sopenharmony_ci	0x9608,
1588c2ecf20Sopenharmony_ci	0x960c,
1598c2ecf20Sopenharmony_ci	0x9610,
1608c2ecf20Sopenharmony_ci	0x9614,
1618c2ecf20Sopenharmony_ci	0x88c4,
1628c2ecf20Sopenharmony_ci	0x88d4,
1638c2ecf20Sopenharmony_ci	0xa008,
1648c2ecf20Sopenharmony_ci	0x900c,
1658c2ecf20Sopenharmony_ci	0x9100,
1668c2ecf20Sopenharmony_ci	0x913c,
1678c2ecf20Sopenharmony_ci	0x98f8,
1688c2ecf20Sopenharmony_ci	0x98f4,
1698c2ecf20Sopenharmony_ci	0x9b7c,
1708c2ecf20Sopenharmony_ci	0x3f8c,
1718c2ecf20Sopenharmony_ci	0x8950,
1728c2ecf20Sopenharmony_ci	0x8954,
1738c2ecf20Sopenharmony_ci	0x8a18,
1748c2ecf20Sopenharmony_ci	0x8b28,
1758c2ecf20Sopenharmony_ci	0x9144,
1768c2ecf20Sopenharmony_ci	0x9148,
1778c2ecf20Sopenharmony_ci	0x914c,
1788c2ecf20Sopenharmony_ci	0x3f90,
1798c2ecf20Sopenharmony_ci	0x3f94,
1808c2ecf20Sopenharmony_ci	0x915c,
1818c2ecf20Sopenharmony_ci	0x9160,
1828c2ecf20Sopenharmony_ci	0x9178,
1838c2ecf20Sopenharmony_ci	0x917c,
1848c2ecf20Sopenharmony_ci	0x9180,
1858c2ecf20Sopenharmony_ci	0x918c,
1868c2ecf20Sopenharmony_ci	0x9190,
1878c2ecf20Sopenharmony_ci	0x9194,
1888c2ecf20Sopenharmony_ci	0x9198,
1898c2ecf20Sopenharmony_ci	0x919c,
1908c2ecf20Sopenharmony_ci	0x91a8,
1918c2ecf20Sopenharmony_ci	0x91ac,
1928c2ecf20Sopenharmony_ci	0x91b0,
1938c2ecf20Sopenharmony_ci	0x91b4,
1948c2ecf20Sopenharmony_ci	0x91b8,
1958c2ecf20Sopenharmony_ci	0x91c4,
1968c2ecf20Sopenharmony_ci	0x91c8,
1978c2ecf20Sopenharmony_ci	0x91cc,
1988c2ecf20Sopenharmony_ci	0x91d0,
1998c2ecf20Sopenharmony_ci	0x91d4,
2008c2ecf20Sopenharmony_ci	0x91e0,
2018c2ecf20Sopenharmony_ci	0x91e4,
2028c2ecf20Sopenharmony_ci	0x91ec,
2038c2ecf20Sopenharmony_ci	0x91f0,
2048c2ecf20Sopenharmony_ci	0x91f4,
2058c2ecf20Sopenharmony_ci	0x9200,
2068c2ecf20Sopenharmony_ci	0x9204,
2078c2ecf20Sopenharmony_ci	0x929c,
2088c2ecf20Sopenharmony_ci	0x9150,
2098c2ecf20Sopenharmony_ci	0x802c,
2108c2ecf20Sopenharmony_ci};
2118c2ecf20Sopenharmony_ci
2128c2ecf20Sopenharmony_cistatic void evergreen_gpu_init(struct radeon_device *rdev);
2138c2ecf20Sopenharmony_civoid evergreen_fini(struct radeon_device *rdev);
2148c2ecf20Sopenharmony_civoid evergreen_pcie_gen2_enable(struct radeon_device *rdev);
2158c2ecf20Sopenharmony_civoid evergreen_program_aspm(struct radeon_device *rdev);
2168c2ecf20Sopenharmony_ciextern void cayman_cp_int_cntl_setup(struct radeon_device *rdev,
2178c2ecf20Sopenharmony_ci				     int ring, u32 cp_int_cntl);
2188c2ecf20Sopenharmony_ciextern void cayman_vm_decode_fault(struct radeon_device *rdev,
2198c2ecf20Sopenharmony_ci				   u32 status, u32 addr);
2208c2ecf20Sopenharmony_civoid cik_init_cp_pg_table(struct radeon_device *rdev);
2218c2ecf20Sopenharmony_ci
2228c2ecf20Sopenharmony_ciextern u32 si_get_csb_size(struct radeon_device *rdev);
2238c2ecf20Sopenharmony_ciextern void si_get_csb_buffer(struct radeon_device *rdev, volatile u32 *buffer);
2248c2ecf20Sopenharmony_ciextern u32 cik_get_csb_size(struct radeon_device *rdev);
2258c2ecf20Sopenharmony_ciextern void cik_get_csb_buffer(struct radeon_device *rdev, volatile u32 *buffer);
2268c2ecf20Sopenharmony_ciextern void rv770_set_clk_bypass_mode(struct radeon_device *rdev);
2278c2ecf20Sopenharmony_ci
2288c2ecf20Sopenharmony_cistatic const u32 evergreen_golden_registers[] =
2298c2ecf20Sopenharmony_ci{
2308c2ecf20Sopenharmony_ci	0x3f90, 0xffff0000, 0xff000000,
2318c2ecf20Sopenharmony_ci	0x9148, 0xffff0000, 0xff000000,
2328c2ecf20Sopenharmony_ci	0x3f94, 0xffff0000, 0xff000000,
2338c2ecf20Sopenharmony_ci	0x914c, 0xffff0000, 0xff000000,
2348c2ecf20Sopenharmony_ci	0x9b7c, 0xffffffff, 0x00000000,
2358c2ecf20Sopenharmony_ci	0x8a14, 0xffffffff, 0x00000007,
2368c2ecf20Sopenharmony_ci	0x8b10, 0xffffffff, 0x00000000,
2378c2ecf20Sopenharmony_ci	0x960c, 0xffffffff, 0x54763210,
2388c2ecf20Sopenharmony_ci	0x88c4, 0xffffffff, 0x000000c2,
2398c2ecf20Sopenharmony_ci	0x88d4, 0xffffffff, 0x00000010,
2408c2ecf20Sopenharmony_ci	0x8974, 0xffffffff, 0x00000000,
2418c2ecf20Sopenharmony_ci	0xc78, 0x00000080, 0x00000080,
2428c2ecf20Sopenharmony_ci	0x5eb4, 0xffffffff, 0x00000002,
2438c2ecf20Sopenharmony_ci	0x5e78, 0xffffffff, 0x001000f0,
2448c2ecf20Sopenharmony_ci	0x6104, 0x01000300, 0x00000000,
2458c2ecf20Sopenharmony_ci	0x5bc0, 0x00300000, 0x00000000,
2468c2ecf20Sopenharmony_ci	0x7030, 0xffffffff, 0x00000011,
2478c2ecf20Sopenharmony_ci	0x7c30, 0xffffffff, 0x00000011,
2488c2ecf20Sopenharmony_ci	0x10830, 0xffffffff, 0x00000011,
2498c2ecf20Sopenharmony_ci	0x11430, 0xffffffff, 0x00000011,
2508c2ecf20Sopenharmony_ci	0x12030, 0xffffffff, 0x00000011,
2518c2ecf20Sopenharmony_ci	0x12c30, 0xffffffff, 0x00000011,
2528c2ecf20Sopenharmony_ci	0xd02c, 0xffffffff, 0x08421000,
2538c2ecf20Sopenharmony_ci	0x240c, 0xffffffff, 0x00000380,
2548c2ecf20Sopenharmony_ci	0x8b24, 0xffffffff, 0x00ff0fff,
2558c2ecf20Sopenharmony_ci	0x28a4c, 0x06000000, 0x06000000,
2568c2ecf20Sopenharmony_ci	0x10c, 0x00000001, 0x00000001,
2578c2ecf20Sopenharmony_ci	0x8d00, 0xffffffff, 0x100e4848,
2588c2ecf20Sopenharmony_ci	0x8d04, 0xffffffff, 0x00164745,
2598c2ecf20Sopenharmony_ci	0x8c00, 0xffffffff, 0xe4000003,
2608c2ecf20Sopenharmony_ci	0x8c04, 0xffffffff, 0x40600060,
2618c2ecf20Sopenharmony_ci	0x8c08, 0xffffffff, 0x001c001c,
2628c2ecf20Sopenharmony_ci	0x8cf0, 0xffffffff, 0x08e00620,
2638c2ecf20Sopenharmony_ci	0x8c20, 0xffffffff, 0x00800080,
2648c2ecf20Sopenharmony_ci	0x8c24, 0xffffffff, 0x00800080,
2658c2ecf20Sopenharmony_ci	0x8c18, 0xffffffff, 0x20202078,
2668c2ecf20Sopenharmony_ci	0x8c1c, 0xffffffff, 0x00001010,
2678c2ecf20Sopenharmony_ci	0x28350, 0xffffffff, 0x00000000,
2688c2ecf20Sopenharmony_ci	0xa008, 0xffffffff, 0x00010000,
2698c2ecf20Sopenharmony_ci	0x5c4, 0xffffffff, 0x00000001,
2708c2ecf20Sopenharmony_ci	0x9508, 0xffffffff, 0x00000002,
2718c2ecf20Sopenharmony_ci	0x913c, 0x0000000f, 0x0000000a
2728c2ecf20Sopenharmony_ci};
2738c2ecf20Sopenharmony_ci
2748c2ecf20Sopenharmony_cistatic const u32 evergreen_golden_registers2[] =
2758c2ecf20Sopenharmony_ci{
2768c2ecf20Sopenharmony_ci	0x2f4c, 0xffffffff, 0x00000000,
2778c2ecf20Sopenharmony_ci	0x54f4, 0xffffffff, 0x00000000,
2788c2ecf20Sopenharmony_ci	0x54f0, 0xffffffff, 0x00000000,
2798c2ecf20Sopenharmony_ci	0x5498, 0xffffffff, 0x00000000,
2808c2ecf20Sopenharmony_ci	0x549c, 0xffffffff, 0x00000000,
2818c2ecf20Sopenharmony_ci	0x5494, 0xffffffff, 0x00000000,
2828c2ecf20Sopenharmony_ci	0x53cc, 0xffffffff, 0x00000000,
2838c2ecf20Sopenharmony_ci	0x53c8, 0xffffffff, 0x00000000,
2848c2ecf20Sopenharmony_ci	0x53c4, 0xffffffff, 0x00000000,
2858c2ecf20Sopenharmony_ci	0x53c0, 0xffffffff, 0x00000000,
2868c2ecf20Sopenharmony_ci	0x53bc, 0xffffffff, 0x00000000,
2878c2ecf20Sopenharmony_ci	0x53b8, 0xffffffff, 0x00000000,
2888c2ecf20Sopenharmony_ci	0x53b4, 0xffffffff, 0x00000000,
2898c2ecf20Sopenharmony_ci	0x53b0, 0xffffffff, 0x00000000
2908c2ecf20Sopenharmony_ci};
2918c2ecf20Sopenharmony_ci
2928c2ecf20Sopenharmony_cistatic const u32 cypress_mgcg_init[] =
2938c2ecf20Sopenharmony_ci{
2948c2ecf20Sopenharmony_ci	0x802c, 0xffffffff, 0xc0000000,
2958c2ecf20Sopenharmony_ci	0x5448, 0xffffffff, 0x00000100,
2968c2ecf20Sopenharmony_ci	0x55e4, 0xffffffff, 0x00000100,
2978c2ecf20Sopenharmony_ci	0x160c, 0xffffffff, 0x00000100,
2988c2ecf20Sopenharmony_ci	0x5644, 0xffffffff, 0x00000100,
2998c2ecf20Sopenharmony_ci	0xc164, 0xffffffff, 0x00000100,
3008c2ecf20Sopenharmony_ci	0x8a18, 0xffffffff, 0x00000100,
3018c2ecf20Sopenharmony_ci	0x897c, 0xffffffff, 0x06000100,
3028c2ecf20Sopenharmony_ci	0x8b28, 0xffffffff, 0x00000100,
3038c2ecf20Sopenharmony_ci	0x9144, 0xffffffff, 0x00000100,
3048c2ecf20Sopenharmony_ci	0x9a60, 0xffffffff, 0x00000100,
3058c2ecf20Sopenharmony_ci	0x9868, 0xffffffff, 0x00000100,
3068c2ecf20Sopenharmony_ci	0x8d58, 0xffffffff, 0x00000100,
3078c2ecf20Sopenharmony_ci	0x9510, 0xffffffff, 0x00000100,
3088c2ecf20Sopenharmony_ci	0x949c, 0xffffffff, 0x00000100,
3098c2ecf20Sopenharmony_ci	0x9654, 0xffffffff, 0x00000100,
3108c2ecf20Sopenharmony_ci	0x9030, 0xffffffff, 0x00000100,
3118c2ecf20Sopenharmony_ci	0x9034, 0xffffffff, 0x00000100,
3128c2ecf20Sopenharmony_ci	0x9038, 0xffffffff, 0x00000100,
3138c2ecf20Sopenharmony_ci	0x903c, 0xffffffff, 0x00000100,
3148c2ecf20Sopenharmony_ci	0x9040, 0xffffffff, 0x00000100,
3158c2ecf20Sopenharmony_ci	0xa200, 0xffffffff, 0x00000100,
3168c2ecf20Sopenharmony_ci	0xa204, 0xffffffff, 0x00000100,
3178c2ecf20Sopenharmony_ci	0xa208, 0xffffffff, 0x00000100,
3188c2ecf20Sopenharmony_ci	0xa20c, 0xffffffff, 0x00000100,
3198c2ecf20Sopenharmony_ci	0x971c, 0xffffffff, 0x00000100,
3208c2ecf20Sopenharmony_ci	0x977c, 0xffffffff, 0x00000100,
3218c2ecf20Sopenharmony_ci	0x3f80, 0xffffffff, 0x00000100,
3228c2ecf20Sopenharmony_ci	0xa210, 0xffffffff, 0x00000100,
3238c2ecf20Sopenharmony_ci	0xa214, 0xffffffff, 0x00000100,
3248c2ecf20Sopenharmony_ci	0x4d8, 0xffffffff, 0x00000100,
3258c2ecf20Sopenharmony_ci	0x9784, 0xffffffff, 0x00000100,
3268c2ecf20Sopenharmony_ci	0x9698, 0xffffffff, 0x00000100,
3278c2ecf20Sopenharmony_ci	0x4d4, 0xffffffff, 0x00000200,
3288c2ecf20Sopenharmony_ci	0x30cc, 0xffffffff, 0x00000100,
3298c2ecf20Sopenharmony_ci	0xd0c0, 0xffffffff, 0xff000100,
3308c2ecf20Sopenharmony_ci	0x802c, 0xffffffff, 0x40000000,
3318c2ecf20Sopenharmony_ci	0x915c, 0xffffffff, 0x00010000,
3328c2ecf20Sopenharmony_ci	0x9160, 0xffffffff, 0x00030002,
3338c2ecf20Sopenharmony_ci	0x9178, 0xffffffff, 0x00070000,
3348c2ecf20Sopenharmony_ci	0x917c, 0xffffffff, 0x00030002,
3358c2ecf20Sopenharmony_ci	0x9180, 0xffffffff, 0x00050004,
3368c2ecf20Sopenharmony_ci	0x918c, 0xffffffff, 0x00010006,
3378c2ecf20Sopenharmony_ci	0x9190, 0xffffffff, 0x00090008,
3388c2ecf20Sopenharmony_ci	0x9194, 0xffffffff, 0x00070000,
3398c2ecf20Sopenharmony_ci	0x9198, 0xffffffff, 0x00030002,
3408c2ecf20Sopenharmony_ci	0x919c, 0xffffffff, 0x00050004,
3418c2ecf20Sopenharmony_ci	0x91a8, 0xffffffff, 0x00010006,
3428c2ecf20Sopenharmony_ci	0x91ac, 0xffffffff, 0x00090008,
3438c2ecf20Sopenharmony_ci	0x91b0, 0xffffffff, 0x00070000,
3448c2ecf20Sopenharmony_ci	0x91b4, 0xffffffff, 0x00030002,
3458c2ecf20Sopenharmony_ci	0x91b8, 0xffffffff, 0x00050004,
3468c2ecf20Sopenharmony_ci	0x91c4, 0xffffffff, 0x00010006,
3478c2ecf20Sopenharmony_ci	0x91c8, 0xffffffff, 0x00090008,
3488c2ecf20Sopenharmony_ci	0x91cc, 0xffffffff, 0x00070000,
3498c2ecf20Sopenharmony_ci	0x91d0, 0xffffffff, 0x00030002,
3508c2ecf20Sopenharmony_ci	0x91d4, 0xffffffff, 0x00050004,
3518c2ecf20Sopenharmony_ci	0x91e0, 0xffffffff, 0x00010006,
3528c2ecf20Sopenharmony_ci	0x91e4, 0xffffffff, 0x00090008,
3538c2ecf20Sopenharmony_ci	0x91e8, 0xffffffff, 0x00000000,
3548c2ecf20Sopenharmony_ci	0x91ec, 0xffffffff, 0x00070000,
3558c2ecf20Sopenharmony_ci	0x91f0, 0xffffffff, 0x00030002,
3568c2ecf20Sopenharmony_ci	0x91f4, 0xffffffff, 0x00050004,
3578c2ecf20Sopenharmony_ci	0x9200, 0xffffffff, 0x00010006,
3588c2ecf20Sopenharmony_ci	0x9204, 0xffffffff, 0x00090008,
3598c2ecf20Sopenharmony_ci	0x9208, 0xffffffff, 0x00070000,
3608c2ecf20Sopenharmony_ci	0x920c, 0xffffffff, 0x00030002,
3618c2ecf20Sopenharmony_ci	0x9210, 0xffffffff, 0x00050004,
3628c2ecf20Sopenharmony_ci	0x921c, 0xffffffff, 0x00010006,
3638c2ecf20Sopenharmony_ci	0x9220, 0xffffffff, 0x00090008,
3648c2ecf20Sopenharmony_ci	0x9224, 0xffffffff, 0x00070000,
3658c2ecf20Sopenharmony_ci	0x9228, 0xffffffff, 0x00030002,
3668c2ecf20Sopenharmony_ci	0x922c, 0xffffffff, 0x00050004,
3678c2ecf20Sopenharmony_ci	0x9238, 0xffffffff, 0x00010006,
3688c2ecf20Sopenharmony_ci	0x923c, 0xffffffff, 0x00090008,
3698c2ecf20Sopenharmony_ci	0x9240, 0xffffffff, 0x00070000,
3708c2ecf20Sopenharmony_ci	0x9244, 0xffffffff, 0x00030002,
3718c2ecf20Sopenharmony_ci	0x9248, 0xffffffff, 0x00050004,
3728c2ecf20Sopenharmony_ci	0x9254, 0xffffffff, 0x00010006,
3738c2ecf20Sopenharmony_ci	0x9258, 0xffffffff, 0x00090008,
3748c2ecf20Sopenharmony_ci	0x925c, 0xffffffff, 0x00070000,
3758c2ecf20Sopenharmony_ci	0x9260, 0xffffffff, 0x00030002,
3768c2ecf20Sopenharmony_ci	0x9264, 0xffffffff, 0x00050004,
3778c2ecf20Sopenharmony_ci	0x9270, 0xffffffff, 0x00010006,
3788c2ecf20Sopenharmony_ci	0x9274, 0xffffffff, 0x00090008,
3798c2ecf20Sopenharmony_ci	0x9278, 0xffffffff, 0x00070000,
3808c2ecf20Sopenharmony_ci	0x927c, 0xffffffff, 0x00030002,
3818c2ecf20Sopenharmony_ci	0x9280, 0xffffffff, 0x00050004,
3828c2ecf20Sopenharmony_ci	0x928c, 0xffffffff, 0x00010006,
3838c2ecf20Sopenharmony_ci	0x9290, 0xffffffff, 0x00090008,
3848c2ecf20Sopenharmony_ci	0x9294, 0xffffffff, 0x00000000,
3858c2ecf20Sopenharmony_ci	0x929c, 0xffffffff, 0x00000001,
3868c2ecf20Sopenharmony_ci	0x802c, 0xffffffff, 0x40010000,
3878c2ecf20Sopenharmony_ci	0x915c, 0xffffffff, 0x00010000,
3888c2ecf20Sopenharmony_ci	0x9160, 0xffffffff, 0x00030002,
3898c2ecf20Sopenharmony_ci	0x9178, 0xffffffff, 0x00070000,
3908c2ecf20Sopenharmony_ci	0x917c, 0xffffffff, 0x00030002,
3918c2ecf20Sopenharmony_ci	0x9180, 0xffffffff, 0x00050004,
3928c2ecf20Sopenharmony_ci	0x918c, 0xffffffff, 0x00010006,
3938c2ecf20Sopenharmony_ci	0x9190, 0xffffffff, 0x00090008,
3948c2ecf20Sopenharmony_ci	0x9194, 0xffffffff, 0x00070000,
3958c2ecf20Sopenharmony_ci	0x9198, 0xffffffff, 0x00030002,
3968c2ecf20Sopenharmony_ci	0x919c, 0xffffffff, 0x00050004,
3978c2ecf20Sopenharmony_ci	0x91a8, 0xffffffff, 0x00010006,
3988c2ecf20Sopenharmony_ci	0x91ac, 0xffffffff, 0x00090008,
3998c2ecf20Sopenharmony_ci	0x91b0, 0xffffffff, 0x00070000,
4008c2ecf20Sopenharmony_ci	0x91b4, 0xffffffff, 0x00030002,
4018c2ecf20Sopenharmony_ci	0x91b8, 0xffffffff, 0x00050004,
4028c2ecf20Sopenharmony_ci	0x91c4, 0xffffffff, 0x00010006,
4038c2ecf20Sopenharmony_ci	0x91c8, 0xffffffff, 0x00090008,
4048c2ecf20Sopenharmony_ci	0x91cc, 0xffffffff, 0x00070000,
4058c2ecf20Sopenharmony_ci	0x91d0, 0xffffffff, 0x00030002,
4068c2ecf20Sopenharmony_ci	0x91d4, 0xffffffff, 0x00050004,
4078c2ecf20Sopenharmony_ci	0x91e0, 0xffffffff, 0x00010006,
4088c2ecf20Sopenharmony_ci	0x91e4, 0xffffffff, 0x00090008,
4098c2ecf20Sopenharmony_ci	0x91e8, 0xffffffff, 0x00000000,
4108c2ecf20Sopenharmony_ci	0x91ec, 0xffffffff, 0x00070000,
4118c2ecf20Sopenharmony_ci	0x91f0, 0xffffffff, 0x00030002,
4128c2ecf20Sopenharmony_ci	0x91f4, 0xffffffff, 0x00050004,
4138c2ecf20Sopenharmony_ci	0x9200, 0xffffffff, 0x00010006,
4148c2ecf20Sopenharmony_ci	0x9204, 0xffffffff, 0x00090008,
4158c2ecf20Sopenharmony_ci	0x9208, 0xffffffff, 0x00070000,
4168c2ecf20Sopenharmony_ci	0x920c, 0xffffffff, 0x00030002,
4178c2ecf20Sopenharmony_ci	0x9210, 0xffffffff, 0x00050004,
4188c2ecf20Sopenharmony_ci	0x921c, 0xffffffff, 0x00010006,
4198c2ecf20Sopenharmony_ci	0x9220, 0xffffffff, 0x00090008,
4208c2ecf20Sopenharmony_ci	0x9224, 0xffffffff, 0x00070000,
4218c2ecf20Sopenharmony_ci	0x9228, 0xffffffff, 0x00030002,
4228c2ecf20Sopenharmony_ci	0x922c, 0xffffffff, 0x00050004,
4238c2ecf20Sopenharmony_ci	0x9238, 0xffffffff, 0x00010006,
4248c2ecf20Sopenharmony_ci	0x923c, 0xffffffff, 0x00090008,
4258c2ecf20Sopenharmony_ci	0x9240, 0xffffffff, 0x00070000,
4268c2ecf20Sopenharmony_ci	0x9244, 0xffffffff, 0x00030002,
4278c2ecf20Sopenharmony_ci	0x9248, 0xffffffff, 0x00050004,
4288c2ecf20Sopenharmony_ci	0x9254, 0xffffffff, 0x00010006,
4298c2ecf20Sopenharmony_ci	0x9258, 0xffffffff, 0x00090008,
4308c2ecf20Sopenharmony_ci	0x925c, 0xffffffff, 0x00070000,
4318c2ecf20Sopenharmony_ci	0x9260, 0xffffffff, 0x00030002,
4328c2ecf20Sopenharmony_ci	0x9264, 0xffffffff, 0x00050004,
4338c2ecf20Sopenharmony_ci	0x9270, 0xffffffff, 0x00010006,
4348c2ecf20Sopenharmony_ci	0x9274, 0xffffffff, 0x00090008,
4358c2ecf20Sopenharmony_ci	0x9278, 0xffffffff, 0x00070000,
4368c2ecf20Sopenharmony_ci	0x927c, 0xffffffff, 0x00030002,
4378c2ecf20Sopenharmony_ci	0x9280, 0xffffffff, 0x00050004,
4388c2ecf20Sopenharmony_ci	0x928c, 0xffffffff, 0x00010006,
4398c2ecf20Sopenharmony_ci	0x9290, 0xffffffff, 0x00090008,
4408c2ecf20Sopenharmony_ci	0x9294, 0xffffffff, 0x00000000,
4418c2ecf20Sopenharmony_ci	0x929c, 0xffffffff, 0x00000001,
4428c2ecf20Sopenharmony_ci	0x802c, 0xffffffff, 0xc0000000
4438c2ecf20Sopenharmony_ci};
4448c2ecf20Sopenharmony_ci
4458c2ecf20Sopenharmony_cistatic const u32 redwood_mgcg_init[] =
4468c2ecf20Sopenharmony_ci{
4478c2ecf20Sopenharmony_ci	0x802c, 0xffffffff, 0xc0000000,
4488c2ecf20Sopenharmony_ci	0x5448, 0xffffffff, 0x00000100,
4498c2ecf20Sopenharmony_ci	0x55e4, 0xffffffff, 0x00000100,
4508c2ecf20Sopenharmony_ci	0x160c, 0xffffffff, 0x00000100,
4518c2ecf20Sopenharmony_ci	0x5644, 0xffffffff, 0x00000100,
4528c2ecf20Sopenharmony_ci	0xc164, 0xffffffff, 0x00000100,
4538c2ecf20Sopenharmony_ci	0x8a18, 0xffffffff, 0x00000100,
4548c2ecf20Sopenharmony_ci	0x897c, 0xffffffff, 0x06000100,
4558c2ecf20Sopenharmony_ci	0x8b28, 0xffffffff, 0x00000100,
4568c2ecf20Sopenharmony_ci	0x9144, 0xffffffff, 0x00000100,
4578c2ecf20Sopenharmony_ci	0x9a60, 0xffffffff, 0x00000100,
4588c2ecf20Sopenharmony_ci	0x9868, 0xffffffff, 0x00000100,
4598c2ecf20Sopenharmony_ci	0x8d58, 0xffffffff, 0x00000100,
4608c2ecf20Sopenharmony_ci	0x9510, 0xffffffff, 0x00000100,
4618c2ecf20Sopenharmony_ci	0x949c, 0xffffffff, 0x00000100,
4628c2ecf20Sopenharmony_ci	0x9654, 0xffffffff, 0x00000100,
4638c2ecf20Sopenharmony_ci	0x9030, 0xffffffff, 0x00000100,
4648c2ecf20Sopenharmony_ci	0x9034, 0xffffffff, 0x00000100,
4658c2ecf20Sopenharmony_ci	0x9038, 0xffffffff, 0x00000100,
4668c2ecf20Sopenharmony_ci	0x903c, 0xffffffff, 0x00000100,
4678c2ecf20Sopenharmony_ci	0x9040, 0xffffffff, 0x00000100,
4688c2ecf20Sopenharmony_ci	0xa200, 0xffffffff, 0x00000100,
4698c2ecf20Sopenharmony_ci	0xa204, 0xffffffff, 0x00000100,
4708c2ecf20Sopenharmony_ci	0xa208, 0xffffffff, 0x00000100,
4718c2ecf20Sopenharmony_ci	0xa20c, 0xffffffff, 0x00000100,
4728c2ecf20Sopenharmony_ci	0x971c, 0xffffffff, 0x00000100,
4738c2ecf20Sopenharmony_ci	0x977c, 0xffffffff, 0x00000100,
4748c2ecf20Sopenharmony_ci	0x3f80, 0xffffffff, 0x00000100,
4758c2ecf20Sopenharmony_ci	0xa210, 0xffffffff, 0x00000100,
4768c2ecf20Sopenharmony_ci	0xa214, 0xffffffff, 0x00000100,
4778c2ecf20Sopenharmony_ci	0x4d8, 0xffffffff, 0x00000100,
4788c2ecf20Sopenharmony_ci	0x9784, 0xffffffff, 0x00000100,
4798c2ecf20Sopenharmony_ci	0x9698, 0xffffffff, 0x00000100,
4808c2ecf20Sopenharmony_ci	0x4d4, 0xffffffff, 0x00000200,
4818c2ecf20Sopenharmony_ci	0x30cc, 0xffffffff, 0x00000100,
4828c2ecf20Sopenharmony_ci	0xd0c0, 0xffffffff, 0xff000100,
4838c2ecf20Sopenharmony_ci	0x802c, 0xffffffff, 0x40000000,
4848c2ecf20Sopenharmony_ci	0x915c, 0xffffffff, 0x00010000,
4858c2ecf20Sopenharmony_ci	0x9160, 0xffffffff, 0x00030002,
4868c2ecf20Sopenharmony_ci	0x9178, 0xffffffff, 0x00070000,
4878c2ecf20Sopenharmony_ci	0x917c, 0xffffffff, 0x00030002,
4888c2ecf20Sopenharmony_ci	0x9180, 0xffffffff, 0x00050004,
4898c2ecf20Sopenharmony_ci	0x918c, 0xffffffff, 0x00010006,
4908c2ecf20Sopenharmony_ci	0x9190, 0xffffffff, 0x00090008,
4918c2ecf20Sopenharmony_ci	0x9194, 0xffffffff, 0x00070000,
4928c2ecf20Sopenharmony_ci	0x9198, 0xffffffff, 0x00030002,
4938c2ecf20Sopenharmony_ci	0x919c, 0xffffffff, 0x00050004,
4948c2ecf20Sopenharmony_ci	0x91a8, 0xffffffff, 0x00010006,
4958c2ecf20Sopenharmony_ci	0x91ac, 0xffffffff, 0x00090008,
4968c2ecf20Sopenharmony_ci	0x91b0, 0xffffffff, 0x00070000,
4978c2ecf20Sopenharmony_ci	0x91b4, 0xffffffff, 0x00030002,
4988c2ecf20Sopenharmony_ci	0x91b8, 0xffffffff, 0x00050004,
4998c2ecf20Sopenharmony_ci	0x91c4, 0xffffffff, 0x00010006,
5008c2ecf20Sopenharmony_ci	0x91c8, 0xffffffff, 0x00090008,
5018c2ecf20Sopenharmony_ci	0x91cc, 0xffffffff, 0x00070000,
5028c2ecf20Sopenharmony_ci	0x91d0, 0xffffffff, 0x00030002,
5038c2ecf20Sopenharmony_ci	0x91d4, 0xffffffff, 0x00050004,
5048c2ecf20Sopenharmony_ci	0x91e0, 0xffffffff, 0x00010006,
5058c2ecf20Sopenharmony_ci	0x91e4, 0xffffffff, 0x00090008,
5068c2ecf20Sopenharmony_ci	0x91e8, 0xffffffff, 0x00000000,
5078c2ecf20Sopenharmony_ci	0x91ec, 0xffffffff, 0x00070000,
5088c2ecf20Sopenharmony_ci	0x91f0, 0xffffffff, 0x00030002,
5098c2ecf20Sopenharmony_ci	0x91f4, 0xffffffff, 0x00050004,
5108c2ecf20Sopenharmony_ci	0x9200, 0xffffffff, 0x00010006,
5118c2ecf20Sopenharmony_ci	0x9204, 0xffffffff, 0x00090008,
5128c2ecf20Sopenharmony_ci	0x9294, 0xffffffff, 0x00000000,
5138c2ecf20Sopenharmony_ci	0x929c, 0xffffffff, 0x00000001,
5148c2ecf20Sopenharmony_ci	0x802c, 0xffffffff, 0xc0000000
5158c2ecf20Sopenharmony_ci};
5168c2ecf20Sopenharmony_ci
5178c2ecf20Sopenharmony_cistatic const u32 cedar_golden_registers[] =
5188c2ecf20Sopenharmony_ci{
5198c2ecf20Sopenharmony_ci	0x3f90, 0xffff0000, 0xff000000,
5208c2ecf20Sopenharmony_ci	0x9148, 0xffff0000, 0xff000000,
5218c2ecf20Sopenharmony_ci	0x3f94, 0xffff0000, 0xff000000,
5228c2ecf20Sopenharmony_ci	0x914c, 0xffff0000, 0xff000000,
5238c2ecf20Sopenharmony_ci	0x9b7c, 0xffffffff, 0x00000000,
5248c2ecf20Sopenharmony_ci	0x8a14, 0xffffffff, 0x00000007,
5258c2ecf20Sopenharmony_ci	0x8b10, 0xffffffff, 0x00000000,
5268c2ecf20Sopenharmony_ci	0x960c, 0xffffffff, 0x54763210,
5278c2ecf20Sopenharmony_ci	0x88c4, 0xffffffff, 0x000000c2,
5288c2ecf20Sopenharmony_ci	0x88d4, 0xffffffff, 0x00000000,
5298c2ecf20Sopenharmony_ci	0x8974, 0xffffffff, 0x00000000,
5308c2ecf20Sopenharmony_ci	0xc78, 0x00000080, 0x00000080,
5318c2ecf20Sopenharmony_ci	0x5eb4, 0xffffffff, 0x00000002,
5328c2ecf20Sopenharmony_ci	0x5e78, 0xffffffff, 0x001000f0,
5338c2ecf20Sopenharmony_ci	0x6104, 0x01000300, 0x00000000,
5348c2ecf20Sopenharmony_ci	0x5bc0, 0x00300000, 0x00000000,
5358c2ecf20Sopenharmony_ci	0x7030, 0xffffffff, 0x00000011,
5368c2ecf20Sopenharmony_ci	0x7c30, 0xffffffff, 0x00000011,
5378c2ecf20Sopenharmony_ci	0x10830, 0xffffffff, 0x00000011,
5388c2ecf20Sopenharmony_ci	0x11430, 0xffffffff, 0x00000011,
5398c2ecf20Sopenharmony_ci	0xd02c, 0xffffffff, 0x08421000,
5408c2ecf20Sopenharmony_ci	0x240c, 0xffffffff, 0x00000380,
5418c2ecf20Sopenharmony_ci	0x8b24, 0xffffffff, 0x00ff0fff,
5428c2ecf20Sopenharmony_ci	0x28a4c, 0x06000000, 0x06000000,
5438c2ecf20Sopenharmony_ci	0x10c, 0x00000001, 0x00000001,
5448c2ecf20Sopenharmony_ci	0x8d00, 0xffffffff, 0x100e4848,
5458c2ecf20Sopenharmony_ci	0x8d04, 0xffffffff, 0x00164745,
5468c2ecf20Sopenharmony_ci	0x8c00, 0xffffffff, 0xe4000003,
5478c2ecf20Sopenharmony_ci	0x8c04, 0xffffffff, 0x40600060,
5488c2ecf20Sopenharmony_ci	0x8c08, 0xffffffff, 0x001c001c,
5498c2ecf20Sopenharmony_ci	0x8cf0, 0xffffffff, 0x08e00410,
5508c2ecf20Sopenharmony_ci	0x8c20, 0xffffffff, 0x00800080,
5518c2ecf20Sopenharmony_ci	0x8c24, 0xffffffff, 0x00800080,
5528c2ecf20Sopenharmony_ci	0x8c18, 0xffffffff, 0x20202078,
5538c2ecf20Sopenharmony_ci	0x8c1c, 0xffffffff, 0x00001010,
5548c2ecf20Sopenharmony_ci	0x28350, 0xffffffff, 0x00000000,
5558c2ecf20Sopenharmony_ci	0xa008, 0xffffffff, 0x00010000,
5568c2ecf20Sopenharmony_ci	0x5c4, 0xffffffff, 0x00000001,
5578c2ecf20Sopenharmony_ci	0x9508, 0xffffffff, 0x00000002
5588c2ecf20Sopenharmony_ci};
5598c2ecf20Sopenharmony_ci
5608c2ecf20Sopenharmony_cistatic const u32 cedar_mgcg_init[] =
5618c2ecf20Sopenharmony_ci{
5628c2ecf20Sopenharmony_ci	0x802c, 0xffffffff, 0xc0000000,
5638c2ecf20Sopenharmony_ci	0x5448, 0xffffffff, 0x00000100,
5648c2ecf20Sopenharmony_ci	0x55e4, 0xffffffff, 0x00000100,
5658c2ecf20Sopenharmony_ci	0x160c, 0xffffffff, 0x00000100,
5668c2ecf20Sopenharmony_ci	0x5644, 0xffffffff, 0x00000100,
5678c2ecf20Sopenharmony_ci	0xc164, 0xffffffff, 0x00000100,
5688c2ecf20Sopenharmony_ci	0x8a18, 0xffffffff, 0x00000100,
5698c2ecf20Sopenharmony_ci	0x897c, 0xffffffff, 0x06000100,
5708c2ecf20Sopenharmony_ci	0x8b28, 0xffffffff, 0x00000100,
5718c2ecf20Sopenharmony_ci	0x9144, 0xffffffff, 0x00000100,
5728c2ecf20Sopenharmony_ci	0x9a60, 0xffffffff, 0x00000100,
5738c2ecf20Sopenharmony_ci	0x9868, 0xffffffff, 0x00000100,
5748c2ecf20Sopenharmony_ci	0x8d58, 0xffffffff, 0x00000100,
5758c2ecf20Sopenharmony_ci	0x9510, 0xffffffff, 0x00000100,
5768c2ecf20Sopenharmony_ci	0x949c, 0xffffffff, 0x00000100,
5778c2ecf20Sopenharmony_ci	0x9654, 0xffffffff, 0x00000100,
5788c2ecf20Sopenharmony_ci	0x9030, 0xffffffff, 0x00000100,
5798c2ecf20Sopenharmony_ci	0x9034, 0xffffffff, 0x00000100,
5808c2ecf20Sopenharmony_ci	0x9038, 0xffffffff, 0x00000100,
5818c2ecf20Sopenharmony_ci	0x903c, 0xffffffff, 0x00000100,
5828c2ecf20Sopenharmony_ci	0x9040, 0xffffffff, 0x00000100,
5838c2ecf20Sopenharmony_ci	0xa200, 0xffffffff, 0x00000100,
5848c2ecf20Sopenharmony_ci	0xa204, 0xffffffff, 0x00000100,
5858c2ecf20Sopenharmony_ci	0xa208, 0xffffffff, 0x00000100,
5868c2ecf20Sopenharmony_ci	0xa20c, 0xffffffff, 0x00000100,
5878c2ecf20Sopenharmony_ci	0x971c, 0xffffffff, 0x00000100,
5888c2ecf20Sopenharmony_ci	0x977c, 0xffffffff, 0x00000100,
5898c2ecf20Sopenharmony_ci	0x3f80, 0xffffffff, 0x00000100,
5908c2ecf20Sopenharmony_ci	0xa210, 0xffffffff, 0x00000100,
5918c2ecf20Sopenharmony_ci	0xa214, 0xffffffff, 0x00000100,
5928c2ecf20Sopenharmony_ci	0x4d8, 0xffffffff, 0x00000100,
5938c2ecf20Sopenharmony_ci	0x9784, 0xffffffff, 0x00000100,
5948c2ecf20Sopenharmony_ci	0x9698, 0xffffffff, 0x00000100,
5958c2ecf20Sopenharmony_ci	0x4d4, 0xffffffff, 0x00000200,
5968c2ecf20Sopenharmony_ci	0x30cc, 0xffffffff, 0x00000100,
5978c2ecf20Sopenharmony_ci	0xd0c0, 0xffffffff, 0xff000100,
5988c2ecf20Sopenharmony_ci	0x802c, 0xffffffff, 0x40000000,
5998c2ecf20Sopenharmony_ci	0x915c, 0xffffffff, 0x00010000,
6008c2ecf20Sopenharmony_ci	0x9178, 0xffffffff, 0x00050000,
6018c2ecf20Sopenharmony_ci	0x917c, 0xffffffff, 0x00030002,
6028c2ecf20Sopenharmony_ci	0x918c, 0xffffffff, 0x00010004,
6038c2ecf20Sopenharmony_ci	0x9190, 0xffffffff, 0x00070006,
6048c2ecf20Sopenharmony_ci	0x9194, 0xffffffff, 0x00050000,
6058c2ecf20Sopenharmony_ci	0x9198, 0xffffffff, 0x00030002,
6068c2ecf20Sopenharmony_ci	0x91a8, 0xffffffff, 0x00010004,
6078c2ecf20Sopenharmony_ci	0x91ac, 0xffffffff, 0x00070006,
6088c2ecf20Sopenharmony_ci	0x91e8, 0xffffffff, 0x00000000,
6098c2ecf20Sopenharmony_ci	0x9294, 0xffffffff, 0x00000000,
6108c2ecf20Sopenharmony_ci	0x929c, 0xffffffff, 0x00000001,
6118c2ecf20Sopenharmony_ci	0x802c, 0xffffffff, 0xc0000000
6128c2ecf20Sopenharmony_ci};
6138c2ecf20Sopenharmony_ci
6148c2ecf20Sopenharmony_cistatic const u32 juniper_mgcg_init[] =
6158c2ecf20Sopenharmony_ci{
6168c2ecf20Sopenharmony_ci	0x802c, 0xffffffff, 0xc0000000,
6178c2ecf20Sopenharmony_ci	0x5448, 0xffffffff, 0x00000100,
6188c2ecf20Sopenharmony_ci	0x55e4, 0xffffffff, 0x00000100,
6198c2ecf20Sopenharmony_ci	0x160c, 0xffffffff, 0x00000100,
6208c2ecf20Sopenharmony_ci	0x5644, 0xffffffff, 0x00000100,
6218c2ecf20Sopenharmony_ci	0xc164, 0xffffffff, 0x00000100,
6228c2ecf20Sopenharmony_ci	0x8a18, 0xffffffff, 0x00000100,
6238c2ecf20Sopenharmony_ci	0x897c, 0xffffffff, 0x06000100,
6248c2ecf20Sopenharmony_ci	0x8b28, 0xffffffff, 0x00000100,
6258c2ecf20Sopenharmony_ci	0x9144, 0xffffffff, 0x00000100,
6268c2ecf20Sopenharmony_ci	0x9a60, 0xffffffff, 0x00000100,
6278c2ecf20Sopenharmony_ci	0x9868, 0xffffffff, 0x00000100,
6288c2ecf20Sopenharmony_ci	0x8d58, 0xffffffff, 0x00000100,
6298c2ecf20Sopenharmony_ci	0x9510, 0xffffffff, 0x00000100,
6308c2ecf20Sopenharmony_ci	0x949c, 0xffffffff, 0x00000100,
6318c2ecf20Sopenharmony_ci	0x9654, 0xffffffff, 0x00000100,
6328c2ecf20Sopenharmony_ci	0x9030, 0xffffffff, 0x00000100,
6338c2ecf20Sopenharmony_ci	0x9034, 0xffffffff, 0x00000100,
6348c2ecf20Sopenharmony_ci	0x9038, 0xffffffff, 0x00000100,
6358c2ecf20Sopenharmony_ci	0x903c, 0xffffffff, 0x00000100,
6368c2ecf20Sopenharmony_ci	0x9040, 0xffffffff, 0x00000100,
6378c2ecf20Sopenharmony_ci	0xa200, 0xffffffff, 0x00000100,
6388c2ecf20Sopenharmony_ci	0xa204, 0xffffffff, 0x00000100,
6398c2ecf20Sopenharmony_ci	0xa208, 0xffffffff, 0x00000100,
6408c2ecf20Sopenharmony_ci	0xa20c, 0xffffffff, 0x00000100,
6418c2ecf20Sopenharmony_ci	0x971c, 0xffffffff, 0x00000100,
6428c2ecf20Sopenharmony_ci	0xd0c0, 0xffffffff, 0xff000100,
6438c2ecf20Sopenharmony_ci	0x802c, 0xffffffff, 0x40000000,
6448c2ecf20Sopenharmony_ci	0x915c, 0xffffffff, 0x00010000,
6458c2ecf20Sopenharmony_ci	0x9160, 0xffffffff, 0x00030002,
6468c2ecf20Sopenharmony_ci	0x9178, 0xffffffff, 0x00070000,
6478c2ecf20Sopenharmony_ci	0x917c, 0xffffffff, 0x00030002,
6488c2ecf20Sopenharmony_ci	0x9180, 0xffffffff, 0x00050004,
6498c2ecf20Sopenharmony_ci	0x918c, 0xffffffff, 0x00010006,
6508c2ecf20Sopenharmony_ci	0x9190, 0xffffffff, 0x00090008,
6518c2ecf20Sopenharmony_ci	0x9194, 0xffffffff, 0x00070000,
6528c2ecf20Sopenharmony_ci	0x9198, 0xffffffff, 0x00030002,
6538c2ecf20Sopenharmony_ci	0x919c, 0xffffffff, 0x00050004,
6548c2ecf20Sopenharmony_ci	0x91a8, 0xffffffff, 0x00010006,
6558c2ecf20Sopenharmony_ci	0x91ac, 0xffffffff, 0x00090008,
6568c2ecf20Sopenharmony_ci	0x91b0, 0xffffffff, 0x00070000,
6578c2ecf20Sopenharmony_ci	0x91b4, 0xffffffff, 0x00030002,
6588c2ecf20Sopenharmony_ci	0x91b8, 0xffffffff, 0x00050004,
6598c2ecf20Sopenharmony_ci	0x91c4, 0xffffffff, 0x00010006,
6608c2ecf20Sopenharmony_ci	0x91c8, 0xffffffff, 0x00090008,
6618c2ecf20Sopenharmony_ci	0x91cc, 0xffffffff, 0x00070000,
6628c2ecf20Sopenharmony_ci	0x91d0, 0xffffffff, 0x00030002,
6638c2ecf20Sopenharmony_ci	0x91d4, 0xffffffff, 0x00050004,
6648c2ecf20Sopenharmony_ci	0x91e0, 0xffffffff, 0x00010006,
6658c2ecf20Sopenharmony_ci	0x91e4, 0xffffffff, 0x00090008,
6668c2ecf20Sopenharmony_ci	0x91e8, 0xffffffff, 0x00000000,
6678c2ecf20Sopenharmony_ci	0x91ec, 0xffffffff, 0x00070000,
6688c2ecf20Sopenharmony_ci	0x91f0, 0xffffffff, 0x00030002,
6698c2ecf20Sopenharmony_ci	0x91f4, 0xffffffff, 0x00050004,
6708c2ecf20Sopenharmony_ci	0x9200, 0xffffffff, 0x00010006,
6718c2ecf20Sopenharmony_ci	0x9204, 0xffffffff, 0x00090008,
6728c2ecf20Sopenharmony_ci	0x9208, 0xffffffff, 0x00070000,
6738c2ecf20Sopenharmony_ci	0x920c, 0xffffffff, 0x00030002,
6748c2ecf20Sopenharmony_ci	0x9210, 0xffffffff, 0x00050004,
6758c2ecf20Sopenharmony_ci	0x921c, 0xffffffff, 0x00010006,
6768c2ecf20Sopenharmony_ci	0x9220, 0xffffffff, 0x00090008,
6778c2ecf20Sopenharmony_ci	0x9224, 0xffffffff, 0x00070000,
6788c2ecf20Sopenharmony_ci	0x9228, 0xffffffff, 0x00030002,
6798c2ecf20Sopenharmony_ci	0x922c, 0xffffffff, 0x00050004,
6808c2ecf20Sopenharmony_ci	0x9238, 0xffffffff, 0x00010006,
6818c2ecf20Sopenharmony_ci	0x923c, 0xffffffff, 0x00090008,
6828c2ecf20Sopenharmony_ci	0x9240, 0xffffffff, 0x00070000,
6838c2ecf20Sopenharmony_ci	0x9244, 0xffffffff, 0x00030002,
6848c2ecf20Sopenharmony_ci	0x9248, 0xffffffff, 0x00050004,
6858c2ecf20Sopenharmony_ci	0x9254, 0xffffffff, 0x00010006,
6868c2ecf20Sopenharmony_ci	0x9258, 0xffffffff, 0x00090008,
6878c2ecf20Sopenharmony_ci	0x925c, 0xffffffff, 0x00070000,
6888c2ecf20Sopenharmony_ci	0x9260, 0xffffffff, 0x00030002,
6898c2ecf20Sopenharmony_ci	0x9264, 0xffffffff, 0x00050004,
6908c2ecf20Sopenharmony_ci	0x9270, 0xffffffff, 0x00010006,
6918c2ecf20Sopenharmony_ci	0x9274, 0xffffffff, 0x00090008,
6928c2ecf20Sopenharmony_ci	0x9278, 0xffffffff, 0x00070000,
6938c2ecf20Sopenharmony_ci	0x927c, 0xffffffff, 0x00030002,
6948c2ecf20Sopenharmony_ci	0x9280, 0xffffffff, 0x00050004,
6958c2ecf20Sopenharmony_ci	0x928c, 0xffffffff, 0x00010006,
6968c2ecf20Sopenharmony_ci	0x9290, 0xffffffff, 0x00090008,
6978c2ecf20Sopenharmony_ci	0x9294, 0xffffffff, 0x00000000,
6988c2ecf20Sopenharmony_ci	0x929c, 0xffffffff, 0x00000001,
6998c2ecf20Sopenharmony_ci	0x802c, 0xffffffff, 0xc0000000,
7008c2ecf20Sopenharmony_ci	0x977c, 0xffffffff, 0x00000100,
7018c2ecf20Sopenharmony_ci	0x3f80, 0xffffffff, 0x00000100,
7028c2ecf20Sopenharmony_ci	0xa210, 0xffffffff, 0x00000100,
7038c2ecf20Sopenharmony_ci	0xa214, 0xffffffff, 0x00000100,
7048c2ecf20Sopenharmony_ci	0x4d8, 0xffffffff, 0x00000100,
7058c2ecf20Sopenharmony_ci	0x9784, 0xffffffff, 0x00000100,
7068c2ecf20Sopenharmony_ci	0x9698, 0xffffffff, 0x00000100,
7078c2ecf20Sopenharmony_ci	0x4d4, 0xffffffff, 0x00000200,
7088c2ecf20Sopenharmony_ci	0x30cc, 0xffffffff, 0x00000100,
7098c2ecf20Sopenharmony_ci	0x802c, 0xffffffff, 0xc0000000
7108c2ecf20Sopenharmony_ci};
7118c2ecf20Sopenharmony_ci
7128c2ecf20Sopenharmony_cistatic const u32 supersumo_golden_registers[] =
7138c2ecf20Sopenharmony_ci{
7148c2ecf20Sopenharmony_ci	0x5eb4, 0xffffffff, 0x00000002,
7158c2ecf20Sopenharmony_ci	0x5c4, 0xffffffff, 0x00000001,
7168c2ecf20Sopenharmony_ci	0x7030, 0xffffffff, 0x00000011,
7178c2ecf20Sopenharmony_ci	0x7c30, 0xffffffff, 0x00000011,
7188c2ecf20Sopenharmony_ci	0x6104, 0x01000300, 0x00000000,
7198c2ecf20Sopenharmony_ci	0x5bc0, 0x00300000, 0x00000000,
7208c2ecf20Sopenharmony_ci	0x8c04, 0xffffffff, 0x40600060,
7218c2ecf20Sopenharmony_ci	0x8c08, 0xffffffff, 0x001c001c,
7228c2ecf20Sopenharmony_ci	0x8c20, 0xffffffff, 0x00800080,
7238c2ecf20Sopenharmony_ci	0x8c24, 0xffffffff, 0x00800080,
7248c2ecf20Sopenharmony_ci	0x8c18, 0xffffffff, 0x20202078,
7258c2ecf20Sopenharmony_ci	0x8c1c, 0xffffffff, 0x00001010,
7268c2ecf20Sopenharmony_ci	0x918c, 0xffffffff, 0x00010006,
7278c2ecf20Sopenharmony_ci	0x91a8, 0xffffffff, 0x00010006,
7288c2ecf20Sopenharmony_ci	0x91c4, 0xffffffff, 0x00010006,
7298c2ecf20Sopenharmony_ci	0x91e0, 0xffffffff, 0x00010006,
7308c2ecf20Sopenharmony_ci	0x9200, 0xffffffff, 0x00010006,
7318c2ecf20Sopenharmony_ci	0x9150, 0xffffffff, 0x6e944040,
7328c2ecf20Sopenharmony_ci	0x917c, 0xffffffff, 0x00030002,
7338c2ecf20Sopenharmony_ci	0x9180, 0xffffffff, 0x00050004,
7348c2ecf20Sopenharmony_ci	0x9198, 0xffffffff, 0x00030002,
7358c2ecf20Sopenharmony_ci	0x919c, 0xffffffff, 0x00050004,
7368c2ecf20Sopenharmony_ci	0x91b4, 0xffffffff, 0x00030002,
7378c2ecf20Sopenharmony_ci	0x91b8, 0xffffffff, 0x00050004,
7388c2ecf20Sopenharmony_ci	0x91d0, 0xffffffff, 0x00030002,
7398c2ecf20Sopenharmony_ci	0x91d4, 0xffffffff, 0x00050004,
7408c2ecf20Sopenharmony_ci	0x91f0, 0xffffffff, 0x00030002,
7418c2ecf20Sopenharmony_ci	0x91f4, 0xffffffff, 0x00050004,
7428c2ecf20Sopenharmony_ci	0x915c, 0xffffffff, 0x00010000,
7438c2ecf20Sopenharmony_ci	0x9160, 0xffffffff, 0x00030002,
7448c2ecf20Sopenharmony_ci	0x3f90, 0xffff0000, 0xff000000,
7458c2ecf20Sopenharmony_ci	0x9178, 0xffffffff, 0x00070000,
7468c2ecf20Sopenharmony_ci	0x9194, 0xffffffff, 0x00070000,
7478c2ecf20Sopenharmony_ci	0x91b0, 0xffffffff, 0x00070000,
7488c2ecf20Sopenharmony_ci	0x91cc, 0xffffffff, 0x00070000,
7498c2ecf20Sopenharmony_ci	0x91ec, 0xffffffff, 0x00070000,
7508c2ecf20Sopenharmony_ci	0x9148, 0xffff0000, 0xff000000,
7518c2ecf20Sopenharmony_ci	0x9190, 0xffffffff, 0x00090008,
7528c2ecf20Sopenharmony_ci	0x91ac, 0xffffffff, 0x00090008,
7538c2ecf20Sopenharmony_ci	0x91c8, 0xffffffff, 0x00090008,
7548c2ecf20Sopenharmony_ci	0x91e4, 0xffffffff, 0x00090008,
7558c2ecf20Sopenharmony_ci	0x9204, 0xffffffff, 0x00090008,
7568c2ecf20Sopenharmony_ci	0x3f94, 0xffff0000, 0xff000000,
7578c2ecf20Sopenharmony_ci	0x914c, 0xffff0000, 0xff000000,
7588c2ecf20Sopenharmony_ci	0x929c, 0xffffffff, 0x00000001,
7598c2ecf20Sopenharmony_ci	0x8a18, 0xffffffff, 0x00000100,
7608c2ecf20Sopenharmony_ci	0x8b28, 0xffffffff, 0x00000100,
7618c2ecf20Sopenharmony_ci	0x9144, 0xffffffff, 0x00000100,
7628c2ecf20Sopenharmony_ci	0x5644, 0xffffffff, 0x00000100,
7638c2ecf20Sopenharmony_ci	0x9b7c, 0xffffffff, 0x00000000,
7648c2ecf20Sopenharmony_ci	0x8030, 0xffffffff, 0x0000100a,
7658c2ecf20Sopenharmony_ci	0x8a14, 0xffffffff, 0x00000007,
7668c2ecf20Sopenharmony_ci	0x8b24, 0xffffffff, 0x00ff0fff,
7678c2ecf20Sopenharmony_ci	0x8b10, 0xffffffff, 0x00000000,
7688c2ecf20Sopenharmony_ci	0x28a4c, 0x06000000, 0x06000000,
7698c2ecf20Sopenharmony_ci	0x4d8, 0xffffffff, 0x00000100,
7708c2ecf20Sopenharmony_ci	0x913c, 0xffff000f, 0x0100000a,
7718c2ecf20Sopenharmony_ci	0x960c, 0xffffffff, 0x54763210,
7728c2ecf20Sopenharmony_ci	0x88c4, 0xffffffff, 0x000000c2,
7738c2ecf20Sopenharmony_ci	0x88d4, 0xffffffff, 0x00000010,
7748c2ecf20Sopenharmony_ci	0x8974, 0xffffffff, 0x00000000,
7758c2ecf20Sopenharmony_ci	0xc78, 0x00000080, 0x00000080,
7768c2ecf20Sopenharmony_ci	0x5e78, 0xffffffff, 0x001000f0,
7778c2ecf20Sopenharmony_ci	0xd02c, 0xffffffff, 0x08421000,
7788c2ecf20Sopenharmony_ci	0xa008, 0xffffffff, 0x00010000,
7798c2ecf20Sopenharmony_ci	0x8d00, 0xffffffff, 0x100e4848,
7808c2ecf20Sopenharmony_ci	0x8d04, 0xffffffff, 0x00164745,
7818c2ecf20Sopenharmony_ci	0x8c00, 0xffffffff, 0xe4000003,
7828c2ecf20Sopenharmony_ci	0x8cf0, 0x1fffffff, 0x08e00620,
7838c2ecf20Sopenharmony_ci	0x28350, 0xffffffff, 0x00000000,
7848c2ecf20Sopenharmony_ci	0x9508, 0xffffffff, 0x00000002
7858c2ecf20Sopenharmony_ci};
7868c2ecf20Sopenharmony_ci
7878c2ecf20Sopenharmony_cistatic const u32 sumo_golden_registers[] =
7888c2ecf20Sopenharmony_ci{
7898c2ecf20Sopenharmony_ci	0x900c, 0x00ffffff, 0x0017071f,
7908c2ecf20Sopenharmony_ci	0x8c18, 0xffffffff, 0x10101060,
7918c2ecf20Sopenharmony_ci	0x8c1c, 0xffffffff, 0x00001010,
7928c2ecf20Sopenharmony_ci	0x8c30, 0x0000000f, 0x00000005,
7938c2ecf20Sopenharmony_ci	0x9688, 0x0000000f, 0x00000007
7948c2ecf20Sopenharmony_ci};
7958c2ecf20Sopenharmony_ci
7968c2ecf20Sopenharmony_cistatic const u32 wrestler_golden_registers[] =
7978c2ecf20Sopenharmony_ci{
7988c2ecf20Sopenharmony_ci	0x5eb4, 0xffffffff, 0x00000002,
7998c2ecf20Sopenharmony_ci	0x5c4, 0xffffffff, 0x00000001,
8008c2ecf20Sopenharmony_ci	0x7030, 0xffffffff, 0x00000011,
8018c2ecf20Sopenharmony_ci	0x7c30, 0xffffffff, 0x00000011,
8028c2ecf20Sopenharmony_ci	0x6104, 0x01000300, 0x00000000,
8038c2ecf20Sopenharmony_ci	0x5bc0, 0x00300000, 0x00000000,
8048c2ecf20Sopenharmony_ci	0x918c, 0xffffffff, 0x00010006,
8058c2ecf20Sopenharmony_ci	0x91a8, 0xffffffff, 0x00010006,
8068c2ecf20Sopenharmony_ci	0x9150, 0xffffffff, 0x6e944040,
8078c2ecf20Sopenharmony_ci	0x917c, 0xffffffff, 0x00030002,
8088c2ecf20Sopenharmony_ci	0x9198, 0xffffffff, 0x00030002,
8098c2ecf20Sopenharmony_ci	0x915c, 0xffffffff, 0x00010000,
8108c2ecf20Sopenharmony_ci	0x3f90, 0xffff0000, 0xff000000,
8118c2ecf20Sopenharmony_ci	0x9178, 0xffffffff, 0x00070000,
8128c2ecf20Sopenharmony_ci	0x9194, 0xffffffff, 0x00070000,
8138c2ecf20Sopenharmony_ci	0x9148, 0xffff0000, 0xff000000,
8148c2ecf20Sopenharmony_ci	0x9190, 0xffffffff, 0x00090008,
8158c2ecf20Sopenharmony_ci	0x91ac, 0xffffffff, 0x00090008,
8168c2ecf20Sopenharmony_ci	0x3f94, 0xffff0000, 0xff000000,
8178c2ecf20Sopenharmony_ci	0x914c, 0xffff0000, 0xff000000,
8188c2ecf20Sopenharmony_ci	0x929c, 0xffffffff, 0x00000001,
8198c2ecf20Sopenharmony_ci	0x8a18, 0xffffffff, 0x00000100,
8208c2ecf20Sopenharmony_ci	0x8b28, 0xffffffff, 0x00000100,
8218c2ecf20Sopenharmony_ci	0x9144, 0xffffffff, 0x00000100,
8228c2ecf20Sopenharmony_ci	0x9b7c, 0xffffffff, 0x00000000,
8238c2ecf20Sopenharmony_ci	0x8030, 0xffffffff, 0x0000100a,
8248c2ecf20Sopenharmony_ci	0x8a14, 0xffffffff, 0x00000001,
8258c2ecf20Sopenharmony_ci	0x8b24, 0xffffffff, 0x00ff0fff,
8268c2ecf20Sopenharmony_ci	0x8b10, 0xffffffff, 0x00000000,
8278c2ecf20Sopenharmony_ci	0x28a4c, 0x06000000, 0x06000000,
8288c2ecf20Sopenharmony_ci	0x4d8, 0xffffffff, 0x00000100,
8298c2ecf20Sopenharmony_ci	0x913c, 0xffff000f, 0x0100000a,
8308c2ecf20Sopenharmony_ci	0x960c, 0xffffffff, 0x54763210,
8318c2ecf20Sopenharmony_ci	0x88c4, 0xffffffff, 0x000000c2,
8328c2ecf20Sopenharmony_ci	0x88d4, 0xffffffff, 0x00000010,
8338c2ecf20Sopenharmony_ci	0x8974, 0xffffffff, 0x00000000,
8348c2ecf20Sopenharmony_ci	0xc78, 0x00000080, 0x00000080,
8358c2ecf20Sopenharmony_ci	0x5e78, 0xffffffff, 0x001000f0,
8368c2ecf20Sopenharmony_ci	0xd02c, 0xffffffff, 0x08421000,
8378c2ecf20Sopenharmony_ci	0xa008, 0xffffffff, 0x00010000,
8388c2ecf20Sopenharmony_ci	0x8d00, 0xffffffff, 0x100e4848,
8398c2ecf20Sopenharmony_ci	0x8d04, 0xffffffff, 0x00164745,
8408c2ecf20Sopenharmony_ci	0x8c00, 0xffffffff, 0xe4000003,
8418c2ecf20Sopenharmony_ci	0x8cf0, 0x1fffffff, 0x08e00410,
8428c2ecf20Sopenharmony_ci	0x28350, 0xffffffff, 0x00000000,
8438c2ecf20Sopenharmony_ci	0x9508, 0xffffffff, 0x00000002,
8448c2ecf20Sopenharmony_ci	0x900c, 0xffffffff, 0x0017071f,
8458c2ecf20Sopenharmony_ci	0x8c18, 0xffffffff, 0x10101060,
8468c2ecf20Sopenharmony_ci	0x8c1c, 0xffffffff, 0x00001010
8478c2ecf20Sopenharmony_ci};
8488c2ecf20Sopenharmony_ci
8498c2ecf20Sopenharmony_cistatic const u32 barts_golden_registers[] =
8508c2ecf20Sopenharmony_ci{
8518c2ecf20Sopenharmony_ci	0x5eb4, 0xffffffff, 0x00000002,
8528c2ecf20Sopenharmony_ci	0x5e78, 0x8f311ff1, 0x001000f0,
8538c2ecf20Sopenharmony_ci	0x3f90, 0xffff0000, 0xff000000,
8548c2ecf20Sopenharmony_ci	0x9148, 0xffff0000, 0xff000000,
8558c2ecf20Sopenharmony_ci	0x3f94, 0xffff0000, 0xff000000,
8568c2ecf20Sopenharmony_ci	0x914c, 0xffff0000, 0xff000000,
8578c2ecf20Sopenharmony_ci	0xc78, 0x00000080, 0x00000080,
8588c2ecf20Sopenharmony_ci	0xbd4, 0x70073777, 0x00010001,
8598c2ecf20Sopenharmony_ci	0xd02c, 0xbfffff1f, 0x08421000,
8608c2ecf20Sopenharmony_ci	0xd0b8, 0x03773777, 0x02011003,
8618c2ecf20Sopenharmony_ci	0x5bc0, 0x00200000, 0x50100000,
8628c2ecf20Sopenharmony_ci	0x98f8, 0x33773777, 0x02011003,
8638c2ecf20Sopenharmony_ci	0x98fc, 0xffffffff, 0x76543210,
8648c2ecf20Sopenharmony_ci	0x7030, 0x31000311, 0x00000011,
8658c2ecf20Sopenharmony_ci	0x2f48, 0x00000007, 0x02011003,
8668c2ecf20Sopenharmony_ci	0x6b28, 0x00000010, 0x00000012,
8678c2ecf20Sopenharmony_ci	0x7728, 0x00000010, 0x00000012,
8688c2ecf20Sopenharmony_ci	0x10328, 0x00000010, 0x00000012,
8698c2ecf20Sopenharmony_ci	0x10f28, 0x00000010, 0x00000012,
8708c2ecf20Sopenharmony_ci	0x11b28, 0x00000010, 0x00000012,
8718c2ecf20Sopenharmony_ci	0x12728, 0x00000010, 0x00000012,
8728c2ecf20Sopenharmony_ci	0x240c, 0x000007ff, 0x00000380,
8738c2ecf20Sopenharmony_ci	0x8a14, 0xf000001f, 0x00000007,
8748c2ecf20Sopenharmony_ci	0x8b24, 0x3fff3fff, 0x00ff0fff,
8758c2ecf20Sopenharmony_ci	0x8b10, 0x0000ff0f, 0x00000000,
8768c2ecf20Sopenharmony_ci	0x28a4c, 0x07ffffff, 0x06000000,
8778c2ecf20Sopenharmony_ci	0x10c, 0x00000001, 0x00010003,
8788c2ecf20Sopenharmony_ci	0xa02c, 0xffffffff, 0x0000009b,
8798c2ecf20Sopenharmony_ci	0x913c, 0x0000000f, 0x0100000a,
8808c2ecf20Sopenharmony_ci	0x8d00, 0xffff7f7f, 0x100e4848,
8818c2ecf20Sopenharmony_ci	0x8d04, 0x00ffffff, 0x00164745,
8828c2ecf20Sopenharmony_ci	0x8c00, 0xfffc0003, 0xe4000003,
8838c2ecf20Sopenharmony_ci	0x8c04, 0xf8ff00ff, 0x40600060,
8848c2ecf20Sopenharmony_ci	0x8c08, 0x00ff00ff, 0x001c001c,
8858c2ecf20Sopenharmony_ci	0x8cf0, 0x1fff1fff, 0x08e00620,
8868c2ecf20Sopenharmony_ci	0x8c20, 0x0fff0fff, 0x00800080,
8878c2ecf20Sopenharmony_ci	0x8c24, 0x0fff0fff, 0x00800080,
8888c2ecf20Sopenharmony_ci	0x8c18, 0xffffffff, 0x20202078,
8898c2ecf20Sopenharmony_ci	0x8c1c, 0x0000ffff, 0x00001010,
8908c2ecf20Sopenharmony_ci	0x28350, 0x00000f01, 0x00000000,
8918c2ecf20Sopenharmony_ci	0x9508, 0x3700001f, 0x00000002,
8928c2ecf20Sopenharmony_ci	0x960c, 0xffffffff, 0x54763210,
8938c2ecf20Sopenharmony_ci	0x88c4, 0x001f3ae3, 0x000000c2,
8948c2ecf20Sopenharmony_ci	0x88d4, 0x0000001f, 0x00000010,
8958c2ecf20Sopenharmony_ci	0x8974, 0xffffffff, 0x00000000
8968c2ecf20Sopenharmony_ci};
8978c2ecf20Sopenharmony_ci
8988c2ecf20Sopenharmony_cistatic const u32 turks_golden_registers[] =
8998c2ecf20Sopenharmony_ci{
9008c2ecf20Sopenharmony_ci	0x5eb4, 0xffffffff, 0x00000002,
9018c2ecf20Sopenharmony_ci	0x5e78, 0x8f311ff1, 0x001000f0,
9028c2ecf20Sopenharmony_ci	0x8c8, 0x00003000, 0x00001070,
9038c2ecf20Sopenharmony_ci	0x8cc, 0x000fffff, 0x00040035,
9048c2ecf20Sopenharmony_ci	0x3f90, 0xffff0000, 0xfff00000,
9058c2ecf20Sopenharmony_ci	0x9148, 0xffff0000, 0xfff00000,
9068c2ecf20Sopenharmony_ci	0x3f94, 0xffff0000, 0xfff00000,
9078c2ecf20Sopenharmony_ci	0x914c, 0xffff0000, 0xfff00000,
9088c2ecf20Sopenharmony_ci	0xc78, 0x00000080, 0x00000080,
9098c2ecf20Sopenharmony_ci	0xbd4, 0x00073007, 0x00010002,
9108c2ecf20Sopenharmony_ci	0xd02c, 0xbfffff1f, 0x08421000,
9118c2ecf20Sopenharmony_ci	0xd0b8, 0x03773777, 0x02010002,
9128c2ecf20Sopenharmony_ci	0x5bc0, 0x00200000, 0x50100000,
9138c2ecf20Sopenharmony_ci	0x98f8, 0x33773777, 0x00010002,
9148c2ecf20Sopenharmony_ci	0x98fc, 0xffffffff, 0x33221100,
9158c2ecf20Sopenharmony_ci	0x7030, 0x31000311, 0x00000011,
9168c2ecf20Sopenharmony_ci	0x2f48, 0x33773777, 0x00010002,
9178c2ecf20Sopenharmony_ci	0x6b28, 0x00000010, 0x00000012,
9188c2ecf20Sopenharmony_ci	0x7728, 0x00000010, 0x00000012,
9198c2ecf20Sopenharmony_ci	0x10328, 0x00000010, 0x00000012,
9208c2ecf20Sopenharmony_ci	0x10f28, 0x00000010, 0x00000012,
9218c2ecf20Sopenharmony_ci	0x11b28, 0x00000010, 0x00000012,
9228c2ecf20Sopenharmony_ci	0x12728, 0x00000010, 0x00000012,
9238c2ecf20Sopenharmony_ci	0x240c, 0x000007ff, 0x00000380,
9248c2ecf20Sopenharmony_ci	0x8a14, 0xf000001f, 0x00000007,
9258c2ecf20Sopenharmony_ci	0x8b24, 0x3fff3fff, 0x00ff0fff,
9268c2ecf20Sopenharmony_ci	0x8b10, 0x0000ff0f, 0x00000000,
9278c2ecf20Sopenharmony_ci	0x28a4c, 0x07ffffff, 0x06000000,
9288c2ecf20Sopenharmony_ci	0x10c, 0x00000001, 0x00010003,
9298c2ecf20Sopenharmony_ci	0xa02c, 0xffffffff, 0x0000009b,
9308c2ecf20Sopenharmony_ci	0x913c, 0x0000000f, 0x0100000a,
9318c2ecf20Sopenharmony_ci	0x8d00, 0xffff7f7f, 0x100e4848,
9328c2ecf20Sopenharmony_ci	0x8d04, 0x00ffffff, 0x00164745,
9338c2ecf20Sopenharmony_ci	0x8c00, 0xfffc0003, 0xe4000003,
9348c2ecf20Sopenharmony_ci	0x8c04, 0xf8ff00ff, 0x40600060,
9358c2ecf20Sopenharmony_ci	0x8c08, 0x00ff00ff, 0x001c001c,
9368c2ecf20Sopenharmony_ci	0x8cf0, 0x1fff1fff, 0x08e00410,
9378c2ecf20Sopenharmony_ci	0x8c20, 0x0fff0fff, 0x00800080,
9388c2ecf20Sopenharmony_ci	0x8c24, 0x0fff0fff, 0x00800080,
9398c2ecf20Sopenharmony_ci	0x8c18, 0xffffffff, 0x20202078,
9408c2ecf20Sopenharmony_ci	0x8c1c, 0x0000ffff, 0x00001010,
9418c2ecf20Sopenharmony_ci	0x28350, 0x00000f01, 0x00000000,
9428c2ecf20Sopenharmony_ci	0x9508, 0x3700001f, 0x00000002,
9438c2ecf20Sopenharmony_ci	0x960c, 0xffffffff, 0x54763210,
9448c2ecf20Sopenharmony_ci	0x88c4, 0x001f3ae3, 0x000000c2,
9458c2ecf20Sopenharmony_ci	0x88d4, 0x0000001f, 0x00000010,
9468c2ecf20Sopenharmony_ci	0x8974, 0xffffffff, 0x00000000
9478c2ecf20Sopenharmony_ci};
9488c2ecf20Sopenharmony_ci
9498c2ecf20Sopenharmony_cistatic const u32 caicos_golden_registers[] =
9508c2ecf20Sopenharmony_ci{
9518c2ecf20Sopenharmony_ci	0x5eb4, 0xffffffff, 0x00000002,
9528c2ecf20Sopenharmony_ci	0x5e78, 0x8f311ff1, 0x001000f0,
9538c2ecf20Sopenharmony_ci	0x8c8, 0x00003420, 0x00001450,
9548c2ecf20Sopenharmony_ci	0x8cc, 0x000fffff, 0x00040035,
9558c2ecf20Sopenharmony_ci	0x3f90, 0xffff0000, 0xfffc0000,
9568c2ecf20Sopenharmony_ci	0x9148, 0xffff0000, 0xfffc0000,
9578c2ecf20Sopenharmony_ci	0x3f94, 0xffff0000, 0xfffc0000,
9588c2ecf20Sopenharmony_ci	0x914c, 0xffff0000, 0xfffc0000,
9598c2ecf20Sopenharmony_ci	0xc78, 0x00000080, 0x00000080,
9608c2ecf20Sopenharmony_ci	0xbd4, 0x00073007, 0x00010001,
9618c2ecf20Sopenharmony_ci	0xd02c, 0xbfffff1f, 0x08421000,
9628c2ecf20Sopenharmony_ci	0xd0b8, 0x03773777, 0x02010001,
9638c2ecf20Sopenharmony_ci	0x5bc0, 0x00200000, 0x50100000,
9648c2ecf20Sopenharmony_ci	0x98f8, 0x33773777, 0x02010001,
9658c2ecf20Sopenharmony_ci	0x98fc, 0xffffffff, 0x33221100,
9668c2ecf20Sopenharmony_ci	0x7030, 0x31000311, 0x00000011,
9678c2ecf20Sopenharmony_ci	0x2f48, 0x33773777, 0x02010001,
9688c2ecf20Sopenharmony_ci	0x6b28, 0x00000010, 0x00000012,
9698c2ecf20Sopenharmony_ci	0x7728, 0x00000010, 0x00000012,
9708c2ecf20Sopenharmony_ci	0x10328, 0x00000010, 0x00000012,
9718c2ecf20Sopenharmony_ci	0x10f28, 0x00000010, 0x00000012,
9728c2ecf20Sopenharmony_ci	0x11b28, 0x00000010, 0x00000012,
9738c2ecf20Sopenharmony_ci	0x12728, 0x00000010, 0x00000012,
9748c2ecf20Sopenharmony_ci	0x240c, 0x000007ff, 0x00000380,
9758c2ecf20Sopenharmony_ci	0x8a14, 0xf000001f, 0x00000001,
9768c2ecf20Sopenharmony_ci	0x8b24, 0x3fff3fff, 0x00ff0fff,
9778c2ecf20Sopenharmony_ci	0x8b10, 0x0000ff0f, 0x00000000,
9788c2ecf20Sopenharmony_ci	0x28a4c, 0x07ffffff, 0x06000000,
9798c2ecf20Sopenharmony_ci	0x10c, 0x00000001, 0x00010003,
9808c2ecf20Sopenharmony_ci	0xa02c, 0xffffffff, 0x0000009b,
9818c2ecf20Sopenharmony_ci	0x913c, 0x0000000f, 0x0100000a,
9828c2ecf20Sopenharmony_ci	0x8d00, 0xffff7f7f, 0x100e4848,
9838c2ecf20Sopenharmony_ci	0x8d04, 0x00ffffff, 0x00164745,
9848c2ecf20Sopenharmony_ci	0x8c00, 0xfffc0003, 0xe4000003,
9858c2ecf20Sopenharmony_ci	0x8c04, 0xf8ff00ff, 0x40600060,
9868c2ecf20Sopenharmony_ci	0x8c08, 0x00ff00ff, 0x001c001c,
9878c2ecf20Sopenharmony_ci	0x8cf0, 0x1fff1fff, 0x08e00410,
9888c2ecf20Sopenharmony_ci	0x8c20, 0x0fff0fff, 0x00800080,
9898c2ecf20Sopenharmony_ci	0x8c24, 0x0fff0fff, 0x00800080,
9908c2ecf20Sopenharmony_ci	0x8c18, 0xffffffff, 0x20202078,
9918c2ecf20Sopenharmony_ci	0x8c1c, 0x0000ffff, 0x00001010,
9928c2ecf20Sopenharmony_ci	0x28350, 0x00000f01, 0x00000000,
9938c2ecf20Sopenharmony_ci	0x9508, 0x3700001f, 0x00000002,
9948c2ecf20Sopenharmony_ci	0x960c, 0xffffffff, 0x54763210,
9958c2ecf20Sopenharmony_ci	0x88c4, 0x001f3ae3, 0x000000c2,
9968c2ecf20Sopenharmony_ci	0x88d4, 0x0000001f, 0x00000010,
9978c2ecf20Sopenharmony_ci	0x8974, 0xffffffff, 0x00000000
9988c2ecf20Sopenharmony_ci};
9998c2ecf20Sopenharmony_ci
10008c2ecf20Sopenharmony_cistatic void evergreen_init_golden_registers(struct radeon_device *rdev)
10018c2ecf20Sopenharmony_ci{
10028c2ecf20Sopenharmony_ci	switch (rdev->family) {
10038c2ecf20Sopenharmony_ci	case CHIP_CYPRESS:
10048c2ecf20Sopenharmony_ci	case CHIP_HEMLOCK:
10058c2ecf20Sopenharmony_ci		radeon_program_register_sequence(rdev,
10068c2ecf20Sopenharmony_ci						 evergreen_golden_registers,
10078c2ecf20Sopenharmony_ci						 (const u32)ARRAY_SIZE(evergreen_golden_registers));
10088c2ecf20Sopenharmony_ci		radeon_program_register_sequence(rdev,
10098c2ecf20Sopenharmony_ci						 evergreen_golden_registers2,
10108c2ecf20Sopenharmony_ci						 (const u32)ARRAY_SIZE(evergreen_golden_registers2));
10118c2ecf20Sopenharmony_ci		radeon_program_register_sequence(rdev,
10128c2ecf20Sopenharmony_ci						 cypress_mgcg_init,
10138c2ecf20Sopenharmony_ci						 (const u32)ARRAY_SIZE(cypress_mgcg_init));
10148c2ecf20Sopenharmony_ci		break;
10158c2ecf20Sopenharmony_ci	case CHIP_JUNIPER:
10168c2ecf20Sopenharmony_ci		radeon_program_register_sequence(rdev,
10178c2ecf20Sopenharmony_ci						 evergreen_golden_registers,
10188c2ecf20Sopenharmony_ci						 (const u32)ARRAY_SIZE(evergreen_golden_registers));
10198c2ecf20Sopenharmony_ci		radeon_program_register_sequence(rdev,
10208c2ecf20Sopenharmony_ci						 evergreen_golden_registers2,
10218c2ecf20Sopenharmony_ci						 (const u32)ARRAY_SIZE(evergreen_golden_registers2));
10228c2ecf20Sopenharmony_ci		radeon_program_register_sequence(rdev,
10238c2ecf20Sopenharmony_ci						 juniper_mgcg_init,
10248c2ecf20Sopenharmony_ci						 (const u32)ARRAY_SIZE(juniper_mgcg_init));
10258c2ecf20Sopenharmony_ci		break;
10268c2ecf20Sopenharmony_ci	case CHIP_REDWOOD:
10278c2ecf20Sopenharmony_ci		radeon_program_register_sequence(rdev,
10288c2ecf20Sopenharmony_ci						 evergreen_golden_registers,
10298c2ecf20Sopenharmony_ci						 (const u32)ARRAY_SIZE(evergreen_golden_registers));
10308c2ecf20Sopenharmony_ci		radeon_program_register_sequence(rdev,
10318c2ecf20Sopenharmony_ci						 evergreen_golden_registers2,
10328c2ecf20Sopenharmony_ci						 (const u32)ARRAY_SIZE(evergreen_golden_registers2));
10338c2ecf20Sopenharmony_ci		radeon_program_register_sequence(rdev,
10348c2ecf20Sopenharmony_ci						 redwood_mgcg_init,
10358c2ecf20Sopenharmony_ci						 (const u32)ARRAY_SIZE(redwood_mgcg_init));
10368c2ecf20Sopenharmony_ci		break;
10378c2ecf20Sopenharmony_ci	case CHIP_CEDAR:
10388c2ecf20Sopenharmony_ci		radeon_program_register_sequence(rdev,
10398c2ecf20Sopenharmony_ci						 cedar_golden_registers,
10408c2ecf20Sopenharmony_ci						 (const u32)ARRAY_SIZE(cedar_golden_registers));
10418c2ecf20Sopenharmony_ci		radeon_program_register_sequence(rdev,
10428c2ecf20Sopenharmony_ci						 evergreen_golden_registers2,
10438c2ecf20Sopenharmony_ci						 (const u32)ARRAY_SIZE(evergreen_golden_registers2));
10448c2ecf20Sopenharmony_ci		radeon_program_register_sequence(rdev,
10458c2ecf20Sopenharmony_ci						 cedar_mgcg_init,
10468c2ecf20Sopenharmony_ci						 (const u32)ARRAY_SIZE(cedar_mgcg_init));
10478c2ecf20Sopenharmony_ci		break;
10488c2ecf20Sopenharmony_ci	case CHIP_PALM:
10498c2ecf20Sopenharmony_ci		radeon_program_register_sequence(rdev,
10508c2ecf20Sopenharmony_ci						 wrestler_golden_registers,
10518c2ecf20Sopenharmony_ci						 (const u32)ARRAY_SIZE(wrestler_golden_registers));
10528c2ecf20Sopenharmony_ci		break;
10538c2ecf20Sopenharmony_ci	case CHIP_SUMO:
10548c2ecf20Sopenharmony_ci		radeon_program_register_sequence(rdev,
10558c2ecf20Sopenharmony_ci						 supersumo_golden_registers,
10568c2ecf20Sopenharmony_ci						 (const u32)ARRAY_SIZE(supersumo_golden_registers));
10578c2ecf20Sopenharmony_ci		break;
10588c2ecf20Sopenharmony_ci	case CHIP_SUMO2:
10598c2ecf20Sopenharmony_ci		radeon_program_register_sequence(rdev,
10608c2ecf20Sopenharmony_ci						 supersumo_golden_registers,
10618c2ecf20Sopenharmony_ci						 (const u32)ARRAY_SIZE(supersumo_golden_registers));
10628c2ecf20Sopenharmony_ci		radeon_program_register_sequence(rdev,
10638c2ecf20Sopenharmony_ci						 sumo_golden_registers,
10648c2ecf20Sopenharmony_ci						 (const u32)ARRAY_SIZE(sumo_golden_registers));
10658c2ecf20Sopenharmony_ci		break;
10668c2ecf20Sopenharmony_ci	case CHIP_BARTS:
10678c2ecf20Sopenharmony_ci		radeon_program_register_sequence(rdev,
10688c2ecf20Sopenharmony_ci						 barts_golden_registers,
10698c2ecf20Sopenharmony_ci						 (const u32)ARRAY_SIZE(barts_golden_registers));
10708c2ecf20Sopenharmony_ci		break;
10718c2ecf20Sopenharmony_ci	case CHIP_TURKS:
10728c2ecf20Sopenharmony_ci		radeon_program_register_sequence(rdev,
10738c2ecf20Sopenharmony_ci						 turks_golden_registers,
10748c2ecf20Sopenharmony_ci						 (const u32)ARRAY_SIZE(turks_golden_registers));
10758c2ecf20Sopenharmony_ci		break;
10768c2ecf20Sopenharmony_ci	case CHIP_CAICOS:
10778c2ecf20Sopenharmony_ci		radeon_program_register_sequence(rdev,
10788c2ecf20Sopenharmony_ci						 caicos_golden_registers,
10798c2ecf20Sopenharmony_ci						 (const u32)ARRAY_SIZE(caicos_golden_registers));
10808c2ecf20Sopenharmony_ci		break;
10818c2ecf20Sopenharmony_ci	default:
10828c2ecf20Sopenharmony_ci		break;
10838c2ecf20Sopenharmony_ci	}
10848c2ecf20Sopenharmony_ci}
10858c2ecf20Sopenharmony_ci
10868c2ecf20Sopenharmony_ci/**
10878c2ecf20Sopenharmony_ci * evergreen_get_allowed_info_register - fetch the register for the info ioctl
10888c2ecf20Sopenharmony_ci *
10898c2ecf20Sopenharmony_ci * @rdev: radeon_device pointer
10908c2ecf20Sopenharmony_ci * @reg: register offset in bytes
10918c2ecf20Sopenharmony_ci * @val: register value
10928c2ecf20Sopenharmony_ci *
10938c2ecf20Sopenharmony_ci * Returns 0 for success or -EINVAL for an invalid register
10948c2ecf20Sopenharmony_ci *
10958c2ecf20Sopenharmony_ci */
10968c2ecf20Sopenharmony_ciint evergreen_get_allowed_info_register(struct radeon_device *rdev,
10978c2ecf20Sopenharmony_ci					u32 reg, u32 *val)
10988c2ecf20Sopenharmony_ci{
10998c2ecf20Sopenharmony_ci	switch (reg) {
11008c2ecf20Sopenharmony_ci	case GRBM_STATUS:
11018c2ecf20Sopenharmony_ci	case GRBM_STATUS_SE0:
11028c2ecf20Sopenharmony_ci	case GRBM_STATUS_SE1:
11038c2ecf20Sopenharmony_ci	case SRBM_STATUS:
11048c2ecf20Sopenharmony_ci	case SRBM_STATUS2:
11058c2ecf20Sopenharmony_ci	case DMA_STATUS_REG:
11068c2ecf20Sopenharmony_ci	case UVD_STATUS:
11078c2ecf20Sopenharmony_ci		*val = RREG32(reg);
11088c2ecf20Sopenharmony_ci		return 0;
11098c2ecf20Sopenharmony_ci	default:
11108c2ecf20Sopenharmony_ci		return -EINVAL;
11118c2ecf20Sopenharmony_ci	}
11128c2ecf20Sopenharmony_ci}
11138c2ecf20Sopenharmony_ci
11148c2ecf20Sopenharmony_civoid evergreen_tiling_fields(unsigned tiling_flags, unsigned *bankw,
11158c2ecf20Sopenharmony_ci			     unsigned *bankh, unsigned *mtaspect,
11168c2ecf20Sopenharmony_ci			     unsigned *tile_split)
11178c2ecf20Sopenharmony_ci{
11188c2ecf20Sopenharmony_ci	*bankw = (tiling_flags >> RADEON_TILING_EG_BANKW_SHIFT) & RADEON_TILING_EG_BANKW_MASK;
11198c2ecf20Sopenharmony_ci	*bankh = (tiling_flags >> RADEON_TILING_EG_BANKH_SHIFT) & RADEON_TILING_EG_BANKH_MASK;
11208c2ecf20Sopenharmony_ci	*mtaspect = (tiling_flags >> RADEON_TILING_EG_MACRO_TILE_ASPECT_SHIFT) & RADEON_TILING_EG_MACRO_TILE_ASPECT_MASK;
11218c2ecf20Sopenharmony_ci	*tile_split = (tiling_flags >> RADEON_TILING_EG_TILE_SPLIT_SHIFT) & RADEON_TILING_EG_TILE_SPLIT_MASK;
11228c2ecf20Sopenharmony_ci	switch (*bankw) {
11238c2ecf20Sopenharmony_ci	default:
11248c2ecf20Sopenharmony_ci	case 1: *bankw = EVERGREEN_ADDR_SURF_BANK_WIDTH_1; break;
11258c2ecf20Sopenharmony_ci	case 2: *bankw = EVERGREEN_ADDR_SURF_BANK_WIDTH_2; break;
11268c2ecf20Sopenharmony_ci	case 4: *bankw = EVERGREEN_ADDR_SURF_BANK_WIDTH_4; break;
11278c2ecf20Sopenharmony_ci	case 8: *bankw = EVERGREEN_ADDR_SURF_BANK_WIDTH_8; break;
11288c2ecf20Sopenharmony_ci	}
11298c2ecf20Sopenharmony_ci	switch (*bankh) {
11308c2ecf20Sopenharmony_ci	default:
11318c2ecf20Sopenharmony_ci	case 1: *bankh = EVERGREEN_ADDR_SURF_BANK_HEIGHT_1; break;
11328c2ecf20Sopenharmony_ci	case 2: *bankh = EVERGREEN_ADDR_SURF_BANK_HEIGHT_2; break;
11338c2ecf20Sopenharmony_ci	case 4: *bankh = EVERGREEN_ADDR_SURF_BANK_HEIGHT_4; break;
11348c2ecf20Sopenharmony_ci	case 8: *bankh = EVERGREEN_ADDR_SURF_BANK_HEIGHT_8; break;
11358c2ecf20Sopenharmony_ci	}
11368c2ecf20Sopenharmony_ci	switch (*mtaspect) {
11378c2ecf20Sopenharmony_ci	default:
11388c2ecf20Sopenharmony_ci	case 1: *mtaspect = EVERGREEN_ADDR_SURF_MACRO_TILE_ASPECT_1; break;
11398c2ecf20Sopenharmony_ci	case 2: *mtaspect = EVERGREEN_ADDR_SURF_MACRO_TILE_ASPECT_2; break;
11408c2ecf20Sopenharmony_ci	case 4: *mtaspect = EVERGREEN_ADDR_SURF_MACRO_TILE_ASPECT_4; break;
11418c2ecf20Sopenharmony_ci	case 8: *mtaspect = EVERGREEN_ADDR_SURF_MACRO_TILE_ASPECT_8; break;
11428c2ecf20Sopenharmony_ci	}
11438c2ecf20Sopenharmony_ci}
11448c2ecf20Sopenharmony_ci
11458c2ecf20Sopenharmony_cistatic int sumo_set_uvd_clock(struct radeon_device *rdev, u32 clock,
11468c2ecf20Sopenharmony_ci			      u32 cntl_reg, u32 status_reg)
11478c2ecf20Sopenharmony_ci{
11488c2ecf20Sopenharmony_ci	int r, i;
11498c2ecf20Sopenharmony_ci	struct atom_clock_dividers dividers;
11508c2ecf20Sopenharmony_ci
11518c2ecf20Sopenharmony_ci	r = radeon_atom_get_clock_dividers(rdev, COMPUTE_ENGINE_PLL_PARAM,
11528c2ecf20Sopenharmony_ci					   clock, false, &dividers);
11538c2ecf20Sopenharmony_ci	if (r)
11548c2ecf20Sopenharmony_ci		return r;
11558c2ecf20Sopenharmony_ci
11568c2ecf20Sopenharmony_ci	WREG32_P(cntl_reg, dividers.post_div, ~(DCLK_DIR_CNTL_EN|DCLK_DIVIDER_MASK));
11578c2ecf20Sopenharmony_ci
11588c2ecf20Sopenharmony_ci	for (i = 0; i < 100; i++) {
11598c2ecf20Sopenharmony_ci		if (RREG32(status_reg) & DCLK_STATUS)
11608c2ecf20Sopenharmony_ci			break;
11618c2ecf20Sopenharmony_ci		mdelay(10);
11628c2ecf20Sopenharmony_ci	}
11638c2ecf20Sopenharmony_ci	if (i == 100)
11648c2ecf20Sopenharmony_ci		return -ETIMEDOUT;
11658c2ecf20Sopenharmony_ci
11668c2ecf20Sopenharmony_ci	return 0;
11678c2ecf20Sopenharmony_ci}
11688c2ecf20Sopenharmony_ci
11698c2ecf20Sopenharmony_ciint sumo_set_uvd_clocks(struct radeon_device *rdev, u32 vclk, u32 dclk)
11708c2ecf20Sopenharmony_ci{
11718c2ecf20Sopenharmony_ci	int r = 0;
11728c2ecf20Sopenharmony_ci	u32 cg_scratch = RREG32(CG_SCRATCH1);
11738c2ecf20Sopenharmony_ci
11748c2ecf20Sopenharmony_ci	r = sumo_set_uvd_clock(rdev, vclk, CG_VCLK_CNTL, CG_VCLK_STATUS);
11758c2ecf20Sopenharmony_ci	if (r)
11768c2ecf20Sopenharmony_ci		goto done;
11778c2ecf20Sopenharmony_ci	cg_scratch &= 0xffff0000;
11788c2ecf20Sopenharmony_ci	cg_scratch |= vclk / 100; /* Mhz */
11798c2ecf20Sopenharmony_ci
11808c2ecf20Sopenharmony_ci	r = sumo_set_uvd_clock(rdev, dclk, CG_DCLK_CNTL, CG_DCLK_STATUS);
11818c2ecf20Sopenharmony_ci	if (r)
11828c2ecf20Sopenharmony_ci		goto done;
11838c2ecf20Sopenharmony_ci	cg_scratch &= 0x0000ffff;
11848c2ecf20Sopenharmony_ci	cg_scratch |= (dclk / 100) << 16; /* Mhz */
11858c2ecf20Sopenharmony_ci
11868c2ecf20Sopenharmony_cidone:
11878c2ecf20Sopenharmony_ci	WREG32(CG_SCRATCH1, cg_scratch);
11888c2ecf20Sopenharmony_ci
11898c2ecf20Sopenharmony_ci	return r;
11908c2ecf20Sopenharmony_ci}
11918c2ecf20Sopenharmony_ci
11928c2ecf20Sopenharmony_ciint evergreen_set_uvd_clocks(struct radeon_device *rdev, u32 vclk, u32 dclk)
11938c2ecf20Sopenharmony_ci{
11948c2ecf20Sopenharmony_ci	/* start off with something large */
11958c2ecf20Sopenharmony_ci	unsigned fb_div = 0, vclk_div = 0, dclk_div = 0;
11968c2ecf20Sopenharmony_ci	int r;
11978c2ecf20Sopenharmony_ci
11988c2ecf20Sopenharmony_ci	/* bypass vclk and dclk with bclk */
11998c2ecf20Sopenharmony_ci	WREG32_P(CG_UPLL_FUNC_CNTL_2,
12008c2ecf20Sopenharmony_ci		VCLK_SRC_SEL(1) | DCLK_SRC_SEL(1),
12018c2ecf20Sopenharmony_ci		~(VCLK_SRC_SEL_MASK | DCLK_SRC_SEL_MASK));
12028c2ecf20Sopenharmony_ci
12038c2ecf20Sopenharmony_ci	/* put PLL in bypass mode */
12048c2ecf20Sopenharmony_ci	WREG32_P(CG_UPLL_FUNC_CNTL, UPLL_BYPASS_EN_MASK, ~UPLL_BYPASS_EN_MASK);
12058c2ecf20Sopenharmony_ci
12068c2ecf20Sopenharmony_ci	if (!vclk || !dclk) {
12078c2ecf20Sopenharmony_ci		/* keep the Bypass mode, put PLL to sleep */
12088c2ecf20Sopenharmony_ci		WREG32_P(CG_UPLL_FUNC_CNTL, UPLL_SLEEP_MASK, ~UPLL_SLEEP_MASK);
12098c2ecf20Sopenharmony_ci		return 0;
12108c2ecf20Sopenharmony_ci	}
12118c2ecf20Sopenharmony_ci
12128c2ecf20Sopenharmony_ci	r = radeon_uvd_calc_upll_dividers(rdev, vclk, dclk, 125000, 250000,
12138c2ecf20Sopenharmony_ci					  16384, 0x03FFFFFF, 0, 128, 5,
12148c2ecf20Sopenharmony_ci					  &fb_div, &vclk_div, &dclk_div);
12158c2ecf20Sopenharmony_ci	if (r)
12168c2ecf20Sopenharmony_ci		return r;
12178c2ecf20Sopenharmony_ci
12188c2ecf20Sopenharmony_ci	/* set VCO_MODE to 1 */
12198c2ecf20Sopenharmony_ci	WREG32_P(CG_UPLL_FUNC_CNTL, UPLL_VCO_MODE_MASK, ~UPLL_VCO_MODE_MASK);
12208c2ecf20Sopenharmony_ci
12218c2ecf20Sopenharmony_ci	/* toggle UPLL_SLEEP to 1 then back to 0 */
12228c2ecf20Sopenharmony_ci	WREG32_P(CG_UPLL_FUNC_CNTL, UPLL_SLEEP_MASK, ~UPLL_SLEEP_MASK);
12238c2ecf20Sopenharmony_ci	WREG32_P(CG_UPLL_FUNC_CNTL, 0, ~UPLL_SLEEP_MASK);
12248c2ecf20Sopenharmony_ci
12258c2ecf20Sopenharmony_ci	/* deassert UPLL_RESET */
12268c2ecf20Sopenharmony_ci	WREG32_P(CG_UPLL_FUNC_CNTL, 0, ~UPLL_RESET_MASK);
12278c2ecf20Sopenharmony_ci
12288c2ecf20Sopenharmony_ci	mdelay(1);
12298c2ecf20Sopenharmony_ci
12308c2ecf20Sopenharmony_ci	r = radeon_uvd_send_upll_ctlreq(rdev, CG_UPLL_FUNC_CNTL);
12318c2ecf20Sopenharmony_ci	if (r)
12328c2ecf20Sopenharmony_ci		return r;
12338c2ecf20Sopenharmony_ci
12348c2ecf20Sopenharmony_ci	/* assert UPLL_RESET again */
12358c2ecf20Sopenharmony_ci	WREG32_P(CG_UPLL_FUNC_CNTL, UPLL_RESET_MASK, ~UPLL_RESET_MASK);
12368c2ecf20Sopenharmony_ci
12378c2ecf20Sopenharmony_ci	/* disable spread spectrum. */
12388c2ecf20Sopenharmony_ci	WREG32_P(CG_UPLL_SPREAD_SPECTRUM, 0, ~SSEN_MASK);
12398c2ecf20Sopenharmony_ci
12408c2ecf20Sopenharmony_ci	/* set feedback divider */
12418c2ecf20Sopenharmony_ci	WREG32_P(CG_UPLL_FUNC_CNTL_3, UPLL_FB_DIV(fb_div), ~UPLL_FB_DIV_MASK);
12428c2ecf20Sopenharmony_ci
12438c2ecf20Sopenharmony_ci	/* set ref divider to 0 */
12448c2ecf20Sopenharmony_ci	WREG32_P(CG_UPLL_FUNC_CNTL, 0, ~UPLL_REF_DIV_MASK);
12458c2ecf20Sopenharmony_ci
12468c2ecf20Sopenharmony_ci	if (fb_div < 307200)
12478c2ecf20Sopenharmony_ci		WREG32_P(CG_UPLL_FUNC_CNTL_4, 0, ~UPLL_SPARE_ISPARE9);
12488c2ecf20Sopenharmony_ci	else
12498c2ecf20Sopenharmony_ci		WREG32_P(CG_UPLL_FUNC_CNTL_4, UPLL_SPARE_ISPARE9, ~UPLL_SPARE_ISPARE9);
12508c2ecf20Sopenharmony_ci
12518c2ecf20Sopenharmony_ci	/* set PDIV_A and PDIV_B */
12528c2ecf20Sopenharmony_ci	WREG32_P(CG_UPLL_FUNC_CNTL_2,
12538c2ecf20Sopenharmony_ci		UPLL_PDIV_A(vclk_div) | UPLL_PDIV_B(dclk_div),
12548c2ecf20Sopenharmony_ci		~(UPLL_PDIV_A_MASK | UPLL_PDIV_B_MASK));
12558c2ecf20Sopenharmony_ci
12568c2ecf20Sopenharmony_ci	/* give the PLL some time to settle */
12578c2ecf20Sopenharmony_ci	mdelay(15);
12588c2ecf20Sopenharmony_ci
12598c2ecf20Sopenharmony_ci	/* deassert PLL_RESET */
12608c2ecf20Sopenharmony_ci	WREG32_P(CG_UPLL_FUNC_CNTL, 0, ~UPLL_RESET_MASK);
12618c2ecf20Sopenharmony_ci
12628c2ecf20Sopenharmony_ci	mdelay(15);
12638c2ecf20Sopenharmony_ci
12648c2ecf20Sopenharmony_ci	/* switch from bypass mode to normal mode */
12658c2ecf20Sopenharmony_ci	WREG32_P(CG_UPLL_FUNC_CNTL, 0, ~UPLL_BYPASS_EN_MASK);
12668c2ecf20Sopenharmony_ci
12678c2ecf20Sopenharmony_ci	r = radeon_uvd_send_upll_ctlreq(rdev, CG_UPLL_FUNC_CNTL);
12688c2ecf20Sopenharmony_ci	if (r)
12698c2ecf20Sopenharmony_ci		return r;
12708c2ecf20Sopenharmony_ci
12718c2ecf20Sopenharmony_ci	/* switch VCLK and DCLK selection */
12728c2ecf20Sopenharmony_ci	WREG32_P(CG_UPLL_FUNC_CNTL_2,
12738c2ecf20Sopenharmony_ci		VCLK_SRC_SEL(2) | DCLK_SRC_SEL(2),
12748c2ecf20Sopenharmony_ci		~(VCLK_SRC_SEL_MASK | DCLK_SRC_SEL_MASK));
12758c2ecf20Sopenharmony_ci
12768c2ecf20Sopenharmony_ci	mdelay(100);
12778c2ecf20Sopenharmony_ci
12788c2ecf20Sopenharmony_ci	return 0;
12798c2ecf20Sopenharmony_ci}
12808c2ecf20Sopenharmony_ci
12818c2ecf20Sopenharmony_civoid evergreen_fix_pci_max_read_req_size(struct radeon_device *rdev)
12828c2ecf20Sopenharmony_ci{
12838c2ecf20Sopenharmony_ci	int readrq;
12848c2ecf20Sopenharmony_ci	u16 v;
12858c2ecf20Sopenharmony_ci
12868c2ecf20Sopenharmony_ci	readrq = pcie_get_readrq(rdev->pdev);
12878c2ecf20Sopenharmony_ci	v = ffs(readrq) - 8;
12888c2ecf20Sopenharmony_ci	/* if bios or OS sets MAX_READ_REQUEST_SIZE to an invalid value, fix it
12898c2ecf20Sopenharmony_ci	 * to avoid hangs or perfomance issues
12908c2ecf20Sopenharmony_ci	 */
12918c2ecf20Sopenharmony_ci	if ((v == 0) || (v == 6) || (v == 7))
12928c2ecf20Sopenharmony_ci		pcie_set_readrq(rdev->pdev, 512);
12938c2ecf20Sopenharmony_ci}
12948c2ecf20Sopenharmony_ci
12958c2ecf20Sopenharmony_civoid dce4_program_fmt(struct drm_encoder *encoder)
12968c2ecf20Sopenharmony_ci{
12978c2ecf20Sopenharmony_ci	struct drm_device *dev = encoder->dev;
12988c2ecf20Sopenharmony_ci	struct radeon_device *rdev = dev->dev_private;
12998c2ecf20Sopenharmony_ci	struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
13008c2ecf20Sopenharmony_ci	struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc);
13018c2ecf20Sopenharmony_ci	struct drm_connector *connector = radeon_get_connector_for_encoder(encoder);
13028c2ecf20Sopenharmony_ci	int bpc = 0;
13038c2ecf20Sopenharmony_ci	u32 tmp = 0;
13048c2ecf20Sopenharmony_ci	enum radeon_connector_dither dither = RADEON_FMT_DITHER_DISABLE;
13058c2ecf20Sopenharmony_ci
13068c2ecf20Sopenharmony_ci	if (connector) {
13078c2ecf20Sopenharmony_ci		struct radeon_connector *radeon_connector = to_radeon_connector(connector);
13088c2ecf20Sopenharmony_ci		bpc = radeon_get_monitor_bpc(connector);
13098c2ecf20Sopenharmony_ci		dither = radeon_connector->dither;
13108c2ecf20Sopenharmony_ci	}
13118c2ecf20Sopenharmony_ci
13128c2ecf20Sopenharmony_ci	/* LVDS/eDP FMT is set up by atom */
13138c2ecf20Sopenharmony_ci	if (radeon_encoder->devices & ATOM_DEVICE_LCD_SUPPORT)
13148c2ecf20Sopenharmony_ci		return;
13158c2ecf20Sopenharmony_ci
13168c2ecf20Sopenharmony_ci	/* not needed for analog */
13178c2ecf20Sopenharmony_ci	if ((radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1) ||
13188c2ecf20Sopenharmony_ci	    (radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2))
13198c2ecf20Sopenharmony_ci		return;
13208c2ecf20Sopenharmony_ci
13218c2ecf20Sopenharmony_ci	if (bpc == 0)
13228c2ecf20Sopenharmony_ci		return;
13238c2ecf20Sopenharmony_ci
13248c2ecf20Sopenharmony_ci	switch (bpc) {
13258c2ecf20Sopenharmony_ci	case 6:
13268c2ecf20Sopenharmony_ci		if (dither == RADEON_FMT_DITHER_ENABLE)
13278c2ecf20Sopenharmony_ci			/* XXX sort out optimal dither settings */
13288c2ecf20Sopenharmony_ci			tmp |= (FMT_FRAME_RANDOM_ENABLE | FMT_HIGHPASS_RANDOM_ENABLE |
13298c2ecf20Sopenharmony_ci				FMT_SPATIAL_DITHER_EN);
13308c2ecf20Sopenharmony_ci		else
13318c2ecf20Sopenharmony_ci			tmp |= FMT_TRUNCATE_EN;
13328c2ecf20Sopenharmony_ci		break;
13338c2ecf20Sopenharmony_ci	case 8:
13348c2ecf20Sopenharmony_ci		if (dither == RADEON_FMT_DITHER_ENABLE)
13358c2ecf20Sopenharmony_ci			/* XXX sort out optimal dither settings */
13368c2ecf20Sopenharmony_ci			tmp |= (FMT_FRAME_RANDOM_ENABLE | FMT_HIGHPASS_RANDOM_ENABLE |
13378c2ecf20Sopenharmony_ci				FMT_RGB_RANDOM_ENABLE |
13388c2ecf20Sopenharmony_ci				FMT_SPATIAL_DITHER_EN | FMT_SPATIAL_DITHER_DEPTH);
13398c2ecf20Sopenharmony_ci		else
13408c2ecf20Sopenharmony_ci			tmp |= (FMT_TRUNCATE_EN | FMT_TRUNCATE_DEPTH);
13418c2ecf20Sopenharmony_ci		break;
13428c2ecf20Sopenharmony_ci	case 10:
13438c2ecf20Sopenharmony_ci	default:
13448c2ecf20Sopenharmony_ci		/* not needed */
13458c2ecf20Sopenharmony_ci		break;
13468c2ecf20Sopenharmony_ci	}
13478c2ecf20Sopenharmony_ci
13488c2ecf20Sopenharmony_ci	WREG32(FMT_BIT_DEPTH_CONTROL + radeon_crtc->crtc_offset, tmp);
13498c2ecf20Sopenharmony_ci}
13508c2ecf20Sopenharmony_ci
13518c2ecf20Sopenharmony_cistatic bool dce4_is_in_vblank(struct radeon_device *rdev, int crtc)
13528c2ecf20Sopenharmony_ci{
13538c2ecf20Sopenharmony_ci	if (RREG32(EVERGREEN_CRTC_STATUS + crtc_offsets[crtc]) & EVERGREEN_CRTC_V_BLANK)
13548c2ecf20Sopenharmony_ci		return true;
13558c2ecf20Sopenharmony_ci	else
13568c2ecf20Sopenharmony_ci		return false;
13578c2ecf20Sopenharmony_ci}
13588c2ecf20Sopenharmony_ci
13598c2ecf20Sopenharmony_cistatic bool dce4_is_counter_moving(struct radeon_device *rdev, int crtc)
13608c2ecf20Sopenharmony_ci{
13618c2ecf20Sopenharmony_ci	u32 pos1, pos2;
13628c2ecf20Sopenharmony_ci
13638c2ecf20Sopenharmony_ci	pos1 = RREG32(EVERGREEN_CRTC_STATUS_POSITION + crtc_offsets[crtc]);
13648c2ecf20Sopenharmony_ci	pos2 = RREG32(EVERGREEN_CRTC_STATUS_POSITION + crtc_offsets[crtc]);
13658c2ecf20Sopenharmony_ci
13668c2ecf20Sopenharmony_ci	if (pos1 != pos2)
13678c2ecf20Sopenharmony_ci		return true;
13688c2ecf20Sopenharmony_ci	else
13698c2ecf20Sopenharmony_ci		return false;
13708c2ecf20Sopenharmony_ci}
13718c2ecf20Sopenharmony_ci
13728c2ecf20Sopenharmony_ci/**
13738c2ecf20Sopenharmony_ci * dce4_wait_for_vblank - vblank wait asic callback.
13748c2ecf20Sopenharmony_ci *
13758c2ecf20Sopenharmony_ci * @rdev: radeon_device pointer
13768c2ecf20Sopenharmony_ci * @crtc: crtc to wait for vblank on
13778c2ecf20Sopenharmony_ci *
13788c2ecf20Sopenharmony_ci * Wait for vblank on the requested crtc (evergreen+).
13798c2ecf20Sopenharmony_ci */
13808c2ecf20Sopenharmony_civoid dce4_wait_for_vblank(struct radeon_device *rdev, int crtc)
13818c2ecf20Sopenharmony_ci{
13828c2ecf20Sopenharmony_ci	unsigned i = 0;
13838c2ecf20Sopenharmony_ci
13848c2ecf20Sopenharmony_ci	if (crtc >= rdev->num_crtc)
13858c2ecf20Sopenharmony_ci		return;
13868c2ecf20Sopenharmony_ci
13878c2ecf20Sopenharmony_ci	if (!(RREG32(EVERGREEN_CRTC_CONTROL + crtc_offsets[crtc]) & EVERGREEN_CRTC_MASTER_EN))
13888c2ecf20Sopenharmony_ci		return;
13898c2ecf20Sopenharmony_ci
13908c2ecf20Sopenharmony_ci	/* depending on when we hit vblank, we may be close to active; if so,
13918c2ecf20Sopenharmony_ci	 * wait for another frame.
13928c2ecf20Sopenharmony_ci	 */
13938c2ecf20Sopenharmony_ci	while (dce4_is_in_vblank(rdev, crtc)) {
13948c2ecf20Sopenharmony_ci		if (i++ % 100 == 0) {
13958c2ecf20Sopenharmony_ci			if (!dce4_is_counter_moving(rdev, crtc))
13968c2ecf20Sopenharmony_ci				break;
13978c2ecf20Sopenharmony_ci		}
13988c2ecf20Sopenharmony_ci	}
13998c2ecf20Sopenharmony_ci
14008c2ecf20Sopenharmony_ci	while (!dce4_is_in_vblank(rdev, crtc)) {
14018c2ecf20Sopenharmony_ci		if (i++ % 100 == 0) {
14028c2ecf20Sopenharmony_ci			if (!dce4_is_counter_moving(rdev, crtc))
14038c2ecf20Sopenharmony_ci				break;
14048c2ecf20Sopenharmony_ci		}
14058c2ecf20Sopenharmony_ci	}
14068c2ecf20Sopenharmony_ci}
14078c2ecf20Sopenharmony_ci
14088c2ecf20Sopenharmony_ci/**
14098c2ecf20Sopenharmony_ci * evergreen_page_flip - pageflip callback.
14108c2ecf20Sopenharmony_ci *
14118c2ecf20Sopenharmony_ci * @rdev: radeon_device pointer
14128c2ecf20Sopenharmony_ci * @crtc_id: crtc to cleanup pageflip on
14138c2ecf20Sopenharmony_ci * @crtc_base: new address of the crtc (GPU MC address)
14148c2ecf20Sopenharmony_ci *
14158c2ecf20Sopenharmony_ci * Triggers the actual pageflip by updating the primary
14168c2ecf20Sopenharmony_ci * surface base address (evergreen+).
14178c2ecf20Sopenharmony_ci */
14188c2ecf20Sopenharmony_civoid evergreen_page_flip(struct radeon_device *rdev, int crtc_id, u64 crtc_base,
14198c2ecf20Sopenharmony_ci			 bool async)
14208c2ecf20Sopenharmony_ci{
14218c2ecf20Sopenharmony_ci	struct radeon_crtc *radeon_crtc = rdev->mode_info.crtcs[crtc_id];
14228c2ecf20Sopenharmony_ci
14238c2ecf20Sopenharmony_ci	/* update the scanout addresses */
14248c2ecf20Sopenharmony_ci	WREG32(EVERGREEN_GRPH_FLIP_CONTROL + radeon_crtc->crtc_offset,
14258c2ecf20Sopenharmony_ci	       async ? EVERGREEN_GRPH_SURFACE_UPDATE_H_RETRACE_EN : 0);
14268c2ecf20Sopenharmony_ci	WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH + radeon_crtc->crtc_offset,
14278c2ecf20Sopenharmony_ci	       upper_32_bits(crtc_base));
14288c2ecf20Sopenharmony_ci	WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS + radeon_crtc->crtc_offset,
14298c2ecf20Sopenharmony_ci	       (u32)crtc_base);
14308c2ecf20Sopenharmony_ci	/* post the write */
14318c2ecf20Sopenharmony_ci	RREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS + radeon_crtc->crtc_offset);
14328c2ecf20Sopenharmony_ci}
14338c2ecf20Sopenharmony_ci
14348c2ecf20Sopenharmony_ci/**
14358c2ecf20Sopenharmony_ci * evergreen_page_flip_pending - check if page flip is still pending
14368c2ecf20Sopenharmony_ci *
14378c2ecf20Sopenharmony_ci * @rdev: radeon_device pointer
14388c2ecf20Sopenharmony_ci * @crtc_id: crtc to check
14398c2ecf20Sopenharmony_ci *
14408c2ecf20Sopenharmony_ci * Returns the current update pending status.
14418c2ecf20Sopenharmony_ci */
14428c2ecf20Sopenharmony_cibool evergreen_page_flip_pending(struct radeon_device *rdev, int crtc_id)
14438c2ecf20Sopenharmony_ci{
14448c2ecf20Sopenharmony_ci	struct radeon_crtc *radeon_crtc = rdev->mode_info.crtcs[crtc_id];
14458c2ecf20Sopenharmony_ci
14468c2ecf20Sopenharmony_ci	/* Return current update_pending status: */
14478c2ecf20Sopenharmony_ci	return !!(RREG32(EVERGREEN_GRPH_UPDATE + radeon_crtc->crtc_offset) &
14488c2ecf20Sopenharmony_ci		EVERGREEN_GRPH_SURFACE_UPDATE_PENDING);
14498c2ecf20Sopenharmony_ci}
14508c2ecf20Sopenharmony_ci
14518c2ecf20Sopenharmony_ci/* get temperature in millidegrees */
14528c2ecf20Sopenharmony_ciint evergreen_get_temp(struct radeon_device *rdev)
14538c2ecf20Sopenharmony_ci{
14548c2ecf20Sopenharmony_ci	u32 temp, toffset;
14558c2ecf20Sopenharmony_ci	int actual_temp = 0;
14568c2ecf20Sopenharmony_ci
14578c2ecf20Sopenharmony_ci	if (rdev->family == CHIP_JUNIPER) {
14588c2ecf20Sopenharmony_ci		toffset = (RREG32(CG_THERMAL_CTRL) & TOFFSET_MASK) >>
14598c2ecf20Sopenharmony_ci			TOFFSET_SHIFT;
14608c2ecf20Sopenharmony_ci		temp = (RREG32(CG_TS0_STATUS) & TS0_ADC_DOUT_MASK) >>
14618c2ecf20Sopenharmony_ci			TS0_ADC_DOUT_SHIFT;
14628c2ecf20Sopenharmony_ci
14638c2ecf20Sopenharmony_ci		if (toffset & 0x100)
14648c2ecf20Sopenharmony_ci			actual_temp = temp / 2 - (0x200 - toffset);
14658c2ecf20Sopenharmony_ci		else
14668c2ecf20Sopenharmony_ci			actual_temp = temp / 2 + toffset;
14678c2ecf20Sopenharmony_ci
14688c2ecf20Sopenharmony_ci		actual_temp = actual_temp * 1000;
14698c2ecf20Sopenharmony_ci
14708c2ecf20Sopenharmony_ci	} else {
14718c2ecf20Sopenharmony_ci		temp = (RREG32(CG_MULT_THERMAL_STATUS) & ASIC_T_MASK) >>
14728c2ecf20Sopenharmony_ci			ASIC_T_SHIFT;
14738c2ecf20Sopenharmony_ci
14748c2ecf20Sopenharmony_ci		if (temp & 0x400)
14758c2ecf20Sopenharmony_ci			actual_temp = -256;
14768c2ecf20Sopenharmony_ci		else if (temp & 0x200)
14778c2ecf20Sopenharmony_ci			actual_temp = 255;
14788c2ecf20Sopenharmony_ci		else if (temp & 0x100) {
14798c2ecf20Sopenharmony_ci			actual_temp = temp & 0x1ff;
14808c2ecf20Sopenharmony_ci			actual_temp |= ~0x1ff;
14818c2ecf20Sopenharmony_ci		} else
14828c2ecf20Sopenharmony_ci			actual_temp = temp & 0xff;
14838c2ecf20Sopenharmony_ci
14848c2ecf20Sopenharmony_ci		actual_temp = (actual_temp * 1000) / 2;
14858c2ecf20Sopenharmony_ci	}
14868c2ecf20Sopenharmony_ci
14878c2ecf20Sopenharmony_ci	return actual_temp;
14888c2ecf20Sopenharmony_ci}
14898c2ecf20Sopenharmony_ci
14908c2ecf20Sopenharmony_ciint sumo_get_temp(struct radeon_device *rdev)
14918c2ecf20Sopenharmony_ci{
14928c2ecf20Sopenharmony_ci	u32 temp = RREG32(CG_THERMAL_STATUS) & 0xff;
14938c2ecf20Sopenharmony_ci	int actual_temp = temp - 49;
14948c2ecf20Sopenharmony_ci
14958c2ecf20Sopenharmony_ci	return actual_temp * 1000;
14968c2ecf20Sopenharmony_ci}
14978c2ecf20Sopenharmony_ci
14988c2ecf20Sopenharmony_ci/**
14998c2ecf20Sopenharmony_ci * sumo_pm_init_profile - Initialize power profiles callback.
15008c2ecf20Sopenharmony_ci *
15018c2ecf20Sopenharmony_ci * @rdev: radeon_device pointer
15028c2ecf20Sopenharmony_ci *
15038c2ecf20Sopenharmony_ci * Initialize the power states used in profile mode
15048c2ecf20Sopenharmony_ci * (sumo, trinity, SI).
15058c2ecf20Sopenharmony_ci * Used for profile mode only.
15068c2ecf20Sopenharmony_ci */
15078c2ecf20Sopenharmony_civoid sumo_pm_init_profile(struct radeon_device *rdev)
15088c2ecf20Sopenharmony_ci{
15098c2ecf20Sopenharmony_ci	int idx;
15108c2ecf20Sopenharmony_ci
15118c2ecf20Sopenharmony_ci	/* default */
15128c2ecf20Sopenharmony_ci	rdev->pm.profiles[PM_PROFILE_DEFAULT_IDX].dpms_off_ps_idx = rdev->pm.default_power_state_index;
15138c2ecf20Sopenharmony_ci	rdev->pm.profiles[PM_PROFILE_DEFAULT_IDX].dpms_on_ps_idx = rdev->pm.default_power_state_index;
15148c2ecf20Sopenharmony_ci	rdev->pm.profiles[PM_PROFILE_DEFAULT_IDX].dpms_off_cm_idx = 0;
15158c2ecf20Sopenharmony_ci	rdev->pm.profiles[PM_PROFILE_DEFAULT_IDX].dpms_on_cm_idx = 0;
15168c2ecf20Sopenharmony_ci
15178c2ecf20Sopenharmony_ci	/* low,mid sh/mh */
15188c2ecf20Sopenharmony_ci	if (rdev->flags & RADEON_IS_MOBILITY)
15198c2ecf20Sopenharmony_ci		idx = radeon_pm_get_type_index(rdev, POWER_STATE_TYPE_BATTERY, 0);
15208c2ecf20Sopenharmony_ci	else
15218c2ecf20Sopenharmony_ci		idx = radeon_pm_get_type_index(rdev, POWER_STATE_TYPE_PERFORMANCE, 0);
15228c2ecf20Sopenharmony_ci
15238c2ecf20Sopenharmony_ci	rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_off_ps_idx = idx;
15248c2ecf20Sopenharmony_ci	rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_on_ps_idx = idx;
15258c2ecf20Sopenharmony_ci	rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_off_cm_idx = 0;
15268c2ecf20Sopenharmony_ci	rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_on_cm_idx = 0;
15278c2ecf20Sopenharmony_ci
15288c2ecf20Sopenharmony_ci	rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_off_ps_idx = idx;
15298c2ecf20Sopenharmony_ci	rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_on_ps_idx = idx;
15308c2ecf20Sopenharmony_ci	rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_off_cm_idx = 0;
15318c2ecf20Sopenharmony_ci	rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_on_cm_idx = 0;
15328c2ecf20Sopenharmony_ci
15338c2ecf20Sopenharmony_ci	rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_off_ps_idx = idx;
15348c2ecf20Sopenharmony_ci	rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_on_ps_idx = idx;
15358c2ecf20Sopenharmony_ci	rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_off_cm_idx = 0;
15368c2ecf20Sopenharmony_ci	rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_on_cm_idx = 0;
15378c2ecf20Sopenharmony_ci
15388c2ecf20Sopenharmony_ci	rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_off_ps_idx = idx;
15398c2ecf20Sopenharmony_ci	rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_on_ps_idx = idx;
15408c2ecf20Sopenharmony_ci	rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_off_cm_idx = 0;
15418c2ecf20Sopenharmony_ci	rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_on_cm_idx = 0;
15428c2ecf20Sopenharmony_ci
15438c2ecf20Sopenharmony_ci	/* high sh/mh */
15448c2ecf20Sopenharmony_ci	idx = radeon_pm_get_type_index(rdev, POWER_STATE_TYPE_PERFORMANCE, 0);
15458c2ecf20Sopenharmony_ci	rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_off_ps_idx = idx;
15468c2ecf20Sopenharmony_ci	rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_on_ps_idx = idx;
15478c2ecf20Sopenharmony_ci	rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_off_cm_idx = 0;
15488c2ecf20Sopenharmony_ci	rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_on_cm_idx =
15498c2ecf20Sopenharmony_ci		rdev->pm.power_state[idx].num_clock_modes - 1;
15508c2ecf20Sopenharmony_ci
15518c2ecf20Sopenharmony_ci	rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_off_ps_idx = idx;
15528c2ecf20Sopenharmony_ci	rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_on_ps_idx = idx;
15538c2ecf20Sopenharmony_ci	rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_off_cm_idx = 0;
15548c2ecf20Sopenharmony_ci	rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_on_cm_idx =
15558c2ecf20Sopenharmony_ci		rdev->pm.power_state[idx].num_clock_modes - 1;
15568c2ecf20Sopenharmony_ci}
15578c2ecf20Sopenharmony_ci
15588c2ecf20Sopenharmony_ci/**
15598c2ecf20Sopenharmony_ci * btc_pm_init_profile - Initialize power profiles callback.
15608c2ecf20Sopenharmony_ci *
15618c2ecf20Sopenharmony_ci * @rdev: radeon_device pointer
15628c2ecf20Sopenharmony_ci *
15638c2ecf20Sopenharmony_ci * Initialize the power states used in profile mode
15648c2ecf20Sopenharmony_ci * (BTC, cayman).
15658c2ecf20Sopenharmony_ci * Used for profile mode only.
15668c2ecf20Sopenharmony_ci */
15678c2ecf20Sopenharmony_civoid btc_pm_init_profile(struct radeon_device *rdev)
15688c2ecf20Sopenharmony_ci{
15698c2ecf20Sopenharmony_ci	int idx;
15708c2ecf20Sopenharmony_ci
15718c2ecf20Sopenharmony_ci	/* default */
15728c2ecf20Sopenharmony_ci	rdev->pm.profiles[PM_PROFILE_DEFAULT_IDX].dpms_off_ps_idx = rdev->pm.default_power_state_index;
15738c2ecf20Sopenharmony_ci	rdev->pm.profiles[PM_PROFILE_DEFAULT_IDX].dpms_on_ps_idx = rdev->pm.default_power_state_index;
15748c2ecf20Sopenharmony_ci	rdev->pm.profiles[PM_PROFILE_DEFAULT_IDX].dpms_off_cm_idx = 0;
15758c2ecf20Sopenharmony_ci	rdev->pm.profiles[PM_PROFILE_DEFAULT_IDX].dpms_on_cm_idx = 2;
15768c2ecf20Sopenharmony_ci	/* starting with BTC, there is one state that is used for both
15778c2ecf20Sopenharmony_ci	 * MH and SH.  Difference is that we always use the high clock index for
15788c2ecf20Sopenharmony_ci	 * mclk.
15798c2ecf20Sopenharmony_ci	 */
15808c2ecf20Sopenharmony_ci	if (rdev->flags & RADEON_IS_MOBILITY)
15818c2ecf20Sopenharmony_ci		idx = radeon_pm_get_type_index(rdev, POWER_STATE_TYPE_BATTERY, 0);
15828c2ecf20Sopenharmony_ci	else
15838c2ecf20Sopenharmony_ci		idx = radeon_pm_get_type_index(rdev, POWER_STATE_TYPE_PERFORMANCE, 0);
15848c2ecf20Sopenharmony_ci	/* low sh */
15858c2ecf20Sopenharmony_ci	rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_off_ps_idx = idx;
15868c2ecf20Sopenharmony_ci	rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_on_ps_idx = idx;
15878c2ecf20Sopenharmony_ci	rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_off_cm_idx = 0;
15888c2ecf20Sopenharmony_ci	rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_on_cm_idx = 0;
15898c2ecf20Sopenharmony_ci	/* mid sh */
15908c2ecf20Sopenharmony_ci	rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_off_ps_idx = idx;
15918c2ecf20Sopenharmony_ci	rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_on_ps_idx = idx;
15928c2ecf20Sopenharmony_ci	rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_off_cm_idx = 0;
15938c2ecf20Sopenharmony_ci	rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_on_cm_idx = 1;
15948c2ecf20Sopenharmony_ci	/* high sh */
15958c2ecf20Sopenharmony_ci	rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_off_ps_idx = idx;
15968c2ecf20Sopenharmony_ci	rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_on_ps_idx = idx;
15978c2ecf20Sopenharmony_ci	rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_off_cm_idx = 0;
15988c2ecf20Sopenharmony_ci	rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_on_cm_idx = 2;
15998c2ecf20Sopenharmony_ci	/* low mh */
16008c2ecf20Sopenharmony_ci	rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_off_ps_idx = idx;
16018c2ecf20Sopenharmony_ci	rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_on_ps_idx = idx;
16028c2ecf20Sopenharmony_ci	rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_off_cm_idx = 0;
16038c2ecf20Sopenharmony_ci	rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_on_cm_idx = 0;
16048c2ecf20Sopenharmony_ci	/* mid mh */
16058c2ecf20Sopenharmony_ci	rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_off_ps_idx = idx;
16068c2ecf20Sopenharmony_ci	rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_on_ps_idx = idx;
16078c2ecf20Sopenharmony_ci	rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_off_cm_idx = 0;
16088c2ecf20Sopenharmony_ci	rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_on_cm_idx = 1;
16098c2ecf20Sopenharmony_ci	/* high mh */
16108c2ecf20Sopenharmony_ci	rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_off_ps_idx = idx;
16118c2ecf20Sopenharmony_ci	rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_on_ps_idx = idx;
16128c2ecf20Sopenharmony_ci	rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_off_cm_idx = 0;
16138c2ecf20Sopenharmony_ci	rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_on_cm_idx = 2;
16148c2ecf20Sopenharmony_ci}
16158c2ecf20Sopenharmony_ci
16168c2ecf20Sopenharmony_ci/**
16178c2ecf20Sopenharmony_ci * evergreen_pm_misc - set additional pm hw parameters callback.
16188c2ecf20Sopenharmony_ci *
16198c2ecf20Sopenharmony_ci * @rdev: radeon_device pointer
16208c2ecf20Sopenharmony_ci *
16218c2ecf20Sopenharmony_ci * Set non-clock parameters associated with a power state
16228c2ecf20Sopenharmony_ci * (voltage, etc.) (evergreen+).
16238c2ecf20Sopenharmony_ci */
16248c2ecf20Sopenharmony_civoid evergreen_pm_misc(struct radeon_device *rdev)
16258c2ecf20Sopenharmony_ci{
16268c2ecf20Sopenharmony_ci	int req_ps_idx = rdev->pm.requested_power_state_index;
16278c2ecf20Sopenharmony_ci	int req_cm_idx = rdev->pm.requested_clock_mode_index;
16288c2ecf20Sopenharmony_ci	struct radeon_power_state *ps = &rdev->pm.power_state[req_ps_idx];
16298c2ecf20Sopenharmony_ci	struct radeon_voltage *voltage = &ps->clock_info[req_cm_idx].voltage;
16308c2ecf20Sopenharmony_ci
16318c2ecf20Sopenharmony_ci	if (voltage->type == VOLTAGE_SW) {
16328c2ecf20Sopenharmony_ci		/* 0xff0x are flags rather then an actual voltage */
16338c2ecf20Sopenharmony_ci		if ((voltage->voltage & 0xff00) == 0xff00)
16348c2ecf20Sopenharmony_ci			return;
16358c2ecf20Sopenharmony_ci		if (voltage->voltage && (voltage->voltage != rdev->pm.current_vddc)) {
16368c2ecf20Sopenharmony_ci			radeon_atom_set_voltage(rdev, voltage->voltage, SET_VOLTAGE_TYPE_ASIC_VDDC);
16378c2ecf20Sopenharmony_ci			rdev->pm.current_vddc = voltage->voltage;
16388c2ecf20Sopenharmony_ci			DRM_DEBUG("Setting: vddc: %d\n", voltage->voltage);
16398c2ecf20Sopenharmony_ci		}
16408c2ecf20Sopenharmony_ci
16418c2ecf20Sopenharmony_ci		/* starting with BTC, there is one state that is used for both
16428c2ecf20Sopenharmony_ci		 * MH and SH.  Difference is that we always use the high clock index for
16438c2ecf20Sopenharmony_ci		 * mclk and vddci.
16448c2ecf20Sopenharmony_ci		 */
16458c2ecf20Sopenharmony_ci		if ((rdev->pm.pm_method == PM_METHOD_PROFILE) &&
16468c2ecf20Sopenharmony_ci		    (rdev->family >= CHIP_BARTS) &&
16478c2ecf20Sopenharmony_ci		    rdev->pm.active_crtc_count &&
16488c2ecf20Sopenharmony_ci		    ((rdev->pm.profile_index == PM_PROFILE_MID_MH_IDX) ||
16498c2ecf20Sopenharmony_ci		     (rdev->pm.profile_index == PM_PROFILE_LOW_MH_IDX)))
16508c2ecf20Sopenharmony_ci			voltage = &rdev->pm.power_state[req_ps_idx].
16518c2ecf20Sopenharmony_ci				clock_info[rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_on_cm_idx].voltage;
16528c2ecf20Sopenharmony_ci
16538c2ecf20Sopenharmony_ci		/* 0xff0x are flags rather then an actual voltage */
16548c2ecf20Sopenharmony_ci		if ((voltage->vddci & 0xff00) == 0xff00)
16558c2ecf20Sopenharmony_ci			return;
16568c2ecf20Sopenharmony_ci		if (voltage->vddci && (voltage->vddci != rdev->pm.current_vddci)) {
16578c2ecf20Sopenharmony_ci			radeon_atom_set_voltage(rdev, voltage->vddci, SET_VOLTAGE_TYPE_ASIC_VDDCI);
16588c2ecf20Sopenharmony_ci			rdev->pm.current_vddci = voltage->vddci;
16598c2ecf20Sopenharmony_ci			DRM_DEBUG("Setting: vddci: %d\n", voltage->vddci);
16608c2ecf20Sopenharmony_ci		}
16618c2ecf20Sopenharmony_ci	}
16628c2ecf20Sopenharmony_ci}
16638c2ecf20Sopenharmony_ci
16648c2ecf20Sopenharmony_ci/**
16658c2ecf20Sopenharmony_ci * evergreen_pm_prepare - pre-power state change callback.
16668c2ecf20Sopenharmony_ci *
16678c2ecf20Sopenharmony_ci * @rdev: radeon_device pointer
16688c2ecf20Sopenharmony_ci *
16698c2ecf20Sopenharmony_ci * Prepare for a power state change (evergreen+).
16708c2ecf20Sopenharmony_ci */
16718c2ecf20Sopenharmony_civoid evergreen_pm_prepare(struct radeon_device *rdev)
16728c2ecf20Sopenharmony_ci{
16738c2ecf20Sopenharmony_ci	struct drm_device *ddev = rdev->ddev;
16748c2ecf20Sopenharmony_ci	struct drm_crtc *crtc;
16758c2ecf20Sopenharmony_ci	struct radeon_crtc *radeon_crtc;
16768c2ecf20Sopenharmony_ci	u32 tmp;
16778c2ecf20Sopenharmony_ci
16788c2ecf20Sopenharmony_ci	/* disable any active CRTCs */
16798c2ecf20Sopenharmony_ci	list_for_each_entry(crtc, &ddev->mode_config.crtc_list, head) {
16808c2ecf20Sopenharmony_ci		radeon_crtc = to_radeon_crtc(crtc);
16818c2ecf20Sopenharmony_ci		if (radeon_crtc->enabled) {
16828c2ecf20Sopenharmony_ci			tmp = RREG32(EVERGREEN_CRTC_CONTROL + radeon_crtc->crtc_offset);
16838c2ecf20Sopenharmony_ci			tmp |= EVERGREEN_CRTC_DISP_READ_REQUEST_DISABLE;
16848c2ecf20Sopenharmony_ci			WREG32(EVERGREEN_CRTC_CONTROL + radeon_crtc->crtc_offset, tmp);
16858c2ecf20Sopenharmony_ci		}
16868c2ecf20Sopenharmony_ci	}
16878c2ecf20Sopenharmony_ci}
16888c2ecf20Sopenharmony_ci
16898c2ecf20Sopenharmony_ci/**
16908c2ecf20Sopenharmony_ci * evergreen_pm_finish - post-power state change callback.
16918c2ecf20Sopenharmony_ci *
16928c2ecf20Sopenharmony_ci * @rdev: radeon_device pointer
16938c2ecf20Sopenharmony_ci *
16948c2ecf20Sopenharmony_ci * Clean up after a power state change (evergreen+).
16958c2ecf20Sopenharmony_ci */
16968c2ecf20Sopenharmony_civoid evergreen_pm_finish(struct radeon_device *rdev)
16978c2ecf20Sopenharmony_ci{
16988c2ecf20Sopenharmony_ci	struct drm_device *ddev = rdev->ddev;
16998c2ecf20Sopenharmony_ci	struct drm_crtc *crtc;
17008c2ecf20Sopenharmony_ci	struct radeon_crtc *radeon_crtc;
17018c2ecf20Sopenharmony_ci	u32 tmp;
17028c2ecf20Sopenharmony_ci
17038c2ecf20Sopenharmony_ci	/* enable any active CRTCs */
17048c2ecf20Sopenharmony_ci	list_for_each_entry(crtc, &ddev->mode_config.crtc_list, head) {
17058c2ecf20Sopenharmony_ci		radeon_crtc = to_radeon_crtc(crtc);
17068c2ecf20Sopenharmony_ci		if (radeon_crtc->enabled) {
17078c2ecf20Sopenharmony_ci			tmp = RREG32(EVERGREEN_CRTC_CONTROL + radeon_crtc->crtc_offset);
17088c2ecf20Sopenharmony_ci			tmp &= ~EVERGREEN_CRTC_DISP_READ_REQUEST_DISABLE;
17098c2ecf20Sopenharmony_ci			WREG32(EVERGREEN_CRTC_CONTROL + radeon_crtc->crtc_offset, tmp);
17108c2ecf20Sopenharmony_ci		}
17118c2ecf20Sopenharmony_ci	}
17128c2ecf20Sopenharmony_ci}
17138c2ecf20Sopenharmony_ci
17148c2ecf20Sopenharmony_ci/**
17158c2ecf20Sopenharmony_ci * evergreen_hpd_sense - hpd sense callback.
17168c2ecf20Sopenharmony_ci *
17178c2ecf20Sopenharmony_ci * @rdev: radeon_device pointer
17188c2ecf20Sopenharmony_ci * @hpd: hpd (hotplug detect) pin
17198c2ecf20Sopenharmony_ci *
17208c2ecf20Sopenharmony_ci * Checks if a digital monitor is connected (evergreen+).
17218c2ecf20Sopenharmony_ci * Returns true if connected, false if not connected.
17228c2ecf20Sopenharmony_ci */
17238c2ecf20Sopenharmony_cibool evergreen_hpd_sense(struct radeon_device *rdev, enum radeon_hpd_id hpd)
17248c2ecf20Sopenharmony_ci{
17258c2ecf20Sopenharmony_ci	if (hpd == RADEON_HPD_NONE)
17268c2ecf20Sopenharmony_ci		return false;
17278c2ecf20Sopenharmony_ci
17288c2ecf20Sopenharmony_ci	return !!(RREG32(DC_HPDx_INT_STATUS_REG(hpd)) & DC_HPDx_SENSE);
17298c2ecf20Sopenharmony_ci}
17308c2ecf20Sopenharmony_ci
17318c2ecf20Sopenharmony_ci/**
17328c2ecf20Sopenharmony_ci * evergreen_hpd_set_polarity - hpd set polarity callback.
17338c2ecf20Sopenharmony_ci *
17348c2ecf20Sopenharmony_ci * @rdev: radeon_device pointer
17358c2ecf20Sopenharmony_ci * @hpd: hpd (hotplug detect) pin
17368c2ecf20Sopenharmony_ci *
17378c2ecf20Sopenharmony_ci * Set the polarity of the hpd pin (evergreen+).
17388c2ecf20Sopenharmony_ci */
17398c2ecf20Sopenharmony_civoid evergreen_hpd_set_polarity(struct radeon_device *rdev,
17408c2ecf20Sopenharmony_ci				enum radeon_hpd_id hpd)
17418c2ecf20Sopenharmony_ci{
17428c2ecf20Sopenharmony_ci	bool connected = evergreen_hpd_sense(rdev, hpd);
17438c2ecf20Sopenharmony_ci
17448c2ecf20Sopenharmony_ci	if (hpd == RADEON_HPD_NONE)
17458c2ecf20Sopenharmony_ci		return;
17468c2ecf20Sopenharmony_ci
17478c2ecf20Sopenharmony_ci	if (connected)
17488c2ecf20Sopenharmony_ci		WREG32_AND(DC_HPDx_INT_CONTROL(hpd), ~DC_HPDx_INT_POLARITY);
17498c2ecf20Sopenharmony_ci	else
17508c2ecf20Sopenharmony_ci		WREG32_OR(DC_HPDx_INT_CONTROL(hpd), DC_HPDx_INT_POLARITY);
17518c2ecf20Sopenharmony_ci}
17528c2ecf20Sopenharmony_ci
17538c2ecf20Sopenharmony_ci/**
17548c2ecf20Sopenharmony_ci * evergreen_hpd_init - hpd setup callback.
17558c2ecf20Sopenharmony_ci *
17568c2ecf20Sopenharmony_ci * @rdev: radeon_device pointer
17578c2ecf20Sopenharmony_ci *
17588c2ecf20Sopenharmony_ci * Setup the hpd pins used by the card (evergreen+).
17598c2ecf20Sopenharmony_ci * Enable the pin, set the polarity, and enable the hpd interrupts.
17608c2ecf20Sopenharmony_ci */
17618c2ecf20Sopenharmony_civoid evergreen_hpd_init(struct radeon_device *rdev)
17628c2ecf20Sopenharmony_ci{
17638c2ecf20Sopenharmony_ci	struct drm_device *dev = rdev->ddev;
17648c2ecf20Sopenharmony_ci	struct drm_connector *connector;
17658c2ecf20Sopenharmony_ci	unsigned enabled = 0;
17668c2ecf20Sopenharmony_ci	u32 tmp = DC_HPDx_CONNECTION_TIMER(0x9c4) |
17678c2ecf20Sopenharmony_ci		DC_HPDx_RX_INT_TIMER(0xfa) | DC_HPDx_EN;
17688c2ecf20Sopenharmony_ci
17698c2ecf20Sopenharmony_ci	list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
17708c2ecf20Sopenharmony_ci		enum radeon_hpd_id hpd =
17718c2ecf20Sopenharmony_ci			to_radeon_connector(connector)->hpd.hpd;
17728c2ecf20Sopenharmony_ci
17738c2ecf20Sopenharmony_ci		if (connector->connector_type == DRM_MODE_CONNECTOR_eDP ||
17748c2ecf20Sopenharmony_ci		    connector->connector_type == DRM_MODE_CONNECTOR_LVDS) {
17758c2ecf20Sopenharmony_ci			/* don't try to enable hpd on eDP or LVDS avoid breaking the
17768c2ecf20Sopenharmony_ci			 * aux dp channel on imac and help (but not completely fix)
17778c2ecf20Sopenharmony_ci			 * https://bugzilla.redhat.com/show_bug.cgi?id=726143
17788c2ecf20Sopenharmony_ci			 * also avoid interrupt storms during dpms.
17798c2ecf20Sopenharmony_ci			 */
17808c2ecf20Sopenharmony_ci			continue;
17818c2ecf20Sopenharmony_ci		}
17828c2ecf20Sopenharmony_ci
17838c2ecf20Sopenharmony_ci		if (hpd == RADEON_HPD_NONE)
17848c2ecf20Sopenharmony_ci			continue;
17858c2ecf20Sopenharmony_ci
17868c2ecf20Sopenharmony_ci		WREG32(DC_HPDx_CONTROL(hpd), tmp);
17878c2ecf20Sopenharmony_ci		enabled |= 1 << hpd;
17888c2ecf20Sopenharmony_ci
17898c2ecf20Sopenharmony_ci		radeon_hpd_set_polarity(rdev, hpd);
17908c2ecf20Sopenharmony_ci	}
17918c2ecf20Sopenharmony_ci	radeon_irq_kms_enable_hpd(rdev, enabled);
17928c2ecf20Sopenharmony_ci}
17938c2ecf20Sopenharmony_ci
17948c2ecf20Sopenharmony_ci/**
17958c2ecf20Sopenharmony_ci * evergreen_hpd_fini - hpd tear down callback.
17968c2ecf20Sopenharmony_ci *
17978c2ecf20Sopenharmony_ci * @rdev: radeon_device pointer
17988c2ecf20Sopenharmony_ci *
17998c2ecf20Sopenharmony_ci * Tear down the hpd pins used by the card (evergreen+).
18008c2ecf20Sopenharmony_ci * Disable the hpd interrupts.
18018c2ecf20Sopenharmony_ci */
18028c2ecf20Sopenharmony_civoid evergreen_hpd_fini(struct radeon_device *rdev)
18038c2ecf20Sopenharmony_ci{
18048c2ecf20Sopenharmony_ci	struct drm_device *dev = rdev->ddev;
18058c2ecf20Sopenharmony_ci	struct drm_connector *connector;
18068c2ecf20Sopenharmony_ci	unsigned disabled = 0;
18078c2ecf20Sopenharmony_ci
18088c2ecf20Sopenharmony_ci	list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
18098c2ecf20Sopenharmony_ci		enum radeon_hpd_id hpd =
18108c2ecf20Sopenharmony_ci			to_radeon_connector(connector)->hpd.hpd;
18118c2ecf20Sopenharmony_ci
18128c2ecf20Sopenharmony_ci		if (hpd == RADEON_HPD_NONE)
18138c2ecf20Sopenharmony_ci			continue;
18148c2ecf20Sopenharmony_ci
18158c2ecf20Sopenharmony_ci		WREG32(DC_HPDx_CONTROL(hpd), 0);
18168c2ecf20Sopenharmony_ci		disabled |= 1 << hpd;
18178c2ecf20Sopenharmony_ci	}
18188c2ecf20Sopenharmony_ci	radeon_irq_kms_disable_hpd(rdev, disabled);
18198c2ecf20Sopenharmony_ci}
18208c2ecf20Sopenharmony_ci
18218c2ecf20Sopenharmony_ci/* watermark setup */
18228c2ecf20Sopenharmony_ci
18238c2ecf20Sopenharmony_cistatic u32 evergreen_line_buffer_adjust(struct radeon_device *rdev,
18248c2ecf20Sopenharmony_ci					struct radeon_crtc *radeon_crtc,
18258c2ecf20Sopenharmony_ci					struct drm_display_mode *mode,
18268c2ecf20Sopenharmony_ci					struct drm_display_mode *other_mode)
18278c2ecf20Sopenharmony_ci{
18288c2ecf20Sopenharmony_ci	u32 tmp, buffer_alloc, i;
18298c2ecf20Sopenharmony_ci	u32 pipe_offset = radeon_crtc->crtc_id * 0x20;
18308c2ecf20Sopenharmony_ci	/*
18318c2ecf20Sopenharmony_ci	 * Line Buffer Setup
18328c2ecf20Sopenharmony_ci	 * There are 3 line buffers, each one shared by 2 display controllers.
18338c2ecf20Sopenharmony_ci	 * DC_LB_MEMORY_SPLIT controls how that line buffer is shared between
18348c2ecf20Sopenharmony_ci	 * the display controllers.  The paritioning is done via one of four
18358c2ecf20Sopenharmony_ci	 * preset allocations specified in bits 2:0:
18368c2ecf20Sopenharmony_ci	 * first display controller
18378c2ecf20Sopenharmony_ci	 *  0 - first half of lb (3840 * 2)
18388c2ecf20Sopenharmony_ci	 *  1 - first 3/4 of lb (5760 * 2)
18398c2ecf20Sopenharmony_ci	 *  2 - whole lb (7680 * 2), other crtc must be disabled
18408c2ecf20Sopenharmony_ci	 *  3 - first 1/4 of lb (1920 * 2)
18418c2ecf20Sopenharmony_ci	 * second display controller
18428c2ecf20Sopenharmony_ci	 *  4 - second half of lb (3840 * 2)
18438c2ecf20Sopenharmony_ci	 *  5 - second 3/4 of lb (5760 * 2)
18448c2ecf20Sopenharmony_ci	 *  6 - whole lb (7680 * 2), other crtc must be disabled
18458c2ecf20Sopenharmony_ci	 *  7 - last 1/4 of lb (1920 * 2)
18468c2ecf20Sopenharmony_ci	 */
18478c2ecf20Sopenharmony_ci	/* this can get tricky if we have two large displays on a paired group
18488c2ecf20Sopenharmony_ci	 * of crtcs.  Ideally for multiple large displays we'd assign them to
18498c2ecf20Sopenharmony_ci	 * non-linked crtcs for maximum line buffer allocation.
18508c2ecf20Sopenharmony_ci	 */
18518c2ecf20Sopenharmony_ci	if (radeon_crtc->base.enabled && mode) {
18528c2ecf20Sopenharmony_ci		if (other_mode) {
18538c2ecf20Sopenharmony_ci			tmp = 0; /* 1/2 */
18548c2ecf20Sopenharmony_ci			buffer_alloc = 1;
18558c2ecf20Sopenharmony_ci		} else {
18568c2ecf20Sopenharmony_ci			tmp = 2; /* whole */
18578c2ecf20Sopenharmony_ci			buffer_alloc = 2;
18588c2ecf20Sopenharmony_ci		}
18598c2ecf20Sopenharmony_ci	} else {
18608c2ecf20Sopenharmony_ci		tmp = 0;
18618c2ecf20Sopenharmony_ci		buffer_alloc = 0;
18628c2ecf20Sopenharmony_ci	}
18638c2ecf20Sopenharmony_ci
18648c2ecf20Sopenharmony_ci	/* second controller of the pair uses second half of the lb */
18658c2ecf20Sopenharmony_ci	if (radeon_crtc->crtc_id % 2)
18668c2ecf20Sopenharmony_ci		tmp += 4;
18678c2ecf20Sopenharmony_ci	WREG32(DC_LB_MEMORY_SPLIT + radeon_crtc->crtc_offset, tmp);
18688c2ecf20Sopenharmony_ci
18698c2ecf20Sopenharmony_ci	if (ASIC_IS_DCE41(rdev) || ASIC_IS_DCE5(rdev)) {
18708c2ecf20Sopenharmony_ci		WREG32(PIPE0_DMIF_BUFFER_CONTROL + pipe_offset,
18718c2ecf20Sopenharmony_ci		       DMIF_BUFFERS_ALLOCATED(buffer_alloc));
18728c2ecf20Sopenharmony_ci		for (i = 0; i < rdev->usec_timeout; i++) {
18738c2ecf20Sopenharmony_ci			if (RREG32(PIPE0_DMIF_BUFFER_CONTROL + pipe_offset) &
18748c2ecf20Sopenharmony_ci			    DMIF_BUFFERS_ALLOCATED_COMPLETED)
18758c2ecf20Sopenharmony_ci				break;
18768c2ecf20Sopenharmony_ci			udelay(1);
18778c2ecf20Sopenharmony_ci		}
18788c2ecf20Sopenharmony_ci	}
18798c2ecf20Sopenharmony_ci
18808c2ecf20Sopenharmony_ci	if (radeon_crtc->base.enabled && mode) {
18818c2ecf20Sopenharmony_ci		switch (tmp) {
18828c2ecf20Sopenharmony_ci		case 0:
18838c2ecf20Sopenharmony_ci		case 4:
18848c2ecf20Sopenharmony_ci		default:
18858c2ecf20Sopenharmony_ci			if (ASIC_IS_DCE5(rdev))
18868c2ecf20Sopenharmony_ci				return 4096 * 2;
18878c2ecf20Sopenharmony_ci			else
18888c2ecf20Sopenharmony_ci				return 3840 * 2;
18898c2ecf20Sopenharmony_ci		case 1:
18908c2ecf20Sopenharmony_ci		case 5:
18918c2ecf20Sopenharmony_ci			if (ASIC_IS_DCE5(rdev))
18928c2ecf20Sopenharmony_ci				return 6144 * 2;
18938c2ecf20Sopenharmony_ci			else
18948c2ecf20Sopenharmony_ci				return 5760 * 2;
18958c2ecf20Sopenharmony_ci		case 2:
18968c2ecf20Sopenharmony_ci		case 6:
18978c2ecf20Sopenharmony_ci			if (ASIC_IS_DCE5(rdev))
18988c2ecf20Sopenharmony_ci				return 8192 * 2;
18998c2ecf20Sopenharmony_ci			else
19008c2ecf20Sopenharmony_ci				return 7680 * 2;
19018c2ecf20Sopenharmony_ci		case 3:
19028c2ecf20Sopenharmony_ci		case 7:
19038c2ecf20Sopenharmony_ci			if (ASIC_IS_DCE5(rdev))
19048c2ecf20Sopenharmony_ci				return 2048 * 2;
19058c2ecf20Sopenharmony_ci			else
19068c2ecf20Sopenharmony_ci				return 1920 * 2;
19078c2ecf20Sopenharmony_ci		}
19088c2ecf20Sopenharmony_ci	}
19098c2ecf20Sopenharmony_ci
19108c2ecf20Sopenharmony_ci	/* controller not enabled, so no lb used */
19118c2ecf20Sopenharmony_ci	return 0;
19128c2ecf20Sopenharmony_ci}
19138c2ecf20Sopenharmony_ci
19148c2ecf20Sopenharmony_ciu32 evergreen_get_number_of_dram_channels(struct radeon_device *rdev)
19158c2ecf20Sopenharmony_ci{
19168c2ecf20Sopenharmony_ci	u32 tmp = RREG32(MC_SHARED_CHMAP);
19178c2ecf20Sopenharmony_ci
19188c2ecf20Sopenharmony_ci	switch ((tmp & NOOFCHAN_MASK) >> NOOFCHAN_SHIFT) {
19198c2ecf20Sopenharmony_ci	case 0:
19208c2ecf20Sopenharmony_ci	default:
19218c2ecf20Sopenharmony_ci		return 1;
19228c2ecf20Sopenharmony_ci	case 1:
19238c2ecf20Sopenharmony_ci		return 2;
19248c2ecf20Sopenharmony_ci	case 2:
19258c2ecf20Sopenharmony_ci		return 4;
19268c2ecf20Sopenharmony_ci	case 3:
19278c2ecf20Sopenharmony_ci		return 8;
19288c2ecf20Sopenharmony_ci	}
19298c2ecf20Sopenharmony_ci}
19308c2ecf20Sopenharmony_ci
19318c2ecf20Sopenharmony_cistruct evergreen_wm_params {
19328c2ecf20Sopenharmony_ci	u32 dram_channels; /* number of dram channels */
19338c2ecf20Sopenharmony_ci	u32 yclk;          /* bandwidth per dram data pin in kHz */
19348c2ecf20Sopenharmony_ci	u32 sclk;          /* engine clock in kHz */
19358c2ecf20Sopenharmony_ci	u32 disp_clk;      /* display clock in kHz */
19368c2ecf20Sopenharmony_ci	u32 src_width;     /* viewport width */
19378c2ecf20Sopenharmony_ci	u32 active_time;   /* active display time in ns */
19388c2ecf20Sopenharmony_ci	u32 blank_time;    /* blank time in ns */
19398c2ecf20Sopenharmony_ci	bool interlaced;    /* mode is interlaced */
19408c2ecf20Sopenharmony_ci	fixed20_12 vsc;    /* vertical scale ratio */
19418c2ecf20Sopenharmony_ci	u32 num_heads;     /* number of active crtcs */
19428c2ecf20Sopenharmony_ci	u32 bytes_per_pixel; /* bytes per pixel display + overlay */
19438c2ecf20Sopenharmony_ci	u32 lb_size;       /* line buffer allocated to pipe */
19448c2ecf20Sopenharmony_ci	u32 vtaps;         /* vertical scaler taps */
19458c2ecf20Sopenharmony_ci};
19468c2ecf20Sopenharmony_ci
19478c2ecf20Sopenharmony_cistatic u32 evergreen_dram_bandwidth(struct evergreen_wm_params *wm)
19488c2ecf20Sopenharmony_ci{
19498c2ecf20Sopenharmony_ci	/* Calculate DRAM Bandwidth and the part allocated to display. */
19508c2ecf20Sopenharmony_ci	fixed20_12 dram_efficiency; /* 0.7 */
19518c2ecf20Sopenharmony_ci	fixed20_12 yclk, dram_channels, bandwidth;
19528c2ecf20Sopenharmony_ci	fixed20_12 a;
19538c2ecf20Sopenharmony_ci
19548c2ecf20Sopenharmony_ci	a.full = dfixed_const(1000);
19558c2ecf20Sopenharmony_ci	yclk.full = dfixed_const(wm->yclk);
19568c2ecf20Sopenharmony_ci	yclk.full = dfixed_div(yclk, a);
19578c2ecf20Sopenharmony_ci	dram_channels.full = dfixed_const(wm->dram_channels * 4);
19588c2ecf20Sopenharmony_ci	a.full = dfixed_const(10);
19598c2ecf20Sopenharmony_ci	dram_efficiency.full = dfixed_const(7);
19608c2ecf20Sopenharmony_ci	dram_efficiency.full = dfixed_div(dram_efficiency, a);
19618c2ecf20Sopenharmony_ci	bandwidth.full = dfixed_mul(dram_channels, yclk);
19628c2ecf20Sopenharmony_ci	bandwidth.full = dfixed_mul(bandwidth, dram_efficiency);
19638c2ecf20Sopenharmony_ci
19648c2ecf20Sopenharmony_ci	return dfixed_trunc(bandwidth);
19658c2ecf20Sopenharmony_ci}
19668c2ecf20Sopenharmony_ci
19678c2ecf20Sopenharmony_cistatic u32 evergreen_dram_bandwidth_for_display(struct evergreen_wm_params *wm)
19688c2ecf20Sopenharmony_ci{
19698c2ecf20Sopenharmony_ci	/* Calculate DRAM Bandwidth and the part allocated to display. */
19708c2ecf20Sopenharmony_ci	fixed20_12 disp_dram_allocation; /* 0.3 to 0.7 */
19718c2ecf20Sopenharmony_ci	fixed20_12 yclk, dram_channels, bandwidth;
19728c2ecf20Sopenharmony_ci	fixed20_12 a;
19738c2ecf20Sopenharmony_ci
19748c2ecf20Sopenharmony_ci	a.full = dfixed_const(1000);
19758c2ecf20Sopenharmony_ci	yclk.full = dfixed_const(wm->yclk);
19768c2ecf20Sopenharmony_ci	yclk.full = dfixed_div(yclk, a);
19778c2ecf20Sopenharmony_ci	dram_channels.full = dfixed_const(wm->dram_channels * 4);
19788c2ecf20Sopenharmony_ci	a.full = dfixed_const(10);
19798c2ecf20Sopenharmony_ci	disp_dram_allocation.full = dfixed_const(3); /* XXX worse case value 0.3 */
19808c2ecf20Sopenharmony_ci	disp_dram_allocation.full = dfixed_div(disp_dram_allocation, a);
19818c2ecf20Sopenharmony_ci	bandwidth.full = dfixed_mul(dram_channels, yclk);
19828c2ecf20Sopenharmony_ci	bandwidth.full = dfixed_mul(bandwidth, disp_dram_allocation);
19838c2ecf20Sopenharmony_ci
19848c2ecf20Sopenharmony_ci	return dfixed_trunc(bandwidth);
19858c2ecf20Sopenharmony_ci}
19868c2ecf20Sopenharmony_ci
19878c2ecf20Sopenharmony_cistatic u32 evergreen_data_return_bandwidth(struct evergreen_wm_params *wm)
19888c2ecf20Sopenharmony_ci{
19898c2ecf20Sopenharmony_ci	/* Calculate the display Data return Bandwidth */
19908c2ecf20Sopenharmony_ci	fixed20_12 return_efficiency; /* 0.8 */
19918c2ecf20Sopenharmony_ci	fixed20_12 sclk, bandwidth;
19928c2ecf20Sopenharmony_ci	fixed20_12 a;
19938c2ecf20Sopenharmony_ci
19948c2ecf20Sopenharmony_ci	a.full = dfixed_const(1000);
19958c2ecf20Sopenharmony_ci	sclk.full = dfixed_const(wm->sclk);
19968c2ecf20Sopenharmony_ci	sclk.full = dfixed_div(sclk, a);
19978c2ecf20Sopenharmony_ci	a.full = dfixed_const(10);
19988c2ecf20Sopenharmony_ci	return_efficiency.full = dfixed_const(8);
19998c2ecf20Sopenharmony_ci	return_efficiency.full = dfixed_div(return_efficiency, a);
20008c2ecf20Sopenharmony_ci	a.full = dfixed_const(32);
20018c2ecf20Sopenharmony_ci	bandwidth.full = dfixed_mul(a, sclk);
20028c2ecf20Sopenharmony_ci	bandwidth.full = dfixed_mul(bandwidth, return_efficiency);
20038c2ecf20Sopenharmony_ci
20048c2ecf20Sopenharmony_ci	return dfixed_trunc(bandwidth);
20058c2ecf20Sopenharmony_ci}
20068c2ecf20Sopenharmony_ci
20078c2ecf20Sopenharmony_cistatic u32 evergreen_dmif_request_bandwidth(struct evergreen_wm_params *wm)
20088c2ecf20Sopenharmony_ci{
20098c2ecf20Sopenharmony_ci	/* Calculate the DMIF Request Bandwidth */
20108c2ecf20Sopenharmony_ci	fixed20_12 disp_clk_request_efficiency; /* 0.8 */
20118c2ecf20Sopenharmony_ci	fixed20_12 disp_clk, bandwidth;
20128c2ecf20Sopenharmony_ci	fixed20_12 a;
20138c2ecf20Sopenharmony_ci
20148c2ecf20Sopenharmony_ci	a.full = dfixed_const(1000);
20158c2ecf20Sopenharmony_ci	disp_clk.full = dfixed_const(wm->disp_clk);
20168c2ecf20Sopenharmony_ci	disp_clk.full = dfixed_div(disp_clk, a);
20178c2ecf20Sopenharmony_ci	a.full = dfixed_const(10);
20188c2ecf20Sopenharmony_ci	disp_clk_request_efficiency.full = dfixed_const(8);
20198c2ecf20Sopenharmony_ci	disp_clk_request_efficiency.full = dfixed_div(disp_clk_request_efficiency, a);
20208c2ecf20Sopenharmony_ci	a.full = dfixed_const(32);
20218c2ecf20Sopenharmony_ci	bandwidth.full = dfixed_mul(a, disp_clk);
20228c2ecf20Sopenharmony_ci	bandwidth.full = dfixed_mul(bandwidth, disp_clk_request_efficiency);
20238c2ecf20Sopenharmony_ci
20248c2ecf20Sopenharmony_ci	return dfixed_trunc(bandwidth);
20258c2ecf20Sopenharmony_ci}
20268c2ecf20Sopenharmony_ci
20278c2ecf20Sopenharmony_cistatic u32 evergreen_available_bandwidth(struct evergreen_wm_params *wm)
20288c2ecf20Sopenharmony_ci{
20298c2ecf20Sopenharmony_ci	/* Calculate the Available bandwidth. Display can use this temporarily but not in average. */
20308c2ecf20Sopenharmony_ci	u32 dram_bandwidth = evergreen_dram_bandwidth(wm);
20318c2ecf20Sopenharmony_ci	u32 data_return_bandwidth = evergreen_data_return_bandwidth(wm);
20328c2ecf20Sopenharmony_ci	u32 dmif_req_bandwidth = evergreen_dmif_request_bandwidth(wm);
20338c2ecf20Sopenharmony_ci
20348c2ecf20Sopenharmony_ci	return min(dram_bandwidth, min(data_return_bandwidth, dmif_req_bandwidth));
20358c2ecf20Sopenharmony_ci}
20368c2ecf20Sopenharmony_ci
20378c2ecf20Sopenharmony_cistatic u32 evergreen_average_bandwidth(struct evergreen_wm_params *wm)
20388c2ecf20Sopenharmony_ci{
20398c2ecf20Sopenharmony_ci	/* Calculate the display mode Average Bandwidth
20408c2ecf20Sopenharmony_ci	 * DisplayMode should contain the source and destination dimensions,
20418c2ecf20Sopenharmony_ci	 * timing, etc.
20428c2ecf20Sopenharmony_ci	 */
20438c2ecf20Sopenharmony_ci	fixed20_12 bpp;
20448c2ecf20Sopenharmony_ci	fixed20_12 line_time;
20458c2ecf20Sopenharmony_ci	fixed20_12 src_width;
20468c2ecf20Sopenharmony_ci	fixed20_12 bandwidth;
20478c2ecf20Sopenharmony_ci	fixed20_12 a;
20488c2ecf20Sopenharmony_ci
20498c2ecf20Sopenharmony_ci	a.full = dfixed_const(1000);
20508c2ecf20Sopenharmony_ci	line_time.full = dfixed_const(wm->active_time + wm->blank_time);
20518c2ecf20Sopenharmony_ci	line_time.full = dfixed_div(line_time, a);
20528c2ecf20Sopenharmony_ci	bpp.full = dfixed_const(wm->bytes_per_pixel);
20538c2ecf20Sopenharmony_ci	src_width.full = dfixed_const(wm->src_width);
20548c2ecf20Sopenharmony_ci	bandwidth.full = dfixed_mul(src_width, bpp);
20558c2ecf20Sopenharmony_ci	bandwidth.full = dfixed_mul(bandwidth, wm->vsc);
20568c2ecf20Sopenharmony_ci	bandwidth.full = dfixed_div(bandwidth, line_time);
20578c2ecf20Sopenharmony_ci
20588c2ecf20Sopenharmony_ci	return dfixed_trunc(bandwidth);
20598c2ecf20Sopenharmony_ci}
20608c2ecf20Sopenharmony_ci
20618c2ecf20Sopenharmony_cistatic u32 evergreen_latency_watermark(struct evergreen_wm_params *wm)
20628c2ecf20Sopenharmony_ci{
20638c2ecf20Sopenharmony_ci	/* First calcualte the latency in ns */
20648c2ecf20Sopenharmony_ci	u32 mc_latency = 2000; /* 2000 ns. */
20658c2ecf20Sopenharmony_ci	u32 available_bandwidth = evergreen_available_bandwidth(wm);
20668c2ecf20Sopenharmony_ci	u32 worst_chunk_return_time = (512 * 8 * 1000) / available_bandwidth;
20678c2ecf20Sopenharmony_ci	u32 cursor_line_pair_return_time = (128 * 4 * 1000) / available_bandwidth;
20688c2ecf20Sopenharmony_ci	u32 dc_latency = 40000000 / wm->disp_clk; /* dc pipe latency */
20698c2ecf20Sopenharmony_ci	u32 other_heads_data_return_time = ((wm->num_heads + 1) * worst_chunk_return_time) +
20708c2ecf20Sopenharmony_ci		(wm->num_heads * cursor_line_pair_return_time);
20718c2ecf20Sopenharmony_ci	u32 latency = mc_latency + other_heads_data_return_time + dc_latency;
20728c2ecf20Sopenharmony_ci	u32 max_src_lines_per_dst_line, lb_fill_bw, line_fill_time;
20738c2ecf20Sopenharmony_ci	fixed20_12 a, b, c;
20748c2ecf20Sopenharmony_ci
20758c2ecf20Sopenharmony_ci	if (wm->num_heads == 0)
20768c2ecf20Sopenharmony_ci		return 0;
20778c2ecf20Sopenharmony_ci
20788c2ecf20Sopenharmony_ci	a.full = dfixed_const(2);
20798c2ecf20Sopenharmony_ci	b.full = dfixed_const(1);
20808c2ecf20Sopenharmony_ci	if ((wm->vsc.full > a.full) ||
20818c2ecf20Sopenharmony_ci	    ((wm->vsc.full > b.full) && (wm->vtaps >= 3)) ||
20828c2ecf20Sopenharmony_ci	    (wm->vtaps >= 5) ||
20838c2ecf20Sopenharmony_ci	    ((wm->vsc.full >= a.full) && wm->interlaced))
20848c2ecf20Sopenharmony_ci		max_src_lines_per_dst_line = 4;
20858c2ecf20Sopenharmony_ci	else
20868c2ecf20Sopenharmony_ci		max_src_lines_per_dst_line = 2;
20878c2ecf20Sopenharmony_ci
20888c2ecf20Sopenharmony_ci	a.full = dfixed_const(available_bandwidth);
20898c2ecf20Sopenharmony_ci	b.full = dfixed_const(wm->num_heads);
20908c2ecf20Sopenharmony_ci	a.full = dfixed_div(a, b);
20918c2ecf20Sopenharmony_ci
20928c2ecf20Sopenharmony_ci	lb_fill_bw = min(dfixed_trunc(a), wm->disp_clk * wm->bytes_per_pixel / 1000);
20938c2ecf20Sopenharmony_ci
20948c2ecf20Sopenharmony_ci	a.full = dfixed_const(max_src_lines_per_dst_line * wm->src_width * wm->bytes_per_pixel);
20958c2ecf20Sopenharmony_ci	b.full = dfixed_const(1000);
20968c2ecf20Sopenharmony_ci	c.full = dfixed_const(lb_fill_bw);
20978c2ecf20Sopenharmony_ci	b.full = dfixed_div(c, b);
20988c2ecf20Sopenharmony_ci	a.full = dfixed_div(a, b);
20998c2ecf20Sopenharmony_ci	line_fill_time = dfixed_trunc(a);
21008c2ecf20Sopenharmony_ci
21018c2ecf20Sopenharmony_ci	if (line_fill_time < wm->active_time)
21028c2ecf20Sopenharmony_ci		return latency;
21038c2ecf20Sopenharmony_ci	else
21048c2ecf20Sopenharmony_ci		return latency + (line_fill_time - wm->active_time);
21058c2ecf20Sopenharmony_ci
21068c2ecf20Sopenharmony_ci}
21078c2ecf20Sopenharmony_ci
21088c2ecf20Sopenharmony_cistatic bool evergreen_average_bandwidth_vs_dram_bandwidth_for_display(struct evergreen_wm_params *wm)
21098c2ecf20Sopenharmony_ci{
21108c2ecf20Sopenharmony_ci	if (evergreen_average_bandwidth(wm) <=
21118c2ecf20Sopenharmony_ci	    (evergreen_dram_bandwidth_for_display(wm) / wm->num_heads))
21128c2ecf20Sopenharmony_ci		return true;
21138c2ecf20Sopenharmony_ci	else
21148c2ecf20Sopenharmony_ci		return false;
21158c2ecf20Sopenharmony_ci};
21168c2ecf20Sopenharmony_ci
21178c2ecf20Sopenharmony_cistatic bool evergreen_average_bandwidth_vs_available_bandwidth(struct evergreen_wm_params *wm)
21188c2ecf20Sopenharmony_ci{
21198c2ecf20Sopenharmony_ci	if (evergreen_average_bandwidth(wm) <=
21208c2ecf20Sopenharmony_ci	    (evergreen_available_bandwidth(wm) / wm->num_heads))
21218c2ecf20Sopenharmony_ci		return true;
21228c2ecf20Sopenharmony_ci	else
21238c2ecf20Sopenharmony_ci		return false;
21248c2ecf20Sopenharmony_ci};
21258c2ecf20Sopenharmony_ci
21268c2ecf20Sopenharmony_cistatic bool evergreen_check_latency_hiding(struct evergreen_wm_params *wm)
21278c2ecf20Sopenharmony_ci{
21288c2ecf20Sopenharmony_ci	u32 lb_partitions = wm->lb_size / wm->src_width;
21298c2ecf20Sopenharmony_ci	u32 line_time = wm->active_time + wm->blank_time;
21308c2ecf20Sopenharmony_ci	u32 latency_tolerant_lines;
21318c2ecf20Sopenharmony_ci	u32 latency_hiding;
21328c2ecf20Sopenharmony_ci	fixed20_12 a;
21338c2ecf20Sopenharmony_ci
21348c2ecf20Sopenharmony_ci	a.full = dfixed_const(1);
21358c2ecf20Sopenharmony_ci	if (wm->vsc.full > a.full)
21368c2ecf20Sopenharmony_ci		latency_tolerant_lines = 1;
21378c2ecf20Sopenharmony_ci	else {
21388c2ecf20Sopenharmony_ci		if (lb_partitions <= (wm->vtaps + 1))
21398c2ecf20Sopenharmony_ci			latency_tolerant_lines = 1;
21408c2ecf20Sopenharmony_ci		else
21418c2ecf20Sopenharmony_ci			latency_tolerant_lines = 2;
21428c2ecf20Sopenharmony_ci	}
21438c2ecf20Sopenharmony_ci
21448c2ecf20Sopenharmony_ci	latency_hiding = (latency_tolerant_lines * line_time + wm->blank_time);
21458c2ecf20Sopenharmony_ci
21468c2ecf20Sopenharmony_ci	if (evergreen_latency_watermark(wm) <= latency_hiding)
21478c2ecf20Sopenharmony_ci		return true;
21488c2ecf20Sopenharmony_ci	else
21498c2ecf20Sopenharmony_ci		return false;
21508c2ecf20Sopenharmony_ci}
21518c2ecf20Sopenharmony_ci
21528c2ecf20Sopenharmony_cistatic void evergreen_program_watermarks(struct radeon_device *rdev,
21538c2ecf20Sopenharmony_ci					 struct radeon_crtc *radeon_crtc,
21548c2ecf20Sopenharmony_ci					 u32 lb_size, u32 num_heads)
21558c2ecf20Sopenharmony_ci{
21568c2ecf20Sopenharmony_ci	struct drm_display_mode *mode = &radeon_crtc->base.mode;
21578c2ecf20Sopenharmony_ci	struct evergreen_wm_params wm_low, wm_high;
21588c2ecf20Sopenharmony_ci	u32 dram_channels;
21598c2ecf20Sopenharmony_ci	u32 active_time;
21608c2ecf20Sopenharmony_ci	u32 line_time = 0;
21618c2ecf20Sopenharmony_ci	u32 latency_watermark_a = 0, latency_watermark_b = 0;
21628c2ecf20Sopenharmony_ci	u32 priority_a_mark = 0, priority_b_mark = 0;
21638c2ecf20Sopenharmony_ci	u32 priority_a_cnt = PRIORITY_OFF;
21648c2ecf20Sopenharmony_ci	u32 priority_b_cnt = PRIORITY_OFF;
21658c2ecf20Sopenharmony_ci	u32 pipe_offset = radeon_crtc->crtc_id * 16;
21668c2ecf20Sopenharmony_ci	u32 tmp, arb_control3;
21678c2ecf20Sopenharmony_ci	fixed20_12 a, b, c;
21688c2ecf20Sopenharmony_ci
21698c2ecf20Sopenharmony_ci	if (radeon_crtc->base.enabled && num_heads && mode) {
21708c2ecf20Sopenharmony_ci		active_time = (u32) div_u64((u64)mode->crtc_hdisplay * 1000000,
21718c2ecf20Sopenharmony_ci					    (u32)mode->clock);
21728c2ecf20Sopenharmony_ci		line_time = (u32) div_u64((u64)mode->crtc_htotal * 1000000,
21738c2ecf20Sopenharmony_ci					  (u32)mode->clock);
21748c2ecf20Sopenharmony_ci		line_time = min(line_time, (u32)65535);
21758c2ecf20Sopenharmony_ci		priority_a_cnt = 0;
21768c2ecf20Sopenharmony_ci		priority_b_cnt = 0;
21778c2ecf20Sopenharmony_ci		dram_channels = evergreen_get_number_of_dram_channels(rdev);
21788c2ecf20Sopenharmony_ci
21798c2ecf20Sopenharmony_ci		/* watermark for high clocks */
21808c2ecf20Sopenharmony_ci		if ((rdev->pm.pm_method == PM_METHOD_DPM) && rdev->pm.dpm_enabled) {
21818c2ecf20Sopenharmony_ci			wm_high.yclk =
21828c2ecf20Sopenharmony_ci				radeon_dpm_get_mclk(rdev, false) * 10;
21838c2ecf20Sopenharmony_ci			wm_high.sclk =
21848c2ecf20Sopenharmony_ci				radeon_dpm_get_sclk(rdev, false) * 10;
21858c2ecf20Sopenharmony_ci		} else {
21868c2ecf20Sopenharmony_ci			wm_high.yclk = rdev->pm.current_mclk * 10;
21878c2ecf20Sopenharmony_ci			wm_high.sclk = rdev->pm.current_sclk * 10;
21888c2ecf20Sopenharmony_ci		}
21898c2ecf20Sopenharmony_ci
21908c2ecf20Sopenharmony_ci		wm_high.disp_clk = mode->clock;
21918c2ecf20Sopenharmony_ci		wm_high.src_width = mode->crtc_hdisplay;
21928c2ecf20Sopenharmony_ci		wm_high.active_time = active_time;
21938c2ecf20Sopenharmony_ci		wm_high.blank_time = line_time - wm_high.active_time;
21948c2ecf20Sopenharmony_ci		wm_high.interlaced = false;
21958c2ecf20Sopenharmony_ci		if (mode->flags & DRM_MODE_FLAG_INTERLACE)
21968c2ecf20Sopenharmony_ci			wm_high.interlaced = true;
21978c2ecf20Sopenharmony_ci		wm_high.vsc = radeon_crtc->vsc;
21988c2ecf20Sopenharmony_ci		wm_high.vtaps = 1;
21998c2ecf20Sopenharmony_ci		if (radeon_crtc->rmx_type != RMX_OFF)
22008c2ecf20Sopenharmony_ci			wm_high.vtaps = 2;
22018c2ecf20Sopenharmony_ci		wm_high.bytes_per_pixel = 4; /* XXX: get this from fb config */
22028c2ecf20Sopenharmony_ci		wm_high.lb_size = lb_size;
22038c2ecf20Sopenharmony_ci		wm_high.dram_channels = dram_channels;
22048c2ecf20Sopenharmony_ci		wm_high.num_heads = num_heads;
22058c2ecf20Sopenharmony_ci
22068c2ecf20Sopenharmony_ci		/* watermark for low clocks */
22078c2ecf20Sopenharmony_ci		if ((rdev->pm.pm_method == PM_METHOD_DPM) && rdev->pm.dpm_enabled) {
22088c2ecf20Sopenharmony_ci			wm_low.yclk =
22098c2ecf20Sopenharmony_ci				radeon_dpm_get_mclk(rdev, true) * 10;
22108c2ecf20Sopenharmony_ci			wm_low.sclk =
22118c2ecf20Sopenharmony_ci				radeon_dpm_get_sclk(rdev, true) * 10;
22128c2ecf20Sopenharmony_ci		} else {
22138c2ecf20Sopenharmony_ci			wm_low.yclk = rdev->pm.current_mclk * 10;
22148c2ecf20Sopenharmony_ci			wm_low.sclk = rdev->pm.current_sclk * 10;
22158c2ecf20Sopenharmony_ci		}
22168c2ecf20Sopenharmony_ci
22178c2ecf20Sopenharmony_ci		wm_low.disp_clk = mode->clock;
22188c2ecf20Sopenharmony_ci		wm_low.src_width = mode->crtc_hdisplay;
22198c2ecf20Sopenharmony_ci		wm_low.active_time = active_time;
22208c2ecf20Sopenharmony_ci		wm_low.blank_time = line_time - wm_low.active_time;
22218c2ecf20Sopenharmony_ci		wm_low.interlaced = false;
22228c2ecf20Sopenharmony_ci		if (mode->flags & DRM_MODE_FLAG_INTERLACE)
22238c2ecf20Sopenharmony_ci			wm_low.interlaced = true;
22248c2ecf20Sopenharmony_ci		wm_low.vsc = radeon_crtc->vsc;
22258c2ecf20Sopenharmony_ci		wm_low.vtaps = 1;
22268c2ecf20Sopenharmony_ci		if (radeon_crtc->rmx_type != RMX_OFF)
22278c2ecf20Sopenharmony_ci			wm_low.vtaps = 2;
22288c2ecf20Sopenharmony_ci		wm_low.bytes_per_pixel = 4; /* XXX: get this from fb config */
22298c2ecf20Sopenharmony_ci		wm_low.lb_size = lb_size;
22308c2ecf20Sopenharmony_ci		wm_low.dram_channels = dram_channels;
22318c2ecf20Sopenharmony_ci		wm_low.num_heads = num_heads;
22328c2ecf20Sopenharmony_ci
22338c2ecf20Sopenharmony_ci		/* set for high clocks */
22348c2ecf20Sopenharmony_ci		latency_watermark_a = min(evergreen_latency_watermark(&wm_high), (u32)65535);
22358c2ecf20Sopenharmony_ci		/* set for low clocks */
22368c2ecf20Sopenharmony_ci		latency_watermark_b = min(evergreen_latency_watermark(&wm_low), (u32)65535);
22378c2ecf20Sopenharmony_ci
22388c2ecf20Sopenharmony_ci		/* possibly force display priority to high */
22398c2ecf20Sopenharmony_ci		/* should really do this at mode validation time... */
22408c2ecf20Sopenharmony_ci		if (!evergreen_average_bandwidth_vs_dram_bandwidth_for_display(&wm_high) ||
22418c2ecf20Sopenharmony_ci		    !evergreen_average_bandwidth_vs_available_bandwidth(&wm_high) ||
22428c2ecf20Sopenharmony_ci		    !evergreen_check_latency_hiding(&wm_high) ||
22438c2ecf20Sopenharmony_ci		    (rdev->disp_priority == 2)) {
22448c2ecf20Sopenharmony_ci			DRM_DEBUG_KMS("force priority a to high\n");
22458c2ecf20Sopenharmony_ci			priority_a_cnt |= PRIORITY_ALWAYS_ON;
22468c2ecf20Sopenharmony_ci		}
22478c2ecf20Sopenharmony_ci		if (!evergreen_average_bandwidth_vs_dram_bandwidth_for_display(&wm_low) ||
22488c2ecf20Sopenharmony_ci		    !evergreen_average_bandwidth_vs_available_bandwidth(&wm_low) ||
22498c2ecf20Sopenharmony_ci		    !evergreen_check_latency_hiding(&wm_low) ||
22508c2ecf20Sopenharmony_ci		    (rdev->disp_priority == 2)) {
22518c2ecf20Sopenharmony_ci			DRM_DEBUG_KMS("force priority b to high\n");
22528c2ecf20Sopenharmony_ci			priority_b_cnt |= PRIORITY_ALWAYS_ON;
22538c2ecf20Sopenharmony_ci		}
22548c2ecf20Sopenharmony_ci
22558c2ecf20Sopenharmony_ci		a.full = dfixed_const(1000);
22568c2ecf20Sopenharmony_ci		b.full = dfixed_const(mode->clock);
22578c2ecf20Sopenharmony_ci		b.full = dfixed_div(b, a);
22588c2ecf20Sopenharmony_ci		c.full = dfixed_const(latency_watermark_a);
22598c2ecf20Sopenharmony_ci		c.full = dfixed_mul(c, b);
22608c2ecf20Sopenharmony_ci		c.full = dfixed_mul(c, radeon_crtc->hsc);
22618c2ecf20Sopenharmony_ci		c.full = dfixed_div(c, a);
22628c2ecf20Sopenharmony_ci		a.full = dfixed_const(16);
22638c2ecf20Sopenharmony_ci		c.full = dfixed_div(c, a);
22648c2ecf20Sopenharmony_ci		priority_a_mark = dfixed_trunc(c);
22658c2ecf20Sopenharmony_ci		priority_a_cnt |= priority_a_mark & PRIORITY_MARK_MASK;
22668c2ecf20Sopenharmony_ci
22678c2ecf20Sopenharmony_ci		a.full = dfixed_const(1000);
22688c2ecf20Sopenharmony_ci		b.full = dfixed_const(mode->clock);
22698c2ecf20Sopenharmony_ci		b.full = dfixed_div(b, a);
22708c2ecf20Sopenharmony_ci		c.full = dfixed_const(latency_watermark_b);
22718c2ecf20Sopenharmony_ci		c.full = dfixed_mul(c, b);
22728c2ecf20Sopenharmony_ci		c.full = dfixed_mul(c, radeon_crtc->hsc);
22738c2ecf20Sopenharmony_ci		c.full = dfixed_div(c, a);
22748c2ecf20Sopenharmony_ci		a.full = dfixed_const(16);
22758c2ecf20Sopenharmony_ci		c.full = dfixed_div(c, a);
22768c2ecf20Sopenharmony_ci		priority_b_mark = dfixed_trunc(c);
22778c2ecf20Sopenharmony_ci		priority_b_cnt |= priority_b_mark & PRIORITY_MARK_MASK;
22788c2ecf20Sopenharmony_ci
22798c2ecf20Sopenharmony_ci		/* Save number of lines the linebuffer leads before the scanout */
22808c2ecf20Sopenharmony_ci		radeon_crtc->lb_vblank_lead_lines = DIV_ROUND_UP(lb_size, mode->crtc_hdisplay);
22818c2ecf20Sopenharmony_ci	}
22828c2ecf20Sopenharmony_ci
22838c2ecf20Sopenharmony_ci	/* select wm A */
22848c2ecf20Sopenharmony_ci	arb_control3 = RREG32(PIPE0_ARBITRATION_CONTROL3 + pipe_offset);
22858c2ecf20Sopenharmony_ci	tmp = arb_control3;
22868c2ecf20Sopenharmony_ci	tmp &= ~LATENCY_WATERMARK_MASK(3);
22878c2ecf20Sopenharmony_ci	tmp |= LATENCY_WATERMARK_MASK(1);
22888c2ecf20Sopenharmony_ci	WREG32(PIPE0_ARBITRATION_CONTROL3 + pipe_offset, tmp);
22898c2ecf20Sopenharmony_ci	WREG32(PIPE0_LATENCY_CONTROL + pipe_offset,
22908c2ecf20Sopenharmony_ci	       (LATENCY_LOW_WATERMARK(latency_watermark_a) |
22918c2ecf20Sopenharmony_ci		LATENCY_HIGH_WATERMARK(line_time)));
22928c2ecf20Sopenharmony_ci	/* select wm B */
22938c2ecf20Sopenharmony_ci	tmp = RREG32(PIPE0_ARBITRATION_CONTROL3 + pipe_offset);
22948c2ecf20Sopenharmony_ci	tmp &= ~LATENCY_WATERMARK_MASK(3);
22958c2ecf20Sopenharmony_ci	tmp |= LATENCY_WATERMARK_MASK(2);
22968c2ecf20Sopenharmony_ci	WREG32(PIPE0_ARBITRATION_CONTROL3 + pipe_offset, tmp);
22978c2ecf20Sopenharmony_ci	WREG32(PIPE0_LATENCY_CONTROL + pipe_offset,
22988c2ecf20Sopenharmony_ci	       (LATENCY_LOW_WATERMARK(latency_watermark_b) |
22998c2ecf20Sopenharmony_ci		LATENCY_HIGH_WATERMARK(line_time)));
23008c2ecf20Sopenharmony_ci	/* restore original selection */
23018c2ecf20Sopenharmony_ci	WREG32(PIPE0_ARBITRATION_CONTROL3 + pipe_offset, arb_control3);
23028c2ecf20Sopenharmony_ci
23038c2ecf20Sopenharmony_ci	/* write the priority marks */
23048c2ecf20Sopenharmony_ci	WREG32(PRIORITY_A_CNT + radeon_crtc->crtc_offset, priority_a_cnt);
23058c2ecf20Sopenharmony_ci	WREG32(PRIORITY_B_CNT + radeon_crtc->crtc_offset, priority_b_cnt);
23068c2ecf20Sopenharmony_ci
23078c2ecf20Sopenharmony_ci	/* save values for DPM */
23088c2ecf20Sopenharmony_ci	radeon_crtc->line_time = line_time;
23098c2ecf20Sopenharmony_ci	radeon_crtc->wm_high = latency_watermark_a;
23108c2ecf20Sopenharmony_ci	radeon_crtc->wm_low = latency_watermark_b;
23118c2ecf20Sopenharmony_ci}
23128c2ecf20Sopenharmony_ci
23138c2ecf20Sopenharmony_ci/**
23148c2ecf20Sopenharmony_ci * evergreen_bandwidth_update - update display watermarks callback.
23158c2ecf20Sopenharmony_ci *
23168c2ecf20Sopenharmony_ci * @rdev: radeon_device pointer
23178c2ecf20Sopenharmony_ci *
23188c2ecf20Sopenharmony_ci * Update the display watermarks based on the requested mode(s)
23198c2ecf20Sopenharmony_ci * (evergreen+).
23208c2ecf20Sopenharmony_ci */
23218c2ecf20Sopenharmony_civoid evergreen_bandwidth_update(struct radeon_device *rdev)
23228c2ecf20Sopenharmony_ci{
23238c2ecf20Sopenharmony_ci	struct drm_display_mode *mode0 = NULL;
23248c2ecf20Sopenharmony_ci	struct drm_display_mode *mode1 = NULL;
23258c2ecf20Sopenharmony_ci	u32 num_heads = 0, lb_size;
23268c2ecf20Sopenharmony_ci	int i;
23278c2ecf20Sopenharmony_ci
23288c2ecf20Sopenharmony_ci	if (!rdev->mode_info.mode_config_initialized)
23298c2ecf20Sopenharmony_ci		return;
23308c2ecf20Sopenharmony_ci
23318c2ecf20Sopenharmony_ci	radeon_update_display_priority(rdev);
23328c2ecf20Sopenharmony_ci
23338c2ecf20Sopenharmony_ci	for (i = 0; i < rdev->num_crtc; i++) {
23348c2ecf20Sopenharmony_ci		if (rdev->mode_info.crtcs[i]->base.enabled)
23358c2ecf20Sopenharmony_ci			num_heads++;
23368c2ecf20Sopenharmony_ci	}
23378c2ecf20Sopenharmony_ci	for (i = 0; i < rdev->num_crtc; i += 2) {
23388c2ecf20Sopenharmony_ci		mode0 = &rdev->mode_info.crtcs[i]->base.mode;
23398c2ecf20Sopenharmony_ci		mode1 = &rdev->mode_info.crtcs[i+1]->base.mode;
23408c2ecf20Sopenharmony_ci		lb_size = evergreen_line_buffer_adjust(rdev, rdev->mode_info.crtcs[i], mode0, mode1);
23418c2ecf20Sopenharmony_ci		evergreen_program_watermarks(rdev, rdev->mode_info.crtcs[i], lb_size, num_heads);
23428c2ecf20Sopenharmony_ci		lb_size = evergreen_line_buffer_adjust(rdev, rdev->mode_info.crtcs[i+1], mode1, mode0);
23438c2ecf20Sopenharmony_ci		evergreen_program_watermarks(rdev, rdev->mode_info.crtcs[i+1], lb_size, num_heads);
23448c2ecf20Sopenharmony_ci	}
23458c2ecf20Sopenharmony_ci}
23468c2ecf20Sopenharmony_ci
23478c2ecf20Sopenharmony_ci/**
23488c2ecf20Sopenharmony_ci * evergreen_mc_wait_for_idle - wait for MC idle callback.
23498c2ecf20Sopenharmony_ci *
23508c2ecf20Sopenharmony_ci * @rdev: radeon_device pointer
23518c2ecf20Sopenharmony_ci *
23528c2ecf20Sopenharmony_ci * Wait for the MC (memory controller) to be idle.
23538c2ecf20Sopenharmony_ci * (evergreen+).
23548c2ecf20Sopenharmony_ci * Returns 0 if the MC is idle, -1 if not.
23558c2ecf20Sopenharmony_ci */
23568c2ecf20Sopenharmony_ciint evergreen_mc_wait_for_idle(struct radeon_device *rdev)
23578c2ecf20Sopenharmony_ci{
23588c2ecf20Sopenharmony_ci	unsigned i;
23598c2ecf20Sopenharmony_ci	u32 tmp;
23608c2ecf20Sopenharmony_ci
23618c2ecf20Sopenharmony_ci	for (i = 0; i < rdev->usec_timeout; i++) {
23628c2ecf20Sopenharmony_ci		/* read MC_STATUS */
23638c2ecf20Sopenharmony_ci		tmp = RREG32(SRBM_STATUS) & 0x1F00;
23648c2ecf20Sopenharmony_ci		if (!tmp)
23658c2ecf20Sopenharmony_ci			return 0;
23668c2ecf20Sopenharmony_ci		udelay(1);
23678c2ecf20Sopenharmony_ci	}
23688c2ecf20Sopenharmony_ci	return -1;
23698c2ecf20Sopenharmony_ci}
23708c2ecf20Sopenharmony_ci
23718c2ecf20Sopenharmony_ci/*
23728c2ecf20Sopenharmony_ci * GART
23738c2ecf20Sopenharmony_ci */
23748c2ecf20Sopenharmony_civoid evergreen_pcie_gart_tlb_flush(struct radeon_device *rdev)
23758c2ecf20Sopenharmony_ci{
23768c2ecf20Sopenharmony_ci	unsigned i;
23778c2ecf20Sopenharmony_ci	u32 tmp;
23788c2ecf20Sopenharmony_ci
23798c2ecf20Sopenharmony_ci	WREG32(HDP_MEM_COHERENCY_FLUSH_CNTL, 0x1);
23808c2ecf20Sopenharmony_ci
23818c2ecf20Sopenharmony_ci	WREG32(VM_CONTEXT0_REQUEST_RESPONSE, REQUEST_TYPE(1));
23828c2ecf20Sopenharmony_ci	for (i = 0; i < rdev->usec_timeout; i++) {
23838c2ecf20Sopenharmony_ci		/* read MC_STATUS */
23848c2ecf20Sopenharmony_ci		tmp = RREG32(VM_CONTEXT0_REQUEST_RESPONSE);
23858c2ecf20Sopenharmony_ci		tmp = (tmp & RESPONSE_TYPE_MASK) >> RESPONSE_TYPE_SHIFT;
23868c2ecf20Sopenharmony_ci		if (tmp == 2) {
23878c2ecf20Sopenharmony_ci			pr_warn("[drm] r600 flush TLB failed\n");
23888c2ecf20Sopenharmony_ci			return;
23898c2ecf20Sopenharmony_ci		}
23908c2ecf20Sopenharmony_ci		if (tmp) {
23918c2ecf20Sopenharmony_ci			return;
23928c2ecf20Sopenharmony_ci		}
23938c2ecf20Sopenharmony_ci		udelay(1);
23948c2ecf20Sopenharmony_ci	}
23958c2ecf20Sopenharmony_ci}
23968c2ecf20Sopenharmony_ci
23978c2ecf20Sopenharmony_cistatic int evergreen_pcie_gart_enable(struct radeon_device *rdev)
23988c2ecf20Sopenharmony_ci{
23998c2ecf20Sopenharmony_ci	u32 tmp;
24008c2ecf20Sopenharmony_ci	int r;
24018c2ecf20Sopenharmony_ci
24028c2ecf20Sopenharmony_ci	if (rdev->gart.robj == NULL) {
24038c2ecf20Sopenharmony_ci		dev_err(rdev->dev, "No VRAM object for PCIE GART.\n");
24048c2ecf20Sopenharmony_ci		return -EINVAL;
24058c2ecf20Sopenharmony_ci	}
24068c2ecf20Sopenharmony_ci	r = radeon_gart_table_vram_pin(rdev);
24078c2ecf20Sopenharmony_ci	if (r)
24088c2ecf20Sopenharmony_ci		return r;
24098c2ecf20Sopenharmony_ci	/* Setup L2 cache */
24108c2ecf20Sopenharmony_ci	WREG32(VM_L2_CNTL, ENABLE_L2_CACHE | ENABLE_L2_FRAGMENT_PROCESSING |
24118c2ecf20Sopenharmony_ci				ENABLE_L2_PTE_CACHE_LRU_UPDATE_BY_WRITE |
24128c2ecf20Sopenharmony_ci				EFFECTIVE_L2_QUEUE_SIZE(7));
24138c2ecf20Sopenharmony_ci	WREG32(VM_L2_CNTL2, 0);
24148c2ecf20Sopenharmony_ci	WREG32(VM_L2_CNTL3, BANK_SELECT(0) | CACHE_UPDATE_MODE(2));
24158c2ecf20Sopenharmony_ci	/* Setup TLB control */
24168c2ecf20Sopenharmony_ci	tmp = ENABLE_L1_TLB | ENABLE_L1_FRAGMENT_PROCESSING |
24178c2ecf20Sopenharmony_ci		SYSTEM_ACCESS_MODE_NOT_IN_SYS |
24188c2ecf20Sopenharmony_ci		SYSTEM_APERTURE_UNMAPPED_ACCESS_PASS_THRU |
24198c2ecf20Sopenharmony_ci		EFFECTIVE_L1_TLB_SIZE(5) | EFFECTIVE_L1_QUEUE_SIZE(5);
24208c2ecf20Sopenharmony_ci	if (rdev->flags & RADEON_IS_IGP) {
24218c2ecf20Sopenharmony_ci		WREG32(FUS_MC_VM_MD_L1_TLB0_CNTL, tmp);
24228c2ecf20Sopenharmony_ci		WREG32(FUS_MC_VM_MD_L1_TLB1_CNTL, tmp);
24238c2ecf20Sopenharmony_ci		WREG32(FUS_MC_VM_MD_L1_TLB2_CNTL, tmp);
24248c2ecf20Sopenharmony_ci	} else {
24258c2ecf20Sopenharmony_ci		WREG32(MC_VM_MD_L1_TLB0_CNTL, tmp);
24268c2ecf20Sopenharmony_ci		WREG32(MC_VM_MD_L1_TLB1_CNTL, tmp);
24278c2ecf20Sopenharmony_ci		WREG32(MC_VM_MD_L1_TLB2_CNTL, tmp);
24288c2ecf20Sopenharmony_ci		if ((rdev->family == CHIP_JUNIPER) ||
24298c2ecf20Sopenharmony_ci		    (rdev->family == CHIP_CYPRESS) ||
24308c2ecf20Sopenharmony_ci		    (rdev->family == CHIP_HEMLOCK) ||
24318c2ecf20Sopenharmony_ci		    (rdev->family == CHIP_BARTS))
24328c2ecf20Sopenharmony_ci			WREG32(MC_VM_MD_L1_TLB3_CNTL, tmp);
24338c2ecf20Sopenharmony_ci	}
24348c2ecf20Sopenharmony_ci	WREG32(MC_VM_MB_L1_TLB0_CNTL, tmp);
24358c2ecf20Sopenharmony_ci	WREG32(MC_VM_MB_L1_TLB1_CNTL, tmp);
24368c2ecf20Sopenharmony_ci	WREG32(MC_VM_MB_L1_TLB2_CNTL, tmp);
24378c2ecf20Sopenharmony_ci	WREG32(MC_VM_MB_L1_TLB3_CNTL, tmp);
24388c2ecf20Sopenharmony_ci	WREG32(VM_CONTEXT0_PAGE_TABLE_START_ADDR, rdev->mc.gtt_start >> 12);
24398c2ecf20Sopenharmony_ci	WREG32(VM_CONTEXT0_PAGE_TABLE_END_ADDR, rdev->mc.gtt_end >> 12);
24408c2ecf20Sopenharmony_ci	WREG32(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR, rdev->gart.table_addr >> 12);
24418c2ecf20Sopenharmony_ci	WREG32(VM_CONTEXT0_CNTL, ENABLE_CONTEXT | PAGE_TABLE_DEPTH(0) |
24428c2ecf20Sopenharmony_ci				RANGE_PROTECTION_FAULT_ENABLE_DEFAULT);
24438c2ecf20Sopenharmony_ci	WREG32(VM_CONTEXT0_PROTECTION_FAULT_DEFAULT_ADDR,
24448c2ecf20Sopenharmony_ci			(u32)(rdev->dummy_page.addr >> 12));
24458c2ecf20Sopenharmony_ci	WREG32(VM_CONTEXT1_CNTL, 0);
24468c2ecf20Sopenharmony_ci
24478c2ecf20Sopenharmony_ci	evergreen_pcie_gart_tlb_flush(rdev);
24488c2ecf20Sopenharmony_ci	DRM_INFO("PCIE GART of %uM enabled (table at 0x%016llX).\n",
24498c2ecf20Sopenharmony_ci		 (unsigned)(rdev->mc.gtt_size >> 20),
24508c2ecf20Sopenharmony_ci		 (unsigned long long)rdev->gart.table_addr);
24518c2ecf20Sopenharmony_ci	rdev->gart.ready = true;
24528c2ecf20Sopenharmony_ci	return 0;
24538c2ecf20Sopenharmony_ci}
24548c2ecf20Sopenharmony_ci
24558c2ecf20Sopenharmony_cistatic void evergreen_pcie_gart_disable(struct radeon_device *rdev)
24568c2ecf20Sopenharmony_ci{
24578c2ecf20Sopenharmony_ci	u32 tmp;
24588c2ecf20Sopenharmony_ci
24598c2ecf20Sopenharmony_ci	/* Disable all tables */
24608c2ecf20Sopenharmony_ci	WREG32(VM_CONTEXT0_CNTL, 0);
24618c2ecf20Sopenharmony_ci	WREG32(VM_CONTEXT1_CNTL, 0);
24628c2ecf20Sopenharmony_ci
24638c2ecf20Sopenharmony_ci	/* Setup L2 cache */
24648c2ecf20Sopenharmony_ci	WREG32(VM_L2_CNTL, ENABLE_L2_FRAGMENT_PROCESSING |
24658c2ecf20Sopenharmony_ci				EFFECTIVE_L2_QUEUE_SIZE(7));
24668c2ecf20Sopenharmony_ci	WREG32(VM_L2_CNTL2, 0);
24678c2ecf20Sopenharmony_ci	WREG32(VM_L2_CNTL3, BANK_SELECT(0) | CACHE_UPDATE_MODE(2));
24688c2ecf20Sopenharmony_ci	/* Setup TLB control */
24698c2ecf20Sopenharmony_ci	tmp = EFFECTIVE_L1_TLB_SIZE(5) | EFFECTIVE_L1_QUEUE_SIZE(5);
24708c2ecf20Sopenharmony_ci	WREG32(MC_VM_MD_L1_TLB0_CNTL, tmp);
24718c2ecf20Sopenharmony_ci	WREG32(MC_VM_MD_L1_TLB1_CNTL, tmp);
24728c2ecf20Sopenharmony_ci	WREG32(MC_VM_MD_L1_TLB2_CNTL, tmp);
24738c2ecf20Sopenharmony_ci	WREG32(MC_VM_MB_L1_TLB0_CNTL, tmp);
24748c2ecf20Sopenharmony_ci	WREG32(MC_VM_MB_L1_TLB1_CNTL, tmp);
24758c2ecf20Sopenharmony_ci	WREG32(MC_VM_MB_L1_TLB2_CNTL, tmp);
24768c2ecf20Sopenharmony_ci	WREG32(MC_VM_MB_L1_TLB3_CNTL, tmp);
24778c2ecf20Sopenharmony_ci	radeon_gart_table_vram_unpin(rdev);
24788c2ecf20Sopenharmony_ci}
24798c2ecf20Sopenharmony_ci
24808c2ecf20Sopenharmony_cistatic void evergreen_pcie_gart_fini(struct radeon_device *rdev)
24818c2ecf20Sopenharmony_ci{
24828c2ecf20Sopenharmony_ci	evergreen_pcie_gart_disable(rdev);
24838c2ecf20Sopenharmony_ci	radeon_gart_table_vram_free(rdev);
24848c2ecf20Sopenharmony_ci	radeon_gart_fini(rdev);
24858c2ecf20Sopenharmony_ci}
24868c2ecf20Sopenharmony_ci
24878c2ecf20Sopenharmony_ci
24888c2ecf20Sopenharmony_cistatic void evergreen_agp_enable(struct radeon_device *rdev)
24898c2ecf20Sopenharmony_ci{
24908c2ecf20Sopenharmony_ci	u32 tmp;
24918c2ecf20Sopenharmony_ci
24928c2ecf20Sopenharmony_ci	/* Setup L2 cache */
24938c2ecf20Sopenharmony_ci	WREG32(VM_L2_CNTL, ENABLE_L2_CACHE | ENABLE_L2_FRAGMENT_PROCESSING |
24948c2ecf20Sopenharmony_ci				ENABLE_L2_PTE_CACHE_LRU_UPDATE_BY_WRITE |
24958c2ecf20Sopenharmony_ci				EFFECTIVE_L2_QUEUE_SIZE(7));
24968c2ecf20Sopenharmony_ci	WREG32(VM_L2_CNTL2, 0);
24978c2ecf20Sopenharmony_ci	WREG32(VM_L2_CNTL3, BANK_SELECT(0) | CACHE_UPDATE_MODE(2));
24988c2ecf20Sopenharmony_ci	/* Setup TLB control */
24998c2ecf20Sopenharmony_ci	tmp = ENABLE_L1_TLB | ENABLE_L1_FRAGMENT_PROCESSING |
25008c2ecf20Sopenharmony_ci		SYSTEM_ACCESS_MODE_NOT_IN_SYS |
25018c2ecf20Sopenharmony_ci		SYSTEM_APERTURE_UNMAPPED_ACCESS_PASS_THRU |
25028c2ecf20Sopenharmony_ci		EFFECTIVE_L1_TLB_SIZE(5) | EFFECTIVE_L1_QUEUE_SIZE(5);
25038c2ecf20Sopenharmony_ci	WREG32(MC_VM_MD_L1_TLB0_CNTL, tmp);
25048c2ecf20Sopenharmony_ci	WREG32(MC_VM_MD_L1_TLB1_CNTL, tmp);
25058c2ecf20Sopenharmony_ci	WREG32(MC_VM_MD_L1_TLB2_CNTL, tmp);
25068c2ecf20Sopenharmony_ci	WREG32(MC_VM_MB_L1_TLB0_CNTL, tmp);
25078c2ecf20Sopenharmony_ci	WREG32(MC_VM_MB_L1_TLB1_CNTL, tmp);
25088c2ecf20Sopenharmony_ci	WREG32(MC_VM_MB_L1_TLB2_CNTL, tmp);
25098c2ecf20Sopenharmony_ci	WREG32(MC_VM_MB_L1_TLB3_CNTL, tmp);
25108c2ecf20Sopenharmony_ci	WREG32(VM_CONTEXT0_CNTL, 0);
25118c2ecf20Sopenharmony_ci	WREG32(VM_CONTEXT1_CNTL, 0);
25128c2ecf20Sopenharmony_ci}
25138c2ecf20Sopenharmony_ci
25148c2ecf20Sopenharmony_cistatic const unsigned ni_dig_offsets[] =
25158c2ecf20Sopenharmony_ci{
25168c2ecf20Sopenharmony_ci	NI_DIG0_REGISTER_OFFSET,
25178c2ecf20Sopenharmony_ci	NI_DIG1_REGISTER_OFFSET,
25188c2ecf20Sopenharmony_ci	NI_DIG2_REGISTER_OFFSET,
25198c2ecf20Sopenharmony_ci	NI_DIG3_REGISTER_OFFSET,
25208c2ecf20Sopenharmony_ci	NI_DIG4_REGISTER_OFFSET,
25218c2ecf20Sopenharmony_ci	NI_DIG5_REGISTER_OFFSET
25228c2ecf20Sopenharmony_ci};
25238c2ecf20Sopenharmony_ci
25248c2ecf20Sopenharmony_cistatic const unsigned ni_tx_offsets[] =
25258c2ecf20Sopenharmony_ci{
25268c2ecf20Sopenharmony_ci	NI_DCIO_UNIPHY0_UNIPHY_TX_CONTROL1,
25278c2ecf20Sopenharmony_ci	NI_DCIO_UNIPHY1_UNIPHY_TX_CONTROL1,
25288c2ecf20Sopenharmony_ci	NI_DCIO_UNIPHY2_UNIPHY_TX_CONTROL1,
25298c2ecf20Sopenharmony_ci	NI_DCIO_UNIPHY3_UNIPHY_TX_CONTROL1,
25308c2ecf20Sopenharmony_ci	NI_DCIO_UNIPHY4_UNIPHY_TX_CONTROL1,
25318c2ecf20Sopenharmony_ci	NI_DCIO_UNIPHY5_UNIPHY_TX_CONTROL1
25328c2ecf20Sopenharmony_ci};
25338c2ecf20Sopenharmony_ci
25348c2ecf20Sopenharmony_cistatic const unsigned evergreen_dp_offsets[] =
25358c2ecf20Sopenharmony_ci{
25368c2ecf20Sopenharmony_ci	EVERGREEN_DP0_REGISTER_OFFSET,
25378c2ecf20Sopenharmony_ci	EVERGREEN_DP1_REGISTER_OFFSET,
25388c2ecf20Sopenharmony_ci	EVERGREEN_DP2_REGISTER_OFFSET,
25398c2ecf20Sopenharmony_ci	EVERGREEN_DP3_REGISTER_OFFSET,
25408c2ecf20Sopenharmony_ci	EVERGREEN_DP4_REGISTER_OFFSET,
25418c2ecf20Sopenharmony_ci	EVERGREEN_DP5_REGISTER_OFFSET
25428c2ecf20Sopenharmony_ci};
25438c2ecf20Sopenharmony_ci
25448c2ecf20Sopenharmony_cistatic const unsigned evergreen_disp_int_status[] =
25458c2ecf20Sopenharmony_ci{
25468c2ecf20Sopenharmony_ci	DISP_INTERRUPT_STATUS,
25478c2ecf20Sopenharmony_ci	DISP_INTERRUPT_STATUS_CONTINUE,
25488c2ecf20Sopenharmony_ci	DISP_INTERRUPT_STATUS_CONTINUE2,
25498c2ecf20Sopenharmony_ci	DISP_INTERRUPT_STATUS_CONTINUE3,
25508c2ecf20Sopenharmony_ci	DISP_INTERRUPT_STATUS_CONTINUE4,
25518c2ecf20Sopenharmony_ci	DISP_INTERRUPT_STATUS_CONTINUE5
25528c2ecf20Sopenharmony_ci};
25538c2ecf20Sopenharmony_ci
25548c2ecf20Sopenharmony_ci/*
25558c2ecf20Sopenharmony_ci * Assumption is that EVERGREEN_CRTC_MASTER_EN enable for requested crtc
25568c2ecf20Sopenharmony_ci * We go from crtc to connector and it is not relible  since it
25578c2ecf20Sopenharmony_ci * should be an opposite direction .If crtc is enable then
25588c2ecf20Sopenharmony_ci * find the dig_fe which selects this crtc and insure that it enable.
25598c2ecf20Sopenharmony_ci * if such dig_fe is found then find dig_be which selects found dig_be and
25608c2ecf20Sopenharmony_ci * insure that it enable and in DP_SST mode.
25618c2ecf20Sopenharmony_ci * if UNIPHY_PLL_CONTROL1.enable then we should disconnect timing
25628c2ecf20Sopenharmony_ci * from dp symbols clocks .
25638c2ecf20Sopenharmony_ci */
25648c2ecf20Sopenharmony_cistatic bool evergreen_is_dp_sst_stream_enabled(struct radeon_device *rdev,
25658c2ecf20Sopenharmony_ci					       unsigned crtc_id, unsigned *ret_dig_fe)
25668c2ecf20Sopenharmony_ci{
25678c2ecf20Sopenharmony_ci	unsigned i;
25688c2ecf20Sopenharmony_ci	unsigned dig_fe;
25698c2ecf20Sopenharmony_ci	unsigned dig_be;
25708c2ecf20Sopenharmony_ci	unsigned dig_en_be;
25718c2ecf20Sopenharmony_ci	unsigned uniphy_pll;
25728c2ecf20Sopenharmony_ci	unsigned digs_fe_selected;
25738c2ecf20Sopenharmony_ci	unsigned dig_be_mode;
25748c2ecf20Sopenharmony_ci	unsigned dig_fe_mask;
25758c2ecf20Sopenharmony_ci	bool is_enabled = false;
25768c2ecf20Sopenharmony_ci	bool found_crtc = false;
25778c2ecf20Sopenharmony_ci
25788c2ecf20Sopenharmony_ci	/* loop through all running dig_fe to find selected crtc */
25798c2ecf20Sopenharmony_ci	for (i = 0; i < ARRAY_SIZE(ni_dig_offsets); i++) {
25808c2ecf20Sopenharmony_ci		dig_fe = RREG32(NI_DIG_FE_CNTL + ni_dig_offsets[i]);
25818c2ecf20Sopenharmony_ci		if (dig_fe & NI_DIG_FE_CNTL_SYMCLK_FE_ON &&
25828c2ecf20Sopenharmony_ci		    crtc_id == NI_DIG_FE_CNTL_SOURCE_SELECT(dig_fe)) {
25838c2ecf20Sopenharmony_ci			/* found running pipe */
25848c2ecf20Sopenharmony_ci			found_crtc = true;
25858c2ecf20Sopenharmony_ci			dig_fe_mask = 1 << i;
25868c2ecf20Sopenharmony_ci			dig_fe = i;
25878c2ecf20Sopenharmony_ci			break;
25888c2ecf20Sopenharmony_ci		}
25898c2ecf20Sopenharmony_ci	}
25908c2ecf20Sopenharmony_ci
25918c2ecf20Sopenharmony_ci	if (found_crtc) {
25928c2ecf20Sopenharmony_ci		/* loop through all running dig_be to find selected dig_fe */
25938c2ecf20Sopenharmony_ci		for (i = 0; i < ARRAY_SIZE(ni_dig_offsets); i++) {
25948c2ecf20Sopenharmony_ci			dig_be = RREG32(NI_DIG_BE_CNTL + ni_dig_offsets[i]);
25958c2ecf20Sopenharmony_ci			/* if dig_fe_selected by dig_be? */
25968c2ecf20Sopenharmony_ci			digs_fe_selected = NI_DIG_BE_CNTL_FE_SOURCE_SELECT(dig_be);
25978c2ecf20Sopenharmony_ci			dig_be_mode = NI_DIG_FE_CNTL_MODE(dig_be);
25988c2ecf20Sopenharmony_ci			if (dig_fe_mask &  digs_fe_selected &&
25998c2ecf20Sopenharmony_ci			    /* if dig_be in sst mode? */
26008c2ecf20Sopenharmony_ci			    dig_be_mode == NI_DIG_BE_DPSST) {
26018c2ecf20Sopenharmony_ci				dig_en_be = RREG32(NI_DIG_BE_EN_CNTL +
26028c2ecf20Sopenharmony_ci						   ni_dig_offsets[i]);
26038c2ecf20Sopenharmony_ci				uniphy_pll = RREG32(NI_DCIO_UNIPHY0_PLL_CONTROL1 +
26048c2ecf20Sopenharmony_ci						    ni_tx_offsets[i]);
26058c2ecf20Sopenharmony_ci				/* dig_be enable and tx is running */
26068c2ecf20Sopenharmony_ci				if (dig_en_be & NI_DIG_BE_EN_CNTL_ENABLE &&
26078c2ecf20Sopenharmony_ci				    dig_en_be & NI_DIG_BE_EN_CNTL_SYMBCLK_ON &&
26088c2ecf20Sopenharmony_ci				    uniphy_pll & NI_DCIO_UNIPHY0_PLL_CONTROL1_ENABLE) {
26098c2ecf20Sopenharmony_ci					is_enabled = true;
26108c2ecf20Sopenharmony_ci					*ret_dig_fe = dig_fe;
26118c2ecf20Sopenharmony_ci					break;
26128c2ecf20Sopenharmony_ci				}
26138c2ecf20Sopenharmony_ci			}
26148c2ecf20Sopenharmony_ci		}
26158c2ecf20Sopenharmony_ci	}
26168c2ecf20Sopenharmony_ci
26178c2ecf20Sopenharmony_ci	return is_enabled;
26188c2ecf20Sopenharmony_ci}
26198c2ecf20Sopenharmony_ci
26208c2ecf20Sopenharmony_ci/*
26218c2ecf20Sopenharmony_ci * Blank dig when in dp sst mode
26228c2ecf20Sopenharmony_ci * Dig ignores crtc timing
26238c2ecf20Sopenharmony_ci */
26248c2ecf20Sopenharmony_cistatic void evergreen_blank_dp_output(struct radeon_device *rdev,
26258c2ecf20Sopenharmony_ci				      unsigned dig_fe)
26268c2ecf20Sopenharmony_ci{
26278c2ecf20Sopenharmony_ci	unsigned stream_ctrl;
26288c2ecf20Sopenharmony_ci	unsigned fifo_ctrl;
26298c2ecf20Sopenharmony_ci	unsigned counter = 0;
26308c2ecf20Sopenharmony_ci
26318c2ecf20Sopenharmony_ci	if (dig_fe >= ARRAY_SIZE(evergreen_dp_offsets)) {
26328c2ecf20Sopenharmony_ci		DRM_ERROR("invalid dig_fe %d\n", dig_fe);
26338c2ecf20Sopenharmony_ci		return;
26348c2ecf20Sopenharmony_ci	}
26358c2ecf20Sopenharmony_ci
26368c2ecf20Sopenharmony_ci	stream_ctrl = RREG32(EVERGREEN_DP_VID_STREAM_CNTL +
26378c2ecf20Sopenharmony_ci			     evergreen_dp_offsets[dig_fe]);
26388c2ecf20Sopenharmony_ci	if (!(stream_ctrl & EVERGREEN_DP_VID_STREAM_CNTL_ENABLE)) {
26398c2ecf20Sopenharmony_ci		DRM_ERROR("dig %d , should be enable\n", dig_fe);
26408c2ecf20Sopenharmony_ci		return;
26418c2ecf20Sopenharmony_ci	}
26428c2ecf20Sopenharmony_ci
26438c2ecf20Sopenharmony_ci	stream_ctrl &=~EVERGREEN_DP_VID_STREAM_CNTL_ENABLE;
26448c2ecf20Sopenharmony_ci	WREG32(EVERGREEN_DP_VID_STREAM_CNTL +
26458c2ecf20Sopenharmony_ci	       evergreen_dp_offsets[dig_fe], stream_ctrl);
26468c2ecf20Sopenharmony_ci
26478c2ecf20Sopenharmony_ci	stream_ctrl = RREG32(EVERGREEN_DP_VID_STREAM_CNTL +
26488c2ecf20Sopenharmony_ci			     evergreen_dp_offsets[dig_fe]);
26498c2ecf20Sopenharmony_ci	while (counter < 32 && stream_ctrl & EVERGREEN_DP_VID_STREAM_STATUS) {
26508c2ecf20Sopenharmony_ci		msleep(1);
26518c2ecf20Sopenharmony_ci		counter++;
26528c2ecf20Sopenharmony_ci		stream_ctrl = RREG32(EVERGREEN_DP_VID_STREAM_CNTL +
26538c2ecf20Sopenharmony_ci				     evergreen_dp_offsets[dig_fe]);
26548c2ecf20Sopenharmony_ci	}
26558c2ecf20Sopenharmony_ci	if (counter >= 32 )
26568c2ecf20Sopenharmony_ci		DRM_ERROR("counter exceeds %d\n", counter);
26578c2ecf20Sopenharmony_ci
26588c2ecf20Sopenharmony_ci	fifo_ctrl = RREG32(EVERGREEN_DP_STEER_FIFO + evergreen_dp_offsets[dig_fe]);
26598c2ecf20Sopenharmony_ci	fifo_ctrl |= EVERGREEN_DP_STEER_FIFO_RESET;
26608c2ecf20Sopenharmony_ci	WREG32(EVERGREEN_DP_STEER_FIFO + evergreen_dp_offsets[dig_fe], fifo_ctrl);
26618c2ecf20Sopenharmony_ci
26628c2ecf20Sopenharmony_ci}
26638c2ecf20Sopenharmony_ci
26648c2ecf20Sopenharmony_civoid evergreen_mc_stop(struct radeon_device *rdev, struct evergreen_mc_save *save)
26658c2ecf20Sopenharmony_ci{
26668c2ecf20Sopenharmony_ci	u32 crtc_enabled, tmp, frame_count, blackout;
26678c2ecf20Sopenharmony_ci	int i, j;
26688c2ecf20Sopenharmony_ci	unsigned dig_fe;
26698c2ecf20Sopenharmony_ci
26708c2ecf20Sopenharmony_ci	if (!ASIC_IS_NODCE(rdev)) {
26718c2ecf20Sopenharmony_ci		save->vga_render_control = RREG32(VGA_RENDER_CONTROL);
26728c2ecf20Sopenharmony_ci		save->vga_hdp_control = RREG32(VGA_HDP_CONTROL);
26738c2ecf20Sopenharmony_ci
26748c2ecf20Sopenharmony_ci		/* disable VGA render */
26758c2ecf20Sopenharmony_ci		WREG32(VGA_RENDER_CONTROL, 0);
26768c2ecf20Sopenharmony_ci	}
26778c2ecf20Sopenharmony_ci	/* blank the display controllers */
26788c2ecf20Sopenharmony_ci	for (i = 0; i < rdev->num_crtc; i++) {
26798c2ecf20Sopenharmony_ci		crtc_enabled = RREG32(EVERGREEN_CRTC_CONTROL + crtc_offsets[i]) & EVERGREEN_CRTC_MASTER_EN;
26808c2ecf20Sopenharmony_ci		if (crtc_enabled) {
26818c2ecf20Sopenharmony_ci			save->crtc_enabled[i] = true;
26828c2ecf20Sopenharmony_ci			if (ASIC_IS_DCE6(rdev)) {
26838c2ecf20Sopenharmony_ci				tmp = RREG32(EVERGREEN_CRTC_BLANK_CONTROL + crtc_offsets[i]);
26848c2ecf20Sopenharmony_ci				if (!(tmp & EVERGREEN_CRTC_BLANK_DATA_EN)) {
26858c2ecf20Sopenharmony_ci					radeon_wait_for_vblank(rdev, i);
26868c2ecf20Sopenharmony_ci					WREG32(EVERGREEN_CRTC_UPDATE_LOCK + crtc_offsets[i], 1);
26878c2ecf20Sopenharmony_ci					tmp |= EVERGREEN_CRTC_BLANK_DATA_EN;
26888c2ecf20Sopenharmony_ci					WREG32(EVERGREEN_CRTC_BLANK_CONTROL + crtc_offsets[i], tmp);
26898c2ecf20Sopenharmony_ci					WREG32(EVERGREEN_CRTC_UPDATE_LOCK + crtc_offsets[i], 0);
26908c2ecf20Sopenharmony_ci				}
26918c2ecf20Sopenharmony_ci			} else {
26928c2ecf20Sopenharmony_ci				tmp = RREG32(EVERGREEN_CRTC_CONTROL + crtc_offsets[i]);
26938c2ecf20Sopenharmony_ci				if (!(tmp & EVERGREEN_CRTC_DISP_READ_REQUEST_DISABLE)) {
26948c2ecf20Sopenharmony_ci					radeon_wait_for_vblank(rdev, i);
26958c2ecf20Sopenharmony_ci					WREG32(EVERGREEN_CRTC_UPDATE_LOCK + crtc_offsets[i], 1);
26968c2ecf20Sopenharmony_ci					tmp |= EVERGREEN_CRTC_DISP_READ_REQUEST_DISABLE;
26978c2ecf20Sopenharmony_ci					WREG32(EVERGREEN_CRTC_CONTROL + crtc_offsets[i], tmp);
26988c2ecf20Sopenharmony_ci					WREG32(EVERGREEN_CRTC_UPDATE_LOCK + crtc_offsets[i], 0);
26998c2ecf20Sopenharmony_ci				}
27008c2ecf20Sopenharmony_ci			}
27018c2ecf20Sopenharmony_ci			/* wait for the next frame */
27028c2ecf20Sopenharmony_ci			frame_count = radeon_get_vblank_counter(rdev, i);
27038c2ecf20Sopenharmony_ci			for (j = 0; j < rdev->usec_timeout; j++) {
27048c2ecf20Sopenharmony_ci				if (radeon_get_vblank_counter(rdev, i) != frame_count)
27058c2ecf20Sopenharmony_ci					break;
27068c2ecf20Sopenharmony_ci				udelay(1);
27078c2ecf20Sopenharmony_ci			}
27088c2ecf20Sopenharmony_ci			/*we should disable dig if it drives dp sst*/
27098c2ecf20Sopenharmony_ci			/*but we are in radeon_device_init and the topology is unknown*/
27108c2ecf20Sopenharmony_ci			/*and it is available after radeon_modeset_init*/
27118c2ecf20Sopenharmony_ci			/*the following method radeon_atom_encoder_dpms_dig*/
27128c2ecf20Sopenharmony_ci			/*does the job if we initialize it properly*/
27138c2ecf20Sopenharmony_ci			/*for now we do it this manually*/
27148c2ecf20Sopenharmony_ci			/**/
27158c2ecf20Sopenharmony_ci			if (ASIC_IS_DCE5(rdev) &&
27168c2ecf20Sopenharmony_ci			    evergreen_is_dp_sst_stream_enabled(rdev, i ,&dig_fe))
27178c2ecf20Sopenharmony_ci				evergreen_blank_dp_output(rdev, dig_fe);
27188c2ecf20Sopenharmony_ci			/*we could remove 6 lines below*/
27198c2ecf20Sopenharmony_ci			/* XXX this is a hack to avoid strange behavior with EFI on certain systems */
27208c2ecf20Sopenharmony_ci			WREG32(EVERGREEN_CRTC_UPDATE_LOCK + crtc_offsets[i], 1);
27218c2ecf20Sopenharmony_ci			tmp = RREG32(EVERGREEN_CRTC_CONTROL + crtc_offsets[i]);
27228c2ecf20Sopenharmony_ci			tmp &= ~EVERGREEN_CRTC_MASTER_EN;
27238c2ecf20Sopenharmony_ci			WREG32(EVERGREEN_CRTC_CONTROL + crtc_offsets[i], tmp);
27248c2ecf20Sopenharmony_ci			WREG32(EVERGREEN_CRTC_UPDATE_LOCK + crtc_offsets[i], 0);
27258c2ecf20Sopenharmony_ci			save->crtc_enabled[i] = false;
27268c2ecf20Sopenharmony_ci			/* ***** */
27278c2ecf20Sopenharmony_ci		} else {
27288c2ecf20Sopenharmony_ci			save->crtc_enabled[i] = false;
27298c2ecf20Sopenharmony_ci		}
27308c2ecf20Sopenharmony_ci	}
27318c2ecf20Sopenharmony_ci
27328c2ecf20Sopenharmony_ci	radeon_mc_wait_for_idle(rdev);
27338c2ecf20Sopenharmony_ci
27348c2ecf20Sopenharmony_ci	blackout = RREG32(MC_SHARED_BLACKOUT_CNTL);
27358c2ecf20Sopenharmony_ci	if ((blackout & BLACKOUT_MODE_MASK) != 1) {
27368c2ecf20Sopenharmony_ci		/* Block CPU access */
27378c2ecf20Sopenharmony_ci		WREG32(BIF_FB_EN, 0);
27388c2ecf20Sopenharmony_ci		/* blackout the MC */
27398c2ecf20Sopenharmony_ci		blackout &= ~BLACKOUT_MODE_MASK;
27408c2ecf20Sopenharmony_ci		WREG32(MC_SHARED_BLACKOUT_CNTL, blackout | 1);
27418c2ecf20Sopenharmony_ci	}
27428c2ecf20Sopenharmony_ci	/* wait for the MC to settle */
27438c2ecf20Sopenharmony_ci	udelay(100);
27448c2ecf20Sopenharmony_ci
27458c2ecf20Sopenharmony_ci	/* lock double buffered regs */
27468c2ecf20Sopenharmony_ci	for (i = 0; i < rdev->num_crtc; i++) {
27478c2ecf20Sopenharmony_ci		if (save->crtc_enabled[i]) {
27488c2ecf20Sopenharmony_ci			tmp = RREG32(EVERGREEN_GRPH_UPDATE + crtc_offsets[i]);
27498c2ecf20Sopenharmony_ci			if (!(tmp & EVERGREEN_GRPH_UPDATE_LOCK)) {
27508c2ecf20Sopenharmony_ci				tmp |= EVERGREEN_GRPH_UPDATE_LOCK;
27518c2ecf20Sopenharmony_ci				WREG32(EVERGREEN_GRPH_UPDATE + crtc_offsets[i], tmp);
27528c2ecf20Sopenharmony_ci			}
27538c2ecf20Sopenharmony_ci			tmp = RREG32(EVERGREEN_MASTER_UPDATE_LOCK + crtc_offsets[i]);
27548c2ecf20Sopenharmony_ci			if (!(tmp & 1)) {
27558c2ecf20Sopenharmony_ci				tmp |= 1;
27568c2ecf20Sopenharmony_ci				WREG32(EVERGREEN_MASTER_UPDATE_LOCK + crtc_offsets[i], tmp);
27578c2ecf20Sopenharmony_ci			}
27588c2ecf20Sopenharmony_ci		}
27598c2ecf20Sopenharmony_ci	}
27608c2ecf20Sopenharmony_ci}
27618c2ecf20Sopenharmony_ci
27628c2ecf20Sopenharmony_civoid evergreen_mc_resume(struct radeon_device *rdev, struct evergreen_mc_save *save)
27638c2ecf20Sopenharmony_ci{
27648c2ecf20Sopenharmony_ci	u32 tmp, frame_count;
27658c2ecf20Sopenharmony_ci	int i, j;
27668c2ecf20Sopenharmony_ci
27678c2ecf20Sopenharmony_ci	/* update crtc base addresses */
27688c2ecf20Sopenharmony_ci	for (i = 0; i < rdev->num_crtc; i++) {
27698c2ecf20Sopenharmony_ci		WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH + crtc_offsets[i],
27708c2ecf20Sopenharmony_ci		       upper_32_bits(rdev->mc.vram_start));
27718c2ecf20Sopenharmony_ci		WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS_HIGH + crtc_offsets[i],
27728c2ecf20Sopenharmony_ci		       upper_32_bits(rdev->mc.vram_start));
27738c2ecf20Sopenharmony_ci		WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS + crtc_offsets[i],
27748c2ecf20Sopenharmony_ci		       (u32)rdev->mc.vram_start);
27758c2ecf20Sopenharmony_ci		WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS + crtc_offsets[i],
27768c2ecf20Sopenharmony_ci		       (u32)rdev->mc.vram_start);
27778c2ecf20Sopenharmony_ci	}
27788c2ecf20Sopenharmony_ci
27798c2ecf20Sopenharmony_ci	if (!ASIC_IS_NODCE(rdev)) {
27808c2ecf20Sopenharmony_ci		WREG32(EVERGREEN_VGA_MEMORY_BASE_ADDRESS_HIGH, upper_32_bits(rdev->mc.vram_start));
27818c2ecf20Sopenharmony_ci		WREG32(EVERGREEN_VGA_MEMORY_BASE_ADDRESS, (u32)rdev->mc.vram_start);
27828c2ecf20Sopenharmony_ci	}
27838c2ecf20Sopenharmony_ci
27848c2ecf20Sopenharmony_ci	/* unlock regs and wait for update */
27858c2ecf20Sopenharmony_ci	for (i = 0; i < rdev->num_crtc; i++) {
27868c2ecf20Sopenharmony_ci		if (save->crtc_enabled[i]) {
27878c2ecf20Sopenharmony_ci			tmp = RREG32(EVERGREEN_MASTER_UPDATE_MODE + crtc_offsets[i]);
27888c2ecf20Sopenharmony_ci			if ((tmp & 0x7) != 0) {
27898c2ecf20Sopenharmony_ci				tmp &= ~0x7;
27908c2ecf20Sopenharmony_ci				WREG32(EVERGREEN_MASTER_UPDATE_MODE + crtc_offsets[i], tmp);
27918c2ecf20Sopenharmony_ci			}
27928c2ecf20Sopenharmony_ci			tmp = RREG32(EVERGREEN_GRPH_UPDATE + crtc_offsets[i]);
27938c2ecf20Sopenharmony_ci			if (tmp & EVERGREEN_GRPH_UPDATE_LOCK) {
27948c2ecf20Sopenharmony_ci				tmp &= ~EVERGREEN_GRPH_UPDATE_LOCK;
27958c2ecf20Sopenharmony_ci				WREG32(EVERGREEN_GRPH_UPDATE + crtc_offsets[i], tmp);
27968c2ecf20Sopenharmony_ci			}
27978c2ecf20Sopenharmony_ci			tmp = RREG32(EVERGREEN_MASTER_UPDATE_LOCK + crtc_offsets[i]);
27988c2ecf20Sopenharmony_ci			if (tmp & 1) {
27998c2ecf20Sopenharmony_ci				tmp &= ~1;
28008c2ecf20Sopenharmony_ci				WREG32(EVERGREEN_MASTER_UPDATE_LOCK + crtc_offsets[i], tmp);
28018c2ecf20Sopenharmony_ci			}
28028c2ecf20Sopenharmony_ci			for (j = 0; j < rdev->usec_timeout; j++) {
28038c2ecf20Sopenharmony_ci				tmp = RREG32(EVERGREEN_GRPH_UPDATE + crtc_offsets[i]);
28048c2ecf20Sopenharmony_ci				if ((tmp & EVERGREEN_GRPH_SURFACE_UPDATE_PENDING) == 0)
28058c2ecf20Sopenharmony_ci					break;
28068c2ecf20Sopenharmony_ci				udelay(1);
28078c2ecf20Sopenharmony_ci			}
28088c2ecf20Sopenharmony_ci		}
28098c2ecf20Sopenharmony_ci	}
28108c2ecf20Sopenharmony_ci
28118c2ecf20Sopenharmony_ci	/* unblackout the MC */
28128c2ecf20Sopenharmony_ci	tmp = RREG32(MC_SHARED_BLACKOUT_CNTL);
28138c2ecf20Sopenharmony_ci	tmp &= ~BLACKOUT_MODE_MASK;
28148c2ecf20Sopenharmony_ci	WREG32(MC_SHARED_BLACKOUT_CNTL, tmp);
28158c2ecf20Sopenharmony_ci	/* allow CPU access */
28168c2ecf20Sopenharmony_ci	WREG32(BIF_FB_EN, FB_READ_EN | FB_WRITE_EN);
28178c2ecf20Sopenharmony_ci
28188c2ecf20Sopenharmony_ci	for (i = 0; i < rdev->num_crtc; i++) {
28198c2ecf20Sopenharmony_ci		if (save->crtc_enabled[i]) {
28208c2ecf20Sopenharmony_ci			if (ASIC_IS_DCE6(rdev)) {
28218c2ecf20Sopenharmony_ci				tmp = RREG32(EVERGREEN_CRTC_BLANK_CONTROL + crtc_offsets[i]);
28228c2ecf20Sopenharmony_ci				tmp &= ~EVERGREEN_CRTC_BLANK_DATA_EN;
28238c2ecf20Sopenharmony_ci				WREG32(EVERGREEN_CRTC_UPDATE_LOCK + crtc_offsets[i], 1);
28248c2ecf20Sopenharmony_ci				WREG32(EVERGREEN_CRTC_BLANK_CONTROL + crtc_offsets[i], tmp);
28258c2ecf20Sopenharmony_ci				WREG32(EVERGREEN_CRTC_UPDATE_LOCK + crtc_offsets[i], 0);
28268c2ecf20Sopenharmony_ci			} else {
28278c2ecf20Sopenharmony_ci				tmp = RREG32(EVERGREEN_CRTC_CONTROL + crtc_offsets[i]);
28288c2ecf20Sopenharmony_ci				tmp &= ~EVERGREEN_CRTC_DISP_READ_REQUEST_DISABLE;
28298c2ecf20Sopenharmony_ci				WREG32(EVERGREEN_CRTC_UPDATE_LOCK + crtc_offsets[i], 1);
28308c2ecf20Sopenharmony_ci				WREG32(EVERGREEN_CRTC_CONTROL + crtc_offsets[i], tmp);
28318c2ecf20Sopenharmony_ci				WREG32(EVERGREEN_CRTC_UPDATE_LOCK + crtc_offsets[i], 0);
28328c2ecf20Sopenharmony_ci			}
28338c2ecf20Sopenharmony_ci			/* wait for the next frame */
28348c2ecf20Sopenharmony_ci			frame_count = radeon_get_vblank_counter(rdev, i);
28358c2ecf20Sopenharmony_ci			for (j = 0; j < rdev->usec_timeout; j++) {
28368c2ecf20Sopenharmony_ci				if (radeon_get_vblank_counter(rdev, i) != frame_count)
28378c2ecf20Sopenharmony_ci					break;
28388c2ecf20Sopenharmony_ci				udelay(1);
28398c2ecf20Sopenharmony_ci			}
28408c2ecf20Sopenharmony_ci		}
28418c2ecf20Sopenharmony_ci	}
28428c2ecf20Sopenharmony_ci	if (!ASIC_IS_NODCE(rdev)) {
28438c2ecf20Sopenharmony_ci		/* Unlock vga access */
28448c2ecf20Sopenharmony_ci		WREG32(VGA_HDP_CONTROL, save->vga_hdp_control);
28458c2ecf20Sopenharmony_ci		mdelay(1);
28468c2ecf20Sopenharmony_ci		WREG32(VGA_RENDER_CONTROL, save->vga_render_control);
28478c2ecf20Sopenharmony_ci	}
28488c2ecf20Sopenharmony_ci}
28498c2ecf20Sopenharmony_ci
28508c2ecf20Sopenharmony_civoid evergreen_mc_program(struct radeon_device *rdev)
28518c2ecf20Sopenharmony_ci{
28528c2ecf20Sopenharmony_ci	struct evergreen_mc_save save;
28538c2ecf20Sopenharmony_ci	u32 tmp;
28548c2ecf20Sopenharmony_ci	int i, j;
28558c2ecf20Sopenharmony_ci
28568c2ecf20Sopenharmony_ci	/* Initialize HDP */
28578c2ecf20Sopenharmony_ci	for (i = 0, j = 0; i < 32; i++, j += 0x18) {
28588c2ecf20Sopenharmony_ci		WREG32((0x2c14 + j), 0x00000000);
28598c2ecf20Sopenharmony_ci		WREG32((0x2c18 + j), 0x00000000);
28608c2ecf20Sopenharmony_ci		WREG32((0x2c1c + j), 0x00000000);
28618c2ecf20Sopenharmony_ci		WREG32((0x2c20 + j), 0x00000000);
28628c2ecf20Sopenharmony_ci		WREG32((0x2c24 + j), 0x00000000);
28638c2ecf20Sopenharmony_ci	}
28648c2ecf20Sopenharmony_ci	WREG32(HDP_REG_COHERENCY_FLUSH_CNTL, 0);
28658c2ecf20Sopenharmony_ci
28668c2ecf20Sopenharmony_ci	evergreen_mc_stop(rdev, &save);
28678c2ecf20Sopenharmony_ci	if (evergreen_mc_wait_for_idle(rdev)) {
28688c2ecf20Sopenharmony_ci		dev_warn(rdev->dev, "Wait for MC idle timedout !\n");
28698c2ecf20Sopenharmony_ci	}
28708c2ecf20Sopenharmony_ci	/* Lockout access through VGA aperture*/
28718c2ecf20Sopenharmony_ci	WREG32(VGA_HDP_CONTROL, VGA_MEMORY_DISABLE);
28728c2ecf20Sopenharmony_ci	/* Update configuration */
28738c2ecf20Sopenharmony_ci	if (rdev->flags & RADEON_IS_AGP) {
28748c2ecf20Sopenharmony_ci		if (rdev->mc.vram_start < rdev->mc.gtt_start) {
28758c2ecf20Sopenharmony_ci			/* VRAM before AGP */
28768c2ecf20Sopenharmony_ci			WREG32(MC_VM_SYSTEM_APERTURE_LOW_ADDR,
28778c2ecf20Sopenharmony_ci				rdev->mc.vram_start >> 12);
28788c2ecf20Sopenharmony_ci			WREG32(MC_VM_SYSTEM_APERTURE_HIGH_ADDR,
28798c2ecf20Sopenharmony_ci				rdev->mc.gtt_end >> 12);
28808c2ecf20Sopenharmony_ci		} else {
28818c2ecf20Sopenharmony_ci			/* VRAM after AGP */
28828c2ecf20Sopenharmony_ci			WREG32(MC_VM_SYSTEM_APERTURE_LOW_ADDR,
28838c2ecf20Sopenharmony_ci				rdev->mc.gtt_start >> 12);
28848c2ecf20Sopenharmony_ci			WREG32(MC_VM_SYSTEM_APERTURE_HIGH_ADDR,
28858c2ecf20Sopenharmony_ci				rdev->mc.vram_end >> 12);
28868c2ecf20Sopenharmony_ci		}
28878c2ecf20Sopenharmony_ci	} else {
28888c2ecf20Sopenharmony_ci		WREG32(MC_VM_SYSTEM_APERTURE_LOW_ADDR,
28898c2ecf20Sopenharmony_ci			rdev->mc.vram_start >> 12);
28908c2ecf20Sopenharmony_ci		WREG32(MC_VM_SYSTEM_APERTURE_HIGH_ADDR,
28918c2ecf20Sopenharmony_ci			rdev->mc.vram_end >> 12);
28928c2ecf20Sopenharmony_ci	}
28938c2ecf20Sopenharmony_ci	WREG32(MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR, rdev->vram_scratch.gpu_addr >> 12);
28948c2ecf20Sopenharmony_ci	/* llano/ontario only */
28958c2ecf20Sopenharmony_ci	if ((rdev->family == CHIP_PALM) ||
28968c2ecf20Sopenharmony_ci	    (rdev->family == CHIP_SUMO) ||
28978c2ecf20Sopenharmony_ci	    (rdev->family == CHIP_SUMO2)) {
28988c2ecf20Sopenharmony_ci		tmp = RREG32(MC_FUS_VM_FB_OFFSET) & 0x000FFFFF;
28998c2ecf20Sopenharmony_ci		tmp |= ((rdev->mc.vram_end >> 20) & 0xF) << 24;
29008c2ecf20Sopenharmony_ci		tmp |= ((rdev->mc.vram_start >> 20) & 0xF) << 20;
29018c2ecf20Sopenharmony_ci		WREG32(MC_FUS_VM_FB_OFFSET, tmp);
29028c2ecf20Sopenharmony_ci	}
29038c2ecf20Sopenharmony_ci	tmp = ((rdev->mc.vram_end >> 24) & 0xFFFF) << 16;
29048c2ecf20Sopenharmony_ci	tmp |= ((rdev->mc.vram_start >> 24) & 0xFFFF);
29058c2ecf20Sopenharmony_ci	WREG32(MC_VM_FB_LOCATION, tmp);
29068c2ecf20Sopenharmony_ci	WREG32(HDP_NONSURFACE_BASE, (rdev->mc.vram_start >> 8));
29078c2ecf20Sopenharmony_ci	WREG32(HDP_NONSURFACE_INFO, (2 << 7) | (1 << 30));
29088c2ecf20Sopenharmony_ci	WREG32(HDP_NONSURFACE_SIZE, 0x3FFFFFFF);
29098c2ecf20Sopenharmony_ci	if (rdev->flags & RADEON_IS_AGP) {
29108c2ecf20Sopenharmony_ci		WREG32(MC_VM_AGP_TOP, rdev->mc.gtt_end >> 16);
29118c2ecf20Sopenharmony_ci		WREG32(MC_VM_AGP_BOT, rdev->mc.gtt_start >> 16);
29128c2ecf20Sopenharmony_ci		WREG32(MC_VM_AGP_BASE, rdev->mc.agp_base >> 22);
29138c2ecf20Sopenharmony_ci	} else {
29148c2ecf20Sopenharmony_ci		WREG32(MC_VM_AGP_BASE, 0);
29158c2ecf20Sopenharmony_ci		WREG32(MC_VM_AGP_TOP, 0x0FFFFFFF);
29168c2ecf20Sopenharmony_ci		WREG32(MC_VM_AGP_BOT, 0x0FFFFFFF);
29178c2ecf20Sopenharmony_ci	}
29188c2ecf20Sopenharmony_ci	if (evergreen_mc_wait_for_idle(rdev)) {
29198c2ecf20Sopenharmony_ci		dev_warn(rdev->dev, "Wait for MC idle timedout !\n");
29208c2ecf20Sopenharmony_ci	}
29218c2ecf20Sopenharmony_ci	evergreen_mc_resume(rdev, &save);
29228c2ecf20Sopenharmony_ci	/* we need to own VRAM, so turn off the VGA renderer here
29238c2ecf20Sopenharmony_ci	 * to stop it overwriting our objects */
29248c2ecf20Sopenharmony_ci	rv515_vga_render_disable(rdev);
29258c2ecf20Sopenharmony_ci}
29268c2ecf20Sopenharmony_ci
29278c2ecf20Sopenharmony_ci/*
29288c2ecf20Sopenharmony_ci * CP.
29298c2ecf20Sopenharmony_ci */
29308c2ecf20Sopenharmony_civoid evergreen_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib)
29318c2ecf20Sopenharmony_ci{
29328c2ecf20Sopenharmony_ci	struct radeon_ring *ring = &rdev->ring[ib->ring];
29338c2ecf20Sopenharmony_ci	u32 next_rptr;
29348c2ecf20Sopenharmony_ci
29358c2ecf20Sopenharmony_ci	/* set to DX10/11 mode */
29368c2ecf20Sopenharmony_ci	radeon_ring_write(ring, PACKET3(PACKET3_MODE_CONTROL, 0));
29378c2ecf20Sopenharmony_ci	radeon_ring_write(ring, 1);
29388c2ecf20Sopenharmony_ci
29398c2ecf20Sopenharmony_ci	if (ring->rptr_save_reg) {
29408c2ecf20Sopenharmony_ci		next_rptr = ring->wptr + 3 + 4;
29418c2ecf20Sopenharmony_ci		radeon_ring_write(ring, PACKET3(PACKET3_SET_CONFIG_REG, 1));
29428c2ecf20Sopenharmony_ci		radeon_ring_write(ring, ((ring->rptr_save_reg -
29438c2ecf20Sopenharmony_ci					  PACKET3_SET_CONFIG_REG_START) >> 2));
29448c2ecf20Sopenharmony_ci		radeon_ring_write(ring, next_rptr);
29458c2ecf20Sopenharmony_ci	} else if (rdev->wb.enabled) {
29468c2ecf20Sopenharmony_ci		next_rptr = ring->wptr + 5 + 4;
29478c2ecf20Sopenharmony_ci		radeon_ring_write(ring, PACKET3(PACKET3_MEM_WRITE, 3));
29488c2ecf20Sopenharmony_ci		radeon_ring_write(ring, ring->next_rptr_gpu_addr & 0xfffffffc);
29498c2ecf20Sopenharmony_ci		radeon_ring_write(ring, (upper_32_bits(ring->next_rptr_gpu_addr) & 0xff) | (1 << 18));
29508c2ecf20Sopenharmony_ci		radeon_ring_write(ring, next_rptr);
29518c2ecf20Sopenharmony_ci		radeon_ring_write(ring, 0);
29528c2ecf20Sopenharmony_ci	}
29538c2ecf20Sopenharmony_ci
29548c2ecf20Sopenharmony_ci	radeon_ring_write(ring, PACKET3(PACKET3_INDIRECT_BUFFER, 2));
29558c2ecf20Sopenharmony_ci	radeon_ring_write(ring,
29568c2ecf20Sopenharmony_ci#ifdef __BIG_ENDIAN
29578c2ecf20Sopenharmony_ci			  (2 << 0) |
29588c2ecf20Sopenharmony_ci#endif
29598c2ecf20Sopenharmony_ci			  (ib->gpu_addr & 0xFFFFFFFC));
29608c2ecf20Sopenharmony_ci	radeon_ring_write(ring, upper_32_bits(ib->gpu_addr) & 0xFF);
29618c2ecf20Sopenharmony_ci	radeon_ring_write(ring, ib->length_dw);
29628c2ecf20Sopenharmony_ci}
29638c2ecf20Sopenharmony_ci
29648c2ecf20Sopenharmony_ci
29658c2ecf20Sopenharmony_cistatic int evergreen_cp_load_microcode(struct radeon_device *rdev)
29668c2ecf20Sopenharmony_ci{
29678c2ecf20Sopenharmony_ci	const __be32 *fw_data;
29688c2ecf20Sopenharmony_ci	int i;
29698c2ecf20Sopenharmony_ci
29708c2ecf20Sopenharmony_ci	if (!rdev->me_fw || !rdev->pfp_fw)
29718c2ecf20Sopenharmony_ci		return -EINVAL;
29728c2ecf20Sopenharmony_ci
29738c2ecf20Sopenharmony_ci	r700_cp_stop(rdev);
29748c2ecf20Sopenharmony_ci	WREG32(CP_RB_CNTL,
29758c2ecf20Sopenharmony_ci#ifdef __BIG_ENDIAN
29768c2ecf20Sopenharmony_ci	       BUF_SWAP_32BIT |
29778c2ecf20Sopenharmony_ci#endif
29788c2ecf20Sopenharmony_ci	       RB_NO_UPDATE | RB_BLKSZ(15) | RB_BUFSZ(3));
29798c2ecf20Sopenharmony_ci
29808c2ecf20Sopenharmony_ci	fw_data = (const __be32 *)rdev->pfp_fw->data;
29818c2ecf20Sopenharmony_ci	WREG32(CP_PFP_UCODE_ADDR, 0);
29828c2ecf20Sopenharmony_ci	for (i = 0; i < EVERGREEN_PFP_UCODE_SIZE; i++)
29838c2ecf20Sopenharmony_ci		WREG32(CP_PFP_UCODE_DATA, be32_to_cpup(fw_data++));
29848c2ecf20Sopenharmony_ci	WREG32(CP_PFP_UCODE_ADDR, 0);
29858c2ecf20Sopenharmony_ci
29868c2ecf20Sopenharmony_ci	fw_data = (const __be32 *)rdev->me_fw->data;
29878c2ecf20Sopenharmony_ci	WREG32(CP_ME_RAM_WADDR, 0);
29888c2ecf20Sopenharmony_ci	for (i = 0; i < EVERGREEN_PM4_UCODE_SIZE; i++)
29898c2ecf20Sopenharmony_ci		WREG32(CP_ME_RAM_DATA, be32_to_cpup(fw_data++));
29908c2ecf20Sopenharmony_ci
29918c2ecf20Sopenharmony_ci	WREG32(CP_PFP_UCODE_ADDR, 0);
29928c2ecf20Sopenharmony_ci	WREG32(CP_ME_RAM_WADDR, 0);
29938c2ecf20Sopenharmony_ci	WREG32(CP_ME_RAM_RADDR, 0);
29948c2ecf20Sopenharmony_ci	return 0;
29958c2ecf20Sopenharmony_ci}
29968c2ecf20Sopenharmony_ci
29978c2ecf20Sopenharmony_cistatic int evergreen_cp_start(struct radeon_device *rdev)
29988c2ecf20Sopenharmony_ci{
29998c2ecf20Sopenharmony_ci	struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX];
30008c2ecf20Sopenharmony_ci	int r, i;
30018c2ecf20Sopenharmony_ci	uint32_t cp_me;
30028c2ecf20Sopenharmony_ci
30038c2ecf20Sopenharmony_ci	r = radeon_ring_lock(rdev, ring, 7);
30048c2ecf20Sopenharmony_ci	if (r) {
30058c2ecf20Sopenharmony_ci		DRM_ERROR("radeon: cp failed to lock ring (%d).\n", r);
30068c2ecf20Sopenharmony_ci		return r;
30078c2ecf20Sopenharmony_ci	}
30088c2ecf20Sopenharmony_ci	radeon_ring_write(ring, PACKET3(PACKET3_ME_INITIALIZE, 5));
30098c2ecf20Sopenharmony_ci	radeon_ring_write(ring, 0x1);
30108c2ecf20Sopenharmony_ci	radeon_ring_write(ring, 0x0);
30118c2ecf20Sopenharmony_ci	radeon_ring_write(ring, rdev->config.evergreen.max_hw_contexts - 1);
30128c2ecf20Sopenharmony_ci	radeon_ring_write(ring, PACKET3_ME_INITIALIZE_DEVICE_ID(1));
30138c2ecf20Sopenharmony_ci	radeon_ring_write(ring, 0);
30148c2ecf20Sopenharmony_ci	radeon_ring_write(ring, 0);
30158c2ecf20Sopenharmony_ci	radeon_ring_unlock_commit(rdev, ring, false);
30168c2ecf20Sopenharmony_ci
30178c2ecf20Sopenharmony_ci	cp_me = 0xff;
30188c2ecf20Sopenharmony_ci	WREG32(CP_ME_CNTL, cp_me);
30198c2ecf20Sopenharmony_ci
30208c2ecf20Sopenharmony_ci	r = radeon_ring_lock(rdev, ring, evergreen_default_size + 19);
30218c2ecf20Sopenharmony_ci	if (r) {
30228c2ecf20Sopenharmony_ci		DRM_ERROR("radeon: cp failed to lock ring (%d).\n", r);
30238c2ecf20Sopenharmony_ci		return r;
30248c2ecf20Sopenharmony_ci	}
30258c2ecf20Sopenharmony_ci
30268c2ecf20Sopenharmony_ci	/* setup clear context state */
30278c2ecf20Sopenharmony_ci	radeon_ring_write(ring, PACKET3(PACKET3_PREAMBLE_CNTL, 0));
30288c2ecf20Sopenharmony_ci	radeon_ring_write(ring, PACKET3_PREAMBLE_BEGIN_CLEAR_STATE);
30298c2ecf20Sopenharmony_ci
30308c2ecf20Sopenharmony_ci	for (i = 0; i < evergreen_default_size; i++)
30318c2ecf20Sopenharmony_ci		radeon_ring_write(ring, evergreen_default_state[i]);
30328c2ecf20Sopenharmony_ci
30338c2ecf20Sopenharmony_ci	radeon_ring_write(ring, PACKET3(PACKET3_PREAMBLE_CNTL, 0));
30348c2ecf20Sopenharmony_ci	radeon_ring_write(ring, PACKET3_PREAMBLE_END_CLEAR_STATE);
30358c2ecf20Sopenharmony_ci
30368c2ecf20Sopenharmony_ci	/* set clear context state */
30378c2ecf20Sopenharmony_ci	radeon_ring_write(ring, PACKET3(PACKET3_CLEAR_STATE, 0));
30388c2ecf20Sopenharmony_ci	radeon_ring_write(ring, 0);
30398c2ecf20Sopenharmony_ci
30408c2ecf20Sopenharmony_ci	/* SQ_VTX_BASE_VTX_LOC */
30418c2ecf20Sopenharmony_ci	radeon_ring_write(ring, 0xc0026f00);
30428c2ecf20Sopenharmony_ci	radeon_ring_write(ring, 0x00000000);
30438c2ecf20Sopenharmony_ci	radeon_ring_write(ring, 0x00000000);
30448c2ecf20Sopenharmony_ci	radeon_ring_write(ring, 0x00000000);
30458c2ecf20Sopenharmony_ci
30468c2ecf20Sopenharmony_ci	/* Clear consts */
30478c2ecf20Sopenharmony_ci	radeon_ring_write(ring, 0xc0036f00);
30488c2ecf20Sopenharmony_ci	radeon_ring_write(ring, 0x00000bc4);
30498c2ecf20Sopenharmony_ci	radeon_ring_write(ring, 0xffffffff);
30508c2ecf20Sopenharmony_ci	radeon_ring_write(ring, 0xffffffff);
30518c2ecf20Sopenharmony_ci	radeon_ring_write(ring, 0xffffffff);
30528c2ecf20Sopenharmony_ci
30538c2ecf20Sopenharmony_ci	radeon_ring_write(ring, 0xc0026900);
30548c2ecf20Sopenharmony_ci	radeon_ring_write(ring, 0x00000316);
30558c2ecf20Sopenharmony_ci	radeon_ring_write(ring, 0x0000000e); /* VGT_VERTEX_REUSE_BLOCK_CNTL */
30568c2ecf20Sopenharmony_ci	radeon_ring_write(ring, 0x00000010); /*  */
30578c2ecf20Sopenharmony_ci
30588c2ecf20Sopenharmony_ci	radeon_ring_unlock_commit(rdev, ring, false);
30598c2ecf20Sopenharmony_ci
30608c2ecf20Sopenharmony_ci	return 0;
30618c2ecf20Sopenharmony_ci}
30628c2ecf20Sopenharmony_ci
30638c2ecf20Sopenharmony_cistatic int evergreen_cp_resume(struct radeon_device *rdev)
30648c2ecf20Sopenharmony_ci{
30658c2ecf20Sopenharmony_ci	struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX];
30668c2ecf20Sopenharmony_ci	u32 tmp;
30678c2ecf20Sopenharmony_ci	u32 rb_bufsz;
30688c2ecf20Sopenharmony_ci	int r;
30698c2ecf20Sopenharmony_ci
30708c2ecf20Sopenharmony_ci	/* Reset cp; if cp is reset, then PA, SH, VGT also need to be reset */
30718c2ecf20Sopenharmony_ci	WREG32(GRBM_SOFT_RESET, (SOFT_RESET_CP |
30728c2ecf20Sopenharmony_ci				 SOFT_RESET_PA |
30738c2ecf20Sopenharmony_ci				 SOFT_RESET_SH |
30748c2ecf20Sopenharmony_ci				 SOFT_RESET_VGT |
30758c2ecf20Sopenharmony_ci				 SOFT_RESET_SPI |
30768c2ecf20Sopenharmony_ci				 SOFT_RESET_SX));
30778c2ecf20Sopenharmony_ci	RREG32(GRBM_SOFT_RESET);
30788c2ecf20Sopenharmony_ci	mdelay(15);
30798c2ecf20Sopenharmony_ci	WREG32(GRBM_SOFT_RESET, 0);
30808c2ecf20Sopenharmony_ci	RREG32(GRBM_SOFT_RESET);
30818c2ecf20Sopenharmony_ci
30828c2ecf20Sopenharmony_ci	/* Set ring buffer size */
30838c2ecf20Sopenharmony_ci	rb_bufsz = order_base_2(ring->ring_size / 8);
30848c2ecf20Sopenharmony_ci	tmp = (order_base_2(RADEON_GPU_PAGE_SIZE/8) << 8) | rb_bufsz;
30858c2ecf20Sopenharmony_ci#ifdef __BIG_ENDIAN
30868c2ecf20Sopenharmony_ci	tmp |= BUF_SWAP_32BIT;
30878c2ecf20Sopenharmony_ci#endif
30888c2ecf20Sopenharmony_ci	WREG32(CP_RB_CNTL, tmp);
30898c2ecf20Sopenharmony_ci	WREG32(CP_SEM_WAIT_TIMER, 0x0);
30908c2ecf20Sopenharmony_ci	WREG32(CP_SEM_INCOMPLETE_TIMER_CNTL, 0x0);
30918c2ecf20Sopenharmony_ci
30928c2ecf20Sopenharmony_ci	/* Set the write pointer delay */
30938c2ecf20Sopenharmony_ci	WREG32(CP_RB_WPTR_DELAY, 0);
30948c2ecf20Sopenharmony_ci
30958c2ecf20Sopenharmony_ci	/* Initialize the ring buffer's read and write pointers */
30968c2ecf20Sopenharmony_ci	WREG32(CP_RB_CNTL, tmp | RB_RPTR_WR_ENA);
30978c2ecf20Sopenharmony_ci	WREG32(CP_RB_RPTR_WR, 0);
30988c2ecf20Sopenharmony_ci	ring->wptr = 0;
30998c2ecf20Sopenharmony_ci	WREG32(CP_RB_WPTR, ring->wptr);
31008c2ecf20Sopenharmony_ci
31018c2ecf20Sopenharmony_ci	/* set the wb address whether it's enabled or not */
31028c2ecf20Sopenharmony_ci	WREG32(CP_RB_RPTR_ADDR,
31038c2ecf20Sopenharmony_ci	       ((rdev->wb.gpu_addr + RADEON_WB_CP_RPTR_OFFSET) & 0xFFFFFFFC));
31048c2ecf20Sopenharmony_ci	WREG32(CP_RB_RPTR_ADDR_HI, upper_32_bits(rdev->wb.gpu_addr + RADEON_WB_CP_RPTR_OFFSET) & 0xFF);
31058c2ecf20Sopenharmony_ci	WREG32(SCRATCH_ADDR, ((rdev->wb.gpu_addr + RADEON_WB_SCRATCH_OFFSET) >> 8) & 0xFFFFFFFF);
31068c2ecf20Sopenharmony_ci
31078c2ecf20Sopenharmony_ci	if (rdev->wb.enabled)
31088c2ecf20Sopenharmony_ci		WREG32(SCRATCH_UMSK, 0xff);
31098c2ecf20Sopenharmony_ci	else {
31108c2ecf20Sopenharmony_ci		tmp |= RB_NO_UPDATE;
31118c2ecf20Sopenharmony_ci		WREG32(SCRATCH_UMSK, 0);
31128c2ecf20Sopenharmony_ci	}
31138c2ecf20Sopenharmony_ci
31148c2ecf20Sopenharmony_ci	mdelay(1);
31158c2ecf20Sopenharmony_ci	WREG32(CP_RB_CNTL, tmp);
31168c2ecf20Sopenharmony_ci
31178c2ecf20Sopenharmony_ci	WREG32(CP_RB_BASE, ring->gpu_addr >> 8);
31188c2ecf20Sopenharmony_ci	WREG32(CP_DEBUG, (1 << 27) | (1 << 28));
31198c2ecf20Sopenharmony_ci
31208c2ecf20Sopenharmony_ci	evergreen_cp_start(rdev);
31218c2ecf20Sopenharmony_ci	ring->ready = true;
31228c2ecf20Sopenharmony_ci	r = radeon_ring_test(rdev, RADEON_RING_TYPE_GFX_INDEX, ring);
31238c2ecf20Sopenharmony_ci	if (r) {
31248c2ecf20Sopenharmony_ci		ring->ready = false;
31258c2ecf20Sopenharmony_ci		return r;
31268c2ecf20Sopenharmony_ci	}
31278c2ecf20Sopenharmony_ci	return 0;
31288c2ecf20Sopenharmony_ci}
31298c2ecf20Sopenharmony_ci
31308c2ecf20Sopenharmony_ci/*
31318c2ecf20Sopenharmony_ci * Core functions
31328c2ecf20Sopenharmony_ci */
31338c2ecf20Sopenharmony_cistatic void evergreen_gpu_init(struct radeon_device *rdev)
31348c2ecf20Sopenharmony_ci{
31358c2ecf20Sopenharmony_ci	u32 gb_addr_config;
31368c2ecf20Sopenharmony_ci	u32 mc_shared_chmap, mc_arb_ramcfg;
31378c2ecf20Sopenharmony_ci	u32 sx_debug_1;
31388c2ecf20Sopenharmony_ci	u32 smx_dc_ctl0;
31398c2ecf20Sopenharmony_ci	u32 sq_config;
31408c2ecf20Sopenharmony_ci	u32 sq_lds_resource_mgmt;
31418c2ecf20Sopenharmony_ci	u32 sq_gpr_resource_mgmt_1;
31428c2ecf20Sopenharmony_ci	u32 sq_gpr_resource_mgmt_2;
31438c2ecf20Sopenharmony_ci	u32 sq_gpr_resource_mgmt_3;
31448c2ecf20Sopenharmony_ci	u32 sq_thread_resource_mgmt;
31458c2ecf20Sopenharmony_ci	u32 sq_thread_resource_mgmt_2;
31468c2ecf20Sopenharmony_ci	u32 sq_stack_resource_mgmt_1;
31478c2ecf20Sopenharmony_ci	u32 sq_stack_resource_mgmt_2;
31488c2ecf20Sopenharmony_ci	u32 sq_stack_resource_mgmt_3;
31498c2ecf20Sopenharmony_ci	u32 vgt_cache_invalidation;
31508c2ecf20Sopenharmony_ci	u32 hdp_host_path_cntl, tmp;
31518c2ecf20Sopenharmony_ci	u32 disabled_rb_mask;
31528c2ecf20Sopenharmony_ci	int i, j, ps_thread_count;
31538c2ecf20Sopenharmony_ci
31548c2ecf20Sopenharmony_ci	switch (rdev->family) {
31558c2ecf20Sopenharmony_ci	case CHIP_CYPRESS:
31568c2ecf20Sopenharmony_ci	case CHIP_HEMLOCK:
31578c2ecf20Sopenharmony_ci		rdev->config.evergreen.num_ses = 2;
31588c2ecf20Sopenharmony_ci		rdev->config.evergreen.max_pipes = 4;
31598c2ecf20Sopenharmony_ci		rdev->config.evergreen.max_tile_pipes = 8;
31608c2ecf20Sopenharmony_ci		rdev->config.evergreen.max_simds = 10;
31618c2ecf20Sopenharmony_ci		rdev->config.evergreen.max_backends = 4 * rdev->config.evergreen.num_ses;
31628c2ecf20Sopenharmony_ci		rdev->config.evergreen.max_gprs = 256;
31638c2ecf20Sopenharmony_ci		rdev->config.evergreen.max_threads = 248;
31648c2ecf20Sopenharmony_ci		rdev->config.evergreen.max_gs_threads = 32;
31658c2ecf20Sopenharmony_ci		rdev->config.evergreen.max_stack_entries = 512;
31668c2ecf20Sopenharmony_ci		rdev->config.evergreen.sx_num_of_sets = 4;
31678c2ecf20Sopenharmony_ci		rdev->config.evergreen.sx_max_export_size = 256;
31688c2ecf20Sopenharmony_ci		rdev->config.evergreen.sx_max_export_pos_size = 64;
31698c2ecf20Sopenharmony_ci		rdev->config.evergreen.sx_max_export_smx_size = 192;
31708c2ecf20Sopenharmony_ci		rdev->config.evergreen.max_hw_contexts = 8;
31718c2ecf20Sopenharmony_ci		rdev->config.evergreen.sq_num_cf_insts = 2;
31728c2ecf20Sopenharmony_ci
31738c2ecf20Sopenharmony_ci		rdev->config.evergreen.sc_prim_fifo_size = 0x100;
31748c2ecf20Sopenharmony_ci		rdev->config.evergreen.sc_hiz_tile_fifo_size = 0x30;
31758c2ecf20Sopenharmony_ci		rdev->config.evergreen.sc_earlyz_tile_fifo_size = 0x130;
31768c2ecf20Sopenharmony_ci		gb_addr_config = CYPRESS_GB_ADDR_CONFIG_GOLDEN;
31778c2ecf20Sopenharmony_ci		break;
31788c2ecf20Sopenharmony_ci	case CHIP_JUNIPER:
31798c2ecf20Sopenharmony_ci		rdev->config.evergreen.num_ses = 1;
31808c2ecf20Sopenharmony_ci		rdev->config.evergreen.max_pipes = 4;
31818c2ecf20Sopenharmony_ci		rdev->config.evergreen.max_tile_pipes = 4;
31828c2ecf20Sopenharmony_ci		rdev->config.evergreen.max_simds = 10;
31838c2ecf20Sopenharmony_ci		rdev->config.evergreen.max_backends = 4 * rdev->config.evergreen.num_ses;
31848c2ecf20Sopenharmony_ci		rdev->config.evergreen.max_gprs = 256;
31858c2ecf20Sopenharmony_ci		rdev->config.evergreen.max_threads = 248;
31868c2ecf20Sopenharmony_ci		rdev->config.evergreen.max_gs_threads = 32;
31878c2ecf20Sopenharmony_ci		rdev->config.evergreen.max_stack_entries = 512;
31888c2ecf20Sopenharmony_ci		rdev->config.evergreen.sx_num_of_sets = 4;
31898c2ecf20Sopenharmony_ci		rdev->config.evergreen.sx_max_export_size = 256;
31908c2ecf20Sopenharmony_ci		rdev->config.evergreen.sx_max_export_pos_size = 64;
31918c2ecf20Sopenharmony_ci		rdev->config.evergreen.sx_max_export_smx_size = 192;
31928c2ecf20Sopenharmony_ci		rdev->config.evergreen.max_hw_contexts = 8;
31938c2ecf20Sopenharmony_ci		rdev->config.evergreen.sq_num_cf_insts = 2;
31948c2ecf20Sopenharmony_ci
31958c2ecf20Sopenharmony_ci		rdev->config.evergreen.sc_prim_fifo_size = 0x100;
31968c2ecf20Sopenharmony_ci		rdev->config.evergreen.sc_hiz_tile_fifo_size = 0x30;
31978c2ecf20Sopenharmony_ci		rdev->config.evergreen.sc_earlyz_tile_fifo_size = 0x130;
31988c2ecf20Sopenharmony_ci		gb_addr_config = JUNIPER_GB_ADDR_CONFIG_GOLDEN;
31998c2ecf20Sopenharmony_ci		break;
32008c2ecf20Sopenharmony_ci	case CHIP_REDWOOD:
32018c2ecf20Sopenharmony_ci		rdev->config.evergreen.num_ses = 1;
32028c2ecf20Sopenharmony_ci		rdev->config.evergreen.max_pipes = 4;
32038c2ecf20Sopenharmony_ci		rdev->config.evergreen.max_tile_pipes = 4;
32048c2ecf20Sopenharmony_ci		rdev->config.evergreen.max_simds = 5;
32058c2ecf20Sopenharmony_ci		rdev->config.evergreen.max_backends = 2 * rdev->config.evergreen.num_ses;
32068c2ecf20Sopenharmony_ci		rdev->config.evergreen.max_gprs = 256;
32078c2ecf20Sopenharmony_ci		rdev->config.evergreen.max_threads = 248;
32088c2ecf20Sopenharmony_ci		rdev->config.evergreen.max_gs_threads = 32;
32098c2ecf20Sopenharmony_ci		rdev->config.evergreen.max_stack_entries = 256;
32108c2ecf20Sopenharmony_ci		rdev->config.evergreen.sx_num_of_sets = 4;
32118c2ecf20Sopenharmony_ci		rdev->config.evergreen.sx_max_export_size = 256;
32128c2ecf20Sopenharmony_ci		rdev->config.evergreen.sx_max_export_pos_size = 64;
32138c2ecf20Sopenharmony_ci		rdev->config.evergreen.sx_max_export_smx_size = 192;
32148c2ecf20Sopenharmony_ci		rdev->config.evergreen.max_hw_contexts = 8;
32158c2ecf20Sopenharmony_ci		rdev->config.evergreen.sq_num_cf_insts = 2;
32168c2ecf20Sopenharmony_ci
32178c2ecf20Sopenharmony_ci		rdev->config.evergreen.sc_prim_fifo_size = 0x100;
32188c2ecf20Sopenharmony_ci		rdev->config.evergreen.sc_hiz_tile_fifo_size = 0x30;
32198c2ecf20Sopenharmony_ci		rdev->config.evergreen.sc_earlyz_tile_fifo_size = 0x130;
32208c2ecf20Sopenharmony_ci		gb_addr_config = REDWOOD_GB_ADDR_CONFIG_GOLDEN;
32218c2ecf20Sopenharmony_ci		break;
32228c2ecf20Sopenharmony_ci	case CHIP_CEDAR:
32238c2ecf20Sopenharmony_ci	default:
32248c2ecf20Sopenharmony_ci		rdev->config.evergreen.num_ses = 1;
32258c2ecf20Sopenharmony_ci		rdev->config.evergreen.max_pipes = 2;
32268c2ecf20Sopenharmony_ci		rdev->config.evergreen.max_tile_pipes = 2;
32278c2ecf20Sopenharmony_ci		rdev->config.evergreen.max_simds = 2;
32288c2ecf20Sopenharmony_ci		rdev->config.evergreen.max_backends = 1 * rdev->config.evergreen.num_ses;
32298c2ecf20Sopenharmony_ci		rdev->config.evergreen.max_gprs = 256;
32308c2ecf20Sopenharmony_ci		rdev->config.evergreen.max_threads = 192;
32318c2ecf20Sopenharmony_ci		rdev->config.evergreen.max_gs_threads = 16;
32328c2ecf20Sopenharmony_ci		rdev->config.evergreen.max_stack_entries = 256;
32338c2ecf20Sopenharmony_ci		rdev->config.evergreen.sx_num_of_sets = 4;
32348c2ecf20Sopenharmony_ci		rdev->config.evergreen.sx_max_export_size = 128;
32358c2ecf20Sopenharmony_ci		rdev->config.evergreen.sx_max_export_pos_size = 32;
32368c2ecf20Sopenharmony_ci		rdev->config.evergreen.sx_max_export_smx_size = 96;
32378c2ecf20Sopenharmony_ci		rdev->config.evergreen.max_hw_contexts = 4;
32388c2ecf20Sopenharmony_ci		rdev->config.evergreen.sq_num_cf_insts = 1;
32398c2ecf20Sopenharmony_ci
32408c2ecf20Sopenharmony_ci		rdev->config.evergreen.sc_prim_fifo_size = 0x40;
32418c2ecf20Sopenharmony_ci		rdev->config.evergreen.sc_hiz_tile_fifo_size = 0x30;
32428c2ecf20Sopenharmony_ci		rdev->config.evergreen.sc_earlyz_tile_fifo_size = 0x130;
32438c2ecf20Sopenharmony_ci		gb_addr_config = CEDAR_GB_ADDR_CONFIG_GOLDEN;
32448c2ecf20Sopenharmony_ci		break;
32458c2ecf20Sopenharmony_ci	case CHIP_PALM:
32468c2ecf20Sopenharmony_ci		rdev->config.evergreen.num_ses = 1;
32478c2ecf20Sopenharmony_ci		rdev->config.evergreen.max_pipes = 2;
32488c2ecf20Sopenharmony_ci		rdev->config.evergreen.max_tile_pipes = 2;
32498c2ecf20Sopenharmony_ci		rdev->config.evergreen.max_simds = 2;
32508c2ecf20Sopenharmony_ci		rdev->config.evergreen.max_backends = 1 * rdev->config.evergreen.num_ses;
32518c2ecf20Sopenharmony_ci		rdev->config.evergreen.max_gprs = 256;
32528c2ecf20Sopenharmony_ci		rdev->config.evergreen.max_threads = 192;
32538c2ecf20Sopenharmony_ci		rdev->config.evergreen.max_gs_threads = 16;
32548c2ecf20Sopenharmony_ci		rdev->config.evergreen.max_stack_entries = 256;
32558c2ecf20Sopenharmony_ci		rdev->config.evergreen.sx_num_of_sets = 4;
32568c2ecf20Sopenharmony_ci		rdev->config.evergreen.sx_max_export_size = 128;
32578c2ecf20Sopenharmony_ci		rdev->config.evergreen.sx_max_export_pos_size = 32;
32588c2ecf20Sopenharmony_ci		rdev->config.evergreen.sx_max_export_smx_size = 96;
32598c2ecf20Sopenharmony_ci		rdev->config.evergreen.max_hw_contexts = 4;
32608c2ecf20Sopenharmony_ci		rdev->config.evergreen.sq_num_cf_insts = 1;
32618c2ecf20Sopenharmony_ci
32628c2ecf20Sopenharmony_ci		rdev->config.evergreen.sc_prim_fifo_size = 0x40;
32638c2ecf20Sopenharmony_ci		rdev->config.evergreen.sc_hiz_tile_fifo_size = 0x30;
32648c2ecf20Sopenharmony_ci		rdev->config.evergreen.sc_earlyz_tile_fifo_size = 0x130;
32658c2ecf20Sopenharmony_ci		gb_addr_config = CEDAR_GB_ADDR_CONFIG_GOLDEN;
32668c2ecf20Sopenharmony_ci		break;
32678c2ecf20Sopenharmony_ci	case CHIP_SUMO:
32688c2ecf20Sopenharmony_ci		rdev->config.evergreen.num_ses = 1;
32698c2ecf20Sopenharmony_ci		rdev->config.evergreen.max_pipes = 4;
32708c2ecf20Sopenharmony_ci		rdev->config.evergreen.max_tile_pipes = 4;
32718c2ecf20Sopenharmony_ci		if (rdev->pdev->device == 0x9648)
32728c2ecf20Sopenharmony_ci			rdev->config.evergreen.max_simds = 3;
32738c2ecf20Sopenharmony_ci		else if ((rdev->pdev->device == 0x9647) ||
32748c2ecf20Sopenharmony_ci			 (rdev->pdev->device == 0x964a))
32758c2ecf20Sopenharmony_ci			rdev->config.evergreen.max_simds = 4;
32768c2ecf20Sopenharmony_ci		else
32778c2ecf20Sopenharmony_ci			rdev->config.evergreen.max_simds = 5;
32788c2ecf20Sopenharmony_ci		rdev->config.evergreen.max_backends = 2 * rdev->config.evergreen.num_ses;
32798c2ecf20Sopenharmony_ci		rdev->config.evergreen.max_gprs = 256;
32808c2ecf20Sopenharmony_ci		rdev->config.evergreen.max_threads = 248;
32818c2ecf20Sopenharmony_ci		rdev->config.evergreen.max_gs_threads = 32;
32828c2ecf20Sopenharmony_ci		rdev->config.evergreen.max_stack_entries = 256;
32838c2ecf20Sopenharmony_ci		rdev->config.evergreen.sx_num_of_sets = 4;
32848c2ecf20Sopenharmony_ci		rdev->config.evergreen.sx_max_export_size = 256;
32858c2ecf20Sopenharmony_ci		rdev->config.evergreen.sx_max_export_pos_size = 64;
32868c2ecf20Sopenharmony_ci		rdev->config.evergreen.sx_max_export_smx_size = 192;
32878c2ecf20Sopenharmony_ci		rdev->config.evergreen.max_hw_contexts = 8;
32888c2ecf20Sopenharmony_ci		rdev->config.evergreen.sq_num_cf_insts = 2;
32898c2ecf20Sopenharmony_ci
32908c2ecf20Sopenharmony_ci		rdev->config.evergreen.sc_prim_fifo_size = 0x40;
32918c2ecf20Sopenharmony_ci		rdev->config.evergreen.sc_hiz_tile_fifo_size = 0x30;
32928c2ecf20Sopenharmony_ci		rdev->config.evergreen.sc_earlyz_tile_fifo_size = 0x130;
32938c2ecf20Sopenharmony_ci		gb_addr_config = SUMO_GB_ADDR_CONFIG_GOLDEN;
32948c2ecf20Sopenharmony_ci		break;
32958c2ecf20Sopenharmony_ci	case CHIP_SUMO2:
32968c2ecf20Sopenharmony_ci		rdev->config.evergreen.num_ses = 1;
32978c2ecf20Sopenharmony_ci		rdev->config.evergreen.max_pipes = 4;
32988c2ecf20Sopenharmony_ci		rdev->config.evergreen.max_tile_pipes = 4;
32998c2ecf20Sopenharmony_ci		rdev->config.evergreen.max_simds = 2;
33008c2ecf20Sopenharmony_ci		rdev->config.evergreen.max_backends = 1 * rdev->config.evergreen.num_ses;
33018c2ecf20Sopenharmony_ci		rdev->config.evergreen.max_gprs = 256;
33028c2ecf20Sopenharmony_ci		rdev->config.evergreen.max_threads = 248;
33038c2ecf20Sopenharmony_ci		rdev->config.evergreen.max_gs_threads = 32;
33048c2ecf20Sopenharmony_ci		rdev->config.evergreen.max_stack_entries = 512;
33058c2ecf20Sopenharmony_ci		rdev->config.evergreen.sx_num_of_sets = 4;
33068c2ecf20Sopenharmony_ci		rdev->config.evergreen.sx_max_export_size = 256;
33078c2ecf20Sopenharmony_ci		rdev->config.evergreen.sx_max_export_pos_size = 64;
33088c2ecf20Sopenharmony_ci		rdev->config.evergreen.sx_max_export_smx_size = 192;
33098c2ecf20Sopenharmony_ci		rdev->config.evergreen.max_hw_contexts = 4;
33108c2ecf20Sopenharmony_ci		rdev->config.evergreen.sq_num_cf_insts = 2;
33118c2ecf20Sopenharmony_ci
33128c2ecf20Sopenharmony_ci		rdev->config.evergreen.sc_prim_fifo_size = 0x40;
33138c2ecf20Sopenharmony_ci		rdev->config.evergreen.sc_hiz_tile_fifo_size = 0x30;
33148c2ecf20Sopenharmony_ci		rdev->config.evergreen.sc_earlyz_tile_fifo_size = 0x130;
33158c2ecf20Sopenharmony_ci		gb_addr_config = SUMO2_GB_ADDR_CONFIG_GOLDEN;
33168c2ecf20Sopenharmony_ci		break;
33178c2ecf20Sopenharmony_ci	case CHIP_BARTS:
33188c2ecf20Sopenharmony_ci		rdev->config.evergreen.num_ses = 2;
33198c2ecf20Sopenharmony_ci		rdev->config.evergreen.max_pipes = 4;
33208c2ecf20Sopenharmony_ci		rdev->config.evergreen.max_tile_pipes = 8;
33218c2ecf20Sopenharmony_ci		rdev->config.evergreen.max_simds = 7;
33228c2ecf20Sopenharmony_ci		rdev->config.evergreen.max_backends = 4 * rdev->config.evergreen.num_ses;
33238c2ecf20Sopenharmony_ci		rdev->config.evergreen.max_gprs = 256;
33248c2ecf20Sopenharmony_ci		rdev->config.evergreen.max_threads = 248;
33258c2ecf20Sopenharmony_ci		rdev->config.evergreen.max_gs_threads = 32;
33268c2ecf20Sopenharmony_ci		rdev->config.evergreen.max_stack_entries = 512;
33278c2ecf20Sopenharmony_ci		rdev->config.evergreen.sx_num_of_sets = 4;
33288c2ecf20Sopenharmony_ci		rdev->config.evergreen.sx_max_export_size = 256;
33298c2ecf20Sopenharmony_ci		rdev->config.evergreen.sx_max_export_pos_size = 64;
33308c2ecf20Sopenharmony_ci		rdev->config.evergreen.sx_max_export_smx_size = 192;
33318c2ecf20Sopenharmony_ci		rdev->config.evergreen.max_hw_contexts = 8;
33328c2ecf20Sopenharmony_ci		rdev->config.evergreen.sq_num_cf_insts = 2;
33338c2ecf20Sopenharmony_ci
33348c2ecf20Sopenharmony_ci		rdev->config.evergreen.sc_prim_fifo_size = 0x100;
33358c2ecf20Sopenharmony_ci		rdev->config.evergreen.sc_hiz_tile_fifo_size = 0x30;
33368c2ecf20Sopenharmony_ci		rdev->config.evergreen.sc_earlyz_tile_fifo_size = 0x130;
33378c2ecf20Sopenharmony_ci		gb_addr_config = BARTS_GB_ADDR_CONFIG_GOLDEN;
33388c2ecf20Sopenharmony_ci		break;
33398c2ecf20Sopenharmony_ci	case CHIP_TURKS:
33408c2ecf20Sopenharmony_ci		rdev->config.evergreen.num_ses = 1;
33418c2ecf20Sopenharmony_ci		rdev->config.evergreen.max_pipes = 4;
33428c2ecf20Sopenharmony_ci		rdev->config.evergreen.max_tile_pipes = 4;
33438c2ecf20Sopenharmony_ci		rdev->config.evergreen.max_simds = 6;
33448c2ecf20Sopenharmony_ci		rdev->config.evergreen.max_backends = 2 * rdev->config.evergreen.num_ses;
33458c2ecf20Sopenharmony_ci		rdev->config.evergreen.max_gprs = 256;
33468c2ecf20Sopenharmony_ci		rdev->config.evergreen.max_threads = 248;
33478c2ecf20Sopenharmony_ci		rdev->config.evergreen.max_gs_threads = 32;
33488c2ecf20Sopenharmony_ci		rdev->config.evergreen.max_stack_entries = 256;
33498c2ecf20Sopenharmony_ci		rdev->config.evergreen.sx_num_of_sets = 4;
33508c2ecf20Sopenharmony_ci		rdev->config.evergreen.sx_max_export_size = 256;
33518c2ecf20Sopenharmony_ci		rdev->config.evergreen.sx_max_export_pos_size = 64;
33528c2ecf20Sopenharmony_ci		rdev->config.evergreen.sx_max_export_smx_size = 192;
33538c2ecf20Sopenharmony_ci		rdev->config.evergreen.max_hw_contexts = 8;
33548c2ecf20Sopenharmony_ci		rdev->config.evergreen.sq_num_cf_insts = 2;
33558c2ecf20Sopenharmony_ci
33568c2ecf20Sopenharmony_ci		rdev->config.evergreen.sc_prim_fifo_size = 0x100;
33578c2ecf20Sopenharmony_ci		rdev->config.evergreen.sc_hiz_tile_fifo_size = 0x30;
33588c2ecf20Sopenharmony_ci		rdev->config.evergreen.sc_earlyz_tile_fifo_size = 0x130;
33598c2ecf20Sopenharmony_ci		gb_addr_config = TURKS_GB_ADDR_CONFIG_GOLDEN;
33608c2ecf20Sopenharmony_ci		break;
33618c2ecf20Sopenharmony_ci	case CHIP_CAICOS:
33628c2ecf20Sopenharmony_ci		rdev->config.evergreen.num_ses = 1;
33638c2ecf20Sopenharmony_ci		rdev->config.evergreen.max_pipes = 2;
33648c2ecf20Sopenharmony_ci		rdev->config.evergreen.max_tile_pipes = 2;
33658c2ecf20Sopenharmony_ci		rdev->config.evergreen.max_simds = 2;
33668c2ecf20Sopenharmony_ci		rdev->config.evergreen.max_backends = 1 * rdev->config.evergreen.num_ses;
33678c2ecf20Sopenharmony_ci		rdev->config.evergreen.max_gprs = 256;
33688c2ecf20Sopenharmony_ci		rdev->config.evergreen.max_threads = 192;
33698c2ecf20Sopenharmony_ci		rdev->config.evergreen.max_gs_threads = 16;
33708c2ecf20Sopenharmony_ci		rdev->config.evergreen.max_stack_entries = 256;
33718c2ecf20Sopenharmony_ci		rdev->config.evergreen.sx_num_of_sets = 4;
33728c2ecf20Sopenharmony_ci		rdev->config.evergreen.sx_max_export_size = 128;
33738c2ecf20Sopenharmony_ci		rdev->config.evergreen.sx_max_export_pos_size = 32;
33748c2ecf20Sopenharmony_ci		rdev->config.evergreen.sx_max_export_smx_size = 96;
33758c2ecf20Sopenharmony_ci		rdev->config.evergreen.max_hw_contexts = 4;
33768c2ecf20Sopenharmony_ci		rdev->config.evergreen.sq_num_cf_insts = 1;
33778c2ecf20Sopenharmony_ci
33788c2ecf20Sopenharmony_ci		rdev->config.evergreen.sc_prim_fifo_size = 0x40;
33798c2ecf20Sopenharmony_ci		rdev->config.evergreen.sc_hiz_tile_fifo_size = 0x30;
33808c2ecf20Sopenharmony_ci		rdev->config.evergreen.sc_earlyz_tile_fifo_size = 0x130;
33818c2ecf20Sopenharmony_ci		gb_addr_config = CAICOS_GB_ADDR_CONFIG_GOLDEN;
33828c2ecf20Sopenharmony_ci		break;
33838c2ecf20Sopenharmony_ci	}
33848c2ecf20Sopenharmony_ci
33858c2ecf20Sopenharmony_ci	/* Initialize HDP */
33868c2ecf20Sopenharmony_ci	for (i = 0, j = 0; i < 32; i++, j += 0x18) {
33878c2ecf20Sopenharmony_ci		WREG32((0x2c14 + j), 0x00000000);
33888c2ecf20Sopenharmony_ci		WREG32((0x2c18 + j), 0x00000000);
33898c2ecf20Sopenharmony_ci		WREG32((0x2c1c + j), 0x00000000);
33908c2ecf20Sopenharmony_ci		WREG32((0x2c20 + j), 0x00000000);
33918c2ecf20Sopenharmony_ci		WREG32((0x2c24 + j), 0x00000000);
33928c2ecf20Sopenharmony_ci	}
33938c2ecf20Sopenharmony_ci
33948c2ecf20Sopenharmony_ci	WREG32(GRBM_CNTL, GRBM_READ_TIMEOUT(0xff));
33958c2ecf20Sopenharmony_ci	WREG32(SRBM_INT_CNTL, 0x1);
33968c2ecf20Sopenharmony_ci	WREG32(SRBM_INT_ACK, 0x1);
33978c2ecf20Sopenharmony_ci
33988c2ecf20Sopenharmony_ci	evergreen_fix_pci_max_read_req_size(rdev);
33998c2ecf20Sopenharmony_ci
34008c2ecf20Sopenharmony_ci	mc_shared_chmap = RREG32(MC_SHARED_CHMAP);
34018c2ecf20Sopenharmony_ci	if ((rdev->family == CHIP_PALM) ||
34028c2ecf20Sopenharmony_ci	    (rdev->family == CHIP_SUMO) ||
34038c2ecf20Sopenharmony_ci	    (rdev->family == CHIP_SUMO2))
34048c2ecf20Sopenharmony_ci		mc_arb_ramcfg = RREG32(FUS_MC_ARB_RAMCFG);
34058c2ecf20Sopenharmony_ci	else
34068c2ecf20Sopenharmony_ci		mc_arb_ramcfg = RREG32(MC_ARB_RAMCFG);
34078c2ecf20Sopenharmony_ci
34088c2ecf20Sopenharmony_ci	/* setup tiling info dword.  gb_addr_config is not adequate since it does
34098c2ecf20Sopenharmony_ci	 * not have bank info, so create a custom tiling dword.
34108c2ecf20Sopenharmony_ci	 * bits 3:0   num_pipes
34118c2ecf20Sopenharmony_ci	 * bits 7:4   num_banks
34128c2ecf20Sopenharmony_ci	 * bits 11:8  group_size
34138c2ecf20Sopenharmony_ci	 * bits 15:12 row_size
34148c2ecf20Sopenharmony_ci	 */
34158c2ecf20Sopenharmony_ci	rdev->config.evergreen.tile_config = 0;
34168c2ecf20Sopenharmony_ci	switch (rdev->config.evergreen.max_tile_pipes) {
34178c2ecf20Sopenharmony_ci	case 1:
34188c2ecf20Sopenharmony_ci	default:
34198c2ecf20Sopenharmony_ci		rdev->config.evergreen.tile_config |= (0 << 0);
34208c2ecf20Sopenharmony_ci		break;
34218c2ecf20Sopenharmony_ci	case 2:
34228c2ecf20Sopenharmony_ci		rdev->config.evergreen.tile_config |= (1 << 0);
34238c2ecf20Sopenharmony_ci		break;
34248c2ecf20Sopenharmony_ci	case 4:
34258c2ecf20Sopenharmony_ci		rdev->config.evergreen.tile_config |= (2 << 0);
34268c2ecf20Sopenharmony_ci		break;
34278c2ecf20Sopenharmony_ci	case 8:
34288c2ecf20Sopenharmony_ci		rdev->config.evergreen.tile_config |= (3 << 0);
34298c2ecf20Sopenharmony_ci		break;
34308c2ecf20Sopenharmony_ci	}
34318c2ecf20Sopenharmony_ci	/* num banks is 8 on all fusion asics. 0 = 4, 1 = 8, 2 = 16 */
34328c2ecf20Sopenharmony_ci	if (rdev->flags & RADEON_IS_IGP)
34338c2ecf20Sopenharmony_ci		rdev->config.evergreen.tile_config |= 1 << 4;
34348c2ecf20Sopenharmony_ci	else {
34358c2ecf20Sopenharmony_ci		switch ((mc_arb_ramcfg & NOOFBANK_MASK) >> NOOFBANK_SHIFT) {
34368c2ecf20Sopenharmony_ci		case 0: /* four banks */
34378c2ecf20Sopenharmony_ci			rdev->config.evergreen.tile_config |= 0 << 4;
34388c2ecf20Sopenharmony_ci			break;
34398c2ecf20Sopenharmony_ci		case 1: /* eight banks */
34408c2ecf20Sopenharmony_ci			rdev->config.evergreen.tile_config |= 1 << 4;
34418c2ecf20Sopenharmony_ci			break;
34428c2ecf20Sopenharmony_ci		case 2: /* sixteen banks */
34438c2ecf20Sopenharmony_ci		default:
34448c2ecf20Sopenharmony_ci			rdev->config.evergreen.tile_config |= 2 << 4;
34458c2ecf20Sopenharmony_ci			break;
34468c2ecf20Sopenharmony_ci		}
34478c2ecf20Sopenharmony_ci	}
34488c2ecf20Sopenharmony_ci	rdev->config.evergreen.tile_config |= 0 << 8;
34498c2ecf20Sopenharmony_ci	rdev->config.evergreen.tile_config |=
34508c2ecf20Sopenharmony_ci		((gb_addr_config & 0x30000000) >> 28) << 12;
34518c2ecf20Sopenharmony_ci
34528c2ecf20Sopenharmony_ci	if ((rdev->family >= CHIP_CEDAR) && (rdev->family <= CHIP_HEMLOCK)) {
34538c2ecf20Sopenharmony_ci		u32 efuse_straps_4;
34548c2ecf20Sopenharmony_ci		u32 efuse_straps_3;
34558c2ecf20Sopenharmony_ci
34568c2ecf20Sopenharmony_ci		efuse_straps_4 = RREG32_RCU(0x204);
34578c2ecf20Sopenharmony_ci		efuse_straps_3 = RREG32_RCU(0x203);
34588c2ecf20Sopenharmony_ci		tmp = (((efuse_straps_4 & 0xf) << 4) |
34598c2ecf20Sopenharmony_ci		      ((efuse_straps_3 & 0xf0000000) >> 28));
34608c2ecf20Sopenharmony_ci	} else {
34618c2ecf20Sopenharmony_ci		tmp = 0;
34628c2ecf20Sopenharmony_ci		for (i = (rdev->config.evergreen.num_ses - 1); i >= 0; i--) {
34638c2ecf20Sopenharmony_ci			u32 rb_disable_bitmap;
34648c2ecf20Sopenharmony_ci
34658c2ecf20Sopenharmony_ci			WREG32(GRBM_GFX_INDEX, INSTANCE_BROADCAST_WRITES | SE_INDEX(i));
34668c2ecf20Sopenharmony_ci			WREG32(RLC_GFX_INDEX, INSTANCE_BROADCAST_WRITES | SE_INDEX(i));
34678c2ecf20Sopenharmony_ci			rb_disable_bitmap = (RREG32(CC_RB_BACKEND_DISABLE) & 0x00ff0000) >> 16;
34688c2ecf20Sopenharmony_ci			tmp <<= 4;
34698c2ecf20Sopenharmony_ci			tmp |= rb_disable_bitmap;
34708c2ecf20Sopenharmony_ci		}
34718c2ecf20Sopenharmony_ci	}
34728c2ecf20Sopenharmony_ci	/* enabled rb are just the one not disabled :) */
34738c2ecf20Sopenharmony_ci	disabled_rb_mask = tmp;
34748c2ecf20Sopenharmony_ci	tmp = 0;
34758c2ecf20Sopenharmony_ci	for (i = 0; i < rdev->config.evergreen.max_backends; i++)
34768c2ecf20Sopenharmony_ci		tmp |= (1 << i);
34778c2ecf20Sopenharmony_ci	/* if all the backends are disabled, fix it up here */
34788c2ecf20Sopenharmony_ci	if ((disabled_rb_mask & tmp) == tmp) {
34798c2ecf20Sopenharmony_ci		for (i = 0; i < rdev->config.evergreen.max_backends; i++)
34808c2ecf20Sopenharmony_ci			disabled_rb_mask &= ~(1 << i);
34818c2ecf20Sopenharmony_ci	}
34828c2ecf20Sopenharmony_ci
34838c2ecf20Sopenharmony_ci	for (i = 0; i < rdev->config.evergreen.num_ses; i++) {
34848c2ecf20Sopenharmony_ci		u32 simd_disable_bitmap;
34858c2ecf20Sopenharmony_ci
34868c2ecf20Sopenharmony_ci		WREG32(GRBM_GFX_INDEX, INSTANCE_BROADCAST_WRITES | SE_INDEX(i));
34878c2ecf20Sopenharmony_ci		WREG32(RLC_GFX_INDEX, INSTANCE_BROADCAST_WRITES | SE_INDEX(i));
34888c2ecf20Sopenharmony_ci		simd_disable_bitmap = (RREG32(CC_GC_SHADER_PIPE_CONFIG) & 0xffff0000) >> 16;
34898c2ecf20Sopenharmony_ci		simd_disable_bitmap |= 0xffffffff << rdev->config.evergreen.max_simds;
34908c2ecf20Sopenharmony_ci		tmp <<= 16;
34918c2ecf20Sopenharmony_ci		tmp |= simd_disable_bitmap;
34928c2ecf20Sopenharmony_ci	}
34938c2ecf20Sopenharmony_ci	rdev->config.evergreen.active_simds = hweight32(~tmp);
34948c2ecf20Sopenharmony_ci
34958c2ecf20Sopenharmony_ci	WREG32(GRBM_GFX_INDEX, INSTANCE_BROADCAST_WRITES | SE_BROADCAST_WRITES);
34968c2ecf20Sopenharmony_ci	WREG32(RLC_GFX_INDEX, INSTANCE_BROADCAST_WRITES | SE_BROADCAST_WRITES);
34978c2ecf20Sopenharmony_ci
34988c2ecf20Sopenharmony_ci	WREG32(GB_ADDR_CONFIG, gb_addr_config);
34998c2ecf20Sopenharmony_ci	WREG32(DMIF_ADDR_CONFIG, gb_addr_config);
35008c2ecf20Sopenharmony_ci	WREG32(HDP_ADDR_CONFIG, gb_addr_config);
35018c2ecf20Sopenharmony_ci	WREG32(DMA_TILING_CONFIG, gb_addr_config);
35028c2ecf20Sopenharmony_ci	WREG32(UVD_UDEC_ADDR_CONFIG, gb_addr_config);
35038c2ecf20Sopenharmony_ci	WREG32(UVD_UDEC_DB_ADDR_CONFIG, gb_addr_config);
35048c2ecf20Sopenharmony_ci	WREG32(UVD_UDEC_DBW_ADDR_CONFIG, gb_addr_config);
35058c2ecf20Sopenharmony_ci
35068c2ecf20Sopenharmony_ci	if ((rdev->config.evergreen.max_backends == 1) &&
35078c2ecf20Sopenharmony_ci	    (rdev->flags & RADEON_IS_IGP)) {
35088c2ecf20Sopenharmony_ci		if ((disabled_rb_mask & 3) == 1) {
35098c2ecf20Sopenharmony_ci			/* RB0 disabled, RB1 enabled */
35108c2ecf20Sopenharmony_ci			tmp = 0x11111111;
35118c2ecf20Sopenharmony_ci		} else {
35128c2ecf20Sopenharmony_ci			/* RB1 disabled, RB0 enabled */
35138c2ecf20Sopenharmony_ci			tmp = 0x00000000;
35148c2ecf20Sopenharmony_ci		}
35158c2ecf20Sopenharmony_ci	} else {
35168c2ecf20Sopenharmony_ci		tmp = gb_addr_config & NUM_PIPES_MASK;
35178c2ecf20Sopenharmony_ci		tmp = r6xx_remap_render_backend(rdev, tmp, rdev->config.evergreen.max_backends,
35188c2ecf20Sopenharmony_ci						EVERGREEN_MAX_BACKENDS, disabled_rb_mask);
35198c2ecf20Sopenharmony_ci	}
35208c2ecf20Sopenharmony_ci	rdev->config.evergreen.backend_map = tmp;
35218c2ecf20Sopenharmony_ci	WREG32(GB_BACKEND_MAP, tmp);
35228c2ecf20Sopenharmony_ci
35238c2ecf20Sopenharmony_ci	WREG32(CGTS_SYS_TCC_DISABLE, 0);
35248c2ecf20Sopenharmony_ci	WREG32(CGTS_TCC_DISABLE, 0);
35258c2ecf20Sopenharmony_ci	WREG32(CGTS_USER_SYS_TCC_DISABLE, 0);
35268c2ecf20Sopenharmony_ci	WREG32(CGTS_USER_TCC_DISABLE, 0);
35278c2ecf20Sopenharmony_ci
35288c2ecf20Sopenharmony_ci	/* set HW defaults for 3D engine */
35298c2ecf20Sopenharmony_ci	WREG32(CP_QUEUE_THRESHOLDS, (ROQ_IB1_START(0x16) |
35308c2ecf20Sopenharmony_ci				     ROQ_IB2_START(0x2b)));
35318c2ecf20Sopenharmony_ci
35328c2ecf20Sopenharmony_ci	WREG32(CP_MEQ_THRESHOLDS, STQ_SPLIT(0x30));
35338c2ecf20Sopenharmony_ci
35348c2ecf20Sopenharmony_ci	WREG32(TA_CNTL_AUX, (DISABLE_CUBE_ANISO |
35358c2ecf20Sopenharmony_ci			     SYNC_GRADIENT |
35368c2ecf20Sopenharmony_ci			     SYNC_WALKER |
35378c2ecf20Sopenharmony_ci			     SYNC_ALIGNER));
35388c2ecf20Sopenharmony_ci
35398c2ecf20Sopenharmony_ci	sx_debug_1 = RREG32(SX_DEBUG_1);
35408c2ecf20Sopenharmony_ci	sx_debug_1 |= ENABLE_NEW_SMX_ADDRESS;
35418c2ecf20Sopenharmony_ci	WREG32(SX_DEBUG_1, sx_debug_1);
35428c2ecf20Sopenharmony_ci
35438c2ecf20Sopenharmony_ci
35448c2ecf20Sopenharmony_ci	smx_dc_ctl0 = RREG32(SMX_DC_CTL0);
35458c2ecf20Sopenharmony_ci	smx_dc_ctl0 &= ~NUMBER_OF_SETS(0x1ff);
35468c2ecf20Sopenharmony_ci	smx_dc_ctl0 |= NUMBER_OF_SETS(rdev->config.evergreen.sx_num_of_sets);
35478c2ecf20Sopenharmony_ci	WREG32(SMX_DC_CTL0, smx_dc_ctl0);
35488c2ecf20Sopenharmony_ci
35498c2ecf20Sopenharmony_ci	if (rdev->family <= CHIP_SUMO2)
35508c2ecf20Sopenharmony_ci		WREG32(SMX_SAR_CTL0, 0x00010000);
35518c2ecf20Sopenharmony_ci
35528c2ecf20Sopenharmony_ci	WREG32(SX_EXPORT_BUFFER_SIZES, (COLOR_BUFFER_SIZE((rdev->config.evergreen.sx_max_export_size / 4) - 1) |
35538c2ecf20Sopenharmony_ci					POSITION_BUFFER_SIZE((rdev->config.evergreen.sx_max_export_pos_size / 4) - 1) |
35548c2ecf20Sopenharmony_ci					SMX_BUFFER_SIZE((rdev->config.evergreen.sx_max_export_smx_size / 4) - 1)));
35558c2ecf20Sopenharmony_ci
35568c2ecf20Sopenharmony_ci	WREG32(PA_SC_FIFO_SIZE, (SC_PRIM_FIFO_SIZE(rdev->config.evergreen.sc_prim_fifo_size) |
35578c2ecf20Sopenharmony_ci				 SC_HIZ_TILE_FIFO_SIZE(rdev->config.evergreen.sc_hiz_tile_fifo_size) |
35588c2ecf20Sopenharmony_ci				 SC_EARLYZ_TILE_FIFO_SIZE(rdev->config.evergreen.sc_earlyz_tile_fifo_size)));
35598c2ecf20Sopenharmony_ci
35608c2ecf20Sopenharmony_ci	WREG32(VGT_NUM_INSTANCES, 1);
35618c2ecf20Sopenharmony_ci	WREG32(SPI_CONFIG_CNTL, 0);
35628c2ecf20Sopenharmony_ci	WREG32(SPI_CONFIG_CNTL_1, VTX_DONE_DELAY(4));
35638c2ecf20Sopenharmony_ci	WREG32(CP_PERFMON_CNTL, 0);
35648c2ecf20Sopenharmony_ci
35658c2ecf20Sopenharmony_ci	WREG32(SQ_MS_FIFO_SIZES, (CACHE_FIFO_SIZE(16 * rdev->config.evergreen.sq_num_cf_insts) |
35668c2ecf20Sopenharmony_ci				  FETCH_FIFO_HIWATER(0x4) |
35678c2ecf20Sopenharmony_ci				  DONE_FIFO_HIWATER(0xe0) |
35688c2ecf20Sopenharmony_ci				  ALU_UPDATE_FIFO_HIWATER(0x8)));
35698c2ecf20Sopenharmony_ci
35708c2ecf20Sopenharmony_ci	sq_config = RREG32(SQ_CONFIG);
35718c2ecf20Sopenharmony_ci	sq_config &= ~(PS_PRIO(3) |
35728c2ecf20Sopenharmony_ci		       VS_PRIO(3) |
35738c2ecf20Sopenharmony_ci		       GS_PRIO(3) |
35748c2ecf20Sopenharmony_ci		       ES_PRIO(3));
35758c2ecf20Sopenharmony_ci	sq_config |= (VC_ENABLE |
35768c2ecf20Sopenharmony_ci		      EXPORT_SRC_C |
35778c2ecf20Sopenharmony_ci		      PS_PRIO(0) |
35788c2ecf20Sopenharmony_ci		      VS_PRIO(1) |
35798c2ecf20Sopenharmony_ci		      GS_PRIO(2) |
35808c2ecf20Sopenharmony_ci		      ES_PRIO(3));
35818c2ecf20Sopenharmony_ci
35828c2ecf20Sopenharmony_ci	switch (rdev->family) {
35838c2ecf20Sopenharmony_ci	case CHIP_CEDAR:
35848c2ecf20Sopenharmony_ci	case CHIP_PALM:
35858c2ecf20Sopenharmony_ci	case CHIP_SUMO:
35868c2ecf20Sopenharmony_ci	case CHIP_SUMO2:
35878c2ecf20Sopenharmony_ci	case CHIP_CAICOS:
35888c2ecf20Sopenharmony_ci		/* no vertex cache */
35898c2ecf20Sopenharmony_ci		sq_config &= ~VC_ENABLE;
35908c2ecf20Sopenharmony_ci		break;
35918c2ecf20Sopenharmony_ci	default:
35928c2ecf20Sopenharmony_ci		break;
35938c2ecf20Sopenharmony_ci	}
35948c2ecf20Sopenharmony_ci
35958c2ecf20Sopenharmony_ci	sq_lds_resource_mgmt = RREG32(SQ_LDS_RESOURCE_MGMT);
35968c2ecf20Sopenharmony_ci
35978c2ecf20Sopenharmony_ci	sq_gpr_resource_mgmt_1 = NUM_PS_GPRS((rdev->config.evergreen.max_gprs - (4 * 2))* 12 / 32);
35988c2ecf20Sopenharmony_ci	sq_gpr_resource_mgmt_1 |= NUM_VS_GPRS((rdev->config.evergreen.max_gprs - (4 * 2)) * 6 / 32);
35998c2ecf20Sopenharmony_ci	sq_gpr_resource_mgmt_1 |= NUM_CLAUSE_TEMP_GPRS(4);
36008c2ecf20Sopenharmony_ci	sq_gpr_resource_mgmt_2 = NUM_GS_GPRS((rdev->config.evergreen.max_gprs - (4 * 2)) * 4 / 32);
36018c2ecf20Sopenharmony_ci	sq_gpr_resource_mgmt_2 |= NUM_ES_GPRS((rdev->config.evergreen.max_gprs - (4 * 2)) * 4 / 32);
36028c2ecf20Sopenharmony_ci	sq_gpr_resource_mgmt_3 = NUM_HS_GPRS((rdev->config.evergreen.max_gprs - (4 * 2)) * 3 / 32);
36038c2ecf20Sopenharmony_ci	sq_gpr_resource_mgmt_3 |= NUM_LS_GPRS((rdev->config.evergreen.max_gprs - (4 * 2)) * 3 / 32);
36048c2ecf20Sopenharmony_ci
36058c2ecf20Sopenharmony_ci	switch (rdev->family) {
36068c2ecf20Sopenharmony_ci	case CHIP_CEDAR:
36078c2ecf20Sopenharmony_ci	case CHIP_PALM:
36088c2ecf20Sopenharmony_ci	case CHIP_SUMO:
36098c2ecf20Sopenharmony_ci	case CHIP_SUMO2:
36108c2ecf20Sopenharmony_ci		ps_thread_count = 96;
36118c2ecf20Sopenharmony_ci		break;
36128c2ecf20Sopenharmony_ci	default:
36138c2ecf20Sopenharmony_ci		ps_thread_count = 128;
36148c2ecf20Sopenharmony_ci		break;
36158c2ecf20Sopenharmony_ci	}
36168c2ecf20Sopenharmony_ci
36178c2ecf20Sopenharmony_ci	sq_thread_resource_mgmt = NUM_PS_THREADS(ps_thread_count);
36188c2ecf20Sopenharmony_ci	sq_thread_resource_mgmt |= NUM_VS_THREADS((((rdev->config.evergreen.max_threads - ps_thread_count) / 6) / 8) * 8);
36198c2ecf20Sopenharmony_ci	sq_thread_resource_mgmt |= NUM_GS_THREADS((((rdev->config.evergreen.max_threads - ps_thread_count) / 6) / 8) * 8);
36208c2ecf20Sopenharmony_ci	sq_thread_resource_mgmt |= NUM_ES_THREADS((((rdev->config.evergreen.max_threads - ps_thread_count) / 6) / 8) * 8);
36218c2ecf20Sopenharmony_ci	sq_thread_resource_mgmt_2 = NUM_HS_THREADS((((rdev->config.evergreen.max_threads - ps_thread_count) / 6) / 8) * 8);
36228c2ecf20Sopenharmony_ci	sq_thread_resource_mgmt_2 |= NUM_LS_THREADS((((rdev->config.evergreen.max_threads - ps_thread_count) / 6) / 8) * 8);
36238c2ecf20Sopenharmony_ci
36248c2ecf20Sopenharmony_ci	sq_stack_resource_mgmt_1 = NUM_PS_STACK_ENTRIES((rdev->config.evergreen.max_stack_entries * 1) / 6);
36258c2ecf20Sopenharmony_ci	sq_stack_resource_mgmt_1 |= NUM_VS_STACK_ENTRIES((rdev->config.evergreen.max_stack_entries * 1) / 6);
36268c2ecf20Sopenharmony_ci	sq_stack_resource_mgmt_2 = NUM_GS_STACK_ENTRIES((rdev->config.evergreen.max_stack_entries * 1) / 6);
36278c2ecf20Sopenharmony_ci	sq_stack_resource_mgmt_2 |= NUM_ES_STACK_ENTRIES((rdev->config.evergreen.max_stack_entries * 1) / 6);
36288c2ecf20Sopenharmony_ci	sq_stack_resource_mgmt_3 = NUM_HS_STACK_ENTRIES((rdev->config.evergreen.max_stack_entries * 1) / 6);
36298c2ecf20Sopenharmony_ci	sq_stack_resource_mgmt_3 |= NUM_LS_STACK_ENTRIES((rdev->config.evergreen.max_stack_entries * 1) / 6);
36308c2ecf20Sopenharmony_ci
36318c2ecf20Sopenharmony_ci	WREG32(SQ_CONFIG, sq_config);
36328c2ecf20Sopenharmony_ci	WREG32(SQ_GPR_RESOURCE_MGMT_1, sq_gpr_resource_mgmt_1);
36338c2ecf20Sopenharmony_ci	WREG32(SQ_GPR_RESOURCE_MGMT_2, sq_gpr_resource_mgmt_2);
36348c2ecf20Sopenharmony_ci	WREG32(SQ_GPR_RESOURCE_MGMT_3, sq_gpr_resource_mgmt_3);
36358c2ecf20Sopenharmony_ci	WREG32(SQ_THREAD_RESOURCE_MGMT, sq_thread_resource_mgmt);
36368c2ecf20Sopenharmony_ci	WREG32(SQ_THREAD_RESOURCE_MGMT_2, sq_thread_resource_mgmt_2);
36378c2ecf20Sopenharmony_ci	WREG32(SQ_STACK_RESOURCE_MGMT_1, sq_stack_resource_mgmt_1);
36388c2ecf20Sopenharmony_ci	WREG32(SQ_STACK_RESOURCE_MGMT_2, sq_stack_resource_mgmt_2);
36398c2ecf20Sopenharmony_ci	WREG32(SQ_STACK_RESOURCE_MGMT_3, sq_stack_resource_mgmt_3);
36408c2ecf20Sopenharmony_ci	WREG32(SQ_DYN_GPR_CNTL_PS_FLUSH_REQ, 0);
36418c2ecf20Sopenharmony_ci	WREG32(SQ_LDS_RESOURCE_MGMT, sq_lds_resource_mgmt);
36428c2ecf20Sopenharmony_ci
36438c2ecf20Sopenharmony_ci	WREG32(PA_SC_FORCE_EOV_MAX_CNTS, (FORCE_EOV_MAX_CLK_CNT(4095) |
36448c2ecf20Sopenharmony_ci					  FORCE_EOV_MAX_REZ_CNT(255)));
36458c2ecf20Sopenharmony_ci
36468c2ecf20Sopenharmony_ci	switch (rdev->family) {
36478c2ecf20Sopenharmony_ci	case CHIP_CEDAR:
36488c2ecf20Sopenharmony_ci	case CHIP_PALM:
36498c2ecf20Sopenharmony_ci	case CHIP_SUMO:
36508c2ecf20Sopenharmony_ci	case CHIP_SUMO2:
36518c2ecf20Sopenharmony_ci	case CHIP_CAICOS:
36528c2ecf20Sopenharmony_ci		vgt_cache_invalidation = CACHE_INVALIDATION(TC_ONLY);
36538c2ecf20Sopenharmony_ci		break;
36548c2ecf20Sopenharmony_ci	default:
36558c2ecf20Sopenharmony_ci		vgt_cache_invalidation = CACHE_INVALIDATION(VC_AND_TC);
36568c2ecf20Sopenharmony_ci		break;
36578c2ecf20Sopenharmony_ci	}
36588c2ecf20Sopenharmony_ci	vgt_cache_invalidation |= AUTO_INVLD_EN(ES_AND_GS_AUTO);
36598c2ecf20Sopenharmony_ci	WREG32(VGT_CACHE_INVALIDATION, vgt_cache_invalidation);
36608c2ecf20Sopenharmony_ci
36618c2ecf20Sopenharmony_ci	WREG32(VGT_GS_VERTEX_REUSE, 16);
36628c2ecf20Sopenharmony_ci	WREG32(PA_SU_LINE_STIPPLE_VALUE, 0);
36638c2ecf20Sopenharmony_ci	WREG32(PA_SC_LINE_STIPPLE_STATE, 0);
36648c2ecf20Sopenharmony_ci
36658c2ecf20Sopenharmony_ci	WREG32(VGT_VERTEX_REUSE_BLOCK_CNTL, 14);
36668c2ecf20Sopenharmony_ci	WREG32(VGT_OUT_DEALLOC_CNTL, 16);
36678c2ecf20Sopenharmony_ci
36688c2ecf20Sopenharmony_ci	WREG32(CB_PERF_CTR0_SEL_0, 0);
36698c2ecf20Sopenharmony_ci	WREG32(CB_PERF_CTR0_SEL_1, 0);
36708c2ecf20Sopenharmony_ci	WREG32(CB_PERF_CTR1_SEL_0, 0);
36718c2ecf20Sopenharmony_ci	WREG32(CB_PERF_CTR1_SEL_1, 0);
36728c2ecf20Sopenharmony_ci	WREG32(CB_PERF_CTR2_SEL_0, 0);
36738c2ecf20Sopenharmony_ci	WREG32(CB_PERF_CTR2_SEL_1, 0);
36748c2ecf20Sopenharmony_ci	WREG32(CB_PERF_CTR3_SEL_0, 0);
36758c2ecf20Sopenharmony_ci	WREG32(CB_PERF_CTR3_SEL_1, 0);
36768c2ecf20Sopenharmony_ci
36778c2ecf20Sopenharmony_ci	/* clear render buffer base addresses */
36788c2ecf20Sopenharmony_ci	WREG32(CB_COLOR0_BASE, 0);
36798c2ecf20Sopenharmony_ci	WREG32(CB_COLOR1_BASE, 0);
36808c2ecf20Sopenharmony_ci	WREG32(CB_COLOR2_BASE, 0);
36818c2ecf20Sopenharmony_ci	WREG32(CB_COLOR3_BASE, 0);
36828c2ecf20Sopenharmony_ci	WREG32(CB_COLOR4_BASE, 0);
36838c2ecf20Sopenharmony_ci	WREG32(CB_COLOR5_BASE, 0);
36848c2ecf20Sopenharmony_ci	WREG32(CB_COLOR6_BASE, 0);
36858c2ecf20Sopenharmony_ci	WREG32(CB_COLOR7_BASE, 0);
36868c2ecf20Sopenharmony_ci	WREG32(CB_COLOR8_BASE, 0);
36878c2ecf20Sopenharmony_ci	WREG32(CB_COLOR9_BASE, 0);
36888c2ecf20Sopenharmony_ci	WREG32(CB_COLOR10_BASE, 0);
36898c2ecf20Sopenharmony_ci	WREG32(CB_COLOR11_BASE, 0);
36908c2ecf20Sopenharmony_ci
36918c2ecf20Sopenharmony_ci	/* set the shader const cache sizes to 0 */
36928c2ecf20Sopenharmony_ci	for (i = SQ_ALU_CONST_BUFFER_SIZE_PS_0; i < 0x28200; i += 4)
36938c2ecf20Sopenharmony_ci		WREG32(i, 0);
36948c2ecf20Sopenharmony_ci	for (i = SQ_ALU_CONST_BUFFER_SIZE_HS_0; i < 0x29000; i += 4)
36958c2ecf20Sopenharmony_ci		WREG32(i, 0);
36968c2ecf20Sopenharmony_ci
36978c2ecf20Sopenharmony_ci	tmp = RREG32(HDP_MISC_CNTL);
36988c2ecf20Sopenharmony_ci	tmp |= HDP_FLUSH_INVALIDATE_CACHE;
36998c2ecf20Sopenharmony_ci	WREG32(HDP_MISC_CNTL, tmp);
37008c2ecf20Sopenharmony_ci
37018c2ecf20Sopenharmony_ci	hdp_host_path_cntl = RREG32(HDP_HOST_PATH_CNTL);
37028c2ecf20Sopenharmony_ci	WREG32(HDP_HOST_PATH_CNTL, hdp_host_path_cntl);
37038c2ecf20Sopenharmony_ci
37048c2ecf20Sopenharmony_ci	WREG32(PA_CL_ENHANCE, CLIP_VTX_REORDER_ENA | NUM_CLIP_SEQ(3));
37058c2ecf20Sopenharmony_ci
37068c2ecf20Sopenharmony_ci	udelay(50);
37078c2ecf20Sopenharmony_ci
37088c2ecf20Sopenharmony_ci}
37098c2ecf20Sopenharmony_ci
37108c2ecf20Sopenharmony_ciint evergreen_mc_init(struct radeon_device *rdev)
37118c2ecf20Sopenharmony_ci{
37128c2ecf20Sopenharmony_ci	u32 tmp;
37138c2ecf20Sopenharmony_ci	int chansize, numchan;
37148c2ecf20Sopenharmony_ci
37158c2ecf20Sopenharmony_ci	/* Get VRAM informations */
37168c2ecf20Sopenharmony_ci	rdev->mc.vram_is_ddr = true;
37178c2ecf20Sopenharmony_ci	if ((rdev->family == CHIP_PALM) ||
37188c2ecf20Sopenharmony_ci	    (rdev->family == CHIP_SUMO) ||
37198c2ecf20Sopenharmony_ci	    (rdev->family == CHIP_SUMO2))
37208c2ecf20Sopenharmony_ci		tmp = RREG32(FUS_MC_ARB_RAMCFG);
37218c2ecf20Sopenharmony_ci	else
37228c2ecf20Sopenharmony_ci		tmp = RREG32(MC_ARB_RAMCFG);
37238c2ecf20Sopenharmony_ci	if (tmp & CHANSIZE_OVERRIDE) {
37248c2ecf20Sopenharmony_ci		chansize = 16;
37258c2ecf20Sopenharmony_ci	} else if (tmp & CHANSIZE_MASK) {
37268c2ecf20Sopenharmony_ci		chansize = 64;
37278c2ecf20Sopenharmony_ci	} else {
37288c2ecf20Sopenharmony_ci		chansize = 32;
37298c2ecf20Sopenharmony_ci	}
37308c2ecf20Sopenharmony_ci	tmp = RREG32(MC_SHARED_CHMAP);
37318c2ecf20Sopenharmony_ci	switch ((tmp & NOOFCHAN_MASK) >> NOOFCHAN_SHIFT) {
37328c2ecf20Sopenharmony_ci	case 0:
37338c2ecf20Sopenharmony_ci	default:
37348c2ecf20Sopenharmony_ci		numchan = 1;
37358c2ecf20Sopenharmony_ci		break;
37368c2ecf20Sopenharmony_ci	case 1:
37378c2ecf20Sopenharmony_ci		numchan = 2;
37388c2ecf20Sopenharmony_ci		break;
37398c2ecf20Sopenharmony_ci	case 2:
37408c2ecf20Sopenharmony_ci		numchan = 4;
37418c2ecf20Sopenharmony_ci		break;
37428c2ecf20Sopenharmony_ci	case 3:
37438c2ecf20Sopenharmony_ci		numchan = 8;
37448c2ecf20Sopenharmony_ci		break;
37458c2ecf20Sopenharmony_ci	}
37468c2ecf20Sopenharmony_ci	rdev->mc.vram_width = numchan * chansize;
37478c2ecf20Sopenharmony_ci	/* Could aper size report 0 ? */
37488c2ecf20Sopenharmony_ci	rdev->mc.aper_base = pci_resource_start(rdev->pdev, 0);
37498c2ecf20Sopenharmony_ci	rdev->mc.aper_size = pci_resource_len(rdev->pdev, 0);
37508c2ecf20Sopenharmony_ci	/* Setup GPU memory space */
37518c2ecf20Sopenharmony_ci	if ((rdev->family == CHIP_PALM) ||
37528c2ecf20Sopenharmony_ci	    (rdev->family == CHIP_SUMO) ||
37538c2ecf20Sopenharmony_ci	    (rdev->family == CHIP_SUMO2)) {
37548c2ecf20Sopenharmony_ci		/* size in bytes on fusion */
37558c2ecf20Sopenharmony_ci		rdev->mc.mc_vram_size = RREG32(CONFIG_MEMSIZE);
37568c2ecf20Sopenharmony_ci		rdev->mc.real_vram_size = RREG32(CONFIG_MEMSIZE);
37578c2ecf20Sopenharmony_ci	} else {
37588c2ecf20Sopenharmony_ci		/* size in MB on evergreen/cayman/tn */
37598c2ecf20Sopenharmony_ci		rdev->mc.mc_vram_size = RREG32(CONFIG_MEMSIZE) * 1024ULL * 1024ULL;
37608c2ecf20Sopenharmony_ci		rdev->mc.real_vram_size = RREG32(CONFIG_MEMSIZE) * 1024ULL * 1024ULL;
37618c2ecf20Sopenharmony_ci	}
37628c2ecf20Sopenharmony_ci	rdev->mc.visible_vram_size = rdev->mc.aper_size;
37638c2ecf20Sopenharmony_ci	r700_vram_gtt_location(rdev, &rdev->mc);
37648c2ecf20Sopenharmony_ci	radeon_update_bandwidth_info(rdev);
37658c2ecf20Sopenharmony_ci
37668c2ecf20Sopenharmony_ci	return 0;
37678c2ecf20Sopenharmony_ci}
37688c2ecf20Sopenharmony_ci
37698c2ecf20Sopenharmony_civoid evergreen_print_gpu_status_regs(struct radeon_device *rdev)
37708c2ecf20Sopenharmony_ci{
37718c2ecf20Sopenharmony_ci	dev_info(rdev->dev, "  GRBM_STATUS               = 0x%08X\n",
37728c2ecf20Sopenharmony_ci		RREG32(GRBM_STATUS));
37738c2ecf20Sopenharmony_ci	dev_info(rdev->dev, "  GRBM_STATUS_SE0           = 0x%08X\n",
37748c2ecf20Sopenharmony_ci		RREG32(GRBM_STATUS_SE0));
37758c2ecf20Sopenharmony_ci	dev_info(rdev->dev, "  GRBM_STATUS_SE1           = 0x%08X\n",
37768c2ecf20Sopenharmony_ci		RREG32(GRBM_STATUS_SE1));
37778c2ecf20Sopenharmony_ci	dev_info(rdev->dev, "  SRBM_STATUS               = 0x%08X\n",
37788c2ecf20Sopenharmony_ci		RREG32(SRBM_STATUS));
37798c2ecf20Sopenharmony_ci	dev_info(rdev->dev, "  SRBM_STATUS2              = 0x%08X\n",
37808c2ecf20Sopenharmony_ci		RREG32(SRBM_STATUS2));
37818c2ecf20Sopenharmony_ci	dev_info(rdev->dev, "  R_008674_CP_STALLED_STAT1 = 0x%08X\n",
37828c2ecf20Sopenharmony_ci		RREG32(CP_STALLED_STAT1));
37838c2ecf20Sopenharmony_ci	dev_info(rdev->dev, "  R_008678_CP_STALLED_STAT2 = 0x%08X\n",
37848c2ecf20Sopenharmony_ci		RREG32(CP_STALLED_STAT2));
37858c2ecf20Sopenharmony_ci	dev_info(rdev->dev, "  R_00867C_CP_BUSY_STAT     = 0x%08X\n",
37868c2ecf20Sopenharmony_ci		RREG32(CP_BUSY_STAT));
37878c2ecf20Sopenharmony_ci	dev_info(rdev->dev, "  R_008680_CP_STAT          = 0x%08X\n",
37888c2ecf20Sopenharmony_ci		RREG32(CP_STAT));
37898c2ecf20Sopenharmony_ci	dev_info(rdev->dev, "  R_00D034_DMA_STATUS_REG   = 0x%08X\n",
37908c2ecf20Sopenharmony_ci		RREG32(DMA_STATUS_REG));
37918c2ecf20Sopenharmony_ci	if (rdev->family >= CHIP_CAYMAN) {
37928c2ecf20Sopenharmony_ci		dev_info(rdev->dev, "  R_00D834_DMA_STATUS_REG   = 0x%08X\n",
37938c2ecf20Sopenharmony_ci			 RREG32(DMA_STATUS_REG + 0x800));
37948c2ecf20Sopenharmony_ci	}
37958c2ecf20Sopenharmony_ci}
37968c2ecf20Sopenharmony_ci
37978c2ecf20Sopenharmony_cibool evergreen_is_display_hung(struct radeon_device *rdev)
37988c2ecf20Sopenharmony_ci{
37998c2ecf20Sopenharmony_ci	u32 crtc_hung = 0;
38008c2ecf20Sopenharmony_ci	u32 crtc_status[6];
38018c2ecf20Sopenharmony_ci	u32 i, j, tmp;
38028c2ecf20Sopenharmony_ci
38038c2ecf20Sopenharmony_ci	for (i = 0; i < rdev->num_crtc; i++) {
38048c2ecf20Sopenharmony_ci		if (RREG32(EVERGREEN_CRTC_CONTROL + crtc_offsets[i]) & EVERGREEN_CRTC_MASTER_EN) {
38058c2ecf20Sopenharmony_ci			crtc_status[i] = RREG32(EVERGREEN_CRTC_STATUS_HV_COUNT + crtc_offsets[i]);
38068c2ecf20Sopenharmony_ci			crtc_hung |= (1 << i);
38078c2ecf20Sopenharmony_ci		}
38088c2ecf20Sopenharmony_ci	}
38098c2ecf20Sopenharmony_ci
38108c2ecf20Sopenharmony_ci	for (j = 0; j < 10; j++) {
38118c2ecf20Sopenharmony_ci		for (i = 0; i < rdev->num_crtc; i++) {
38128c2ecf20Sopenharmony_ci			if (crtc_hung & (1 << i)) {
38138c2ecf20Sopenharmony_ci				tmp = RREG32(EVERGREEN_CRTC_STATUS_HV_COUNT + crtc_offsets[i]);
38148c2ecf20Sopenharmony_ci				if (tmp != crtc_status[i])
38158c2ecf20Sopenharmony_ci					crtc_hung &= ~(1 << i);
38168c2ecf20Sopenharmony_ci			}
38178c2ecf20Sopenharmony_ci		}
38188c2ecf20Sopenharmony_ci		if (crtc_hung == 0)
38198c2ecf20Sopenharmony_ci			return false;
38208c2ecf20Sopenharmony_ci		udelay(100);
38218c2ecf20Sopenharmony_ci	}
38228c2ecf20Sopenharmony_ci
38238c2ecf20Sopenharmony_ci	return true;
38248c2ecf20Sopenharmony_ci}
38258c2ecf20Sopenharmony_ci
38268c2ecf20Sopenharmony_ciu32 evergreen_gpu_check_soft_reset(struct radeon_device *rdev)
38278c2ecf20Sopenharmony_ci{
38288c2ecf20Sopenharmony_ci	u32 reset_mask = 0;
38298c2ecf20Sopenharmony_ci	u32 tmp;
38308c2ecf20Sopenharmony_ci
38318c2ecf20Sopenharmony_ci	/* GRBM_STATUS */
38328c2ecf20Sopenharmony_ci	tmp = RREG32(GRBM_STATUS);
38338c2ecf20Sopenharmony_ci	if (tmp & (PA_BUSY | SC_BUSY |
38348c2ecf20Sopenharmony_ci		   SH_BUSY | SX_BUSY |
38358c2ecf20Sopenharmony_ci		   TA_BUSY | VGT_BUSY |
38368c2ecf20Sopenharmony_ci		   DB_BUSY | CB_BUSY |
38378c2ecf20Sopenharmony_ci		   SPI_BUSY | VGT_BUSY_NO_DMA))
38388c2ecf20Sopenharmony_ci		reset_mask |= RADEON_RESET_GFX;
38398c2ecf20Sopenharmony_ci
38408c2ecf20Sopenharmony_ci	if (tmp & (CF_RQ_PENDING | PF_RQ_PENDING |
38418c2ecf20Sopenharmony_ci		   CP_BUSY | CP_COHERENCY_BUSY))
38428c2ecf20Sopenharmony_ci		reset_mask |= RADEON_RESET_CP;
38438c2ecf20Sopenharmony_ci
38448c2ecf20Sopenharmony_ci	if (tmp & GRBM_EE_BUSY)
38458c2ecf20Sopenharmony_ci		reset_mask |= RADEON_RESET_GRBM | RADEON_RESET_GFX | RADEON_RESET_CP;
38468c2ecf20Sopenharmony_ci
38478c2ecf20Sopenharmony_ci	/* DMA_STATUS_REG */
38488c2ecf20Sopenharmony_ci	tmp = RREG32(DMA_STATUS_REG);
38498c2ecf20Sopenharmony_ci	if (!(tmp & DMA_IDLE))
38508c2ecf20Sopenharmony_ci		reset_mask |= RADEON_RESET_DMA;
38518c2ecf20Sopenharmony_ci
38528c2ecf20Sopenharmony_ci	/* SRBM_STATUS2 */
38538c2ecf20Sopenharmony_ci	tmp = RREG32(SRBM_STATUS2);
38548c2ecf20Sopenharmony_ci	if (tmp & DMA_BUSY)
38558c2ecf20Sopenharmony_ci		reset_mask |= RADEON_RESET_DMA;
38568c2ecf20Sopenharmony_ci
38578c2ecf20Sopenharmony_ci	/* SRBM_STATUS */
38588c2ecf20Sopenharmony_ci	tmp = RREG32(SRBM_STATUS);
38598c2ecf20Sopenharmony_ci	if (tmp & (RLC_RQ_PENDING | RLC_BUSY))
38608c2ecf20Sopenharmony_ci		reset_mask |= RADEON_RESET_RLC;
38618c2ecf20Sopenharmony_ci
38628c2ecf20Sopenharmony_ci	if (tmp & IH_BUSY)
38638c2ecf20Sopenharmony_ci		reset_mask |= RADEON_RESET_IH;
38648c2ecf20Sopenharmony_ci
38658c2ecf20Sopenharmony_ci	if (tmp & SEM_BUSY)
38668c2ecf20Sopenharmony_ci		reset_mask |= RADEON_RESET_SEM;
38678c2ecf20Sopenharmony_ci
38688c2ecf20Sopenharmony_ci	if (tmp & GRBM_RQ_PENDING)
38698c2ecf20Sopenharmony_ci		reset_mask |= RADEON_RESET_GRBM;
38708c2ecf20Sopenharmony_ci
38718c2ecf20Sopenharmony_ci	if (tmp & VMC_BUSY)
38728c2ecf20Sopenharmony_ci		reset_mask |= RADEON_RESET_VMC;
38738c2ecf20Sopenharmony_ci
38748c2ecf20Sopenharmony_ci	if (tmp & (MCB_BUSY | MCB_NON_DISPLAY_BUSY |
38758c2ecf20Sopenharmony_ci		   MCC_BUSY | MCD_BUSY))
38768c2ecf20Sopenharmony_ci		reset_mask |= RADEON_RESET_MC;
38778c2ecf20Sopenharmony_ci
38788c2ecf20Sopenharmony_ci	if (evergreen_is_display_hung(rdev))
38798c2ecf20Sopenharmony_ci		reset_mask |= RADEON_RESET_DISPLAY;
38808c2ecf20Sopenharmony_ci
38818c2ecf20Sopenharmony_ci	/* VM_L2_STATUS */
38828c2ecf20Sopenharmony_ci	tmp = RREG32(VM_L2_STATUS);
38838c2ecf20Sopenharmony_ci	if (tmp & L2_BUSY)
38848c2ecf20Sopenharmony_ci		reset_mask |= RADEON_RESET_VMC;
38858c2ecf20Sopenharmony_ci
38868c2ecf20Sopenharmony_ci	/* Skip MC reset as it's mostly likely not hung, just busy */
38878c2ecf20Sopenharmony_ci	if (reset_mask & RADEON_RESET_MC) {
38888c2ecf20Sopenharmony_ci		DRM_DEBUG("MC busy: 0x%08X, clearing.\n", reset_mask);
38898c2ecf20Sopenharmony_ci		reset_mask &= ~RADEON_RESET_MC;
38908c2ecf20Sopenharmony_ci	}
38918c2ecf20Sopenharmony_ci
38928c2ecf20Sopenharmony_ci	return reset_mask;
38938c2ecf20Sopenharmony_ci}
38948c2ecf20Sopenharmony_ci
38958c2ecf20Sopenharmony_cistatic void evergreen_gpu_soft_reset(struct radeon_device *rdev, u32 reset_mask)
38968c2ecf20Sopenharmony_ci{
38978c2ecf20Sopenharmony_ci	struct evergreen_mc_save save;
38988c2ecf20Sopenharmony_ci	u32 grbm_soft_reset = 0, srbm_soft_reset = 0;
38998c2ecf20Sopenharmony_ci	u32 tmp;
39008c2ecf20Sopenharmony_ci
39018c2ecf20Sopenharmony_ci	if (reset_mask == 0)
39028c2ecf20Sopenharmony_ci		return;
39038c2ecf20Sopenharmony_ci
39048c2ecf20Sopenharmony_ci	dev_info(rdev->dev, "GPU softreset: 0x%08X\n", reset_mask);
39058c2ecf20Sopenharmony_ci
39068c2ecf20Sopenharmony_ci	evergreen_print_gpu_status_regs(rdev);
39078c2ecf20Sopenharmony_ci
39088c2ecf20Sopenharmony_ci	/* Disable CP parsing/prefetching */
39098c2ecf20Sopenharmony_ci	WREG32(CP_ME_CNTL, CP_ME_HALT | CP_PFP_HALT);
39108c2ecf20Sopenharmony_ci
39118c2ecf20Sopenharmony_ci	if (reset_mask & RADEON_RESET_DMA) {
39128c2ecf20Sopenharmony_ci		/* Disable DMA */
39138c2ecf20Sopenharmony_ci		tmp = RREG32(DMA_RB_CNTL);
39148c2ecf20Sopenharmony_ci		tmp &= ~DMA_RB_ENABLE;
39158c2ecf20Sopenharmony_ci		WREG32(DMA_RB_CNTL, tmp);
39168c2ecf20Sopenharmony_ci	}
39178c2ecf20Sopenharmony_ci
39188c2ecf20Sopenharmony_ci	udelay(50);
39198c2ecf20Sopenharmony_ci
39208c2ecf20Sopenharmony_ci	evergreen_mc_stop(rdev, &save);
39218c2ecf20Sopenharmony_ci	if (evergreen_mc_wait_for_idle(rdev)) {
39228c2ecf20Sopenharmony_ci		dev_warn(rdev->dev, "Wait for MC idle timedout !\n");
39238c2ecf20Sopenharmony_ci	}
39248c2ecf20Sopenharmony_ci
39258c2ecf20Sopenharmony_ci	if (reset_mask & (RADEON_RESET_GFX | RADEON_RESET_COMPUTE)) {
39268c2ecf20Sopenharmony_ci		grbm_soft_reset |= SOFT_RESET_DB |
39278c2ecf20Sopenharmony_ci			SOFT_RESET_CB |
39288c2ecf20Sopenharmony_ci			SOFT_RESET_PA |
39298c2ecf20Sopenharmony_ci			SOFT_RESET_SC |
39308c2ecf20Sopenharmony_ci			SOFT_RESET_SPI |
39318c2ecf20Sopenharmony_ci			SOFT_RESET_SX |
39328c2ecf20Sopenharmony_ci			SOFT_RESET_SH |
39338c2ecf20Sopenharmony_ci			SOFT_RESET_TC |
39348c2ecf20Sopenharmony_ci			SOFT_RESET_TA |
39358c2ecf20Sopenharmony_ci			SOFT_RESET_VC |
39368c2ecf20Sopenharmony_ci			SOFT_RESET_VGT;
39378c2ecf20Sopenharmony_ci	}
39388c2ecf20Sopenharmony_ci
39398c2ecf20Sopenharmony_ci	if (reset_mask & RADEON_RESET_CP) {
39408c2ecf20Sopenharmony_ci		grbm_soft_reset |= SOFT_RESET_CP |
39418c2ecf20Sopenharmony_ci			SOFT_RESET_VGT;
39428c2ecf20Sopenharmony_ci
39438c2ecf20Sopenharmony_ci		srbm_soft_reset |= SOFT_RESET_GRBM;
39448c2ecf20Sopenharmony_ci	}
39458c2ecf20Sopenharmony_ci
39468c2ecf20Sopenharmony_ci	if (reset_mask & RADEON_RESET_DMA)
39478c2ecf20Sopenharmony_ci		srbm_soft_reset |= SOFT_RESET_DMA;
39488c2ecf20Sopenharmony_ci
39498c2ecf20Sopenharmony_ci	if (reset_mask & RADEON_RESET_DISPLAY)
39508c2ecf20Sopenharmony_ci		srbm_soft_reset |= SOFT_RESET_DC;
39518c2ecf20Sopenharmony_ci
39528c2ecf20Sopenharmony_ci	if (reset_mask & RADEON_RESET_RLC)
39538c2ecf20Sopenharmony_ci		srbm_soft_reset |= SOFT_RESET_RLC;
39548c2ecf20Sopenharmony_ci
39558c2ecf20Sopenharmony_ci	if (reset_mask & RADEON_RESET_SEM)
39568c2ecf20Sopenharmony_ci		srbm_soft_reset |= SOFT_RESET_SEM;
39578c2ecf20Sopenharmony_ci
39588c2ecf20Sopenharmony_ci	if (reset_mask & RADEON_RESET_IH)
39598c2ecf20Sopenharmony_ci		srbm_soft_reset |= SOFT_RESET_IH;
39608c2ecf20Sopenharmony_ci
39618c2ecf20Sopenharmony_ci	if (reset_mask & RADEON_RESET_GRBM)
39628c2ecf20Sopenharmony_ci		srbm_soft_reset |= SOFT_RESET_GRBM;
39638c2ecf20Sopenharmony_ci
39648c2ecf20Sopenharmony_ci	if (reset_mask & RADEON_RESET_VMC)
39658c2ecf20Sopenharmony_ci		srbm_soft_reset |= SOFT_RESET_VMC;
39668c2ecf20Sopenharmony_ci
39678c2ecf20Sopenharmony_ci	if (!(rdev->flags & RADEON_IS_IGP)) {
39688c2ecf20Sopenharmony_ci		if (reset_mask & RADEON_RESET_MC)
39698c2ecf20Sopenharmony_ci			srbm_soft_reset |= SOFT_RESET_MC;
39708c2ecf20Sopenharmony_ci	}
39718c2ecf20Sopenharmony_ci
39728c2ecf20Sopenharmony_ci	if (grbm_soft_reset) {
39738c2ecf20Sopenharmony_ci		tmp = RREG32(GRBM_SOFT_RESET);
39748c2ecf20Sopenharmony_ci		tmp |= grbm_soft_reset;
39758c2ecf20Sopenharmony_ci		dev_info(rdev->dev, "GRBM_SOFT_RESET=0x%08X\n", tmp);
39768c2ecf20Sopenharmony_ci		WREG32(GRBM_SOFT_RESET, tmp);
39778c2ecf20Sopenharmony_ci		tmp = RREG32(GRBM_SOFT_RESET);
39788c2ecf20Sopenharmony_ci
39798c2ecf20Sopenharmony_ci		udelay(50);
39808c2ecf20Sopenharmony_ci
39818c2ecf20Sopenharmony_ci		tmp &= ~grbm_soft_reset;
39828c2ecf20Sopenharmony_ci		WREG32(GRBM_SOFT_RESET, tmp);
39838c2ecf20Sopenharmony_ci		tmp = RREG32(GRBM_SOFT_RESET);
39848c2ecf20Sopenharmony_ci	}
39858c2ecf20Sopenharmony_ci
39868c2ecf20Sopenharmony_ci	if (srbm_soft_reset) {
39878c2ecf20Sopenharmony_ci		tmp = RREG32(SRBM_SOFT_RESET);
39888c2ecf20Sopenharmony_ci		tmp |= srbm_soft_reset;
39898c2ecf20Sopenharmony_ci		dev_info(rdev->dev, "SRBM_SOFT_RESET=0x%08X\n", tmp);
39908c2ecf20Sopenharmony_ci		WREG32(SRBM_SOFT_RESET, tmp);
39918c2ecf20Sopenharmony_ci		tmp = RREG32(SRBM_SOFT_RESET);
39928c2ecf20Sopenharmony_ci
39938c2ecf20Sopenharmony_ci		udelay(50);
39948c2ecf20Sopenharmony_ci
39958c2ecf20Sopenharmony_ci		tmp &= ~srbm_soft_reset;
39968c2ecf20Sopenharmony_ci		WREG32(SRBM_SOFT_RESET, tmp);
39978c2ecf20Sopenharmony_ci		tmp = RREG32(SRBM_SOFT_RESET);
39988c2ecf20Sopenharmony_ci	}
39998c2ecf20Sopenharmony_ci
40008c2ecf20Sopenharmony_ci	/* Wait a little for things to settle down */
40018c2ecf20Sopenharmony_ci	udelay(50);
40028c2ecf20Sopenharmony_ci
40038c2ecf20Sopenharmony_ci	evergreen_mc_resume(rdev, &save);
40048c2ecf20Sopenharmony_ci	udelay(50);
40058c2ecf20Sopenharmony_ci
40068c2ecf20Sopenharmony_ci	evergreen_print_gpu_status_regs(rdev);
40078c2ecf20Sopenharmony_ci}
40088c2ecf20Sopenharmony_ci
40098c2ecf20Sopenharmony_civoid evergreen_gpu_pci_config_reset(struct radeon_device *rdev)
40108c2ecf20Sopenharmony_ci{
40118c2ecf20Sopenharmony_ci	struct evergreen_mc_save save;
40128c2ecf20Sopenharmony_ci	u32 tmp, i;
40138c2ecf20Sopenharmony_ci
40148c2ecf20Sopenharmony_ci	dev_info(rdev->dev, "GPU pci config reset\n");
40158c2ecf20Sopenharmony_ci
40168c2ecf20Sopenharmony_ci	/* disable dpm? */
40178c2ecf20Sopenharmony_ci
40188c2ecf20Sopenharmony_ci	/* Disable CP parsing/prefetching */
40198c2ecf20Sopenharmony_ci	WREG32(CP_ME_CNTL, CP_ME_HALT | CP_PFP_HALT);
40208c2ecf20Sopenharmony_ci	udelay(50);
40218c2ecf20Sopenharmony_ci	/* Disable DMA */
40228c2ecf20Sopenharmony_ci	tmp = RREG32(DMA_RB_CNTL);
40238c2ecf20Sopenharmony_ci	tmp &= ~DMA_RB_ENABLE;
40248c2ecf20Sopenharmony_ci	WREG32(DMA_RB_CNTL, tmp);
40258c2ecf20Sopenharmony_ci	/* XXX other engines? */
40268c2ecf20Sopenharmony_ci
40278c2ecf20Sopenharmony_ci	/* halt the rlc */
40288c2ecf20Sopenharmony_ci	r600_rlc_stop(rdev);
40298c2ecf20Sopenharmony_ci
40308c2ecf20Sopenharmony_ci	udelay(50);
40318c2ecf20Sopenharmony_ci
40328c2ecf20Sopenharmony_ci	/* set mclk/sclk to bypass */
40338c2ecf20Sopenharmony_ci	rv770_set_clk_bypass_mode(rdev);
40348c2ecf20Sopenharmony_ci	/* disable BM */
40358c2ecf20Sopenharmony_ci	pci_clear_master(rdev->pdev);
40368c2ecf20Sopenharmony_ci	/* disable mem access */
40378c2ecf20Sopenharmony_ci	evergreen_mc_stop(rdev, &save);
40388c2ecf20Sopenharmony_ci	if (evergreen_mc_wait_for_idle(rdev)) {
40398c2ecf20Sopenharmony_ci		dev_warn(rdev->dev, "Wait for MC idle timed out !\n");
40408c2ecf20Sopenharmony_ci	}
40418c2ecf20Sopenharmony_ci	/* reset */
40428c2ecf20Sopenharmony_ci	radeon_pci_config_reset(rdev);
40438c2ecf20Sopenharmony_ci	/* wait for asic to come out of reset */
40448c2ecf20Sopenharmony_ci	for (i = 0; i < rdev->usec_timeout; i++) {
40458c2ecf20Sopenharmony_ci		if (RREG32(CONFIG_MEMSIZE) != 0xffffffff)
40468c2ecf20Sopenharmony_ci			break;
40478c2ecf20Sopenharmony_ci		udelay(1);
40488c2ecf20Sopenharmony_ci	}
40498c2ecf20Sopenharmony_ci}
40508c2ecf20Sopenharmony_ci
40518c2ecf20Sopenharmony_ciint evergreen_asic_reset(struct radeon_device *rdev, bool hard)
40528c2ecf20Sopenharmony_ci{
40538c2ecf20Sopenharmony_ci	u32 reset_mask;
40548c2ecf20Sopenharmony_ci
40558c2ecf20Sopenharmony_ci	if (hard) {
40568c2ecf20Sopenharmony_ci		evergreen_gpu_pci_config_reset(rdev);
40578c2ecf20Sopenharmony_ci		return 0;
40588c2ecf20Sopenharmony_ci	}
40598c2ecf20Sopenharmony_ci
40608c2ecf20Sopenharmony_ci	reset_mask = evergreen_gpu_check_soft_reset(rdev);
40618c2ecf20Sopenharmony_ci
40628c2ecf20Sopenharmony_ci	if (reset_mask)
40638c2ecf20Sopenharmony_ci		r600_set_bios_scratch_engine_hung(rdev, true);
40648c2ecf20Sopenharmony_ci
40658c2ecf20Sopenharmony_ci	/* try soft reset */
40668c2ecf20Sopenharmony_ci	evergreen_gpu_soft_reset(rdev, reset_mask);
40678c2ecf20Sopenharmony_ci
40688c2ecf20Sopenharmony_ci	reset_mask = evergreen_gpu_check_soft_reset(rdev);
40698c2ecf20Sopenharmony_ci
40708c2ecf20Sopenharmony_ci	/* try pci config reset */
40718c2ecf20Sopenharmony_ci	if (reset_mask && radeon_hard_reset)
40728c2ecf20Sopenharmony_ci		evergreen_gpu_pci_config_reset(rdev);
40738c2ecf20Sopenharmony_ci
40748c2ecf20Sopenharmony_ci	reset_mask = evergreen_gpu_check_soft_reset(rdev);
40758c2ecf20Sopenharmony_ci
40768c2ecf20Sopenharmony_ci	if (!reset_mask)
40778c2ecf20Sopenharmony_ci		r600_set_bios_scratch_engine_hung(rdev, false);
40788c2ecf20Sopenharmony_ci
40798c2ecf20Sopenharmony_ci	return 0;
40808c2ecf20Sopenharmony_ci}
40818c2ecf20Sopenharmony_ci
40828c2ecf20Sopenharmony_ci/**
40838c2ecf20Sopenharmony_ci * evergreen_gfx_is_lockup - Check if the GFX engine is locked up
40848c2ecf20Sopenharmony_ci *
40858c2ecf20Sopenharmony_ci * @rdev: radeon_device pointer
40868c2ecf20Sopenharmony_ci * @ring: radeon_ring structure holding ring information
40878c2ecf20Sopenharmony_ci *
40888c2ecf20Sopenharmony_ci * Check if the GFX engine is locked up.
40898c2ecf20Sopenharmony_ci * Returns true if the engine appears to be locked up, false if not.
40908c2ecf20Sopenharmony_ci */
40918c2ecf20Sopenharmony_cibool evergreen_gfx_is_lockup(struct radeon_device *rdev, struct radeon_ring *ring)
40928c2ecf20Sopenharmony_ci{
40938c2ecf20Sopenharmony_ci	u32 reset_mask = evergreen_gpu_check_soft_reset(rdev);
40948c2ecf20Sopenharmony_ci
40958c2ecf20Sopenharmony_ci	if (!(reset_mask & (RADEON_RESET_GFX |
40968c2ecf20Sopenharmony_ci			    RADEON_RESET_COMPUTE |
40978c2ecf20Sopenharmony_ci			    RADEON_RESET_CP))) {
40988c2ecf20Sopenharmony_ci		radeon_ring_lockup_update(rdev, ring);
40998c2ecf20Sopenharmony_ci		return false;
41008c2ecf20Sopenharmony_ci	}
41018c2ecf20Sopenharmony_ci	return radeon_ring_test_lockup(rdev, ring);
41028c2ecf20Sopenharmony_ci}
41038c2ecf20Sopenharmony_ci
41048c2ecf20Sopenharmony_ci/*
41058c2ecf20Sopenharmony_ci * RLC
41068c2ecf20Sopenharmony_ci */
41078c2ecf20Sopenharmony_ci#define RLC_SAVE_RESTORE_LIST_END_MARKER    0x00000000
41088c2ecf20Sopenharmony_ci#define RLC_CLEAR_STATE_END_MARKER          0x00000001
41098c2ecf20Sopenharmony_ci
41108c2ecf20Sopenharmony_civoid sumo_rlc_fini(struct radeon_device *rdev)
41118c2ecf20Sopenharmony_ci{
41128c2ecf20Sopenharmony_ci	int r;
41138c2ecf20Sopenharmony_ci
41148c2ecf20Sopenharmony_ci	/* save restore block */
41158c2ecf20Sopenharmony_ci	if (rdev->rlc.save_restore_obj) {
41168c2ecf20Sopenharmony_ci		r = radeon_bo_reserve(rdev->rlc.save_restore_obj, false);
41178c2ecf20Sopenharmony_ci		if (unlikely(r != 0))
41188c2ecf20Sopenharmony_ci			dev_warn(rdev->dev, "(%d) reserve RLC sr bo failed\n", r);
41198c2ecf20Sopenharmony_ci		radeon_bo_unpin(rdev->rlc.save_restore_obj);
41208c2ecf20Sopenharmony_ci		radeon_bo_unreserve(rdev->rlc.save_restore_obj);
41218c2ecf20Sopenharmony_ci
41228c2ecf20Sopenharmony_ci		radeon_bo_unref(&rdev->rlc.save_restore_obj);
41238c2ecf20Sopenharmony_ci		rdev->rlc.save_restore_obj = NULL;
41248c2ecf20Sopenharmony_ci	}
41258c2ecf20Sopenharmony_ci
41268c2ecf20Sopenharmony_ci	/* clear state block */
41278c2ecf20Sopenharmony_ci	if (rdev->rlc.clear_state_obj) {
41288c2ecf20Sopenharmony_ci		r = radeon_bo_reserve(rdev->rlc.clear_state_obj, false);
41298c2ecf20Sopenharmony_ci		if (unlikely(r != 0))
41308c2ecf20Sopenharmony_ci			dev_warn(rdev->dev, "(%d) reserve RLC c bo failed\n", r);
41318c2ecf20Sopenharmony_ci		radeon_bo_unpin(rdev->rlc.clear_state_obj);
41328c2ecf20Sopenharmony_ci		radeon_bo_unreserve(rdev->rlc.clear_state_obj);
41338c2ecf20Sopenharmony_ci
41348c2ecf20Sopenharmony_ci		radeon_bo_unref(&rdev->rlc.clear_state_obj);
41358c2ecf20Sopenharmony_ci		rdev->rlc.clear_state_obj = NULL;
41368c2ecf20Sopenharmony_ci	}
41378c2ecf20Sopenharmony_ci
41388c2ecf20Sopenharmony_ci	/* clear state block */
41398c2ecf20Sopenharmony_ci	if (rdev->rlc.cp_table_obj) {
41408c2ecf20Sopenharmony_ci		r = radeon_bo_reserve(rdev->rlc.cp_table_obj, false);
41418c2ecf20Sopenharmony_ci		if (unlikely(r != 0))
41428c2ecf20Sopenharmony_ci			dev_warn(rdev->dev, "(%d) reserve RLC cp table bo failed\n", r);
41438c2ecf20Sopenharmony_ci		radeon_bo_unpin(rdev->rlc.cp_table_obj);
41448c2ecf20Sopenharmony_ci		radeon_bo_unreserve(rdev->rlc.cp_table_obj);
41458c2ecf20Sopenharmony_ci
41468c2ecf20Sopenharmony_ci		radeon_bo_unref(&rdev->rlc.cp_table_obj);
41478c2ecf20Sopenharmony_ci		rdev->rlc.cp_table_obj = NULL;
41488c2ecf20Sopenharmony_ci	}
41498c2ecf20Sopenharmony_ci}
41508c2ecf20Sopenharmony_ci
41518c2ecf20Sopenharmony_ci#define CP_ME_TABLE_SIZE    96
41528c2ecf20Sopenharmony_ci
41538c2ecf20Sopenharmony_ciint sumo_rlc_init(struct radeon_device *rdev)
41548c2ecf20Sopenharmony_ci{
41558c2ecf20Sopenharmony_ci	const u32 *src_ptr;
41568c2ecf20Sopenharmony_ci	volatile u32 *dst_ptr;
41578c2ecf20Sopenharmony_ci	u32 dws, data, i, j, k, reg_num;
41588c2ecf20Sopenharmony_ci	u32 reg_list_num, reg_list_hdr_blk_index, reg_list_blk_index = 0;
41598c2ecf20Sopenharmony_ci	u64 reg_list_mc_addr;
41608c2ecf20Sopenharmony_ci	const struct cs_section_def *cs_data;
41618c2ecf20Sopenharmony_ci	int r;
41628c2ecf20Sopenharmony_ci
41638c2ecf20Sopenharmony_ci	src_ptr = rdev->rlc.reg_list;
41648c2ecf20Sopenharmony_ci	dws = rdev->rlc.reg_list_size;
41658c2ecf20Sopenharmony_ci	if (rdev->family >= CHIP_BONAIRE) {
41668c2ecf20Sopenharmony_ci		dws += (5 * 16) + 48 + 48 + 64;
41678c2ecf20Sopenharmony_ci	}
41688c2ecf20Sopenharmony_ci	cs_data = rdev->rlc.cs_data;
41698c2ecf20Sopenharmony_ci
41708c2ecf20Sopenharmony_ci	if (src_ptr) {
41718c2ecf20Sopenharmony_ci		/* save restore block */
41728c2ecf20Sopenharmony_ci		if (rdev->rlc.save_restore_obj == NULL) {
41738c2ecf20Sopenharmony_ci			r = radeon_bo_create(rdev, dws * 4, PAGE_SIZE, true,
41748c2ecf20Sopenharmony_ci					     RADEON_GEM_DOMAIN_VRAM, 0, NULL,
41758c2ecf20Sopenharmony_ci					     NULL, &rdev->rlc.save_restore_obj);
41768c2ecf20Sopenharmony_ci			if (r) {
41778c2ecf20Sopenharmony_ci				dev_warn(rdev->dev, "(%d) create RLC sr bo failed\n", r);
41788c2ecf20Sopenharmony_ci				return r;
41798c2ecf20Sopenharmony_ci			}
41808c2ecf20Sopenharmony_ci		}
41818c2ecf20Sopenharmony_ci
41828c2ecf20Sopenharmony_ci		r = radeon_bo_reserve(rdev->rlc.save_restore_obj, false);
41838c2ecf20Sopenharmony_ci		if (unlikely(r != 0)) {
41848c2ecf20Sopenharmony_ci			sumo_rlc_fini(rdev);
41858c2ecf20Sopenharmony_ci			return r;
41868c2ecf20Sopenharmony_ci		}
41878c2ecf20Sopenharmony_ci		r = radeon_bo_pin(rdev->rlc.save_restore_obj, RADEON_GEM_DOMAIN_VRAM,
41888c2ecf20Sopenharmony_ci				  &rdev->rlc.save_restore_gpu_addr);
41898c2ecf20Sopenharmony_ci		if (r) {
41908c2ecf20Sopenharmony_ci			radeon_bo_unreserve(rdev->rlc.save_restore_obj);
41918c2ecf20Sopenharmony_ci			dev_warn(rdev->dev, "(%d) pin RLC sr bo failed\n", r);
41928c2ecf20Sopenharmony_ci			sumo_rlc_fini(rdev);
41938c2ecf20Sopenharmony_ci			return r;
41948c2ecf20Sopenharmony_ci		}
41958c2ecf20Sopenharmony_ci
41968c2ecf20Sopenharmony_ci		r = radeon_bo_kmap(rdev->rlc.save_restore_obj, (void **)&rdev->rlc.sr_ptr);
41978c2ecf20Sopenharmony_ci		if (r) {
41988c2ecf20Sopenharmony_ci			dev_warn(rdev->dev, "(%d) map RLC sr bo failed\n", r);
41998c2ecf20Sopenharmony_ci			sumo_rlc_fini(rdev);
42008c2ecf20Sopenharmony_ci			return r;
42018c2ecf20Sopenharmony_ci		}
42028c2ecf20Sopenharmony_ci		/* write the sr buffer */
42038c2ecf20Sopenharmony_ci		dst_ptr = rdev->rlc.sr_ptr;
42048c2ecf20Sopenharmony_ci		if (rdev->family >= CHIP_TAHITI) {
42058c2ecf20Sopenharmony_ci			/* SI */
42068c2ecf20Sopenharmony_ci			for (i = 0; i < rdev->rlc.reg_list_size; i++)
42078c2ecf20Sopenharmony_ci				dst_ptr[i] = cpu_to_le32(src_ptr[i]);
42088c2ecf20Sopenharmony_ci		} else {
42098c2ecf20Sopenharmony_ci			/* ON/LN/TN */
42108c2ecf20Sopenharmony_ci			/* format:
42118c2ecf20Sopenharmony_ci			 * dw0: (reg2 << 16) | reg1
42128c2ecf20Sopenharmony_ci			 * dw1: reg1 save space
42138c2ecf20Sopenharmony_ci			 * dw2: reg2 save space
42148c2ecf20Sopenharmony_ci			 */
42158c2ecf20Sopenharmony_ci			for (i = 0; i < dws; i++) {
42168c2ecf20Sopenharmony_ci				data = src_ptr[i] >> 2;
42178c2ecf20Sopenharmony_ci				i++;
42188c2ecf20Sopenharmony_ci				if (i < dws)
42198c2ecf20Sopenharmony_ci					data |= (src_ptr[i] >> 2) << 16;
42208c2ecf20Sopenharmony_ci				j = (((i - 1) * 3) / 2);
42218c2ecf20Sopenharmony_ci				dst_ptr[j] = cpu_to_le32(data);
42228c2ecf20Sopenharmony_ci			}
42238c2ecf20Sopenharmony_ci			j = ((i * 3) / 2);
42248c2ecf20Sopenharmony_ci			dst_ptr[j] = cpu_to_le32(RLC_SAVE_RESTORE_LIST_END_MARKER);
42258c2ecf20Sopenharmony_ci		}
42268c2ecf20Sopenharmony_ci		radeon_bo_kunmap(rdev->rlc.save_restore_obj);
42278c2ecf20Sopenharmony_ci		radeon_bo_unreserve(rdev->rlc.save_restore_obj);
42288c2ecf20Sopenharmony_ci	}
42298c2ecf20Sopenharmony_ci
42308c2ecf20Sopenharmony_ci	if (cs_data) {
42318c2ecf20Sopenharmony_ci		/* clear state block */
42328c2ecf20Sopenharmony_ci		if (rdev->family >= CHIP_BONAIRE) {
42338c2ecf20Sopenharmony_ci			rdev->rlc.clear_state_size = dws = cik_get_csb_size(rdev);
42348c2ecf20Sopenharmony_ci		} else if (rdev->family >= CHIP_TAHITI) {
42358c2ecf20Sopenharmony_ci			rdev->rlc.clear_state_size = si_get_csb_size(rdev);
42368c2ecf20Sopenharmony_ci			dws = rdev->rlc.clear_state_size + (256 / 4);
42378c2ecf20Sopenharmony_ci		} else {
42388c2ecf20Sopenharmony_ci			reg_list_num = 0;
42398c2ecf20Sopenharmony_ci			dws = 0;
42408c2ecf20Sopenharmony_ci			for (i = 0; cs_data[i].section != NULL; i++) {
42418c2ecf20Sopenharmony_ci				for (j = 0; cs_data[i].section[j].extent != NULL; j++) {
42428c2ecf20Sopenharmony_ci					reg_list_num++;
42438c2ecf20Sopenharmony_ci					dws += cs_data[i].section[j].reg_count;
42448c2ecf20Sopenharmony_ci				}
42458c2ecf20Sopenharmony_ci			}
42468c2ecf20Sopenharmony_ci			reg_list_blk_index = (3 * reg_list_num + 2);
42478c2ecf20Sopenharmony_ci			dws += reg_list_blk_index;
42488c2ecf20Sopenharmony_ci			rdev->rlc.clear_state_size = dws;
42498c2ecf20Sopenharmony_ci		}
42508c2ecf20Sopenharmony_ci
42518c2ecf20Sopenharmony_ci		if (rdev->rlc.clear_state_obj == NULL) {
42528c2ecf20Sopenharmony_ci			r = radeon_bo_create(rdev, dws * 4, PAGE_SIZE, true,
42538c2ecf20Sopenharmony_ci					     RADEON_GEM_DOMAIN_VRAM, 0, NULL,
42548c2ecf20Sopenharmony_ci					     NULL, &rdev->rlc.clear_state_obj);
42558c2ecf20Sopenharmony_ci			if (r) {
42568c2ecf20Sopenharmony_ci				dev_warn(rdev->dev, "(%d) create RLC c bo failed\n", r);
42578c2ecf20Sopenharmony_ci				sumo_rlc_fini(rdev);
42588c2ecf20Sopenharmony_ci				return r;
42598c2ecf20Sopenharmony_ci			}
42608c2ecf20Sopenharmony_ci		}
42618c2ecf20Sopenharmony_ci		r = radeon_bo_reserve(rdev->rlc.clear_state_obj, false);
42628c2ecf20Sopenharmony_ci		if (unlikely(r != 0)) {
42638c2ecf20Sopenharmony_ci			sumo_rlc_fini(rdev);
42648c2ecf20Sopenharmony_ci			return r;
42658c2ecf20Sopenharmony_ci		}
42668c2ecf20Sopenharmony_ci		r = radeon_bo_pin(rdev->rlc.clear_state_obj, RADEON_GEM_DOMAIN_VRAM,
42678c2ecf20Sopenharmony_ci				  &rdev->rlc.clear_state_gpu_addr);
42688c2ecf20Sopenharmony_ci		if (r) {
42698c2ecf20Sopenharmony_ci			radeon_bo_unreserve(rdev->rlc.clear_state_obj);
42708c2ecf20Sopenharmony_ci			dev_warn(rdev->dev, "(%d) pin RLC c bo failed\n", r);
42718c2ecf20Sopenharmony_ci			sumo_rlc_fini(rdev);
42728c2ecf20Sopenharmony_ci			return r;
42738c2ecf20Sopenharmony_ci		}
42748c2ecf20Sopenharmony_ci
42758c2ecf20Sopenharmony_ci		r = radeon_bo_kmap(rdev->rlc.clear_state_obj, (void **)&rdev->rlc.cs_ptr);
42768c2ecf20Sopenharmony_ci		if (r) {
42778c2ecf20Sopenharmony_ci			dev_warn(rdev->dev, "(%d) map RLC c bo failed\n", r);
42788c2ecf20Sopenharmony_ci			sumo_rlc_fini(rdev);
42798c2ecf20Sopenharmony_ci			return r;
42808c2ecf20Sopenharmony_ci		}
42818c2ecf20Sopenharmony_ci		/* set up the cs buffer */
42828c2ecf20Sopenharmony_ci		dst_ptr = rdev->rlc.cs_ptr;
42838c2ecf20Sopenharmony_ci		if (rdev->family >= CHIP_BONAIRE) {
42848c2ecf20Sopenharmony_ci			cik_get_csb_buffer(rdev, dst_ptr);
42858c2ecf20Sopenharmony_ci		} else if (rdev->family >= CHIP_TAHITI) {
42868c2ecf20Sopenharmony_ci			reg_list_mc_addr = rdev->rlc.clear_state_gpu_addr + 256;
42878c2ecf20Sopenharmony_ci			dst_ptr[0] = cpu_to_le32(upper_32_bits(reg_list_mc_addr));
42888c2ecf20Sopenharmony_ci			dst_ptr[1] = cpu_to_le32(lower_32_bits(reg_list_mc_addr));
42898c2ecf20Sopenharmony_ci			dst_ptr[2] = cpu_to_le32(rdev->rlc.clear_state_size);
42908c2ecf20Sopenharmony_ci			si_get_csb_buffer(rdev, &dst_ptr[(256/4)]);
42918c2ecf20Sopenharmony_ci		} else {
42928c2ecf20Sopenharmony_ci			reg_list_hdr_blk_index = 0;
42938c2ecf20Sopenharmony_ci			reg_list_mc_addr = rdev->rlc.clear_state_gpu_addr + (reg_list_blk_index * 4);
42948c2ecf20Sopenharmony_ci			data = upper_32_bits(reg_list_mc_addr);
42958c2ecf20Sopenharmony_ci			dst_ptr[reg_list_hdr_blk_index] = cpu_to_le32(data);
42968c2ecf20Sopenharmony_ci			reg_list_hdr_blk_index++;
42978c2ecf20Sopenharmony_ci			for (i = 0; cs_data[i].section != NULL; i++) {
42988c2ecf20Sopenharmony_ci				for (j = 0; cs_data[i].section[j].extent != NULL; j++) {
42998c2ecf20Sopenharmony_ci					reg_num = cs_data[i].section[j].reg_count;
43008c2ecf20Sopenharmony_ci					data = reg_list_mc_addr & 0xffffffff;
43018c2ecf20Sopenharmony_ci					dst_ptr[reg_list_hdr_blk_index] = cpu_to_le32(data);
43028c2ecf20Sopenharmony_ci					reg_list_hdr_blk_index++;
43038c2ecf20Sopenharmony_ci
43048c2ecf20Sopenharmony_ci					data = (cs_data[i].section[j].reg_index * 4) & 0xffffffff;
43058c2ecf20Sopenharmony_ci					dst_ptr[reg_list_hdr_blk_index] = cpu_to_le32(data);
43068c2ecf20Sopenharmony_ci					reg_list_hdr_blk_index++;
43078c2ecf20Sopenharmony_ci
43088c2ecf20Sopenharmony_ci					data = 0x08000000 | (reg_num * 4);
43098c2ecf20Sopenharmony_ci					dst_ptr[reg_list_hdr_blk_index] = cpu_to_le32(data);
43108c2ecf20Sopenharmony_ci					reg_list_hdr_blk_index++;
43118c2ecf20Sopenharmony_ci
43128c2ecf20Sopenharmony_ci					for (k = 0; k < reg_num; k++) {
43138c2ecf20Sopenharmony_ci						data = cs_data[i].section[j].extent[k];
43148c2ecf20Sopenharmony_ci						dst_ptr[reg_list_blk_index + k] = cpu_to_le32(data);
43158c2ecf20Sopenharmony_ci					}
43168c2ecf20Sopenharmony_ci					reg_list_mc_addr += reg_num * 4;
43178c2ecf20Sopenharmony_ci					reg_list_blk_index += reg_num;
43188c2ecf20Sopenharmony_ci				}
43198c2ecf20Sopenharmony_ci			}
43208c2ecf20Sopenharmony_ci			dst_ptr[reg_list_hdr_blk_index] = cpu_to_le32(RLC_CLEAR_STATE_END_MARKER);
43218c2ecf20Sopenharmony_ci		}
43228c2ecf20Sopenharmony_ci		radeon_bo_kunmap(rdev->rlc.clear_state_obj);
43238c2ecf20Sopenharmony_ci		radeon_bo_unreserve(rdev->rlc.clear_state_obj);
43248c2ecf20Sopenharmony_ci	}
43258c2ecf20Sopenharmony_ci
43268c2ecf20Sopenharmony_ci	if (rdev->rlc.cp_table_size) {
43278c2ecf20Sopenharmony_ci		if (rdev->rlc.cp_table_obj == NULL) {
43288c2ecf20Sopenharmony_ci			r = radeon_bo_create(rdev, rdev->rlc.cp_table_size,
43298c2ecf20Sopenharmony_ci					     PAGE_SIZE, true,
43308c2ecf20Sopenharmony_ci					     RADEON_GEM_DOMAIN_VRAM, 0, NULL,
43318c2ecf20Sopenharmony_ci					     NULL, &rdev->rlc.cp_table_obj);
43328c2ecf20Sopenharmony_ci			if (r) {
43338c2ecf20Sopenharmony_ci				dev_warn(rdev->dev, "(%d) create RLC cp table bo failed\n", r);
43348c2ecf20Sopenharmony_ci				sumo_rlc_fini(rdev);
43358c2ecf20Sopenharmony_ci				return r;
43368c2ecf20Sopenharmony_ci			}
43378c2ecf20Sopenharmony_ci		}
43388c2ecf20Sopenharmony_ci
43398c2ecf20Sopenharmony_ci		r = radeon_bo_reserve(rdev->rlc.cp_table_obj, false);
43408c2ecf20Sopenharmony_ci		if (unlikely(r != 0)) {
43418c2ecf20Sopenharmony_ci			dev_warn(rdev->dev, "(%d) reserve RLC cp table bo failed\n", r);
43428c2ecf20Sopenharmony_ci			sumo_rlc_fini(rdev);
43438c2ecf20Sopenharmony_ci			return r;
43448c2ecf20Sopenharmony_ci		}
43458c2ecf20Sopenharmony_ci		r = radeon_bo_pin(rdev->rlc.cp_table_obj, RADEON_GEM_DOMAIN_VRAM,
43468c2ecf20Sopenharmony_ci				  &rdev->rlc.cp_table_gpu_addr);
43478c2ecf20Sopenharmony_ci		if (r) {
43488c2ecf20Sopenharmony_ci			radeon_bo_unreserve(rdev->rlc.cp_table_obj);
43498c2ecf20Sopenharmony_ci			dev_warn(rdev->dev, "(%d) pin RLC cp_table bo failed\n", r);
43508c2ecf20Sopenharmony_ci			sumo_rlc_fini(rdev);
43518c2ecf20Sopenharmony_ci			return r;
43528c2ecf20Sopenharmony_ci		}
43538c2ecf20Sopenharmony_ci		r = radeon_bo_kmap(rdev->rlc.cp_table_obj, (void **)&rdev->rlc.cp_table_ptr);
43548c2ecf20Sopenharmony_ci		if (r) {
43558c2ecf20Sopenharmony_ci			dev_warn(rdev->dev, "(%d) map RLC cp table bo failed\n", r);
43568c2ecf20Sopenharmony_ci			sumo_rlc_fini(rdev);
43578c2ecf20Sopenharmony_ci			return r;
43588c2ecf20Sopenharmony_ci		}
43598c2ecf20Sopenharmony_ci
43608c2ecf20Sopenharmony_ci		cik_init_cp_pg_table(rdev);
43618c2ecf20Sopenharmony_ci
43628c2ecf20Sopenharmony_ci		radeon_bo_kunmap(rdev->rlc.cp_table_obj);
43638c2ecf20Sopenharmony_ci		radeon_bo_unreserve(rdev->rlc.cp_table_obj);
43648c2ecf20Sopenharmony_ci
43658c2ecf20Sopenharmony_ci	}
43668c2ecf20Sopenharmony_ci
43678c2ecf20Sopenharmony_ci	return 0;
43688c2ecf20Sopenharmony_ci}
43698c2ecf20Sopenharmony_ci
43708c2ecf20Sopenharmony_cistatic void evergreen_rlc_start(struct radeon_device *rdev)
43718c2ecf20Sopenharmony_ci{
43728c2ecf20Sopenharmony_ci	u32 mask = RLC_ENABLE;
43738c2ecf20Sopenharmony_ci
43748c2ecf20Sopenharmony_ci	if (rdev->flags & RADEON_IS_IGP) {
43758c2ecf20Sopenharmony_ci		mask |= GFX_POWER_GATING_ENABLE | GFX_POWER_GATING_SRC;
43768c2ecf20Sopenharmony_ci	}
43778c2ecf20Sopenharmony_ci
43788c2ecf20Sopenharmony_ci	WREG32(RLC_CNTL, mask);
43798c2ecf20Sopenharmony_ci}
43808c2ecf20Sopenharmony_ci
43818c2ecf20Sopenharmony_ciint evergreen_rlc_resume(struct radeon_device *rdev)
43828c2ecf20Sopenharmony_ci{
43838c2ecf20Sopenharmony_ci	u32 i;
43848c2ecf20Sopenharmony_ci	const __be32 *fw_data;
43858c2ecf20Sopenharmony_ci
43868c2ecf20Sopenharmony_ci	if (!rdev->rlc_fw)
43878c2ecf20Sopenharmony_ci		return -EINVAL;
43888c2ecf20Sopenharmony_ci
43898c2ecf20Sopenharmony_ci	r600_rlc_stop(rdev);
43908c2ecf20Sopenharmony_ci
43918c2ecf20Sopenharmony_ci	WREG32(RLC_HB_CNTL, 0);
43928c2ecf20Sopenharmony_ci
43938c2ecf20Sopenharmony_ci	if (rdev->flags & RADEON_IS_IGP) {
43948c2ecf20Sopenharmony_ci		if (rdev->family == CHIP_ARUBA) {
43958c2ecf20Sopenharmony_ci			u32 always_on_bitmap =
43968c2ecf20Sopenharmony_ci				3 | (3 << (16 * rdev->config.cayman.max_shader_engines));
43978c2ecf20Sopenharmony_ci			/* find out the number of active simds */
43988c2ecf20Sopenharmony_ci			u32 tmp = (RREG32(CC_GC_SHADER_PIPE_CONFIG) & 0xffff0000) >> 16;
43998c2ecf20Sopenharmony_ci			tmp |= 0xffffffff << rdev->config.cayman.max_simds_per_se;
44008c2ecf20Sopenharmony_ci			tmp = hweight32(~tmp);
44018c2ecf20Sopenharmony_ci			if (tmp == rdev->config.cayman.max_simds_per_se) {
44028c2ecf20Sopenharmony_ci				WREG32(TN_RLC_LB_ALWAYS_ACTIVE_SIMD_MASK, always_on_bitmap);
44038c2ecf20Sopenharmony_ci				WREG32(TN_RLC_LB_PARAMS, 0x00601004);
44048c2ecf20Sopenharmony_ci				WREG32(TN_RLC_LB_INIT_SIMD_MASK, 0xffffffff);
44058c2ecf20Sopenharmony_ci				WREG32(TN_RLC_LB_CNTR_INIT, 0x00000000);
44068c2ecf20Sopenharmony_ci				WREG32(TN_RLC_LB_CNTR_MAX, 0x00002000);
44078c2ecf20Sopenharmony_ci			}
44088c2ecf20Sopenharmony_ci		} else {
44098c2ecf20Sopenharmony_ci			WREG32(RLC_HB_WPTR_LSB_ADDR, 0);
44108c2ecf20Sopenharmony_ci			WREG32(RLC_HB_WPTR_MSB_ADDR, 0);
44118c2ecf20Sopenharmony_ci		}
44128c2ecf20Sopenharmony_ci		WREG32(TN_RLC_SAVE_AND_RESTORE_BASE, rdev->rlc.save_restore_gpu_addr >> 8);
44138c2ecf20Sopenharmony_ci		WREG32(TN_RLC_CLEAR_STATE_RESTORE_BASE, rdev->rlc.clear_state_gpu_addr >> 8);
44148c2ecf20Sopenharmony_ci	} else {
44158c2ecf20Sopenharmony_ci		WREG32(RLC_HB_BASE, 0);
44168c2ecf20Sopenharmony_ci		WREG32(RLC_HB_RPTR, 0);
44178c2ecf20Sopenharmony_ci		WREG32(RLC_HB_WPTR, 0);
44188c2ecf20Sopenharmony_ci		WREG32(RLC_HB_WPTR_LSB_ADDR, 0);
44198c2ecf20Sopenharmony_ci		WREG32(RLC_HB_WPTR_MSB_ADDR, 0);
44208c2ecf20Sopenharmony_ci	}
44218c2ecf20Sopenharmony_ci	WREG32(RLC_MC_CNTL, 0);
44228c2ecf20Sopenharmony_ci	WREG32(RLC_UCODE_CNTL, 0);
44238c2ecf20Sopenharmony_ci
44248c2ecf20Sopenharmony_ci	fw_data = (const __be32 *)rdev->rlc_fw->data;
44258c2ecf20Sopenharmony_ci	if (rdev->family >= CHIP_ARUBA) {
44268c2ecf20Sopenharmony_ci		for (i = 0; i < ARUBA_RLC_UCODE_SIZE; i++) {
44278c2ecf20Sopenharmony_ci			WREG32(RLC_UCODE_ADDR, i);
44288c2ecf20Sopenharmony_ci			WREG32(RLC_UCODE_DATA, be32_to_cpup(fw_data++));
44298c2ecf20Sopenharmony_ci		}
44308c2ecf20Sopenharmony_ci	} else if (rdev->family >= CHIP_CAYMAN) {
44318c2ecf20Sopenharmony_ci		for (i = 0; i < CAYMAN_RLC_UCODE_SIZE; i++) {
44328c2ecf20Sopenharmony_ci			WREG32(RLC_UCODE_ADDR, i);
44338c2ecf20Sopenharmony_ci			WREG32(RLC_UCODE_DATA, be32_to_cpup(fw_data++));
44348c2ecf20Sopenharmony_ci		}
44358c2ecf20Sopenharmony_ci	} else {
44368c2ecf20Sopenharmony_ci		for (i = 0; i < EVERGREEN_RLC_UCODE_SIZE; i++) {
44378c2ecf20Sopenharmony_ci			WREG32(RLC_UCODE_ADDR, i);
44388c2ecf20Sopenharmony_ci			WREG32(RLC_UCODE_DATA, be32_to_cpup(fw_data++));
44398c2ecf20Sopenharmony_ci		}
44408c2ecf20Sopenharmony_ci	}
44418c2ecf20Sopenharmony_ci	WREG32(RLC_UCODE_ADDR, 0);
44428c2ecf20Sopenharmony_ci
44438c2ecf20Sopenharmony_ci	evergreen_rlc_start(rdev);
44448c2ecf20Sopenharmony_ci
44458c2ecf20Sopenharmony_ci	return 0;
44468c2ecf20Sopenharmony_ci}
44478c2ecf20Sopenharmony_ci
44488c2ecf20Sopenharmony_ci/* Interrupts */
44498c2ecf20Sopenharmony_ci
44508c2ecf20Sopenharmony_ciu32 evergreen_get_vblank_counter(struct radeon_device *rdev, int crtc)
44518c2ecf20Sopenharmony_ci{
44528c2ecf20Sopenharmony_ci	if (crtc >= rdev->num_crtc)
44538c2ecf20Sopenharmony_ci		return 0;
44548c2ecf20Sopenharmony_ci	else
44558c2ecf20Sopenharmony_ci		return RREG32(CRTC_STATUS_FRAME_COUNT + crtc_offsets[crtc]);
44568c2ecf20Sopenharmony_ci}
44578c2ecf20Sopenharmony_ci
44588c2ecf20Sopenharmony_civoid evergreen_disable_interrupt_state(struct radeon_device *rdev)
44598c2ecf20Sopenharmony_ci{
44608c2ecf20Sopenharmony_ci	int i;
44618c2ecf20Sopenharmony_ci	u32 tmp;
44628c2ecf20Sopenharmony_ci
44638c2ecf20Sopenharmony_ci	if (rdev->family >= CHIP_CAYMAN) {
44648c2ecf20Sopenharmony_ci		cayman_cp_int_cntl_setup(rdev, 0,
44658c2ecf20Sopenharmony_ci					 CNTX_BUSY_INT_ENABLE | CNTX_EMPTY_INT_ENABLE);
44668c2ecf20Sopenharmony_ci		cayman_cp_int_cntl_setup(rdev, 1, 0);
44678c2ecf20Sopenharmony_ci		cayman_cp_int_cntl_setup(rdev, 2, 0);
44688c2ecf20Sopenharmony_ci		tmp = RREG32(CAYMAN_DMA1_CNTL) & ~TRAP_ENABLE;
44698c2ecf20Sopenharmony_ci		WREG32(CAYMAN_DMA1_CNTL, tmp);
44708c2ecf20Sopenharmony_ci	} else
44718c2ecf20Sopenharmony_ci		WREG32(CP_INT_CNTL, CNTX_BUSY_INT_ENABLE | CNTX_EMPTY_INT_ENABLE);
44728c2ecf20Sopenharmony_ci	tmp = RREG32(DMA_CNTL) & ~TRAP_ENABLE;
44738c2ecf20Sopenharmony_ci	WREG32(DMA_CNTL, tmp);
44748c2ecf20Sopenharmony_ci	WREG32(GRBM_INT_CNTL, 0);
44758c2ecf20Sopenharmony_ci	WREG32(SRBM_INT_CNTL, 0);
44768c2ecf20Sopenharmony_ci	for (i = 0; i < rdev->num_crtc; i++)
44778c2ecf20Sopenharmony_ci		WREG32(INT_MASK + crtc_offsets[i], 0);
44788c2ecf20Sopenharmony_ci	for (i = 0; i < rdev->num_crtc; i++)
44798c2ecf20Sopenharmony_ci		WREG32(GRPH_INT_CONTROL + crtc_offsets[i], 0);
44808c2ecf20Sopenharmony_ci
44818c2ecf20Sopenharmony_ci	/* only one DAC on DCE5 */
44828c2ecf20Sopenharmony_ci	if (!ASIC_IS_DCE5(rdev))
44838c2ecf20Sopenharmony_ci		WREG32(DACA_AUTODETECT_INT_CONTROL, 0);
44848c2ecf20Sopenharmony_ci	WREG32(DACB_AUTODETECT_INT_CONTROL, 0);
44858c2ecf20Sopenharmony_ci
44868c2ecf20Sopenharmony_ci	for (i = 0; i < 6; i++)
44878c2ecf20Sopenharmony_ci		WREG32_AND(DC_HPDx_INT_CONTROL(i), DC_HPDx_INT_POLARITY);
44888c2ecf20Sopenharmony_ci}
44898c2ecf20Sopenharmony_ci
44908c2ecf20Sopenharmony_ci/* Note that the order we write back regs here is important */
44918c2ecf20Sopenharmony_ciint evergreen_irq_set(struct radeon_device *rdev)
44928c2ecf20Sopenharmony_ci{
44938c2ecf20Sopenharmony_ci	int i;
44948c2ecf20Sopenharmony_ci	u32 cp_int_cntl = CNTX_BUSY_INT_ENABLE | CNTX_EMPTY_INT_ENABLE;
44958c2ecf20Sopenharmony_ci	u32 cp_int_cntl1 = 0, cp_int_cntl2 = 0;
44968c2ecf20Sopenharmony_ci	u32 grbm_int_cntl = 0;
44978c2ecf20Sopenharmony_ci	u32 dma_cntl, dma_cntl1 = 0;
44988c2ecf20Sopenharmony_ci	u32 thermal_int = 0;
44998c2ecf20Sopenharmony_ci
45008c2ecf20Sopenharmony_ci	if (!rdev->irq.installed) {
45018c2ecf20Sopenharmony_ci		WARN(1, "Can't enable IRQ/MSI because no handler is installed\n");
45028c2ecf20Sopenharmony_ci		return -EINVAL;
45038c2ecf20Sopenharmony_ci	}
45048c2ecf20Sopenharmony_ci	/* don't enable anything if the ih is disabled */
45058c2ecf20Sopenharmony_ci	if (!rdev->ih.enabled) {
45068c2ecf20Sopenharmony_ci		r600_disable_interrupts(rdev);
45078c2ecf20Sopenharmony_ci		/* force the active interrupt state to all disabled */
45088c2ecf20Sopenharmony_ci		evergreen_disable_interrupt_state(rdev);
45098c2ecf20Sopenharmony_ci		return 0;
45108c2ecf20Sopenharmony_ci	}
45118c2ecf20Sopenharmony_ci
45128c2ecf20Sopenharmony_ci	if (rdev->family == CHIP_ARUBA)
45138c2ecf20Sopenharmony_ci		thermal_int = RREG32(TN_CG_THERMAL_INT_CTRL) &
45148c2ecf20Sopenharmony_ci			~(THERM_INT_MASK_HIGH | THERM_INT_MASK_LOW);
45158c2ecf20Sopenharmony_ci	else
45168c2ecf20Sopenharmony_ci		thermal_int = RREG32(CG_THERMAL_INT) &
45178c2ecf20Sopenharmony_ci			~(THERM_INT_MASK_HIGH | THERM_INT_MASK_LOW);
45188c2ecf20Sopenharmony_ci
45198c2ecf20Sopenharmony_ci	dma_cntl = RREG32(DMA_CNTL) & ~TRAP_ENABLE;
45208c2ecf20Sopenharmony_ci
45218c2ecf20Sopenharmony_ci	if (rdev->family >= CHIP_CAYMAN) {
45228c2ecf20Sopenharmony_ci		/* enable CP interrupts on all rings */
45238c2ecf20Sopenharmony_ci		if (atomic_read(&rdev->irq.ring_int[RADEON_RING_TYPE_GFX_INDEX])) {
45248c2ecf20Sopenharmony_ci			DRM_DEBUG("evergreen_irq_set: sw int gfx\n");
45258c2ecf20Sopenharmony_ci			cp_int_cntl |= TIME_STAMP_INT_ENABLE;
45268c2ecf20Sopenharmony_ci		}
45278c2ecf20Sopenharmony_ci		if (atomic_read(&rdev->irq.ring_int[CAYMAN_RING_TYPE_CP1_INDEX])) {
45288c2ecf20Sopenharmony_ci			DRM_DEBUG("evergreen_irq_set: sw int cp1\n");
45298c2ecf20Sopenharmony_ci			cp_int_cntl1 |= TIME_STAMP_INT_ENABLE;
45308c2ecf20Sopenharmony_ci		}
45318c2ecf20Sopenharmony_ci		if (atomic_read(&rdev->irq.ring_int[CAYMAN_RING_TYPE_CP2_INDEX])) {
45328c2ecf20Sopenharmony_ci			DRM_DEBUG("evergreen_irq_set: sw int cp2\n");
45338c2ecf20Sopenharmony_ci			cp_int_cntl2 |= TIME_STAMP_INT_ENABLE;
45348c2ecf20Sopenharmony_ci		}
45358c2ecf20Sopenharmony_ci	} else {
45368c2ecf20Sopenharmony_ci		if (atomic_read(&rdev->irq.ring_int[RADEON_RING_TYPE_GFX_INDEX])) {
45378c2ecf20Sopenharmony_ci			DRM_DEBUG("evergreen_irq_set: sw int gfx\n");
45388c2ecf20Sopenharmony_ci			cp_int_cntl |= RB_INT_ENABLE;
45398c2ecf20Sopenharmony_ci			cp_int_cntl |= TIME_STAMP_INT_ENABLE;
45408c2ecf20Sopenharmony_ci		}
45418c2ecf20Sopenharmony_ci	}
45428c2ecf20Sopenharmony_ci
45438c2ecf20Sopenharmony_ci	if (atomic_read(&rdev->irq.ring_int[R600_RING_TYPE_DMA_INDEX])) {
45448c2ecf20Sopenharmony_ci		DRM_DEBUG("r600_irq_set: sw int dma\n");
45458c2ecf20Sopenharmony_ci		dma_cntl |= TRAP_ENABLE;
45468c2ecf20Sopenharmony_ci	}
45478c2ecf20Sopenharmony_ci
45488c2ecf20Sopenharmony_ci	if (rdev->family >= CHIP_CAYMAN) {
45498c2ecf20Sopenharmony_ci		dma_cntl1 = RREG32(CAYMAN_DMA1_CNTL) & ~TRAP_ENABLE;
45508c2ecf20Sopenharmony_ci		if (atomic_read(&rdev->irq.ring_int[CAYMAN_RING_TYPE_DMA1_INDEX])) {
45518c2ecf20Sopenharmony_ci			DRM_DEBUG("r600_irq_set: sw int dma1\n");
45528c2ecf20Sopenharmony_ci			dma_cntl1 |= TRAP_ENABLE;
45538c2ecf20Sopenharmony_ci		}
45548c2ecf20Sopenharmony_ci	}
45558c2ecf20Sopenharmony_ci
45568c2ecf20Sopenharmony_ci	if (rdev->irq.dpm_thermal) {
45578c2ecf20Sopenharmony_ci		DRM_DEBUG("dpm thermal\n");
45588c2ecf20Sopenharmony_ci		thermal_int |= THERM_INT_MASK_HIGH | THERM_INT_MASK_LOW;
45598c2ecf20Sopenharmony_ci	}
45608c2ecf20Sopenharmony_ci
45618c2ecf20Sopenharmony_ci	if (rdev->family >= CHIP_CAYMAN) {
45628c2ecf20Sopenharmony_ci		cayman_cp_int_cntl_setup(rdev, 0, cp_int_cntl);
45638c2ecf20Sopenharmony_ci		cayman_cp_int_cntl_setup(rdev, 1, cp_int_cntl1);
45648c2ecf20Sopenharmony_ci		cayman_cp_int_cntl_setup(rdev, 2, cp_int_cntl2);
45658c2ecf20Sopenharmony_ci	} else
45668c2ecf20Sopenharmony_ci		WREG32(CP_INT_CNTL, cp_int_cntl);
45678c2ecf20Sopenharmony_ci
45688c2ecf20Sopenharmony_ci	WREG32(DMA_CNTL, dma_cntl);
45698c2ecf20Sopenharmony_ci
45708c2ecf20Sopenharmony_ci	if (rdev->family >= CHIP_CAYMAN)
45718c2ecf20Sopenharmony_ci		WREG32(CAYMAN_DMA1_CNTL, dma_cntl1);
45728c2ecf20Sopenharmony_ci
45738c2ecf20Sopenharmony_ci	WREG32(GRBM_INT_CNTL, grbm_int_cntl);
45748c2ecf20Sopenharmony_ci
45758c2ecf20Sopenharmony_ci	for (i = 0; i < rdev->num_crtc; i++) {
45768c2ecf20Sopenharmony_ci		radeon_irq_kms_set_irq_n_enabled(
45778c2ecf20Sopenharmony_ci		    rdev, INT_MASK + crtc_offsets[i],
45788c2ecf20Sopenharmony_ci		    VBLANK_INT_MASK,
45798c2ecf20Sopenharmony_ci		    rdev->irq.crtc_vblank_int[i] ||
45808c2ecf20Sopenharmony_ci		    atomic_read(&rdev->irq.pflip[i]), "vblank", i);
45818c2ecf20Sopenharmony_ci	}
45828c2ecf20Sopenharmony_ci
45838c2ecf20Sopenharmony_ci	for (i = 0; i < rdev->num_crtc; i++)
45848c2ecf20Sopenharmony_ci		WREG32(GRPH_INT_CONTROL + crtc_offsets[i], GRPH_PFLIP_INT_MASK);
45858c2ecf20Sopenharmony_ci
45868c2ecf20Sopenharmony_ci	for (i = 0; i < 6; i++) {
45878c2ecf20Sopenharmony_ci		radeon_irq_kms_set_irq_n_enabled(
45888c2ecf20Sopenharmony_ci		    rdev, DC_HPDx_INT_CONTROL(i),
45898c2ecf20Sopenharmony_ci		    DC_HPDx_INT_EN | DC_HPDx_RX_INT_EN,
45908c2ecf20Sopenharmony_ci		    rdev->irq.hpd[i], "HPD", i);
45918c2ecf20Sopenharmony_ci	}
45928c2ecf20Sopenharmony_ci
45938c2ecf20Sopenharmony_ci	if (rdev->family == CHIP_ARUBA)
45948c2ecf20Sopenharmony_ci		WREG32(TN_CG_THERMAL_INT_CTRL, thermal_int);
45958c2ecf20Sopenharmony_ci	else
45968c2ecf20Sopenharmony_ci		WREG32(CG_THERMAL_INT, thermal_int);
45978c2ecf20Sopenharmony_ci
45988c2ecf20Sopenharmony_ci	for (i = 0; i < 6; i++) {
45998c2ecf20Sopenharmony_ci		radeon_irq_kms_set_irq_n_enabled(
46008c2ecf20Sopenharmony_ci		    rdev, AFMT_AUDIO_PACKET_CONTROL + crtc_offsets[i],
46018c2ecf20Sopenharmony_ci		    AFMT_AZ_FORMAT_WTRIG_MASK,
46028c2ecf20Sopenharmony_ci		    rdev->irq.afmt[i], "HDMI", i);
46038c2ecf20Sopenharmony_ci	}
46048c2ecf20Sopenharmony_ci
46058c2ecf20Sopenharmony_ci	/* posting read */
46068c2ecf20Sopenharmony_ci	RREG32(SRBM_STATUS);
46078c2ecf20Sopenharmony_ci
46088c2ecf20Sopenharmony_ci	return 0;
46098c2ecf20Sopenharmony_ci}
46108c2ecf20Sopenharmony_ci
46118c2ecf20Sopenharmony_ci/* Note that the order we write back regs here is important */
46128c2ecf20Sopenharmony_cistatic void evergreen_irq_ack(struct radeon_device *rdev)
46138c2ecf20Sopenharmony_ci{
46148c2ecf20Sopenharmony_ci	int i, j;
46158c2ecf20Sopenharmony_ci	u32 *grph_int = rdev->irq.stat_regs.evergreen.grph_int;
46168c2ecf20Sopenharmony_ci	u32 *disp_int = rdev->irq.stat_regs.evergreen.disp_int;
46178c2ecf20Sopenharmony_ci	u32 *afmt_status = rdev->irq.stat_regs.evergreen.afmt_status;
46188c2ecf20Sopenharmony_ci
46198c2ecf20Sopenharmony_ci	for (i = 0; i < 6; i++) {
46208c2ecf20Sopenharmony_ci		disp_int[i] = RREG32(evergreen_disp_int_status[i]);
46218c2ecf20Sopenharmony_ci		afmt_status[i] = RREG32(AFMT_STATUS + crtc_offsets[i]);
46228c2ecf20Sopenharmony_ci		if (i < rdev->num_crtc)
46238c2ecf20Sopenharmony_ci			grph_int[i] = RREG32(GRPH_INT_STATUS + crtc_offsets[i]);
46248c2ecf20Sopenharmony_ci	}
46258c2ecf20Sopenharmony_ci
46268c2ecf20Sopenharmony_ci	/* We write back each interrupt register in pairs of two */
46278c2ecf20Sopenharmony_ci	for (i = 0; i < rdev->num_crtc; i += 2) {
46288c2ecf20Sopenharmony_ci		for (j = i; j < (i + 2); j++) {
46298c2ecf20Sopenharmony_ci			if (grph_int[j] & GRPH_PFLIP_INT_OCCURRED)
46308c2ecf20Sopenharmony_ci				WREG32(GRPH_INT_STATUS + crtc_offsets[j],
46318c2ecf20Sopenharmony_ci				       GRPH_PFLIP_INT_CLEAR);
46328c2ecf20Sopenharmony_ci		}
46338c2ecf20Sopenharmony_ci
46348c2ecf20Sopenharmony_ci		for (j = i; j < (i + 2); j++) {
46358c2ecf20Sopenharmony_ci			if (disp_int[j] & LB_D1_VBLANK_INTERRUPT)
46368c2ecf20Sopenharmony_ci				WREG32(VBLANK_STATUS + crtc_offsets[j],
46378c2ecf20Sopenharmony_ci				       VBLANK_ACK);
46388c2ecf20Sopenharmony_ci			if (disp_int[j] & LB_D1_VLINE_INTERRUPT)
46398c2ecf20Sopenharmony_ci				WREG32(VLINE_STATUS + crtc_offsets[j],
46408c2ecf20Sopenharmony_ci				       VLINE_ACK);
46418c2ecf20Sopenharmony_ci		}
46428c2ecf20Sopenharmony_ci	}
46438c2ecf20Sopenharmony_ci
46448c2ecf20Sopenharmony_ci	for (i = 0; i < 6; i++) {
46458c2ecf20Sopenharmony_ci		if (disp_int[i] & DC_HPD1_INTERRUPT)
46468c2ecf20Sopenharmony_ci			WREG32_OR(DC_HPDx_INT_CONTROL(i), DC_HPDx_INT_ACK);
46478c2ecf20Sopenharmony_ci	}
46488c2ecf20Sopenharmony_ci
46498c2ecf20Sopenharmony_ci	for (i = 0; i < 6; i++) {
46508c2ecf20Sopenharmony_ci		if (disp_int[i] & DC_HPD1_RX_INTERRUPT)
46518c2ecf20Sopenharmony_ci			WREG32_OR(DC_HPDx_INT_CONTROL(i), DC_HPDx_RX_INT_ACK);
46528c2ecf20Sopenharmony_ci	}
46538c2ecf20Sopenharmony_ci
46548c2ecf20Sopenharmony_ci	for (i = 0; i < 6; i++) {
46558c2ecf20Sopenharmony_ci		if (afmt_status[i] & AFMT_AZ_FORMAT_WTRIG)
46568c2ecf20Sopenharmony_ci			WREG32_OR(AFMT_AUDIO_PACKET_CONTROL + crtc_offsets[i],
46578c2ecf20Sopenharmony_ci				  AFMT_AZ_FORMAT_WTRIG_ACK);
46588c2ecf20Sopenharmony_ci	}
46598c2ecf20Sopenharmony_ci}
46608c2ecf20Sopenharmony_ci
46618c2ecf20Sopenharmony_cistatic void evergreen_irq_disable(struct radeon_device *rdev)
46628c2ecf20Sopenharmony_ci{
46638c2ecf20Sopenharmony_ci	r600_disable_interrupts(rdev);
46648c2ecf20Sopenharmony_ci	/* Wait and acknowledge irq */
46658c2ecf20Sopenharmony_ci	mdelay(1);
46668c2ecf20Sopenharmony_ci	evergreen_irq_ack(rdev);
46678c2ecf20Sopenharmony_ci	evergreen_disable_interrupt_state(rdev);
46688c2ecf20Sopenharmony_ci}
46698c2ecf20Sopenharmony_ci
46708c2ecf20Sopenharmony_civoid evergreen_irq_suspend(struct radeon_device *rdev)
46718c2ecf20Sopenharmony_ci{
46728c2ecf20Sopenharmony_ci	evergreen_irq_disable(rdev);
46738c2ecf20Sopenharmony_ci	r600_rlc_stop(rdev);
46748c2ecf20Sopenharmony_ci}
46758c2ecf20Sopenharmony_ci
46768c2ecf20Sopenharmony_cistatic u32 evergreen_get_ih_wptr(struct radeon_device *rdev)
46778c2ecf20Sopenharmony_ci{
46788c2ecf20Sopenharmony_ci	u32 wptr, tmp;
46798c2ecf20Sopenharmony_ci
46808c2ecf20Sopenharmony_ci	if (rdev->wb.enabled)
46818c2ecf20Sopenharmony_ci		wptr = le32_to_cpu(rdev->wb.wb[R600_WB_IH_WPTR_OFFSET/4]);
46828c2ecf20Sopenharmony_ci	else
46838c2ecf20Sopenharmony_ci		wptr = RREG32(IH_RB_WPTR);
46848c2ecf20Sopenharmony_ci
46858c2ecf20Sopenharmony_ci	if (wptr & RB_OVERFLOW) {
46868c2ecf20Sopenharmony_ci		wptr &= ~RB_OVERFLOW;
46878c2ecf20Sopenharmony_ci		/* When a ring buffer overflow happen start parsing interrupt
46888c2ecf20Sopenharmony_ci		 * from the last not overwritten vector (wptr + 16). Hopefully
46898c2ecf20Sopenharmony_ci		 * this should allow us to catchup.
46908c2ecf20Sopenharmony_ci		 */
46918c2ecf20Sopenharmony_ci		dev_warn(rdev->dev, "IH ring buffer overflow (0x%08X, 0x%08X, 0x%08X)\n",
46928c2ecf20Sopenharmony_ci			 wptr, rdev->ih.rptr, (wptr + 16) & rdev->ih.ptr_mask);
46938c2ecf20Sopenharmony_ci		rdev->ih.rptr = (wptr + 16) & rdev->ih.ptr_mask;
46948c2ecf20Sopenharmony_ci		tmp = RREG32(IH_RB_CNTL);
46958c2ecf20Sopenharmony_ci		tmp |= IH_WPTR_OVERFLOW_CLEAR;
46968c2ecf20Sopenharmony_ci		WREG32(IH_RB_CNTL, tmp);
46978c2ecf20Sopenharmony_ci	}
46988c2ecf20Sopenharmony_ci	return (wptr & rdev->ih.ptr_mask);
46998c2ecf20Sopenharmony_ci}
47008c2ecf20Sopenharmony_ci
47018c2ecf20Sopenharmony_ciint evergreen_irq_process(struct radeon_device *rdev)
47028c2ecf20Sopenharmony_ci{
47038c2ecf20Sopenharmony_ci	u32 *disp_int = rdev->irq.stat_regs.evergreen.disp_int;
47048c2ecf20Sopenharmony_ci	u32 *afmt_status = rdev->irq.stat_regs.evergreen.afmt_status;
47058c2ecf20Sopenharmony_ci	u32 crtc_idx, hpd_idx, afmt_idx;
47068c2ecf20Sopenharmony_ci	u32 mask;
47078c2ecf20Sopenharmony_ci	u32 wptr;
47088c2ecf20Sopenharmony_ci	u32 rptr;
47098c2ecf20Sopenharmony_ci	u32 src_id, src_data;
47108c2ecf20Sopenharmony_ci	u32 ring_index;
47118c2ecf20Sopenharmony_ci	bool queue_hotplug = false;
47128c2ecf20Sopenharmony_ci	bool queue_hdmi = false;
47138c2ecf20Sopenharmony_ci	bool queue_dp = false;
47148c2ecf20Sopenharmony_ci	bool queue_thermal = false;
47158c2ecf20Sopenharmony_ci	u32 status, addr;
47168c2ecf20Sopenharmony_ci	const char *event_name;
47178c2ecf20Sopenharmony_ci
47188c2ecf20Sopenharmony_ci	if (!rdev->ih.enabled || rdev->shutdown)
47198c2ecf20Sopenharmony_ci		return IRQ_NONE;
47208c2ecf20Sopenharmony_ci
47218c2ecf20Sopenharmony_ci	wptr = evergreen_get_ih_wptr(rdev);
47228c2ecf20Sopenharmony_ci
47238c2ecf20Sopenharmony_cirestart_ih:
47248c2ecf20Sopenharmony_ci	/* is somebody else already processing irqs? */
47258c2ecf20Sopenharmony_ci	if (atomic_xchg(&rdev->ih.lock, 1))
47268c2ecf20Sopenharmony_ci		return IRQ_NONE;
47278c2ecf20Sopenharmony_ci
47288c2ecf20Sopenharmony_ci	rptr = rdev->ih.rptr;
47298c2ecf20Sopenharmony_ci	DRM_DEBUG("evergreen_irq_process start: rptr %d, wptr %d\n", rptr, wptr);
47308c2ecf20Sopenharmony_ci
47318c2ecf20Sopenharmony_ci	/* Order reading of wptr vs. reading of IH ring data */
47328c2ecf20Sopenharmony_ci	rmb();
47338c2ecf20Sopenharmony_ci
47348c2ecf20Sopenharmony_ci	/* display interrupts */
47358c2ecf20Sopenharmony_ci	evergreen_irq_ack(rdev);
47368c2ecf20Sopenharmony_ci
47378c2ecf20Sopenharmony_ci	while (rptr != wptr) {
47388c2ecf20Sopenharmony_ci		/* wptr/rptr are in bytes! */
47398c2ecf20Sopenharmony_ci		ring_index = rptr / 4;
47408c2ecf20Sopenharmony_ci		src_id =  le32_to_cpu(rdev->ih.ring[ring_index]) & 0xff;
47418c2ecf20Sopenharmony_ci		src_data = le32_to_cpu(rdev->ih.ring[ring_index + 1]) & 0xfffffff;
47428c2ecf20Sopenharmony_ci
47438c2ecf20Sopenharmony_ci		switch (src_id) {
47448c2ecf20Sopenharmony_ci		case 1: /* D1 vblank/vline */
47458c2ecf20Sopenharmony_ci		case 2: /* D2 vblank/vline */
47468c2ecf20Sopenharmony_ci		case 3: /* D3 vblank/vline */
47478c2ecf20Sopenharmony_ci		case 4: /* D4 vblank/vline */
47488c2ecf20Sopenharmony_ci		case 5: /* D5 vblank/vline */
47498c2ecf20Sopenharmony_ci		case 6: /* D6 vblank/vline */
47508c2ecf20Sopenharmony_ci			crtc_idx = src_id - 1;
47518c2ecf20Sopenharmony_ci
47528c2ecf20Sopenharmony_ci			if (src_data == 0) { /* vblank */
47538c2ecf20Sopenharmony_ci				mask = LB_D1_VBLANK_INTERRUPT;
47548c2ecf20Sopenharmony_ci				event_name = "vblank";
47558c2ecf20Sopenharmony_ci
47568c2ecf20Sopenharmony_ci				if (rdev->irq.crtc_vblank_int[crtc_idx]) {
47578c2ecf20Sopenharmony_ci					drm_handle_vblank(rdev->ddev, crtc_idx);
47588c2ecf20Sopenharmony_ci					rdev->pm.vblank_sync = true;
47598c2ecf20Sopenharmony_ci					wake_up(&rdev->irq.vblank_queue);
47608c2ecf20Sopenharmony_ci				}
47618c2ecf20Sopenharmony_ci				if (atomic_read(&rdev->irq.pflip[crtc_idx])) {
47628c2ecf20Sopenharmony_ci					radeon_crtc_handle_vblank(rdev,
47638c2ecf20Sopenharmony_ci								  crtc_idx);
47648c2ecf20Sopenharmony_ci				}
47658c2ecf20Sopenharmony_ci
47668c2ecf20Sopenharmony_ci			} else if (src_data == 1) { /* vline */
47678c2ecf20Sopenharmony_ci				mask = LB_D1_VLINE_INTERRUPT;
47688c2ecf20Sopenharmony_ci				event_name = "vline";
47698c2ecf20Sopenharmony_ci			} else {
47708c2ecf20Sopenharmony_ci				DRM_DEBUG("Unhandled interrupt: %d %d\n",
47718c2ecf20Sopenharmony_ci					  src_id, src_data);
47728c2ecf20Sopenharmony_ci				break;
47738c2ecf20Sopenharmony_ci			}
47748c2ecf20Sopenharmony_ci
47758c2ecf20Sopenharmony_ci			if (!(disp_int[crtc_idx] & mask)) {
47768c2ecf20Sopenharmony_ci				DRM_DEBUG("IH: D%d %s - IH event w/o asserted irq bit?\n",
47778c2ecf20Sopenharmony_ci					  crtc_idx + 1, event_name);
47788c2ecf20Sopenharmony_ci			}
47798c2ecf20Sopenharmony_ci
47808c2ecf20Sopenharmony_ci			disp_int[crtc_idx] &= ~mask;
47818c2ecf20Sopenharmony_ci			DRM_DEBUG("IH: D%d %s\n", crtc_idx + 1, event_name);
47828c2ecf20Sopenharmony_ci
47838c2ecf20Sopenharmony_ci			break;
47848c2ecf20Sopenharmony_ci		case 8: /* D1 page flip */
47858c2ecf20Sopenharmony_ci		case 10: /* D2 page flip */
47868c2ecf20Sopenharmony_ci		case 12: /* D3 page flip */
47878c2ecf20Sopenharmony_ci		case 14: /* D4 page flip */
47888c2ecf20Sopenharmony_ci		case 16: /* D5 page flip */
47898c2ecf20Sopenharmony_ci		case 18: /* D6 page flip */
47908c2ecf20Sopenharmony_ci			DRM_DEBUG("IH: D%d flip\n", ((src_id - 8) >> 1) + 1);
47918c2ecf20Sopenharmony_ci			if (radeon_use_pflipirq > 0)
47928c2ecf20Sopenharmony_ci				radeon_crtc_handle_flip(rdev, (src_id - 8) >> 1);
47938c2ecf20Sopenharmony_ci			break;
47948c2ecf20Sopenharmony_ci		case 42: /* HPD hotplug */
47958c2ecf20Sopenharmony_ci			if (src_data <= 5) {
47968c2ecf20Sopenharmony_ci				hpd_idx = src_data;
47978c2ecf20Sopenharmony_ci				mask = DC_HPD1_INTERRUPT;
47988c2ecf20Sopenharmony_ci				queue_hotplug = true;
47998c2ecf20Sopenharmony_ci				event_name = "HPD";
48008c2ecf20Sopenharmony_ci
48018c2ecf20Sopenharmony_ci			} else if (src_data <= 11) {
48028c2ecf20Sopenharmony_ci				hpd_idx = src_data - 6;
48038c2ecf20Sopenharmony_ci				mask = DC_HPD1_RX_INTERRUPT;
48048c2ecf20Sopenharmony_ci				queue_dp = true;
48058c2ecf20Sopenharmony_ci				event_name = "HPD_RX";
48068c2ecf20Sopenharmony_ci
48078c2ecf20Sopenharmony_ci			} else {
48088c2ecf20Sopenharmony_ci				DRM_DEBUG("Unhandled interrupt: %d %d\n",
48098c2ecf20Sopenharmony_ci					  src_id, src_data);
48108c2ecf20Sopenharmony_ci				break;
48118c2ecf20Sopenharmony_ci			}
48128c2ecf20Sopenharmony_ci
48138c2ecf20Sopenharmony_ci			if (!(disp_int[hpd_idx] & mask))
48148c2ecf20Sopenharmony_ci				DRM_DEBUG("IH: IH event w/o asserted irq bit?\n");
48158c2ecf20Sopenharmony_ci
48168c2ecf20Sopenharmony_ci			disp_int[hpd_idx] &= ~mask;
48178c2ecf20Sopenharmony_ci			DRM_DEBUG("IH: %s%d\n", event_name, hpd_idx + 1);
48188c2ecf20Sopenharmony_ci
48198c2ecf20Sopenharmony_ci			break;
48208c2ecf20Sopenharmony_ci		case 44: /* hdmi */
48218c2ecf20Sopenharmony_ci			afmt_idx = src_data;
48228c2ecf20Sopenharmony_ci			if (afmt_idx > 5) {
48238c2ecf20Sopenharmony_ci				DRM_ERROR("Unhandled interrupt: %d %d\n",
48248c2ecf20Sopenharmony_ci					  src_id, src_data);
48258c2ecf20Sopenharmony_ci				break;
48268c2ecf20Sopenharmony_ci			}
48278c2ecf20Sopenharmony_ci
48288c2ecf20Sopenharmony_ci			if (!(afmt_status[afmt_idx] & AFMT_AZ_FORMAT_WTRIG))
48298c2ecf20Sopenharmony_ci				DRM_DEBUG("IH: IH event w/o asserted irq bit?\n");
48308c2ecf20Sopenharmony_ci
48318c2ecf20Sopenharmony_ci			afmt_status[afmt_idx] &= ~AFMT_AZ_FORMAT_WTRIG;
48328c2ecf20Sopenharmony_ci			queue_hdmi = true;
48338c2ecf20Sopenharmony_ci			DRM_DEBUG("IH: HDMI%d\n", afmt_idx + 1);
48348c2ecf20Sopenharmony_ci			break;
48358c2ecf20Sopenharmony_ci		case 96:
48368c2ecf20Sopenharmony_ci			DRM_ERROR("SRBM_READ_ERROR: 0x%x\n", RREG32(SRBM_READ_ERROR));
48378c2ecf20Sopenharmony_ci			WREG32(SRBM_INT_ACK, 0x1);
48388c2ecf20Sopenharmony_ci			break;
48398c2ecf20Sopenharmony_ci		case 124: /* UVD */
48408c2ecf20Sopenharmony_ci			DRM_DEBUG("IH: UVD int: 0x%08x\n", src_data);
48418c2ecf20Sopenharmony_ci			radeon_fence_process(rdev, R600_RING_TYPE_UVD_INDEX);
48428c2ecf20Sopenharmony_ci			break;
48438c2ecf20Sopenharmony_ci		case 146:
48448c2ecf20Sopenharmony_ci		case 147:
48458c2ecf20Sopenharmony_ci			addr = RREG32(VM_CONTEXT1_PROTECTION_FAULT_ADDR);
48468c2ecf20Sopenharmony_ci			status = RREG32(VM_CONTEXT1_PROTECTION_FAULT_STATUS);
48478c2ecf20Sopenharmony_ci			/* reset addr and status */
48488c2ecf20Sopenharmony_ci			WREG32_P(VM_CONTEXT1_CNTL2, 1, ~1);
48498c2ecf20Sopenharmony_ci			if (addr == 0x0 && status == 0x0)
48508c2ecf20Sopenharmony_ci				break;
48518c2ecf20Sopenharmony_ci			dev_err(rdev->dev, "GPU fault detected: %d 0x%08x\n", src_id, src_data);
48528c2ecf20Sopenharmony_ci			dev_err(rdev->dev, "  VM_CONTEXT1_PROTECTION_FAULT_ADDR   0x%08X\n",
48538c2ecf20Sopenharmony_ci				addr);
48548c2ecf20Sopenharmony_ci			dev_err(rdev->dev, "  VM_CONTEXT1_PROTECTION_FAULT_STATUS 0x%08X\n",
48558c2ecf20Sopenharmony_ci				status);
48568c2ecf20Sopenharmony_ci			cayman_vm_decode_fault(rdev, status, addr);
48578c2ecf20Sopenharmony_ci			break;
48588c2ecf20Sopenharmony_ci		case 176: /* CP_INT in ring buffer */
48598c2ecf20Sopenharmony_ci		case 177: /* CP_INT in IB1 */
48608c2ecf20Sopenharmony_ci		case 178: /* CP_INT in IB2 */
48618c2ecf20Sopenharmony_ci			DRM_DEBUG("IH: CP int: 0x%08x\n", src_data);
48628c2ecf20Sopenharmony_ci			radeon_fence_process(rdev, RADEON_RING_TYPE_GFX_INDEX);
48638c2ecf20Sopenharmony_ci			break;
48648c2ecf20Sopenharmony_ci		case 181: /* CP EOP event */
48658c2ecf20Sopenharmony_ci			DRM_DEBUG("IH: CP EOP\n");
48668c2ecf20Sopenharmony_ci			if (rdev->family >= CHIP_CAYMAN) {
48678c2ecf20Sopenharmony_ci				switch (src_data) {
48688c2ecf20Sopenharmony_ci				case 0:
48698c2ecf20Sopenharmony_ci					radeon_fence_process(rdev, RADEON_RING_TYPE_GFX_INDEX);
48708c2ecf20Sopenharmony_ci					break;
48718c2ecf20Sopenharmony_ci				case 1:
48728c2ecf20Sopenharmony_ci					radeon_fence_process(rdev, CAYMAN_RING_TYPE_CP1_INDEX);
48738c2ecf20Sopenharmony_ci					break;
48748c2ecf20Sopenharmony_ci				case 2:
48758c2ecf20Sopenharmony_ci					radeon_fence_process(rdev, CAYMAN_RING_TYPE_CP2_INDEX);
48768c2ecf20Sopenharmony_ci					break;
48778c2ecf20Sopenharmony_ci				}
48788c2ecf20Sopenharmony_ci			} else
48798c2ecf20Sopenharmony_ci				radeon_fence_process(rdev, RADEON_RING_TYPE_GFX_INDEX);
48808c2ecf20Sopenharmony_ci			break;
48818c2ecf20Sopenharmony_ci		case 224: /* DMA trap event */
48828c2ecf20Sopenharmony_ci			DRM_DEBUG("IH: DMA trap\n");
48838c2ecf20Sopenharmony_ci			radeon_fence_process(rdev, R600_RING_TYPE_DMA_INDEX);
48848c2ecf20Sopenharmony_ci			break;
48858c2ecf20Sopenharmony_ci		case 230: /* thermal low to high */
48868c2ecf20Sopenharmony_ci			DRM_DEBUG("IH: thermal low to high\n");
48878c2ecf20Sopenharmony_ci			rdev->pm.dpm.thermal.high_to_low = false;
48888c2ecf20Sopenharmony_ci			queue_thermal = true;
48898c2ecf20Sopenharmony_ci			break;
48908c2ecf20Sopenharmony_ci		case 231: /* thermal high to low */
48918c2ecf20Sopenharmony_ci			DRM_DEBUG("IH: thermal high to low\n");
48928c2ecf20Sopenharmony_ci			rdev->pm.dpm.thermal.high_to_low = true;
48938c2ecf20Sopenharmony_ci			queue_thermal = true;
48948c2ecf20Sopenharmony_ci			break;
48958c2ecf20Sopenharmony_ci		case 233: /* GUI IDLE */
48968c2ecf20Sopenharmony_ci			DRM_DEBUG("IH: GUI idle\n");
48978c2ecf20Sopenharmony_ci			break;
48988c2ecf20Sopenharmony_ci		case 244: /* DMA trap event */
48998c2ecf20Sopenharmony_ci			if (rdev->family >= CHIP_CAYMAN) {
49008c2ecf20Sopenharmony_ci				DRM_DEBUG("IH: DMA1 trap\n");
49018c2ecf20Sopenharmony_ci				radeon_fence_process(rdev, CAYMAN_RING_TYPE_DMA1_INDEX);
49028c2ecf20Sopenharmony_ci			}
49038c2ecf20Sopenharmony_ci			break;
49048c2ecf20Sopenharmony_ci		default:
49058c2ecf20Sopenharmony_ci			DRM_DEBUG("Unhandled interrupt: %d %d\n", src_id, src_data);
49068c2ecf20Sopenharmony_ci			break;
49078c2ecf20Sopenharmony_ci		}
49088c2ecf20Sopenharmony_ci
49098c2ecf20Sopenharmony_ci		/* wptr/rptr are in bytes! */
49108c2ecf20Sopenharmony_ci		rptr += 16;
49118c2ecf20Sopenharmony_ci		rptr &= rdev->ih.ptr_mask;
49128c2ecf20Sopenharmony_ci		WREG32(IH_RB_RPTR, rptr);
49138c2ecf20Sopenharmony_ci	}
49148c2ecf20Sopenharmony_ci	if (queue_dp)
49158c2ecf20Sopenharmony_ci		schedule_work(&rdev->dp_work);
49168c2ecf20Sopenharmony_ci	if (queue_hotplug)
49178c2ecf20Sopenharmony_ci		schedule_delayed_work(&rdev->hotplug_work, 0);
49188c2ecf20Sopenharmony_ci	if (queue_hdmi)
49198c2ecf20Sopenharmony_ci		schedule_work(&rdev->audio_work);
49208c2ecf20Sopenharmony_ci	if (queue_thermal && rdev->pm.dpm_enabled)
49218c2ecf20Sopenharmony_ci		schedule_work(&rdev->pm.dpm.thermal.work);
49228c2ecf20Sopenharmony_ci	rdev->ih.rptr = rptr;
49238c2ecf20Sopenharmony_ci	WREG32(IH_RB_RPTR, rptr);
49248c2ecf20Sopenharmony_ci	atomic_set(&rdev->ih.lock, 0);
49258c2ecf20Sopenharmony_ci
49268c2ecf20Sopenharmony_ci	/* make sure wptr hasn't changed while processing */
49278c2ecf20Sopenharmony_ci	wptr = evergreen_get_ih_wptr(rdev);
49288c2ecf20Sopenharmony_ci	if (wptr != rptr)
49298c2ecf20Sopenharmony_ci		goto restart_ih;
49308c2ecf20Sopenharmony_ci
49318c2ecf20Sopenharmony_ci	return IRQ_HANDLED;
49328c2ecf20Sopenharmony_ci}
49338c2ecf20Sopenharmony_ci
49348c2ecf20Sopenharmony_cistatic void evergreen_uvd_init(struct radeon_device *rdev)
49358c2ecf20Sopenharmony_ci{
49368c2ecf20Sopenharmony_ci	int r;
49378c2ecf20Sopenharmony_ci
49388c2ecf20Sopenharmony_ci	if (!rdev->has_uvd)
49398c2ecf20Sopenharmony_ci		return;
49408c2ecf20Sopenharmony_ci
49418c2ecf20Sopenharmony_ci	r = radeon_uvd_init(rdev);
49428c2ecf20Sopenharmony_ci	if (r) {
49438c2ecf20Sopenharmony_ci		dev_err(rdev->dev, "failed UVD (%d) init.\n", r);
49448c2ecf20Sopenharmony_ci		/*
49458c2ecf20Sopenharmony_ci		 * At this point rdev->uvd.vcpu_bo is NULL which trickles down
49468c2ecf20Sopenharmony_ci		 * to early fails uvd_v2_2_resume() and thus nothing happens
49478c2ecf20Sopenharmony_ci		 * there. So it is pointless to try to go through that code
49488c2ecf20Sopenharmony_ci		 * hence why we disable uvd here.
49498c2ecf20Sopenharmony_ci		 */
49508c2ecf20Sopenharmony_ci		rdev->has_uvd = false;
49518c2ecf20Sopenharmony_ci		return;
49528c2ecf20Sopenharmony_ci	}
49538c2ecf20Sopenharmony_ci	rdev->ring[R600_RING_TYPE_UVD_INDEX].ring_obj = NULL;
49548c2ecf20Sopenharmony_ci	r600_ring_init(rdev, &rdev->ring[R600_RING_TYPE_UVD_INDEX], 4096);
49558c2ecf20Sopenharmony_ci}
49568c2ecf20Sopenharmony_ci
49578c2ecf20Sopenharmony_cistatic void evergreen_uvd_start(struct radeon_device *rdev)
49588c2ecf20Sopenharmony_ci{
49598c2ecf20Sopenharmony_ci	int r;
49608c2ecf20Sopenharmony_ci
49618c2ecf20Sopenharmony_ci	if (!rdev->has_uvd)
49628c2ecf20Sopenharmony_ci		return;
49638c2ecf20Sopenharmony_ci
49648c2ecf20Sopenharmony_ci	r = uvd_v2_2_resume(rdev);
49658c2ecf20Sopenharmony_ci	if (r) {
49668c2ecf20Sopenharmony_ci		dev_err(rdev->dev, "failed UVD resume (%d).\n", r);
49678c2ecf20Sopenharmony_ci		goto error;
49688c2ecf20Sopenharmony_ci	}
49698c2ecf20Sopenharmony_ci	r = radeon_fence_driver_start_ring(rdev, R600_RING_TYPE_UVD_INDEX);
49708c2ecf20Sopenharmony_ci	if (r) {
49718c2ecf20Sopenharmony_ci		dev_err(rdev->dev, "failed initializing UVD fences (%d).\n", r);
49728c2ecf20Sopenharmony_ci		goto error;
49738c2ecf20Sopenharmony_ci	}
49748c2ecf20Sopenharmony_ci	return;
49758c2ecf20Sopenharmony_ci
49768c2ecf20Sopenharmony_cierror:
49778c2ecf20Sopenharmony_ci	rdev->ring[R600_RING_TYPE_UVD_INDEX].ring_size = 0;
49788c2ecf20Sopenharmony_ci}
49798c2ecf20Sopenharmony_ci
49808c2ecf20Sopenharmony_cistatic void evergreen_uvd_resume(struct radeon_device *rdev)
49818c2ecf20Sopenharmony_ci{
49828c2ecf20Sopenharmony_ci	struct radeon_ring *ring;
49838c2ecf20Sopenharmony_ci	int r;
49848c2ecf20Sopenharmony_ci
49858c2ecf20Sopenharmony_ci	if (!rdev->has_uvd || !rdev->ring[R600_RING_TYPE_UVD_INDEX].ring_size)
49868c2ecf20Sopenharmony_ci		return;
49878c2ecf20Sopenharmony_ci
49888c2ecf20Sopenharmony_ci	ring = &rdev->ring[R600_RING_TYPE_UVD_INDEX];
49898c2ecf20Sopenharmony_ci	r = radeon_ring_init(rdev, ring, ring->ring_size, 0, PACKET0(UVD_NO_OP, 0));
49908c2ecf20Sopenharmony_ci	if (r) {
49918c2ecf20Sopenharmony_ci		dev_err(rdev->dev, "failed initializing UVD ring (%d).\n", r);
49928c2ecf20Sopenharmony_ci		return;
49938c2ecf20Sopenharmony_ci	}
49948c2ecf20Sopenharmony_ci	r = uvd_v1_0_init(rdev);
49958c2ecf20Sopenharmony_ci	if (r) {
49968c2ecf20Sopenharmony_ci		dev_err(rdev->dev, "failed initializing UVD (%d).\n", r);
49978c2ecf20Sopenharmony_ci		return;
49988c2ecf20Sopenharmony_ci	}
49998c2ecf20Sopenharmony_ci}
50008c2ecf20Sopenharmony_ci
50018c2ecf20Sopenharmony_cistatic int evergreen_startup(struct radeon_device *rdev)
50028c2ecf20Sopenharmony_ci{
50038c2ecf20Sopenharmony_ci	struct radeon_ring *ring;
50048c2ecf20Sopenharmony_ci	int r;
50058c2ecf20Sopenharmony_ci
50068c2ecf20Sopenharmony_ci	/* enable pcie gen2 link */
50078c2ecf20Sopenharmony_ci	evergreen_pcie_gen2_enable(rdev);
50088c2ecf20Sopenharmony_ci	/* enable aspm */
50098c2ecf20Sopenharmony_ci	evergreen_program_aspm(rdev);
50108c2ecf20Sopenharmony_ci
50118c2ecf20Sopenharmony_ci	/* scratch needs to be initialized before MC */
50128c2ecf20Sopenharmony_ci	r = r600_vram_scratch_init(rdev);
50138c2ecf20Sopenharmony_ci	if (r)
50148c2ecf20Sopenharmony_ci		return r;
50158c2ecf20Sopenharmony_ci
50168c2ecf20Sopenharmony_ci	evergreen_mc_program(rdev);
50178c2ecf20Sopenharmony_ci
50188c2ecf20Sopenharmony_ci	if (ASIC_IS_DCE5(rdev) && !rdev->pm.dpm_enabled) {
50198c2ecf20Sopenharmony_ci		r = ni_mc_load_microcode(rdev);
50208c2ecf20Sopenharmony_ci		if (r) {
50218c2ecf20Sopenharmony_ci			DRM_ERROR("Failed to load MC firmware!\n");
50228c2ecf20Sopenharmony_ci			return r;
50238c2ecf20Sopenharmony_ci		}
50248c2ecf20Sopenharmony_ci	}
50258c2ecf20Sopenharmony_ci
50268c2ecf20Sopenharmony_ci	if (rdev->flags & RADEON_IS_AGP) {
50278c2ecf20Sopenharmony_ci		evergreen_agp_enable(rdev);
50288c2ecf20Sopenharmony_ci	} else {
50298c2ecf20Sopenharmony_ci		r = evergreen_pcie_gart_enable(rdev);
50308c2ecf20Sopenharmony_ci		if (r)
50318c2ecf20Sopenharmony_ci			return r;
50328c2ecf20Sopenharmony_ci	}
50338c2ecf20Sopenharmony_ci	evergreen_gpu_init(rdev);
50348c2ecf20Sopenharmony_ci
50358c2ecf20Sopenharmony_ci	/* allocate rlc buffers */
50368c2ecf20Sopenharmony_ci	if (rdev->flags & RADEON_IS_IGP) {
50378c2ecf20Sopenharmony_ci		rdev->rlc.reg_list = sumo_rlc_save_restore_register_list;
50388c2ecf20Sopenharmony_ci		rdev->rlc.reg_list_size =
50398c2ecf20Sopenharmony_ci			(u32)ARRAY_SIZE(sumo_rlc_save_restore_register_list);
50408c2ecf20Sopenharmony_ci		rdev->rlc.cs_data = evergreen_cs_data;
50418c2ecf20Sopenharmony_ci		r = sumo_rlc_init(rdev);
50428c2ecf20Sopenharmony_ci		if (r) {
50438c2ecf20Sopenharmony_ci			DRM_ERROR("Failed to init rlc BOs!\n");
50448c2ecf20Sopenharmony_ci			return r;
50458c2ecf20Sopenharmony_ci		}
50468c2ecf20Sopenharmony_ci	}
50478c2ecf20Sopenharmony_ci
50488c2ecf20Sopenharmony_ci	/* allocate wb buffer */
50498c2ecf20Sopenharmony_ci	r = radeon_wb_init(rdev);
50508c2ecf20Sopenharmony_ci	if (r)
50518c2ecf20Sopenharmony_ci		return r;
50528c2ecf20Sopenharmony_ci
50538c2ecf20Sopenharmony_ci	r = radeon_fence_driver_start_ring(rdev, RADEON_RING_TYPE_GFX_INDEX);
50548c2ecf20Sopenharmony_ci	if (r) {
50558c2ecf20Sopenharmony_ci		dev_err(rdev->dev, "failed initializing CP fences (%d).\n", r);
50568c2ecf20Sopenharmony_ci		return r;
50578c2ecf20Sopenharmony_ci	}
50588c2ecf20Sopenharmony_ci
50598c2ecf20Sopenharmony_ci	r = radeon_fence_driver_start_ring(rdev, R600_RING_TYPE_DMA_INDEX);
50608c2ecf20Sopenharmony_ci	if (r) {
50618c2ecf20Sopenharmony_ci		dev_err(rdev->dev, "failed initializing DMA fences (%d).\n", r);
50628c2ecf20Sopenharmony_ci		return r;
50638c2ecf20Sopenharmony_ci	}
50648c2ecf20Sopenharmony_ci
50658c2ecf20Sopenharmony_ci	evergreen_uvd_start(rdev);
50668c2ecf20Sopenharmony_ci
50678c2ecf20Sopenharmony_ci	/* Enable IRQ */
50688c2ecf20Sopenharmony_ci	if (!rdev->irq.installed) {
50698c2ecf20Sopenharmony_ci		r = radeon_irq_kms_init(rdev);
50708c2ecf20Sopenharmony_ci		if (r)
50718c2ecf20Sopenharmony_ci			return r;
50728c2ecf20Sopenharmony_ci	}
50738c2ecf20Sopenharmony_ci
50748c2ecf20Sopenharmony_ci	r = r600_irq_init(rdev);
50758c2ecf20Sopenharmony_ci	if (r) {
50768c2ecf20Sopenharmony_ci		DRM_ERROR("radeon: IH init failed (%d).\n", r);
50778c2ecf20Sopenharmony_ci		radeon_irq_kms_fini(rdev);
50788c2ecf20Sopenharmony_ci		return r;
50798c2ecf20Sopenharmony_ci	}
50808c2ecf20Sopenharmony_ci	evergreen_irq_set(rdev);
50818c2ecf20Sopenharmony_ci
50828c2ecf20Sopenharmony_ci	ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX];
50838c2ecf20Sopenharmony_ci	r = radeon_ring_init(rdev, ring, ring->ring_size, RADEON_WB_CP_RPTR_OFFSET,
50848c2ecf20Sopenharmony_ci			     RADEON_CP_PACKET2);
50858c2ecf20Sopenharmony_ci	if (r)
50868c2ecf20Sopenharmony_ci		return r;
50878c2ecf20Sopenharmony_ci
50888c2ecf20Sopenharmony_ci	ring = &rdev->ring[R600_RING_TYPE_DMA_INDEX];
50898c2ecf20Sopenharmony_ci	r = radeon_ring_init(rdev, ring, ring->ring_size, R600_WB_DMA_RPTR_OFFSET,
50908c2ecf20Sopenharmony_ci			     DMA_PACKET(DMA_PACKET_NOP, 0, 0));
50918c2ecf20Sopenharmony_ci	if (r)
50928c2ecf20Sopenharmony_ci		return r;
50938c2ecf20Sopenharmony_ci
50948c2ecf20Sopenharmony_ci	r = evergreen_cp_load_microcode(rdev);
50958c2ecf20Sopenharmony_ci	if (r)
50968c2ecf20Sopenharmony_ci		return r;
50978c2ecf20Sopenharmony_ci	r = evergreen_cp_resume(rdev);
50988c2ecf20Sopenharmony_ci	if (r)
50998c2ecf20Sopenharmony_ci		return r;
51008c2ecf20Sopenharmony_ci	r = r600_dma_resume(rdev);
51018c2ecf20Sopenharmony_ci	if (r)
51028c2ecf20Sopenharmony_ci		return r;
51038c2ecf20Sopenharmony_ci
51048c2ecf20Sopenharmony_ci	evergreen_uvd_resume(rdev);
51058c2ecf20Sopenharmony_ci
51068c2ecf20Sopenharmony_ci	r = radeon_ib_pool_init(rdev);
51078c2ecf20Sopenharmony_ci	if (r) {
51088c2ecf20Sopenharmony_ci		dev_err(rdev->dev, "IB initialization failed (%d).\n", r);
51098c2ecf20Sopenharmony_ci		return r;
51108c2ecf20Sopenharmony_ci	}
51118c2ecf20Sopenharmony_ci
51128c2ecf20Sopenharmony_ci	r = radeon_audio_init(rdev);
51138c2ecf20Sopenharmony_ci	if (r) {
51148c2ecf20Sopenharmony_ci		DRM_ERROR("radeon: audio init failed\n");
51158c2ecf20Sopenharmony_ci		return r;
51168c2ecf20Sopenharmony_ci	}
51178c2ecf20Sopenharmony_ci
51188c2ecf20Sopenharmony_ci	return 0;
51198c2ecf20Sopenharmony_ci}
51208c2ecf20Sopenharmony_ci
51218c2ecf20Sopenharmony_ciint evergreen_resume(struct radeon_device *rdev)
51228c2ecf20Sopenharmony_ci{
51238c2ecf20Sopenharmony_ci	int r;
51248c2ecf20Sopenharmony_ci
51258c2ecf20Sopenharmony_ci	/* reset the asic, the gfx blocks are often in a bad state
51268c2ecf20Sopenharmony_ci	 * after the driver is unloaded or after a resume
51278c2ecf20Sopenharmony_ci	 */
51288c2ecf20Sopenharmony_ci	if (radeon_asic_reset(rdev))
51298c2ecf20Sopenharmony_ci		dev_warn(rdev->dev, "GPU reset failed !\n");
51308c2ecf20Sopenharmony_ci	/* Do not reset GPU before posting, on rv770 hw unlike on r500 hw,
51318c2ecf20Sopenharmony_ci	 * posting will perform necessary task to bring back GPU into good
51328c2ecf20Sopenharmony_ci	 * shape.
51338c2ecf20Sopenharmony_ci	 */
51348c2ecf20Sopenharmony_ci	/* post card */
51358c2ecf20Sopenharmony_ci	atom_asic_init(rdev->mode_info.atom_context);
51368c2ecf20Sopenharmony_ci
51378c2ecf20Sopenharmony_ci	/* init golden registers */
51388c2ecf20Sopenharmony_ci	evergreen_init_golden_registers(rdev);
51398c2ecf20Sopenharmony_ci
51408c2ecf20Sopenharmony_ci	if (rdev->pm.pm_method == PM_METHOD_DPM)
51418c2ecf20Sopenharmony_ci		radeon_pm_resume(rdev);
51428c2ecf20Sopenharmony_ci
51438c2ecf20Sopenharmony_ci	rdev->accel_working = true;
51448c2ecf20Sopenharmony_ci	r = evergreen_startup(rdev);
51458c2ecf20Sopenharmony_ci	if (r) {
51468c2ecf20Sopenharmony_ci		DRM_ERROR("evergreen startup failed on resume\n");
51478c2ecf20Sopenharmony_ci		rdev->accel_working = false;
51488c2ecf20Sopenharmony_ci		return r;
51498c2ecf20Sopenharmony_ci	}
51508c2ecf20Sopenharmony_ci
51518c2ecf20Sopenharmony_ci	return r;
51528c2ecf20Sopenharmony_ci
51538c2ecf20Sopenharmony_ci}
51548c2ecf20Sopenharmony_ci
51558c2ecf20Sopenharmony_ciint evergreen_suspend(struct radeon_device *rdev)
51568c2ecf20Sopenharmony_ci{
51578c2ecf20Sopenharmony_ci	radeon_pm_suspend(rdev);
51588c2ecf20Sopenharmony_ci	radeon_audio_fini(rdev);
51598c2ecf20Sopenharmony_ci	if (rdev->has_uvd) {
51608c2ecf20Sopenharmony_ci		uvd_v1_0_fini(rdev);
51618c2ecf20Sopenharmony_ci		radeon_uvd_suspend(rdev);
51628c2ecf20Sopenharmony_ci	}
51638c2ecf20Sopenharmony_ci	r700_cp_stop(rdev);
51648c2ecf20Sopenharmony_ci	r600_dma_stop(rdev);
51658c2ecf20Sopenharmony_ci	evergreen_irq_suspend(rdev);
51668c2ecf20Sopenharmony_ci	radeon_wb_disable(rdev);
51678c2ecf20Sopenharmony_ci	evergreen_pcie_gart_disable(rdev);
51688c2ecf20Sopenharmony_ci
51698c2ecf20Sopenharmony_ci	return 0;
51708c2ecf20Sopenharmony_ci}
51718c2ecf20Sopenharmony_ci
51728c2ecf20Sopenharmony_ci/* Plan is to move initialization in that function and use
51738c2ecf20Sopenharmony_ci * helper function so that radeon_device_init pretty much
51748c2ecf20Sopenharmony_ci * do nothing more than calling asic specific function. This
51758c2ecf20Sopenharmony_ci * should also allow to remove a bunch of callback function
51768c2ecf20Sopenharmony_ci * like vram_info.
51778c2ecf20Sopenharmony_ci */
51788c2ecf20Sopenharmony_ciint evergreen_init(struct radeon_device *rdev)
51798c2ecf20Sopenharmony_ci{
51808c2ecf20Sopenharmony_ci	int r;
51818c2ecf20Sopenharmony_ci
51828c2ecf20Sopenharmony_ci	/* Read BIOS */
51838c2ecf20Sopenharmony_ci	if (!radeon_get_bios(rdev)) {
51848c2ecf20Sopenharmony_ci		if (ASIC_IS_AVIVO(rdev))
51858c2ecf20Sopenharmony_ci			return -EINVAL;
51868c2ecf20Sopenharmony_ci	}
51878c2ecf20Sopenharmony_ci	/* Must be an ATOMBIOS */
51888c2ecf20Sopenharmony_ci	if (!rdev->is_atom_bios) {
51898c2ecf20Sopenharmony_ci		dev_err(rdev->dev, "Expecting atombios for evergreen GPU\n");
51908c2ecf20Sopenharmony_ci		return -EINVAL;
51918c2ecf20Sopenharmony_ci	}
51928c2ecf20Sopenharmony_ci	r = radeon_atombios_init(rdev);
51938c2ecf20Sopenharmony_ci	if (r)
51948c2ecf20Sopenharmony_ci		return r;
51958c2ecf20Sopenharmony_ci	/* reset the asic, the gfx blocks are often in a bad state
51968c2ecf20Sopenharmony_ci	 * after the driver is unloaded or after a resume
51978c2ecf20Sopenharmony_ci	 */
51988c2ecf20Sopenharmony_ci	if (radeon_asic_reset(rdev))
51998c2ecf20Sopenharmony_ci		dev_warn(rdev->dev, "GPU reset failed !\n");
52008c2ecf20Sopenharmony_ci	/* Post card if necessary */
52018c2ecf20Sopenharmony_ci	if (!radeon_card_posted(rdev)) {
52028c2ecf20Sopenharmony_ci		if (!rdev->bios) {
52038c2ecf20Sopenharmony_ci			dev_err(rdev->dev, "Card not posted and no BIOS - ignoring\n");
52048c2ecf20Sopenharmony_ci			return -EINVAL;
52058c2ecf20Sopenharmony_ci		}
52068c2ecf20Sopenharmony_ci		DRM_INFO("GPU not posted. posting now...\n");
52078c2ecf20Sopenharmony_ci		atom_asic_init(rdev->mode_info.atom_context);
52088c2ecf20Sopenharmony_ci	}
52098c2ecf20Sopenharmony_ci	/* init golden registers */
52108c2ecf20Sopenharmony_ci	evergreen_init_golden_registers(rdev);
52118c2ecf20Sopenharmony_ci	/* Initialize scratch registers */
52128c2ecf20Sopenharmony_ci	r600_scratch_init(rdev);
52138c2ecf20Sopenharmony_ci	/* Initialize surface registers */
52148c2ecf20Sopenharmony_ci	radeon_surface_init(rdev);
52158c2ecf20Sopenharmony_ci	/* Initialize clocks */
52168c2ecf20Sopenharmony_ci	radeon_get_clock_info(rdev->ddev);
52178c2ecf20Sopenharmony_ci	/* Fence driver */
52188c2ecf20Sopenharmony_ci	r = radeon_fence_driver_init(rdev);
52198c2ecf20Sopenharmony_ci	if (r)
52208c2ecf20Sopenharmony_ci		return r;
52218c2ecf20Sopenharmony_ci	/* initialize AGP */
52228c2ecf20Sopenharmony_ci	if (rdev->flags & RADEON_IS_AGP) {
52238c2ecf20Sopenharmony_ci		r = radeon_agp_init(rdev);
52248c2ecf20Sopenharmony_ci		if (r)
52258c2ecf20Sopenharmony_ci			radeon_agp_disable(rdev);
52268c2ecf20Sopenharmony_ci	}
52278c2ecf20Sopenharmony_ci	/* initialize memory controller */
52288c2ecf20Sopenharmony_ci	r = evergreen_mc_init(rdev);
52298c2ecf20Sopenharmony_ci	if (r)
52308c2ecf20Sopenharmony_ci		return r;
52318c2ecf20Sopenharmony_ci	/* Memory manager */
52328c2ecf20Sopenharmony_ci	r = radeon_bo_init(rdev);
52338c2ecf20Sopenharmony_ci	if (r)
52348c2ecf20Sopenharmony_ci		return r;
52358c2ecf20Sopenharmony_ci
52368c2ecf20Sopenharmony_ci	if (ASIC_IS_DCE5(rdev)) {
52378c2ecf20Sopenharmony_ci		if (!rdev->me_fw || !rdev->pfp_fw || !rdev->rlc_fw || !rdev->mc_fw) {
52388c2ecf20Sopenharmony_ci			r = ni_init_microcode(rdev);
52398c2ecf20Sopenharmony_ci			if (r) {
52408c2ecf20Sopenharmony_ci				DRM_ERROR("Failed to load firmware!\n");
52418c2ecf20Sopenharmony_ci				return r;
52428c2ecf20Sopenharmony_ci			}
52438c2ecf20Sopenharmony_ci		}
52448c2ecf20Sopenharmony_ci	} else {
52458c2ecf20Sopenharmony_ci		if (!rdev->me_fw || !rdev->pfp_fw || !rdev->rlc_fw) {
52468c2ecf20Sopenharmony_ci			r = r600_init_microcode(rdev);
52478c2ecf20Sopenharmony_ci			if (r) {
52488c2ecf20Sopenharmony_ci				DRM_ERROR("Failed to load firmware!\n");
52498c2ecf20Sopenharmony_ci				return r;
52508c2ecf20Sopenharmony_ci			}
52518c2ecf20Sopenharmony_ci		}
52528c2ecf20Sopenharmony_ci	}
52538c2ecf20Sopenharmony_ci
52548c2ecf20Sopenharmony_ci	/* Initialize power management */
52558c2ecf20Sopenharmony_ci	radeon_pm_init(rdev);
52568c2ecf20Sopenharmony_ci
52578c2ecf20Sopenharmony_ci	rdev->ring[RADEON_RING_TYPE_GFX_INDEX].ring_obj = NULL;
52588c2ecf20Sopenharmony_ci	r600_ring_init(rdev, &rdev->ring[RADEON_RING_TYPE_GFX_INDEX], 1024 * 1024);
52598c2ecf20Sopenharmony_ci
52608c2ecf20Sopenharmony_ci	rdev->ring[R600_RING_TYPE_DMA_INDEX].ring_obj = NULL;
52618c2ecf20Sopenharmony_ci	r600_ring_init(rdev, &rdev->ring[R600_RING_TYPE_DMA_INDEX], 64 * 1024);
52628c2ecf20Sopenharmony_ci
52638c2ecf20Sopenharmony_ci	evergreen_uvd_init(rdev);
52648c2ecf20Sopenharmony_ci
52658c2ecf20Sopenharmony_ci	rdev->ih.ring_obj = NULL;
52668c2ecf20Sopenharmony_ci	r600_ih_ring_init(rdev, 64 * 1024);
52678c2ecf20Sopenharmony_ci
52688c2ecf20Sopenharmony_ci	r = r600_pcie_gart_init(rdev);
52698c2ecf20Sopenharmony_ci	if (r)
52708c2ecf20Sopenharmony_ci		return r;
52718c2ecf20Sopenharmony_ci
52728c2ecf20Sopenharmony_ci	rdev->accel_working = true;
52738c2ecf20Sopenharmony_ci	r = evergreen_startup(rdev);
52748c2ecf20Sopenharmony_ci	if (r) {
52758c2ecf20Sopenharmony_ci		dev_err(rdev->dev, "disabling GPU acceleration\n");
52768c2ecf20Sopenharmony_ci		r700_cp_fini(rdev);
52778c2ecf20Sopenharmony_ci		r600_dma_fini(rdev);
52788c2ecf20Sopenharmony_ci		r600_irq_fini(rdev);
52798c2ecf20Sopenharmony_ci		if (rdev->flags & RADEON_IS_IGP)
52808c2ecf20Sopenharmony_ci			sumo_rlc_fini(rdev);
52818c2ecf20Sopenharmony_ci		radeon_wb_fini(rdev);
52828c2ecf20Sopenharmony_ci		radeon_ib_pool_fini(rdev);
52838c2ecf20Sopenharmony_ci		radeon_irq_kms_fini(rdev);
52848c2ecf20Sopenharmony_ci		evergreen_pcie_gart_fini(rdev);
52858c2ecf20Sopenharmony_ci		rdev->accel_working = false;
52868c2ecf20Sopenharmony_ci	}
52878c2ecf20Sopenharmony_ci
52888c2ecf20Sopenharmony_ci	/* Don't start up if the MC ucode is missing on BTC parts.
52898c2ecf20Sopenharmony_ci	 * The default clocks and voltages before the MC ucode
52908c2ecf20Sopenharmony_ci	 * is loaded are not suffient for advanced operations.
52918c2ecf20Sopenharmony_ci	 */
52928c2ecf20Sopenharmony_ci	if (ASIC_IS_DCE5(rdev)) {
52938c2ecf20Sopenharmony_ci		if (!rdev->mc_fw && !(rdev->flags & RADEON_IS_IGP)) {
52948c2ecf20Sopenharmony_ci			DRM_ERROR("radeon: MC ucode required for NI+.\n");
52958c2ecf20Sopenharmony_ci			return -EINVAL;
52968c2ecf20Sopenharmony_ci		}
52978c2ecf20Sopenharmony_ci	}
52988c2ecf20Sopenharmony_ci
52998c2ecf20Sopenharmony_ci	return 0;
53008c2ecf20Sopenharmony_ci}
53018c2ecf20Sopenharmony_ci
53028c2ecf20Sopenharmony_civoid evergreen_fini(struct radeon_device *rdev)
53038c2ecf20Sopenharmony_ci{
53048c2ecf20Sopenharmony_ci	radeon_pm_fini(rdev);
53058c2ecf20Sopenharmony_ci	radeon_audio_fini(rdev);
53068c2ecf20Sopenharmony_ci	r700_cp_fini(rdev);
53078c2ecf20Sopenharmony_ci	r600_dma_fini(rdev);
53088c2ecf20Sopenharmony_ci	r600_irq_fini(rdev);
53098c2ecf20Sopenharmony_ci	if (rdev->flags & RADEON_IS_IGP)
53108c2ecf20Sopenharmony_ci		sumo_rlc_fini(rdev);
53118c2ecf20Sopenharmony_ci	radeon_wb_fini(rdev);
53128c2ecf20Sopenharmony_ci	radeon_ib_pool_fini(rdev);
53138c2ecf20Sopenharmony_ci	radeon_irq_kms_fini(rdev);
53148c2ecf20Sopenharmony_ci	uvd_v1_0_fini(rdev);
53158c2ecf20Sopenharmony_ci	radeon_uvd_fini(rdev);
53168c2ecf20Sopenharmony_ci	evergreen_pcie_gart_fini(rdev);
53178c2ecf20Sopenharmony_ci	r600_vram_scratch_fini(rdev);
53188c2ecf20Sopenharmony_ci	radeon_gem_fini(rdev);
53198c2ecf20Sopenharmony_ci	radeon_fence_driver_fini(rdev);
53208c2ecf20Sopenharmony_ci	radeon_agp_fini(rdev);
53218c2ecf20Sopenharmony_ci	radeon_bo_fini(rdev);
53228c2ecf20Sopenharmony_ci	radeon_atombios_fini(rdev);
53238c2ecf20Sopenharmony_ci	kfree(rdev->bios);
53248c2ecf20Sopenharmony_ci	rdev->bios = NULL;
53258c2ecf20Sopenharmony_ci}
53268c2ecf20Sopenharmony_ci
53278c2ecf20Sopenharmony_civoid evergreen_pcie_gen2_enable(struct radeon_device *rdev)
53288c2ecf20Sopenharmony_ci{
53298c2ecf20Sopenharmony_ci	u32 link_width_cntl, speed_cntl;
53308c2ecf20Sopenharmony_ci
53318c2ecf20Sopenharmony_ci	if (radeon_pcie_gen2 == 0)
53328c2ecf20Sopenharmony_ci		return;
53338c2ecf20Sopenharmony_ci
53348c2ecf20Sopenharmony_ci	if (rdev->flags & RADEON_IS_IGP)
53358c2ecf20Sopenharmony_ci		return;
53368c2ecf20Sopenharmony_ci
53378c2ecf20Sopenharmony_ci	if (!(rdev->flags & RADEON_IS_PCIE))
53388c2ecf20Sopenharmony_ci		return;
53398c2ecf20Sopenharmony_ci
53408c2ecf20Sopenharmony_ci	/* x2 cards have a special sequence */
53418c2ecf20Sopenharmony_ci	if (ASIC_IS_X2(rdev))
53428c2ecf20Sopenharmony_ci		return;
53438c2ecf20Sopenharmony_ci
53448c2ecf20Sopenharmony_ci	if ((rdev->pdev->bus->max_bus_speed != PCIE_SPEED_5_0GT) &&
53458c2ecf20Sopenharmony_ci		(rdev->pdev->bus->max_bus_speed != PCIE_SPEED_8_0GT))
53468c2ecf20Sopenharmony_ci		return;
53478c2ecf20Sopenharmony_ci
53488c2ecf20Sopenharmony_ci	speed_cntl = RREG32_PCIE_PORT(PCIE_LC_SPEED_CNTL);
53498c2ecf20Sopenharmony_ci	if (speed_cntl & LC_CURRENT_DATA_RATE) {
53508c2ecf20Sopenharmony_ci		DRM_INFO("PCIE gen 2 link speeds already enabled\n");
53518c2ecf20Sopenharmony_ci		return;
53528c2ecf20Sopenharmony_ci	}
53538c2ecf20Sopenharmony_ci
53548c2ecf20Sopenharmony_ci	DRM_INFO("enabling PCIE gen 2 link speeds, disable with radeon.pcie_gen2=0\n");
53558c2ecf20Sopenharmony_ci
53568c2ecf20Sopenharmony_ci	if ((speed_cntl & LC_OTHER_SIDE_EVER_SENT_GEN2) ||
53578c2ecf20Sopenharmony_ci	    (speed_cntl & LC_OTHER_SIDE_SUPPORTS_GEN2)) {
53588c2ecf20Sopenharmony_ci
53598c2ecf20Sopenharmony_ci		link_width_cntl = RREG32_PCIE_PORT(PCIE_LC_LINK_WIDTH_CNTL);
53608c2ecf20Sopenharmony_ci		link_width_cntl &= ~LC_UPCONFIGURE_DIS;
53618c2ecf20Sopenharmony_ci		WREG32_PCIE_PORT(PCIE_LC_LINK_WIDTH_CNTL, link_width_cntl);
53628c2ecf20Sopenharmony_ci
53638c2ecf20Sopenharmony_ci		speed_cntl = RREG32_PCIE_PORT(PCIE_LC_SPEED_CNTL);
53648c2ecf20Sopenharmony_ci		speed_cntl &= ~LC_TARGET_LINK_SPEED_OVERRIDE_EN;
53658c2ecf20Sopenharmony_ci		WREG32_PCIE_PORT(PCIE_LC_SPEED_CNTL, speed_cntl);
53668c2ecf20Sopenharmony_ci
53678c2ecf20Sopenharmony_ci		speed_cntl = RREG32_PCIE_PORT(PCIE_LC_SPEED_CNTL);
53688c2ecf20Sopenharmony_ci		speed_cntl |= LC_CLR_FAILED_SPD_CHANGE_CNT;
53698c2ecf20Sopenharmony_ci		WREG32_PCIE_PORT(PCIE_LC_SPEED_CNTL, speed_cntl);
53708c2ecf20Sopenharmony_ci
53718c2ecf20Sopenharmony_ci		speed_cntl = RREG32_PCIE_PORT(PCIE_LC_SPEED_CNTL);
53728c2ecf20Sopenharmony_ci		speed_cntl &= ~LC_CLR_FAILED_SPD_CHANGE_CNT;
53738c2ecf20Sopenharmony_ci		WREG32_PCIE_PORT(PCIE_LC_SPEED_CNTL, speed_cntl);
53748c2ecf20Sopenharmony_ci
53758c2ecf20Sopenharmony_ci		speed_cntl = RREG32_PCIE_PORT(PCIE_LC_SPEED_CNTL);
53768c2ecf20Sopenharmony_ci		speed_cntl |= LC_GEN2_EN_STRAP;
53778c2ecf20Sopenharmony_ci		WREG32_PCIE_PORT(PCIE_LC_SPEED_CNTL, speed_cntl);
53788c2ecf20Sopenharmony_ci
53798c2ecf20Sopenharmony_ci	} else {
53808c2ecf20Sopenharmony_ci		link_width_cntl = RREG32_PCIE_PORT(PCIE_LC_LINK_WIDTH_CNTL);
53818c2ecf20Sopenharmony_ci		/* XXX: only disable it if gen1 bridge vendor == 0x111d or 0x1106 */
53828c2ecf20Sopenharmony_ci		if (1)
53838c2ecf20Sopenharmony_ci			link_width_cntl |= LC_UPCONFIGURE_DIS;
53848c2ecf20Sopenharmony_ci		else
53858c2ecf20Sopenharmony_ci			link_width_cntl &= ~LC_UPCONFIGURE_DIS;
53868c2ecf20Sopenharmony_ci		WREG32_PCIE_PORT(PCIE_LC_LINK_WIDTH_CNTL, link_width_cntl);
53878c2ecf20Sopenharmony_ci	}
53888c2ecf20Sopenharmony_ci}
53898c2ecf20Sopenharmony_ci
53908c2ecf20Sopenharmony_civoid evergreen_program_aspm(struct radeon_device *rdev)
53918c2ecf20Sopenharmony_ci{
53928c2ecf20Sopenharmony_ci	u32 data, orig;
53938c2ecf20Sopenharmony_ci	u32 pcie_lc_cntl, pcie_lc_cntl_old;
53948c2ecf20Sopenharmony_ci	bool disable_l0s, disable_l1 = false, disable_plloff_in_l1 = false;
53958c2ecf20Sopenharmony_ci	/* fusion_platform = true
53968c2ecf20Sopenharmony_ci	 * if the system is a fusion system
53978c2ecf20Sopenharmony_ci	 * (APU or DGPU in a fusion system).
53988c2ecf20Sopenharmony_ci	 * todo: check if the system is a fusion platform.
53998c2ecf20Sopenharmony_ci	 */
54008c2ecf20Sopenharmony_ci	bool fusion_platform = false;
54018c2ecf20Sopenharmony_ci
54028c2ecf20Sopenharmony_ci	if (radeon_aspm == 0)
54038c2ecf20Sopenharmony_ci		return;
54048c2ecf20Sopenharmony_ci
54058c2ecf20Sopenharmony_ci	if (!(rdev->flags & RADEON_IS_PCIE))
54068c2ecf20Sopenharmony_ci		return;
54078c2ecf20Sopenharmony_ci
54088c2ecf20Sopenharmony_ci	switch (rdev->family) {
54098c2ecf20Sopenharmony_ci	case CHIP_CYPRESS:
54108c2ecf20Sopenharmony_ci	case CHIP_HEMLOCK:
54118c2ecf20Sopenharmony_ci	case CHIP_JUNIPER:
54128c2ecf20Sopenharmony_ci	case CHIP_REDWOOD:
54138c2ecf20Sopenharmony_ci	case CHIP_CEDAR:
54148c2ecf20Sopenharmony_ci	case CHIP_SUMO:
54158c2ecf20Sopenharmony_ci	case CHIP_SUMO2:
54168c2ecf20Sopenharmony_ci	case CHIP_PALM:
54178c2ecf20Sopenharmony_ci	case CHIP_ARUBA:
54188c2ecf20Sopenharmony_ci		disable_l0s = true;
54198c2ecf20Sopenharmony_ci		break;
54208c2ecf20Sopenharmony_ci	default:
54218c2ecf20Sopenharmony_ci		disable_l0s = false;
54228c2ecf20Sopenharmony_ci		break;
54238c2ecf20Sopenharmony_ci	}
54248c2ecf20Sopenharmony_ci
54258c2ecf20Sopenharmony_ci	if (rdev->flags & RADEON_IS_IGP)
54268c2ecf20Sopenharmony_ci		fusion_platform = true; /* XXX also dGPUs in a fusion system */
54278c2ecf20Sopenharmony_ci
54288c2ecf20Sopenharmony_ci	data = orig = RREG32_PIF_PHY0(PB0_PIF_PAIRING);
54298c2ecf20Sopenharmony_ci	if (fusion_platform)
54308c2ecf20Sopenharmony_ci		data &= ~MULTI_PIF;
54318c2ecf20Sopenharmony_ci	else
54328c2ecf20Sopenharmony_ci		data |= MULTI_PIF;
54338c2ecf20Sopenharmony_ci	if (data != orig)
54348c2ecf20Sopenharmony_ci		WREG32_PIF_PHY0(PB0_PIF_PAIRING, data);
54358c2ecf20Sopenharmony_ci
54368c2ecf20Sopenharmony_ci	data = orig = RREG32_PIF_PHY1(PB1_PIF_PAIRING);
54378c2ecf20Sopenharmony_ci	if (fusion_platform)
54388c2ecf20Sopenharmony_ci		data &= ~MULTI_PIF;
54398c2ecf20Sopenharmony_ci	else
54408c2ecf20Sopenharmony_ci		data |= MULTI_PIF;
54418c2ecf20Sopenharmony_ci	if (data != orig)
54428c2ecf20Sopenharmony_ci		WREG32_PIF_PHY1(PB1_PIF_PAIRING, data);
54438c2ecf20Sopenharmony_ci
54448c2ecf20Sopenharmony_ci	pcie_lc_cntl = pcie_lc_cntl_old = RREG32_PCIE_PORT(PCIE_LC_CNTL);
54458c2ecf20Sopenharmony_ci	pcie_lc_cntl &= ~(LC_L0S_INACTIVITY_MASK | LC_L1_INACTIVITY_MASK);
54468c2ecf20Sopenharmony_ci	if (!disable_l0s) {
54478c2ecf20Sopenharmony_ci		if (rdev->family >= CHIP_BARTS)
54488c2ecf20Sopenharmony_ci			pcie_lc_cntl |= LC_L0S_INACTIVITY(7);
54498c2ecf20Sopenharmony_ci		else
54508c2ecf20Sopenharmony_ci			pcie_lc_cntl |= LC_L0S_INACTIVITY(3);
54518c2ecf20Sopenharmony_ci	}
54528c2ecf20Sopenharmony_ci
54538c2ecf20Sopenharmony_ci	if (!disable_l1) {
54548c2ecf20Sopenharmony_ci		if (rdev->family >= CHIP_BARTS)
54558c2ecf20Sopenharmony_ci			pcie_lc_cntl |= LC_L1_INACTIVITY(7);
54568c2ecf20Sopenharmony_ci		else
54578c2ecf20Sopenharmony_ci			pcie_lc_cntl |= LC_L1_INACTIVITY(8);
54588c2ecf20Sopenharmony_ci
54598c2ecf20Sopenharmony_ci		if (!disable_plloff_in_l1) {
54608c2ecf20Sopenharmony_ci			data = orig = RREG32_PIF_PHY0(PB0_PIF_PWRDOWN_0);
54618c2ecf20Sopenharmony_ci			data &= ~(PLL_POWER_STATE_IN_OFF_0_MASK | PLL_POWER_STATE_IN_TXS2_0_MASK);
54628c2ecf20Sopenharmony_ci			data |= PLL_POWER_STATE_IN_OFF_0(7) | PLL_POWER_STATE_IN_TXS2_0(7);
54638c2ecf20Sopenharmony_ci			if (data != orig)
54648c2ecf20Sopenharmony_ci				WREG32_PIF_PHY0(PB0_PIF_PWRDOWN_0, data);
54658c2ecf20Sopenharmony_ci
54668c2ecf20Sopenharmony_ci			data = orig = RREG32_PIF_PHY0(PB0_PIF_PWRDOWN_1);
54678c2ecf20Sopenharmony_ci			data &= ~(PLL_POWER_STATE_IN_OFF_1_MASK | PLL_POWER_STATE_IN_TXS2_1_MASK);
54688c2ecf20Sopenharmony_ci			data |= PLL_POWER_STATE_IN_OFF_1(7) | PLL_POWER_STATE_IN_TXS2_1(7);
54698c2ecf20Sopenharmony_ci			if (data != orig)
54708c2ecf20Sopenharmony_ci				WREG32_PIF_PHY0(PB0_PIF_PWRDOWN_1, data);
54718c2ecf20Sopenharmony_ci
54728c2ecf20Sopenharmony_ci			data = orig = RREG32_PIF_PHY1(PB1_PIF_PWRDOWN_0);
54738c2ecf20Sopenharmony_ci			data &= ~(PLL_POWER_STATE_IN_OFF_0_MASK | PLL_POWER_STATE_IN_TXS2_0_MASK);
54748c2ecf20Sopenharmony_ci			data |= PLL_POWER_STATE_IN_OFF_0(7) | PLL_POWER_STATE_IN_TXS2_0(7);
54758c2ecf20Sopenharmony_ci			if (data != orig)
54768c2ecf20Sopenharmony_ci				WREG32_PIF_PHY1(PB1_PIF_PWRDOWN_0, data);
54778c2ecf20Sopenharmony_ci
54788c2ecf20Sopenharmony_ci			data = orig = RREG32_PIF_PHY1(PB1_PIF_PWRDOWN_1);
54798c2ecf20Sopenharmony_ci			data &= ~(PLL_POWER_STATE_IN_OFF_1_MASK | PLL_POWER_STATE_IN_TXS2_1_MASK);
54808c2ecf20Sopenharmony_ci			data |= PLL_POWER_STATE_IN_OFF_1(7) | PLL_POWER_STATE_IN_TXS2_1(7);
54818c2ecf20Sopenharmony_ci			if (data != orig)
54828c2ecf20Sopenharmony_ci				WREG32_PIF_PHY1(PB1_PIF_PWRDOWN_1, data);
54838c2ecf20Sopenharmony_ci
54848c2ecf20Sopenharmony_ci			if (rdev->family >= CHIP_BARTS) {
54858c2ecf20Sopenharmony_ci				data = orig = RREG32_PIF_PHY0(PB0_PIF_PWRDOWN_0);
54868c2ecf20Sopenharmony_ci				data &= ~PLL_RAMP_UP_TIME_0_MASK;
54878c2ecf20Sopenharmony_ci				data |= PLL_RAMP_UP_TIME_0(4);
54888c2ecf20Sopenharmony_ci				if (data != orig)
54898c2ecf20Sopenharmony_ci					WREG32_PIF_PHY0(PB0_PIF_PWRDOWN_0, data);
54908c2ecf20Sopenharmony_ci
54918c2ecf20Sopenharmony_ci				data = orig = RREG32_PIF_PHY0(PB0_PIF_PWRDOWN_1);
54928c2ecf20Sopenharmony_ci				data &= ~PLL_RAMP_UP_TIME_1_MASK;
54938c2ecf20Sopenharmony_ci				data |= PLL_RAMP_UP_TIME_1(4);
54948c2ecf20Sopenharmony_ci				if (data != orig)
54958c2ecf20Sopenharmony_ci					WREG32_PIF_PHY0(PB0_PIF_PWRDOWN_1, data);
54968c2ecf20Sopenharmony_ci
54978c2ecf20Sopenharmony_ci				data = orig = RREG32_PIF_PHY1(PB1_PIF_PWRDOWN_0);
54988c2ecf20Sopenharmony_ci				data &= ~PLL_RAMP_UP_TIME_0_MASK;
54998c2ecf20Sopenharmony_ci				data |= PLL_RAMP_UP_TIME_0(4);
55008c2ecf20Sopenharmony_ci				if (data != orig)
55018c2ecf20Sopenharmony_ci					WREG32_PIF_PHY1(PB1_PIF_PWRDOWN_0, data);
55028c2ecf20Sopenharmony_ci
55038c2ecf20Sopenharmony_ci				data = orig = RREG32_PIF_PHY1(PB1_PIF_PWRDOWN_1);
55048c2ecf20Sopenharmony_ci				data &= ~PLL_RAMP_UP_TIME_1_MASK;
55058c2ecf20Sopenharmony_ci				data |= PLL_RAMP_UP_TIME_1(4);
55068c2ecf20Sopenharmony_ci				if (data != orig)
55078c2ecf20Sopenharmony_ci					WREG32_PIF_PHY1(PB1_PIF_PWRDOWN_1, data);
55088c2ecf20Sopenharmony_ci			}
55098c2ecf20Sopenharmony_ci
55108c2ecf20Sopenharmony_ci			data = orig = RREG32_PCIE_PORT(PCIE_LC_LINK_WIDTH_CNTL);
55118c2ecf20Sopenharmony_ci			data &= ~LC_DYN_LANES_PWR_STATE_MASK;
55128c2ecf20Sopenharmony_ci			data |= LC_DYN_LANES_PWR_STATE(3);
55138c2ecf20Sopenharmony_ci			if (data != orig)
55148c2ecf20Sopenharmony_ci				WREG32_PCIE_PORT(PCIE_LC_LINK_WIDTH_CNTL, data);
55158c2ecf20Sopenharmony_ci
55168c2ecf20Sopenharmony_ci			if (rdev->family >= CHIP_BARTS) {
55178c2ecf20Sopenharmony_ci				data = orig = RREG32_PIF_PHY0(PB0_PIF_CNTL);
55188c2ecf20Sopenharmony_ci				data &= ~LS2_EXIT_TIME_MASK;
55198c2ecf20Sopenharmony_ci				data |= LS2_EXIT_TIME(1);
55208c2ecf20Sopenharmony_ci				if (data != orig)
55218c2ecf20Sopenharmony_ci					WREG32_PIF_PHY0(PB0_PIF_CNTL, data);
55228c2ecf20Sopenharmony_ci
55238c2ecf20Sopenharmony_ci				data = orig = RREG32_PIF_PHY1(PB1_PIF_CNTL);
55248c2ecf20Sopenharmony_ci				data &= ~LS2_EXIT_TIME_MASK;
55258c2ecf20Sopenharmony_ci				data |= LS2_EXIT_TIME(1);
55268c2ecf20Sopenharmony_ci				if (data != orig)
55278c2ecf20Sopenharmony_ci					WREG32_PIF_PHY1(PB1_PIF_CNTL, data);
55288c2ecf20Sopenharmony_ci			}
55298c2ecf20Sopenharmony_ci		}
55308c2ecf20Sopenharmony_ci	}
55318c2ecf20Sopenharmony_ci
55328c2ecf20Sopenharmony_ci	/* evergreen parts only */
55338c2ecf20Sopenharmony_ci	if (rdev->family < CHIP_BARTS)
55348c2ecf20Sopenharmony_ci		pcie_lc_cntl |= LC_PMI_TO_L1_DIS;
55358c2ecf20Sopenharmony_ci
55368c2ecf20Sopenharmony_ci	if (pcie_lc_cntl != pcie_lc_cntl_old)
55378c2ecf20Sopenharmony_ci		WREG32_PCIE_PORT(PCIE_LC_CNTL, pcie_lc_cntl);
55388c2ecf20Sopenharmony_ci}
5539