18c2ecf20Sopenharmony_ci/*
28c2ecf20Sopenharmony_ci * Copyright 2011 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/module.h>
278c2ecf20Sopenharmony_ci#include <linux/pci.h>
288c2ecf20Sopenharmony_ci#include <linux/slab.h>
298c2ecf20Sopenharmony_ci
308c2ecf20Sopenharmony_ci#include <drm/drm_vblank.h>
318c2ecf20Sopenharmony_ci#include <drm/radeon_drm.h>
328c2ecf20Sopenharmony_ci
338c2ecf20Sopenharmony_ci#include "atom.h"
348c2ecf20Sopenharmony_ci#include "clearstate_si.h"
358c2ecf20Sopenharmony_ci#include "radeon.h"
368c2ecf20Sopenharmony_ci#include "radeon_asic.h"
378c2ecf20Sopenharmony_ci#include "radeon_audio.h"
388c2ecf20Sopenharmony_ci#include "radeon_ucode.h"
398c2ecf20Sopenharmony_ci#include "si_blit_shaders.h"
408c2ecf20Sopenharmony_ci#include "sid.h"
418c2ecf20Sopenharmony_ci
428c2ecf20Sopenharmony_ci
438c2ecf20Sopenharmony_ciMODULE_FIRMWARE("radeon/TAHITI_pfp.bin");
448c2ecf20Sopenharmony_ciMODULE_FIRMWARE("radeon/TAHITI_me.bin");
458c2ecf20Sopenharmony_ciMODULE_FIRMWARE("radeon/TAHITI_ce.bin");
468c2ecf20Sopenharmony_ciMODULE_FIRMWARE("radeon/TAHITI_mc.bin");
478c2ecf20Sopenharmony_ciMODULE_FIRMWARE("radeon/TAHITI_mc2.bin");
488c2ecf20Sopenharmony_ciMODULE_FIRMWARE("radeon/TAHITI_rlc.bin");
498c2ecf20Sopenharmony_ciMODULE_FIRMWARE("radeon/TAHITI_smc.bin");
508c2ecf20Sopenharmony_ci
518c2ecf20Sopenharmony_ciMODULE_FIRMWARE("radeon/tahiti_pfp.bin");
528c2ecf20Sopenharmony_ciMODULE_FIRMWARE("radeon/tahiti_me.bin");
538c2ecf20Sopenharmony_ciMODULE_FIRMWARE("radeon/tahiti_ce.bin");
548c2ecf20Sopenharmony_ciMODULE_FIRMWARE("radeon/tahiti_mc.bin");
558c2ecf20Sopenharmony_ciMODULE_FIRMWARE("radeon/tahiti_rlc.bin");
568c2ecf20Sopenharmony_ciMODULE_FIRMWARE("radeon/tahiti_smc.bin");
578c2ecf20Sopenharmony_ci
588c2ecf20Sopenharmony_ciMODULE_FIRMWARE("radeon/PITCAIRN_pfp.bin");
598c2ecf20Sopenharmony_ciMODULE_FIRMWARE("radeon/PITCAIRN_me.bin");
608c2ecf20Sopenharmony_ciMODULE_FIRMWARE("radeon/PITCAIRN_ce.bin");
618c2ecf20Sopenharmony_ciMODULE_FIRMWARE("radeon/PITCAIRN_mc.bin");
628c2ecf20Sopenharmony_ciMODULE_FIRMWARE("radeon/PITCAIRN_mc2.bin");
638c2ecf20Sopenharmony_ciMODULE_FIRMWARE("radeon/PITCAIRN_rlc.bin");
648c2ecf20Sopenharmony_ciMODULE_FIRMWARE("radeon/PITCAIRN_smc.bin");
658c2ecf20Sopenharmony_ci
668c2ecf20Sopenharmony_ciMODULE_FIRMWARE("radeon/pitcairn_pfp.bin");
678c2ecf20Sopenharmony_ciMODULE_FIRMWARE("radeon/pitcairn_me.bin");
688c2ecf20Sopenharmony_ciMODULE_FIRMWARE("radeon/pitcairn_ce.bin");
698c2ecf20Sopenharmony_ciMODULE_FIRMWARE("radeon/pitcairn_mc.bin");
708c2ecf20Sopenharmony_ciMODULE_FIRMWARE("radeon/pitcairn_rlc.bin");
718c2ecf20Sopenharmony_ciMODULE_FIRMWARE("radeon/pitcairn_smc.bin");
728c2ecf20Sopenharmony_ciMODULE_FIRMWARE("radeon/pitcairn_k_smc.bin");
738c2ecf20Sopenharmony_ci
748c2ecf20Sopenharmony_ciMODULE_FIRMWARE("radeon/VERDE_pfp.bin");
758c2ecf20Sopenharmony_ciMODULE_FIRMWARE("radeon/VERDE_me.bin");
768c2ecf20Sopenharmony_ciMODULE_FIRMWARE("radeon/VERDE_ce.bin");
778c2ecf20Sopenharmony_ciMODULE_FIRMWARE("radeon/VERDE_mc.bin");
788c2ecf20Sopenharmony_ciMODULE_FIRMWARE("radeon/VERDE_mc2.bin");
798c2ecf20Sopenharmony_ciMODULE_FIRMWARE("radeon/VERDE_rlc.bin");
808c2ecf20Sopenharmony_ciMODULE_FIRMWARE("radeon/VERDE_smc.bin");
818c2ecf20Sopenharmony_ci
828c2ecf20Sopenharmony_ciMODULE_FIRMWARE("radeon/verde_pfp.bin");
838c2ecf20Sopenharmony_ciMODULE_FIRMWARE("radeon/verde_me.bin");
848c2ecf20Sopenharmony_ciMODULE_FIRMWARE("radeon/verde_ce.bin");
858c2ecf20Sopenharmony_ciMODULE_FIRMWARE("radeon/verde_mc.bin");
868c2ecf20Sopenharmony_ciMODULE_FIRMWARE("radeon/verde_rlc.bin");
878c2ecf20Sopenharmony_ciMODULE_FIRMWARE("radeon/verde_smc.bin");
888c2ecf20Sopenharmony_ciMODULE_FIRMWARE("radeon/verde_k_smc.bin");
898c2ecf20Sopenharmony_ci
908c2ecf20Sopenharmony_ciMODULE_FIRMWARE("radeon/OLAND_pfp.bin");
918c2ecf20Sopenharmony_ciMODULE_FIRMWARE("radeon/OLAND_me.bin");
928c2ecf20Sopenharmony_ciMODULE_FIRMWARE("radeon/OLAND_ce.bin");
938c2ecf20Sopenharmony_ciMODULE_FIRMWARE("radeon/OLAND_mc.bin");
948c2ecf20Sopenharmony_ciMODULE_FIRMWARE("radeon/OLAND_mc2.bin");
958c2ecf20Sopenharmony_ciMODULE_FIRMWARE("radeon/OLAND_rlc.bin");
968c2ecf20Sopenharmony_ciMODULE_FIRMWARE("radeon/OLAND_smc.bin");
978c2ecf20Sopenharmony_ci
988c2ecf20Sopenharmony_ciMODULE_FIRMWARE("radeon/oland_pfp.bin");
998c2ecf20Sopenharmony_ciMODULE_FIRMWARE("radeon/oland_me.bin");
1008c2ecf20Sopenharmony_ciMODULE_FIRMWARE("radeon/oland_ce.bin");
1018c2ecf20Sopenharmony_ciMODULE_FIRMWARE("radeon/oland_mc.bin");
1028c2ecf20Sopenharmony_ciMODULE_FIRMWARE("radeon/oland_rlc.bin");
1038c2ecf20Sopenharmony_ciMODULE_FIRMWARE("radeon/oland_smc.bin");
1048c2ecf20Sopenharmony_ciMODULE_FIRMWARE("radeon/oland_k_smc.bin");
1058c2ecf20Sopenharmony_ci
1068c2ecf20Sopenharmony_ciMODULE_FIRMWARE("radeon/HAINAN_pfp.bin");
1078c2ecf20Sopenharmony_ciMODULE_FIRMWARE("radeon/HAINAN_me.bin");
1088c2ecf20Sopenharmony_ciMODULE_FIRMWARE("radeon/HAINAN_ce.bin");
1098c2ecf20Sopenharmony_ciMODULE_FIRMWARE("radeon/HAINAN_mc.bin");
1108c2ecf20Sopenharmony_ciMODULE_FIRMWARE("radeon/HAINAN_mc2.bin");
1118c2ecf20Sopenharmony_ciMODULE_FIRMWARE("radeon/HAINAN_rlc.bin");
1128c2ecf20Sopenharmony_ciMODULE_FIRMWARE("radeon/HAINAN_smc.bin");
1138c2ecf20Sopenharmony_ci
1148c2ecf20Sopenharmony_ciMODULE_FIRMWARE("radeon/hainan_pfp.bin");
1158c2ecf20Sopenharmony_ciMODULE_FIRMWARE("radeon/hainan_me.bin");
1168c2ecf20Sopenharmony_ciMODULE_FIRMWARE("radeon/hainan_ce.bin");
1178c2ecf20Sopenharmony_ciMODULE_FIRMWARE("radeon/hainan_mc.bin");
1188c2ecf20Sopenharmony_ciMODULE_FIRMWARE("radeon/hainan_rlc.bin");
1198c2ecf20Sopenharmony_ciMODULE_FIRMWARE("radeon/hainan_smc.bin");
1208c2ecf20Sopenharmony_ciMODULE_FIRMWARE("radeon/hainan_k_smc.bin");
1218c2ecf20Sopenharmony_ciMODULE_FIRMWARE("radeon/banks_k_2_smc.bin");
1228c2ecf20Sopenharmony_ci
1238c2ecf20Sopenharmony_ciMODULE_FIRMWARE("radeon/si58_mc.bin");
1248c2ecf20Sopenharmony_ci
1258c2ecf20Sopenharmony_cistatic u32 si_get_cu_active_bitmap(struct radeon_device *rdev, u32 se, u32 sh);
1268c2ecf20Sopenharmony_cistatic void si_pcie_gen3_enable(struct radeon_device *rdev);
1278c2ecf20Sopenharmony_cistatic void si_program_aspm(struct radeon_device *rdev);
1288c2ecf20Sopenharmony_ciextern void sumo_rlc_fini(struct radeon_device *rdev);
1298c2ecf20Sopenharmony_ciextern int sumo_rlc_init(struct radeon_device *rdev);
1308c2ecf20Sopenharmony_ciextern int r600_ih_ring_alloc(struct radeon_device *rdev);
1318c2ecf20Sopenharmony_ciextern void r600_ih_ring_fini(struct radeon_device *rdev);
1328c2ecf20Sopenharmony_ciextern void evergreen_fix_pci_max_read_req_size(struct radeon_device *rdev);
1338c2ecf20Sopenharmony_ciextern void evergreen_mc_stop(struct radeon_device *rdev, struct evergreen_mc_save *save);
1348c2ecf20Sopenharmony_ciextern void evergreen_mc_resume(struct radeon_device *rdev, struct evergreen_mc_save *save);
1358c2ecf20Sopenharmony_ciextern u32 evergreen_get_number_of_dram_channels(struct radeon_device *rdev);
1368c2ecf20Sopenharmony_ciextern void evergreen_print_gpu_status_regs(struct radeon_device *rdev);
1378c2ecf20Sopenharmony_ciextern bool evergreen_is_display_hung(struct radeon_device *rdev);
1388c2ecf20Sopenharmony_cistatic void si_enable_gui_idle_interrupt(struct radeon_device *rdev,
1398c2ecf20Sopenharmony_ci					 bool enable);
1408c2ecf20Sopenharmony_cistatic void si_init_pg(struct radeon_device *rdev);
1418c2ecf20Sopenharmony_cistatic void si_init_cg(struct radeon_device *rdev);
1428c2ecf20Sopenharmony_cistatic void si_fini_pg(struct radeon_device *rdev);
1438c2ecf20Sopenharmony_cistatic void si_fini_cg(struct radeon_device *rdev);
1448c2ecf20Sopenharmony_cistatic void si_rlc_stop(struct radeon_device *rdev);
1458c2ecf20Sopenharmony_ci
1468c2ecf20Sopenharmony_cistatic const u32 crtc_offsets[] =
1478c2ecf20Sopenharmony_ci{
1488c2ecf20Sopenharmony_ci	EVERGREEN_CRTC0_REGISTER_OFFSET,
1498c2ecf20Sopenharmony_ci	EVERGREEN_CRTC1_REGISTER_OFFSET,
1508c2ecf20Sopenharmony_ci	EVERGREEN_CRTC2_REGISTER_OFFSET,
1518c2ecf20Sopenharmony_ci	EVERGREEN_CRTC3_REGISTER_OFFSET,
1528c2ecf20Sopenharmony_ci	EVERGREEN_CRTC4_REGISTER_OFFSET,
1538c2ecf20Sopenharmony_ci	EVERGREEN_CRTC5_REGISTER_OFFSET
1548c2ecf20Sopenharmony_ci};
1558c2ecf20Sopenharmony_ci
1568c2ecf20Sopenharmony_cistatic const u32 si_disp_int_status[] =
1578c2ecf20Sopenharmony_ci{
1588c2ecf20Sopenharmony_ci	DISP_INTERRUPT_STATUS,
1598c2ecf20Sopenharmony_ci	DISP_INTERRUPT_STATUS_CONTINUE,
1608c2ecf20Sopenharmony_ci	DISP_INTERRUPT_STATUS_CONTINUE2,
1618c2ecf20Sopenharmony_ci	DISP_INTERRUPT_STATUS_CONTINUE3,
1628c2ecf20Sopenharmony_ci	DISP_INTERRUPT_STATUS_CONTINUE4,
1638c2ecf20Sopenharmony_ci	DISP_INTERRUPT_STATUS_CONTINUE5
1648c2ecf20Sopenharmony_ci};
1658c2ecf20Sopenharmony_ci
1668c2ecf20Sopenharmony_ci#define DC_HPDx_CONTROL(x)        (DC_HPD1_CONTROL     + (x * 0xc))
1678c2ecf20Sopenharmony_ci#define DC_HPDx_INT_CONTROL(x)    (DC_HPD1_INT_CONTROL + (x * 0xc))
1688c2ecf20Sopenharmony_ci#define DC_HPDx_INT_STATUS_REG(x) (DC_HPD1_INT_STATUS  + (x * 0xc))
1698c2ecf20Sopenharmony_ci
1708c2ecf20Sopenharmony_cistatic const u32 verde_rlc_save_restore_register_list[] =
1718c2ecf20Sopenharmony_ci{
1728c2ecf20Sopenharmony_ci	(0x8000 << 16) | (0x98f4 >> 2),
1738c2ecf20Sopenharmony_ci	0x00000000,
1748c2ecf20Sopenharmony_ci	(0x8040 << 16) | (0x98f4 >> 2),
1758c2ecf20Sopenharmony_ci	0x00000000,
1768c2ecf20Sopenharmony_ci	(0x8000 << 16) | (0xe80 >> 2),
1778c2ecf20Sopenharmony_ci	0x00000000,
1788c2ecf20Sopenharmony_ci	(0x8040 << 16) | (0xe80 >> 2),
1798c2ecf20Sopenharmony_ci	0x00000000,
1808c2ecf20Sopenharmony_ci	(0x8000 << 16) | (0x89bc >> 2),
1818c2ecf20Sopenharmony_ci	0x00000000,
1828c2ecf20Sopenharmony_ci	(0x8040 << 16) | (0x89bc >> 2),
1838c2ecf20Sopenharmony_ci	0x00000000,
1848c2ecf20Sopenharmony_ci	(0x8000 << 16) | (0x8c1c >> 2),
1858c2ecf20Sopenharmony_ci	0x00000000,
1868c2ecf20Sopenharmony_ci	(0x8040 << 16) | (0x8c1c >> 2),
1878c2ecf20Sopenharmony_ci	0x00000000,
1888c2ecf20Sopenharmony_ci	(0x9c00 << 16) | (0x98f0 >> 2),
1898c2ecf20Sopenharmony_ci	0x00000000,
1908c2ecf20Sopenharmony_ci	(0x9c00 << 16) | (0xe7c >> 2),
1918c2ecf20Sopenharmony_ci	0x00000000,
1928c2ecf20Sopenharmony_ci	(0x8000 << 16) | (0x9148 >> 2),
1938c2ecf20Sopenharmony_ci	0x00000000,
1948c2ecf20Sopenharmony_ci	(0x8040 << 16) | (0x9148 >> 2),
1958c2ecf20Sopenharmony_ci	0x00000000,
1968c2ecf20Sopenharmony_ci	(0x9c00 << 16) | (0x9150 >> 2),
1978c2ecf20Sopenharmony_ci	0x00000000,
1988c2ecf20Sopenharmony_ci	(0x9c00 << 16) | (0x897c >> 2),
1998c2ecf20Sopenharmony_ci	0x00000000,
2008c2ecf20Sopenharmony_ci	(0x9c00 << 16) | (0x8d8c >> 2),
2018c2ecf20Sopenharmony_ci	0x00000000,
2028c2ecf20Sopenharmony_ci	(0x9c00 << 16) | (0xac54 >> 2),
2038c2ecf20Sopenharmony_ci	0X00000000,
2048c2ecf20Sopenharmony_ci	0x3,
2058c2ecf20Sopenharmony_ci	(0x9c00 << 16) | (0x98f8 >> 2),
2068c2ecf20Sopenharmony_ci	0x00000000,
2078c2ecf20Sopenharmony_ci	(0x9c00 << 16) | (0x9910 >> 2),
2088c2ecf20Sopenharmony_ci	0x00000000,
2098c2ecf20Sopenharmony_ci	(0x9c00 << 16) | (0x9914 >> 2),
2108c2ecf20Sopenharmony_ci	0x00000000,
2118c2ecf20Sopenharmony_ci	(0x9c00 << 16) | (0x9918 >> 2),
2128c2ecf20Sopenharmony_ci	0x00000000,
2138c2ecf20Sopenharmony_ci	(0x9c00 << 16) | (0x991c >> 2),
2148c2ecf20Sopenharmony_ci	0x00000000,
2158c2ecf20Sopenharmony_ci	(0x9c00 << 16) | (0x9920 >> 2),
2168c2ecf20Sopenharmony_ci	0x00000000,
2178c2ecf20Sopenharmony_ci	(0x9c00 << 16) | (0x9924 >> 2),
2188c2ecf20Sopenharmony_ci	0x00000000,
2198c2ecf20Sopenharmony_ci	(0x9c00 << 16) | (0x9928 >> 2),
2208c2ecf20Sopenharmony_ci	0x00000000,
2218c2ecf20Sopenharmony_ci	(0x9c00 << 16) | (0x992c >> 2),
2228c2ecf20Sopenharmony_ci	0x00000000,
2238c2ecf20Sopenharmony_ci	(0x9c00 << 16) | (0x9930 >> 2),
2248c2ecf20Sopenharmony_ci	0x00000000,
2258c2ecf20Sopenharmony_ci	(0x9c00 << 16) | (0x9934 >> 2),
2268c2ecf20Sopenharmony_ci	0x00000000,
2278c2ecf20Sopenharmony_ci	(0x9c00 << 16) | (0x9938 >> 2),
2288c2ecf20Sopenharmony_ci	0x00000000,
2298c2ecf20Sopenharmony_ci	(0x9c00 << 16) | (0x993c >> 2),
2308c2ecf20Sopenharmony_ci	0x00000000,
2318c2ecf20Sopenharmony_ci	(0x9c00 << 16) | (0x9940 >> 2),
2328c2ecf20Sopenharmony_ci	0x00000000,
2338c2ecf20Sopenharmony_ci	(0x9c00 << 16) | (0x9944 >> 2),
2348c2ecf20Sopenharmony_ci	0x00000000,
2358c2ecf20Sopenharmony_ci	(0x9c00 << 16) | (0x9948 >> 2),
2368c2ecf20Sopenharmony_ci	0x00000000,
2378c2ecf20Sopenharmony_ci	(0x9c00 << 16) | (0x994c >> 2),
2388c2ecf20Sopenharmony_ci	0x00000000,
2398c2ecf20Sopenharmony_ci	(0x9c00 << 16) | (0x9950 >> 2),
2408c2ecf20Sopenharmony_ci	0x00000000,
2418c2ecf20Sopenharmony_ci	(0x9c00 << 16) | (0x9954 >> 2),
2428c2ecf20Sopenharmony_ci	0x00000000,
2438c2ecf20Sopenharmony_ci	(0x9c00 << 16) | (0x9958 >> 2),
2448c2ecf20Sopenharmony_ci	0x00000000,
2458c2ecf20Sopenharmony_ci	(0x9c00 << 16) | (0x995c >> 2),
2468c2ecf20Sopenharmony_ci	0x00000000,
2478c2ecf20Sopenharmony_ci	(0x9c00 << 16) | (0x9960 >> 2),
2488c2ecf20Sopenharmony_ci	0x00000000,
2498c2ecf20Sopenharmony_ci	(0x9c00 << 16) | (0x9964 >> 2),
2508c2ecf20Sopenharmony_ci	0x00000000,
2518c2ecf20Sopenharmony_ci	(0x9c00 << 16) | (0x9968 >> 2),
2528c2ecf20Sopenharmony_ci	0x00000000,
2538c2ecf20Sopenharmony_ci	(0x9c00 << 16) | (0x996c >> 2),
2548c2ecf20Sopenharmony_ci	0x00000000,
2558c2ecf20Sopenharmony_ci	(0x9c00 << 16) | (0x9970 >> 2),
2568c2ecf20Sopenharmony_ci	0x00000000,
2578c2ecf20Sopenharmony_ci	(0x9c00 << 16) | (0x9974 >> 2),
2588c2ecf20Sopenharmony_ci	0x00000000,
2598c2ecf20Sopenharmony_ci	(0x9c00 << 16) | (0x9978 >> 2),
2608c2ecf20Sopenharmony_ci	0x00000000,
2618c2ecf20Sopenharmony_ci	(0x9c00 << 16) | (0x997c >> 2),
2628c2ecf20Sopenharmony_ci	0x00000000,
2638c2ecf20Sopenharmony_ci	(0x9c00 << 16) | (0x9980 >> 2),
2648c2ecf20Sopenharmony_ci	0x00000000,
2658c2ecf20Sopenharmony_ci	(0x9c00 << 16) | (0x9984 >> 2),
2668c2ecf20Sopenharmony_ci	0x00000000,
2678c2ecf20Sopenharmony_ci	(0x9c00 << 16) | (0x9988 >> 2),
2688c2ecf20Sopenharmony_ci	0x00000000,
2698c2ecf20Sopenharmony_ci	(0x9c00 << 16) | (0x998c >> 2),
2708c2ecf20Sopenharmony_ci	0x00000000,
2718c2ecf20Sopenharmony_ci	(0x9c00 << 16) | (0x8c00 >> 2),
2728c2ecf20Sopenharmony_ci	0x00000000,
2738c2ecf20Sopenharmony_ci	(0x9c00 << 16) | (0x8c14 >> 2),
2748c2ecf20Sopenharmony_ci	0x00000000,
2758c2ecf20Sopenharmony_ci	(0x9c00 << 16) | (0x8c04 >> 2),
2768c2ecf20Sopenharmony_ci	0x00000000,
2778c2ecf20Sopenharmony_ci	(0x9c00 << 16) | (0x8c08 >> 2),
2788c2ecf20Sopenharmony_ci	0x00000000,
2798c2ecf20Sopenharmony_ci	(0x8000 << 16) | (0x9b7c >> 2),
2808c2ecf20Sopenharmony_ci	0x00000000,
2818c2ecf20Sopenharmony_ci	(0x8040 << 16) | (0x9b7c >> 2),
2828c2ecf20Sopenharmony_ci	0x00000000,
2838c2ecf20Sopenharmony_ci	(0x8000 << 16) | (0xe84 >> 2),
2848c2ecf20Sopenharmony_ci	0x00000000,
2858c2ecf20Sopenharmony_ci	(0x8040 << 16) | (0xe84 >> 2),
2868c2ecf20Sopenharmony_ci	0x00000000,
2878c2ecf20Sopenharmony_ci	(0x8000 << 16) | (0x89c0 >> 2),
2888c2ecf20Sopenharmony_ci	0x00000000,
2898c2ecf20Sopenharmony_ci	(0x8040 << 16) | (0x89c0 >> 2),
2908c2ecf20Sopenharmony_ci	0x00000000,
2918c2ecf20Sopenharmony_ci	(0x8000 << 16) | (0x914c >> 2),
2928c2ecf20Sopenharmony_ci	0x00000000,
2938c2ecf20Sopenharmony_ci	(0x8040 << 16) | (0x914c >> 2),
2948c2ecf20Sopenharmony_ci	0x00000000,
2958c2ecf20Sopenharmony_ci	(0x8000 << 16) | (0x8c20 >> 2),
2968c2ecf20Sopenharmony_ci	0x00000000,
2978c2ecf20Sopenharmony_ci	(0x8040 << 16) | (0x8c20 >> 2),
2988c2ecf20Sopenharmony_ci	0x00000000,
2998c2ecf20Sopenharmony_ci	(0x8000 << 16) | (0x9354 >> 2),
3008c2ecf20Sopenharmony_ci	0x00000000,
3018c2ecf20Sopenharmony_ci	(0x8040 << 16) | (0x9354 >> 2),
3028c2ecf20Sopenharmony_ci	0x00000000,
3038c2ecf20Sopenharmony_ci	(0x9c00 << 16) | (0x9060 >> 2),
3048c2ecf20Sopenharmony_ci	0x00000000,
3058c2ecf20Sopenharmony_ci	(0x9c00 << 16) | (0x9364 >> 2),
3068c2ecf20Sopenharmony_ci	0x00000000,
3078c2ecf20Sopenharmony_ci	(0x9c00 << 16) | (0x9100 >> 2),
3088c2ecf20Sopenharmony_ci	0x00000000,
3098c2ecf20Sopenharmony_ci	(0x9c00 << 16) | (0x913c >> 2),
3108c2ecf20Sopenharmony_ci	0x00000000,
3118c2ecf20Sopenharmony_ci	(0x8000 << 16) | (0x90e0 >> 2),
3128c2ecf20Sopenharmony_ci	0x00000000,
3138c2ecf20Sopenharmony_ci	(0x8000 << 16) | (0x90e4 >> 2),
3148c2ecf20Sopenharmony_ci	0x00000000,
3158c2ecf20Sopenharmony_ci	(0x8000 << 16) | (0x90e8 >> 2),
3168c2ecf20Sopenharmony_ci	0x00000000,
3178c2ecf20Sopenharmony_ci	(0x8040 << 16) | (0x90e0 >> 2),
3188c2ecf20Sopenharmony_ci	0x00000000,
3198c2ecf20Sopenharmony_ci	(0x8040 << 16) | (0x90e4 >> 2),
3208c2ecf20Sopenharmony_ci	0x00000000,
3218c2ecf20Sopenharmony_ci	(0x8040 << 16) | (0x90e8 >> 2),
3228c2ecf20Sopenharmony_ci	0x00000000,
3238c2ecf20Sopenharmony_ci	(0x9c00 << 16) | (0x8bcc >> 2),
3248c2ecf20Sopenharmony_ci	0x00000000,
3258c2ecf20Sopenharmony_ci	(0x9c00 << 16) | (0x8b24 >> 2),
3268c2ecf20Sopenharmony_ci	0x00000000,
3278c2ecf20Sopenharmony_ci	(0x9c00 << 16) | (0x88c4 >> 2),
3288c2ecf20Sopenharmony_ci	0x00000000,
3298c2ecf20Sopenharmony_ci	(0x9c00 << 16) | (0x8e50 >> 2),
3308c2ecf20Sopenharmony_ci	0x00000000,
3318c2ecf20Sopenharmony_ci	(0x9c00 << 16) | (0x8c0c >> 2),
3328c2ecf20Sopenharmony_ci	0x00000000,
3338c2ecf20Sopenharmony_ci	(0x9c00 << 16) | (0x8e58 >> 2),
3348c2ecf20Sopenharmony_ci	0x00000000,
3358c2ecf20Sopenharmony_ci	(0x9c00 << 16) | (0x8e5c >> 2),
3368c2ecf20Sopenharmony_ci	0x00000000,
3378c2ecf20Sopenharmony_ci	(0x9c00 << 16) | (0x9508 >> 2),
3388c2ecf20Sopenharmony_ci	0x00000000,
3398c2ecf20Sopenharmony_ci	(0x9c00 << 16) | (0x950c >> 2),
3408c2ecf20Sopenharmony_ci	0x00000000,
3418c2ecf20Sopenharmony_ci	(0x9c00 << 16) | (0x9494 >> 2),
3428c2ecf20Sopenharmony_ci	0x00000000,
3438c2ecf20Sopenharmony_ci	(0x9c00 << 16) | (0xac0c >> 2),
3448c2ecf20Sopenharmony_ci	0x00000000,
3458c2ecf20Sopenharmony_ci	(0x9c00 << 16) | (0xac10 >> 2),
3468c2ecf20Sopenharmony_ci	0x00000000,
3478c2ecf20Sopenharmony_ci	(0x9c00 << 16) | (0xac14 >> 2),
3488c2ecf20Sopenharmony_ci	0x00000000,
3498c2ecf20Sopenharmony_ci	(0x9c00 << 16) | (0xae00 >> 2),
3508c2ecf20Sopenharmony_ci	0x00000000,
3518c2ecf20Sopenharmony_ci	(0x9c00 << 16) | (0xac08 >> 2),
3528c2ecf20Sopenharmony_ci	0x00000000,
3538c2ecf20Sopenharmony_ci	(0x9c00 << 16) | (0x88d4 >> 2),
3548c2ecf20Sopenharmony_ci	0x00000000,
3558c2ecf20Sopenharmony_ci	(0x9c00 << 16) | (0x88c8 >> 2),
3568c2ecf20Sopenharmony_ci	0x00000000,
3578c2ecf20Sopenharmony_ci	(0x9c00 << 16) | (0x88cc >> 2),
3588c2ecf20Sopenharmony_ci	0x00000000,
3598c2ecf20Sopenharmony_ci	(0x9c00 << 16) | (0x89b0 >> 2),
3608c2ecf20Sopenharmony_ci	0x00000000,
3618c2ecf20Sopenharmony_ci	(0x9c00 << 16) | (0x8b10 >> 2),
3628c2ecf20Sopenharmony_ci	0x00000000,
3638c2ecf20Sopenharmony_ci	(0x9c00 << 16) | (0x8a14 >> 2),
3648c2ecf20Sopenharmony_ci	0x00000000,
3658c2ecf20Sopenharmony_ci	(0x9c00 << 16) | (0x9830 >> 2),
3668c2ecf20Sopenharmony_ci	0x00000000,
3678c2ecf20Sopenharmony_ci	(0x9c00 << 16) | (0x9834 >> 2),
3688c2ecf20Sopenharmony_ci	0x00000000,
3698c2ecf20Sopenharmony_ci	(0x9c00 << 16) | (0x9838 >> 2),
3708c2ecf20Sopenharmony_ci	0x00000000,
3718c2ecf20Sopenharmony_ci	(0x9c00 << 16) | (0x9a10 >> 2),
3728c2ecf20Sopenharmony_ci	0x00000000,
3738c2ecf20Sopenharmony_ci	(0x8000 << 16) | (0x9870 >> 2),
3748c2ecf20Sopenharmony_ci	0x00000000,
3758c2ecf20Sopenharmony_ci	(0x8000 << 16) | (0x9874 >> 2),
3768c2ecf20Sopenharmony_ci	0x00000000,
3778c2ecf20Sopenharmony_ci	(0x8001 << 16) | (0x9870 >> 2),
3788c2ecf20Sopenharmony_ci	0x00000000,
3798c2ecf20Sopenharmony_ci	(0x8001 << 16) | (0x9874 >> 2),
3808c2ecf20Sopenharmony_ci	0x00000000,
3818c2ecf20Sopenharmony_ci	(0x8040 << 16) | (0x9870 >> 2),
3828c2ecf20Sopenharmony_ci	0x00000000,
3838c2ecf20Sopenharmony_ci	(0x8040 << 16) | (0x9874 >> 2),
3848c2ecf20Sopenharmony_ci	0x00000000,
3858c2ecf20Sopenharmony_ci	(0x8041 << 16) | (0x9870 >> 2),
3868c2ecf20Sopenharmony_ci	0x00000000,
3878c2ecf20Sopenharmony_ci	(0x8041 << 16) | (0x9874 >> 2),
3888c2ecf20Sopenharmony_ci	0x00000000,
3898c2ecf20Sopenharmony_ci	0x00000000
3908c2ecf20Sopenharmony_ci};
3918c2ecf20Sopenharmony_ci
3928c2ecf20Sopenharmony_cistatic const u32 tahiti_golden_rlc_registers[] =
3938c2ecf20Sopenharmony_ci{
3948c2ecf20Sopenharmony_ci	0xc424, 0xffffffff, 0x00601005,
3958c2ecf20Sopenharmony_ci	0xc47c, 0xffffffff, 0x10104040,
3968c2ecf20Sopenharmony_ci	0xc488, 0xffffffff, 0x0100000a,
3978c2ecf20Sopenharmony_ci	0xc314, 0xffffffff, 0x00000800,
3988c2ecf20Sopenharmony_ci	0xc30c, 0xffffffff, 0x800000f4,
3998c2ecf20Sopenharmony_ci	0xf4a8, 0xffffffff, 0x00000000
4008c2ecf20Sopenharmony_ci};
4018c2ecf20Sopenharmony_ci
4028c2ecf20Sopenharmony_cistatic const u32 tahiti_golden_registers[] =
4038c2ecf20Sopenharmony_ci{
4048c2ecf20Sopenharmony_ci	0x9a10, 0x00010000, 0x00018208,
4058c2ecf20Sopenharmony_ci	0x9830, 0xffffffff, 0x00000000,
4068c2ecf20Sopenharmony_ci	0x9834, 0xf00fffff, 0x00000400,
4078c2ecf20Sopenharmony_ci	0x9838, 0x0002021c, 0x00020200,
4088c2ecf20Sopenharmony_ci	0xc78, 0x00000080, 0x00000000,
4098c2ecf20Sopenharmony_ci	0xd030, 0x000300c0, 0x00800040,
4108c2ecf20Sopenharmony_ci	0xd830, 0x000300c0, 0x00800040,
4118c2ecf20Sopenharmony_ci	0x5bb0, 0x000000f0, 0x00000070,
4128c2ecf20Sopenharmony_ci	0x5bc0, 0x00200000, 0x50100000,
4138c2ecf20Sopenharmony_ci	0x7030, 0x31000311, 0x00000011,
4148c2ecf20Sopenharmony_ci	0x277c, 0x00000003, 0x000007ff,
4158c2ecf20Sopenharmony_ci	0x240c, 0x000007ff, 0x00000000,
4168c2ecf20Sopenharmony_ci	0x8a14, 0xf000001f, 0x00000007,
4178c2ecf20Sopenharmony_ci	0x8b24, 0xffffffff, 0x00ffffff,
4188c2ecf20Sopenharmony_ci	0x8b10, 0x0000ff0f, 0x00000000,
4198c2ecf20Sopenharmony_ci	0x28a4c, 0x07ffffff, 0x4e000000,
4208c2ecf20Sopenharmony_ci	0x28350, 0x3f3f3fff, 0x2a00126a,
4218c2ecf20Sopenharmony_ci	0x30, 0x000000ff, 0x0040,
4228c2ecf20Sopenharmony_ci	0x34, 0x00000040, 0x00004040,
4238c2ecf20Sopenharmony_ci	0x9100, 0x07ffffff, 0x03000000,
4248c2ecf20Sopenharmony_ci	0x8e88, 0x01ff1f3f, 0x00000000,
4258c2ecf20Sopenharmony_ci	0x8e84, 0x01ff1f3f, 0x00000000,
4268c2ecf20Sopenharmony_ci	0x9060, 0x0000007f, 0x00000020,
4278c2ecf20Sopenharmony_ci	0x9508, 0x00010000, 0x00010000,
4288c2ecf20Sopenharmony_ci	0xac14, 0x00000200, 0x000002fb,
4298c2ecf20Sopenharmony_ci	0xac10, 0xffffffff, 0x0000543b,
4308c2ecf20Sopenharmony_ci	0xac0c, 0xffffffff, 0xa9210876,
4318c2ecf20Sopenharmony_ci	0x88d0, 0xffffffff, 0x000fff40,
4328c2ecf20Sopenharmony_ci	0x88d4, 0x0000001f, 0x00000010,
4338c2ecf20Sopenharmony_ci	0x1410, 0x20000000, 0x20fffed8,
4348c2ecf20Sopenharmony_ci	0x15c0, 0x000c0fc0, 0x000c0400
4358c2ecf20Sopenharmony_ci};
4368c2ecf20Sopenharmony_ci
4378c2ecf20Sopenharmony_cistatic const u32 tahiti_golden_registers2[] =
4388c2ecf20Sopenharmony_ci{
4398c2ecf20Sopenharmony_ci	0xc64, 0x00000001, 0x00000001
4408c2ecf20Sopenharmony_ci};
4418c2ecf20Sopenharmony_ci
4428c2ecf20Sopenharmony_cistatic const u32 pitcairn_golden_rlc_registers[] =
4438c2ecf20Sopenharmony_ci{
4448c2ecf20Sopenharmony_ci	0xc424, 0xffffffff, 0x00601004,
4458c2ecf20Sopenharmony_ci	0xc47c, 0xffffffff, 0x10102020,
4468c2ecf20Sopenharmony_ci	0xc488, 0xffffffff, 0x01000020,
4478c2ecf20Sopenharmony_ci	0xc314, 0xffffffff, 0x00000800,
4488c2ecf20Sopenharmony_ci	0xc30c, 0xffffffff, 0x800000a4
4498c2ecf20Sopenharmony_ci};
4508c2ecf20Sopenharmony_ci
4518c2ecf20Sopenharmony_cistatic const u32 pitcairn_golden_registers[] =
4528c2ecf20Sopenharmony_ci{
4538c2ecf20Sopenharmony_ci	0x9a10, 0x00010000, 0x00018208,
4548c2ecf20Sopenharmony_ci	0x9830, 0xffffffff, 0x00000000,
4558c2ecf20Sopenharmony_ci	0x9834, 0xf00fffff, 0x00000400,
4568c2ecf20Sopenharmony_ci	0x9838, 0x0002021c, 0x00020200,
4578c2ecf20Sopenharmony_ci	0xc78, 0x00000080, 0x00000000,
4588c2ecf20Sopenharmony_ci	0xd030, 0x000300c0, 0x00800040,
4598c2ecf20Sopenharmony_ci	0xd830, 0x000300c0, 0x00800040,
4608c2ecf20Sopenharmony_ci	0x5bb0, 0x000000f0, 0x00000070,
4618c2ecf20Sopenharmony_ci	0x5bc0, 0x00200000, 0x50100000,
4628c2ecf20Sopenharmony_ci	0x7030, 0x31000311, 0x00000011,
4638c2ecf20Sopenharmony_ci	0x2ae4, 0x00073ffe, 0x000022a2,
4648c2ecf20Sopenharmony_ci	0x240c, 0x000007ff, 0x00000000,
4658c2ecf20Sopenharmony_ci	0x8a14, 0xf000001f, 0x00000007,
4668c2ecf20Sopenharmony_ci	0x8b24, 0xffffffff, 0x00ffffff,
4678c2ecf20Sopenharmony_ci	0x8b10, 0x0000ff0f, 0x00000000,
4688c2ecf20Sopenharmony_ci	0x28a4c, 0x07ffffff, 0x4e000000,
4698c2ecf20Sopenharmony_ci	0x28350, 0x3f3f3fff, 0x2a00126a,
4708c2ecf20Sopenharmony_ci	0x30, 0x000000ff, 0x0040,
4718c2ecf20Sopenharmony_ci	0x34, 0x00000040, 0x00004040,
4728c2ecf20Sopenharmony_ci	0x9100, 0x07ffffff, 0x03000000,
4738c2ecf20Sopenharmony_ci	0x9060, 0x0000007f, 0x00000020,
4748c2ecf20Sopenharmony_ci	0x9508, 0x00010000, 0x00010000,
4758c2ecf20Sopenharmony_ci	0xac14, 0x000003ff, 0x000000f7,
4768c2ecf20Sopenharmony_ci	0xac10, 0xffffffff, 0x00000000,
4778c2ecf20Sopenharmony_ci	0xac0c, 0xffffffff, 0x32761054,
4788c2ecf20Sopenharmony_ci	0x88d4, 0x0000001f, 0x00000010,
4798c2ecf20Sopenharmony_ci	0x15c0, 0x000c0fc0, 0x000c0400
4808c2ecf20Sopenharmony_ci};
4818c2ecf20Sopenharmony_ci
4828c2ecf20Sopenharmony_cistatic const u32 verde_golden_rlc_registers[] =
4838c2ecf20Sopenharmony_ci{
4848c2ecf20Sopenharmony_ci	0xc424, 0xffffffff, 0x033f1005,
4858c2ecf20Sopenharmony_ci	0xc47c, 0xffffffff, 0x10808020,
4868c2ecf20Sopenharmony_ci	0xc488, 0xffffffff, 0x00800008,
4878c2ecf20Sopenharmony_ci	0xc314, 0xffffffff, 0x00001000,
4888c2ecf20Sopenharmony_ci	0xc30c, 0xffffffff, 0x80010014
4898c2ecf20Sopenharmony_ci};
4908c2ecf20Sopenharmony_ci
4918c2ecf20Sopenharmony_cistatic const u32 verde_golden_registers[] =
4928c2ecf20Sopenharmony_ci{
4938c2ecf20Sopenharmony_ci	0x9a10, 0x00010000, 0x00018208,
4948c2ecf20Sopenharmony_ci	0x9830, 0xffffffff, 0x00000000,
4958c2ecf20Sopenharmony_ci	0x9834, 0xf00fffff, 0x00000400,
4968c2ecf20Sopenharmony_ci	0x9838, 0x0002021c, 0x00020200,
4978c2ecf20Sopenharmony_ci	0xc78, 0x00000080, 0x00000000,
4988c2ecf20Sopenharmony_ci	0xd030, 0x000300c0, 0x00800040,
4998c2ecf20Sopenharmony_ci	0xd030, 0x000300c0, 0x00800040,
5008c2ecf20Sopenharmony_ci	0xd830, 0x000300c0, 0x00800040,
5018c2ecf20Sopenharmony_ci	0xd830, 0x000300c0, 0x00800040,
5028c2ecf20Sopenharmony_ci	0x5bb0, 0x000000f0, 0x00000070,
5038c2ecf20Sopenharmony_ci	0x5bc0, 0x00200000, 0x50100000,
5048c2ecf20Sopenharmony_ci	0x7030, 0x31000311, 0x00000011,
5058c2ecf20Sopenharmony_ci	0x2ae4, 0x00073ffe, 0x000022a2,
5068c2ecf20Sopenharmony_ci	0x2ae4, 0x00073ffe, 0x000022a2,
5078c2ecf20Sopenharmony_ci	0x2ae4, 0x00073ffe, 0x000022a2,
5088c2ecf20Sopenharmony_ci	0x240c, 0x000007ff, 0x00000000,
5098c2ecf20Sopenharmony_ci	0x240c, 0x000007ff, 0x00000000,
5108c2ecf20Sopenharmony_ci	0x240c, 0x000007ff, 0x00000000,
5118c2ecf20Sopenharmony_ci	0x8a14, 0xf000001f, 0x00000007,
5128c2ecf20Sopenharmony_ci	0x8a14, 0xf000001f, 0x00000007,
5138c2ecf20Sopenharmony_ci	0x8a14, 0xf000001f, 0x00000007,
5148c2ecf20Sopenharmony_ci	0x8b24, 0xffffffff, 0x00ffffff,
5158c2ecf20Sopenharmony_ci	0x8b10, 0x0000ff0f, 0x00000000,
5168c2ecf20Sopenharmony_ci	0x28a4c, 0x07ffffff, 0x4e000000,
5178c2ecf20Sopenharmony_ci	0x28350, 0x3f3f3fff, 0x0000124a,
5188c2ecf20Sopenharmony_ci	0x28350, 0x3f3f3fff, 0x0000124a,
5198c2ecf20Sopenharmony_ci	0x28350, 0x3f3f3fff, 0x0000124a,
5208c2ecf20Sopenharmony_ci	0x30, 0x000000ff, 0x0040,
5218c2ecf20Sopenharmony_ci	0x34, 0x00000040, 0x00004040,
5228c2ecf20Sopenharmony_ci	0x9100, 0x07ffffff, 0x03000000,
5238c2ecf20Sopenharmony_ci	0x9100, 0x07ffffff, 0x03000000,
5248c2ecf20Sopenharmony_ci	0x8e88, 0x01ff1f3f, 0x00000000,
5258c2ecf20Sopenharmony_ci	0x8e88, 0x01ff1f3f, 0x00000000,
5268c2ecf20Sopenharmony_ci	0x8e88, 0x01ff1f3f, 0x00000000,
5278c2ecf20Sopenharmony_ci	0x8e84, 0x01ff1f3f, 0x00000000,
5288c2ecf20Sopenharmony_ci	0x8e84, 0x01ff1f3f, 0x00000000,
5298c2ecf20Sopenharmony_ci	0x8e84, 0x01ff1f3f, 0x00000000,
5308c2ecf20Sopenharmony_ci	0x9060, 0x0000007f, 0x00000020,
5318c2ecf20Sopenharmony_ci	0x9508, 0x00010000, 0x00010000,
5328c2ecf20Sopenharmony_ci	0xac14, 0x000003ff, 0x00000003,
5338c2ecf20Sopenharmony_ci	0xac14, 0x000003ff, 0x00000003,
5348c2ecf20Sopenharmony_ci	0xac14, 0x000003ff, 0x00000003,
5358c2ecf20Sopenharmony_ci	0xac10, 0xffffffff, 0x00000000,
5368c2ecf20Sopenharmony_ci	0xac10, 0xffffffff, 0x00000000,
5378c2ecf20Sopenharmony_ci	0xac10, 0xffffffff, 0x00000000,
5388c2ecf20Sopenharmony_ci	0xac0c, 0xffffffff, 0x00001032,
5398c2ecf20Sopenharmony_ci	0xac0c, 0xffffffff, 0x00001032,
5408c2ecf20Sopenharmony_ci	0xac0c, 0xffffffff, 0x00001032,
5418c2ecf20Sopenharmony_ci	0x88d4, 0x0000001f, 0x00000010,
5428c2ecf20Sopenharmony_ci	0x88d4, 0x0000001f, 0x00000010,
5438c2ecf20Sopenharmony_ci	0x88d4, 0x0000001f, 0x00000010,
5448c2ecf20Sopenharmony_ci	0x15c0, 0x000c0fc0, 0x000c0400
5458c2ecf20Sopenharmony_ci};
5468c2ecf20Sopenharmony_ci
5478c2ecf20Sopenharmony_cistatic const u32 oland_golden_rlc_registers[] =
5488c2ecf20Sopenharmony_ci{
5498c2ecf20Sopenharmony_ci	0xc424, 0xffffffff, 0x00601005,
5508c2ecf20Sopenharmony_ci	0xc47c, 0xffffffff, 0x10104040,
5518c2ecf20Sopenharmony_ci	0xc488, 0xffffffff, 0x0100000a,
5528c2ecf20Sopenharmony_ci	0xc314, 0xffffffff, 0x00000800,
5538c2ecf20Sopenharmony_ci	0xc30c, 0xffffffff, 0x800000f4
5548c2ecf20Sopenharmony_ci};
5558c2ecf20Sopenharmony_ci
5568c2ecf20Sopenharmony_cistatic const u32 oland_golden_registers[] =
5578c2ecf20Sopenharmony_ci{
5588c2ecf20Sopenharmony_ci	0x9a10, 0x00010000, 0x00018208,
5598c2ecf20Sopenharmony_ci	0x9830, 0xffffffff, 0x00000000,
5608c2ecf20Sopenharmony_ci	0x9834, 0xf00fffff, 0x00000400,
5618c2ecf20Sopenharmony_ci	0x9838, 0x0002021c, 0x00020200,
5628c2ecf20Sopenharmony_ci	0xc78, 0x00000080, 0x00000000,
5638c2ecf20Sopenharmony_ci	0xd030, 0x000300c0, 0x00800040,
5648c2ecf20Sopenharmony_ci	0xd830, 0x000300c0, 0x00800040,
5658c2ecf20Sopenharmony_ci	0x5bb0, 0x000000f0, 0x00000070,
5668c2ecf20Sopenharmony_ci	0x5bc0, 0x00200000, 0x50100000,
5678c2ecf20Sopenharmony_ci	0x7030, 0x31000311, 0x00000011,
5688c2ecf20Sopenharmony_ci	0x2ae4, 0x00073ffe, 0x000022a2,
5698c2ecf20Sopenharmony_ci	0x240c, 0x000007ff, 0x00000000,
5708c2ecf20Sopenharmony_ci	0x8a14, 0xf000001f, 0x00000007,
5718c2ecf20Sopenharmony_ci	0x8b24, 0xffffffff, 0x00ffffff,
5728c2ecf20Sopenharmony_ci	0x8b10, 0x0000ff0f, 0x00000000,
5738c2ecf20Sopenharmony_ci	0x28a4c, 0x07ffffff, 0x4e000000,
5748c2ecf20Sopenharmony_ci	0x28350, 0x3f3f3fff, 0x00000082,
5758c2ecf20Sopenharmony_ci	0x30, 0x000000ff, 0x0040,
5768c2ecf20Sopenharmony_ci	0x34, 0x00000040, 0x00004040,
5778c2ecf20Sopenharmony_ci	0x9100, 0x07ffffff, 0x03000000,
5788c2ecf20Sopenharmony_ci	0x9060, 0x0000007f, 0x00000020,
5798c2ecf20Sopenharmony_ci	0x9508, 0x00010000, 0x00010000,
5808c2ecf20Sopenharmony_ci	0xac14, 0x000003ff, 0x000000f3,
5818c2ecf20Sopenharmony_ci	0xac10, 0xffffffff, 0x00000000,
5828c2ecf20Sopenharmony_ci	0xac0c, 0xffffffff, 0x00003210,
5838c2ecf20Sopenharmony_ci	0x88d4, 0x0000001f, 0x00000010,
5848c2ecf20Sopenharmony_ci	0x15c0, 0x000c0fc0, 0x000c0400
5858c2ecf20Sopenharmony_ci};
5868c2ecf20Sopenharmony_ci
5878c2ecf20Sopenharmony_cistatic const u32 hainan_golden_registers[] =
5888c2ecf20Sopenharmony_ci{
5898c2ecf20Sopenharmony_ci	0x9a10, 0x00010000, 0x00018208,
5908c2ecf20Sopenharmony_ci	0x9830, 0xffffffff, 0x00000000,
5918c2ecf20Sopenharmony_ci	0x9834, 0xf00fffff, 0x00000400,
5928c2ecf20Sopenharmony_ci	0x9838, 0x0002021c, 0x00020200,
5938c2ecf20Sopenharmony_ci	0xd0c0, 0xff000fff, 0x00000100,
5948c2ecf20Sopenharmony_ci	0xd030, 0x000300c0, 0x00800040,
5958c2ecf20Sopenharmony_ci	0xd8c0, 0xff000fff, 0x00000100,
5968c2ecf20Sopenharmony_ci	0xd830, 0x000300c0, 0x00800040,
5978c2ecf20Sopenharmony_ci	0x2ae4, 0x00073ffe, 0x000022a2,
5988c2ecf20Sopenharmony_ci	0x240c, 0x000007ff, 0x00000000,
5998c2ecf20Sopenharmony_ci	0x8a14, 0xf000001f, 0x00000007,
6008c2ecf20Sopenharmony_ci	0x8b24, 0xffffffff, 0x00ffffff,
6018c2ecf20Sopenharmony_ci	0x8b10, 0x0000ff0f, 0x00000000,
6028c2ecf20Sopenharmony_ci	0x28a4c, 0x07ffffff, 0x4e000000,
6038c2ecf20Sopenharmony_ci	0x28350, 0x3f3f3fff, 0x00000000,
6048c2ecf20Sopenharmony_ci	0x30, 0x000000ff, 0x0040,
6058c2ecf20Sopenharmony_ci	0x34, 0x00000040, 0x00004040,
6068c2ecf20Sopenharmony_ci	0x9100, 0x03e00000, 0x03600000,
6078c2ecf20Sopenharmony_ci	0x9060, 0x0000007f, 0x00000020,
6088c2ecf20Sopenharmony_ci	0x9508, 0x00010000, 0x00010000,
6098c2ecf20Sopenharmony_ci	0xac14, 0x000003ff, 0x000000f1,
6108c2ecf20Sopenharmony_ci	0xac10, 0xffffffff, 0x00000000,
6118c2ecf20Sopenharmony_ci	0xac0c, 0xffffffff, 0x00003210,
6128c2ecf20Sopenharmony_ci	0x88d4, 0x0000001f, 0x00000010,
6138c2ecf20Sopenharmony_ci	0x15c0, 0x000c0fc0, 0x000c0400
6148c2ecf20Sopenharmony_ci};
6158c2ecf20Sopenharmony_ci
6168c2ecf20Sopenharmony_cistatic const u32 hainan_golden_registers2[] =
6178c2ecf20Sopenharmony_ci{
6188c2ecf20Sopenharmony_ci	0x98f8, 0xffffffff, 0x02010001
6198c2ecf20Sopenharmony_ci};
6208c2ecf20Sopenharmony_ci
6218c2ecf20Sopenharmony_cistatic const u32 tahiti_mgcg_cgcg_init[] =
6228c2ecf20Sopenharmony_ci{
6238c2ecf20Sopenharmony_ci	0xc400, 0xffffffff, 0xfffffffc,
6248c2ecf20Sopenharmony_ci	0x802c, 0xffffffff, 0xe0000000,
6258c2ecf20Sopenharmony_ci	0x9a60, 0xffffffff, 0x00000100,
6268c2ecf20Sopenharmony_ci	0x92a4, 0xffffffff, 0x00000100,
6278c2ecf20Sopenharmony_ci	0xc164, 0xffffffff, 0x00000100,
6288c2ecf20Sopenharmony_ci	0x9774, 0xffffffff, 0x00000100,
6298c2ecf20Sopenharmony_ci	0x8984, 0xffffffff, 0x06000100,
6308c2ecf20Sopenharmony_ci	0x8a18, 0xffffffff, 0x00000100,
6318c2ecf20Sopenharmony_ci	0x92a0, 0xffffffff, 0x00000100,
6328c2ecf20Sopenharmony_ci	0xc380, 0xffffffff, 0x00000100,
6338c2ecf20Sopenharmony_ci	0x8b28, 0xffffffff, 0x00000100,
6348c2ecf20Sopenharmony_ci	0x9144, 0xffffffff, 0x00000100,
6358c2ecf20Sopenharmony_ci	0x8d88, 0xffffffff, 0x00000100,
6368c2ecf20Sopenharmony_ci	0x8d8c, 0xffffffff, 0x00000100,
6378c2ecf20Sopenharmony_ci	0x9030, 0xffffffff, 0x00000100,
6388c2ecf20Sopenharmony_ci	0x9034, 0xffffffff, 0x00000100,
6398c2ecf20Sopenharmony_ci	0x9038, 0xffffffff, 0x00000100,
6408c2ecf20Sopenharmony_ci	0x903c, 0xffffffff, 0x00000100,
6418c2ecf20Sopenharmony_ci	0xad80, 0xffffffff, 0x00000100,
6428c2ecf20Sopenharmony_ci	0xac54, 0xffffffff, 0x00000100,
6438c2ecf20Sopenharmony_ci	0x897c, 0xffffffff, 0x06000100,
6448c2ecf20Sopenharmony_ci	0x9868, 0xffffffff, 0x00000100,
6458c2ecf20Sopenharmony_ci	0x9510, 0xffffffff, 0x00000100,
6468c2ecf20Sopenharmony_ci	0xaf04, 0xffffffff, 0x00000100,
6478c2ecf20Sopenharmony_ci	0xae04, 0xffffffff, 0x00000100,
6488c2ecf20Sopenharmony_ci	0x949c, 0xffffffff, 0x00000100,
6498c2ecf20Sopenharmony_ci	0x802c, 0xffffffff, 0xe0000000,
6508c2ecf20Sopenharmony_ci	0x9160, 0xffffffff, 0x00010000,
6518c2ecf20Sopenharmony_ci	0x9164, 0xffffffff, 0x00030002,
6528c2ecf20Sopenharmony_ci	0x9168, 0xffffffff, 0x00040007,
6538c2ecf20Sopenharmony_ci	0x916c, 0xffffffff, 0x00060005,
6548c2ecf20Sopenharmony_ci	0x9170, 0xffffffff, 0x00090008,
6558c2ecf20Sopenharmony_ci	0x9174, 0xffffffff, 0x00020001,
6568c2ecf20Sopenharmony_ci	0x9178, 0xffffffff, 0x00040003,
6578c2ecf20Sopenharmony_ci	0x917c, 0xffffffff, 0x00000007,
6588c2ecf20Sopenharmony_ci	0x9180, 0xffffffff, 0x00060005,
6598c2ecf20Sopenharmony_ci	0x9184, 0xffffffff, 0x00090008,
6608c2ecf20Sopenharmony_ci	0x9188, 0xffffffff, 0x00030002,
6618c2ecf20Sopenharmony_ci	0x918c, 0xffffffff, 0x00050004,
6628c2ecf20Sopenharmony_ci	0x9190, 0xffffffff, 0x00000008,
6638c2ecf20Sopenharmony_ci	0x9194, 0xffffffff, 0x00070006,
6648c2ecf20Sopenharmony_ci	0x9198, 0xffffffff, 0x000a0009,
6658c2ecf20Sopenharmony_ci	0x919c, 0xffffffff, 0x00040003,
6668c2ecf20Sopenharmony_ci	0x91a0, 0xffffffff, 0x00060005,
6678c2ecf20Sopenharmony_ci	0x91a4, 0xffffffff, 0x00000009,
6688c2ecf20Sopenharmony_ci	0x91a8, 0xffffffff, 0x00080007,
6698c2ecf20Sopenharmony_ci	0x91ac, 0xffffffff, 0x000b000a,
6708c2ecf20Sopenharmony_ci	0x91b0, 0xffffffff, 0x00050004,
6718c2ecf20Sopenharmony_ci	0x91b4, 0xffffffff, 0x00070006,
6728c2ecf20Sopenharmony_ci	0x91b8, 0xffffffff, 0x0008000b,
6738c2ecf20Sopenharmony_ci	0x91bc, 0xffffffff, 0x000a0009,
6748c2ecf20Sopenharmony_ci	0x91c0, 0xffffffff, 0x000d000c,
6758c2ecf20Sopenharmony_ci	0x91c4, 0xffffffff, 0x00060005,
6768c2ecf20Sopenharmony_ci	0x91c8, 0xffffffff, 0x00080007,
6778c2ecf20Sopenharmony_ci	0x91cc, 0xffffffff, 0x0000000b,
6788c2ecf20Sopenharmony_ci	0x91d0, 0xffffffff, 0x000a0009,
6798c2ecf20Sopenharmony_ci	0x91d4, 0xffffffff, 0x000d000c,
6808c2ecf20Sopenharmony_ci	0x91d8, 0xffffffff, 0x00070006,
6818c2ecf20Sopenharmony_ci	0x91dc, 0xffffffff, 0x00090008,
6828c2ecf20Sopenharmony_ci	0x91e0, 0xffffffff, 0x0000000c,
6838c2ecf20Sopenharmony_ci	0x91e4, 0xffffffff, 0x000b000a,
6848c2ecf20Sopenharmony_ci	0x91e8, 0xffffffff, 0x000e000d,
6858c2ecf20Sopenharmony_ci	0x91ec, 0xffffffff, 0x00080007,
6868c2ecf20Sopenharmony_ci	0x91f0, 0xffffffff, 0x000a0009,
6878c2ecf20Sopenharmony_ci	0x91f4, 0xffffffff, 0x0000000d,
6888c2ecf20Sopenharmony_ci	0x91f8, 0xffffffff, 0x000c000b,
6898c2ecf20Sopenharmony_ci	0x91fc, 0xffffffff, 0x000f000e,
6908c2ecf20Sopenharmony_ci	0x9200, 0xffffffff, 0x00090008,
6918c2ecf20Sopenharmony_ci	0x9204, 0xffffffff, 0x000b000a,
6928c2ecf20Sopenharmony_ci	0x9208, 0xffffffff, 0x000c000f,
6938c2ecf20Sopenharmony_ci	0x920c, 0xffffffff, 0x000e000d,
6948c2ecf20Sopenharmony_ci	0x9210, 0xffffffff, 0x00110010,
6958c2ecf20Sopenharmony_ci	0x9214, 0xffffffff, 0x000a0009,
6968c2ecf20Sopenharmony_ci	0x9218, 0xffffffff, 0x000c000b,
6978c2ecf20Sopenharmony_ci	0x921c, 0xffffffff, 0x0000000f,
6988c2ecf20Sopenharmony_ci	0x9220, 0xffffffff, 0x000e000d,
6998c2ecf20Sopenharmony_ci	0x9224, 0xffffffff, 0x00110010,
7008c2ecf20Sopenharmony_ci	0x9228, 0xffffffff, 0x000b000a,
7018c2ecf20Sopenharmony_ci	0x922c, 0xffffffff, 0x000d000c,
7028c2ecf20Sopenharmony_ci	0x9230, 0xffffffff, 0x00000010,
7038c2ecf20Sopenharmony_ci	0x9234, 0xffffffff, 0x000f000e,
7048c2ecf20Sopenharmony_ci	0x9238, 0xffffffff, 0x00120011,
7058c2ecf20Sopenharmony_ci	0x923c, 0xffffffff, 0x000c000b,
7068c2ecf20Sopenharmony_ci	0x9240, 0xffffffff, 0x000e000d,
7078c2ecf20Sopenharmony_ci	0x9244, 0xffffffff, 0x00000011,
7088c2ecf20Sopenharmony_ci	0x9248, 0xffffffff, 0x0010000f,
7098c2ecf20Sopenharmony_ci	0x924c, 0xffffffff, 0x00130012,
7108c2ecf20Sopenharmony_ci	0x9250, 0xffffffff, 0x000d000c,
7118c2ecf20Sopenharmony_ci	0x9254, 0xffffffff, 0x000f000e,
7128c2ecf20Sopenharmony_ci	0x9258, 0xffffffff, 0x00100013,
7138c2ecf20Sopenharmony_ci	0x925c, 0xffffffff, 0x00120011,
7148c2ecf20Sopenharmony_ci	0x9260, 0xffffffff, 0x00150014,
7158c2ecf20Sopenharmony_ci	0x9264, 0xffffffff, 0x000e000d,
7168c2ecf20Sopenharmony_ci	0x9268, 0xffffffff, 0x0010000f,
7178c2ecf20Sopenharmony_ci	0x926c, 0xffffffff, 0x00000013,
7188c2ecf20Sopenharmony_ci	0x9270, 0xffffffff, 0x00120011,
7198c2ecf20Sopenharmony_ci	0x9274, 0xffffffff, 0x00150014,
7208c2ecf20Sopenharmony_ci	0x9278, 0xffffffff, 0x000f000e,
7218c2ecf20Sopenharmony_ci	0x927c, 0xffffffff, 0x00110010,
7228c2ecf20Sopenharmony_ci	0x9280, 0xffffffff, 0x00000014,
7238c2ecf20Sopenharmony_ci	0x9284, 0xffffffff, 0x00130012,
7248c2ecf20Sopenharmony_ci	0x9288, 0xffffffff, 0x00160015,
7258c2ecf20Sopenharmony_ci	0x928c, 0xffffffff, 0x0010000f,
7268c2ecf20Sopenharmony_ci	0x9290, 0xffffffff, 0x00120011,
7278c2ecf20Sopenharmony_ci	0x9294, 0xffffffff, 0x00000015,
7288c2ecf20Sopenharmony_ci	0x9298, 0xffffffff, 0x00140013,
7298c2ecf20Sopenharmony_ci	0x929c, 0xffffffff, 0x00170016,
7308c2ecf20Sopenharmony_ci	0x9150, 0xffffffff, 0x96940200,
7318c2ecf20Sopenharmony_ci	0x8708, 0xffffffff, 0x00900100,
7328c2ecf20Sopenharmony_ci	0xc478, 0xffffffff, 0x00000080,
7338c2ecf20Sopenharmony_ci	0xc404, 0xffffffff, 0x0020003f,
7348c2ecf20Sopenharmony_ci	0x30, 0xffffffff, 0x0000001c,
7358c2ecf20Sopenharmony_ci	0x34, 0x000f0000, 0x000f0000,
7368c2ecf20Sopenharmony_ci	0x160c, 0xffffffff, 0x00000100,
7378c2ecf20Sopenharmony_ci	0x1024, 0xffffffff, 0x00000100,
7388c2ecf20Sopenharmony_ci	0x102c, 0x00000101, 0x00000000,
7398c2ecf20Sopenharmony_ci	0x20a8, 0xffffffff, 0x00000104,
7408c2ecf20Sopenharmony_ci	0x264c, 0x000c0000, 0x000c0000,
7418c2ecf20Sopenharmony_ci	0x2648, 0x000c0000, 0x000c0000,
7428c2ecf20Sopenharmony_ci	0x55e4, 0xff000fff, 0x00000100,
7438c2ecf20Sopenharmony_ci	0x55e8, 0x00000001, 0x00000001,
7448c2ecf20Sopenharmony_ci	0x2f50, 0x00000001, 0x00000001,
7458c2ecf20Sopenharmony_ci	0x30cc, 0xc0000fff, 0x00000104,
7468c2ecf20Sopenharmony_ci	0xc1e4, 0x00000001, 0x00000001,
7478c2ecf20Sopenharmony_ci	0xd0c0, 0xfffffff0, 0x00000100,
7488c2ecf20Sopenharmony_ci	0xd8c0, 0xfffffff0, 0x00000100
7498c2ecf20Sopenharmony_ci};
7508c2ecf20Sopenharmony_ci
7518c2ecf20Sopenharmony_cistatic const u32 pitcairn_mgcg_cgcg_init[] =
7528c2ecf20Sopenharmony_ci{
7538c2ecf20Sopenharmony_ci	0xc400, 0xffffffff, 0xfffffffc,
7548c2ecf20Sopenharmony_ci	0x802c, 0xffffffff, 0xe0000000,
7558c2ecf20Sopenharmony_ci	0x9a60, 0xffffffff, 0x00000100,
7568c2ecf20Sopenharmony_ci	0x92a4, 0xffffffff, 0x00000100,
7578c2ecf20Sopenharmony_ci	0xc164, 0xffffffff, 0x00000100,
7588c2ecf20Sopenharmony_ci	0x9774, 0xffffffff, 0x00000100,
7598c2ecf20Sopenharmony_ci	0x8984, 0xffffffff, 0x06000100,
7608c2ecf20Sopenharmony_ci	0x8a18, 0xffffffff, 0x00000100,
7618c2ecf20Sopenharmony_ci	0x92a0, 0xffffffff, 0x00000100,
7628c2ecf20Sopenharmony_ci	0xc380, 0xffffffff, 0x00000100,
7638c2ecf20Sopenharmony_ci	0x8b28, 0xffffffff, 0x00000100,
7648c2ecf20Sopenharmony_ci	0x9144, 0xffffffff, 0x00000100,
7658c2ecf20Sopenharmony_ci	0x8d88, 0xffffffff, 0x00000100,
7668c2ecf20Sopenharmony_ci	0x8d8c, 0xffffffff, 0x00000100,
7678c2ecf20Sopenharmony_ci	0x9030, 0xffffffff, 0x00000100,
7688c2ecf20Sopenharmony_ci	0x9034, 0xffffffff, 0x00000100,
7698c2ecf20Sopenharmony_ci	0x9038, 0xffffffff, 0x00000100,
7708c2ecf20Sopenharmony_ci	0x903c, 0xffffffff, 0x00000100,
7718c2ecf20Sopenharmony_ci	0xad80, 0xffffffff, 0x00000100,
7728c2ecf20Sopenharmony_ci	0xac54, 0xffffffff, 0x00000100,
7738c2ecf20Sopenharmony_ci	0x897c, 0xffffffff, 0x06000100,
7748c2ecf20Sopenharmony_ci	0x9868, 0xffffffff, 0x00000100,
7758c2ecf20Sopenharmony_ci	0x9510, 0xffffffff, 0x00000100,
7768c2ecf20Sopenharmony_ci	0xaf04, 0xffffffff, 0x00000100,
7778c2ecf20Sopenharmony_ci	0xae04, 0xffffffff, 0x00000100,
7788c2ecf20Sopenharmony_ci	0x949c, 0xffffffff, 0x00000100,
7798c2ecf20Sopenharmony_ci	0x802c, 0xffffffff, 0xe0000000,
7808c2ecf20Sopenharmony_ci	0x9160, 0xffffffff, 0x00010000,
7818c2ecf20Sopenharmony_ci	0x9164, 0xffffffff, 0x00030002,
7828c2ecf20Sopenharmony_ci	0x9168, 0xffffffff, 0x00040007,
7838c2ecf20Sopenharmony_ci	0x916c, 0xffffffff, 0x00060005,
7848c2ecf20Sopenharmony_ci	0x9170, 0xffffffff, 0x00090008,
7858c2ecf20Sopenharmony_ci	0x9174, 0xffffffff, 0x00020001,
7868c2ecf20Sopenharmony_ci	0x9178, 0xffffffff, 0x00040003,
7878c2ecf20Sopenharmony_ci	0x917c, 0xffffffff, 0x00000007,
7888c2ecf20Sopenharmony_ci	0x9180, 0xffffffff, 0x00060005,
7898c2ecf20Sopenharmony_ci	0x9184, 0xffffffff, 0x00090008,
7908c2ecf20Sopenharmony_ci	0x9188, 0xffffffff, 0x00030002,
7918c2ecf20Sopenharmony_ci	0x918c, 0xffffffff, 0x00050004,
7928c2ecf20Sopenharmony_ci	0x9190, 0xffffffff, 0x00000008,
7938c2ecf20Sopenharmony_ci	0x9194, 0xffffffff, 0x00070006,
7948c2ecf20Sopenharmony_ci	0x9198, 0xffffffff, 0x000a0009,
7958c2ecf20Sopenharmony_ci	0x919c, 0xffffffff, 0x00040003,
7968c2ecf20Sopenharmony_ci	0x91a0, 0xffffffff, 0x00060005,
7978c2ecf20Sopenharmony_ci	0x91a4, 0xffffffff, 0x00000009,
7988c2ecf20Sopenharmony_ci	0x91a8, 0xffffffff, 0x00080007,
7998c2ecf20Sopenharmony_ci	0x91ac, 0xffffffff, 0x000b000a,
8008c2ecf20Sopenharmony_ci	0x91b0, 0xffffffff, 0x00050004,
8018c2ecf20Sopenharmony_ci	0x91b4, 0xffffffff, 0x00070006,
8028c2ecf20Sopenharmony_ci	0x91b8, 0xffffffff, 0x0008000b,
8038c2ecf20Sopenharmony_ci	0x91bc, 0xffffffff, 0x000a0009,
8048c2ecf20Sopenharmony_ci	0x91c0, 0xffffffff, 0x000d000c,
8058c2ecf20Sopenharmony_ci	0x9200, 0xffffffff, 0x00090008,
8068c2ecf20Sopenharmony_ci	0x9204, 0xffffffff, 0x000b000a,
8078c2ecf20Sopenharmony_ci	0x9208, 0xffffffff, 0x000c000f,
8088c2ecf20Sopenharmony_ci	0x920c, 0xffffffff, 0x000e000d,
8098c2ecf20Sopenharmony_ci	0x9210, 0xffffffff, 0x00110010,
8108c2ecf20Sopenharmony_ci	0x9214, 0xffffffff, 0x000a0009,
8118c2ecf20Sopenharmony_ci	0x9218, 0xffffffff, 0x000c000b,
8128c2ecf20Sopenharmony_ci	0x921c, 0xffffffff, 0x0000000f,
8138c2ecf20Sopenharmony_ci	0x9220, 0xffffffff, 0x000e000d,
8148c2ecf20Sopenharmony_ci	0x9224, 0xffffffff, 0x00110010,
8158c2ecf20Sopenharmony_ci	0x9228, 0xffffffff, 0x000b000a,
8168c2ecf20Sopenharmony_ci	0x922c, 0xffffffff, 0x000d000c,
8178c2ecf20Sopenharmony_ci	0x9230, 0xffffffff, 0x00000010,
8188c2ecf20Sopenharmony_ci	0x9234, 0xffffffff, 0x000f000e,
8198c2ecf20Sopenharmony_ci	0x9238, 0xffffffff, 0x00120011,
8208c2ecf20Sopenharmony_ci	0x923c, 0xffffffff, 0x000c000b,
8218c2ecf20Sopenharmony_ci	0x9240, 0xffffffff, 0x000e000d,
8228c2ecf20Sopenharmony_ci	0x9244, 0xffffffff, 0x00000011,
8238c2ecf20Sopenharmony_ci	0x9248, 0xffffffff, 0x0010000f,
8248c2ecf20Sopenharmony_ci	0x924c, 0xffffffff, 0x00130012,
8258c2ecf20Sopenharmony_ci	0x9250, 0xffffffff, 0x000d000c,
8268c2ecf20Sopenharmony_ci	0x9254, 0xffffffff, 0x000f000e,
8278c2ecf20Sopenharmony_ci	0x9258, 0xffffffff, 0x00100013,
8288c2ecf20Sopenharmony_ci	0x925c, 0xffffffff, 0x00120011,
8298c2ecf20Sopenharmony_ci	0x9260, 0xffffffff, 0x00150014,
8308c2ecf20Sopenharmony_ci	0x9150, 0xffffffff, 0x96940200,
8318c2ecf20Sopenharmony_ci	0x8708, 0xffffffff, 0x00900100,
8328c2ecf20Sopenharmony_ci	0xc478, 0xffffffff, 0x00000080,
8338c2ecf20Sopenharmony_ci	0xc404, 0xffffffff, 0x0020003f,
8348c2ecf20Sopenharmony_ci	0x30, 0xffffffff, 0x0000001c,
8358c2ecf20Sopenharmony_ci	0x34, 0x000f0000, 0x000f0000,
8368c2ecf20Sopenharmony_ci	0x160c, 0xffffffff, 0x00000100,
8378c2ecf20Sopenharmony_ci	0x1024, 0xffffffff, 0x00000100,
8388c2ecf20Sopenharmony_ci	0x102c, 0x00000101, 0x00000000,
8398c2ecf20Sopenharmony_ci	0x20a8, 0xffffffff, 0x00000104,
8408c2ecf20Sopenharmony_ci	0x55e4, 0xff000fff, 0x00000100,
8418c2ecf20Sopenharmony_ci	0x55e8, 0x00000001, 0x00000001,
8428c2ecf20Sopenharmony_ci	0x2f50, 0x00000001, 0x00000001,
8438c2ecf20Sopenharmony_ci	0x30cc, 0xc0000fff, 0x00000104,
8448c2ecf20Sopenharmony_ci	0xc1e4, 0x00000001, 0x00000001,
8458c2ecf20Sopenharmony_ci	0xd0c0, 0xfffffff0, 0x00000100,
8468c2ecf20Sopenharmony_ci	0xd8c0, 0xfffffff0, 0x00000100
8478c2ecf20Sopenharmony_ci};
8488c2ecf20Sopenharmony_ci
8498c2ecf20Sopenharmony_cistatic const u32 verde_mgcg_cgcg_init[] =
8508c2ecf20Sopenharmony_ci{
8518c2ecf20Sopenharmony_ci	0xc400, 0xffffffff, 0xfffffffc,
8528c2ecf20Sopenharmony_ci	0x802c, 0xffffffff, 0xe0000000,
8538c2ecf20Sopenharmony_ci	0x9a60, 0xffffffff, 0x00000100,
8548c2ecf20Sopenharmony_ci	0x92a4, 0xffffffff, 0x00000100,
8558c2ecf20Sopenharmony_ci	0xc164, 0xffffffff, 0x00000100,
8568c2ecf20Sopenharmony_ci	0x9774, 0xffffffff, 0x00000100,
8578c2ecf20Sopenharmony_ci	0x8984, 0xffffffff, 0x06000100,
8588c2ecf20Sopenharmony_ci	0x8a18, 0xffffffff, 0x00000100,
8598c2ecf20Sopenharmony_ci	0x92a0, 0xffffffff, 0x00000100,
8608c2ecf20Sopenharmony_ci	0xc380, 0xffffffff, 0x00000100,
8618c2ecf20Sopenharmony_ci	0x8b28, 0xffffffff, 0x00000100,
8628c2ecf20Sopenharmony_ci	0x9144, 0xffffffff, 0x00000100,
8638c2ecf20Sopenharmony_ci	0x8d88, 0xffffffff, 0x00000100,
8648c2ecf20Sopenharmony_ci	0x8d8c, 0xffffffff, 0x00000100,
8658c2ecf20Sopenharmony_ci	0x9030, 0xffffffff, 0x00000100,
8668c2ecf20Sopenharmony_ci	0x9034, 0xffffffff, 0x00000100,
8678c2ecf20Sopenharmony_ci	0x9038, 0xffffffff, 0x00000100,
8688c2ecf20Sopenharmony_ci	0x903c, 0xffffffff, 0x00000100,
8698c2ecf20Sopenharmony_ci	0xad80, 0xffffffff, 0x00000100,
8708c2ecf20Sopenharmony_ci	0xac54, 0xffffffff, 0x00000100,
8718c2ecf20Sopenharmony_ci	0x897c, 0xffffffff, 0x06000100,
8728c2ecf20Sopenharmony_ci	0x9868, 0xffffffff, 0x00000100,
8738c2ecf20Sopenharmony_ci	0x9510, 0xffffffff, 0x00000100,
8748c2ecf20Sopenharmony_ci	0xaf04, 0xffffffff, 0x00000100,
8758c2ecf20Sopenharmony_ci	0xae04, 0xffffffff, 0x00000100,
8768c2ecf20Sopenharmony_ci	0x949c, 0xffffffff, 0x00000100,
8778c2ecf20Sopenharmony_ci	0x802c, 0xffffffff, 0xe0000000,
8788c2ecf20Sopenharmony_ci	0x9160, 0xffffffff, 0x00010000,
8798c2ecf20Sopenharmony_ci	0x9164, 0xffffffff, 0x00030002,
8808c2ecf20Sopenharmony_ci	0x9168, 0xffffffff, 0x00040007,
8818c2ecf20Sopenharmony_ci	0x916c, 0xffffffff, 0x00060005,
8828c2ecf20Sopenharmony_ci	0x9170, 0xffffffff, 0x00090008,
8838c2ecf20Sopenharmony_ci	0x9174, 0xffffffff, 0x00020001,
8848c2ecf20Sopenharmony_ci	0x9178, 0xffffffff, 0x00040003,
8858c2ecf20Sopenharmony_ci	0x917c, 0xffffffff, 0x00000007,
8868c2ecf20Sopenharmony_ci	0x9180, 0xffffffff, 0x00060005,
8878c2ecf20Sopenharmony_ci	0x9184, 0xffffffff, 0x00090008,
8888c2ecf20Sopenharmony_ci	0x9188, 0xffffffff, 0x00030002,
8898c2ecf20Sopenharmony_ci	0x918c, 0xffffffff, 0x00050004,
8908c2ecf20Sopenharmony_ci	0x9190, 0xffffffff, 0x00000008,
8918c2ecf20Sopenharmony_ci	0x9194, 0xffffffff, 0x00070006,
8928c2ecf20Sopenharmony_ci	0x9198, 0xffffffff, 0x000a0009,
8938c2ecf20Sopenharmony_ci	0x919c, 0xffffffff, 0x00040003,
8948c2ecf20Sopenharmony_ci	0x91a0, 0xffffffff, 0x00060005,
8958c2ecf20Sopenharmony_ci	0x91a4, 0xffffffff, 0x00000009,
8968c2ecf20Sopenharmony_ci	0x91a8, 0xffffffff, 0x00080007,
8978c2ecf20Sopenharmony_ci	0x91ac, 0xffffffff, 0x000b000a,
8988c2ecf20Sopenharmony_ci	0x91b0, 0xffffffff, 0x00050004,
8998c2ecf20Sopenharmony_ci	0x91b4, 0xffffffff, 0x00070006,
9008c2ecf20Sopenharmony_ci	0x91b8, 0xffffffff, 0x0008000b,
9018c2ecf20Sopenharmony_ci	0x91bc, 0xffffffff, 0x000a0009,
9028c2ecf20Sopenharmony_ci	0x91c0, 0xffffffff, 0x000d000c,
9038c2ecf20Sopenharmony_ci	0x9200, 0xffffffff, 0x00090008,
9048c2ecf20Sopenharmony_ci	0x9204, 0xffffffff, 0x000b000a,
9058c2ecf20Sopenharmony_ci	0x9208, 0xffffffff, 0x000c000f,
9068c2ecf20Sopenharmony_ci	0x920c, 0xffffffff, 0x000e000d,
9078c2ecf20Sopenharmony_ci	0x9210, 0xffffffff, 0x00110010,
9088c2ecf20Sopenharmony_ci	0x9214, 0xffffffff, 0x000a0009,
9098c2ecf20Sopenharmony_ci	0x9218, 0xffffffff, 0x000c000b,
9108c2ecf20Sopenharmony_ci	0x921c, 0xffffffff, 0x0000000f,
9118c2ecf20Sopenharmony_ci	0x9220, 0xffffffff, 0x000e000d,
9128c2ecf20Sopenharmony_ci	0x9224, 0xffffffff, 0x00110010,
9138c2ecf20Sopenharmony_ci	0x9228, 0xffffffff, 0x000b000a,
9148c2ecf20Sopenharmony_ci	0x922c, 0xffffffff, 0x000d000c,
9158c2ecf20Sopenharmony_ci	0x9230, 0xffffffff, 0x00000010,
9168c2ecf20Sopenharmony_ci	0x9234, 0xffffffff, 0x000f000e,
9178c2ecf20Sopenharmony_ci	0x9238, 0xffffffff, 0x00120011,
9188c2ecf20Sopenharmony_ci	0x923c, 0xffffffff, 0x000c000b,
9198c2ecf20Sopenharmony_ci	0x9240, 0xffffffff, 0x000e000d,
9208c2ecf20Sopenharmony_ci	0x9244, 0xffffffff, 0x00000011,
9218c2ecf20Sopenharmony_ci	0x9248, 0xffffffff, 0x0010000f,
9228c2ecf20Sopenharmony_ci	0x924c, 0xffffffff, 0x00130012,
9238c2ecf20Sopenharmony_ci	0x9250, 0xffffffff, 0x000d000c,
9248c2ecf20Sopenharmony_ci	0x9254, 0xffffffff, 0x000f000e,
9258c2ecf20Sopenharmony_ci	0x9258, 0xffffffff, 0x00100013,
9268c2ecf20Sopenharmony_ci	0x925c, 0xffffffff, 0x00120011,
9278c2ecf20Sopenharmony_ci	0x9260, 0xffffffff, 0x00150014,
9288c2ecf20Sopenharmony_ci	0x9150, 0xffffffff, 0x96940200,
9298c2ecf20Sopenharmony_ci	0x8708, 0xffffffff, 0x00900100,
9308c2ecf20Sopenharmony_ci	0xc478, 0xffffffff, 0x00000080,
9318c2ecf20Sopenharmony_ci	0xc404, 0xffffffff, 0x0020003f,
9328c2ecf20Sopenharmony_ci	0x30, 0xffffffff, 0x0000001c,
9338c2ecf20Sopenharmony_ci	0x34, 0x000f0000, 0x000f0000,
9348c2ecf20Sopenharmony_ci	0x160c, 0xffffffff, 0x00000100,
9358c2ecf20Sopenharmony_ci	0x1024, 0xffffffff, 0x00000100,
9368c2ecf20Sopenharmony_ci	0x102c, 0x00000101, 0x00000000,
9378c2ecf20Sopenharmony_ci	0x20a8, 0xffffffff, 0x00000104,
9388c2ecf20Sopenharmony_ci	0x264c, 0x000c0000, 0x000c0000,
9398c2ecf20Sopenharmony_ci	0x2648, 0x000c0000, 0x000c0000,
9408c2ecf20Sopenharmony_ci	0x55e4, 0xff000fff, 0x00000100,
9418c2ecf20Sopenharmony_ci	0x55e8, 0x00000001, 0x00000001,
9428c2ecf20Sopenharmony_ci	0x2f50, 0x00000001, 0x00000001,
9438c2ecf20Sopenharmony_ci	0x30cc, 0xc0000fff, 0x00000104,
9448c2ecf20Sopenharmony_ci	0xc1e4, 0x00000001, 0x00000001,
9458c2ecf20Sopenharmony_ci	0xd0c0, 0xfffffff0, 0x00000100,
9468c2ecf20Sopenharmony_ci	0xd8c0, 0xfffffff0, 0x00000100
9478c2ecf20Sopenharmony_ci};
9488c2ecf20Sopenharmony_ci
9498c2ecf20Sopenharmony_cistatic const u32 oland_mgcg_cgcg_init[] =
9508c2ecf20Sopenharmony_ci{
9518c2ecf20Sopenharmony_ci	0xc400, 0xffffffff, 0xfffffffc,
9528c2ecf20Sopenharmony_ci	0x802c, 0xffffffff, 0xe0000000,
9538c2ecf20Sopenharmony_ci	0x9a60, 0xffffffff, 0x00000100,
9548c2ecf20Sopenharmony_ci	0x92a4, 0xffffffff, 0x00000100,
9558c2ecf20Sopenharmony_ci	0xc164, 0xffffffff, 0x00000100,
9568c2ecf20Sopenharmony_ci	0x9774, 0xffffffff, 0x00000100,
9578c2ecf20Sopenharmony_ci	0x8984, 0xffffffff, 0x06000100,
9588c2ecf20Sopenharmony_ci	0x8a18, 0xffffffff, 0x00000100,
9598c2ecf20Sopenharmony_ci	0x92a0, 0xffffffff, 0x00000100,
9608c2ecf20Sopenharmony_ci	0xc380, 0xffffffff, 0x00000100,
9618c2ecf20Sopenharmony_ci	0x8b28, 0xffffffff, 0x00000100,
9628c2ecf20Sopenharmony_ci	0x9144, 0xffffffff, 0x00000100,
9638c2ecf20Sopenharmony_ci	0x8d88, 0xffffffff, 0x00000100,
9648c2ecf20Sopenharmony_ci	0x8d8c, 0xffffffff, 0x00000100,
9658c2ecf20Sopenharmony_ci	0x9030, 0xffffffff, 0x00000100,
9668c2ecf20Sopenharmony_ci	0x9034, 0xffffffff, 0x00000100,
9678c2ecf20Sopenharmony_ci	0x9038, 0xffffffff, 0x00000100,
9688c2ecf20Sopenharmony_ci	0x903c, 0xffffffff, 0x00000100,
9698c2ecf20Sopenharmony_ci	0xad80, 0xffffffff, 0x00000100,
9708c2ecf20Sopenharmony_ci	0xac54, 0xffffffff, 0x00000100,
9718c2ecf20Sopenharmony_ci	0x897c, 0xffffffff, 0x06000100,
9728c2ecf20Sopenharmony_ci	0x9868, 0xffffffff, 0x00000100,
9738c2ecf20Sopenharmony_ci	0x9510, 0xffffffff, 0x00000100,
9748c2ecf20Sopenharmony_ci	0xaf04, 0xffffffff, 0x00000100,
9758c2ecf20Sopenharmony_ci	0xae04, 0xffffffff, 0x00000100,
9768c2ecf20Sopenharmony_ci	0x949c, 0xffffffff, 0x00000100,
9778c2ecf20Sopenharmony_ci	0x802c, 0xffffffff, 0xe0000000,
9788c2ecf20Sopenharmony_ci	0x9160, 0xffffffff, 0x00010000,
9798c2ecf20Sopenharmony_ci	0x9164, 0xffffffff, 0x00030002,
9808c2ecf20Sopenharmony_ci	0x9168, 0xffffffff, 0x00040007,
9818c2ecf20Sopenharmony_ci	0x916c, 0xffffffff, 0x00060005,
9828c2ecf20Sopenharmony_ci	0x9170, 0xffffffff, 0x00090008,
9838c2ecf20Sopenharmony_ci	0x9174, 0xffffffff, 0x00020001,
9848c2ecf20Sopenharmony_ci	0x9178, 0xffffffff, 0x00040003,
9858c2ecf20Sopenharmony_ci	0x917c, 0xffffffff, 0x00000007,
9868c2ecf20Sopenharmony_ci	0x9180, 0xffffffff, 0x00060005,
9878c2ecf20Sopenharmony_ci	0x9184, 0xffffffff, 0x00090008,
9888c2ecf20Sopenharmony_ci	0x9188, 0xffffffff, 0x00030002,
9898c2ecf20Sopenharmony_ci	0x918c, 0xffffffff, 0x00050004,
9908c2ecf20Sopenharmony_ci	0x9190, 0xffffffff, 0x00000008,
9918c2ecf20Sopenharmony_ci	0x9194, 0xffffffff, 0x00070006,
9928c2ecf20Sopenharmony_ci	0x9198, 0xffffffff, 0x000a0009,
9938c2ecf20Sopenharmony_ci	0x919c, 0xffffffff, 0x00040003,
9948c2ecf20Sopenharmony_ci	0x91a0, 0xffffffff, 0x00060005,
9958c2ecf20Sopenharmony_ci	0x91a4, 0xffffffff, 0x00000009,
9968c2ecf20Sopenharmony_ci	0x91a8, 0xffffffff, 0x00080007,
9978c2ecf20Sopenharmony_ci	0x91ac, 0xffffffff, 0x000b000a,
9988c2ecf20Sopenharmony_ci	0x91b0, 0xffffffff, 0x00050004,
9998c2ecf20Sopenharmony_ci	0x91b4, 0xffffffff, 0x00070006,
10008c2ecf20Sopenharmony_ci	0x91b8, 0xffffffff, 0x0008000b,
10018c2ecf20Sopenharmony_ci	0x91bc, 0xffffffff, 0x000a0009,
10028c2ecf20Sopenharmony_ci	0x91c0, 0xffffffff, 0x000d000c,
10038c2ecf20Sopenharmony_ci	0x91c4, 0xffffffff, 0x00060005,
10048c2ecf20Sopenharmony_ci	0x91c8, 0xffffffff, 0x00080007,
10058c2ecf20Sopenharmony_ci	0x91cc, 0xffffffff, 0x0000000b,
10068c2ecf20Sopenharmony_ci	0x91d0, 0xffffffff, 0x000a0009,
10078c2ecf20Sopenharmony_ci	0x91d4, 0xffffffff, 0x000d000c,
10088c2ecf20Sopenharmony_ci	0x9150, 0xffffffff, 0x96940200,
10098c2ecf20Sopenharmony_ci	0x8708, 0xffffffff, 0x00900100,
10108c2ecf20Sopenharmony_ci	0xc478, 0xffffffff, 0x00000080,
10118c2ecf20Sopenharmony_ci	0xc404, 0xffffffff, 0x0020003f,
10128c2ecf20Sopenharmony_ci	0x30, 0xffffffff, 0x0000001c,
10138c2ecf20Sopenharmony_ci	0x34, 0x000f0000, 0x000f0000,
10148c2ecf20Sopenharmony_ci	0x160c, 0xffffffff, 0x00000100,
10158c2ecf20Sopenharmony_ci	0x1024, 0xffffffff, 0x00000100,
10168c2ecf20Sopenharmony_ci	0x102c, 0x00000101, 0x00000000,
10178c2ecf20Sopenharmony_ci	0x20a8, 0xffffffff, 0x00000104,
10188c2ecf20Sopenharmony_ci	0x264c, 0x000c0000, 0x000c0000,
10198c2ecf20Sopenharmony_ci	0x2648, 0x000c0000, 0x000c0000,
10208c2ecf20Sopenharmony_ci	0x55e4, 0xff000fff, 0x00000100,
10218c2ecf20Sopenharmony_ci	0x55e8, 0x00000001, 0x00000001,
10228c2ecf20Sopenharmony_ci	0x2f50, 0x00000001, 0x00000001,
10238c2ecf20Sopenharmony_ci	0x30cc, 0xc0000fff, 0x00000104,
10248c2ecf20Sopenharmony_ci	0xc1e4, 0x00000001, 0x00000001,
10258c2ecf20Sopenharmony_ci	0xd0c0, 0xfffffff0, 0x00000100,
10268c2ecf20Sopenharmony_ci	0xd8c0, 0xfffffff0, 0x00000100
10278c2ecf20Sopenharmony_ci};
10288c2ecf20Sopenharmony_ci
10298c2ecf20Sopenharmony_cistatic const u32 hainan_mgcg_cgcg_init[] =
10308c2ecf20Sopenharmony_ci{
10318c2ecf20Sopenharmony_ci	0xc400, 0xffffffff, 0xfffffffc,
10328c2ecf20Sopenharmony_ci	0x802c, 0xffffffff, 0xe0000000,
10338c2ecf20Sopenharmony_ci	0x9a60, 0xffffffff, 0x00000100,
10348c2ecf20Sopenharmony_ci	0x92a4, 0xffffffff, 0x00000100,
10358c2ecf20Sopenharmony_ci	0xc164, 0xffffffff, 0x00000100,
10368c2ecf20Sopenharmony_ci	0x9774, 0xffffffff, 0x00000100,
10378c2ecf20Sopenharmony_ci	0x8984, 0xffffffff, 0x06000100,
10388c2ecf20Sopenharmony_ci	0x8a18, 0xffffffff, 0x00000100,
10398c2ecf20Sopenharmony_ci	0x92a0, 0xffffffff, 0x00000100,
10408c2ecf20Sopenharmony_ci	0xc380, 0xffffffff, 0x00000100,
10418c2ecf20Sopenharmony_ci	0x8b28, 0xffffffff, 0x00000100,
10428c2ecf20Sopenharmony_ci	0x9144, 0xffffffff, 0x00000100,
10438c2ecf20Sopenharmony_ci	0x8d88, 0xffffffff, 0x00000100,
10448c2ecf20Sopenharmony_ci	0x8d8c, 0xffffffff, 0x00000100,
10458c2ecf20Sopenharmony_ci	0x9030, 0xffffffff, 0x00000100,
10468c2ecf20Sopenharmony_ci	0x9034, 0xffffffff, 0x00000100,
10478c2ecf20Sopenharmony_ci	0x9038, 0xffffffff, 0x00000100,
10488c2ecf20Sopenharmony_ci	0x903c, 0xffffffff, 0x00000100,
10498c2ecf20Sopenharmony_ci	0xad80, 0xffffffff, 0x00000100,
10508c2ecf20Sopenharmony_ci	0xac54, 0xffffffff, 0x00000100,
10518c2ecf20Sopenharmony_ci	0x897c, 0xffffffff, 0x06000100,
10528c2ecf20Sopenharmony_ci	0x9868, 0xffffffff, 0x00000100,
10538c2ecf20Sopenharmony_ci	0x9510, 0xffffffff, 0x00000100,
10548c2ecf20Sopenharmony_ci	0xaf04, 0xffffffff, 0x00000100,
10558c2ecf20Sopenharmony_ci	0xae04, 0xffffffff, 0x00000100,
10568c2ecf20Sopenharmony_ci	0x949c, 0xffffffff, 0x00000100,
10578c2ecf20Sopenharmony_ci	0x802c, 0xffffffff, 0xe0000000,
10588c2ecf20Sopenharmony_ci	0x9160, 0xffffffff, 0x00010000,
10598c2ecf20Sopenharmony_ci	0x9164, 0xffffffff, 0x00030002,
10608c2ecf20Sopenharmony_ci	0x9168, 0xffffffff, 0x00040007,
10618c2ecf20Sopenharmony_ci	0x916c, 0xffffffff, 0x00060005,
10628c2ecf20Sopenharmony_ci	0x9170, 0xffffffff, 0x00090008,
10638c2ecf20Sopenharmony_ci	0x9174, 0xffffffff, 0x00020001,
10648c2ecf20Sopenharmony_ci	0x9178, 0xffffffff, 0x00040003,
10658c2ecf20Sopenharmony_ci	0x917c, 0xffffffff, 0x00000007,
10668c2ecf20Sopenharmony_ci	0x9180, 0xffffffff, 0x00060005,
10678c2ecf20Sopenharmony_ci	0x9184, 0xffffffff, 0x00090008,
10688c2ecf20Sopenharmony_ci	0x9188, 0xffffffff, 0x00030002,
10698c2ecf20Sopenharmony_ci	0x918c, 0xffffffff, 0x00050004,
10708c2ecf20Sopenharmony_ci	0x9190, 0xffffffff, 0x00000008,
10718c2ecf20Sopenharmony_ci	0x9194, 0xffffffff, 0x00070006,
10728c2ecf20Sopenharmony_ci	0x9198, 0xffffffff, 0x000a0009,
10738c2ecf20Sopenharmony_ci	0x919c, 0xffffffff, 0x00040003,
10748c2ecf20Sopenharmony_ci	0x91a0, 0xffffffff, 0x00060005,
10758c2ecf20Sopenharmony_ci	0x91a4, 0xffffffff, 0x00000009,
10768c2ecf20Sopenharmony_ci	0x91a8, 0xffffffff, 0x00080007,
10778c2ecf20Sopenharmony_ci	0x91ac, 0xffffffff, 0x000b000a,
10788c2ecf20Sopenharmony_ci	0x91b0, 0xffffffff, 0x00050004,
10798c2ecf20Sopenharmony_ci	0x91b4, 0xffffffff, 0x00070006,
10808c2ecf20Sopenharmony_ci	0x91b8, 0xffffffff, 0x0008000b,
10818c2ecf20Sopenharmony_ci	0x91bc, 0xffffffff, 0x000a0009,
10828c2ecf20Sopenharmony_ci	0x91c0, 0xffffffff, 0x000d000c,
10838c2ecf20Sopenharmony_ci	0x91c4, 0xffffffff, 0x00060005,
10848c2ecf20Sopenharmony_ci	0x91c8, 0xffffffff, 0x00080007,
10858c2ecf20Sopenharmony_ci	0x91cc, 0xffffffff, 0x0000000b,
10868c2ecf20Sopenharmony_ci	0x91d0, 0xffffffff, 0x000a0009,
10878c2ecf20Sopenharmony_ci	0x91d4, 0xffffffff, 0x000d000c,
10888c2ecf20Sopenharmony_ci	0x9150, 0xffffffff, 0x96940200,
10898c2ecf20Sopenharmony_ci	0x8708, 0xffffffff, 0x00900100,
10908c2ecf20Sopenharmony_ci	0xc478, 0xffffffff, 0x00000080,
10918c2ecf20Sopenharmony_ci	0xc404, 0xffffffff, 0x0020003f,
10928c2ecf20Sopenharmony_ci	0x30, 0xffffffff, 0x0000001c,
10938c2ecf20Sopenharmony_ci	0x34, 0x000f0000, 0x000f0000,
10948c2ecf20Sopenharmony_ci	0x160c, 0xffffffff, 0x00000100,
10958c2ecf20Sopenharmony_ci	0x1024, 0xffffffff, 0x00000100,
10968c2ecf20Sopenharmony_ci	0x20a8, 0xffffffff, 0x00000104,
10978c2ecf20Sopenharmony_ci	0x264c, 0x000c0000, 0x000c0000,
10988c2ecf20Sopenharmony_ci	0x2648, 0x000c0000, 0x000c0000,
10998c2ecf20Sopenharmony_ci	0x2f50, 0x00000001, 0x00000001,
11008c2ecf20Sopenharmony_ci	0x30cc, 0xc0000fff, 0x00000104,
11018c2ecf20Sopenharmony_ci	0xc1e4, 0x00000001, 0x00000001,
11028c2ecf20Sopenharmony_ci	0xd0c0, 0xfffffff0, 0x00000100,
11038c2ecf20Sopenharmony_ci	0xd8c0, 0xfffffff0, 0x00000100
11048c2ecf20Sopenharmony_ci};
11058c2ecf20Sopenharmony_ci
11068c2ecf20Sopenharmony_cistatic u32 verde_pg_init[] =
11078c2ecf20Sopenharmony_ci{
11088c2ecf20Sopenharmony_ci	0x353c, 0xffffffff, 0x40000,
11098c2ecf20Sopenharmony_ci	0x3538, 0xffffffff, 0x200010ff,
11108c2ecf20Sopenharmony_ci	0x353c, 0xffffffff, 0x0,
11118c2ecf20Sopenharmony_ci	0x353c, 0xffffffff, 0x0,
11128c2ecf20Sopenharmony_ci	0x353c, 0xffffffff, 0x0,
11138c2ecf20Sopenharmony_ci	0x353c, 0xffffffff, 0x0,
11148c2ecf20Sopenharmony_ci	0x353c, 0xffffffff, 0x0,
11158c2ecf20Sopenharmony_ci	0x353c, 0xffffffff, 0x7007,
11168c2ecf20Sopenharmony_ci	0x3538, 0xffffffff, 0x300010ff,
11178c2ecf20Sopenharmony_ci	0x353c, 0xffffffff, 0x0,
11188c2ecf20Sopenharmony_ci	0x353c, 0xffffffff, 0x0,
11198c2ecf20Sopenharmony_ci	0x353c, 0xffffffff, 0x0,
11208c2ecf20Sopenharmony_ci	0x353c, 0xffffffff, 0x0,
11218c2ecf20Sopenharmony_ci	0x353c, 0xffffffff, 0x0,
11228c2ecf20Sopenharmony_ci	0x353c, 0xffffffff, 0x400000,
11238c2ecf20Sopenharmony_ci	0x3538, 0xffffffff, 0x100010ff,
11248c2ecf20Sopenharmony_ci	0x353c, 0xffffffff, 0x0,
11258c2ecf20Sopenharmony_ci	0x353c, 0xffffffff, 0x0,
11268c2ecf20Sopenharmony_ci	0x353c, 0xffffffff, 0x0,
11278c2ecf20Sopenharmony_ci	0x353c, 0xffffffff, 0x0,
11288c2ecf20Sopenharmony_ci	0x353c, 0xffffffff, 0x0,
11298c2ecf20Sopenharmony_ci	0x353c, 0xffffffff, 0x120200,
11308c2ecf20Sopenharmony_ci	0x3538, 0xffffffff, 0x500010ff,
11318c2ecf20Sopenharmony_ci	0x353c, 0xffffffff, 0x0,
11328c2ecf20Sopenharmony_ci	0x353c, 0xffffffff, 0x0,
11338c2ecf20Sopenharmony_ci	0x353c, 0xffffffff, 0x0,
11348c2ecf20Sopenharmony_ci	0x353c, 0xffffffff, 0x0,
11358c2ecf20Sopenharmony_ci	0x353c, 0xffffffff, 0x0,
11368c2ecf20Sopenharmony_ci	0x353c, 0xffffffff, 0x1e1e16,
11378c2ecf20Sopenharmony_ci	0x3538, 0xffffffff, 0x600010ff,
11388c2ecf20Sopenharmony_ci	0x353c, 0xffffffff, 0x0,
11398c2ecf20Sopenharmony_ci	0x353c, 0xffffffff, 0x0,
11408c2ecf20Sopenharmony_ci	0x353c, 0xffffffff, 0x0,
11418c2ecf20Sopenharmony_ci	0x353c, 0xffffffff, 0x0,
11428c2ecf20Sopenharmony_ci	0x353c, 0xffffffff, 0x0,
11438c2ecf20Sopenharmony_ci	0x353c, 0xffffffff, 0x171f1e,
11448c2ecf20Sopenharmony_ci	0x3538, 0xffffffff, 0x700010ff,
11458c2ecf20Sopenharmony_ci	0x353c, 0xffffffff, 0x0,
11468c2ecf20Sopenharmony_ci	0x353c, 0xffffffff, 0x0,
11478c2ecf20Sopenharmony_ci	0x353c, 0xffffffff, 0x0,
11488c2ecf20Sopenharmony_ci	0x353c, 0xffffffff, 0x0,
11498c2ecf20Sopenharmony_ci	0x353c, 0xffffffff, 0x0,
11508c2ecf20Sopenharmony_ci	0x353c, 0xffffffff, 0x0,
11518c2ecf20Sopenharmony_ci	0x3538, 0xffffffff, 0x9ff,
11528c2ecf20Sopenharmony_ci	0x3500, 0xffffffff, 0x0,
11538c2ecf20Sopenharmony_ci	0x3504, 0xffffffff, 0x10000800,
11548c2ecf20Sopenharmony_ci	0x3504, 0xffffffff, 0xf,
11558c2ecf20Sopenharmony_ci	0x3504, 0xffffffff, 0xf,
11568c2ecf20Sopenharmony_ci	0x3500, 0xffffffff, 0x4,
11578c2ecf20Sopenharmony_ci	0x3504, 0xffffffff, 0x1000051e,
11588c2ecf20Sopenharmony_ci	0x3504, 0xffffffff, 0xffff,
11598c2ecf20Sopenharmony_ci	0x3504, 0xffffffff, 0xffff,
11608c2ecf20Sopenharmony_ci	0x3500, 0xffffffff, 0x8,
11618c2ecf20Sopenharmony_ci	0x3504, 0xffffffff, 0x80500,
11628c2ecf20Sopenharmony_ci	0x3500, 0xffffffff, 0x12,
11638c2ecf20Sopenharmony_ci	0x3504, 0xffffffff, 0x9050c,
11648c2ecf20Sopenharmony_ci	0x3500, 0xffffffff, 0x1d,
11658c2ecf20Sopenharmony_ci	0x3504, 0xffffffff, 0xb052c,
11668c2ecf20Sopenharmony_ci	0x3500, 0xffffffff, 0x2a,
11678c2ecf20Sopenharmony_ci	0x3504, 0xffffffff, 0x1053e,
11688c2ecf20Sopenharmony_ci	0x3500, 0xffffffff, 0x2d,
11698c2ecf20Sopenharmony_ci	0x3504, 0xffffffff, 0x10546,
11708c2ecf20Sopenharmony_ci	0x3500, 0xffffffff, 0x30,
11718c2ecf20Sopenharmony_ci	0x3504, 0xffffffff, 0xa054e,
11728c2ecf20Sopenharmony_ci	0x3500, 0xffffffff, 0x3c,
11738c2ecf20Sopenharmony_ci	0x3504, 0xffffffff, 0x1055f,
11748c2ecf20Sopenharmony_ci	0x3500, 0xffffffff, 0x3f,
11758c2ecf20Sopenharmony_ci	0x3504, 0xffffffff, 0x10567,
11768c2ecf20Sopenharmony_ci	0x3500, 0xffffffff, 0x42,
11778c2ecf20Sopenharmony_ci	0x3504, 0xffffffff, 0x1056f,
11788c2ecf20Sopenharmony_ci	0x3500, 0xffffffff, 0x45,
11798c2ecf20Sopenharmony_ci	0x3504, 0xffffffff, 0x10572,
11808c2ecf20Sopenharmony_ci	0x3500, 0xffffffff, 0x48,
11818c2ecf20Sopenharmony_ci	0x3504, 0xffffffff, 0x20575,
11828c2ecf20Sopenharmony_ci	0x3500, 0xffffffff, 0x4c,
11838c2ecf20Sopenharmony_ci	0x3504, 0xffffffff, 0x190801,
11848c2ecf20Sopenharmony_ci	0x3500, 0xffffffff, 0x67,
11858c2ecf20Sopenharmony_ci	0x3504, 0xffffffff, 0x1082a,
11868c2ecf20Sopenharmony_ci	0x3500, 0xffffffff, 0x6a,
11878c2ecf20Sopenharmony_ci	0x3504, 0xffffffff, 0x1b082d,
11888c2ecf20Sopenharmony_ci	0x3500, 0xffffffff, 0x87,
11898c2ecf20Sopenharmony_ci	0x3504, 0xffffffff, 0x310851,
11908c2ecf20Sopenharmony_ci	0x3500, 0xffffffff, 0xba,
11918c2ecf20Sopenharmony_ci	0x3504, 0xffffffff, 0x891,
11928c2ecf20Sopenharmony_ci	0x3500, 0xffffffff, 0xbc,
11938c2ecf20Sopenharmony_ci	0x3504, 0xffffffff, 0x893,
11948c2ecf20Sopenharmony_ci	0x3500, 0xffffffff, 0xbe,
11958c2ecf20Sopenharmony_ci	0x3504, 0xffffffff, 0x20895,
11968c2ecf20Sopenharmony_ci	0x3500, 0xffffffff, 0xc2,
11978c2ecf20Sopenharmony_ci	0x3504, 0xffffffff, 0x20899,
11988c2ecf20Sopenharmony_ci	0x3500, 0xffffffff, 0xc6,
11998c2ecf20Sopenharmony_ci	0x3504, 0xffffffff, 0x2089d,
12008c2ecf20Sopenharmony_ci	0x3500, 0xffffffff, 0xca,
12018c2ecf20Sopenharmony_ci	0x3504, 0xffffffff, 0x8a1,
12028c2ecf20Sopenharmony_ci	0x3500, 0xffffffff, 0xcc,
12038c2ecf20Sopenharmony_ci	0x3504, 0xffffffff, 0x8a3,
12048c2ecf20Sopenharmony_ci	0x3500, 0xffffffff, 0xce,
12058c2ecf20Sopenharmony_ci	0x3504, 0xffffffff, 0x308a5,
12068c2ecf20Sopenharmony_ci	0x3500, 0xffffffff, 0xd3,
12078c2ecf20Sopenharmony_ci	0x3504, 0xffffffff, 0x6d08cd,
12088c2ecf20Sopenharmony_ci	0x3500, 0xffffffff, 0x142,
12098c2ecf20Sopenharmony_ci	0x3504, 0xffffffff, 0x2000095a,
12108c2ecf20Sopenharmony_ci	0x3504, 0xffffffff, 0x1,
12118c2ecf20Sopenharmony_ci	0x3500, 0xffffffff, 0x144,
12128c2ecf20Sopenharmony_ci	0x3504, 0xffffffff, 0x301f095b,
12138c2ecf20Sopenharmony_ci	0x3500, 0xffffffff, 0x165,
12148c2ecf20Sopenharmony_ci	0x3504, 0xffffffff, 0xc094d,
12158c2ecf20Sopenharmony_ci	0x3500, 0xffffffff, 0x173,
12168c2ecf20Sopenharmony_ci	0x3504, 0xffffffff, 0xf096d,
12178c2ecf20Sopenharmony_ci	0x3500, 0xffffffff, 0x184,
12188c2ecf20Sopenharmony_ci	0x3504, 0xffffffff, 0x15097f,
12198c2ecf20Sopenharmony_ci	0x3500, 0xffffffff, 0x19b,
12208c2ecf20Sopenharmony_ci	0x3504, 0xffffffff, 0xc0998,
12218c2ecf20Sopenharmony_ci	0x3500, 0xffffffff, 0x1a9,
12228c2ecf20Sopenharmony_ci	0x3504, 0xffffffff, 0x409a7,
12238c2ecf20Sopenharmony_ci	0x3500, 0xffffffff, 0x1af,
12248c2ecf20Sopenharmony_ci	0x3504, 0xffffffff, 0xcdc,
12258c2ecf20Sopenharmony_ci	0x3500, 0xffffffff, 0x1b1,
12268c2ecf20Sopenharmony_ci	0x3504, 0xffffffff, 0x800,
12278c2ecf20Sopenharmony_ci	0x3508, 0xffffffff, 0x6c9b2000,
12288c2ecf20Sopenharmony_ci	0x3510, 0xfc00, 0x2000,
12298c2ecf20Sopenharmony_ci	0x3544, 0xffffffff, 0xfc0,
12308c2ecf20Sopenharmony_ci	0x28d4, 0x00000100, 0x100
12318c2ecf20Sopenharmony_ci};
12328c2ecf20Sopenharmony_ci
12338c2ecf20Sopenharmony_cistatic void si_init_golden_registers(struct radeon_device *rdev)
12348c2ecf20Sopenharmony_ci{
12358c2ecf20Sopenharmony_ci	switch (rdev->family) {
12368c2ecf20Sopenharmony_ci	case CHIP_TAHITI:
12378c2ecf20Sopenharmony_ci		radeon_program_register_sequence(rdev,
12388c2ecf20Sopenharmony_ci						 tahiti_golden_registers,
12398c2ecf20Sopenharmony_ci						 (const u32)ARRAY_SIZE(tahiti_golden_registers));
12408c2ecf20Sopenharmony_ci		radeon_program_register_sequence(rdev,
12418c2ecf20Sopenharmony_ci						 tahiti_golden_rlc_registers,
12428c2ecf20Sopenharmony_ci						 (const u32)ARRAY_SIZE(tahiti_golden_rlc_registers));
12438c2ecf20Sopenharmony_ci		radeon_program_register_sequence(rdev,
12448c2ecf20Sopenharmony_ci						 tahiti_mgcg_cgcg_init,
12458c2ecf20Sopenharmony_ci						 (const u32)ARRAY_SIZE(tahiti_mgcg_cgcg_init));
12468c2ecf20Sopenharmony_ci		radeon_program_register_sequence(rdev,
12478c2ecf20Sopenharmony_ci						 tahiti_golden_registers2,
12488c2ecf20Sopenharmony_ci						 (const u32)ARRAY_SIZE(tahiti_golden_registers2));
12498c2ecf20Sopenharmony_ci		break;
12508c2ecf20Sopenharmony_ci	case CHIP_PITCAIRN:
12518c2ecf20Sopenharmony_ci		radeon_program_register_sequence(rdev,
12528c2ecf20Sopenharmony_ci						 pitcairn_golden_registers,
12538c2ecf20Sopenharmony_ci						 (const u32)ARRAY_SIZE(pitcairn_golden_registers));
12548c2ecf20Sopenharmony_ci		radeon_program_register_sequence(rdev,
12558c2ecf20Sopenharmony_ci						 pitcairn_golden_rlc_registers,
12568c2ecf20Sopenharmony_ci						 (const u32)ARRAY_SIZE(pitcairn_golden_rlc_registers));
12578c2ecf20Sopenharmony_ci		radeon_program_register_sequence(rdev,
12588c2ecf20Sopenharmony_ci						 pitcairn_mgcg_cgcg_init,
12598c2ecf20Sopenharmony_ci						 (const u32)ARRAY_SIZE(pitcairn_mgcg_cgcg_init));
12608c2ecf20Sopenharmony_ci		break;
12618c2ecf20Sopenharmony_ci	case CHIP_VERDE:
12628c2ecf20Sopenharmony_ci		radeon_program_register_sequence(rdev,
12638c2ecf20Sopenharmony_ci						 verde_golden_registers,
12648c2ecf20Sopenharmony_ci						 (const u32)ARRAY_SIZE(verde_golden_registers));
12658c2ecf20Sopenharmony_ci		radeon_program_register_sequence(rdev,
12668c2ecf20Sopenharmony_ci						 verde_golden_rlc_registers,
12678c2ecf20Sopenharmony_ci						 (const u32)ARRAY_SIZE(verde_golden_rlc_registers));
12688c2ecf20Sopenharmony_ci		radeon_program_register_sequence(rdev,
12698c2ecf20Sopenharmony_ci						 verde_mgcg_cgcg_init,
12708c2ecf20Sopenharmony_ci						 (const u32)ARRAY_SIZE(verde_mgcg_cgcg_init));
12718c2ecf20Sopenharmony_ci		radeon_program_register_sequence(rdev,
12728c2ecf20Sopenharmony_ci						 verde_pg_init,
12738c2ecf20Sopenharmony_ci						 (const u32)ARRAY_SIZE(verde_pg_init));
12748c2ecf20Sopenharmony_ci		break;
12758c2ecf20Sopenharmony_ci	case CHIP_OLAND:
12768c2ecf20Sopenharmony_ci		radeon_program_register_sequence(rdev,
12778c2ecf20Sopenharmony_ci						 oland_golden_registers,
12788c2ecf20Sopenharmony_ci						 (const u32)ARRAY_SIZE(oland_golden_registers));
12798c2ecf20Sopenharmony_ci		radeon_program_register_sequence(rdev,
12808c2ecf20Sopenharmony_ci						 oland_golden_rlc_registers,
12818c2ecf20Sopenharmony_ci						 (const u32)ARRAY_SIZE(oland_golden_rlc_registers));
12828c2ecf20Sopenharmony_ci		radeon_program_register_sequence(rdev,
12838c2ecf20Sopenharmony_ci						 oland_mgcg_cgcg_init,
12848c2ecf20Sopenharmony_ci						 (const u32)ARRAY_SIZE(oland_mgcg_cgcg_init));
12858c2ecf20Sopenharmony_ci		break;
12868c2ecf20Sopenharmony_ci	case CHIP_HAINAN:
12878c2ecf20Sopenharmony_ci		radeon_program_register_sequence(rdev,
12888c2ecf20Sopenharmony_ci						 hainan_golden_registers,
12898c2ecf20Sopenharmony_ci						 (const u32)ARRAY_SIZE(hainan_golden_registers));
12908c2ecf20Sopenharmony_ci		radeon_program_register_sequence(rdev,
12918c2ecf20Sopenharmony_ci						 hainan_golden_registers2,
12928c2ecf20Sopenharmony_ci						 (const u32)ARRAY_SIZE(hainan_golden_registers2));
12938c2ecf20Sopenharmony_ci		radeon_program_register_sequence(rdev,
12948c2ecf20Sopenharmony_ci						 hainan_mgcg_cgcg_init,
12958c2ecf20Sopenharmony_ci						 (const u32)ARRAY_SIZE(hainan_mgcg_cgcg_init));
12968c2ecf20Sopenharmony_ci		break;
12978c2ecf20Sopenharmony_ci	default:
12988c2ecf20Sopenharmony_ci		break;
12998c2ecf20Sopenharmony_ci	}
13008c2ecf20Sopenharmony_ci}
13018c2ecf20Sopenharmony_ci
13028c2ecf20Sopenharmony_ci/**
13038c2ecf20Sopenharmony_ci * si_get_allowed_info_register - fetch the register for the info ioctl
13048c2ecf20Sopenharmony_ci *
13058c2ecf20Sopenharmony_ci * @rdev: radeon_device pointer
13068c2ecf20Sopenharmony_ci * @reg: register offset in bytes
13078c2ecf20Sopenharmony_ci * @val: register value
13088c2ecf20Sopenharmony_ci *
13098c2ecf20Sopenharmony_ci * Returns 0 for success or -EINVAL for an invalid register
13108c2ecf20Sopenharmony_ci *
13118c2ecf20Sopenharmony_ci */
13128c2ecf20Sopenharmony_ciint si_get_allowed_info_register(struct radeon_device *rdev,
13138c2ecf20Sopenharmony_ci				 u32 reg, u32 *val)
13148c2ecf20Sopenharmony_ci{
13158c2ecf20Sopenharmony_ci	switch (reg) {
13168c2ecf20Sopenharmony_ci	case GRBM_STATUS:
13178c2ecf20Sopenharmony_ci	case GRBM_STATUS2:
13188c2ecf20Sopenharmony_ci	case GRBM_STATUS_SE0:
13198c2ecf20Sopenharmony_ci	case GRBM_STATUS_SE1:
13208c2ecf20Sopenharmony_ci	case SRBM_STATUS:
13218c2ecf20Sopenharmony_ci	case SRBM_STATUS2:
13228c2ecf20Sopenharmony_ci	case (DMA_STATUS_REG + DMA0_REGISTER_OFFSET):
13238c2ecf20Sopenharmony_ci	case (DMA_STATUS_REG + DMA1_REGISTER_OFFSET):
13248c2ecf20Sopenharmony_ci	case UVD_STATUS:
13258c2ecf20Sopenharmony_ci		*val = RREG32(reg);
13268c2ecf20Sopenharmony_ci		return 0;
13278c2ecf20Sopenharmony_ci	default:
13288c2ecf20Sopenharmony_ci		return -EINVAL;
13298c2ecf20Sopenharmony_ci	}
13308c2ecf20Sopenharmony_ci}
13318c2ecf20Sopenharmony_ci
13328c2ecf20Sopenharmony_ci#define PCIE_BUS_CLK                10000
13338c2ecf20Sopenharmony_ci#define TCLK                        (PCIE_BUS_CLK / 10)
13348c2ecf20Sopenharmony_ci
13358c2ecf20Sopenharmony_ci/**
13368c2ecf20Sopenharmony_ci * si_get_xclk - get the xclk
13378c2ecf20Sopenharmony_ci *
13388c2ecf20Sopenharmony_ci * @rdev: radeon_device pointer
13398c2ecf20Sopenharmony_ci *
13408c2ecf20Sopenharmony_ci * Returns the reference clock used by the gfx engine
13418c2ecf20Sopenharmony_ci * (SI).
13428c2ecf20Sopenharmony_ci */
13438c2ecf20Sopenharmony_ciu32 si_get_xclk(struct radeon_device *rdev)
13448c2ecf20Sopenharmony_ci{
13458c2ecf20Sopenharmony_ci	u32 reference_clock = rdev->clock.spll.reference_freq;
13468c2ecf20Sopenharmony_ci	u32 tmp;
13478c2ecf20Sopenharmony_ci
13488c2ecf20Sopenharmony_ci	tmp = RREG32(CG_CLKPIN_CNTL_2);
13498c2ecf20Sopenharmony_ci	if (tmp & MUX_TCLK_TO_XCLK)
13508c2ecf20Sopenharmony_ci		return TCLK;
13518c2ecf20Sopenharmony_ci
13528c2ecf20Sopenharmony_ci	tmp = RREG32(CG_CLKPIN_CNTL);
13538c2ecf20Sopenharmony_ci	if (tmp & XTALIN_DIVIDE)
13548c2ecf20Sopenharmony_ci		return reference_clock / 4;
13558c2ecf20Sopenharmony_ci
13568c2ecf20Sopenharmony_ci	return reference_clock;
13578c2ecf20Sopenharmony_ci}
13588c2ecf20Sopenharmony_ci
13598c2ecf20Sopenharmony_ci/* get temperature in millidegrees */
13608c2ecf20Sopenharmony_ciint si_get_temp(struct radeon_device *rdev)
13618c2ecf20Sopenharmony_ci{
13628c2ecf20Sopenharmony_ci	u32 temp;
13638c2ecf20Sopenharmony_ci	int actual_temp = 0;
13648c2ecf20Sopenharmony_ci
13658c2ecf20Sopenharmony_ci	temp = (RREG32(CG_MULT_THERMAL_STATUS) & CTF_TEMP_MASK) >>
13668c2ecf20Sopenharmony_ci		CTF_TEMP_SHIFT;
13678c2ecf20Sopenharmony_ci
13688c2ecf20Sopenharmony_ci	if (temp & 0x200)
13698c2ecf20Sopenharmony_ci		actual_temp = 255;
13708c2ecf20Sopenharmony_ci	else
13718c2ecf20Sopenharmony_ci		actual_temp = temp & 0x1ff;
13728c2ecf20Sopenharmony_ci
13738c2ecf20Sopenharmony_ci	actual_temp = (actual_temp * 1000);
13748c2ecf20Sopenharmony_ci
13758c2ecf20Sopenharmony_ci	return actual_temp;
13768c2ecf20Sopenharmony_ci}
13778c2ecf20Sopenharmony_ci
13788c2ecf20Sopenharmony_ci#define TAHITI_IO_MC_REGS_SIZE 36
13798c2ecf20Sopenharmony_ci
13808c2ecf20Sopenharmony_cistatic const u32 tahiti_io_mc_regs[TAHITI_IO_MC_REGS_SIZE][2] = {
13818c2ecf20Sopenharmony_ci	{0x0000006f, 0x03044000},
13828c2ecf20Sopenharmony_ci	{0x00000070, 0x0480c018},
13838c2ecf20Sopenharmony_ci	{0x00000071, 0x00000040},
13848c2ecf20Sopenharmony_ci	{0x00000072, 0x01000000},
13858c2ecf20Sopenharmony_ci	{0x00000074, 0x000000ff},
13868c2ecf20Sopenharmony_ci	{0x00000075, 0x00143400},
13878c2ecf20Sopenharmony_ci	{0x00000076, 0x08ec0800},
13888c2ecf20Sopenharmony_ci	{0x00000077, 0x040000cc},
13898c2ecf20Sopenharmony_ci	{0x00000079, 0x00000000},
13908c2ecf20Sopenharmony_ci	{0x0000007a, 0x21000409},
13918c2ecf20Sopenharmony_ci	{0x0000007c, 0x00000000},
13928c2ecf20Sopenharmony_ci	{0x0000007d, 0xe8000000},
13938c2ecf20Sopenharmony_ci	{0x0000007e, 0x044408a8},
13948c2ecf20Sopenharmony_ci	{0x0000007f, 0x00000003},
13958c2ecf20Sopenharmony_ci	{0x00000080, 0x00000000},
13968c2ecf20Sopenharmony_ci	{0x00000081, 0x01000000},
13978c2ecf20Sopenharmony_ci	{0x00000082, 0x02000000},
13988c2ecf20Sopenharmony_ci	{0x00000083, 0x00000000},
13998c2ecf20Sopenharmony_ci	{0x00000084, 0xe3f3e4f4},
14008c2ecf20Sopenharmony_ci	{0x00000085, 0x00052024},
14018c2ecf20Sopenharmony_ci	{0x00000087, 0x00000000},
14028c2ecf20Sopenharmony_ci	{0x00000088, 0x66036603},
14038c2ecf20Sopenharmony_ci	{0x00000089, 0x01000000},
14048c2ecf20Sopenharmony_ci	{0x0000008b, 0x1c0a0000},
14058c2ecf20Sopenharmony_ci	{0x0000008c, 0xff010000},
14068c2ecf20Sopenharmony_ci	{0x0000008e, 0xffffefff},
14078c2ecf20Sopenharmony_ci	{0x0000008f, 0xfff3efff},
14088c2ecf20Sopenharmony_ci	{0x00000090, 0xfff3efbf},
14098c2ecf20Sopenharmony_ci	{0x00000094, 0x00101101},
14108c2ecf20Sopenharmony_ci	{0x00000095, 0x00000fff},
14118c2ecf20Sopenharmony_ci	{0x00000096, 0x00116fff},
14128c2ecf20Sopenharmony_ci	{0x00000097, 0x60010000},
14138c2ecf20Sopenharmony_ci	{0x00000098, 0x10010000},
14148c2ecf20Sopenharmony_ci	{0x00000099, 0x00006000},
14158c2ecf20Sopenharmony_ci	{0x0000009a, 0x00001000},
14168c2ecf20Sopenharmony_ci	{0x0000009f, 0x00a77400}
14178c2ecf20Sopenharmony_ci};
14188c2ecf20Sopenharmony_ci
14198c2ecf20Sopenharmony_cistatic const u32 pitcairn_io_mc_regs[TAHITI_IO_MC_REGS_SIZE][2] = {
14208c2ecf20Sopenharmony_ci	{0x0000006f, 0x03044000},
14218c2ecf20Sopenharmony_ci	{0x00000070, 0x0480c018},
14228c2ecf20Sopenharmony_ci	{0x00000071, 0x00000040},
14238c2ecf20Sopenharmony_ci	{0x00000072, 0x01000000},
14248c2ecf20Sopenharmony_ci	{0x00000074, 0x000000ff},
14258c2ecf20Sopenharmony_ci	{0x00000075, 0x00143400},
14268c2ecf20Sopenharmony_ci	{0x00000076, 0x08ec0800},
14278c2ecf20Sopenharmony_ci	{0x00000077, 0x040000cc},
14288c2ecf20Sopenharmony_ci	{0x00000079, 0x00000000},
14298c2ecf20Sopenharmony_ci	{0x0000007a, 0x21000409},
14308c2ecf20Sopenharmony_ci	{0x0000007c, 0x00000000},
14318c2ecf20Sopenharmony_ci	{0x0000007d, 0xe8000000},
14328c2ecf20Sopenharmony_ci	{0x0000007e, 0x044408a8},
14338c2ecf20Sopenharmony_ci	{0x0000007f, 0x00000003},
14348c2ecf20Sopenharmony_ci	{0x00000080, 0x00000000},
14358c2ecf20Sopenharmony_ci	{0x00000081, 0x01000000},
14368c2ecf20Sopenharmony_ci	{0x00000082, 0x02000000},
14378c2ecf20Sopenharmony_ci	{0x00000083, 0x00000000},
14388c2ecf20Sopenharmony_ci	{0x00000084, 0xe3f3e4f4},
14398c2ecf20Sopenharmony_ci	{0x00000085, 0x00052024},
14408c2ecf20Sopenharmony_ci	{0x00000087, 0x00000000},
14418c2ecf20Sopenharmony_ci	{0x00000088, 0x66036603},
14428c2ecf20Sopenharmony_ci	{0x00000089, 0x01000000},
14438c2ecf20Sopenharmony_ci	{0x0000008b, 0x1c0a0000},
14448c2ecf20Sopenharmony_ci	{0x0000008c, 0xff010000},
14458c2ecf20Sopenharmony_ci	{0x0000008e, 0xffffefff},
14468c2ecf20Sopenharmony_ci	{0x0000008f, 0xfff3efff},
14478c2ecf20Sopenharmony_ci	{0x00000090, 0xfff3efbf},
14488c2ecf20Sopenharmony_ci	{0x00000094, 0x00101101},
14498c2ecf20Sopenharmony_ci	{0x00000095, 0x00000fff},
14508c2ecf20Sopenharmony_ci	{0x00000096, 0x00116fff},
14518c2ecf20Sopenharmony_ci	{0x00000097, 0x60010000},
14528c2ecf20Sopenharmony_ci	{0x00000098, 0x10010000},
14538c2ecf20Sopenharmony_ci	{0x00000099, 0x00006000},
14548c2ecf20Sopenharmony_ci	{0x0000009a, 0x00001000},
14558c2ecf20Sopenharmony_ci	{0x0000009f, 0x00a47400}
14568c2ecf20Sopenharmony_ci};
14578c2ecf20Sopenharmony_ci
14588c2ecf20Sopenharmony_cistatic const u32 verde_io_mc_regs[TAHITI_IO_MC_REGS_SIZE][2] = {
14598c2ecf20Sopenharmony_ci	{0x0000006f, 0x03044000},
14608c2ecf20Sopenharmony_ci	{0x00000070, 0x0480c018},
14618c2ecf20Sopenharmony_ci	{0x00000071, 0x00000040},
14628c2ecf20Sopenharmony_ci	{0x00000072, 0x01000000},
14638c2ecf20Sopenharmony_ci	{0x00000074, 0x000000ff},
14648c2ecf20Sopenharmony_ci	{0x00000075, 0x00143400},
14658c2ecf20Sopenharmony_ci	{0x00000076, 0x08ec0800},
14668c2ecf20Sopenharmony_ci	{0x00000077, 0x040000cc},
14678c2ecf20Sopenharmony_ci	{0x00000079, 0x00000000},
14688c2ecf20Sopenharmony_ci	{0x0000007a, 0x21000409},
14698c2ecf20Sopenharmony_ci	{0x0000007c, 0x00000000},
14708c2ecf20Sopenharmony_ci	{0x0000007d, 0xe8000000},
14718c2ecf20Sopenharmony_ci	{0x0000007e, 0x044408a8},
14728c2ecf20Sopenharmony_ci	{0x0000007f, 0x00000003},
14738c2ecf20Sopenharmony_ci	{0x00000080, 0x00000000},
14748c2ecf20Sopenharmony_ci	{0x00000081, 0x01000000},
14758c2ecf20Sopenharmony_ci	{0x00000082, 0x02000000},
14768c2ecf20Sopenharmony_ci	{0x00000083, 0x00000000},
14778c2ecf20Sopenharmony_ci	{0x00000084, 0xe3f3e4f4},
14788c2ecf20Sopenharmony_ci	{0x00000085, 0x00052024},
14798c2ecf20Sopenharmony_ci	{0x00000087, 0x00000000},
14808c2ecf20Sopenharmony_ci	{0x00000088, 0x66036603},
14818c2ecf20Sopenharmony_ci	{0x00000089, 0x01000000},
14828c2ecf20Sopenharmony_ci	{0x0000008b, 0x1c0a0000},
14838c2ecf20Sopenharmony_ci	{0x0000008c, 0xff010000},
14848c2ecf20Sopenharmony_ci	{0x0000008e, 0xffffefff},
14858c2ecf20Sopenharmony_ci	{0x0000008f, 0xfff3efff},
14868c2ecf20Sopenharmony_ci	{0x00000090, 0xfff3efbf},
14878c2ecf20Sopenharmony_ci	{0x00000094, 0x00101101},
14888c2ecf20Sopenharmony_ci	{0x00000095, 0x00000fff},
14898c2ecf20Sopenharmony_ci	{0x00000096, 0x00116fff},
14908c2ecf20Sopenharmony_ci	{0x00000097, 0x60010000},
14918c2ecf20Sopenharmony_ci	{0x00000098, 0x10010000},
14928c2ecf20Sopenharmony_ci	{0x00000099, 0x00006000},
14938c2ecf20Sopenharmony_ci	{0x0000009a, 0x00001000},
14948c2ecf20Sopenharmony_ci	{0x0000009f, 0x00a37400}
14958c2ecf20Sopenharmony_ci};
14968c2ecf20Sopenharmony_ci
14978c2ecf20Sopenharmony_cistatic const u32 oland_io_mc_regs[TAHITI_IO_MC_REGS_SIZE][2] = {
14988c2ecf20Sopenharmony_ci	{0x0000006f, 0x03044000},
14998c2ecf20Sopenharmony_ci	{0x00000070, 0x0480c018},
15008c2ecf20Sopenharmony_ci	{0x00000071, 0x00000040},
15018c2ecf20Sopenharmony_ci	{0x00000072, 0x01000000},
15028c2ecf20Sopenharmony_ci	{0x00000074, 0x000000ff},
15038c2ecf20Sopenharmony_ci	{0x00000075, 0x00143400},
15048c2ecf20Sopenharmony_ci	{0x00000076, 0x08ec0800},
15058c2ecf20Sopenharmony_ci	{0x00000077, 0x040000cc},
15068c2ecf20Sopenharmony_ci	{0x00000079, 0x00000000},
15078c2ecf20Sopenharmony_ci	{0x0000007a, 0x21000409},
15088c2ecf20Sopenharmony_ci	{0x0000007c, 0x00000000},
15098c2ecf20Sopenharmony_ci	{0x0000007d, 0xe8000000},
15108c2ecf20Sopenharmony_ci	{0x0000007e, 0x044408a8},
15118c2ecf20Sopenharmony_ci	{0x0000007f, 0x00000003},
15128c2ecf20Sopenharmony_ci	{0x00000080, 0x00000000},
15138c2ecf20Sopenharmony_ci	{0x00000081, 0x01000000},
15148c2ecf20Sopenharmony_ci	{0x00000082, 0x02000000},
15158c2ecf20Sopenharmony_ci	{0x00000083, 0x00000000},
15168c2ecf20Sopenharmony_ci	{0x00000084, 0xe3f3e4f4},
15178c2ecf20Sopenharmony_ci	{0x00000085, 0x00052024},
15188c2ecf20Sopenharmony_ci	{0x00000087, 0x00000000},
15198c2ecf20Sopenharmony_ci	{0x00000088, 0x66036603},
15208c2ecf20Sopenharmony_ci	{0x00000089, 0x01000000},
15218c2ecf20Sopenharmony_ci	{0x0000008b, 0x1c0a0000},
15228c2ecf20Sopenharmony_ci	{0x0000008c, 0xff010000},
15238c2ecf20Sopenharmony_ci	{0x0000008e, 0xffffefff},
15248c2ecf20Sopenharmony_ci	{0x0000008f, 0xfff3efff},
15258c2ecf20Sopenharmony_ci	{0x00000090, 0xfff3efbf},
15268c2ecf20Sopenharmony_ci	{0x00000094, 0x00101101},
15278c2ecf20Sopenharmony_ci	{0x00000095, 0x00000fff},
15288c2ecf20Sopenharmony_ci	{0x00000096, 0x00116fff},
15298c2ecf20Sopenharmony_ci	{0x00000097, 0x60010000},
15308c2ecf20Sopenharmony_ci	{0x00000098, 0x10010000},
15318c2ecf20Sopenharmony_ci	{0x00000099, 0x00006000},
15328c2ecf20Sopenharmony_ci	{0x0000009a, 0x00001000},
15338c2ecf20Sopenharmony_ci	{0x0000009f, 0x00a17730}
15348c2ecf20Sopenharmony_ci};
15358c2ecf20Sopenharmony_ci
15368c2ecf20Sopenharmony_cistatic const u32 hainan_io_mc_regs[TAHITI_IO_MC_REGS_SIZE][2] = {
15378c2ecf20Sopenharmony_ci	{0x0000006f, 0x03044000},
15388c2ecf20Sopenharmony_ci	{0x00000070, 0x0480c018},
15398c2ecf20Sopenharmony_ci	{0x00000071, 0x00000040},
15408c2ecf20Sopenharmony_ci	{0x00000072, 0x01000000},
15418c2ecf20Sopenharmony_ci	{0x00000074, 0x000000ff},
15428c2ecf20Sopenharmony_ci	{0x00000075, 0x00143400},
15438c2ecf20Sopenharmony_ci	{0x00000076, 0x08ec0800},
15448c2ecf20Sopenharmony_ci	{0x00000077, 0x040000cc},
15458c2ecf20Sopenharmony_ci	{0x00000079, 0x00000000},
15468c2ecf20Sopenharmony_ci	{0x0000007a, 0x21000409},
15478c2ecf20Sopenharmony_ci	{0x0000007c, 0x00000000},
15488c2ecf20Sopenharmony_ci	{0x0000007d, 0xe8000000},
15498c2ecf20Sopenharmony_ci	{0x0000007e, 0x044408a8},
15508c2ecf20Sopenharmony_ci	{0x0000007f, 0x00000003},
15518c2ecf20Sopenharmony_ci	{0x00000080, 0x00000000},
15528c2ecf20Sopenharmony_ci	{0x00000081, 0x01000000},
15538c2ecf20Sopenharmony_ci	{0x00000082, 0x02000000},
15548c2ecf20Sopenharmony_ci	{0x00000083, 0x00000000},
15558c2ecf20Sopenharmony_ci	{0x00000084, 0xe3f3e4f4},
15568c2ecf20Sopenharmony_ci	{0x00000085, 0x00052024},
15578c2ecf20Sopenharmony_ci	{0x00000087, 0x00000000},
15588c2ecf20Sopenharmony_ci	{0x00000088, 0x66036603},
15598c2ecf20Sopenharmony_ci	{0x00000089, 0x01000000},
15608c2ecf20Sopenharmony_ci	{0x0000008b, 0x1c0a0000},
15618c2ecf20Sopenharmony_ci	{0x0000008c, 0xff010000},
15628c2ecf20Sopenharmony_ci	{0x0000008e, 0xffffefff},
15638c2ecf20Sopenharmony_ci	{0x0000008f, 0xfff3efff},
15648c2ecf20Sopenharmony_ci	{0x00000090, 0xfff3efbf},
15658c2ecf20Sopenharmony_ci	{0x00000094, 0x00101101},
15668c2ecf20Sopenharmony_ci	{0x00000095, 0x00000fff},
15678c2ecf20Sopenharmony_ci	{0x00000096, 0x00116fff},
15688c2ecf20Sopenharmony_ci	{0x00000097, 0x60010000},
15698c2ecf20Sopenharmony_ci	{0x00000098, 0x10010000},
15708c2ecf20Sopenharmony_ci	{0x00000099, 0x00006000},
15718c2ecf20Sopenharmony_ci	{0x0000009a, 0x00001000},
15728c2ecf20Sopenharmony_ci	{0x0000009f, 0x00a07730}
15738c2ecf20Sopenharmony_ci};
15748c2ecf20Sopenharmony_ci
15758c2ecf20Sopenharmony_ci/* ucode loading */
15768c2ecf20Sopenharmony_ciint si_mc_load_microcode(struct radeon_device *rdev)
15778c2ecf20Sopenharmony_ci{
15788c2ecf20Sopenharmony_ci	const __be32 *fw_data = NULL;
15798c2ecf20Sopenharmony_ci	const __le32 *new_fw_data = NULL;
15808c2ecf20Sopenharmony_ci	u32 running;
15818c2ecf20Sopenharmony_ci	u32 *io_mc_regs = NULL;
15828c2ecf20Sopenharmony_ci	const __le32 *new_io_mc_regs = NULL;
15838c2ecf20Sopenharmony_ci	int i, regs_size, ucode_size;
15848c2ecf20Sopenharmony_ci
15858c2ecf20Sopenharmony_ci	if (!rdev->mc_fw)
15868c2ecf20Sopenharmony_ci		return -EINVAL;
15878c2ecf20Sopenharmony_ci
15888c2ecf20Sopenharmony_ci	if (rdev->new_fw) {
15898c2ecf20Sopenharmony_ci		const struct mc_firmware_header_v1_0 *hdr =
15908c2ecf20Sopenharmony_ci			(const struct mc_firmware_header_v1_0 *)rdev->mc_fw->data;
15918c2ecf20Sopenharmony_ci
15928c2ecf20Sopenharmony_ci		radeon_ucode_print_mc_hdr(&hdr->header);
15938c2ecf20Sopenharmony_ci		regs_size = le32_to_cpu(hdr->io_debug_size_bytes) / (4 * 2);
15948c2ecf20Sopenharmony_ci		new_io_mc_regs = (const __le32 *)
15958c2ecf20Sopenharmony_ci			(rdev->mc_fw->data + le32_to_cpu(hdr->io_debug_array_offset_bytes));
15968c2ecf20Sopenharmony_ci		ucode_size = le32_to_cpu(hdr->header.ucode_size_bytes) / 4;
15978c2ecf20Sopenharmony_ci		new_fw_data = (const __le32 *)
15988c2ecf20Sopenharmony_ci			(rdev->mc_fw->data + le32_to_cpu(hdr->header.ucode_array_offset_bytes));
15998c2ecf20Sopenharmony_ci	} else {
16008c2ecf20Sopenharmony_ci		ucode_size = rdev->mc_fw->size / 4;
16018c2ecf20Sopenharmony_ci
16028c2ecf20Sopenharmony_ci		switch (rdev->family) {
16038c2ecf20Sopenharmony_ci		case CHIP_TAHITI:
16048c2ecf20Sopenharmony_ci			io_mc_regs = (u32 *)&tahiti_io_mc_regs;
16058c2ecf20Sopenharmony_ci			regs_size = TAHITI_IO_MC_REGS_SIZE;
16068c2ecf20Sopenharmony_ci			break;
16078c2ecf20Sopenharmony_ci		case CHIP_PITCAIRN:
16088c2ecf20Sopenharmony_ci			io_mc_regs = (u32 *)&pitcairn_io_mc_regs;
16098c2ecf20Sopenharmony_ci			regs_size = TAHITI_IO_MC_REGS_SIZE;
16108c2ecf20Sopenharmony_ci			break;
16118c2ecf20Sopenharmony_ci		case CHIP_VERDE:
16128c2ecf20Sopenharmony_ci		default:
16138c2ecf20Sopenharmony_ci			io_mc_regs = (u32 *)&verde_io_mc_regs;
16148c2ecf20Sopenharmony_ci			regs_size = TAHITI_IO_MC_REGS_SIZE;
16158c2ecf20Sopenharmony_ci			break;
16168c2ecf20Sopenharmony_ci		case CHIP_OLAND:
16178c2ecf20Sopenharmony_ci			io_mc_regs = (u32 *)&oland_io_mc_regs;
16188c2ecf20Sopenharmony_ci			regs_size = TAHITI_IO_MC_REGS_SIZE;
16198c2ecf20Sopenharmony_ci			break;
16208c2ecf20Sopenharmony_ci		case CHIP_HAINAN:
16218c2ecf20Sopenharmony_ci			io_mc_regs = (u32 *)&hainan_io_mc_regs;
16228c2ecf20Sopenharmony_ci			regs_size = TAHITI_IO_MC_REGS_SIZE;
16238c2ecf20Sopenharmony_ci			break;
16248c2ecf20Sopenharmony_ci		}
16258c2ecf20Sopenharmony_ci		fw_data = (const __be32 *)rdev->mc_fw->data;
16268c2ecf20Sopenharmony_ci	}
16278c2ecf20Sopenharmony_ci
16288c2ecf20Sopenharmony_ci	running = RREG32(MC_SEQ_SUP_CNTL) & RUN_MASK;
16298c2ecf20Sopenharmony_ci
16308c2ecf20Sopenharmony_ci	if (running == 0) {
16318c2ecf20Sopenharmony_ci		/* reset the engine and set to writable */
16328c2ecf20Sopenharmony_ci		WREG32(MC_SEQ_SUP_CNTL, 0x00000008);
16338c2ecf20Sopenharmony_ci		WREG32(MC_SEQ_SUP_CNTL, 0x00000010);
16348c2ecf20Sopenharmony_ci
16358c2ecf20Sopenharmony_ci		/* load mc io regs */
16368c2ecf20Sopenharmony_ci		for (i = 0; i < regs_size; i++) {
16378c2ecf20Sopenharmony_ci			if (rdev->new_fw) {
16388c2ecf20Sopenharmony_ci				WREG32(MC_SEQ_IO_DEBUG_INDEX, le32_to_cpup(new_io_mc_regs++));
16398c2ecf20Sopenharmony_ci				WREG32(MC_SEQ_IO_DEBUG_DATA, le32_to_cpup(new_io_mc_regs++));
16408c2ecf20Sopenharmony_ci			} else {
16418c2ecf20Sopenharmony_ci				WREG32(MC_SEQ_IO_DEBUG_INDEX, io_mc_regs[(i << 1)]);
16428c2ecf20Sopenharmony_ci				WREG32(MC_SEQ_IO_DEBUG_DATA, io_mc_regs[(i << 1) + 1]);
16438c2ecf20Sopenharmony_ci			}
16448c2ecf20Sopenharmony_ci		}
16458c2ecf20Sopenharmony_ci		/* load the MC ucode */
16468c2ecf20Sopenharmony_ci		for (i = 0; i < ucode_size; i++) {
16478c2ecf20Sopenharmony_ci			if (rdev->new_fw)
16488c2ecf20Sopenharmony_ci				WREG32(MC_SEQ_SUP_PGM, le32_to_cpup(new_fw_data++));
16498c2ecf20Sopenharmony_ci			else
16508c2ecf20Sopenharmony_ci				WREG32(MC_SEQ_SUP_PGM, be32_to_cpup(fw_data++));
16518c2ecf20Sopenharmony_ci		}
16528c2ecf20Sopenharmony_ci
16538c2ecf20Sopenharmony_ci		/* put the engine back into the active state */
16548c2ecf20Sopenharmony_ci		WREG32(MC_SEQ_SUP_CNTL, 0x00000008);
16558c2ecf20Sopenharmony_ci		WREG32(MC_SEQ_SUP_CNTL, 0x00000004);
16568c2ecf20Sopenharmony_ci		WREG32(MC_SEQ_SUP_CNTL, 0x00000001);
16578c2ecf20Sopenharmony_ci
16588c2ecf20Sopenharmony_ci		/* wait for training to complete */
16598c2ecf20Sopenharmony_ci		for (i = 0; i < rdev->usec_timeout; i++) {
16608c2ecf20Sopenharmony_ci			if (RREG32(MC_SEQ_TRAIN_WAKEUP_CNTL) & TRAIN_DONE_D0)
16618c2ecf20Sopenharmony_ci				break;
16628c2ecf20Sopenharmony_ci			udelay(1);
16638c2ecf20Sopenharmony_ci		}
16648c2ecf20Sopenharmony_ci		for (i = 0; i < rdev->usec_timeout; i++) {
16658c2ecf20Sopenharmony_ci			if (RREG32(MC_SEQ_TRAIN_WAKEUP_CNTL) & TRAIN_DONE_D1)
16668c2ecf20Sopenharmony_ci				break;
16678c2ecf20Sopenharmony_ci			udelay(1);
16688c2ecf20Sopenharmony_ci		}
16698c2ecf20Sopenharmony_ci	}
16708c2ecf20Sopenharmony_ci
16718c2ecf20Sopenharmony_ci	return 0;
16728c2ecf20Sopenharmony_ci}
16738c2ecf20Sopenharmony_ci
16748c2ecf20Sopenharmony_cistatic int si_init_microcode(struct radeon_device *rdev)
16758c2ecf20Sopenharmony_ci{
16768c2ecf20Sopenharmony_ci	const char *chip_name;
16778c2ecf20Sopenharmony_ci	const char *new_chip_name;
16788c2ecf20Sopenharmony_ci	size_t pfp_req_size, me_req_size, ce_req_size, rlc_req_size, mc_req_size;
16798c2ecf20Sopenharmony_ci	size_t smc_req_size, mc2_req_size;
16808c2ecf20Sopenharmony_ci	char fw_name[30];
16818c2ecf20Sopenharmony_ci	int err;
16828c2ecf20Sopenharmony_ci	int new_fw = 0;
16838c2ecf20Sopenharmony_ci	bool new_smc = false;
16848c2ecf20Sopenharmony_ci	bool si58_fw = false;
16858c2ecf20Sopenharmony_ci	bool banks2_fw = false;
16868c2ecf20Sopenharmony_ci
16878c2ecf20Sopenharmony_ci	DRM_DEBUG("\n");
16888c2ecf20Sopenharmony_ci
16898c2ecf20Sopenharmony_ci	switch (rdev->family) {
16908c2ecf20Sopenharmony_ci	case CHIP_TAHITI:
16918c2ecf20Sopenharmony_ci		chip_name = "TAHITI";
16928c2ecf20Sopenharmony_ci		new_chip_name = "tahiti";
16938c2ecf20Sopenharmony_ci		pfp_req_size = SI_PFP_UCODE_SIZE * 4;
16948c2ecf20Sopenharmony_ci		me_req_size = SI_PM4_UCODE_SIZE * 4;
16958c2ecf20Sopenharmony_ci		ce_req_size = SI_CE_UCODE_SIZE * 4;
16968c2ecf20Sopenharmony_ci		rlc_req_size = SI_RLC_UCODE_SIZE * 4;
16978c2ecf20Sopenharmony_ci		mc_req_size = SI_MC_UCODE_SIZE * 4;
16988c2ecf20Sopenharmony_ci		mc2_req_size = TAHITI_MC_UCODE_SIZE * 4;
16998c2ecf20Sopenharmony_ci		smc_req_size = ALIGN(TAHITI_SMC_UCODE_SIZE, 4);
17008c2ecf20Sopenharmony_ci		break;
17018c2ecf20Sopenharmony_ci	case CHIP_PITCAIRN:
17028c2ecf20Sopenharmony_ci		chip_name = "PITCAIRN";
17038c2ecf20Sopenharmony_ci		if ((rdev->pdev->revision == 0x81) &&
17048c2ecf20Sopenharmony_ci		    ((rdev->pdev->device == 0x6810) ||
17058c2ecf20Sopenharmony_ci		     (rdev->pdev->device == 0x6811)))
17068c2ecf20Sopenharmony_ci			new_smc = true;
17078c2ecf20Sopenharmony_ci		new_chip_name = "pitcairn";
17088c2ecf20Sopenharmony_ci		pfp_req_size = SI_PFP_UCODE_SIZE * 4;
17098c2ecf20Sopenharmony_ci		me_req_size = SI_PM4_UCODE_SIZE * 4;
17108c2ecf20Sopenharmony_ci		ce_req_size = SI_CE_UCODE_SIZE * 4;
17118c2ecf20Sopenharmony_ci		rlc_req_size = SI_RLC_UCODE_SIZE * 4;
17128c2ecf20Sopenharmony_ci		mc_req_size = SI_MC_UCODE_SIZE * 4;
17138c2ecf20Sopenharmony_ci		mc2_req_size = PITCAIRN_MC_UCODE_SIZE * 4;
17148c2ecf20Sopenharmony_ci		smc_req_size = ALIGN(PITCAIRN_SMC_UCODE_SIZE, 4);
17158c2ecf20Sopenharmony_ci		break;
17168c2ecf20Sopenharmony_ci	case CHIP_VERDE:
17178c2ecf20Sopenharmony_ci		chip_name = "VERDE";
17188c2ecf20Sopenharmony_ci		if (((rdev->pdev->device == 0x6820) &&
17198c2ecf20Sopenharmony_ci		     ((rdev->pdev->revision == 0x81) ||
17208c2ecf20Sopenharmony_ci		      (rdev->pdev->revision == 0x83))) ||
17218c2ecf20Sopenharmony_ci		    ((rdev->pdev->device == 0x6821) &&
17228c2ecf20Sopenharmony_ci		     ((rdev->pdev->revision == 0x83) ||
17238c2ecf20Sopenharmony_ci		      (rdev->pdev->revision == 0x87))) ||
17248c2ecf20Sopenharmony_ci		    ((rdev->pdev->revision == 0x87) &&
17258c2ecf20Sopenharmony_ci		     ((rdev->pdev->device == 0x6823) ||
17268c2ecf20Sopenharmony_ci		      (rdev->pdev->device == 0x682b))))
17278c2ecf20Sopenharmony_ci			new_smc = true;
17288c2ecf20Sopenharmony_ci		new_chip_name = "verde";
17298c2ecf20Sopenharmony_ci		pfp_req_size = SI_PFP_UCODE_SIZE * 4;
17308c2ecf20Sopenharmony_ci		me_req_size = SI_PM4_UCODE_SIZE * 4;
17318c2ecf20Sopenharmony_ci		ce_req_size = SI_CE_UCODE_SIZE * 4;
17328c2ecf20Sopenharmony_ci		rlc_req_size = SI_RLC_UCODE_SIZE * 4;
17338c2ecf20Sopenharmony_ci		mc_req_size = SI_MC_UCODE_SIZE * 4;
17348c2ecf20Sopenharmony_ci		mc2_req_size = VERDE_MC_UCODE_SIZE * 4;
17358c2ecf20Sopenharmony_ci		smc_req_size = ALIGN(VERDE_SMC_UCODE_SIZE, 4);
17368c2ecf20Sopenharmony_ci		break;
17378c2ecf20Sopenharmony_ci	case CHIP_OLAND:
17388c2ecf20Sopenharmony_ci		chip_name = "OLAND";
17398c2ecf20Sopenharmony_ci		if (((rdev->pdev->revision == 0x81) &&
17408c2ecf20Sopenharmony_ci		     ((rdev->pdev->device == 0x6600) ||
17418c2ecf20Sopenharmony_ci		      (rdev->pdev->device == 0x6604) ||
17428c2ecf20Sopenharmony_ci		      (rdev->pdev->device == 0x6605) ||
17438c2ecf20Sopenharmony_ci		      (rdev->pdev->device == 0x6610))) ||
17448c2ecf20Sopenharmony_ci		    ((rdev->pdev->revision == 0x83) &&
17458c2ecf20Sopenharmony_ci		     (rdev->pdev->device == 0x6610)))
17468c2ecf20Sopenharmony_ci			new_smc = true;
17478c2ecf20Sopenharmony_ci		new_chip_name = "oland";
17488c2ecf20Sopenharmony_ci		pfp_req_size = SI_PFP_UCODE_SIZE * 4;
17498c2ecf20Sopenharmony_ci		me_req_size = SI_PM4_UCODE_SIZE * 4;
17508c2ecf20Sopenharmony_ci		ce_req_size = SI_CE_UCODE_SIZE * 4;
17518c2ecf20Sopenharmony_ci		rlc_req_size = SI_RLC_UCODE_SIZE * 4;
17528c2ecf20Sopenharmony_ci		mc_req_size = mc2_req_size = OLAND_MC_UCODE_SIZE * 4;
17538c2ecf20Sopenharmony_ci		smc_req_size = ALIGN(OLAND_SMC_UCODE_SIZE, 4);
17548c2ecf20Sopenharmony_ci		break;
17558c2ecf20Sopenharmony_ci	case CHIP_HAINAN:
17568c2ecf20Sopenharmony_ci		chip_name = "HAINAN";
17578c2ecf20Sopenharmony_ci		if (((rdev->pdev->revision == 0x81) &&
17588c2ecf20Sopenharmony_ci		     (rdev->pdev->device == 0x6660)) ||
17598c2ecf20Sopenharmony_ci		    ((rdev->pdev->revision == 0x83) &&
17608c2ecf20Sopenharmony_ci		     ((rdev->pdev->device == 0x6660) ||
17618c2ecf20Sopenharmony_ci		      (rdev->pdev->device == 0x6663) ||
17628c2ecf20Sopenharmony_ci		      (rdev->pdev->device == 0x6665) ||
17638c2ecf20Sopenharmony_ci		      (rdev->pdev->device == 0x6667))))
17648c2ecf20Sopenharmony_ci			new_smc = true;
17658c2ecf20Sopenharmony_ci		else if ((rdev->pdev->revision == 0xc3) &&
17668c2ecf20Sopenharmony_ci			 (rdev->pdev->device == 0x6665))
17678c2ecf20Sopenharmony_ci			banks2_fw = true;
17688c2ecf20Sopenharmony_ci		new_chip_name = "hainan";
17698c2ecf20Sopenharmony_ci		pfp_req_size = SI_PFP_UCODE_SIZE * 4;
17708c2ecf20Sopenharmony_ci		me_req_size = SI_PM4_UCODE_SIZE * 4;
17718c2ecf20Sopenharmony_ci		ce_req_size = SI_CE_UCODE_SIZE * 4;
17728c2ecf20Sopenharmony_ci		rlc_req_size = SI_RLC_UCODE_SIZE * 4;
17738c2ecf20Sopenharmony_ci		mc_req_size = mc2_req_size = OLAND_MC_UCODE_SIZE * 4;
17748c2ecf20Sopenharmony_ci		smc_req_size = ALIGN(HAINAN_SMC_UCODE_SIZE, 4);
17758c2ecf20Sopenharmony_ci		break;
17768c2ecf20Sopenharmony_ci	default: BUG();
17778c2ecf20Sopenharmony_ci	}
17788c2ecf20Sopenharmony_ci
17798c2ecf20Sopenharmony_ci	/* this memory configuration requires special firmware */
17808c2ecf20Sopenharmony_ci	if (((RREG32(MC_SEQ_MISC0) & 0xff000000) >> 24) == 0x58)
17818c2ecf20Sopenharmony_ci		si58_fw = true;
17828c2ecf20Sopenharmony_ci
17838c2ecf20Sopenharmony_ci	DRM_INFO("Loading %s Microcode\n", new_chip_name);
17848c2ecf20Sopenharmony_ci
17858c2ecf20Sopenharmony_ci	snprintf(fw_name, sizeof(fw_name), "radeon/%s_pfp.bin", new_chip_name);
17868c2ecf20Sopenharmony_ci	err = request_firmware(&rdev->pfp_fw, fw_name, rdev->dev);
17878c2ecf20Sopenharmony_ci	if (err) {
17888c2ecf20Sopenharmony_ci		snprintf(fw_name, sizeof(fw_name), "radeon/%s_pfp.bin", chip_name);
17898c2ecf20Sopenharmony_ci		err = request_firmware(&rdev->pfp_fw, fw_name, rdev->dev);
17908c2ecf20Sopenharmony_ci		if (err)
17918c2ecf20Sopenharmony_ci			goto out;
17928c2ecf20Sopenharmony_ci		if (rdev->pfp_fw->size != pfp_req_size) {
17938c2ecf20Sopenharmony_ci			pr_err("si_cp: Bogus length %zu in firmware \"%s\"\n",
17948c2ecf20Sopenharmony_ci			       rdev->pfp_fw->size, fw_name);
17958c2ecf20Sopenharmony_ci			err = -EINVAL;
17968c2ecf20Sopenharmony_ci			goto out;
17978c2ecf20Sopenharmony_ci		}
17988c2ecf20Sopenharmony_ci	} else {
17998c2ecf20Sopenharmony_ci		err = radeon_ucode_validate(rdev->pfp_fw);
18008c2ecf20Sopenharmony_ci		if (err) {
18018c2ecf20Sopenharmony_ci			pr_err("si_cp: validation failed for firmware \"%s\"\n",
18028c2ecf20Sopenharmony_ci			       fw_name);
18038c2ecf20Sopenharmony_ci			goto out;
18048c2ecf20Sopenharmony_ci		} else {
18058c2ecf20Sopenharmony_ci			new_fw++;
18068c2ecf20Sopenharmony_ci		}
18078c2ecf20Sopenharmony_ci	}
18088c2ecf20Sopenharmony_ci
18098c2ecf20Sopenharmony_ci	snprintf(fw_name, sizeof(fw_name), "radeon/%s_me.bin", new_chip_name);
18108c2ecf20Sopenharmony_ci	err = request_firmware(&rdev->me_fw, fw_name, rdev->dev);
18118c2ecf20Sopenharmony_ci	if (err) {
18128c2ecf20Sopenharmony_ci		snprintf(fw_name, sizeof(fw_name), "radeon/%s_me.bin", chip_name);
18138c2ecf20Sopenharmony_ci		err = request_firmware(&rdev->me_fw, fw_name, rdev->dev);
18148c2ecf20Sopenharmony_ci		if (err)
18158c2ecf20Sopenharmony_ci			goto out;
18168c2ecf20Sopenharmony_ci		if (rdev->me_fw->size != me_req_size) {
18178c2ecf20Sopenharmony_ci			pr_err("si_cp: Bogus length %zu in firmware \"%s\"\n",
18188c2ecf20Sopenharmony_ci			       rdev->me_fw->size, fw_name);
18198c2ecf20Sopenharmony_ci			err = -EINVAL;
18208c2ecf20Sopenharmony_ci		}
18218c2ecf20Sopenharmony_ci	} else {
18228c2ecf20Sopenharmony_ci		err = radeon_ucode_validate(rdev->me_fw);
18238c2ecf20Sopenharmony_ci		if (err) {
18248c2ecf20Sopenharmony_ci			pr_err("si_cp: validation failed for firmware \"%s\"\n",
18258c2ecf20Sopenharmony_ci			       fw_name);
18268c2ecf20Sopenharmony_ci			goto out;
18278c2ecf20Sopenharmony_ci		} else {
18288c2ecf20Sopenharmony_ci			new_fw++;
18298c2ecf20Sopenharmony_ci		}
18308c2ecf20Sopenharmony_ci	}
18318c2ecf20Sopenharmony_ci
18328c2ecf20Sopenharmony_ci	snprintf(fw_name, sizeof(fw_name), "radeon/%s_ce.bin", new_chip_name);
18338c2ecf20Sopenharmony_ci	err = request_firmware(&rdev->ce_fw, fw_name, rdev->dev);
18348c2ecf20Sopenharmony_ci	if (err) {
18358c2ecf20Sopenharmony_ci		snprintf(fw_name, sizeof(fw_name), "radeon/%s_ce.bin", chip_name);
18368c2ecf20Sopenharmony_ci		err = request_firmware(&rdev->ce_fw, fw_name, rdev->dev);
18378c2ecf20Sopenharmony_ci		if (err)
18388c2ecf20Sopenharmony_ci			goto out;
18398c2ecf20Sopenharmony_ci		if (rdev->ce_fw->size != ce_req_size) {
18408c2ecf20Sopenharmony_ci			pr_err("si_cp: Bogus length %zu in firmware \"%s\"\n",
18418c2ecf20Sopenharmony_ci			       rdev->ce_fw->size, fw_name);
18428c2ecf20Sopenharmony_ci			err = -EINVAL;
18438c2ecf20Sopenharmony_ci		}
18448c2ecf20Sopenharmony_ci	} else {
18458c2ecf20Sopenharmony_ci		err = radeon_ucode_validate(rdev->ce_fw);
18468c2ecf20Sopenharmony_ci		if (err) {
18478c2ecf20Sopenharmony_ci			pr_err("si_cp: validation failed for firmware \"%s\"\n",
18488c2ecf20Sopenharmony_ci			       fw_name);
18498c2ecf20Sopenharmony_ci			goto out;
18508c2ecf20Sopenharmony_ci		} else {
18518c2ecf20Sopenharmony_ci			new_fw++;
18528c2ecf20Sopenharmony_ci		}
18538c2ecf20Sopenharmony_ci	}
18548c2ecf20Sopenharmony_ci
18558c2ecf20Sopenharmony_ci	snprintf(fw_name, sizeof(fw_name), "radeon/%s_rlc.bin", new_chip_name);
18568c2ecf20Sopenharmony_ci	err = request_firmware(&rdev->rlc_fw, fw_name, rdev->dev);
18578c2ecf20Sopenharmony_ci	if (err) {
18588c2ecf20Sopenharmony_ci		snprintf(fw_name, sizeof(fw_name), "radeon/%s_rlc.bin", chip_name);
18598c2ecf20Sopenharmony_ci		err = request_firmware(&rdev->rlc_fw, fw_name, rdev->dev);
18608c2ecf20Sopenharmony_ci		if (err)
18618c2ecf20Sopenharmony_ci			goto out;
18628c2ecf20Sopenharmony_ci		if (rdev->rlc_fw->size != rlc_req_size) {
18638c2ecf20Sopenharmony_ci			pr_err("si_rlc: Bogus length %zu in firmware \"%s\"\n",
18648c2ecf20Sopenharmony_ci			       rdev->rlc_fw->size, fw_name);
18658c2ecf20Sopenharmony_ci			err = -EINVAL;
18668c2ecf20Sopenharmony_ci		}
18678c2ecf20Sopenharmony_ci	} else {
18688c2ecf20Sopenharmony_ci		err = radeon_ucode_validate(rdev->rlc_fw);
18698c2ecf20Sopenharmony_ci		if (err) {
18708c2ecf20Sopenharmony_ci			pr_err("si_cp: validation failed for firmware \"%s\"\n",
18718c2ecf20Sopenharmony_ci			       fw_name);
18728c2ecf20Sopenharmony_ci			goto out;
18738c2ecf20Sopenharmony_ci		} else {
18748c2ecf20Sopenharmony_ci			new_fw++;
18758c2ecf20Sopenharmony_ci		}
18768c2ecf20Sopenharmony_ci	}
18778c2ecf20Sopenharmony_ci
18788c2ecf20Sopenharmony_ci	if (si58_fw)
18798c2ecf20Sopenharmony_ci		snprintf(fw_name, sizeof(fw_name), "radeon/si58_mc.bin");
18808c2ecf20Sopenharmony_ci	else
18818c2ecf20Sopenharmony_ci		snprintf(fw_name, sizeof(fw_name), "radeon/%s_mc.bin", new_chip_name);
18828c2ecf20Sopenharmony_ci	err = request_firmware(&rdev->mc_fw, fw_name, rdev->dev);
18838c2ecf20Sopenharmony_ci	if (err) {
18848c2ecf20Sopenharmony_ci		snprintf(fw_name, sizeof(fw_name), "radeon/%s_mc2.bin", chip_name);
18858c2ecf20Sopenharmony_ci		err = request_firmware(&rdev->mc_fw, fw_name, rdev->dev);
18868c2ecf20Sopenharmony_ci		if (err) {
18878c2ecf20Sopenharmony_ci			snprintf(fw_name, sizeof(fw_name), "radeon/%s_mc.bin", chip_name);
18888c2ecf20Sopenharmony_ci			err = request_firmware(&rdev->mc_fw, fw_name, rdev->dev);
18898c2ecf20Sopenharmony_ci			if (err)
18908c2ecf20Sopenharmony_ci				goto out;
18918c2ecf20Sopenharmony_ci		}
18928c2ecf20Sopenharmony_ci		if ((rdev->mc_fw->size != mc_req_size) &&
18938c2ecf20Sopenharmony_ci		    (rdev->mc_fw->size != mc2_req_size)) {
18948c2ecf20Sopenharmony_ci			pr_err("si_mc: Bogus length %zu in firmware \"%s\"\n",
18958c2ecf20Sopenharmony_ci			       rdev->mc_fw->size, fw_name);
18968c2ecf20Sopenharmony_ci			err = -EINVAL;
18978c2ecf20Sopenharmony_ci		}
18988c2ecf20Sopenharmony_ci		DRM_INFO("%s: %zu bytes\n", fw_name, rdev->mc_fw->size);
18998c2ecf20Sopenharmony_ci	} else {
19008c2ecf20Sopenharmony_ci		err = radeon_ucode_validate(rdev->mc_fw);
19018c2ecf20Sopenharmony_ci		if (err) {
19028c2ecf20Sopenharmony_ci			pr_err("si_cp: validation failed for firmware \"%s\"\n",
19038c2ecf20Sopenharmony_ci			       fw_name);
19048c2ecf20Sopenharmony_ci			goto out;
19058c2ecf20Sopenharmony_ci		} else {
19068c2ecf20Sopenharmony_ci			new_fw++;
19078c2ecf20Sopenharmony_ci		}
19088c2ecf20Sopenharmony_ci	}
19098c2ecf20Sopenharmony_ci
19108c2ecf20Sopenharmony_ci	if (banks2_fw)
19118c2ecf20Sopenharmony_ci		snprintf(fw_name, sizeof(fw_name), "radeon/banks_k_2_smc.bin");
19128c2ecf20Sopenharmony_ci	else if (new_smc)
19138c2ecf20Sopenharmony_ci		snprintf(fw_name, sizeof(fw_name), "radeon/%s_k_smc.bin", new_chip_name);
19148c2ecf20Sopenharmony_ci	else
19158c2ecf20Sopenharmony_ci		snprintf(fw_name, sizeof(fw_name), "radeon/%s_smc.bin", new_chip_name);
19168c2ecf20Sopenharmony_ci	err = request_firmware(&rdev->smc_fw, fw_name, rdev->dev);
19178c2ecf20Sopenharmony_ci	if (err) {
19188c2ecf20Sopenharmony_ci		snprintf(fw_name, sizeof(fw_name), "radeon/%s_smc.bin", chip_name);
19198c2ecf20Sopenharmony_ci		err = request_firmware(&rdev->smc_fw, fw_name, rdev->dev);
19208c2ecf20Sopenharmony_ci		if (err) {
19218c2ecf20Sopenharmony_ci			pr_err("smc: error loading firmware \"%s\"\n", fw_name);
19228c2ecf20Sopenharmony_ci			release_firmware(rdev->smc_fw);
19238c2ecf20Sopenharmony_ci			rdev->smc_fw = NULL;
19248c2ecf20Sopenharmony_ci			err = 0;
19258c2ecf20Sopenharmony_ci		} else if (rdev->smc_fw->size != smc_req_size) {
19268c2ecf20Sopenharmony_ci			pr_err("si_smc: Bogus length %zu in firmware \"%s\"\n",
19278c2ecf20Sopenharmony_ci			       rdev->smc_fw->size, fw_name);
19288c2ecf20Sopenharmony_ci			err = -EINVAL;
19298c2ecf20Sopenharmony_ci		}
19308c2ecf20Sopenharmony_ci	} else {
19318c2ecf20Sopenharmony_ci		err = radeon_ucode_validate(rdev->smc_fw);
19328c2ecf20Sopenharmony_ci		if (err) {
19338c2ecf20Sopenharmony_ci			pr_err("si_cp: validation failed for firmware \"%s\"\n",
19348c2ecf20Sopenharmony_ci			       fw_name);
19358c2ecf20Sopenharmony_ci			goto out;
19368c2ecf20Sopenharmony_ci		} else {
19378c2ecf20Sopenharmony_ci			new_fw++;
19388c2ecf20Sopenharmony_ci		}
19398c2ecf20Sopenharmony_ci	}
19408c2ecf20Sopenharmony_ci
19418c2ecf20Sopenharmony_ci	if (new_fw == 0) {
19428c2ecf20Sopenharmony_ci		rdev->new_fw = false;
19438c2ecf20Sopenharmony_ci	} else if (new_fw < 6) {
19448c2ecf20Sopenharmony_ci		pr_err("si_fw: mixing new and old firmware!\n");
19458c2ecf20Sopenharmony_ci		err = -EINVAL;
19468c2ecf20Sopenharmony_ci	} else {
19478c2ecf20Sopenharmony_ci		rdev->new_fw = true;
19488c2ecf20Sopenharmony_ci	}
19498c2ecf20Sopenharmony_ciout:
19508c2ecf20Sopenharmony_ci	if (err) {
19518c2ecf20Sopenharmony_ci		if (err != -EINVAL)
19528c2ecf20Sopenharmony_ci			pr_err("si_cp: Failed to load firmware \"%s\"\n",
19538c2ecf20Sopenharmony_ci			       fw_name);
19548c2ecf20Sopenharmony_ci		release_firmware(rdev->pfp_fw);
19558c2ecf20Sopenharmony_ci		rdev->pfp_fw = NULL;
19568c2ecf20Sopenharmony_ci		release_firmware(rdev->me_fw);
19578c2ecf20Sopenharmony_ci		rdev->me_fw = NULL;
19588c2ecf20Sopenharmony_ci		release_firmware(rdev->ce_fw);
19598c2ecf20Sopenharmony_ci		rdev->ce_fw = NULL;
19608c2ecf20Sopenharmony_ci		release_firmware(rdev->rlc_fw);
19618c2ecf20Sopenharmony_ci		rdev->rlc_fw = NULL;
19628c2ecf20Sopenharmony_ci		release_firmware(rdev->mc_fw);
19638c2ecf20Sopenharmony_ci		rdev->mc_fw = NULL;
19648c2ecf20Sopenharmony_ci		release_firmware(rdev->smc_fw);
19658c2ecf20Sopenharmony_ci		rdev->smc_fw = NULL;
19668c2ecf20Sopenharmony_ci	}
19678c2ecf20Sopenharmony_ci	return err;
19688c2ecf20Sopenharmony_ci}
19698c2ecf20Sopenharmony_ci
19708c2ecf20Sopenharmony_ci/* watermark setup */
19718c2ecf20Sopenharmony_cistatic u32 dce6_line_buffer_adjust(struct radeon_device *rdev,
19728c2ecf20Sopenharmony_ci				   struct radeon_crtc *radeon_crtc,
19738c2ecf20Sopenharmony_ci				   struct drm_display_mode *mode,
19748c2ecf20Sopenharmony_ci				   struct drm_display_mode *other_mode)
19758c2ecf20Sopenharmony_ci{
19768c2ecf20Sopenharmony_ci	u32 tmp, buffer_alloc, i;
19778c2ecf20Sopenharmony_ci	u32 pipe_offset = radeon_crtc->crtc_id * 0x20;
19788c2ecf20Sopenharmony_ci	/*
19798c2ecf20Sopenharmony_ci	 * Line Buffer Setup
19808c2ecf20Sopenharmony_ci	 * There are 3 line buffers, each one shared by 2 display controllers.
19818c2ecf20Sopenharmony_ci	 * DC_LB_MEMORY_SPLIT controls how that line buffer is shared between
19828c2ecf20Sopenharmony_ci	 * the display controllers.  The paritioning is done via one of four
19838c2ecf20Sopenharmony_ci	 * preset allocations specified in bits 21:20:
19848c2ecf20Sopenharmony_ci	 *  0 - half lb
19858c2ecf20Sopenharmony_ci	 *  2 - whole lb, other crtc must be disabled
19868c2ecf20Sopenharmony_ci	 */
19878c2ecf20Sopenharmony_ci	/* this can get tricky if we have two large displays on a paired group
19888c2ecf20Sopenharmony_ci	 * of crtcs.  Ideally for multiple large displays we'd assign them to
19898c2ecf20Sopenharmony_ci	 * non-linked crtcs for maximum line buffer allocation.
19908c2ecf20Sopenharmony_ci	 */
19918c2ecf20Sopenharmony_ci	if (radeon_crtc->base.enabled && mode) {
19928c2ecf20Sopenharmony_ci		if (other_mode) {
19938c2ecf20Sopenharmony_ci			tmp = 0; /* 1/2 */
19948c2ecf20Sopenharmony_ci			buffer_alloc = 1;
19958c2ecf20Sopenharmony_ci		} else {
19968c2ecf20Sopenharmony_ci			tmp = 2; /* whole */
19978c2ecf20Sopenharmony_ci			buffer_alloc = 2;
19988c2ecf20Sopenharmony_ci		}
19998c2ecf20Sopenharmony_ci	} else {
20008c2ecf20Sopenharmony_ci		tmp = 0;
20018c2ecf20Sopenharmony_ci		buffer_alloc = 0;
20028c2ecf20Sopenharmony_ci	}
20038c2ecf20Sopenharmony_ci
20048c2ecf20Sopenharmony_ci	WREG32(DC_LB_MEMORY_SPLIT + radeon_crtc->crtc_offset,
20058c2ecf20Sopenharmony_ci	       DC_LB_MEMORY_CONFIG(tmp));
20068c2ecf20Sopenharmony_ci
20078c2ecf20Sopenharmony_ci	WREG32(PIPE0_DMIF_BUFFER_CONTROL + pipe_offset,
20088c2ecf20Sopenharmony_ci	       DMIF_BUFFERS_ALLOCATED(buffer_alloc));
20098c2ecf20Sopenharmony_ci	for (i = 0; i < rdev->usec_timeout; i++) {
20108c2ecf20Sopenharmony_ci		if (RREG32(PIPE0_DMIF_BUFFER_CONTROL + pipe_offset) &
20118c2ecf20Sopenharmony_ci		    DMIF_BUFFERS_ALLOCATED_COMPLETED)
20128c2ecf20Sopenharmony_ci			break;
20138c2ecf20Sopenharmony_ci		udelay(1);
20148c2ecf20Sopenharmony_ci	}
20158c2ecf20Sopenharmony_ci
20168c2ecf20Sopenharmony_ci	if (radeon_crtc->base.enabled && mode) {
20178c2ecf20Sopenharmony_ci		switch (tmp) {
20188c2ecf20Sopenharmony_ci		case 0:
20198c2ecf20Sopenharmony_ci		default:
20208c2ecf20Sopenharmony_ci			return 4096 * 2;
20218c2ecf20Sopenharmony_ci		case 2:
20228c2ecf20Sopenharmony_ci			return 8192 * 2;
20238c2ecf20Sopenharmony_ci		}
20248c2ecf20Sopenharmony_ci	}
20258c2ecf20Sopenharmony_ci
20268c2ecf20Sopenharmony_ci	/* controller not enabled, so no lb used */
20278c2ecf20Sopenharmony_ci	return 0;
20288c2ecf20Sopenharmony_ci}
20298c2ecf20Sopenharmony_ci
20308c2ecf20Sopenharmony_cistatic u32 si_get_number_of_dram_channels(struct radeon_device *rdev)
20318c2ecf20Sopenharmony_ci{
20328c2ecf20Sopenharmony_ci	u32 tmp = RREG32(MC_SHARED_CHMAP);
20338c2ecf20Sopenharmony_ci
20348c2ecf20Sopenharmony_ci	switch ((tmp & NOOFCHAN_MASK) >> NOOFCHAN_SHIFT) {
20358c2ecf20Sopenharmony_ci	case 0:
20368c2ecf20Sopenharmony_ci	default:
20378c2ecf20Sopenharmony_ci		return 1;
20388c2ecf20Sopenharmony_ci	case 1:
20398c2ecf20Sopenharmony_ci		return 2;
20408c2ecf20Sopenharmony_ci	case 2:
20418c2ecf20Sopenharmony_ci		return 4;
20428c2ecf20Sopenharmony_ci	case 3:
20438c2ecf20Sopenharmony_ci		return 8;
20448c2ecf20Sopenharmony_ci	case 4:
20458c2ecf20Sopenharmony_ci		return 3;
20468c2ecf20Sopenharmony_ci	case 5:
20478c2ecf20Sopenharmony_ci		return 6;
20488c2ecf20Sopenharmony_ci	case 6:
20498c2ecf20Sopenharmony_ci		return 10;
20508c2ecf20Sopenharmony_ci	case 7:
20518c2ecf20Sopenharmony_ci		return 12;
20528c2ecf20Sopenharmony_ci	case 8:
20538c2ecf20Sopenharmony_ci		return 16;
20548c2ecf20Sopenharmony_ci	}
20558c2ecf20Sopenharmony_ci}
20568c2ecf20Sopenharmony_ci
20578c2ecf20Sopenharmony_cistruct dce6_wm_params {
20588c2ecf20Sopenharmony_ci	u32 dram_channels; /* number of dram channels */
20598c2ecf20Sopenharmony_ci	u32 yclk;          /* bandwidth per dram data pin in kHz */
20608c2ecf20Sopenharmony_ci	u32 sclk;          /* engine clock in kHz */
20618c2ecf20Sopenharmony_ci	u32 disp_clk;      /* display clock in kHz */
20628c2ecf20Sopenharmony_ci	u32 src_width;     /* viewport width */
20638c2ecf20Sopenharmony_ci	u32 active_time;   /* active display time in ns */
20648c2ecf20Sopenharmony_ci	u32 blank_time;    /* blank time in ns */
20658c2ecf20Sopenharmony_ci	bool interlaced;    /* mode is interlaced */
20668c2ecf20Sopenharmony_ci	fixed20_12 vsc;    /* vertical scale ratio */
20678c2ecf20Sopenharmony_ci	u32 num_heads;     /* number of active crtcs */
20688c2ecf20Sopenharmony_ci	u32 bytes_per_pixel; /* bytes per pixel display + overlay */
20698c2ecf20Sopenharmony_ci	u32 lb_size;       /* line buffer allocated to pipe */
20708c2ecf20Sopenharmony_ci	u32 vtaps;         /* vertical scaler taps */
20718c2ecf20Sopenharmony_ci};
20728c2ecf20Sopenharmony_ci
20738c2ecf20Sopenharmony_cistatic u32 dce6_dram_bandwidth(struct dce6_wm_params *wm)
20748c2ecf20Sopenharmony_ci{
20758c2ecf20Sopenharmony_ci	/* Calculate raw DRAM Bandwidth */
20768c2ecf20Sopenharmony_ci	fixed20_12 dram_efficiency; /* 0.7 */
20778c2ecf20Sopenharmony_ci	fixed20_12 yclk, dram_channels, bandwidth;
20788c2ecf20Sopenharmony_ci	fixed20_12 a;
20798c2ecf20Sopenharmony_ci
20808c2ecf20Sopenharmony_ci	a.full = dfixed_const(1000);
20818c2ecf20Sopenharmony_ci	yclk.full = dfixed_const(wm->yclk);
20828c2ecf20Sopenharmony_ci	yclk.full = dfixed_div(yclk, a);
20838c2ecf20Sopenharmony_ci	dram_channels.full = dfixed_const(wm->dram_channels * 4);
20848c2ecf20Sopenharmony_ci	a.full = dfixed_const(10);
20858c2ecf20Sopenharmony_ci	dram_efficiency.full = dfixed_const(7);
20868c2ecf20Sopenharmony_ci	dram_efficiency.full = dfixed_div(dram_efficiency, a);
20878c2ecf20Sopenharmony_ci	bandwidth.full = dfixed_mul(dram_channels, yclk);
20888c2ecf20Sopenharmony_ci	bandwidth.full = dfixed_mul(bandwidth, dram_efficiency);
20898c2ecf20Sopenharmony_ci
20908c2ecf20Sopenharmony_ci	return dfixed_trunc(bandwidth);
20918c2ecf20Sopenharmony_ci}
20928c2ecf20Sopenharmony_ci
20938c2ecf20Sopenharmony_cistatic u32 dce6_dram_bandwidth_for_display(struct dce6_wm_params *wm)
20948c2ecf20Sopenharmony_ci{
20958c2ecf20Sopenharmony_ci	/* Calculate DRAM Bandwidth and the part allocated to display. */
20968c2ecf20Sopenharmony_ci	fixed20_12 disp_dram_allocation; /* 0.3 to 0.7 */
20978c2ecf20Sopenharmony_ci	fixed20_12 yclk, dram_channels, bandwidth;
20988c2ecf20Sopenharmony_ci	fixed20_12 a;
20998c2ecf20Sopenharmony_ci
21008c2ecf20Sopenharmony_ci	a.full = dfixed_const(1000);
21018c2ecf20Sopenharmony_ci	yclk.full = dfixed_const(wm->yclk);
21028c2ecf20Sopenharmony_ci	yclk.full = dfixed_div(yclk, a);
21038c2ecf20Sopenharmony_ci	dram_channels.full = dfixed_const(wm->dram_channels * 4);
21048c2ecf20Sopenharmony_ci	a.full = dfixed_const(10);
21058c2ecf20Sopenharmony_ci	disp_dram_allocation.full = dfixed_const(3); /* XXX worse case value 0.3 */
21068c2ecf20Sopenharmony_ci	disp_dram_allocation.full = dfixed_div(disp_dram_allocation, a);
21078c2ecf20Sopenharmony_ci	bandwidth.full = dfixed_mul(dram_channels, yclk);
21088c2ecf20Sopenharmony_ci	bandwidth.full = dfixed_mul(bandwidth, disp_dram_allocation);
21098c2ecf20Sopenharmony_ci
21108c2ecf20Sopenharmony_ci	return dfixed_trunc(bandwidth);
21118c2ecf20Sopenharmony_ci}
21128c2ecf20Sopenharmony_ci
21138c2ecf20Sopenharmony_cistatic u32 dce6_data_return_bandwidth(struct dce6_wm_params *wm)
21148c2ecf20Sopenharmony_ci{
21158c2ecf20Sopenharmony_ci	/* Calculate the display Data return Bandwidth */
21168c2ecf20Sopenharmony_ci	fixed20_12 return_efficiency; /* 0.8 */
21178c2ecf20Sopenharmony_ci	fixed20_12 sclk, bandwidth;
21188c2ecf20Sopenharmony_ci	fixed20_12 a;
21198c2ecf20Sopenharmony_ci
21208c2ecf20Sopenharmony_ci	a.full = dfixed_const(1000);
21218c2ecf20Sopenharmony_ci	sclk.full = dfixed_const(wm->sclk);
21228c2ecf20Sopenharmony_ci	sclk.full = dfixed_div(sclk, a);
21238c2ecf20Sopenharmony_ci	a.full = dfixed_const(10);
21248c2ecf20Sopenharmony_ci	return_efficiency.full = dfixed_const(8);
21258c2ecf20Sopenharmony_ci	return_efficiency.full = dfixed_div(return_efficiency, a);
21268c2ecf20Sopenharmony_ci	a.full = dfixed_const(32);
21278c2ecf20Sopenharmony_ci	bandwidth.full = dfixed_mul(a, sclk);
21288c2ecf20Sopenharmony_ci	bandwidth.full = dfixed_mul(bandwidth, return_efficiency);
21298c2ecf20Sopenharmony_ci
21308c2ecf20Sopenharmony_ci	return dfixed_trunc(bandwidth);
21318c2ecf20Sopenharmony_ci}
21328c2ecf20Sopenharmony_ci
21338c2ecf20Sopenharmony_cistatic u32 dce6_get_dmif_bytes_per_request(struct dce6_wm_params *wm)
21348c2ecf20Sopenharmony_ci{
21358c2ecf20Sopenharmony_ci	return 32;
21368c2ecf20Sopenharmony_ci}
21378c2ecf20Sopenharmony_ci
21388c2ecf20Sopenharmony_cistatic u32 dce6_dmif_request_bandwidth(struct dce6_wm_params *wm)
21398c2ecf20Sopenharmony_ci{
21408c2ecf20Sopenharmony_ci	/* Calculate the DMIF Request Bandwidth */
21418c2ecf20Sopenharmony_ci	fixed20_12 disp_clk_request_efficiency; /* 0.8 */
21428c2ecf20Sopenharmony_ci	fixed20_12 disp_clk, sclk, bandwidth;
21438c2ecf20Sopenharmony_ci	fixed20_12 a, b1, b2;
21448c2ecf20Sopenharmony_ci	u32 min_bandwidth;
21458c2ecf20Sopenharmony_ci
21468c2ecf20Sopenharmony_ci	a.full = dfixed_const(1000);
21478c2ecf20Sopenharmony_ci	disp_clk.full = dfixed_const(wm->disp_clk);
21488c2ecf20Sopenharmony_ci	disp_clk.full = dfixed_div(disp_clk, a);
21498c2ecf20Sopenharmony_ci	a.full = dfixed_const(dce6_get_dmif_bytes_per_request(wm) / 2);
21508c2ecf20Sopenharmony_ci	b1.full = dfixed_mul(a, disp_clk);
21518c2ecf20Sopenharmony_ci
21528c2ecf20Sopenharmony_ci	a.full = dfixed_const(1000);
21538c2ecf20Sopenharmony_ci	sclk.full = dfixed_const(wm->sclk);
21548c2ecf20Sopenharmony_ci	sclk.full = dfixed_div(sclk, a);
21558c2ecf20Sopenharmony_ci	a.full = dfixed_const(dce6_get_dmif_bytes_per_request(wm));
21568c2ecf20Sopenharmony_ci	b2.full = dfixed_mul(a, sclk);
21578c2ecf20Sopenharmony_ci
21588c2ecf20Sopenharmony_ci	a.full = dfixed_const(10);
21598c2ecf20Sopenharmony_ci	disp_clk_request_efficiency.full = dfixed_const(8);
21608c2ecf20Sopenharmony_ci	disp_clk_request_efficiency.full = dfixed_div(disp_clk_request_efficiency, a);
21618c2ecf20Sopenharmony_ci
21628c2ecf20Sopenharmony_ci	min_bandwidth = min(dfixed_trunc(b1), dfixed_trunc(b2));
21638c2ecf20Sopenharmony_ci
21648c2ecf20Sopenharmony_ci	a.full = dfixed_const(min_bandwidth);
21658c2ecf20Sopenharmony_ci	bandwidth.full = dfixed_mul(a, disp_clk_request_efficiency);
21668c2ecf20Sopenharmony_ci
21678c2ecf20Sopenharmony_ci	return dfixed_trunc(bandwidth);
21688c2ecf20Sopenharmony_ci}
21698c2ecf20Sopenharmony_ci
21708c2ecf20Sopenharmony_cistatic u32 dce6_available_bandwidth(struct dce6_wm_params *wm)
21718c2ecf20Sopenharmony_ci{
21728c2ecf20Sopenharmony_ci	/* Calculate the Available bandwidth. Display can use this temporarily but not in average. */
21738c2ecf20Sopenharmony_ci	u32 dram_bandwidth = dce6_dram_bandwidth(wm);
21748c2ecf20Sopenharmony_ci	u32 data_return_bandwidth = dce6_data_return_bandwidth(wm);
21758c2ecf20Sopenharmony_ci	u32 dmif_req_bandwidth = dce6_dmif_request_bandwidth(wm);
21768c2ecf20Sopenharmony_ci
21778c2ecf20Sopenharmony_ci	return min(dram_bandwidth, min(data_return_bandwidth, dmif_req_bandwidth));
21788c2ecf20Sopenharmony_ci}
21798c2ecf20Sopenharmony_ci
21808c2ecf20Sopenharmony_cistatic u32 dce6_average_bandwidth(struct dce6_wm_params *wm)
21818c2ecf20Sopenharmony_ci{
21828c2ecf20Sopenharmony_ci	/* Calculate the display mode Average Bandwidth
21838c2ecf20Sopenharmony_ci	 * DisplayMode should contain the source and destination dimensions,
21848c2ecf20Sopenharmony_ci	 * timing, etc.
21858c2ecf20Sopenharmony_ci	 */
21868c2ecf20Sopenharmony_ci	fixed20_12 bpp;
21878c2ecf20Sopenharmony_ci	fixed20_12 line_time;
21888c2ecf20Sopenharmony_ci	fixed20_12 src_width;
21898c2ecf20Sopenharmony_ci	fixed20_12 bandwidth;
21908c2ecf20Sopenharmony_ci	fixed20_12 a;
21918c2ecf20Sopenharmony_ci
21928c2ecf20Sopenharmony_ci	a.full = dfixed_const(1000);
21938c2ecf20Sopenharmony_ci	line_time.full = dfixed_const(wm->active_time + wm->blank_time);
21948c2ecf20Sopenharmony_ci	line_time.full = dfixed_div(line_time, a);
21958c2ecf20Sopenharmony_ci	bpp.full = dfixed_const(wm->bytes_per_pixel);
21968c2ecf20Sopenharmony_ci	src_width.full = dfixed_const(wm->src_width);
21978c2ecf20Sopenharmony_ci	bandwidth.full = dfixed_mul(src_width, bpp);
21988c2ecf20Sopenharmony_ci	bandwidth.full = dfixed_mul(bandwidth, wm->vsc);
21998c2ecf20Sopenharmony_ci	bandwidth.full = dfixed_div(bandwidth, line_time);
22008c2ecf20Sopenharmony_ci
22018c2ecf20Sopenharmony_ci	return dfixed_trunc(bandwidth);
22028c2ecf20Sopenharmony_ci}
22038c2ecf20Sopenharmony_ci
22048c2ecf20Sopenharmony_cistatic u32 dce6_latency_watermark(struct dce6_wm_params *wm)
22058c2ecf20Sopenharmony_ci{
22068c2ecf20Sopenharmony_ci	/* First calcualte the latency in ns */
22078c2ecf20Sopenharmony_ci	u32 mc_latency = 2000; /* 2000 ns. */
22088c2ecf20Sopenharmony_ci	u32 available_bandwidth = dce6_available_bandwidth(wm);
22098c2ecf20Sopenharmony_ci	u32 worst_chunk_return_time = (512 * 8 * 1000) / available_bandwidth;
22108c2ecf20Sopenharmony_ci	u32 cursor_line_pair_return_time = (128 * 4 * 1000) / available_bandwidth;
22118c2ecf20Sopenharmony_ci	u32 dc_latency = 40000000 / wm->disp_clk; /* dc pipe latency */
22128c2ecf20Sopenharmony_ci	u32 other_heads_data_return_time = ((wm->num_heads + 1) * worst_chunk_return_time) +
22138c2ecf20Sopenharmony_ci		(wm->num_heads * cursor_line_pair_return_time);
22148c2ecf20Sopenharmony_ci	u32 latency = mc_latency + other_heads_data_return_time + dc_latency;
22158c2ecf20Sopenharmony_ci	u32 max_src_lines_per_dst_line, lb_fill_bw, line_fill_time;
22168c2ecf20Sopenharmony_ci	u32 tmp, dmif_size = 12288;
22178c2ecf20Sopenharmony_ci	fixed20_12 a, b, c;
22188c2ecf20Sopenharmony_ci
22198c2ecf20Sopenharmony_ci	if (wm->num_heads == 0)
22208c2ecf20Sopenharmony_ci		return 0;
22218c2ecf20Sopenharmony_ci
22228c2ecf20Sopenharmony_ci	a.full = dfixed_const(2);
22238c2ecf20Sopenharmony_ci	b.full = dfixed_const(1);
22248c2ecf20Sopenharmony_ci	if ((wm->vsc.full > a.full) ||
22258c2ecf20Sopenharmony_ci	    ((wm->vsc.full > b.full) && (wm->vtaps >= 3)) ||
22268c2ecf20Sopenharmony_ci	    (wm->vtaps >= 5) ||
22278c2ecf20Sopenharmony_ci	    ((wm->vsc.full >= a.full) && wm->interlaced))
22288c2ecf20Sopenharmony_ci		max_src_lines_per_dst_line = 4;
22298c2ecf20Sopenharmony_ci	else
22308c2ecf20Sopenharmony_ci		max_src_lines_per_dst_line = 2;
22318c2ecf20Sopenharmony_ci
22328c2ecf20Sopenharmony_ci	a.full = dfixed_const(available_bandwidth);
22338c2ecf20Sopenharmony_ci	b.full = dfixed_const(wm->num_heads);
22348c2ecf20Sopenharmony_ci	a.full = dfixed_div(a, b);
22358c2ecf20Sopenharmony_ci	tmp = div_u64((u64) dmif_size * (u64) wm->disp_clk, mc_latency + 512);
22368c2ecf20Sopenharmony_ci	tmp = min(dfixed_trunc(a), tmp);
22378c2ecf20Sopenharmony_ci
22388c2ecf20Sopenharmony_ci	lb_fill_bw = min(tmp, wm->disp_clk * wm->bytes_per_pixel / 1000);
22398c2ecf20Sopenharmony_ci
22408c2ecf20Sopenharmony_ci	a.full = dfixed_const(max_src_lines_per_dst_line * wm->src_width * wm->bytes_per_pixel);
22418c2ecf20Sopenharmony_ci	b.full = dfixed_const(1000);
22428c2ecf20Sopenharmony_ci	c.full = dfixed_const(lb_fill_bw);
22438c2ecf20Sopenharmony_ci	b.full = dfixed_div(c, b);
22448c2ecf20Sopenharmony_ci	a.full = dfixed_div(a, b);
22458c2ecf20Sopenharmony_ci	line_fill_time = dfixed_trunc(a);
22468c2ecf20Sopenharmony_ci
22478c2ecf20Sopenharmony_ci	if (line_fill_time < wm->active_time)
22488c2ecf20Sopenharmony_ci		return latency;
22498c2ecf20Sopenharmony_ci	else
22508c2ecf20Sopenharmony_ci		return latency + (line_fill_time - wm->active_time);
22518c2ecf20Sopenharmony_ci
22528c2ecf20Sopenharmony_ci}
22538c2ecf20Sopenharmony_ci
22548c2ecf20Sopenharmony_cistatic bool dce6_average_bandwidth_vs_dram_bandwidth_for_display(struct dce6_wm_params *wm)
22558c2ecf20Sopenharmony_ci{
22568c2ecf20Sopenharmony_ci	if (dce6_average_bandwidth(wm) <=
22578c2ecf20Sopenharmony_ci	    (dce6_dram_bandwidth_for_display(wm) / wm->num_heads))
22588c2ecf20Sopenharmony_ci		return true;
22598c2ecf20Sopenharmony_ci	else
22608c2ecf20Sopenharmony_ci		return false;
22618c2ecf20Sopenharmony_ci};
22628c2ecf20Sopenharmony_ci
22638c2ecf20Sopenharmony_cistatic bool dce6_average_bandwidth_vs_available_bandwidth(struct dce6_wm_params *wm)
22648c2ecf20Sopenharmony_ci{
22658c2ecf20Sopenharmony_ci	if (dce6_average_bandwidth(wm) <=
22668c2ecf20Sopenharmony_ci	    (dce6_available_bandwidth(wm) / wm->num_heads))
22678c2ecf20Sopenharmony_ci		return true;
22688c2ecf20Sopenharmony_ci	else
22698c2ecf20Sopenharmony_ci		return false;
22708c2ecf20Sopenharmony_ci};
22718c2ecf20Sopenharmony_ci
22728c2ecf20Sopenharmony_cistatic bool dce6_check_latency_hiding(struct dce6_wm_params *wm)
22738c2ecf20Sopenharmony_ci{
22748c2ecf20Sopenharmony_ci	u32 lb_partitions = wm->lb_size / wm->src_width;
22758c2ecf20Sopenharmony_ci	u32 line_time = wm->active_time + wm->blank_time;
22768c2ecf20Sopenharmony_ci	u32 latency_tolerant_lines;
22778c2ecf20Sopenharmony_ci	u32 latency_hiding;
22788c2ecf20Sopenharmony_ci	fixed20_12 a;
22798c2ecf20Sopenharmony_ci
22808c2ecf20Sopenharmony_ci	a.full = dfixed_const(1);
22818c2ecf20Sopenharmony_ci	if (wm->vsc.full > a.full)
22828c2ecf20Sopenharmony_ci		latency_tolerant_lines = 1;
22838c2ecf20Sopenharmony_ci	else {
22848c2ecf20Sopenharmony_ci		if (lb_partitions <= (wm->vtaps + 1))
22858c2ecf20Sopenharmony_ci			latency_tolerant_lines = 1;
22868c2ecf20Sopenharmony_ci		else
22878c2ecf20Sopenharmony_ci			latency_tolerant_lines = 2;
22888c2ecf20Sopenharmony_ci	}
22898c2ecf20Sopenharmony_ci
22908c2ecf20Sopenharmony_ci	latency_hiding = (latency_tolerant_lines * line_time + wm->blank_time);
22918c2ecf20Sopenharmony_ci
22928c2ecf20Sopenharmony_ci	if (dce6_latency_watermark(wm) <= latency_hiding)
22938c2ecf20Sopenharmony_ci		return true;
22948c2ecf20Sopenharmony_ci	else
22958c2ecf20Sopenharmony_ci		return false;
22968c2ecf20Sopenharmony_ci}
22978c2ecf20Sopenharmony_ci
22988c2ecf20Sopenharmony_cistatic void dce6_program_watermarks(struct radeon_device *rdev,
22998c2ecf20Sopenharmony_ci					 struct radeon_crtc *radeon_crtc,
23008c2ecf20Sopenharmony_ci					 u32 lb_size, u32 num_heads)
23018c2ecf20Sopenharmony_ci{
23028c2ecf20Sopenharmony_ci	struct drm_display_mode *mode = &radeon_crtc->base.mode;
23038c2ecf20Sopenharmony_ci	struct dce6_wm_params wm_low, wm_high;
23048c2ecf20Sopenharmony_ci	u32 dram_channels;
23058c2ecf20Sopenharmony_ci	u32 active_time;
23068c2ecf20Sopenharmony_ci	u32 line_time = 0;
23078c2ecf20Sopenharmony_ci	u32 latency_watermark_a = 0, latency_watermark_b = 0;
23088c2ecf20Sopenharmony_ci	u32 priority_a_mark = 0, priority_b_mark = 0;
23098c2ecf20Sopenharmony_ci	u32 priority_a_cnt = PRIORITY_OFF;
23108c2ecf20Sopenharmony_ci	u32 priority_b_cnt = PRIORITY_OFF;
23118c2ecf20Sopenharmony_ci	u32 tmp, arb_control3;
23128c2ecf20Sopenharmony_ci	fixed20_12 a, b, c;
23138c2ecf20Sopenharmony_ci
23148c2ecf20Sopenharmony_ci	if (radeon_crtc->base.enabled && num_heads && mode) {
23158c2ecf20Sopenharmony_ci		active_time = (u32) div_u64((u64)mode->crtc_hdisplay * 1000000,
23168c2ecf20Sopenharmony_ci					    (u32)mode->clock);
23178c2ecf20Sopenharmony_ci		line_time = (u32) div_u64((u64)mode->crtc_htotal * 1000000,
23188c2ecf20Sopenharmony_ci					  (u32)mode->clock);
23198c2ecf20Sopenharmony_ci		line_time = min(line_time, (u32)65535);
23208c2ecf20Sopenharmony_ci		priority_a_cnt = 0;
23218c2ecf20Sopenharmony_ci		priority_b_cnt = 0;
23228c2ecf20Sopenharmony_ci
23238c2ecf20Sopenharmony_ci		if (rdev->family == CHIP_ARUBA)
23248c2ecf20Sopenharmony_ci			dram_channels = evergreen_get_number_of_dram_channels(rdev);
23258c2ecf20Sopenharmony_ci		else
23268c2ecf20Sopenharmony_ci			dram_channels = si_get_number_of_dram_channels(rdev);
23278c2ecf20Sopenharmony_ci
23288c2ecf20Sopenharmony_ci		/* watermark for high clocks */
23298c2ecf20Sopenharmony_ci		if ((rdev->pm.pm_method == PM_METHOD_DPM) && rdev->pm.dpm_enabled) {
23308c2ecf20Sopenharmony_ci			wm_high.yclk =
23318c2ecf20Sopenharmony_ci				radeon_dpm_get_mclk(rdev, false) * 10;
23328c2ecf20Sopenharmony_ci			wm_high.sclk =
23338c2ecf20Sopenharmony_ci				radeon_dpm_get_sclk(rdev, false) * 10;
23348c2ecf20Sopenharmony_ci		} else {
23358c2ecf20Sopenharmony_ci			wm_high.yclk = rdev->pm.current_mclk * 10;
23368c2ecf20Sopenharmony_ci			wm_high.sclk = rdev->pm.current_sclk * 10;
23378c2ecf20Sopenharmony_ci		}
23388c2ecf20Sopenharmony_ci
23398c2ecf20Sopenharmony_ci		wm_high.disp_clk = mode->clock;
23408c2ecf20Sopenharmony_ci		wm_high.src_width = mode->crtc_hdisplay;
23418c2ecf20Sopenharmony_ci		wm_high.active_time = active_time;
23428c2ecf20Sopenharmony_ci		wm_high.blank_time = line_time - wm_high.active_time;
23438c2ecf20Sopenharmony_ci		wm_high.interlaced = false;
23448c2ecf20Sopenharmony_ci		if (mode->flags & DRM_MODE_FLAG_INTERLACE)
23458c2ecf20Sopenharmony_ci			wm_high.interlaced = true;
23468c2ecf20Sopenharmony_ci		wm_high.vsc = radeon_crtc->vsc;
23478c2ecf20Sopenharmony_ci		wm_high.vtaps = 1;
23488c2ecf20Sopenharmony_ci		if (radeon_crtc->rmx_type != RMX_OFF)
23498c2ecf20Sopenharmony_ci			wm_high.vtaps = 2;
23508c2ecf20Sopenharmony_ci		wm_high.bytes_per_pixel = 4; /* XXX: get this from fb config */
23518c2ecf20Sopenharmony_ci		wm_high.lb_size = lb_size;
23528c2ecf20Sopenharmony_ci		wm_high.dram_channels = dram_channels;
23538c2ecf20Sopenharmony_ci		wm_high.num_heads = num_heads;
23548c2ecf20Sopenharmony_ci
23558c2ecf20Sopenharmony_ci		/* watermark for low clocks */
23568c2ecf20Sopenharmony_ci		if ((rdev->pm.pm_method == PM_METHOD_DPM) && rdev->pm.dpm_enabled) {
23578c2ecf20Sopenharmony_ci			wm_low.yclk =
23588c2ecf20Sopenharmony_ci				radeon_dpm_get_mclk(rdev, true) * 10;
23598c2ecf20Sopenharmony_ci			wm_low.sclk =
23608c2ecf20Sopenharmony_ci				radeon_dpm_get_sclk(rdev, true) * 10;
23618c2ecf20Sopenharmony_ci		} else {
23628c2ecf20Sopenharmony_ci			wm_low.yclk = rdev->pm.current_mclk * 10;
23638c2ecf20Sopenharmony_ci			wm_low.sclk = rdev->pm.current_sclk * 10;
23648c2ecf20Sopenharmony_ci		}
23658c2ecf20Sopenharmony_ci
23668c2ecf20Sopenharmony_ci		wm_low.disp_clk = mode->clock;
23678c2ecf20Sopenharmony_ci		wm_low.src_width = mode->crtc_hdisplay;
23688c2ecf20Sopenharmony_ci		wm_low.active_time = active_time;
23698c2ecf20Sopenharmony_ci		wm_low.blank_time = line_time - wm_low.active_time;
23708c2ecf20Sopenharmony_ci		wm_low.interlaced = false;
23718c2ecf20Sopenharmony_ci		if (mode->flags & DRM_MODE_FLAG_INTERLACE)
23728c2ecf20Sopenharmony_ci			wm_low.interlaced = true;
23738c2ecf20Sopenharmony_ci		wm_low.vsc = radeon_crtc->vsc;
23748c2ecf20Sopenharmony_ci		wm_low.vtaps = 1;
23758c2ecf20Sopenharmony_ci		if (radeon_crtc->rmx_type != RMX_OFF)
23768c2ecf20Sopenharmony_ci			wm_low.vtaps = 2;
23778c2ecf20Sopenharmony_ci		wm_low.bytes_per_pixel = 4; /* XXX: get this from fb config */
23788c2ecf20Sopenharmony_ci		wm_low.lb_size = lb_size;
23798c2ecf20Sopenharmony_ci		wm_low.dram_channels = dram_channels;
23808c2ecf20Sopenharmony_ci		wm_low.num_heads = num_heads;
23818c2ecf20Sopenharmony_ci
23828c2ecf20Sopenharmony_ci		/* set for high clocks */
23838c2ecf20Sopenharmony_ci		latency_watermark_a = min(dce6_latency_watermark(&wm_high), (u32)65535);
23848c2ecf20Sopenharmony_ci		/* set for low clocks */
23858c2ecf20Sopenharmony_ci		latency_watermark_b = min(dce6_latency_watermark(&wm_low), (u32)65535);
23868c2ecf20Sopenharmony_ci
23878c2ecf20Sopenharmony_ci		/* possibly force display priority to high */
23888c2ecf20Sopenharmony_ci		/* should really do this at mode validation time... */
23898c2ecf20Sopenharmony_ci		if (!dce6_average_bandwidth_vs_dram_bandwidth_for_display(&wm_high) ||
23908c2ecf20Sopenharmony_ci		    !dce6_average_bandwidth_vs_available_bandwidth(&wm_high) ||
23918c2ecf20Sopenharmony_ci		    !dce6_check_latency_hiding(&wm_high) ||
23928c2ecf20Sopenharmony_ci		    (rdev->disp_priority == 2)) {
23938c2ecf20Sopenharmony_ci			DRM_DEBUG_KMS("force priority to high\n");
23948c2ecf20Sopenharmony_ci			priority_a_cnt |= PRIORITY_ALWAYS_ON;
23958c2ecf20Sopenharmony_ci			priority_b_cnt |= PRIORITY_ALWAYS_ON;
23968c2ecf20Sopenharmony_ci		}
23978c2ecf20Sopenharmony_ci		if (!dce6_average_bandwidth_vs_dram_bandwidth_for_display(&wm_low) ||
23988c2ecf20Sopenharmony_ci		    !dce6_average_bandwidth_vs_available_bandwidth(&wm_low) ||
23998c2ecf20Sopenharmony_ci		    !dce6_check_latency_hiding(&wm_low) ||
24008c2ecf20Sopenharmony_ci		    (rdev->disp_priority == 2)) {
24018c2ecf20Sopenharmony_ci			DRM_DEBUG_KMS("force priority to high\n");
24028c2ecf20Sopenharmony_ci			priority_a_cnt |= PRIORITY_ALWAYS_ON;
24038c2ecf20Sopenharmony_ci			priority_b_cnt |= PRIORITY_ALWAYS_ON;
24048c2ecf20Sopenharmony_ci		}
24058c2ecf20Sopenharmony_ci
24068c2ecf20Sopenharmony_ci		a.full = dfixed_const(1000);
24078c2ecf20Sopenharmony_ci		b.full = dfixed_const(mode->clock);
24088c2ecf20Sopenharmony_ci		b.full = dfixed_div(b, a);
24098c2ecf20Sopenharmony_ci		c.full = dfixed_const(latency_watermark_a);
24108c2ecf20Sopenharmony_ci		c.full = dfixed_mul(c, b);
24118c2ecf20Sopenharmony_ci		c.full = dfixed_mul(c, radeon_crtc->hsc);
24128c2ecf20Sopenharmony_ci		c.full = dfixed_div(c, a);
24138c2ecf20Sopenharmony_ci		a.full = dfixed_const(16);
24148c2ecf20Sopenharmony_ci		c.full = dfixed_div(c, a);
24158c2ecf20Sopenharmony_ci		priority_a_mark = dfixed_trunc(c);
24168c2ecf20Sopenharmony_ci		priority_a_cnt |= priority_a_mark & PRIORITY_MARK_MASK;
24178c2ecf20Sopenharmony_ci
24188c2ecf20Sopenharmony_ci		a.full = dfixed_const(1000);
24198c2ecf20Sopenharmony_ci		b.full = dfixed_const(mode->clock);
24208c2ecf20Sopenharmony_ci		b.full = dfixed_div(b, a);
24218c2ecf20Sopenharmony_ci		c.full = dfixed_const(latency_watermark_b);
24228c2ecf20Sopenharmony_ci		c.full = dfixed_mul(c, b);
24238c2ecf20Sopenharmony_ci		c.full = dfixed_mul(c, radeon_crtc->hsc);
24248c2ecf20Sopenharmony_ci		c.full = dfixed_div(c, a);
24258c2ecf20Sopenharmony_ci		a.full = dfixed_const(16);
24268c2ecf20Sopenharmony_ci		c.full = dfixed_div(c, a);
24278c2ecf20Sopenharmony_ci		priority_b_mark = dfixed_trunc(c);
24288c2ecf20Sopenharmony_ci		priority_b_cnt |= priority_b_mark & PRIORITY_MARK_MASK;
24298c2ecf20Sopenharmony_ci
24308c2ecf20Sopenharmony_ci		/* Save number of lines the linebuffer leads before the scanout */
24318c2ecf20Sopenharmony_ci		radeon_crtc->lb_vblank_lead_lines = DIV_ROUND_UP(lb_size, mode->crtc_hdisplay);
24328c2ecf20Sopenharmony_ci	}
24338c2ecf20Sopenharmony_ci
24348c2ecf20Sopenharmony_ci	/* select wm A */
24358c2ecf20Sopenharmony_ci	arb_control3 = RREG32(DPG_PIPE_ARBITRATION_CONTROL3 + radeon_crtc->crtc_offset);
24368c2ecf20Sopenharmony_ci	tmp = arb_control3;
24378c2ecf20Sopenharmony_ci	tmp &= ~LATENCY_WATERMARK_MASK(3);
24388c2ecf20Sopenharmony_ci	tmp |= LATENCY_WATERMARK_MASK(1);
24398c2ecf20Sopenharmony_ci	WREG32(DPG_PIPE_ARBITRATION_CONTROL3 + radeon_crtc->crtc_offset, tmp);
24408c2ecf20Sopenharmony_ci	WREG32(DPG_PIPE_LATENCY_CONTROL + radeon_crtc->crtc_offset,
24418c2ecf20Sopenharmony_ci	       (LATENCY_LOW_WATERMARK(latency_watermark_a) |
24428c2ecf20Sopenharmony_ci		LATENCY_HIGH_WATERMARK(line_time)));
24438c2ecf20Sopenharmony_ci	/* select wm B */
24448c2ecf20Sopenharmony_ci	tmp = RREG32(DPG_PIPE_ARBITRATION_CONTROL3 + radeon_crtc->crtc_offset);
24458c2ecf20Sopenharmony_ci	tmp &= ~LATENCY_WATERMARK_MASK(3);
24468c2ecf20Sopenharmony_ci	tmp |= LATENCY_WATERMARK_MASK(2);
24478c2ecf20Sopenharmony_ci	WREG32(DPG_PIPE_ARBITRATION_CONTROL3 + radeon_crtc->crtc_offset, tmp);
24488c2ecf20Sopenharmony_ci	WREG32(DPG_PIPE_LATENCY_CONTROL + radeon_crtc->crtc_offset,
24498c2ecf20Sopenharmony_ci	       (LATENCY_LOW_WATERMARK(latency_watermark_b) |
24508c2ecf20Sopenharmony_ci		LATENCY_HIGH_WATERMARK(line_time)));
24518c2ecf20Sopenharmony_ci	/* restore original selection */
24528c2ecf20Sopenharmony_ci	WREG32(DPG_PIPE_ARBITRATION_CONTROL3 + radeon_crtc->crtc_offset, arb_control3);
24538c2ecf20Sopenharmony_ci
24548c2ecf20Sopenharmony_ci	/* write the priority marks */
24558c2ecf20Sopenharmony_ci	WREG32(PRIORITY_A_CNT + radeon_crtc->crtc_offset, priority_a_cnt);
24568c2ecf20Sopenharmony_ci	WREG32(PRIORITY_B_CNT + radeon_crtc->crtc_offset, priority_b_cnt);
24578c2ecf20Sopenharmony_ci
24588c2ecf20Sopenharmony_ci	/* save values for DPM */
24598c2ecf20Sopenharmony_ci	radeon_crtc->line_time = line_time;
24608c2ecf20Sopenharmony_ci	radeon_crtc->wm_high = latency_watermark_a;
24618c2ecf20Sopenharmony_ci	radeon_crtc->wm_low = latency_watermark_b;
24628c2ecf20Sopenharmony_ci}
24638c2ecf20Sopenharmony_ci
24648c2ecf20Sopenharmony_civoid dce6_bandwidth_update(struct radeon_device *rdev)
24658c2ecf20Sopenharmony_ci{
24668c2ecf20Sopenharmony_ci	struct drm_display_mode *mode0 = NULL;
24678c2ecf20Sopenharmony_ci	struct drm_display_mode *mode1 = NULL;
24688c2ecf20Sopenharmony_ci	u32 num_heads = 0, lb_size;
24698c2ecf20Sopenharmony_ci	int i;
24708c2ecf20Sopenharmony_ci
24718c2ecf20Sopenharmony_ci	if (!rdev->mode_info.mode_config_initialized)
24728c2ecf20Sopenharmony_ci		return;
24738c2ecf20Sopenharmony_ci
24748c2ecf20Sopenharmony_ci	radeon_update_display_priority(rdev);
24758c2ecf20Sopenharmony_ci
24768c2ecf20Sopenharmony_ci	for (i = 0; i < rdev->num_crtc; i++) {
24778c2ecf20Sopenharmony_ci		if (rdev->mode_info.crtcs[i]->base.enabled)
24788c2ecf20Sopenharmony_ci			num_heads++;
24798c2ecf20Sopenharmony_ci	}
24808c2ecf20Sopenharmony_ci	for (i = 0; i < rdev->num_crtc; i += 2) {
24818c2ecf20Sopenharmony_ci		mode0 = &rdev->mode_info.crtcs[i]->base.mode;
24828c2ecf20Sopenharmony_ci		mode1 = &rdev->mode_info.crtcs[i+1]->base.mode;
24838c2ecf20Sopenharmony_ci		lb_size = dce6_line_buffer_adjust(rdev, rdev->mode_info.crtcs[i], mode0, mode1);
24848c2ecf20Sopenharmony_ci		dce6_program_watermarks(rdev, rdev->mode_info.crtcs[i], lb_size, num_heads);
24858c2ecf20Sopenharmony_ci		lb_size = dce6_line_buffer_adjust(rdev, rdev->mode_info.crtcs[i+1], mode1, mode0);
24868c2ecf20Sopenharmony_ci		dce6_program_watermarks(rdev, rdev->mode_info.crtcs[i+1], lb_size, num_heads);
24878c2ecf20Sopenharmony_ci	}
24888c2ecf20Sopenharmony_ci}
24898c2ecf20Sopenharmony_ci
24908c2ecf20Sopenharmony_ci/*
24918c2ecf20Sopenharmony_ci * Core functions
24928c2ecf20Sopenharmony_ci */
24938c2ecf20Sopenharmony_cistatic void si_tiling_mode_table_init(struct radeon_device *rdev)
24948c2ecf20Sopenharmony_ci{
24958c2ecf20Sopenharmony_ci	u32 *tile = rdev->config.si.tile_mode_array;
24968c2ecf20Sopenharmony_ci	const u32 num_tile_mode_states =
24978c2ecf20Sopenharmony_ci			ARRAY_SIZE(rdev->config.si.tile_mode_array);
24988c2ecf20Sopenharmony_ci	u32 reg_offset, split_equal_to_row_size;
24998c2ecf20Sopenharmony_ci
25008c2ecf20Sopenharmony_ci	switch (rdev->config.si.mem_row_size_in_kb) {
25018c2ecf20Sopenharmony_ci	case 1:
25028c2ecf20Sopenharmony_ci		split_equal_to_row_size = ADDR_SURF_TILE_SPLIT_1KB;
25038c2ecf20Sopenharmony_ci		break;
25048c2ecf20Sopenharmony_ci	case 2:
25058c2ecf20Sopenharmony_ci	default:
25068c2ecf20Sopenharmony_ci		split_equal_to_row_size = ADDR_SURF_TILE_SPLIT_2KB;
25078c2ecf20Sopenharmony_ci		break;
25088c2ecf20Sopenharmony_ci	case 4:
25098c2ecf20Sopenharmony_ci		split_equal_to_row_size = ADDR_SURF_TILE_SPLIT_4KB;
25108c2ecf20Sopenharmony_ci		break;
25118c2ecf20Sopenharmony_ci	}
25128c2ecf20Sopenharmony_ci
25138c2ecf20Sopenharmony_ci	for (reg_offset = 0; reg_offset < num_tile_mode_states; reg_offset++)
25148c2ecf20Sopenharmony_ci		tile[reg_offset] = 0;
25158c2ecf20Sopenharmony_ci
25168c2ecf20Sopenharmony_ci	switch(rdev->family) {
25178c2ecf20Sopenharmony_ci	case CHIP_TAHITI:
25188c2ecf20Sopenharmony_ci	case CHIP_PITCAIRN:
25198c2ecf20Sopenharmony_ci		/* non-AA compressed depth or any compressed stencil */
25208c2ecf20Sopenharmony_ci		tile[0] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
25218c2ecf20Sopenharmony_ci			   MICRO_TILE_MODE(ADDR_SURF_DEPTH_MICRO_TILING) |
25228c2ecf20Sopenharmony_ci			   PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) |
25238c2ecf20Sopenharmony_ci			   TILE_SPLIT(ADDR_SURF_TILE_SPLIT_64B) |
25248c2ecf20Sopenharmony_ci			   NUM_BANKS(ADDR_SURF_16_BANK) |
25258c2ecf20Sopenharmony_ci			   BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
25268c2ecf20Sopenharmony_ci			   BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) |
25278c2ecf20Sopenharmony_ci			   MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2));
25288c2ecf20Sopenharmony_ci		/* 2xAA/4xAA compressed depth only */
25298c2ecf20Sopenharmony_ci		tile[1] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
25308c2ecf20Sopenharmony_ci			   MICRO_TILE_MODE(ADDR_SURF_DEPTH_MICRO_TILING) |
25318c2ecf20Sopenharmony_ci			   PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) |
25328c2ecf20Sopenharmony_ci			   TILE_SPLIT(ADDR_SURF_TILE_SPLIT_128B) |
25338c2ecf20Sopenharmony_ci			   NUM_BANKS(ADDR_SURF_16_BANK) |
25348c2ecf20Sopenharmony_ci			   BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
25358c2ecf20Sopenharmony_ci			   BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) |
25368c2ecf20Sopenharmony_ci			   MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2));
25378c2ecf20Sopenharmony_ci		/* 8xAA compressed depth only */
25388c2ecf20Sopenharmony_ci		tile[2] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
25398c2ecf20Sopenharmony_ci			   MICRO_TILE_MODE(ADDR_SURF_DEPTH_MICRO_TILING) |
25408c2ecf20Sopenharmony_ci			   PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) |
25418c2ecf20Sopenharmony_ci			   TILE_SPLIT(ADDR_SURF_TILE_SPLIT_256B) |
25428c2ecf20Sopenharmony_ci			   NUM_BANKS(ADDR_SURF_16_BANK) |
25438c2ecf20Sopenharmony_ci			   BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
25448c2ecf20Sopenharmony_ci			   BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) |
25458c2ecf20Sopenharmony_ci			   MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2));
25468c2ecf20Sopenharmony_ci		/* 2xAA/4xAA compressed depth with stencil (for depth buffer) */
25478c2ecf20Sopenharmony_ci		tile[3] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
25488c2ecf20Sopenharmony_ci			   MICRO_TILE_MODE(ADDR_SURF_DEPTH_MICRO_TILING) |
25498c2ecf20Sopenharmony_ci			   PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) |
25508c2ecf20Sopenharmony_ci			   TILE_SPLIT(ADDR_SURF_TILE_SPLIT_128B) |
25518c2ecf20Sopenharmony_ci			   NUM_BANKS(ADDR_SURF_16_BANK) |
25528c2ecf20Sopenharmony_ci			   BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
25538c2ecf20Sopenharmony_ci			   BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) |
25548c2ecf20Sopenharmony_ci			   MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2));
25558c2ecf20Sopenharmony_ci		/* Maps w/ a dimension less than the 2D macro-tile dimensions (for mipmapped depth textures) */
25568c2ecf20Sopenharmony_ci		tile[4] = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) |
25578c2ecf20Sopenharmony_ci			   MICRO_TILE_MODE(ADDR_SURF_DEPTH_MICRO_TILING) |
25588c2ecf20Sopenharmony_ci			   PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) |
25598c2ecf20Sopenharmony_ci			   TILE_SPLIT(ADDR_SURF_TILE_SPLIT_64B) |
25608c2ecf20Sopenharmony_ci			   NUM_BANKS(ADDR_SURF_16_BANK) |
25618c2ecf20Sopenharmony_ci			   BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
25628c2ecf20Sopenharmony_ci			   BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) |
25638c2ecf20Sopenharmony_ci			   MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2));
25648c2ecf20Sopenharmony_ci		/* Uncompressed 16bpp depth - and stencil buffer allocated with it */
25658c2ecf20Sopenharmony_ci		tile[5] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
25668c2ecf20Sopenharmony_ci			   MICRO_TILE_MODE(ADDR_SURF_DEPTH_MICRO_TILING) |
25678c2ecf20Sopenharmony_ci			   PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) |
25688c2ecf20Sopenharmony_ci			   TILE_SPLIT(split_equal_to_row_size) |
25698c2ecf20Sopenharmony_ci			   NUM_BANKS(ADDR_SURF_16_BANK) |
25708c2ecf20Sopenharmony_ci			   BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
25718c2ecf20Sopenharmony_ci			   BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) |
25728c2ecf20Sopenharmony_ci			   MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2));
25738c2ecf20Sopenharmony_ci		/* Uncompressed 32bpp depth - and stencil buffer allocated with it */
25748c2ecf20Sopenharmony_ci		tile[6] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
25758c2ecf20Sopenharmony_ci			   MICRO_TILE_MODE(ADDR_SURF_DEPTH_MICRO_TILING) |
25768c2ecf20Sopenharmony_ci			   PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) |
25778c2ecf20Sopenharmony_ci			   TILE_SPLIT(split_equal_to_row_size) |
25788c2ecf20Sopenharmony_ci			   NUM_BANKS(ADDR_SURF_16_BANK) |
25798c2ecf20Sopenharmony_ci			   BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
25808c2ecf20Sopenharmony_ci			   BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) |
25818c2ecf20Sopenharmony_ci			   MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1));
25828c2ecf20Sopenharmony_ci		/* Uncompressed 8bpp stencil without depth (drivers typically do not use) */
25838c2ecf20Sopenharmony_ci		tile[7] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
25848c2ecf20Sopenharmony_ci			   MICRO_TILE_MODE(ADDR_SURF_DEPTH_MICRO_TILING) |
25858c2ecf20Sopenharmony_ci			   PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) |
25868c2ecf20Sopenharmony_ci			   TILE_SPLIT(split_equal_to_row_size) |
25878c2ecf20Sopenharmony_ci			   NUM_BANKS(ADDR_SURF_16_BANK) |
25888c2ecf20Sopenharmony_ci			   BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
25898c2ecf20Sopenharmony_ci			   BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) |
25908c2ecf20Sopenharmony_ci			   MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2));
25918c2ecf20Sopenharmony_ci		/* 1D and 1D Array Surfaces */
25928c2ecf20Sopenharmony_ci		tile[8] = (ARRAY_MODE(ARRAY_LINEAR_ALIGNED) |
25938c2ecf20Sopenharmony_ci			   MICRO_TILE_MODE(ADDR_SURF_DISPLAY_MICRO_TILING) |
25948c2ecf20Sopenharmony_ci			   PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) |
25958c2ecf20Sopenharmony_ci			   TILE_SPLIT(ADDR_SURF_TILE_SPLIT_64B) |
25968c2ecf20Sopenharmony_ci			   NUM_BANKS(ADDR_SURF_16_BANK) |
25978c2ecf20Sopenharmony_ci			   BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
25988c2ecf20Sopenharmony_ci			   BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) |
25998c2ecf20Sopenharmony_ci			   MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2));
26008c2ecf20Sopenharmony_ci		/* Displayable maps. */
26018c2ecf20Sopenharmony_ci		tile[9] = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) |
26028c2ecf20Sopenharmony_ci			   MICRO_TILE_MODE(ADDR_SURF_DISPLAY_MICRO_TILING) |
26038c2ecf20Sopenharmony_ci			   PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) |
26048c2ecf20Sopenharmony_ci			   TILE_SPLIT(ADDR_SURF_TILE_SPLIT_64B) |
26058c2ecf20Sopenharmony_ci			   NUM_BANKS(ADDR_SURF_16_BANK) |
26068c2ecf20Sopenharmony_ci			   BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
26078c2ecf20Sopenharmony_ci			   BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) |
26088c2ecf20Sopenharmony_ci			   MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2));
26098c2ecf20Sopenharmony_ci		/* Display 8bpp. */
26108c2ecf20Sopenharmony_ci		tile[10] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
26118c2ecf20Sopenharmony_ci			   MICRO_TILE_MODE(ADDR_SURF_DISPLAY_MICRO_TILING) |
26128c2ecf20Sopenharmony_ci			   PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) |
26138c2ecf20Sopenharmony_ci			   TILE_SPLIT(ADDR_SURF_TILE_SPLIT_256B) |
26148c2ecf20Sopenharmony_ci			   NUM_BANKS(ADDR_SURF_16_BANK) |
26158c2ecf20Sopenharmony_ci			   BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
26168c2ecf20Sopenharmony_ci			   BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) |
26178c2ecf20Sopenharmony_ci			   MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2));
26188c2ecf20Sopenharmony_ci		/* Display 16bpp. */
26198c2ecf20Sopenharmony_ci		tile[11] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
26208c2ecf20Sopenharmony_ci			   MICRO_TILE_MODE(ADDR_SURF_DISPLAY_MICRO_TILING) |
26218c2ecf20Sopenharmony_ci			   PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) |
26228c2ecf20Sopenharmony_ci			   TILE_SPLIT(ADDR_SURF_TILE_SPLIT_256B) |
26238c2ecf20Sopenharmony_ci			   NUM_BANKS(ADDR_SURF_16_BANK) |
26248c2ecf20Sopenharmony_ci			   BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
26258c2ecf20Sopenharmony_ci			   BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) |
26268c2ecf20Sopenharmony_ci			   MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2));
26278c2ecf20Sopenharmony_ci		/* Display 32bpp. */
26288c2ecf20Sopenharmony_ci		tile[12] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
26298c2ecf20Sopenharmony_ci			   MICRO_TILE_MODE(ADDR_SURF_DISPLAY_MICRO_TILING) |
26308c2ecf20Sopenharmony_ci			   PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) |
26318c2ecf20Sopenharmony_ci			   TILE_SPLIT(ADDR_SURF_TILE_SPLIT_512B) |
26328c2ecf20Sopenharmony_ci			   NUM_BANKS(ADDR_SURF_16_BANK) |
26338c2ecf20Sopenharmony_ci			   BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
26348c2ecf20Sopenharmony_ci			   BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) |
26358c2ecf20Sopenharmony_ci			   MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1));
26368c2ecf20Sopenharmony_ci		/* Thin. */
26378c2ecf20Sopenharmony_ci		tile[13] = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) |
26388c2ecf20Sopenharmony_ci			   MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) |
26398c2ecf20Sopenharmony_ci			   PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) |
26408c2ecf20Sopenharmony_ci			   TILE_SPLIT(ADDR_SURF_TILE_SPLIT_64B) |
26418c2ecf20Sopenharmony_ci			   NUM_BANKS(ADDR_SURF_16_BANK) |
26428c2ecf20Sopenharmony_ci			   BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
26438c2ecf20Sopenharmony_ci			   BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) |
26448c2ecf20Sopenharmony_ci			   MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2));
26458c2ecf20Sopenharmony_ci		/* Thin 8 bpp. */
26468c2ecf20Sopenharmony_ci		tile[14] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
26478c2ecf20Sopenharmony_ci			   MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) |
26488c2ecf20Sopenharmony_ci			   PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) |
26498c2ecf20Sopenharmony_ci			   TILE_SPLIT(ADDR_SURF_TILE_SPLIT_256B) |
26508c2ecf20Sopenharmony_ci			   NUM_BANKS(ADDR_SURF_16_BANK) |
26518c2ecf20Sopenharmony_ci			   BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
26528c2ecf20Sopenharmony_ci			   BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) |
26538c2ecf20Sopenharmony_ci			   MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1));
26548c2ecf20Sopenharmony_ci		/* Thin 16 bpp. */
26558c2ecf20Sopenharmony_ci		tile[15] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
26568c2ecf20Sopenharmony_ci			   MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) |
26578c2ecf20Sopenharmony_ci			   PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) |
26588c2ecf20Sopenharmony_ci			   TILE_SPLIT(ADDR_SURF_TILE_SPLIT_256B) |
26598c2ecf20Sopenharmony_ci			   NUM_BANKS(ADDR_SURF_16_BANK) |
26608c2ecf20Sopenharmony_ci			   BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
26618c2ecf20Sopenharmony_ci			   BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) |
26628c2ecf20Sopenharmony_ci			   MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1));
26638c2ecf20Sopenharmony_ci		/* Thin 32 bpp. */
26648c2ecf20Sopenharmony_ci		tile[16] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
26658c2ecf20Sopenharmony_ci			   MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) |
26668c2ecf20Sopenharmony_ci			   PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) |
26678c2ecf20Sopenharmony_ci			   TILE_SPLIT(ADDR_SURF_TILE_SPLIT_512B) |
26688c2ecf20Sopenharmony_ci			   NUM_BANKS(ADDR_SURF_16_BANK) |
26698c2ecf20Sopenharmony_ci			   BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
26708c2ecf20Sopenharmony_ci			   BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) |
26718c2ecf20Sopenharmony_ci			   MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1));
26728c2ecf20Sopenharmony_ci		/* Thin 64 bpp. */
26738c2ecf20Sopenharmony_ci		tile[17] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
26748c2ecf20Sopenharmony_ci			   MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) |
26758c2ecf20Sopenharmony_ci			   PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) |
26768c2ecf20Sopenharmony_ci			   TILE_SPLIT(split_equal_to_row_size) |
26778c2ecf20Sopenharmony_ci			   NUM_BANKS(ADDR_SURF_16_BANK) |
26788c2ecf20Sopenharmony_ci			   BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
26798c2ecf20Sopenharmony_ci			   BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) |
26808c2ecf20Sopenharmony_ci			   MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1));
26818c2ecf20Sopenharmony_ci		/* 8 bpp PRT. */
26828c2ecf20Sopenharmony_ci		tile[21] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
26838c2ecf20Sopenharmony_ci			   MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) |
26848c2ecf20Sopenharmony_ci			   PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) |
26858c2ecf20Sopenharmony_ci			   TILE_SPLIT(ADDR_SURF_TILE_SPLIT_256B) |
26868c2ecf20Sopenharmony_ci			   NUM_BANKS(ADDR_SURF_16_BANK) |
26878c2ecf20Sopenharmony_ci			   BANK_WIDTH(ADDR_SURF_BANK_WIDTH_2) |
26888c2ecf20Sopenharmony_ci			   BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) |
26898c2ecf20Sopenharmony_ci			   MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2));
26908c2ecf20Sopenharmony_ci		/* 16 bpp PRT */
26918c2ecf20Sopenharmony_ci		tile[22] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
26928c2ecf20Sopenharmony_ci			   MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) |
26938c2ecf20Sopenharmony_ci			   PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) |
26948c2ecf20Sopenharmony_ci			   TILE_SPLIT(ADDR_SURF_TILE_SPLIT_256B) |
26958c2ecf20Sopenharmony_ci			   NUM_BANKS(ADDR_SURF_16_BANK) |
26968c2ecf20Sopenharmony_ci			   BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
26978c2ecf20Sopenharmony_ci			   BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) |
26988c2ecf20Sopenharmony_ci			   MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4));
26998c2ecf20Sopenharmony_ci		/* 32 bpp PRT */
27008c2ecf20Sopenharmony_ci		tile[23] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
27018c2ecf20Sopenharmony_ci			   MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) |
27028c2ecf20Sopenharmony_ci			   PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) |
27038c2ecf20Sopenharmony_ci			   TILE_SPLIT(ADDR_SURF_TILE_SPLIT_256B) |
27048c2ecf20Sopenharmony_ci			   NUM_BANKS(ADDR_SURF_16_BANK) |
27058c2ecf20Sopenharmony_ci			   BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
27068c2ecf20Sopenharmony_ci			   BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) |
27078c2ecf20Sopenharmony_ci			   MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2));
27088c2ecf20Sopenharmony_ci		/* 64 bpp PRT */
27098c2ecf20Sopenharmony_ci		tile[24] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
27108c2ecf20Sopenharmony_ci			   MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) |
27118c2ecf20Sopenharmony_ci			   PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) |
27128c2ecf20Sopenharmony_ci			   TILE_SPLIT(ADDR_SURF_TILE_SPLIT_512B) |
27138c2ecf20Sopenharmony_ci			   NUM_BANKS(ADDR_SURF_16_BANK) |
27148c2ecf20Sopenharmony_ci			   BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
27158c2ecf20Sopenharmony_ci			   BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) |
27168c2ecf20Sopenharmony_ci			   MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2));
27178c2ecf20Sopenharmony_ci		/* 128 bpp PRT */
27188c2ecf20Sopenharmony_ci		tile[25] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
27198c2ecf20Sopenharmony_ci			   MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) |
27208c2ecf20Sopenharmony_ci			   PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) |
27218c2ecf20Sopenharmony_ci			   TILE_SPLIT(ADDR_SURF_TILE_SPLIT_1KB) |
27228c2ecf20Sopenharmony_ci			   NUM_BANKS(ADDR_SURF_8_BANK) |
27238c2ecf20Sopenharmony_ci			   BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
27248c2ecf20Sopenharmony_ci			   BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) |
27258c2ecf20Sopenharmony_ci			   MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1));
27268c2ecf20Sopenharmony_ci
27278c2ecf20Sopenharmony_ci		for (reg_offset = 0; reg_offset < num_tile_mode_states; reg_offset++)
27288c2ecf20Sopenharmony_ci			WREG32(GB_TILE_MODE0 + (reg_offset * 4), tile[reg_offset]);
27298c2ecf20Sopenharmony_ci		break;
27308c2ecf20Sopenharmony_ci
27318c2ecf20Sopenharmony_ci	case CHIP_VERDE:
27328c2ecf20Sopenharmony_ci	case CHIP_OLAND:
27338c2ecf20Sopenharmony_ci	case CHIP_HAINAN:
27348c2ecf20Sopenharmony_ci		/* non-AA compressed depth or any compressed stencil */
27358c2ecf20Sopenharmony_ci		tile[0] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
27368c2ecf20Sopenharmony_ci			   MICRO_TILE_MODE(ADDR_SURF_DEPTH_MICRO_TILING) |
27378c2ecf20Sopenharmony_ci			   PIPE_CONFIG(ADDR_SURF_P4_8x16) |
27388c2ecf20Sopenharmony_ci			   TILE_SPLIT(ADDR_SURF_TILE_SPLIT_64B) |
27398c2ecf20Sopenharmony_ci			   NUM_BANKS(ADDR_SURF_16_BANK) |
27408c2ecf20Sopenharmony_ci			   BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
27418c2ecf20Sopenharmony_ci			   BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) |
27428c2ecf20Sopenharmony_ci			   MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4));
27438c2ecf20Sopenharmony_ci		/* 2xAA/4xAA compressed depth only */
27448c2ecf20Sopenharmony_ci		tile[1] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
27458c2ecf20Sopenharmony_ci			   MICRO_TILE_MODE(ADDR_SURF_DEPTH_MICRO_TILING) |
27468c2ecf20Sopenharmony_ci			   PIPE_CONFIG(ADDR_SURF_P4_8x16) |
27478c2ecf20Sopenharmony_ci			   TILE_SPLIT(ADDR_SURF_TILE_SPLIT_128B) |
27488c2ecf20Sopenharmony_ci			   NUM_BANKS(ADDR_SURF_16_BANK) |
27498c2ecf20Sopenharmony_ci			   BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
27508c2ecf20Sopenharmony_ci			   BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) |
27518c2ecf20Sopenharmony_ci			   MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4));
27528c2ecf20Sopenharmony_ci		/* 8xAA compressed depth only */
27538c2ecf20Sopenharmony_ci		tile[2] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
27548c2ecf20Sopenharmony_ci			   MICRO_TILE_MODE(ADDR_SURF_DEPTH_MICRO_TILING) |
27558c2ecf20Sopenharmony_ci			   PIPE_CONFIG(ADDR_SURF_P4_8x16) |
27568c2ecf20Sopenharmony_ci			   TILE_SPLIT(ADDR_SURF_TILE_SPLIT_256B) |
27578c2ecf20Sopenharmony_ci			   NUM_BANKS(ADDR_SURF_16_BANK) |
27588c2ecf20Sopenharmony_ci			   BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
27598c2ecf20Sopenharmony_ci			   BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) |
27608c2ecf20Sopenharmony_ci			   MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4));
27618c2ecf20Sopenharmony_ci		/* 2xAA/4xAA compressed depth with stencil (for depth buffer) */
27628c2ecf20Sopenharmony_ci		tile[3] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
27638c2ecf20Sopenharmony_ci			   MICRO_TILE_MODE(ADDR_SURF_DEPTH_MICRO_TILING) |
27648c2ecf20Sopenharmony_ci			   PIPE_CONFIG(ADDR_SURF_P4_8x16) |
27658c2ecf20Sopenharmony_ci			   TILE_SPLIT(ADDR_SURF_TILE_SPLIT_128B) |
27668c2ecf20Sopenharmony_ci			   NUM_BANKS(ADDR_SURF_16_BANK) |
27678c2ecf20Sopenharmony_ci			   BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
27688c2ecf20Sopenharmony_ci			   BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) |
27698c2ecf20Sopenharmony_ci			   MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4));
27708c2ecf20Sopenharmony_ci		/* Maps w/ a dimension less than the 2D macro-tile dimensions (for mipmapped depth textures) */
27718c2ecf20Sopenharmony_ci		tile[4] = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) |
27728c2ecf20Sopenharmony_ci			   MICRO_TILE_MODE(ADDR_SURF_DEPTH_MICRO_TILING) |
27738c2ecf20Sopenharmony_ci			   PIPE_CONFIG(ADDR_SURF_P4_8x16) |
27748c2ecf20Sopenharmony_ci			   TILE_SPLIT(ADDR_SURF_TILE_SPLIT_64B) |
27758c2ecf20Sopenharmony_ci			   NUM_BANKS(ADDR_SURF_16_BANK) |
27768c2ecf20Sopenharmony_ci			   BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
27778c2ecf20Sopenharmony_ci			   BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) |
27788c2ecf20Sopenharmony_ci			   MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2));
27798c2ecf20Sopenharmony_ci		/* Uncompressed 16bpp depth - and stencil buffer allocated with it */
27808c2ecf20Sopenharmony_ci		tile[5] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
27818c2ecf20Sopenharmony_ci			   MICRO_TILE_MODE(ADDR_SURF_DEPTH_MICRO_TILING) |
27828c2ecf20Sopenharmony_ci			   PIPE_CONFIG(ADDR_SURF_P4_8x16) |
27838c2ecf20Sopenharmony_ci			   TILE_SPLIT(split_equal_to_row_size) |
27848c2ecf20Sopenharmony_ci			   NUM_BANKS(ADDR_SURF_16_BANK) |
27858c2ecf20Sopenharmony_ci			   BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
27868c2ecf20Sopenharmony_ci			   BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) |
27878c2ecf20Sopenharmony_ci			   MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2));
27888c2ecf20Sopenharmony_ci		/* Uncompressed 32bpp depth - and stencil buffer allocated with it */
27898c2ecf20Sopenharmony_ci		tile[6] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
27908c2ecf20Sopenharmony_ci			   MICRO_TILE_MODE(ADDR_SURF_DEPTH_MICRO_TILING) |
27918c2ecf20Sopenharmony_ci			   PIPE_CONFIG(ADDR_SURF_P4_8x16) |
27928c2ecf20Sopenharmony_ci			   TILE_SPLIT(split_equal_to_row_size) |
27938c2ecf20Sopenharmony_ci			   NUM_BANKS(ADDR_SURF_16_BANK) |
27948c2ecf20Sopenharmony_ci			   BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
27958c2ecf20Sopenharmony_ci			   BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) |
27968c2ecf20Sopenharmony_ci			   MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2));
27978c2ecf20Sopenharmony_ci		/* Uncompressed 8bpp stencil without depth (drivers typically do not use) */
27988c2ecf20Sopenharmony_ci		tile[7] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
27998c2ecf20Sopenharmony_ci			   MICRO_TILE_MODE(ADDR_SURF_DEPTH_MICRO_TILING) |
28008c2ecf20Sopenharmony_ci			   PIPE_CONFIG(ADDR_SURF_P4_8x16) |
28018c2ecf20Sopenharmony_ci			   TILE_SPLIT(split_equal_to_row_size) |
28028c2ecf20Sopenharmony_ci			   NUM_BANKS(ADDR_SURF_16_BANK) |
28038c2ecf20Sopenharmony_ci			   BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
28048c2ecf20Sopenharmony_ci			   BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) |
28058c2ecf20Sopenharmony_ci			   MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4));
28068c2ecf20Sopenharmony_ci		/* 1D and 1D Array Surfaces */
28078c2ecf20Sopenharmony_ci		tile[8] = (ARRAY_MODE(ARRAY_LINEAR_ALIGNED) |
28088c2ecf20Sopenharmony_ci			   MICRO_TILE_MODE(ADDR_SURF_DISPLAY_MICRO_TILING) |
28098c2ecf20Sopenharmony_ci			   PIPE_CONFIG(ADDR_SURF_P4_8x16) |
28108c2ecf20Sopenharmony_ci			   TILE_SPLIT(ADDR_SURF_TILE_SPLIT_64B) |
28118c2ecf20Sopenharmony_ci			   NUM_BANKS(ADDR_SURF_16_BANK) |
28128c2ecf20Sopenharmony_ci			   BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
28138c2ecf20Sopenharmony_ci			   BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) |
28148c2ecf20Sopenharmony_ci			   MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2));
28158c2ecf20Sopenharmony_ci		/* Displayable maps. */
28168c2ecf20Sopenharmony_ci		tile[9] = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) |
28178c2ecf20Sopenharmony_ci			   MICRO_TILE_MODE(ADDR_SURF_DISPLAY_MICRO_TILING) |
28188c2ecf20Sopenharmony_ci			   PIPE_CONFIG(ADDR_SURF_P4_8x16) |
28198c2ecf20Sopenharmony_ci			   TILE_SPLIT(ADDR_SURF_TILE_SPLIT_64B) |
28208c2ecf20Sopenharmony_ci			   NUM_BANKS(ADDR_SURF_16_BANK) |
28218c2ecf20Sopenharmony_ci			   BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
28228c2ecf20Sopenharmony_ci			   BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) |
28238c2ecf20Sopenharmony_ci			   MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2));
28248c2ecf20Sopenharmony_ci		/* Display 8bpp. */
28258c2ecf20Sopenharmony_ci		tile[10] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
28268c2ecf20Sopenharmony_ci			   MICRO_TILE_MODE(ADDR_SURF_DISPLAY_MICRO_TILING) |
28278c2ecf20Sopenharmony_ci			   PIPE_CONFIG(ADDR_SURF_P4_8x16) |
28288c2ecf20Sopenharmony_ci			   TILE_SPLIT(ADDR_SURF_TILE_SPLIT_256B) |
28298c2ecf20Sopenharmony_ci			   NUM_BANKS(ADDR_SURF_16_BANK) |
28308c2ecf20Sopenharmony_ci			   BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
28318c2ecf20Sopenharmony_ci			   BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) |
28328c2ecf20Sopenharmony_ci			   MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4));
28338c2ecf20Sopenharmony_ci		/* Display 16bpp. */
28348c2ecf20Sopenharmony_ci		tile[11] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
28358c2ecf20Sopenharmony_ci			   MICRO_TILE_MODE(ADDR_SURF_DISPLAY_MICRO_TILING) |
28368c2ecf20Sopenharmony_ci			   PIPE_CONFIG(ADDR_SURF_P4_8x16) |
28378c2ecf20Sopenharmony_ci			   TILE_SPLIT(ADDR_SURF_TILE_SPLIT_256B) |
28388c2ecf20Sopenharmony_ci			   NUM_BANKS(ADDR_SURF_16_BANK) |
28398c2ecf20Sopenharmony_ci			   BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
28408c2ecf20Sopenharmony_ci			   BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) |
28418c2ecf20Sopenharmony_ci			   MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2));
28428c2ecf20Sopenharmony_ci		/* Display 32bpp. */
28438c2ecf20Sopenharmony_ci		tile[12] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
28448c2ecf20Sopenharmony_ci			   MICRO_TILE_MODE(ADDR_SURF_DISPLAY_MICRO_TILING) |
28458c2ecf20Sopenharmony_ci			   PIPE_CONFIG(ADDR_SURF_P4_8x16) |
28468c2ecf20Sopenharmony_ci			   TILE_SPLIT(ADDR_SURF_TILE_SPLIT_512B) |
28478c2ecf20Sopenharmony_ci			   NUM_BANKS(ADDR_SURF_16_BANK) |
28488c2ecf20Sopenharmony_ci			   BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
28498c2ecf20Sopenharmony_ci			   BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) |
28508c2ecf20Sopenharmony_ci			   MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2));
28518c2ecf20Sopenharmony_ci		/* Thin. */
28528c2ecf20Sopenharmony_ci		tile[13] = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) |
28538c2ecf20Sopenharmony_ci			   MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) |
28548c2ecf20Sopenharmony_ci			   PIPE_CONFIG(ADDR_SURF_P4_8x16) |
28558c2ecf20Sopenharmony_ci			   TILE_SPLIT(ADDR_SURF_TILE_SPLIT_64B) |
28568c2ecf20Sopenharmony_ci			   NUM_BANKS(ADDR_SURF_16_BANK) |
28578c2ecf20Sopenharmony_ci			   BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
28588c2ecf20Sopenharmony_ci			   BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) |
28598c2ecf20Sopenharmony_ci			   MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2));
28608c2ecf20Sopenharmony_ci		/* Thin 8 bpp. */
28618c2ecf20Sopenharmony_ci		tile[14] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
28628c2ecf20Sopenharmony_ci			   MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) |
28638c2ecf20Sopenharmony_ci			   PIPE_CONFIG(ADDR_SURF_P4_8x16) |
28648c2ecf20Sopenharmony_ci			   TILE_SPLIT(ADDR_SURF_TILE_SPLIT_256B) |
28658c2ecf20Sopenharmony_ci			   NUM_BANKS(ADDR_SURF_16_BANK) |
28668c2ecf20Sopenharmony_ci			   BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
28678c2ecf20Sopenharmony_ci			   BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) |
28688c2ecf20Sopenharmony_ci			   MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2));
28698c2ecf20Sopenharmony_ci		/* Thin 16 bpp. */
28708c2ecf20Sopenharmony_ci		tile[15] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
28718c2ecf20Sopenharmony_ci			   MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) |
28728c2ecf20Sopenharmony_ci			   PIPE_CONFIG(ADDR_SURF_P4_8x16) |
28738c2ecf20Sopenharmony_ci			   TILE_SPLIT(ADDR_SURF_TILE_SPLIT_256B) |
28748c2ecf20Sopenharmony_ci			   NUM_BANKS(ADDR_SURF_16_BANK) |
28758c2ecf20Sopenharmony_ci			   BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
28768c2ecf20Sopenharmony_ci			   BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) |
28778c2ecf20Sopenharmony_ci			   MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2));
28788c2ecf20Sopenharmony_ci		/* Thin 32 bpp. */
28798c2ecf20Sopenharmony_ci		tile[16] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
28808c2ecf20Sopenharmony_ci			   MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) |
28818c2ecf20Sopenharmony_ci			   PIPE_CONFIG(ADDR_SURF_P4_8x16) |
28828c2ecf20Sopenharmony_ci			   TILE_SPLIT(ADDR_SURF_TILE_SPLIT_512B) |
28838c2ecf20Sopenharmony_ci			   NUM_BANKS(ADDR_SURF_16_BANK) |
28848c2ecf20Sopenharmony_ci			   BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
28858c2ecf20Sopenharmony_ci			   BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) |
28868c2ecf20Sopenharmony_ci			   MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2));
28878c2ecf20Sopenharmony_ci		/* Thin 64 bpp. */
28888c2ecf20Sopenharmony_ci		tile[17] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
28898c2ecf20Sopenharmony_ci			   MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) |
28908c2ecf20Sopenharmony_ci			   PIPE_CONFIG(ADDR_SURF_P4_8x16) |
28918c2ecf20Sopenharmony_ci			   TILE_SPLIT(split_equal_to_row_size) |
28928c2ecf20Sopenharmony_ci			   NUM_BANKS(ADDR_SURF_16_BANK) |
28938c2ecf20Sopenharmony_ci			   BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
28948c2ecf20Sopenharmony_ci			   BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) |
28958c2ecf20Sopenharmony_ci			   MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2));
28968c2ecf20Sopenharmony_ci		/* 8 bpp PRT. */
28978c2ecf20Sopenharmony_ci		tile[21] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
28988c2ecf20Sopenharmony_ci			   MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) |
28998c2ecf20Sopenharmony_ci			   PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) |
29008c2ecf20Sopenharmony_ci			   TILE_SPLIT(ADDR_SURF_TILE_SPLIT_256B) |
29018c2ecf20Sopenharmony_ci			   NUM_BANKS(ADDR_SURF_16_BANK) |
29028c2ecf20Sopenharmony_ci			   BANK_WIDTH(ADDR_SURF_BANK_WIDTH_2) |
29038c2ecf20Sopenharmony_ci			   BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) |
29048c2ecf20Sopenharmony_ci			   MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2));
29058c2ecf20Sopenharmony_ci		/* 16 bpp PRT */
29068c2ecf20Sopenharmony_ci		tile[22] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
29078c2ecf20Sopenharmony_ci			   MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) |
29088c2ecf20Sopenharmony_ci			   PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) |
29098c2ecf20Sopenharmony_ci			   TILE_SPLIT(ADDR_SURF_TILE_SPLIT_256B) |
29108c2ecf20Sopenharmony_ci			   NUM_BANKS(ADDR_SURF_16_BANK) |
29118c2ecf20Sopenharmony_ci			   BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
29128c2ecf20Sopenharmony_ci			   BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) |
29138c2ecf20Sopenharmony_ci			   MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4));
29148c2ecf20Sopenharmony_ci		/* 32 bpp PRT */
29158c2ecf20Sopenharmony_ci		tile[23] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
29168c2ecf20Sopenharmony_ci			   MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) |
29178c2ecf20Sopenharmony_ci			   PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) |
29188c2ecf20Sopenharmony_ci			   TILE_SPLIT(ADDR_SURF_TILE_SPLIT_256B) |
29198c2ecf20Sopenharmony_ci			   NUM_BANKS(ADDR_SURF_16_BANK) |
29208c2ecf20Sopenharmony_ci			   BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
29218c2ecf20Sopenharmony_ci			   BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) |
29228c2ecf20Sopenharmony_ci			   MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2));
29238c2ecf20Sopenharmony_ci		/* 64 bpp PRT */
29248c2ecf20Sopenharmony_ci		tile[24] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
29258c2ecf20Sopenharmony_ci			   MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) |
29268c2ecf20Sopenharmony_ci			   PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) |
29278c2ecf20Sopenharmony_ci			   TILE_SPLIT(ADDR_SURF_TILE_SPLIT_512B) |
29288c2ecf20Sopenharmony_ci			   NUM_BANKS(ADDR_SURF_16_BANK) |
29298c2ecf20Sopenharmony_ci			   BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
29308c2ecf20Sopenharmony_ci			   BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) |
29318c2ecf20Sopenharmony_ci			   MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2));
29328c2ecf20Sopenharmony_ci		/* 128 bpp PRT */
29338c2ecf20Sopenharmony_ci		tile[25] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
29348c2ecf20Sopenharmony_ci			   MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) |
29358c2ecf20Sopenharmony_ci			   PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) |
29368c2ecf20Sopenharmony_ci			   TILE_SPLIT(ADDR_SURF_TILE_SPLIT_1KB) |
29378c2ecf20Sopenharmony_ci			   NUM_BANKS(ADDR_SURF_8_BANK) |
29388c2ecf20Sopenharmony_ci			   BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
29398c2ecf20Sopenharmony_ci			   BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) |
29408c2ecf20Sopenharmony_ci			   MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1));
29418c2ecf20Sopenharmony_ci
29428c2ecf20Sopenharmony_ci		for (reg_offset = 0; reg_offset < num_tile_mode_states; reg_offset++)
29438c2ecf20Sopenharmony_ci			WREG32(GB_TILE_MODE0 + (reg_offset * 4), tile[reg_offset]);
29448c2ecf20Sopenharmony_ci		break;
29458c2ecf20Sopenharmony_ci
29468c2ecf20Sopenharmony_ci	default:
29478c2ecf20Sopenharmony_ci		DRM_ERROR("unknown asic: 0x%x\n", rdev->family);
29488c2ecf20Sopenharmony_ci	}
29498c2ecf20Sopenharmony_ci}
29508c2ecf20Sopenharmony_ci
29518c2ecf20Sopenharmony_cistatic void si_select_se_sh(struct radeon_device *rdev,
29528c2ecf20Sopenharmony_ci			    u32 se_num, u32 sh_num)
29538c2ecf20Sopenharmony_ci{
29548c2ecf20Sopenharmony_ci	u32 data = INSTANCE_BROADCAST_WRITES;
29558c2ecf20Sopenharmony_ci
29568c2ecf20Sopenharmony_ci	if ((se_num == 0xffffffff) && (sh_num == 0xffffffff))
29578c2ecf20Sopenharmony_ci		data |= SH_BROADCAST_WRITES | SE_BROADCAST_WRITES;
29588c2ecf20Sopenharmony_ci	else if (se_num == 0xffffffff)
29598c2ecf20Sopenharmony_ci		data |= SE_BROADCAST_WRITES | SH_INDEX(sh_num);
29608c2ecf20Sopenharmony_ci	else if (sh_num == 0xffffffff)
29618c2ecf20Sopenharmony_ci		data |= SH_BROADCAST_WRITES | SE_INDEX(se_num);
29628c2ecf20Sopenharmony_ci	else
29638c2ecf20Sopenharmony_ci		data |= SH_INDEX(sh_num) | SE_INDEX(se_num);
29648c2ecf20Sopenharmony_ci	WREG32(GRBM_GFX_INDEX, data);
29658c2ecf20Sopenharmony_ci}
29668c2ecf20Sopenharmony_ci
29678c2ecf20Sopenharmony_cistatic u32 si_create_bitmask(u32 bit_width)
29688c2ecf20Sopenharmony_ci{
29698c2ecf20Sopenharmony_ci	u32 i, mask = 0;
29708c2ecf20Sopenharmony_ci
29718c2ecf20Sopenharmony_ci	for (i = 0; i < bit_width; i++) {
29728c2ecf20Sopenharmony_ci		mask <<= 1;
29738c2ecf20Sopenharmony_ci		mask |= 1;
29748c2ecf20Sopenharmony_ci	}
29758c2ecf20Sopenharmony_ci	return mask;
29768c2ecf20Sopenharmony_ci}
29778c2ecf20Sopenharmony_ci
29788c2ecf20Sopenharmony_cistatic u32 si_get_cu_enabled(struct radeon_device *rdev, u32 cu_per_sh)
29798c2ecf20Sopenharmony_ci{
29808c2ecf20Sopenharmony_ci	u32 data, mask;
29818c2ecf20Sopenharmony_ci
29828c2ecf20Sopenharmony_ci	data = RREG32(CC_GC_SHADER_ARRAY_CONFIG);
29838c2ecf20Sopenharmony_ci	if (data & 1)
29848c2ecf20Sopenharmony_ci		data &= INACTIVE_CUS_MASK;
29858c2ecf20Sopenharmony_ci	else
29868c2ecf20Sopenharmony_ci		data = 0;
29878c2ecf20Sopenharmony_ci	data |= RREG32(GC_USER_SHADER_ARRAY_CONFIG);
29888c2ecf20Sopenharmony_ci
29898c2ecf20Sopenharmony_ci	data >>= INACTIVE_CUS_SHIFT;
29908c2ecf20Sopenharmony_ci
29918c2ecf20Sopenharmony_ci	mask = si_create_bitmask(cu_per_sh);
29928c2ecf20Sopenharmony_ci
29938c2ecf20Sopenharmony_ci	return ~data & mask;
29948c2ecf20Sopenharmony_ci}
29958c2ecf20Sopenharmony_ci
29968c2ecf20Sopenharmony_cistatic void si_setup_spi(struct radeon_device *rdev,
29978c2ecf20Sopenharmony_ci			 u32 se_num, u32 sh_per_se,
29988c2ecf20Sopenharmony_ci			 u32 cu_per_sh)
29998c2ecf20Sopenharmony_ci{
30008c2ecf20Sopenharmony_ci	int i, j, k;
30018c2ecf20Sopenharmony_ci	u32 data, mask, active_cu;
30028c2ecf20Sopenharmony_ci
30038c2ecf20Sopenharmony_ci	for (i = 0; i < se_num; i++) {
30048c2ecf20Sopenharmony_ci		for (j = 0; j < sh_per_se; j++) {
30058c2ecf20Sopenharmony_ci			si_select_se_sh(rdev, i, j);
30068c2ecf20Sopenharmony_ci			data = RREG32(SPI_STATIC_THREAD_MGMT_3);
30078c2ecf20Sopenharmony_ci			active_cu = si_get_cu_enabled(rdev, cu_per_sh);
30088c2ecf20Sopenharmony_ci
30098c2ecf20Sopenharmony_ci			mask = 1;
30108c2ecf20Sopenharmony_ci			for (k = 0; k < 16; k++) {
30118c2ecf20Sopenharmony_ci				mask <<= k;
30128c2ecf20Sopenharmony_ci				if (active_cu & mask) {
30138c2ecf20Sopenharmony_ci					data &= ~mask;
30148c2ecf20Sopenharmony_ci					WREG32(SPI_STATIC_THREAD_MGMT_3, data);
30158c2ecf20Sopenharmony_ci					break;
30168c2ecf20Sopenharmony_ci				}
30178c2ecf20Sopenharmony_ci			}
30188c2ecf20Sopenharmony_ci		}
30198c2ecf20Sopenharmony_ci	}
30208c2ecf20Sopenharmony_ci	si_select_se_sh(rdev, 0xffffffff, 0xffffffff);
30218c2ecf20Sopenharmony_ci}
30228c2ecf20Sopenharmony_ci
30238c2ecf20Sopenharmony_cistatic u32 si_get_rb_disabled(struct radeon_device *rdev,
30248c2ecf20Sopenharmony_ci			      u32 max_rb_num_per_se,
30258c2ecf20Sopenharmony_ci			      u32 sh_per_se)
30268c2ecf20Sopenharmony_ci{
30278c2ecf20Sopenharmony_ci	u32 data, mask;
30288c2ecf20Sopenharmony_ci
30298c2ecf20Sopenharmony_ci	data = RREG32(CC_RB_BACKEND_DISABLE);
30308c2ecf20Sopenharmony_ci	if (data & 1)
30318c2ecf20Sopenharmony_ci		data &= BACKEND_DISABLE_MASK;
30328c2ecf20Sopenharmony_ci	else
30338c2ecf20Sopenharmony_ci		data = 0;
30348c2ecf20Sopenharmony_ci	data |= RREG32(GC_USER_RB_BACKEND_DISABLE);
30358c2ecf20Sopenharmony_ci
30368c2ecf20Sopenharmony_ci	data >>= BACKEND_DISABLE_SHIFT;
30378c2ecf20Sopenharmony_ci
30388c2ecf20Sopenharmony_ci	mask = si_create_bitmask(max_rb_num_per_se / sh_per_se);
30398c2ecf20Sopenharmony_ci
30408c2ecf20Sopenharmony_ci	return data & mask;
30418c2ecf20Sopenharmony_ci}
30428c2ecf20Sopenharmony_ci
30438c2ecf20Sopenharmony_cistatic void si_setup_rb(struct radeon_device *rdev,
30448c2ecf20Sopenharmony_ci			u32 se_num, u32 sh_per_se,
30458c2ecf20Sopenharmony_ci			u32 max_rb_num_per_se)
30468c2ecf20Sopenharmony_ci{
30478c2ecf20Sopenharmony_ci	int i, j;
30488c2ecf20Sopenharmony_ci	u32 data, mask;
30498c2ecf20Sopenharmony_ci	u32 disabled_rbs = 0;
30508c2ecf20Sopenharmony_ci	u32 enabled_rbs = 0;
30518c2ecf20Sopenharmony_ci
30528c2ecf20Sopenharmony_ci	for (i = 0; i < se_num; i++) {
30538c2ecf20Sopenharmony_ci		for (j = 0; j < sh_per_se; j++) {
30548c2ecf20Sopenharmony_ci			si_select_se_sh(rdev, i, j);
30558c2ecf20Sopenharmony_ci			data = si_get_rb_disabled(rdev, max_rb_num_per_se, sh_per_se);
30568c2ecf20Sopenharmony_ci			disabled_rbs |= data << ((i * sh_per_se + j) * TAHITI_RB_BITMAP_WIDTH_PER_SH);
30578c2ecf20Sopenharmony_ci		}
30588c2ecf20Sopenharmony_ci	}
30598c2ecf20Sopenharmony_ci	si_select_se_sh(rdev, 0xffffffff, 0xffffffff);
30608c2ecf20Sopenharmony_ci
30618c2ecf20Sopenharmony_ci	mask = 1;
30628c2ecf20Sopenharmony_ci	for (i = 0; i < max_rb_num_per_se * se_num; i++) {
30638c2ecf20Sopenharmony_ci		if (!(disabled_rbs & mask))
30648c2ecf20Sopenharmony_ci			enabled_rbs |= mask;
30658c2ecf20Sopenharmony_ci		mask <<= 1;
30668c2ecf20Sopenharmony_ci	}
30678c2ecf20Sopenharmony_ci
30688c2ecf20Sopenharmony_ci	rdev->config.si.backend_enable_mask = enabled_rbs;
30698c2ecf20Sopenharmony_ci
30708c2ecf20Sopenharmony_ci	for (i = 0; i < se_num; i++) {
30718c2ecf20Sopenharmony_ci		si_select_se_sh(rdev, i, 0xffffffff);
30728c2ecf20Sopenharmony_ci		data = 0;
30738c2ecf20Sopenharmony_ci		for (j = 0; j < sh_per_se; j++) {
30748c2ecf20Sopenharmony_ci			switch (enabled_rbs & 3) {
30758c2ecf20Sopenharmony_ci			case 1:
30768c2ecf20Sopenharmony_ci				data |= (RASTER_CONFIG_RB_MAP_0 << (i * sh_per_se + j) * 2);
30778c2ecf20Sopenharmony_ci				break;
30788c2ecf20Sopenharmony_ci			case 2:
30798c2ecf20Sopenharmony_ci				data |= (RASTER_CONFIG_RB_MAP_3 << (i * sh_per_se + j) * 2);
30808c2ecf20Sopenharmony_ci				break;
30818c2ecf20Sopenharmony_ci			case 3:
30828c2ecf20Sopenharmony_ci			default:
30838c2ecf20Sopenharmony_ci				data |= (RASTER_CONFIG_RB_MAP_2 << (i * sh_per_se + j) * 2);
30848c2ecf20Sopenharmony_ci				break;
30858c2ecf20Sopenharmony_ci			}
30868c2ecf20Sopenharmony_ci			enabled_rbs >>= 2;
30878c2ecf20Sopenharmony_ci		}
30888c2ecf20Sopenharmony_ci		WREG32(PA_SC_RASTER_CONFIG, data);
30898c2ecf20Sopenharmony_ci	}
30908c2ecf20Sopenharmony_ci	si_select_se_sh(rdev, 0xffffffff, 0xffffffff);
30918c2ecf20Sopenharmony_ci}
30928c2ecf20Sopenharmony_ci
30938c2ecf20Sopenharmony_cistatic void si_gpu_init(struct radeon_device *rdev)
30948c2ecf20Sopenharmony_ci{
30958c2ecf20Sopenharmony_ci	u32 gb_addr_config = 0;
30968c2ecf20Sopenharmony_ci	u32 mc_shared_chmap, mc_arb_ramcfg;
30978c2ecf20Sopenharmony_ci	u32 sx_debug_1;
30988c2ecf20Sopenharmony_ci	u32 hdp_host_path_cntl;
30998c2ecf20Sopenharmony_ci	u32 tmp;
31008c2ecf20Sopenharmony_ci	int i, j;
31018c2ecf20Sopenharmony_ci
31028c2ecf20Sopenharmony_ci	switch (rdev->family) {
31038c2ecf20Sopenharmony_ci	case CHIP_TAHITI:
31048c2ecf20Sopenharmony_ci		rdev->config.si.max_shader_engines = 2;
31058c2ecf20Sopenharmony_ci		rdev->config.si.max_tile_pipes = 12;
31068c2ecf20Sopenharmony_ci		rdev->config.si.max_cu_per_sh = 8;
31078c2ecf20Sopenharmony_ci		rdev->config.si.max_sh_per_se = 2;
31088c2ecf20Sopenharmony_ci		rdev->config.si.max_backends_per_se = 4;
31098c2ecf20Sopenharmony_ci		rdev->config.si.max_texture_channel_caches = 12;
31108c2ecf20Sopenharmony_ci		rdev->config.si.max_gprs = 256;
31118c2ecf20Sopenharmony_ci		rdev->config.si.max_gs_threads = 32;
31128c2ecf20Sopenharmony_ci		rdev->config.si.max_hw_contexts = 8;
31138c2ecf20Sopenharmony_ci
31148c2ecf20Sopenharmony_ci		rdev->config.si.sc_prim_fifo_size_frontend = 0x20;
31158c2ecf20Sopenharmony_ci		rdev->config.si.sc_prim_fifo_size_backend = 0x100;
31168c2ecf20Sopenharmony_ci		rdev->config.si.sc_hiz_tile_fifo_size = 0x30;
31178c2ecf20Sopenharmony_ci		rdev->config.si.sc_earlyz_tile_fifo_size = 0x130;
31188c2ecf20Sopenharmony_ci		gb_addr_config = TAHITI_GB_ADDR_CONFIG_GOLDEN;
31198c2ecf20Sopenharmony_ci		break;
31208c2ecf20Sopenharmony_ci	case CHIP_PITCAIRN:
31218c2ecf20Sopenharmony_ci		rdev->config.si.max_shader_engines = 2;
31228c2ecf20Sopenharmony_ci		rdev->config.si.max_tile_pipes = 8;
31238c2ecf20Sopenharmony_ci		rdev->config.si.max_cu_per_sh = 5;
31248c2ecf20Sopenharmony_ci		rdev->config.si.max_sh_per_se = 2;
31258c2ecf20Sopenharmony_ci		rdev->config.si.max_backends_per_se = 4;
31268c2ecf20Sopenharmony_ci		rdev->config.si.max_texture_channel_caches = 8;
31278c2ecf20Sopenharmony_ci		rdev->config.si.max_gprs = 256;
31288c2ecf20Sopenharmony_ci		rdev->config.si.max_gs_threads = 32;
31298c2ecf20Sopenharmony_ci		rdev->config.si.max_hw_contexts = 8;
31308c2ecf20Sopenharmony_ci
31318c2ecf20Sopenharmony_ci		rdev->config.si.sc_prim_fifo_size_frontend = 0x20;
31328c2ecf20Sopenharmony_ci		rdev->config.si.sc_prim_fifo_size_backend = 0x100;
31338c2ecf20Sopenharmony_ci		rdev->config.si.sc_hiz_tile_fifo_size = 0x30;
31348c2ecf20Sopenharmony_ci		rdev->config.si.sc_earlyz_tile_fifo_size = 0x130;
31358c2ecf20Sopenharmony_ci		gb_addr_config = TAHITI_GB_ADDR_CONFIG_GOLDEN;
31368c2ecf20Sopenharmony_ci		break;
31378c2ecf20Sopenharmony_ci	case CHIP_VERDE:
31388c2ecf20Sopenharmony_ci	default:
31398c2ecf20Sopenharmony_ci		rdev->config.si.max_shader_engines = 1;
31408c2ecf20Sopenharmony_ci		rdev->config.si.max_tile_pipes = 4;
31418c2ecf20Sopenharmony_ci		rdev->config.si.max_cu_per_sh = 5;
31428c2ecf20Sopenharmony_ci		rdev->config.si.max_sh_per_se = 2;
31438c2ecf20Sopenharmony_ci		rdev->config.si.max_backends_per_se = 4;
31448c2ecf20Sopenharmony_ci		rdev->config.si.max_texture_channel_caches = 4;
31458c2ecf20Sopenharmony_ci		rdev->config.si.max_gprs = 256;
31468c2ecf20Sopenharmony_ci		rdev->config.si.max_gs_threads = 32;
31478c2ecf20Sopenharmony_ci		rdev->config.si.max_hw_contexts = 8;
31488c2ecf20Sopenharmony_ci
31498c2ecf20Sopenharmony_ci		rdev->config.si.sc_prim_fifo_size_frontend = 0x20;
31508c2ecf20Sopenharmony_ci		rdev->config.si.sc_prim_fifo_size_backend = 0x40;
31518c2ecf20Sopenharmony_ci		rdev->config.si.sc_hiz_tile_fifo_size = 0x30;
31528c2ecf20Sopenharmony_ci		rdev->config.si.sc_earlyz_tile_fifo_size = 0x130;
31538c2ecf20Sopenharmony_ci		gb_addr_config = VERDE_GB_ADDR_CONFIG_GOLDEN;
31548c2ecf20Sopenharmony_ci		break;
31558c2ecf20Sopenharmony_ci	case CHIP_OLAND:
31568c2ecf20Sopenharmony_ci		rdev->config.si.max_shader_engines = 1;
31578c2ecf20Sopenharmony_ci		rdev->config.si.max_tile_pipes = 4;
31588c2ecf20Sopenharmony_ci		rdev->config.si.max_cu_per_sh = 6;
31598c2ecf20Sopenharmony_ci		rdev->config.si.max_sh_per_se = 1;
31608c2ecf20Sopenharmony_ci		rdev->config.si.max_backends_per_se = 2;
31618c2ecf20Sopenharmony_ci		rdev->config.si.max_texture_channel_caches = 4;
31628c2ecf20Sopenharmony_ci		rdev->config.si.max_gprs = 256;
31638c2ecf20Sopenharmony_ci		rdev->config.si.max_gs_threads = 16;
31648c2ecf20Sopenharmony_ci		rdev->config.si.max_hw_contexts = 8;
31658c2ecf20Sopenharmony_ci
31668c2ecf20Sopenharmony_ci		rdev->config.si.sc_prim_fifo_size_frontend = 0x20;
31678c2ecf20Sopenharmony_ci		rdev->config.si.sc_prim_fifo_size_backend = 0x40;
31688c2ecf20Sopenharmony_ci		rdev->config.si.sc_hiz_tile_fifo_size = 0x30;
31698c2ecf20Sopenharmony_ci		rdev->config.si.sc_earlyz_tile_fifo_size = 0x130;
31708c2ecf20Sopenharmony_ci		gb_addr_config = VERDE_GB_ADDR_CONFIG_GOLDEN;
31718c2ecf20Sopenharmony_ci		break;
31728c2ecf20Sopenharmony_ci	case CHIP_HAINAN:
31738c2ecf20Sopenharmony_ci		rdev->config.si.max_shader_engines = 1;
31748c2ecf20Sopenharmony_ci		rdev->config.si.max_tile_pipes = 4;
31758c2ecf20Sopenharmony_ci		rdev->config.si.max_cu_per_sh = 5;
31768c2ecf20Sopenharmony_ci		rdev->config.si.max_sh_per_se = 1;
31778c2ecf20Sopenharmony_ci		rdev->config.si.max_backends_per_se = 1;
31788c2ecf20Sopenharmony_ci		rdev->config.si.max_texture_channel_caches = 2;
31798c2ecf20Sopenharmony_ci		rdev->config.si.max_gprs = 256;
31808c2ecf20Sopenharmony_ci		rdev->config.si.max_gs_threads = 16;
31818c2ecf20Sopenharmony_ci		rdev->config.si.max_hw_contexts = 8;
31828c2ecf20Sopenharmony_ci
31838c2ecf20Sopenharmony_ci		rdev->config.si.sc_prim_fifo_size_frontend = 0x20;
31848c2ecf20Sopenharmony_ci		rdev->config.si.sc_prim_fifo_size_backend = 0x40;
31858c2ecf20Sopenharmony_ci		rdev->config.si.sc_hiz_tile_fifo_size = 0x30;
31868c2ecf20Sopenharmony_ci		rdev->config.si.sc_earlyz_tile_fifo_size = 0x130;
31878c2ecf20Sopenharmony_ci		gb_addr_config = HAINAN_GB_ADDR_CONFIG_GOLDEN;
31888c2ecf20Sopenharmony_ci		break;
31898c2ecf20Sopenharmony_ci	}
31908c2ecf20Sopenharmony_ci
31918c2ecf20Sopenharmony_ci	/* Initialize HDP */
31928c2ecf20Sopenharmony_ci	for (i = 0, j = 0; i < 32; i++, j += 0x18) {
31938c2ecf20Sopenharmony_ci		WREG32((0x2c14 + j), 0x00000000);
31948c2ecf20Sopenharmony_ci		WREG32((0x2c18 + j), 0x00000000);
31958c2ecf20Sopenharmony_ci		WREG32((0x2c1c + j), 0x00000000);
31968c2ecf20Sopenharmony_ci		WREG32((0x2c20 + j), 0x00000000);
31978c2ecf20Sopenharmony_ci		WREG32((0x2c24 + j), 0x00000000);
31988c2ecf20Sopenharmony_ci	}
31998c2ecf20Sopenharmony_ci
32008c2ecf20Sopenharmony_ci	WREG32(GRBM_CNTL, GRBM_READ_TIMEOUT(0xff));
32018c2ecf20Sopenharmony_ci	WREG32(SRBM_INT_CNTL, 1);
32028c2ecf20Sopenharmony_ci	WREG32(SRBM_INT_ACK, 1);
32038c2ecf20Sopenharmony_ci
32048c2ecf20Sopenharmony_ci	evergreen_fix_pci_max_read_req_size(rdev);
32058c2ecf20Sopenharmony_ci
32068c2ecf20Sopenharmony_ci	WREG32(BIF_FB_EN, FB_READ_EN | FB_WRITE_EN);
32078c2ecf20Sopenharmony_ci
32088c2ecf20Sopenharmony_ci	mc_shared_chmap = RREG32(MC_SHARED_CHMAP);
32098c2ecf20Sopenharmony_ci	mc_arb_ramcfg = RREG32(MC_ARB_RAMCFG);
32108c2ecf20Sopenharmony_ci
32118c2ecf20Sopenharmony_ci	rdev->config.si.num_tile_pipes = rdev->config.si.max_tile_pipes;
32128c2ecf20Sopenharmony_ci	rdev->config.si.mem_max_burst_length_bytes = 256;
32138c2ecf20Sopenharmony_ci	tmp = (mc_arb_ramcfg & NOOFCOLS_MASK) >> NOOFCOLS_SHIFT;
32148c2ecf20Sopenharmony_ci	rdev->config.si.mem_row_size_in_kb = (4 * (1 << (8 + tmp))) / 1024;
32158c2ecf20Sopenharmony_ci	if (rdev->config.si.mem_row_size_in_kb > 4)
32168c2ecf20Sopenharmony_ci		rdev->config.si.mem_row_size_in_kb = 4;
32178c2ecf20Sopenharmony_ci	/* XXX use MC settings? */
32188c2ecf20Sopenharmony_ci	rdev->config.si.shader_engine_tile_size = 32;
32198c2ecf20Sopenharmony_ci	rdev->config.si.num_gpus = 1;
32208c2ecf20Sopenharmony_ci	rdev->config.si.multi_gpu_tile_size = 64;
32218c2ecf20Sopenharmony_ci
32228c2ecf20Sopenharmony_ci	/* fix up row size */
32238c2ecf20Sopenharmony_ci	gb_addr_config &= ~ROW_SIZE_MASK;
32248c2ecf20Sopenharmony_ci	switch (rdev->config.si.mem_row_size_in_kb) {
32258c2ecf20Sopenharmony_ci	case 1:
32268c2ecf20Sopenharmony_ci	default:
32278c2ecf20Sopenharmony_ci		gb_addr_config |= ROW_SIZE(0);
32288c2ecf20Sopenharmony_ci		break;
32298c2ecf20Sopenharmony_ci	case 2:
32308c2ecf20Sopenharmony_ci		gb_addr_config |= ROW_SIZE(1);
32318c2ecf20Sopenharmony_ci		break;
32328c2ecf20Sopenharmony_ci	case 4:
32338c2ecf20Sopenharmony_ci		gb_addr_config |= ROW_SIZE(2);
32348c2ecf20Sopenharmony_ci		break;
32358c2ecf20Sopenharmony_ci	}
32368c2ecf20Sopenharmony_ci
32378c2ecf20Sopenharmony_ci	/* setup tiling info dword.  gb_addr_config is not adequate since it does
32388c2ecf20Sopenharmony_ci	 * not have bank info, so create a custom tiling dword.
32398c2ecf20Sopenharmony_ci	 * bits 3:0   num_pipes
32408c2ecf20Sopenharmony_ci	 * bits 7:4   num_banks
32418c2ecf20Sopenharmony_ci	 * bits 11:8  group_size
32428c2ecf20Sopenharmony_ci	 * bits 15:12 row_size
32438c2ecf20Sopenharmony_ci	 */
32448c2ecf20Sopenharmony_ci	rdev->config.si.tile_config = 0;
32458c2ecf20Sopenharmony_ci	switch (rdev->config.si.num_tile_pipes) {
32468c2ecf20Sopenharmony_ci	case 1:
32478c2ecf20Sopenharmony_ci		rdev->config.si.tile_config |= (0 << 0);
32488c2ecf20Sopenharmony_ci		break;
32498c2ecf20Sopenharmony_ci	case 2:
32508c2ecf20Sopenharmony_ci		rdev->config.si.tile_config |= (1 << 0);
32518c2ecf20Sopenharmony_ci		break;
32528c2ecf20Sopenharmony_ci	case 4:
32538c2ecf20Sopenharmony_ci		rdev->config.si.tile_config |= (2 << 0);
32548c2ecf20Sopenharmony_ci		break;
32558c2ecf20Sopenharmony_ci	case 8:
32568c2ecf20Sopenharmony_ci	default:
32578c2ecf20Sopenharmony_ci		/* XXX what about 12? */
32588c2ecf20Sopenharmony_ci		rdev->config.si.tile_config |= (3 << 0);
32598c2ecf20Sopenharmony_ci		break;
32608c2ecf20Sopenharmony_ci	}
32618c2ecf20Sopenharmony_ci	switch ((mc_arb_ramcfg & NOOFBANK_MASK) >> NOOFBANK_SHIFT) {
32628c2ecf20Sopenharmony_ci	case 0: /* four banks */
32638c2ecf20Sopenharmony_ci		rdev->config.si.tile_config |= 0 << 4;
32648c2ecf20Sopenharmony_ci		break;
32658c2ecf20Sopenharmony_ci	case 1: /* eight banks */
32668c2ecf20Sopenharmony_ci		rdev->config.si.tile_config |= 1 << 4;
32678c2ecf20Sopenharmony_ci		break;
32688c2ecf20Sopenharmony_ci	case 2: /* sixteen banks */
32698c2ecf20Sopenharmony_ci	default:
32708c2ecf20Sopenharmony_ci		rdev->config.si.tile_config |= 2 << 4;
32718c2ecf20Sopenharmony_ci		break;
32728c2ecf20Sopenharmony_ci	}
32738c2ecf20Sopenharmony_ci	rdev->config.si.tile_config |=
32748c2ecf20Sopenharmony_ci		((gb_addr_config & PIPE_INTERLEAVE_SIZE_MASK) >> PIPE_INTERLEAVE_SIZE_SHIFT) << 8;
32758c2ecf20Sopenharmony_ci	rdev->config.si.tile_config |=
32768c2ecf20Sopenharmony_ci		((gb_addr_config & ROW_SIZE_MASK) >> ROW_SIZE_SHIFT) << 12;
32778c2ecf20Sopenharmony_ci
32788c2ecf20Sopenharmony_ci	WREG32(GB_ADDR_CONFIG, gb_addr_config);
32798c2ecf20Sopenharmony_ci	WREG32(DMIF_ADDR_CONFIG, gb_addr_config);
32808c2ecf20Sopenharmony_ci	WREG32(DMIF_ADDR_CALC, gb_addr_config);
32818c2ecf20Sopenharmony_ci	WREG32(HDP_ADDR_CONFIG, gb_addr_config);
32828c2ecf20Sopenharmony_ci	WREG32(DMA_TILING_CONFIG + DMA0_REGISTER_OFFSET, gb_addr_config);
32838c2ecf20Sopenharmony_ci	WREG32(DMA_TILING_CONFIG + DMA1_REGISTER_OFFSET, gb_addr_config);
32848c2ecf20Sopenharmony_ci	if (rdev->has_uvd) {
32858c2ecf20Sopenharmony_ci		WREG32(UVD_UDEC_ADDR_CONFIG, gb_addr_config);
32868c2ecf20Sopenharmony_ci		WREG32(UVD_UDEC_DB_ADDR_CONFIG, gb_addr_config);
32878c2ecf20Sopenharmony_ci		WREG32(UVD_UDEC_DBW_ADDR_CONFIG, gb_addr_config);
32888c2ecf20Sopenharmony_ci	}
32898c2ecf20Sopenharmony_ci
32908c2ecf20Sopenharmony_ci	si_tiling_mode_table_init(rdev);
32918c2ecf20Sopenharmony_ci
32928c2ecf20Sopenharmony_ci	si_setup_rb(rdev, rdev->config.si.max_shader_engines,
32938c2ecf20Sopenharmony_ci		    rdev->config.si.max_sh_per_se,
32948c2ecf20Sopenharmony_ci		    rdev->config.si.max_backends_per_se);
32958c2ecf20Sopenharmony_ci
32968c2ecf20Sopenharmony_ci	si_setup_spi(rdev, rdev->config.si.max_shader_engines,
32978c2ecf20Sopenharmony_ci		     rdev->config.si.max_sh_per_se,
32988c2ecf20Sopenharmony_ci		     rdev->config.si.max_cu_per_sh);
32998c2ecf20Sopenharmony_ci
33008c2ecf20Sopenharmony_ci	rdev->config.si.active_cus = 0;
33018c2ecf20Sopenharmony_ci	for (i = 0; i < rdev->config.si.max_shader_engines; i++) {
33028c2ecf20Sopenharmony_ci		for (j = 0; j < rdev->config.si.max_sh_per_se; j++) {
33038c2ecf20Sopenharmony_ci			rdev->config.si.active_cus +=
33048c2ecf20Sopenharmony_ci				hweight32(si_get_cu_active_bitmap(rdev, i, j));
33058c2ecf20Sopenharmony_ci		}
33068c2ecf20Sopenharmony_ci	}
33078c2ecf20Sopenharmony_ci
33088c2ecf20Sopenharmony_ci	/* set HW defaults for 3D engine */
33098c2ecf20Sopenharmony_ci	WREG32(CP_QUEUE_THRESHOLDS, (ROQ_IB1_START(0x16) |
33108c2ecf20Sopenharmony_ci				     ROQ_IB2_START(0x2b)));
33118c2ecf20Sopenharmony_ci	WREG32(CP_MEQ_THRESHOLDS, MEQ1_START(0x30) | MEQ2_START(0x60));
33128c2ecf20Sopenharmony_ci
33138c2ecf20Sopenharmony_ci	sx_debug_1 = RREG32(SX_DEBUG_1);
33148c2ecf20Sopenharmony_ci	WREG32(SX_DEBUG_1, sx_debug_1);
33158c2ecf20Sopenharmony_ci
33168c2ecf20Sopenharmony_ci	WREG32(SPI_CONFIG_CNTL_1, VTX_DONE_DELAY(4));
33178c2ecf20Sopenharmony_ci
33188c2ecf20Sopenharmony_ci	WREG32(PA_SC_FIFO_SIZE, (SC_FRONTEND_PRIM_FIFO_SIZE(rdev->config.si.sc_prim_fifo_size_frontend) |
33198c2ecf20Sopenharmony_ci				 SC_BACKEND_PRIM_FIFO_SIZE(rdev->config.si.sc_prim_fifo_size_backend) |
33208c2ecf20Sopenharmony_ci				 SC_HIZ_TILE_FIFO_SIZE(rdev->config.si.sc_hiz_tile_fifo_size) |
33218c2ecf20Sopenharmony_ci				 SC_EARLYZ_TILE_FIFO_SIZE(rdev->config.si.sc_earlyz_tile_fifo_size)));
33228c2ecf20Sopenharmony_ci
33238c2ecf20Sopenharmony_ci	WREG32(VGT_NUM_INSTANCES, 1);
33248c2ecf20Sopenharmony_ci
33258c2ecf20Sopenharmony_ci	WREG32(CP_PERFMON_CNTL, 0);
33268c2ecf20Sopenharmony_ci
33278c2ecf20Sopenharmony_ci	WREG32(SQ_CONFIG, 0);
33288c2ecf20Sopenharmony_ci
33298c2ecf20Sopenharmony_ci	WREG32(PA_SC_FORCE_EOV_MAX_CNTS, (FORCE_EOV_MAX_CLK_CNT(4095) |
33308c2ecf20Sopenharmony_ci					  FORCE_EOV_MAX_REZ_CNT(255)));
33318c2ecf20Sopenharmony_ci
33328c2ecf20Sopenharmony_ci	WREG32(VGT_CACHE_INVALIDATION, CACHE_INVALIDATION(VC_AND_TC) |
33338c2ecf20Sopenharmony_ci	       AUTO_INVLD_EN(ES_AND_GS_AUTO));
33348c2ecf20Sopenharmony_ci
33358c2ecf20Sopenharmony_ci	WREG32(VGT_GS_VERTEX_REUSE, 16);
33368c2ecf20Sopenharmony_ci	WREG32(PA_SC_LINE_STIPPLE_STATE, 0);
33378c2ecf20Sopenharmony_ci
33388c2ecf20Sopenharmony_ci	WREG32(CB_PERFCOUNTER0_SELECT0, 0);
33398c2ecf20Sopenharmony_ci	WREG32(CB_PERFCOUNTER0_SELECT1, 0);
33408c2ecf20Sopenharmony_ci	WREG32(CB_PERFCOUNTER1_SELECT0, 0);
33418c2ecf20Sopenharmony_ci	WREG32(CB_PERFCOUNTER1_SELECT1, 0);
33428c2ecf20Sopenharmony_ci	WREG32(CB_PERFCOUNTER2_SELECT0, 0);
33438c2ecf20Sopenharmony_ci	WREG32(CB_PERFCOUNTER2_SELECT1, 0);
33448c2ecf20Sopenharmony_ci	WREG32(CB_PERFCOUNTER3_SELECT0, 0);
33458c2ecf20Sopenharmony_ci	WREG32(CB_PERFCOUNTER3_SELECT1, 0);
33468c2ecf20Sopenharmony_ci
33478c2ecf20Sopenharmony_ci	tmp = RREG32(HDP_MISC_CNTL);
33488c2ecf20Sopenharmony_ci	tmp |= HDP_FLUSH_INVALIDATE_CACHE;
33498c2ecf20Sopenharmony_ci	WREG32(HDP_MISC_CNTL, tmp);
33508c2ecf20Sopenharmony_ci
33518c2ecf20Sopenharmony_ci	hdp_host_path_cntl = RREG32(HDP_HOST_PATH_CNTL);
33528c2ecf20Sopenharmony_ci	WREG32(HDP_HOST_PATH_CNTL, hdp_host_path_cntl);
33538c2ecf20Sopenharmony_ci
33548c2ecf20Sopenharmony_ci	WREG32(PA_CL_ENHANCE, CLIP_VTX_REORDER_ENA | NUM_CLIP_SEQ(3));
33558c2ecf20Sopenharmony_ci
33568c2ecf20Sopenharmony_ci	udelay(50);
33578c2ecf20Sopenharmony_ci}
33588c2ecf20Sopenharmony_ci
33598c2ecf20Sopenharmony_ci/*
33608c2ecf20Sopenharmony_ci * GPU scratch registers helpers function.
33618c2ecf20Sopenharmony_ci */
33628c2ecf20Sopenharmony_cistatic void si_scratch_init(struct radeon_device *rdev)
33638c2ecf20Sopenharmony_ci{
33648c2ecf20Sopenharmony_ci	int i;
33658c2ecf20Sopenharmony_ci
33668c2ecf20Sopenharmony_ci	rdev->scratch.num_reg = 7;
33678c2ecf20Sopenharmony_ci	rdev->scratch.reg_base = SCRATCH_REG0;
33688c2ecf20Sopenharmony_ci	for (i = 0; i < rdev->scratch.num_reg; i++) {
33698c2ecf20Sopenharmony_ci		rdev->scratch.free[i] = true;
33708c2ecf20Sopenharmony_ci		rdev->scratch.reg[i] = rdev->scratch.reg_base + (i * 4);
33718c2ecf20Sopenharmony_ci	}
33728c2ecf20Sopenharmony_ci}
33738c2ecf20Sopenharmony_ci
33748c2ecf20Sopenharmony_civoid si_fence_ring_emit(struct radeon_device *rdev,
33758c2ecf20Sopenharmony_ci			struct radeon_fence *fence)
33768c2ecf20Sopenharmony_ci{
33778c2ecf20Sopenharmony_ci	struct radeon_ring *ring = &rdev->ring[fence->ring];
33788c2ecf20Sopenharmony_ci	u64 addr = rdev->fence_drv[fence->ring].gpu_addr;
33798c2ecf20Sopenharmony_ci
33808c2ecf20Sopenharmony_ci	/* flush read cache over gart */
33818c2ecf20Sopenharmony_ci	radeon_ring_write(ring, PACKET3(PACKET3_SET_CONFIG_REG, 1));
33828c2ecf20Sopenharmony_ci	radeon_ring_write(ring, (CP_COHER_CNTL2 - PACKET3_SET_CONFIG_REG_START) >> 2);
33838c2ecf20Sopenharmony_ci	radeon_ring_write(ring, 0);
33848c2ecf20Sopenharmony_ci	radeon_ring_write(ring, PACKET3(PACKET3_SURFACE_SYNC, 3));
33858c2ecf20Sopenharmony_ci	radeon_ring_write(ring, PACKET3_TCL1_ACTION_ENA |
33868c2ecf20Sopenharmony_ci			  PACKET3_TC_ACTION_ENA |
33878c2ecf20Sopenharmony_ci			  PACKET3_SH_KCACHE_ACTION_ENA |
33888c2ecf20Sopenharmony_ci			  PACKET3_SH_ICACHE_ACTION_ENA);
33898c2ecf20Sopenharmony_ci	radeon_ring_write(ring, 0xFFFFFFFF);
33908c2ecf20Sopenharmony_ci	radeon_ring_write(ring, 0);
33918c2ecf20Sopenharmony_ci	radeon_ring_write(ring, 10); /* poll interval */
33928c2ecf20Sopenharmony_ci	/* EVENT_WRITE_EOP - flush caches, send int */
33938c2ecf20Sopenharmony_ci	radeon_ring_write(ring, PACKET3(PACKET3_EVENT_WRITE_EOP, 4));
33948c2ecf20Sopenharmony_ci	radeon_ring_write(ring, EVENT_TYPE(CACHE_FLUSH_AND_INV_TS_EVENT) | EVENT_INDEX(5));
33958c2ecf20Sopenharmony_ci	radeon_ring_write(ring, lower_32_bits(addr));
33968c2ecf20Sopenharmony_ci	radeon_ring_write(ring, (upper_32_bits(addr) & 0xff) | DATA_SEL(1) | INT_SEL(2));
33978c2ecf20Sopenharmony_ci	radeon_ring_write(ring, fence->seq);
33988c2ecf20Sopenharmony_ci	radeon_ring_write(ring, 0);
33998c2ecf20Sopenharmony_ci}
34008c2ecf20Sopenharmony_ci
34018c2ecf20Sopenharmony_ci/*
34028c2ecf20Sopenharmony_ci * IB stuff
34038c2ecf20Sopenharmony_ci */
34048c2ecf20Sopenharmony_civoid si_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib)
34058c2ecf20Sopenharmony_ci{
34068c2ecf20Sopenharmony_ci	struct radeon_ring *ring = &rdev->ring[ib->ring];
34078c2ecf20Sopenharmony_ci	unsigned vm_id = ib->vm ? ib->vm->ids[ib->ring].id : 0;
34088c2ecf20Sopenharmony_ci	u32 header;
34098c2ecf20Sopenharmony_ci
34108c2ecf20Sopenharmony_ci	if (ib->is_const_ib) {
34118c2ecf20Sopenharmony_ci		/* set switch buffer packet before const IB */
34128c2ecf20Sopenharmony_ci		radeon_ring_write(ring, PACKET3(PACKET3_SWITCH_BUFFER, 0));
34138c2ecf20Sopenharmony_ci		radeon_ring_write(ring, 0);
34148c2ecf20Sopenharmony_ci
34158c2ecf20Sopenharmony_ci		header = PACKET3(PACKET3_INDIRECT_BUFFER_CONST, 2);
34168c2ecf20Sopenharmony_ci	} else {
34178c2ecf20Sopenharmony_ci		u32 next_rptr;
34188c2ecf20Sopenharmony_ci		if (ring->rptr_save_reg) {
34198c2ecf20Sopenharmony_ci			next_rptr = ring->wptr + 3 + 4 + 8;
34208c2ecf20Sopenharmony_ci			radeon_ring_write(ring, PACKET3(PACKET3_SET_CONFIG_REG, 1));
34218c2ecf20Sopenharmony_ci			radeon_ring_write(ring, ((ring->rptr_save_reg -
34228c2ecf20Sopenharmony_ci						  PACKET3_SET_CONFIG_REG_START) >> 2));
34238c2ecf20Sopenharmony_ci			radeon_ring_write(ring, next_rptr);
34248c2ecf20Sopenharmony_ci		} else if (rdev->wb.enabled) {
34258c2ecf20Sopenharmony_ci			next_rptr = ring->wptr + 5 + 4 + 8;
34268c2ecf20Sopenharmony_ci			radeon_ring_write(ring, PACKET3(PACKET3_WRITE_DATA, 3));
34278c2ecf20Sopenharmony_ci			radeon_ring_write(ring, (1 << 8));
34288c2ecf20Sopenharmony_ci			radeon_ring_write(ring, ring->next_rptr_gpu_addr & 0xfffffffc);
34298c2ecf20Sopenharmony_ci			radeon_ring_write(ring, upper_32_bits(ring->next_rptr_gpu_addr));
34308c2ecf20Sopenharmony_ci			radeon_ring_write(ring, next_rptr);
34318c2ecf20Sopenharmony_ci		}
34328c2ecf20Sopenharmony_ci
34338c2ecf20Sopenharmony_ci		header = PACKET3(PACKET3_INDIRECT_BUFFER, 2);
34348c2ecf20Sopenharmony_ci	}
34358c2ecf20Sopenharmony_ci
34368c2ecf20Sopenharmony_ci	radeon_ring_write(ring, header);
34378c2ecf20Sopenharmony_ci	radeon_ring_write(ring,
34388c2ecf20Sopenharmony_ci#ifdef __BIG_ENDIAN
34398c2ecf20Sopenharmony_ci			  (2 << 0) |
34408c2ecf20Sopenharmony_ci#endif
34418c2ecf20Sopenharmony_ci			  (ib->gpu_addr & 0xFFFFFFFC));
34428c2ecf20Sopenharmony_ci	radeon_ring_write(ring, upper_32_bits(ib->gpu_addr) & 0xFFFF);
34438c2ecf20Sopenharmony_ci	radeon_ring_write(ring, ib->length_dw | (vm_id << 24));
34448c2ecf20Sopenharmony_ci
34458c2ecf20Sopenharmony_ci	if (!ib->is_const_ib) {
34468c2ecf20Sopenharmony_ci		/* flush read cache over gart for this vmid */
34478c2ecf20Sopenharmony_ci		radeon_ring_write(ring, PACKET3(PACKET3_SET_CONFIG_REG, 1));
34488c2ecf20Sopenharmony_ci		radeon_ring_write(ring, (CP_COHER_CNTL2 - PACKET3_SET_CONFIG_REG_START) >> 2);
34498c2ecf20Sopenharmony_ci		radeon_ring_write(ring, vm_id);
34508c2ecf20Sopenharmony_ci		radeon_ring_write(ring, PACKET3(PACKET3_SURFACE_SYNC, 3));
34518c2ecf20Sopenharmony_ci		radeon_ring_write(ring, PACKET3_TCL1_ACTION_ENA |
34528c2ecf20Sopenharmony_ci				  PACKET3_TC_ACTION_ENA |
34538c2ecf20Sopenharmony_ci				  PACKET3_SH_KCACHE_ACTION_ENA |
34548c2ecf20Sopenharmony_ci				  PACKET3_SH_ICACHE_ACTION_ENA);
34558c2ecf20Sopenharmony_ci		radeon_ring_write(ring, 0xFFFFFFFF);
34568c2ecf20Sopenharmony_ci		radeon_ring_write(ring, 0);
34578c2ecf20Sopenharmony_ci		radeon_ring_write(ring, 10); /* poll interval */
34588c2ecf20Sopenharmony_ci	}
34598c2ecf20Sopenharmony_ci}
34608c2ecf20Sopenharmony_ci
34618c2ecf20Sopenharmony_ci/*
34628c2ecf20Sopenharmony_ci * CP.
34638c2ecf20Sopenharmony_ci */
34648c2ecf20Sopenharmony_cistatic void si_cp_enable(struct radeon_device *rdev, bool enable)
34658c2ecf20Sopenharmony_ci{
34668c2ecf20Sopenharmony_ci	if (enable)
34678c2ecf20Sopenharmony_ci		WREG32(CP_ME_CNTL, 0);
34688c2ecf20Sopenharmony_ci	else {
34698c2ecf20Sopenharmony_ci		if (rdev->asic->copy.copy_ring_index == RADEON_RING_TYPE_GFX_INDEX)
34708c2ecf20Sopenharmony_ci			radeon_ttm_set_active_vram_size(rdev, rdev->mc.visible_vram_size);
34718c2ecf20Sopenharmony_ci		WREG32(CP_ME_CNTL, (CP_ME_HALT | CP_PFP_HALT | CP_CE_HALT));
34728c2ecf20Sopenharmony_ci		WREG32(SCRATCH_UMSK, 0);
34738c2ecf20Sopenharmony_ci		rdev->ring[RADEON_RING_TYPE_GFX_INDEX].ready = false;
34748c2ecf20Sopenharmony_ci		rdev->ring[CAYMAN_RING_TYPE_CP1_INDEX].ready = false;
34758c2ecf20Sopenharmony_ci		rdev->ring[CAYMAN_RING_TYPE_CP2_INDEX].ready = false;
34768c2ecf20Sopenharmony_ci	}
34778c2ecf20Sopenharmony_ci	udelay(50);
34788c2ecf20Sopenharmony_ci}
34798c2ecf20Sopenharmony_ci
34808c2ecf20Sopenharmony_cistatic int si_cp_load_microcode(struct radeon_device *rdev)
34818c2ecf20Sopenharmony_ci{
34828c2ecf20Sopenharmony_ci	int i;
34838c2ecf20Sopenharmony_ci
34848c2ecf20Sopenharmony_ci	if (!rdev->me_fw || !rdev->pfp_fw || !rdev->ce_fw)
34858c2ecf20Sopenharmony_ci		return -EINVAL;
34868c2ecf20Sopenharmony_ci
34878c2ecf20Sopenharmony_ci	si_cp_enable(rdev, false);
34888c2ecf20Sopenharmony_ci
34898c2ecf20Sopenharmony_ci	if (rdev->new_fw) {
34908c2ecf20Sopenharmony_ci		const struct gfx_firmware_header_v1_0 *pfp_hdr =
34918c2ecf20Sopenharmony_ci			(const struct gfx_firmware_header_v1_0 *)rdev->pfp_fw->data;
34928c2ecf20Sopenharmony_ci		const struct gfx_firmware_header_v1_0 *ce_hdr =
34938c2ecf20Sopenharmony_ci			(const struct gfx_firmware_header_v1_0 *)rdev->ce_fw->data;
34948c2ecf20Sopenharmony_ci		const struct gfx_firmware_header_v1_0 *me_hdr =
34958c2ecf20Sopenharmony_ci			(const struct gfx_firmware_header_v1_0 *)rdev->me_fw->data;
34968c2ecf20Sopenharmony_ci		const __le32 *fw_data;
34978c2ecf20Sopenharmony_ci		u32 fw_size;
34988c2ecf20Sopenharmony_ci
34998c2ecf20Sopenharmony_ci		radeon_ucode_print_gfx_hdr(&pfp_hdr->header);
35008c2ecf20Sopenharmony_ci		radeon_ucode_print_gfx_hdr(&ce_hdr->header);
35018c2ecf20Sopenharmony_ci		radeon_ucode_print_gfx_hdr(&me_hdr->header);
35028c2ecf20Sopenharmony_ci
35038c2ecf20Sopenharmony_ci		/* PFP */
35048c2ecf20Sopenharmony_ci		fw_data = (const __le32 *)
35058c2ecf20Sopenharmony_ci			(rdev->pfp_fw->data + le32_to_cpu(pfp_hdr->header.ucode_array_offset_bytes));
35068c2ecf20Sopenharmony_ci		fw_size = le32_to_cpu(pfp_hdr->header.ucode_size_bytes) / 4;
35078c2ecf20Sopenharmony_ci		WREG32(CP_PFP_UCODE_ADDR, 0);
35088c2ecf20Sopenharmony_ci		for (i = 0; i < fw_size; i++)
35098c2ecf20Sopenharmony_ci			WREG32(CP_PFP_UCODE_DATA, le32_to_cpup(fw_data++));
35108c2ecf20Sopenharmony_ci		WREG32(CP_PFP_UCODE_ADDR, 0);
35118c2ecf20Sopenharmony_ci
35128c2ecf20Sopenharmony_ci		/* CE */
35138c2ecf20Sopenharmony_ci		fw_data = (const __le32 *)
35148c2ecf20Sopenharmony_ci			(rdev->ce_fw->data + le32_to_cpu(ce_hdr->header.ucode_array_offset_bytes));
35158c2ecf20Sopenharmony_ci		fw_size = le32_to_cpu(ce_hdr->header.ucode_size_bytes) / 4;
35168c2ecf20Sopenharmony_ci		WREG32(CP_CE_UCODE_ADDR, 0);
35178c2ecf20Sopenharmony_ci		for (i = 0; i < fw_size; i++)
35188c2ecf20Sopenharmony_ci			WREG32(CP_CE_UCODE_DATA, le32_to_cpup(fw_data++));
35198c2ecf20Sopenharmony_ci		WREG32(CP_CE_UCODE_ADDR, 0);
35208c2ecf20Sopenharmony_ci
35218c2ecf20Sopenharmony_ci		/* ME */
35228c2ecf20Sopenharmony_ci		fw_data = (const __be32 *)
35238c2ecf20Sopenharmony_ci			(rdev->me_fw->data + le32_to_cpu(me_hdr->header.ucode_array_offset_bytes));
35248c2ecf20Sopenharmony_ci		fw_size = le32_to_cpu(me_hdr->header.ucode_size_bytes) / 4;
35258c2ecf20Sopenharmony_ci		WREG32(CP_ME_RAM_WADDR, 0);
35268c2ecf20Sopenharmony_ci		for (i = 0; i < fw_size; i++)
35278c2ecf20Sopenharmony_ci			WREG32(CP_ME_RAM_DATA, le32_to_cpup(fw_data++));
35288c2ecf20Sopenharmony_ci		WREG32(CP_ME_RAM_WADDR, 0);
35298c2ecf20Sopenharmony_ci	} else {
35308c2ecf20Sopenharmony_ci		const __be32 *fw_data;
35318c2ecf20Sopenharmony_ci
35328c2ecf20Sopenharmony_ci		/* PFP */
35338c2ecf20Sopenharmony_ci		fw_data = (const __be32 *)rdev->pfp_fw->data;
35348c2ecf20Sopenharmony_ci		WREG32(CP_PFP_UCODE_ADDR, 0);
35358c2ecf20Sopenharmony_ci		for (i = 0; i < SI_PFP_UCODE_SIZE; i++)
35368c2ecf20Sopenharmony_ci			WREG32(CP_PFP_UCODE_DATA, be32_to_cpup(fw_data++));
35378c2ecf20Sopenharmony_ci		WREG32(CP_PFP_UCODE_ADDR, 0);
35388c2ecf20Sopenharmony_ci
35398c2ecf20Sopenharmony_ci		/* CE */
35408c2ecf20Sopenharmony_ci		fw_data = (const __be32 *)rdev->ce_fw->data;
35418c2ecf20Sopenharmony_ci		WREG32(CP_CE_UCODE_ADDR, 0);
35428c2ecf20Sopenharmony_ci		for (i = 0; i < SI_CE_UCODE_SIZE; i++)
35438c2ecf20Sopenharmony_ci			WREG32(CP_CE_UCODE_DATA, be32_to_cpup(fw_data++));
35448c2ecf20Sopenharmony_ci		WREG32(CP_CE_UCODE_ADDR, 0);
35458c2ecf20Sopenharmony_ci
35468c2ecf20Sopenharmony_ci		/* ME */
35478c2ecf20Sopenharmony_ci		fw_data = (const __be32 *)rdev->me_fw->data;
35488c2ecf20Sopenharmony_ci		WREG32(CP_ME_RAM_WADDR, 0);
35498c2ecf20Sopenharmony_ci		for (i = 0; i < SI_PM4_UCODE_SIZE; i++)
35508c2ecf20Sopenharmony_ci			WREG32(CP_ME_RAM_DATA, be32_to_cpup(fw_data++));
35518c2ecf20Sopenharmony_ci		WREG32(CP_ME_RAM_WADDR, 0);
35528c2ecf20Sopenharmony_ci	}
35538c2ecf20Sopenharmony_ci
35548c2ecf20Sopenharmony_ci	WREG32(CP_PFP_UCODE_ADDR, 0);
35558c2ecf20Sopenharmony_ci	WREG32(CP_CE_UCODE_ADDR, 0);
35568c2ecf20Sopenharmony_ci	WREG32(CP_ME_RAM_WADDR, 0);
35578c2ecf20Sopenharmony_ci	WREG32(CP_ME_RAM_RADDR, 0);
35588c2ecf20Sopenharmony_ci	return 0;
35598c2ecf20Sopenharmony_ci}
35608c2ecf20Sopenharmony_ci
35618c2ecf20Sopenharmony_cistatic int si_cp_start(struct radeon_device *rdev)
35628c2ecf20Sopenharmony_ci{
35638c2ecf20Sopenharmony_ci	struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX];
35648c2ecf20Sopenharmony_ci	int r, i;
35658c2ecf20Sopenharmony_ci
35668c2ecf20Sopenharmony_ci	r = radeon_ring_lock(rdev, ring, 7 + 4);
35678c2ecf20Sopenharmony_ci	if (r) {
35688c2ecf20Sopenharmony_ci		DRM_ERROR("radeon: cp failed to lock ring (%d).\n", r);
35698c2ecf20Sopenharmony_ci		return r;
35708c2ecf20Sopenharmony_ci	}
35718c2ecf20Sopenharmony_ci	/* init the CP */
35728c2ecf20Sopenharmony_ci	radeon_ring_write(ring, PACKET3(PACKET3_ME_INITIALIZE, 5));
35738c2ecf20Sopenharmony_ci	radeon_ring_write(ring, 0x1);
35748c2ecf20Sopenharmony_ci	radeon_ring_write(ring, 0x0);
35758c2ecf20Sopenharmony_ci	radeon_ring_write(ring, rdev->config.si.max_hw_contexts - 1);
35768c2ecf20Sopenharmony_ci	radeon_ring_write(ring, PACKET3_ME_INITIALIZE_DEVICE_ID(1));
35778c2ecf20Sopenharmony_ci	radeon_ring_write(ring, 0);
35788c2ecf20Sopenharmony_ci	radeon_ring_write(ring, 0);
35798c2ecf20Sopenharmony_ci
35808c2ecf20Sopenharmony_ci	/* init the CE partitions */
35818c2ecf20Sopenharmony_ci	radeon_ring_write(ring, PACKET3(PACKET3_SET_BASE, 2));
35828c2ecf20Sopenharmony_ci	radeon_ring_write(ring, PACKET3_BASE_INDEX(CE_PARTITION_BASE));
35838c2ecf20Sopenharmony_ci	radeon_ring_write(ring, 0xc000);
35848c2ecf20Sopenharmony_ci	radeon_ring_write(ring, 0xe000);
35858c2ecf20Sopenharmony_ci	radeon_ring_unlock_commit(rdev, ring, false);
35868c2ecf20Sopenharmony_ci
35878c2ecf20Sopenharmony_ci	si_cp_enable(rdev, true);
35888c2ecf20Sopenharmony_ci
35898c2ecf20Sopenharmony_ci	r = radeon_ring_lock(rdev, ring, si_default_size + 10);
35908c2ecf20Sopenharmony_ci	if (r) {
35918c2ecf20Sopenharmony_ci		DRM_ERROR("radeon: cp failed to lock ring (%d).\n", r);
35928c2ecf20Sopenharmony_ci		return r;
35938c2ecf20Sopenharmony_ci	}
35948c2ecf20Sopenharmony_ci
35958c2ecf20Sopenharmony_ci	/* setup clear context state */
35968c2ecf20Sopenharmony_ci	radeon_ring_write(ring, PACKET3(PACKET3_PREAMBLE_CNTL, 0));
35978c2ecf20Sopenharmony_ci	radeon_ring_write(ring, PACKET3_PREAMBLE_BEGIN_CLEAR_STATE);
35988c2ecf20Sopenharmony_ci
35998c2ecf20Sopenharmony_ci	for (i = 0; i < si_default_size; i++)
36008c2ecf20Sopenharmony_ci		radeon_ring_write(ring, si_default_state[i]);
36018c2ecf20Sopenharmony_ci
36028c2ecf20Sopenharmony_ci	radeon_ring_write(ring, PACKET3(PACKET3_PREAMBLE_CNTL, 0));
36038c2ecf20Sopenharmony_ci	radeon_ring_write(ring, PACKET3_PREAMBLE_END_CLEAR_STATE);
36048c2ecf20Sopenharmony_ci
36058c2ecf20Sopenharmony_ci	/* set clear context state */
36068c2ecf20Sopenharmony_ci	radeon_ring_write(ring, PACKET3(PACKET3_CLEAR_STATE, 0));
36078c2ecf20Sopenharmony_ci	radeon_ring_write(ring, 0);
36088c2ecf20Sopenharmony_ci
36098c2ecf20Sopenharmony_ci	radeon_ring_write(ring, PACKET3(PACKET3_SET_CONTEXT_REG, 2));
36108c2ecf20Sopenharmony_ci	radeon_ring_write(ring, 0x00000316);
36118c2ecf20Sopenharmony_ci	radeon_ring_write(ring, 0x0000000e); /* VGT_VERTEX_REUSE_BLOCK_CNTL */
36128c2ecf20Sopenharmony_ci	radeon_ring_write(ring, 0x00000010); /* VGT_OUT_DEALLOC_CNTL */
36138c2ecf20Sopenharmony_ci
36148c2ecf20Sopenharmony_ci	radeon_ring_unlock_commit(rdev, ring, false);
36158c2ecf20Sopenharmony_ci
36168c2ecf20Sopenharmony_ci	for (i = RADEON_RING_TYPE_GFX_INDEX; i <= CAYMAN_RING_TYPE_CP2_INDEX; ++i) {
36178c2ecf20Sopenharmony_ci		ring = &rdev->ring[i];
36188c2ecf20Sopenharmony_ci		r = radeon_ring_lock(rdev, ring, 2);
36198c2ecf20Sopenharmony_ci		if (r) {
36208c2ecf20Sopenharmony_ci			DRM_ERROR("radeon: cp failed to lock ring (%d).\n", r);
36218c2ecf20Sopenharmony_ci			return r;
36228c2ecf20Sopenharmony_ci		}
36238c2ecf20Sopenharmony_ci
36248c2ecf20Sopenharmony_ci		/* clear the compute context state */
36258c2ecf20Sopenharmony_ci		radeon_ring_write(ring, PACKET3_COMPUTE(PACKET3_CLEAR_STATE, 0));
36268c2ecf20Sopenharmony_ci		radeon_ring_write(ring, 0);
36278c2ecf20Sopenharmony_ci
36288c2ecf20Sopenharmony_ci		radeon_ring_unlock_commit(rdev, ring, false);
36298c2ecf20Sopenharmony_ci	}
36308c2ecf20Sopenharmony_ci
36318c2ecf20Sopenharmony_ci	return 0;
36328c2ecf20Sopenharmony_ci}
36338c2ecf20Sopenharmony_ci
36348c2ecf20Sopenharmony_cistatic void si_cp_fini(struct radeon_device *rdev)
36358c2ecf20Sopenharmony_ci{
36368c2ecf20Sopenharmony_ci	struct radeon_ring *ring;
36378c2ecf20Sopenharmony_ci	si_cp_enable(rdev, false);
36388c2ecf20Sopenharmony_ci
36398c2ecf20Sopenharmony_ci	ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX];
36408c2ecf20Sopenharmony_ci	radeon_ring_fini(rdev, ring);
36418c2ecf20Sopenharmony_ci	radeon_scratch_free(rdev, ring->rptr_save_reg);
36428c2ecf20Sopenharmony_ci
36438c2ecf20Sopenharmony_ci	ring = &rdev->ring[CAYMAN_RING_TYPE_CP1_INDEX];
36448c2ecf20Sopenharmony_ci	radeon_ring_fini(rdev, ring);
36458c2ecf20Sopenharmony_ci	radeon_scratch_free(rdev, ring->rptr_save_reg);
36468c2ecf20Sopenharmony_ci
36478c2ecf20Sopenharmony_ci	ring = &rdev->ring[CAYMAN_RING_TYPE_CP2_INDEX];
36488c2ecf20Sopenharmony_ci	radeon_ring_fini(rdev, ring);
36498c2ecf20Sopenharmony_ci	radeon_scratch_free(rdev, ring->rptr_save_reg);
36508c2ecf20Sopenharmony_ci}
36518c2ecf20Sopenharmony_ci
36528c2ecf20Sopenharmony_cistatic int si_cp_resume(struct radeon_device *rdev)
36538c2ecf20Sopenharmony_ci{
36548c2ecf20Sopenharmony_ci	struct radeon_ring *ring;
36558c2ecf20Sopenharmony_ci	u32 tmp;
36568c2ecf20Sopenharmony_ci	u32 rb_bufsz;
36578c2ecf20Sopenharmony_ci	int r;
36588c2ecf20Sopenharmony_ci
36598c2ecf20Sopenharmony_ci	si_enable_gui_idle_interrupt(rdev, false);
36608c2ecf20Sopenharmony_ci
36618c2ecf20Sopenharmony_ci	WREG32(CP_SEM_WAIT_TIMER, 0x0);
36628c2ecf20Sopenharmony_ci	WREG32(CP_SEM_INCOMPLETE_TIMER_CNTL, 0x0);
36638c2ecf20Sopenharmony_ci
36648c2ecf20Sopenharmony_ci	/* Set the write pointer delay */
36658c2ecf20Sopenharmony_ci	WREG32(CP_RB_WPTR_DELAY, 0);
36668c2ecf20Sopenharmony_ci
36678c2ecf20Sopenharmony_ci	WREG32(CP_DEBUG, 0);
36688c2ecf20Sopenharmony_ci	WREG32(SCRATCH_ADDR, ((rdev->wb.gpu_addr + RADEON_WB_SCRATCH_OFFSET) >> 8) & 0xFFFFFFFF);
36698c2ecf20Sopenharmony_ci
36708c2ecf20Sopenharmony_ci	/* ring 0 - compute and gfx */
36718c2ecf20Sopenharmony_ci	/* Set ring buffer size */
36728c2ecf20Sopenharmony_ci	ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX];
36738c2ecf20Sopenharmony_ci	rb_bufsz = order_base_2(ring->ring_size / 8);
36748c2ecf20Sopenharmony_ci	tmp = (order_base_2(RADEON_GPU_PAGE_SIZE/8) << 8) | rb_bufsz;
36758c2ecf20Sopenharmony_ci#ifdef __BIG_ENDIAN
36768c2ecf20Sopenharmony_ci	tmp |= BUF_SWAP_32BIT;
36778c2ecf20Sopenharmony_ci#endif
36788c2ecf20Sopenharmony_ci	WREG32(CP_RB0_CNTL, tmp);
36798c2ecf20Sopenharmony_ci
36808c2ecf20Sopenharmony_ci	/* Initialize the ring buffer's read and write pointers */
36818c2ecf20Sopenharmony_ci	WREG32(CP_RB0_CNTL, tmp | RB_RPTR_WR_ENA);
36828c2ecf20Sopenharmony_ci	ring->wptr = 0;
36838c2ecf20Sopenharmony_ci	WREG32(CP_RB0_WPTR, ring->wptr);
36848c2ecf20Sopenharmony_ci
36858c2ecf20Sopenharmony_ci	/* set the wb address whether it's enabled or not */
36868c2ecf20Sopenharmony_ci	WREG32(CP_RB0_RPTR_ADDR, (rdev->wb.gpu_addr + RADEON_WB_CP_RPTR_OFFSET) & 0xFFFFFFFC);
36878c2ecf20Sopenharmony_ci	WREG32(CP_RB0_RPTR_ADDR_HI, upper_32_bits(rdev->wb.gpu_addr + RADEON_WB_CP_RPTR_OFFSET) & 0xFF);
36888c2ecf20Sopenharmony_ci
36898c2ecf20Sopenharmony_ci	if (rdev->wb.enabled)
36908c2ecf20Sopenharmony_ci		WREG32(SCRATCH_UMSK, 0xff);
36918c2ecf20Sopenharmony_ci	else {
36928c2ecf20Sopenharmony_ci		tmp |= RB_NO_UPDATE;
36938c2ecf20Sopenharmony_ci		WREG32(SCRATCH_UMSK, 0);
36948c2ecf20Sopenharmony_ci	}
36958c2ecf20Sopenharmony_ci
36968c2ecf20Sopenharmony_ci	mdelay(1);
36978c2ecf20Sopenharmony_ci	WREG32(CP_RB0_CNTL, tmp);
36988c2ecf20Sopenharmony_ci
36998c2ecf20Sopenharmony_ci	WREG32(CP_RB0_BASE, ring->gpu_addr >> 8);
37008c2ecf20Sopenharmony_ci
37018c2ecf20Sopenharmony_ci	/* ring1  - compute only */
37028c2ecf20Sopenharmony_ci	/* Set ring buffer size */
37038c2ecf20Sopenharmony_ci	ring = &rdev->ring[CAYMAN_RING_TYPE_CP1_INDEX];
37048c2ecf20Sopenharmony_ci	rb_bufsz = order_base_2(ring->ring_size / 8);
37058c2ecf20Sopenharmony_ci	tmp = (order_base_2(RADEON_GPU_PAGE_SIZE/8) << 8) | rb_bufsz;
37068c2ecf20Sopenharmony_ci#ifdef __BIG_ENDIAN
37078c2ecf20Sopenharmony_ci	tmp |= BUF_SWAP_32BIT;
37088c2ecf20Sopenharmony_ci#endif
37098c2ecf20Sopenharmony_ci	WREG32(CP_RB1_CNTL, tmp);
37108c2ecf20Sopenharmony_ci
37118c2ecf20Sopenharmony_ci	/* Initialize the ring buffer's read and write pointers */
37128c2ecf20Sopenharmony_ci	WREG32(CP_RB1_CNTL, tmp | RB_RPTR_WR_ENA);
37138c2ecf20Sopenharmony_ci	ring->wptr = 0;
37148c2ecf20Sopenharmony_ci	WREG32(CP_RB1_WPTR, ring->wptr);
37158c2ecf20Sopenharmony_ci
37168c2ecf20Sopenharmony_ci	/* set the wb address whether it's enabled or not */
37178c2ecf20Sopenharmony_ci	WREG32(CP_RB1_RPTR_ADDR, (rdev->wb.gpu_addr + RADEON_WB_CP1_RPTR_OFFSET) & 0xFFFFFFFC);
37188c2ecf20Sopenharmony_ci	WREG32(CP_RB1_RPTR_ADDR_HI, upper_32_bits(rdev->wb.gpu_addr + RADEON_WB_CP1_RPTR_OFFSET) & 0xFF);
37198c2ecf20Sopenharmony_ci
37208c2ecf20Sopenharmony_ci	mdelay(1);
37218c2ecf20Sopenharmony_ci	WREG32(CP_RB1_CNTL, tmp);
37228c2ecf20Sopenharmony_ci
37238c2ecf20Sopenharmony_ci	WREG32(CP_RB1_BASE, ring->gpu_addr >> 8);
37248c2ecf20Sopenharmony_ci
37258c2ecf20Sopenharmony_ci	/* ring2 - compute only */
37268c2ecf20Sopenharmony_ci	/* Set ring buffer size */
37278c2ecf20Sopenharmony_ci	ring = &rdev->ring[CAYMAN_RING_TYPE_CP2_INDEX];
37288c2ecf20Sopenharmony_ci	rb_bufsz = order_base_2(ring->ring_size / 8);
37298c2ecf20Sopenharmony_ci	tmp = (order_base_2(RADEON_GPU_PAGE_SIZE/8) << 8) | rb_bufsz;
37308c2ecf20Sopenharmony_ci#ifdef __BIG_ENDIAN
37318c2ecf20Sopenharmony_ci	tmp |= BUF_SWAP_32BIT;
37328c2ecf20Sopenharmony_ci#endif
37338c2ecf20Sopenharmony_ci	WREG32(CP_RB2_CNTL, tmp);
37348c2ecf20Sopenharmony_ci
37358c2ecf20Sopenharmony_ci	/* Initialize the ring buffer's read and write pointers */
37368c2ecf20Sopenharmony_ci	WREG32(CP_RB2_CNTL, tmp | RB_RPTR_WR_ENA);
37378c2ecf20Sopenharmony_ci	ring->wptr = 0;
37388c2ecf20Sopenharmony_ci	WREG32(CP_RB2_WPTR, ring->wptr);
37398c2ecf20Sopenharmony_ci
37408c2ecf20Sopenharmony_ci	/* set the wb address whether it's enabled or not */
37418c2ecf20Sopenharmony_ci	WREG32(CP_RB2_RPTR_ADDR, (rdev->wb.gpu_addr + RADEON_WB_CP2_RPTR_OFFSET) & 0xFFFFFFFC);
37428c2ecf20Sopenharmony_ci	WREG32(CP_RB2_RPTR_ADDR_HI, upper_32_bits(rdev->wb.gpu_addr + RADEON_WB_CP2_RPTR_OFFSET) & 0xFF);
37438c2ecf20Sopenharmony_ci
37448c2ecf20Sopenharmony_ci	mdelay(1);
37458c2ecf20Sopenharmony_ci	WREG32(CP_RB2_CNTL, tmp);
37468c2ecf20Sopenharmony_ci
37478c2ecf20Sopenharmony_ci	WREG32(CP_RB2_BASE, ring->gpu_addr >> 8);
37488c2ecf20Sopenharmony_ci
37498c2ecf20Sopenharmony_ci	/* start the rings */
37508c2ecf20Sopenharmony_ci	si_cp_start(rdev);
37518c2ecf20Sopenharmony_ci	rdev->ring[RADEON_RING_TYPE_GFX_INDEX].ready = true;
37528c2ecf20Sopenharmony_ci	rdev->ring[CAYMAN_RING_TYPE_CP1_INDEX].ready = true;
37538c2ecf20Sopenharmony_ci	rdev->ring[CAYMAN_RING_TYPE_CP2_INDEX].ready = true;
37548c2ecf20Sopenharmony_ci	r = radeon_ring_test(rdev, RADEON_RING_TYPE_GFX_INDEX, &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]);
37558c2ecf20Sopenharmony_ci	if (r) {
37568c2ecf20Sopenharmony_ci		rdev->ring[RADEON_RING_TYPE_GFX_INDEX].ready = false;
37578c2ecf20Sopenharmony_ci		rdev->ring[CAYMAN_RING_TYPE_CP1_INDEX].ready = false;
37588c2ecf20Sopenharmony_ci		rdev->ring[CAYMAN_RING_TYPE_CP2_INDEX].ready = false;
37598c2ecf20Sopenharmony_ci		return r;
37608c2ecf20Sopenharmony_ci	}
37618c2ecf20Sopenharmony_ci	r = radeon_ring_test(rdev, CAYMAN_RING_TYPE_CP1_INDEX, &rdev->ring[CAYMAN_RING_TYPE_CP1_INDEX]);
37628c2ecf20Sopenharmony_ci	if (r) {
37638c2ecf20Sopenharmony_ci		rdev->ring[CAYMAN_RING_TYPE_CP1_INDEX].ready = false;
37648c2ecf20Sopenharmony_ci	}
37658c2ecf20Sopenharmony_ci	r = radeon_ring_test(rdev, CAYMAN_RING_TYPE_CP2_INDEX, &rdev->ring[CAYMAN_RING_TYPE_CP2_INDEX]);
37668c2ecf20Sopenharmony_ci	if (r) {
37678c2ecf20Sopenharmony_ci		rdev->ring[CAYMAN_RING_TYPE_CP2_INDEX].ready = false;
37688c2ecf20Sopenharmony_ci	}
37698c2ecf20Sopenharmony_ci
37708c2ecf20Sopenharmony_ci	si_enable_gui_idle_interrupt(rdev, true);
37718c2ecf20Sopenharmony_ci
37728c2ecf20Sopenharmony_ci	if (rdev->asic->copy.copy_ring_index == RADEON_RING_TYPE_GFX_INDEX)
37738c2ecf20Sopenharmony_ci		radeon_ttm_set_active_vram_size(rdev, rdev->mc.real_vram_size);
37748c2ecf20Sopenharmony_ci
37758c2ecf20Sopenharmony_ci	return 0;
37768c2ecf20Sopenharmony_ci}
37778c2ecf20Sopenharmony_ci
37788c2ecf20Sopenharmony_ciu32 si_gpu_check_soft_reset(struct radeon_device *rdev)
37798c2ecf20Sopenharmony_ci{
37808c2ecf20Sopenharmony_ci	u32 reset_mask = 0;
37818c2ecf20Sopenharmony_ci	u32 tmp;
37828c2ecf20Sopenharmony_ci
37838c2ecf20Sopenharmony_ci	/* GRBM_STATUS */
37848c2ecf20Sopenharmony_ci	tmp = RREG32(GRBM_STATUS);
37858c2ecf20Sopenharmony_ci	if (tmp & (PA_BUSY | SC_BUSY |
37868c2ecf20Sopenharmony_ci		   BCI_BUSY | SX_BUSY |
37878c2ecf20Sopenharmony_ci		   TA_BUSY | VGT_BUSY |
37888c2ecf20Sopenharmony_ci		   DB_BUSY | CB_BUSY |
37898c2ecf20Sopenharmony_ci		   GDS_BUSY | SPI_BUSY |
37908c2ecf20Sopenharmony_ci		   IA_BUSY | IA_BUSY_NO_DMA))
37918c2ecf20Sopenharmony_ci		reset_mask |= RADEON_RESET_GFX;
37928c2ecf20Sopenharmony_ci
37938c2ecf20Sopenharmony_ci	if (tmp & (CF_RQ_PENDING | PF_RQ_PENDING |
37948c2ecf20Sopenharmony_ci		   CP_BUSY | CP_COHERENCY_BUSY))
37958c2ecf20Sopenharmony_ci		reset_mask |= RADEON_RESET_CP;
37968c2ecf20Sopenharmony_ci
37978c2ecf20Sopenharmony_ci	if (tmp & GRBM_EE_BUSY)
37988c2ecf20Sopenharmony_ci		reset_mask |= RADEON_RESET_GRBM | RADEON_RESET_GFX | RADEON_RESET_CP;
37998c2ecf20Sopenharmony_ci
38008c2ecf20Sopenharmony_ci	/* GRBM_STATUS2 */
38018c2ecf20Sopenharmony_ci	tmp = RREG32(GRBM_STATUS2);
38028c2ecf20Sopenharmony_ci	if (tmp & (RLC_RQ_PENDING | RLC_BUSY))
38038c2ecf20Sopenharmony_ci		reset_mask |= RADEON_RESET_RLC;
38048c2ecf20Sopenharmony_ci
38058c2ecf20Sopenharmony_ci	/* DMA_STATUS_REG 0 */
38068c2ecf20Sopenharmony_ci	tmp = RREG32(DMA_STATUS_REG + DMA0_REGISTER_OFFSET);
38078c2ecf20Sopenharmony_ci	if (!(tmp & DMA_IDLE))
38088c2ecf20Sopenharmony_ci		reset_mask |= RADEON_RESET_DMA;
38098c2ecf20Sopenharmony_ci
38108c2ecf20Sopenharmony_ci	/* DMA_STATUS_REG 1 */
38118c2ecf20Sopenharmony_ci	tmp = RREG32(DMA_STATUS_REG + DMA1_REGISTER_OFFSET);
38128c2ecf20Sopenharmony_ci	if (!(tmp & DMA_IDLE))
38138c2ecf20Sopenharmony_ci		reset_mask |= RADEON_RESET_DMA1;
38148c2ecf20Sopenharmony_ci
38158c2ecf20Sopenharmony_ci	/* SRBM_STATUS2 */
38168c2ecf20Sopenharmony_ci	tmp = RREG32(SRBM_STATUS2);
38178c2ecf20Sopenharmony_ci	if (tmp & DMA_BUSY)
38188c2ecf20Sopenharmony_ci		reset_mask |= RADEON_RESET_DMA;
38198c2ecf20Sopenharmony_ci
38208c2ecf20Sopenharmony_ci	if (tmp & DMA1_BUSY)
38218c2ecf20Sopenharmony_ci		reset_mask |= RADEON_RESET_DMA1;
38228c2ecf20Sopenharmony_ci
38238c2ecf20Sopenharmony_ci	/* SRBM_STATUS */
38248c2ecf20Sopenharmony_ci	tmp = RREG32(SRBM_STATUS);
38258c2ecf20Sopenharmony_ci
38268c2ecf20Sopenharmony_ci	if (tmp & IH_BUSY)
38278c2ecf20Sopenharmony_ci		reset_mask |= RADEON_RESET_IH;
38288c2ecf20Sopenharmony_ci
38298c2ecf20Sopenharmony_ci	if (tmp & SEM_BUSY)
38308c2ecf20Sopenharmony_ci		reset_mask |= RADEON_RESET_SEM;
38318c2ecf20Sopenharmony_ci
38328c2ecf20Sopenharmony_ci	if (tmp & GRBM_RQ_PENDING)
38338c2ecf20Sopenharmony_ci		reset_mask |= RADEON_RESET_GRBM;
38348c2ecf20Sopenharmony_ci
38358c2ecf20Sopenharmony_ci	if (tmp & VMC_BUSY)
38368c2ecf20Sopenharmony_ci		reset_mask |= RADEON_RESET_VMC;
38378c2ecf20Sopenharmony_ci
38388c2ecf20Sopenharmony_ci	if (tmp & (MCB_BUSY | MCB_NON_DISPLAY_BUSY |
38398c2ecf20Sopenharmony_ci		   MCC_BUSY | MCD_BUSY))
38408c2ecf20Sopenharmony_ci		reset_mask |= RADEON_RESET_MC;
38418c2ecf20Sopenharmony_ci
38428c2ecf20Sopenharmony_ci	if (evergreen_is_display_hung(rdev))
38438c2ecf20Sopenharmony_ci		reset_mask |= RADEON_RESET_DISPLAY;
38448c2ecf20Sopenharmony_ci
38458c2ecf20Sopenharmony_ci	/* VM_L2_STATUS */
38468c2ecf20Sopenharmony_ci	tmp = RREG32(VM_L2_STATUS);
38478c2ecf20Sopenharmony_ci	if (tmp & L2_BUSY)
38488c2ecf20Sopenharmony_ci		reset_mask |= RADEON_RESET_VMC;
38498c2ecf20Sopenharmony_ci
38508c2ecf20Sopenharmony_ci	/* Skip MC reset as it's mostly likely not hung, just busy */
38518c2ecf20Sopenharmony_ci	if (reset_mask & RADEON_RESET_MC) {
38528c2ecf20Sopenharmony_ci		DRM_DEBUG("MC busy: 0x%08X, clearing.\n", reset_mask);
38538c2ecf20Sopenharmony_ci		reset_mask &= ~RADEON_RESET_MC;
38548c2ecf20Sopenharmony_ci	}
38558c2ecf20Sopenharmony_ci
38568c2ecf20Sopenharmony_ci	return reset_mask;
38578c2ecf20Sopenharmony_ci}
38588c2ecf20Sopenharmony_ci
38598c2ecf20Sopenharmony_cistatic void si_gpu_soft_reset(struct radeon_device *rdev, u32 reset_mask)
38608c2ecf20Sopenharmony_ci{
38618c2ecf20Sopenharmony_ci	struct evergreen_mc_save save;
38628c2ecf20Sopenharmony_ci	u32 grbm_soft_reset = 0, srbm_soft_reset = 0;
38638c2ecf20Sopenharmony_ci	u32 tmp;
38648c2ecf20Sopenharmony_ci
38658c2ecf20Sopenharmony_ci	if (reset_mask == 0)
38668c2ecf20Sopenharmony_ci		return;
38678c2ecf20Sopenharmony_ci
38688c2ecf20Sopenharmony_ci	dev_info(rdev->dev, "GPU softreset: 0x%08X\n", reset_mask);
38698c2ecf20Sopenharmony_ci
38708c2ecf20Sopenharmony_ci	evergreen_print_gpu_status_regs(rdev);
38718c2ecf20Sopenharmony_ci	dev_info(rdev->dev, "  VM_CONTEXT1_PROTECTION_FAULT_ADDR   0x%08X\n",
38728c2ecf20Sopenharmony_ci		 RREG32(VM_CONTEXT1_PROTECTION_FAULT_ADDR));
38738c2ecf20Sopenharmony_ci	dev_info(rdev->dev, "  VM_CONTEXT1_PROTECTION_FAULT_STATUS 0x%08X\n",
38748c2ecf20Sopenharmony_ci		 RREG32(VM_CONTEXT1_PROTECTION_FAULT_STATUS));
38758c2ecf20Sopenharmony_ci
38768c2ecf20Sopenharmony_ci	/* disable PG/CG */
38778c2ecf20Sopenharmony_ci	si_fini_pg(rdev);
38788c2ecf20Sopenharmony_ci	si_fini_cg(rdev);
38798c2ecf20Sopenharmony_ci
38808c2ecf20Sopenharmony_ci	/* stop the rlc */
38818c2ecf20Sopenharmony_ci	si_rlc_stop(rdev);
38828c2ecf20Sopenharmony_ci
38838c2ecf20Sopenharmony_ci	/* Disable CP parsing/prefetching */
38848c2ecf20Sopenharmony_ci	WREG32(CP_ME_CNTL, CP_ME_HALT | CP_PFP_HALT | CP_CE_HALT);
38858c2ecf20Sopenharmony_ci
38868c2ecf20Sopenharmony_ci	if (reset_mask & RADEON_RESET_DMA) {
38878c2ecf20Sopenharmony_ci		/* dma0 */
38888c2ecf20Sopenharmony_ci		tmp = RREG32(DMA_RB_CNTL + DMA0_REGISTER_OFFSET);
38898c2ecf20Sopenharmony_ci		tmp &= ~DMA_RB_ENABLE;
38908c2ecf20Sopenharmony_ci		WREG32(DMA_RB_CNTL + DMA0_REGISTER_OFFSET, tmp);
38918c2ecf20Sopenharmony_ci	}
38928c2ecf20Sopenharmony_ci	if (reset_mask & RADEON_RESET_DMA1) {
38938c2ecf20Sopenharmony_ci		/* dma1 */
38948c2ecf20Sopenharmony_ci		tmp = RREG32(DMA_RB_CNTL + DMA1_REGISTER_OFFSET);
38958c2ecf20Sopenharmony_ci		tmp &= ~DMA_RB_ENABLE;
38968c2ecf20Sopenharmony_ci		WREG32(DMA_RB_CNTL + DMA1_REGISTER_OFFSET, tmp);
38978c2ecf20Sopenharmony_ci	}
38988c2ecf20Sopenharmony_ci
38998c2ecf20Sopenharmony_ci	udelay(50);
39008c2ecf20Sopenharmony_ci
39018c2ecf20Sopenharmony_ci	evergreen_mc_stop(rdev, &save);
39028c2ecf20Sopenharmony_ci	if (evergreen_mc_wait_for_idle(rdev)) {
39038c2ecf20Sopenharmony_ci		dev_warn(rdev->dev, "Wait for MC idle timedout !\n");
39048c2ecf20Sopenharmony_ci	}
39058c2ecf20Sopenharmony_ci
39068c2ecf20Sopenharmony_ci	if (reset_mask & (RADEON_RESET_GFX | RADEON_RESET_COMPUTE | RADEON_RESET_CP)) {
39078c2ecf20Sopenharmony_ci		grbm_soft_reset = SOFT_RESET_CB |
39088c2ecf20Sopenharmony_ci			SOFT_RESET_DB |
39098c2ecf20Sopenharmony_ci			SOFT_RESET_GDS |
39108c2ecf20Sopenharmony_ci			SOFT_RESET_PA |
39118c2ecf20Sopenharmony_ci			SOFT_RESET_SC |
39128c2ecf20Sopenharmony_ci			SOFT_RESET_BCI |
39138c2ecf20Sopenharmony_ci			SOFT_RESET_SPI |
39148c2ecf20Sopenharmony_ci			SOFT_RESET_SX |
39158c2ecf20Sopenharmony_ci			SOFT_RESET_TC |
39168c2ecf20Sopenharmony_ci			SOFT_RESET_TA |
39178c2ecf20Sopenharmony_ci			SOFT_RESET_VGT |
39188c2ecf20Sopenharmony_ci			SOFT_RESET_IA;
39198c2ecf20Sopenharmony_ci	}
39208c2ecf20Sopenharmony_ci
39218c2ecf20Sopenharmony_ci	if (reset_mask & RADEON_RESET_CP) {
39228c2ecf20Sopenharmony_ci		grbm_soft_reset |= SOFT_RESET_CP | SOFT_RESET_VGT;
39238c2ecf20Sopenharmony_ci
39248c2ecf20Sopenharmony_ci		srbm_soft_reset |= SOFT_RESET_GRBM;
39258c2ecf20Sopenharmony_ci	}
39268c2ecf20Sopenharmony_ci
39278c2ecf20Sopenharmony_ci	if (reset_mask & RADEON_RESET_DMA)
39288c2ecf20Sopenharmony_ci		srbm_soft_reset |= SOFT_RESET_DMA;
39298c2ecf20Sopenharmony_ci
39308c2ecf20Sopenharmony_ci	if (reset_mask & RADEON_RESET_DMA1)
39318c2ecf20Sopenharmony_ci		srbm_soft_reset |= SOFT_RESET_DMA1;
39328c2ecf20Sopenharmony_ci
39338c2ecf20Sopenharmony_ci	if (reset_mask & RADEON_RESET_DISPLAY)
39348c2ecf20Sopenharmony_ci		srbm_soft_reset |= SOFT_RESET_DC;
39358c2ecf20Sopenharmony_ci
39368c2ecf20Sopenharmony_ci	if (reset_mask & RADEON_RESET_RLC)
39378c2ecf20Sopenharmony_ci		grbm_soft_reset |= SOFT_RESET_RLC;
39388c2ecf20Sopenharmony_ci
39398c2ecf20Sopenharmony_ci	if (reset_mask & RADEON_RESET_SEM)
39408c2ecf20Sopenharmony_ci		srbm_soft_reset |= SOFT_RESET_SEM;
39418c2ecf20Sopenharmony_ci
39428c2ecf20Sopenharmony_ci	if (reset_mask & RADEON_RESET_IH)
39438c2ecf20Sopenharmony_ci		srbm_soft_reset |= SOFT_RESET_IH;
39448c2ecf20Sopenharmony_ci
39458c2ecf20Sopenharmony_ci	if (reset_mask & RADEON_RESET_GRBM)
39468c2ecf20Sopenharmony_ci		srbm_soft_reset |= SOFT_RESET_GRBM;
39478c2ecf20Sopenharmony_ci
39488c2ecf20Sopenharmony_ci	if (reset_mask & RADEON_RESET_VMC)
39498c2ecf20Sopenharmony_ci		srbm_soft_reset |= SOFT_RESET_VMC;
39508c2ecf20Sopenharmony_ci
39518c2ecf20Sopenharmony_ci	if (reset_mask & RADEON_RESET_MC)
39528c2ecf20Sopenharmony_ci		srbm_soft_reset |= SOFT_RESET_MC;
39538c2ecf20Sopenharmony_ci
39548c2ecf20Sopenharmony_ci	if (grbm_soft_reset) {
39558c2ecf20Sopenharmony_ci		tmp = RREG32(GRBM_SOFT_RESET);
39568c2ecf20Sopenharmony_ci		tmp |= grbm_soft_reset;
39578c2ecf20Sopenharmony_ci		dev_info(rdev->dev, "GRBM_SOFT_RESET=0x%08X\n", tmp);
39588c2ecf20Sopenharmony_ci		WREG32(GRBM_SOFT_RESET, tmp);
39598c2ecf20Sopenharmony_ci		tmp = RREG32(GRBM_SOFT_RESET);
39608c2ecf20Sopenharmony_ci
39618c2ecf20Sopenharmony_ci		udelay(50);
39628c2ecf20Sopenharmony_ci
39638c2ecf20Sopenharmony_ci		tmp &= ~grbm_soft_reset;
39648c2ecf20Sopenharmony_ci		WREG32(GRBM_SOFT_RESET, tmp);
39658c2ecf20Sopenharmony_ci		tmp = RREG32(GRBM_SOFT_RESET);
39668c2ecf20Sopenharmony_ci	}
39678c2ecf20Sopenharmony_ci
39688c2ecf20Sopenharmony_ci	if (srbm_soft_reset) {
39698c2ecf20Sopenharmony_ci		tmp = RREG32(SRBM_SOFT_RESET);
39708c2ecf20Sopenharmony_ci		tmp |= srbm_soft_reset;
39718c2ecf20Sopenharmony_ci		dev_info(rdev->dev, "SRBM_SOFT_RESET=0x%08X\n", tmp);
39728c2ecf20Sopenharmony_ci		WREG32(SRBM_SOFT_RESET, tmp);
39738c2ecf20Sopenharmony_ci		tmp = RREG32(SRBM_SOFT_RESET);
39748c2ecf20Sopenharmony_ci
39758c2ecf20Sopenharmony_ci		udelay(50);
39768c2ecf20Sopenharmony_ci
39778c2ecf20Sopenharmony_ci		tmp &= ~srbm_soft_reset;
39788c2ecf20Sopenharmony_ci		WREG32(SRBM_SOFT_RESET, tmp);
39798c2ecf20Sopenharmony_ci		tmp = RREG32(SRBM_SOFT_RESET);
39808c2ecf20Sopenharmony_ci	}
39818c2ecf20Sopenharmony_ci
39828c2ecf20Sopenharmony_ci	/* Wait a little for things to settle down */
39838c2ecf20Sopenharmony_ci	udelay(50);
39848c2ecf20Sopenharmony_ci
39858c2ecf20Sopenharmony_ci	evergreen_mc_resume(rdev, &save);
39868c2ecf20Sopenharmony_ci	udelay(50);
39878c2ecf20Sopenharmony_ci
39888c2ecf20Sopenharmony_ci	evergreen_print_gpu_status_regs(rdev);
39898c2ecf20Sopenharmony_ci}
39908c2ecf20Sopenharmony_ci
39918c2ecf20Sopenharmony_cistatic void si_set_clk_bypass_mode(struct radeon_device *rdev)
39928c2ecf20Sopenharmony_ci{
39938c2ecf20Sopenharmony_ci	u32 tmp, i;
39948c2ecf20Sopenharmony_ci
39958c2ecf20Sopenharmony_ci	tmp = RREG32(CG_SPLL_FUNC_CNTL);
39968c2ecf20Sopenharmony_ci	tmp |= SPLL_BYPASS_EN;
39978c2ecf20Sopenharmony_ci	WREG32(CG_SPLL_FUNC_CNTL, tmp);
39988c2ecf20Sopenharmony_ci
39998c2ecf20Sopenharmony_ci	tmp = RREG32(CG_SPLL_FUNC_CNTL_2);
40008c2ecf20Sopenharmony_ci	tmp |= SPLL_CTLREQ_CHG;
40018c2ecf20Sopenharmony_ci	WREG32(CG_SPLL_FUNC_CNTL_2, tmp);
40028c2ecf20Sopenharmony_ci
40038c2ecf20Sopenharmony_ci	for (i = 0; i < rdev->usec_timeout; i++) {
40048c2ecf20Sopenharmony_ci		if (RREG32(SPLL_STATUS) & SPLL_CHG_STATUS)
40058c2ecf20Sopenharmony_ci			break;
40068c2ecf20Sopenharmony_ci		udelay(1);
40078c2ecf20Sopenharmony_ci	}
40088c2ecf20Sopenharmony_ci
40098c2ecf20Sopenharmony_ci	tmp = RREG32(CG_SPLL_FUNC_CNTL_2);
40108c2ecf20Sopenharmony_ci	tmp &= ~(SPLL_CTLREQ_CHG | SCLK_MUX_UPDATE);
40118c2ecf20Sopenharmony_ci	WREG32(CG_SPLL_FUNC_CNTL_2, tmp);
40128c2ecf20Sopenharmony_ci
40138c2ecf20Sopenharmony_ci	tmp = RREG32(MPLL_CNTL_MODE);
40148c2ecf20Sopenharmony_ci	tmp &= ~MPLL_MCLK_SEL;
40158c2ecf20Sopenharmony_ci	WREG32(MPLL_CNTL_MODE, tmp);
40168c2ecf20Sopenharmony_ci}
40178c2ecf20Sopenharmony_ci
40188c2ecf20Sopenharmony_cistatic void si_spll_powerdown(struct radeon_device *rdev)
40198c2ecf20Sopenharmony_ci{
40208c2ecf20Sopenharmony_ci	u32 tmp;
40218c2ecf20Sopenharmony_ci
40228c2ecf20Sopenharmony_ci	tmp = RREG32(SPLL_CNTL_MODE);
40238c2ecf20Sopenharmony_ci	tmp |= SPLL_SW_DIR_CONTROL;
40248c2ecf20Sopenharmony_ci	WREG32(SPLL_CNTL_MODE, tmp);
40258c2ecf20Sopenharmony_ci
40268c2ecf20Sopenharmony_ci	tmp = RREG32(CG_SPLL_FUNC_CNTL);
40278c2ecf20Sopenharmony_ci	tmp |= SPLL_RESET;
40288c2ecf20Sopenharmony_ci	WREG32(CG_SPLL_FUNC_CNTL, tmp);
40298c2ecf20Sopenharmony_ci
40308c2ecf20Sopenharmony_ci	tmp = RREG32(CG_SPLL_FUNC_CNTL);
40318c2ecf20Sopenharmony_ci	tmp |= SPLL_SLEEP;
40328c2ecf20Sopenharmony_ci	WREG32(CG_SPLL_FUNC_CNTL, tmp);
40338c2ecf20Sopenharmony_ci
40348c2ecf20Sopenharmony_ci	tmp = RREG32(SPLL_CNTL_MODE);
40358c2ecf20Sopenharmony_ci	tmp &= ~SPLL_SW_DIR_CONTROL;
40368c2ecf20Sopenharmony_ci	WREG32(SPLL_CNTL_MODE, tmp);
40378c2ecf20Sopenharmony_ci}
40388c2ecf20Sopenharmony_ci
40398c2ecf20Sopenharmony_cistatic void si_gpu_pci_config_reset(struct radeon_device *rdev)
40408c2ecf20Sopenharmony_ci{
40418c2ecf20Sopenharmony_ci	struct evergreen_mc_save save;
40428c2ecf20Sopenharmony_ci	u32 tmp, i;
40438c2ecf20Sopenharmony_ci
40448c2ecf20Sopenharmony_ci	dev_info(rdev->dev, "GPU pci config reset\n");
40458c2ecf20Sopenharmony_ci
40468c2ecf20Sopenharmony_ci	/* disable dpm? */
40478c2ecf20Sopenharmony_ci
40488c2ecf20Sopenharmony_ci	/* disable cg/pg */
40498c2ecf20Sopenharmony_ci	si_fini_pg(rdev);
40508c2ecf20Sopenharmony_ci	si_fini_cg(rdev);
40518c2ecf20Sopenharmony_ci
40528c2ecf20Sopenharmony_ci	/* Disable CP parsing/prefetching */
40538c2ecf20Sopenharmony_ci	WREG32(CP_ME_CNTL, CP_ME_HALT | CP_PFP_HALT | CP_CE_HALT);
40548c2ecf20Sopenharmony_ci	/* dma0 */
40558c2ecf20Sopenharmony_ci	tmp = RREG32(DMA_RB_CNTL + DMA0_REGISTER_OFFSET);
40568c2ecf20Sopenharmony_ci	tmp &= ~DMA_RB_ENABLE;
40578c2ecf20Sopenharmony_ci	WREG32(DMA_RB_CNTL + DMA0_REGISTER_OFFSET, tmp);
40588c2ecf20Sopenharmony_ci	/* dma1 */
40598c2ecf20Sopenharmony_ci	tmp = RREG32(DMA_RB_CNTL + DMA1_REGISTER_OFFSET);
40608c2ecf20Sopenharmony_ci	tmp &= ~DMA_RB_ENABLE;
40618c2ecf20Sopenharmony_ci	WREG32(DMA_RB_CNTL + DMA1_REGISTER_OFFSET, tmp);
40628c2ecf20Sopenharmony_ci	/* XXX other engines? */
40638c2ecf20Sopenharmony_ci
40648c2ecf20Sopenharmony_ci	/* halt the rlc, disable cp internal ints */
40658c2ecf20Sopenharmony_ci	si_rlc_stop(rdev);
40668c2ecf20Sopenharmony_ci
40678c2ecf20Sopenharmony_ci	udelay(50);
40688c2ecf20Sopenharmony_ci
40698c2ecf20Sopenharmony_ci	/* disable mem access */
40708c2ecf20Sopenharmony_ci	evergreen_mc_stop(rdev, &save);
40718c2ecf20Sopenharmony_ci	if (evergreen_mc_wait_for_idle(rdev)) {
40728c2ecf20Sopenharmony_ci		dev_warn(rdev->dev, "Wait for MC idle timed out !\n");
40738c2ecf20Sopenharmony_ci	}
40748c2ecf20Sopenharmony_ci
40758c2ecf20Sopenharmony_ci	/* set mclk/sclk to bypass */
40768c2ecf20Sopenharmony_ci	si_set_clk_bypass_mode(rdev);
40778c2ecf20Sopenharmony_ci	/* powerdown spll */
40788c2ecf20Sopenharmony_ci	si_spll_powerdown(rdev);
40798c2ecf20Sopenharmony_ci	/* disable BM */
40808c2ecf20Sopenharmony_ci	pci_clear_master(rdev->pdev);
40818c2ecf20Sopenharmony_ci	/* reset */
40828c2ecf20Sopenharmony_ci	radeon_pci_config_reset(rdev);
40838c2ecf20Sopenharmony_ci	/* wait for asic to come out of reset */
40848c2ecf20Sopenharmony_ci	for (i = 0; i < rdev->usec_timeout; i++) {
40858c2ecf20Sopenharmony_ci		if (RREG32(CONFIG_MEMSIZE) != 0xffffffff)
40868c2ecf20Sopenharmony_ci			break;
40878c2ecf20Sopenharmony_ci		udelay(1);
40888c2ecf20Sopenharmony_ci	}
40898c2ecf20Sopenharmony_ci}
40908c2ecf20Sopenharmony_ci
40918c2ecf20Sopenharmony_ciint si_asic_reset(struct radeon_device *rdev, bool hard)
40928c2ecf20Sopenharmony_ci{
40938c2ecf20Sopenharmony_ci	u32 reset_mask;
40948c2ecf20Sopenharmony_ci
40958c2ecf20Sopenharmony_ci	if (hard) {
40968c2ecf20Sopenharmony_ci		si_gpu_pci_config_reset(rdev);
40978c2ecf20Sopenharmony_ci		return 0;
40988c2ecf20Sopenharmony_ci	}
40998c2ecf20Sopenharmony_ci
41008c2ecf20Sopenharmony_ci	reset_mask = si_gpu_check_soft_reset(rdev);
41018c2ecf20Sopenharmony_ci
41028c2ecf20Sopenharmony_ci	if (reset_mask)
41038c2ecf20Sopenharmony_ci		r600_set_bios_scratch_engine_hung(rdev, true);
41048c2ecf20Sopenharmony_ci
41058c2ecf20Sopenharmony_ci	/* try soft reset */
41068c2ecf20Sopenharmony_ci	si_gpu_soft_reset(rdev, reset_mask);
41078c2ecf20Sopenharmony_ci
41088c2ecf20Sopenharmony_ci	reset_mask = si_gpu_check_soft_reset(rdev);
41098c2ecf20Sopenharmony_ci
41108c2ecf20Sopenharmony_ci	/* try pci config reset */
41118c2ecf20Sopenharmony_ci	if (reset_mask && radeon_hard_reset)
41128c2ecf20Sopenharmony_ci		si_gpu_pci_config_reset(rdev);
41138c2ecf20Sopenharmony_ci
41148c2ecf20Sopenharmony_ci	reset_mask = si_gpu_check_soft_reset(rdev);
41158c2ecf20Sopenharmony_ci
41168c2ecf20Sopenharmony_ci	if (!reset_mask)
41178c2ecf20Sopenharmony_ci		r600_set_bios_scratch_engine_hung(rdev, false);
41188c2ecf20Sopenharmony_ci
41198c2ecf20Sopenharmony_ci	return 0;
41208c2ecf20Sopenharmony_ci}
41218c2ecf20Sopenharmony_ci
41228c2ecf20Sopenharmony_ci/**
41238c2ecf20Sopenharmony_ci * si_gfx_is_lockup - Check if the GFX engine is locked up
41248c2ecf20Sopenharmony_ci *
41258c2ecf20Sopenharmony_ci * @rdev: radeon_device pointer
41268c2ecf20Sopenharmony_ci * @ring: radeon_ring structure holding ring information
41278c2ecf20Sopenharmony_ci *
41288c2ecf20Sopenharmony_ci * Check if the GFX engine is locked up.
41298c2ecf20Sopenharmony_ci * Returns true if the engine appears to be locked up, false if not.
41308c2ecf20Sopenharmony_ci */
41318c2ecf20Sopenharmony_cibool si_gfx_is_lockup(struct radeon_device *rdev, struct radeon_ring *ring)
41328c2ecf20Sopenharmony_ci{
41338c2ecf20Sopenharmony_ci	u32 reset_mask = si_gpu_check_soft_reset(rdev);
41348c2ecf20Sopenharmony_ci
41358c2ecf20Sopenharmony_ci	if (!(reset_mask & (RADEON_RESET_GFX |
41368c2ecf20Sopenharmony_ci			    RADEON_RESET_COMPUTE |
41378c2ecf20Sopenharmony_ci			    RADEON_RESET_CP))) {
41388c2ecf20Sopenharmony_ci		radeon_ring_lockup_update(rdev, ring);
41398c2ecf20Sopenharmony_ci		return false;
41408c2ecf20Sopenharmony_ci	}
41418c2ecf20Sopenharmony_ci	return radeon_ring_test_lockup(rdev, ring);
41428c2ecf20Sopenharmony_ci}
41438c2ecf20Sopenharmony_ci
41448c2ecf20Sopenharmony_ci/* MC */
41458c2ecf20Sopenharmony_cistatic void si_mc_program(struct radeon_device *rdev)
41468c2ecf20Sopenharmony_ci{
41478c2ecf20Sopenharmony_ci	struct evergreen_mc_save save;
41488c2ecf20Sopenharmony_ci	u32 tmp;
41498c2ecf20Sopenharmony_ci	int i, j;
41508c2ecf20Sopenharmony_ci
41518c2ecf20Sopenharmony_ci	/* Initialize HDP */
41528c2ecf20Sopenharmony_ci	for (i = 0, j = 0; i < 32; i++, j += 0x18) {
41538c2ecf20Sopenharmony_ci		WREG32((0x2c14 + j), 0x00000000);
41548c2ecf20Sopenharmony_ci		WREG32((0x2c18 + j), 0x00000000);
41558c2ecf20Sopenharmony_ci		WREG32((0x2c1c + j), 0x00000000);
41568c2ecf20Sopenharmony_ci		WREG32((0x2c20 + j), 0x00000000);
41578c2ecf20Sopenharmony_ci		WREG32((0x2c24 + j), 0x00000000);
41588c2ecf20Sopenharmony_ci	}
41598c2ecf20Sopenharmony_ci	WREG32(HDP_REG_COHERENCY_FLUSH_CNTL, 0);
41608c2ecf20Sopenharmony_ci
41618c2ecf20Sopenharmony_ci	evergreen_mc_stop(rdev, &save);
41628c2ecf20Sopenharmony_ci	if (radeon_mc_wait_for_idle(rdev)) {
41638c2ecf20Sopenharmony_ci		dev_warn(rdev->dev, "Wait for MC idle timedout !\n");
41648c2ecf20Sopenharmony_ci	}
41658c2ecf20Sopenharmony_ci	if (!ASIC_IS_NODCE(rdev))
41668c2ecf20Sopenharmony_ci		/* Lockout access through VGA aperture*/
41678c2ecf20Sopenharmony_ci		WREG32(VGA_HDP_CONTROL, VGA_MEMORY_DISABLE);
41688c2ecf20Sopenharmony_ci	/* Update configuration */
41698c2ecf20Sopenharmony_ci	WREG32(MC_VM_SYSTEM_APERTURE_LOW_ADDR,
41708c2ecf20Sopenharmony_ci	       rdev->mc.vram_start >> 12);
41718c2ecf20Sopenharmony_ci	WREG32(MC_VM_SYSTEM_APERTURE_HIGH_ADDR,
41728c2ecf20Sopenharmony_ci	       rdev->mc.vram_end >> 12);
41738c2ecf20Sopenharmony_ci	WREG32(MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR,
41748c2ecf20Sopenharmony_ci	       rdev->vram_scratch.gpu_addr >> 12);
41758c2ecf20Sopenharmony_ci	tmp = ((rdev->mc.vram_end >> 24) & 0xFFFF) << 16;
41768c2ecf20Sopenharmony_ci	tmp |= ((rdev->mc.vram_start >> 24) & 0xFFFF);
41778c2ecf20Sopenharmony_ci	WREG32(MC_VM_FB_LOCATION, tmp);
41788c2ecf20Sopenharmony_ci	/* XXX double check these! */
41798c2ecf20Sopenharmony_ci	WREG32(HDP_NONSURFACE_BASE, (rdev->mc.vram_start >> 8));
41808c2ecf20Sopenharmony_ci	WREG32(HDP_NONSURFACE_INFO, (2 << 7) | (1 << 30));
41818c2ecf20Sopenharmony_ci	WREG32(HDP_NONSURFACE_SIZE, 0x3FFFFFFF);
41828c2ecf20Sopenharmony_ci	WREG32(MC_VM_AGP_BASE, 0);
41838c2ecf20Sopenharmony_ci	WREG32(MC_VM_AGP_TOP, 0x0FFFFFFF);
41848c2ecf20Sopenharmony_ci	WREG32(MC_VM_AGP_BOT, 0x0FFFFFFF);
41858c2ecf20Sopenharmony_ci	if (radeon_mc_wait_for_idle(rdev)) {
41868c2ecf20Sopenharmony_ci		dev_warn(rdev->dev, "Wait for MC idle timedout !\n");
41878c2ecf20Sopenharmony_ci	}
41888c2ecf20Sopenharmony_ci	evergreen_mc_resume(rdev, &save);
41898c2ecf20Sopenharmony_ci	if (!ASIC_IS_NODCE(rdev)) {
41908c2ecf20Sopenharmony_ci		/* we need to own VRAM, so turn off the VGA renderer here
41918c2ecf20Sopenharmony_ci		 * to stop it overwriting our objects */
41928c2ecf20Sopenharmony_ci		rv515_vga_render_disable(rdev);
41938c2ecf20Sopenharmony_ci	}
41948c2ecf20Sopenharmony_ci}
41958c2ecf20Sopenharmony_ci
41968c2ecf20Sopenharmony_civoid si_vram_gtt_location(struct radeon_device *rdev,
41978c2ecf20Sopenharmony_ci			  struct radeon_mc *mc)
41988c2ecf20Sopenharmony_ci{
41998c2ecf20Sopenharmony_ci	if (mc->mc_vram_size > 0xFFC0000000ULL) {
42008c2ecf20Sopenharmony_ci		/* leave room for at least 1024M GTT */
42018c2ecf20Sopenharmony_ci		dev_warn(rdev->dev, "limiting VRAM\n");
42028c2ecf20Sopenharmony_ci		mc->real_vram_size = 0xFFC0000000ULL;
42038c2ecf20Sopenharmony_ci		mc->mc_vram_size = 0xFFC0000000ULL;
42048c2ecf20Sopenharmony_ci	}
42058c2ecf20Sopenharmony_ci	radeon_vram_location(rdev, &rdev->mc, 0);
42068c2ecf20Sopenharmony_ci	rdev->mc.gtt_base_align = 0;
42078c2ecf20Sopenharmony_ci	radeon_gtt_location(rdev, mc);
42088c2ecf20Sopenharmony_ci}
42098c2ecf20Sopenharmony_ci
42108c2ecf20Sopenharmony_cistatic int si_mc_init(struct radeon_device *rdev)
42118c2ecf20Sopenharmony_ci{
42128c2ecf20Sopenharmony_ci	u32 tmp;
42138c2ecf20Sopenharmony_ci	int chansize, numchan;
42148c2ecf20Sopenharmony_ci
42158c2ecf20Sopenharmony_ci	/* Get VRAM informations */
42168c2ecf20Sopenharmony_ci	rdev->mc.vram_is_ddr = true;
42178c2ecf20Sopenharmony_ci	tmp = RREG32(MC_ARB_RAMCFG);
42188c2ecf20Sopenharmony_ci	if (tmp & CHANSIZE_OVERRIDE) {
42198c2ecf20Sopenharmony_ci		chansize = 16;
42208c2ecf20Sopenharmony_ci	} else if (tmp & CHANSIZE_MASK) {
42218c2ecf20Sopenharmony_ci		chansize = 64;
42228c2ecf20Sopenharmony_ci	} else {
42238c2ecf20Sopenharmony_ci		chansize = 32;
42248c2ecf20Sopenharmony_ci	}
42258c2ecf20Sopenharmony_ci	tmp = RREG32(MC_SHARED_CHMAP);
42268c2ecf20Sopenharmony_ci	switch ((tmp & NOOFCHAN_MASK) >> NOOFCHAN_SHIFT) {
42278c2ecf20Sopenharmony_ci	case 0:
42288c2ecf20Sopenharmony_ci	default:
42298c2ecf20Sopenharmony_ci		numchan = 1;
42308c2ecf20Sopenharmony_ci		break;
42318c2ecf20Sopenharmony_ci	case 1:
42328c2ecf20Sopenharmony_ci		numchan = 2;
42338c2ecf20Sopenharmony_ci		break;
42348c2ecf20Sopenharmony_ci	case 2:
42358c2ecf20Sopenharmony_ci		numchan = 4;
42368c2ecf20Sopenharmony_ci		break;
42378c2ecf20Sopenharmony_ci	case 3:
42388c2ecf20Sopenharmony_ci		numchan = 8;
42398c2ecf20Sopenharmony_ci		break;
42408c2ecf20Sopenharmony_ci	case 4:
42418c2ecf20Sopenharmony_ci		numchan = 3;
42428c2ecf20Sopenharmony_ci		break;
42438c2ecf20Sopenharmony_ci	case 5:
42448c2ecf20Sopenharmony_ci		numchan = 6;
42458c2ecf20Sopenharmony_ci		break;
42468c2ecf20Sopenharmony_ci	case 6:
42478c2ecf20Sopenharmony_ci		numchan = 10;
42488c2ecf20Sopenharmony_ci		break;
42498c2ecf20Sopenharmony_ci	case 7:
42508c2ecf20Sopenharmony_ci		numchan = 12;
42518c2ecf20Sopenharmony_ci		break;
42528c2ecf20Sopenharmony_ci	case 8:
42538c2ecf20Sopenharmony_ci		numchan = 16;
42548c2ecf20Sopenharmony_ci		break;
42558c2ecf20Sopenharmony_ci	}
42568c2ecf20Sopenharmony_ci	rdev->mc.vram_width = numchan * chansize;
42578c2ecf20Sopenharmony_ci	/* Could aper size report 0 ? */
42588c2ecf20Sopenharmony_ci	rdev->mc.aper_base = pci_resource_start(rdev->pdev, 0);
42598c2ecf20Sopenharmony_ci	rdev->mc.aper_size = pci_resource_len(rdev->pdev, 0);
42608c2ecf20Sopenharmony_ci	/* size in MB on si */
42618c2ecf20Sopenharmony_ci	tmp = RREG32(CONFIG_MEMSIZE);
42628c2ecf20Sopenharmony_ci	/* some boards may have garbage in the upper 16 bits */
42638c2ecf20Sopenharmony_ci	if (tmp & 0xffff0000) {
42648c2ecf20Sopenharmony_ci		DRM_INFO("Probable bad vram size: 0x%08x\n", tmp);
42658c2ecf20Sopenharmony_ci		if (tmp & 0xffff)
42668c2ecf20Sopenharmony_ci			tmp &= 0xffff;
42678c2ecf20Sopenharmony_ci	}
42688c2ecf20Sopenharmony_ci	rdev->mc.mc_vram_size = tmp * 1024ULL * 1024ULL;
42698c2ecf20Sopenharmony_ci	rdev->mc.real_vram_size = rdev->mc.mc_vram_size;
42708c2ecf20Sopenharmony_ci	rdev->mc.visible_vram_size = rdev->mc.aper_size;
42718c2ecf20Sopenharmony_ci	si_vram_gtt_location(rdev, &rdev->mc);
42728c2ecf20Sopenharmony_ci	radeon_update_bandwidth_info(rdev);
42738c2ecf20Sopenharmony_ci
42748c2ecf20Sopenharmony_ci	return 0;
42758c2ecf20Sopenharmony_ci}
42768c2ecf20Sopenharmony_ci
42778c2ecf20Sopenharmony_ci/*
42788c2ecf20Sopenharmony_ci * GART
42798c2ecf20Sopenharmony_ci */
42808c2ecf20Sopenharmony_civoid si_pcie_gart_tlb_flush(struct radeon_device *rdev)
42818c2ecf20Sopenharmony_ci{
42828c2ecf20Sopenharmony_ci	/* flush hdp cache */
42838c2ecf20Sopenharmony_ci	WREG32(HDP_MEM_COHERENCY_FLUSH_CNTL, 0x1);
42848c2ecf20Sopenharmony_ci
42858c2ecf20Sopenharmony_ci	/* bits 0-15 are the VM contexts0-15 */
42868c2ecf20Sopenharmony_ci	WREG32(VM_INVALIDATE_REQUEST, 1);
42878c2ecf20Sopenharmony_ci}
42888c2ecf20Sopenharmony_ci
42898c2ecf20Sopenharmony_cistatic int si_pcie_gart_enable(struct radeon_device *rdev)
42908c2ecf20Sopenharmony_ci{
42918c2ecf20Sopenharmony_ci	int r, i;
42928c2ecf20Sopenharmony_ci
42938c2ecf20Sopenharmony_ci	if (rdev->gart.robj == NULL) {
42948c2ecf20Sopenharmony_ci		dev_err(rdev->dev, "No VRAM object for PCIE GART.\n");
42958c2ecf20Sopenharmony_ci		return -EINVAL;
42968c2ecf20Sopenharmony_ci	}
42978c2ecf20Sopenharmony_ci	r = radeon_gart_table_vram_pin(rdev);
42988c2ecf20Sopenharmony_ci	if (r)
42998c2ecf20Sopenharmony_ci		return r;
43008c2ecf20Sopenharmony_ci	/* Setup TLB control */
43018c2ecf20Sopenharmony_ci	WREG32(MC_VM_MX_L1_TLB_CNTL,
43028c2ecf20Sopenharmony_ci	       (0xA << 7) |
43038c2ecf20Sopenharmony_ci	       ENABLE_L1_TLB |
43048c2ecf20Sopenharmony_ci	       ENABLE_L1_FRAGMENT_PROCESSING |
43058c2ecf20Sopenharmony_ci	       SYSTEM_ACCESS_MODE_NOT_IN_SYS |
43068c2ecf20Sopenharmony_ci	       ENABLE_ADVANCED_DRIVER_MODEL |
43078c2ecf20Sopenharmony_ci	       SYSTEM_APERTURE_UNMAPPED_ACCESS_PASS_THRU);
43088c2ecf20Sopenharmony_ci	/* Setup L2 cache */
43098c2ecf20Sopenharmony_ci	WREG32(VM_L2_CNTL, ENABLE_L2_CACHE |
43108c2ecf20Sopenharmony_ci	       ENABLE_L2_FRAGMENT_PROCESSING |
43118c2ecf20Sopenharmony_ci	       ENABLE_L2_PTE_CACHE_LRU_UPDATE_BY_WRITE |
43128c2ecf20Sopenharmony_ci	       ENABLE_L2_PDE0_CACHE_LRU_UPDATE_BY_WRITE |
43138c2ecf20Sopenharmony_ci	       EFFECTIVE_L2_QUEUE_SIZE(7) |
43148c2ecf20Sopenharmony_ci	       CONTEXT1_IDENTITY_ACCESS_MODE(1));
43158c2ecf20Sopenharmony_ci	WREG32(VM_L2_CNTL2, INVALIDATE_ALL_L1_TLBS | INVALIDATE_L2_CACHE);
43168c2ecf20Sopenharmony_ci	WREG32(VM_L2_CNTL3, L2_CACHE_BIGK_ASSOCIATIVITY |
43178c2ecf20Sopenharmony_ci	       BANK_SELECT(4) |
43188c2ecf20Sopenharmony_ci	       L2_CACHE_BIGK_FRAGMENT_SIZE(4));
43198c2ecf20Sopenharmony_ci	/* setup context0 */
43208c2ecf20Sopenharmony_ci	WREG32(VM_CONTEXT0_PAGE_TABLE_START_ADDR, rdev->mc.gtt_start >> 12);
43218c2ecf20Sopenharmony_ci	WREG32(VM_CONTEXT0_PAGE_TABLE_END_ADDR, rdev->mc.gtt_end >> 12);
43228c2ecf20Sopenharmony_ci	WREG32(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR, rdev->gart.table_addr >> 12);
43238c2ecf20Sopenharmony_ci	WREG32(VM_CONTEXT0_PROTECTION_FAULT_DEFAULT_ADDR,
43248c2ecf20Sopenharmony_ci			(u32)(rdev->dummy_page.addr >> 12));
43258c2ecf20Sopenharmony_ci	WREG32(VM_CONTEXT0_CNTL2, 0);
43268c2ecf20Sopenharmony_ci	WREG32(VM_CONTEXT0_CNTL, (ENABLE_CONTEXT | PAGE_TABLE_DEPTH(0) |
43278c2ecf20Sopenharmony_ci				  RANGE_PROTECTION_FAULT_ENABLE_DEFAULT));
43288c2ecf20Sopenharmony_ci
43298c2ecf20Sopenharmony_ci	WREG32(0x15D4, 0);
43308c2ecf20Sopenharmony_ci	WREG32(0x15D8, 0);
43318c2ecf20Sopenharmony_ci	WREG32(0x15DC, 0);
43328c2ecf20Sopenharmony_ci
43338c2ecf20Sopenharmony_ci	/* empty context1-15 */
43348c2ecf20Sopenharmony_ci	/* set vm size, must be a multiple of 4 */
43358c2ecf20Sopenharmony_ci	WREG32(VM_CONTEXT1_PAGE_TABLE_START_ADDR, 0);
43368c2ecf20Sopenharmony_ci	WREG32(VM_CONTEXT1_PAGE_TABLE_END_ADDR, rdev->vm_manager.max_pfn - 1);
43378c2ecf20Sopenharmony_ci	/* Assign the pt base to something valid for now; the pts used for
43388c2ecf20Sopenharmony_ci	 * the VMs are determined by the application and setup and assigned
43398c2ecf20Sopenharmony_ci	 * on the fly in the vm part of radeon_gart.c
43408c2ecf20Sopenharmony_ci	 */
43418c2ecf20Sopenharmony_ci	for (i = 1; i < 16; i++) {
43428c2ecf20Sopenharmony_ci		if (i < 8)
43438c2ecf20Sopenharmony_ci			WREG32(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR + (i << 2),
43448c2ecf20Sopenharmony_ci			       rdev->vm_manager.saved_table_addr[i]);
43458c2ecf20Sopenharmony_ci		else
43468c2ecf20Sopenharmony_ci			WREG32(VM_CONTEXT8_PAGE_TABLE_BASE_ADDR + ((i - 8) << 2),
43478c2ecf20Sopenharmony_ci			       rdev->vm_manager.saved_table_addr[i]);
43488c2ecf20Sopenharmony_ci	}
43498c2ecf20Sopenharmony_ci
43508c2ecf20Sopenharmony_ci	/* enable context1-15 */
43518c2ecf20Sopenharmony_ci	WREG32(VM_CONTEXT1_PROTECTION_FAULT_DEFAULT_ADDR,
43528c2ecf20Sopenharmony_ci	       (u32)(rdev->dummy_page.addr >> 12));
43538c2ecf20Sopenharmony_ci	WREG32(VM_CONTEXT1_CNTL2, 4);
43548c2ecf20Sopenharmony_ci	WREG32(VM_CONTEXT1_CNTL, ENABLE_CONTEXT | PAGE_TABLE_DEPTH(1) |
43558c2ecf20Sopenharmony_ci				PAGE_TABLE_BLOCK_SIZE(radeon_vm_block_size - 9) |
43568c2ecf20Sopenharmony_ci				RANGE_PROTECTION_FAULT_ENABLE_INTERRUPT |
43578c2ecf20Sopenharmony_ci				RANGE_PROTECTION_FAULT_ENABLE_DEFAULT |
43588c2ecf20Sopenharmony_ci				DUMMY_PAGE_PROTECTION_FAULT_ENABLE_INTERRUPT |
43598c2ecf20Sopenharmony_ci				DUMMY_PAGE_PROTECTION_FAULT_ENABLE_DEFAULT |
43608c2ecf20Sopenharmony_ci				PDE0_PROTECTION_FAULT_ENABLE_INTERRUPT |
43618c2ecf20Sopenharmony_ci				PDE0_PROTECTION_FAULT_ENABLE_DEFAULT |
43628c2ecf20Sopenharmony_ci				VALID_PROTECTION_FAULT_ENABLE_INTERRUPT |
43638c2ecf20Sopenharmony_ci				VALID_PROTECTION_FAULT_ENABLE_DEFAULT |
43648c2ecf20Sopenharmony_ci				READ_PROTECTION_FAULT_ENABLE_INTERRUPT |
43658c2ecf20Sopenharmony_ci				READ_PROTECTION_FAULT_ENABLE_DEFAULT |
43668c2ecf20Sopenharmony_ci				WRITE_PROTECTION_FAULT_ENABLE_INTERRUPT |
43678c2ecf20Sopenharmony_ci				WRITE_PROTECTION_FAULT_ENABLE_DEFAULT);
43688c2ecf20Sopenharmony_ci
43698c2ecf20Sopenharmony_ci	si_pcie_gart_tlb_flush(rdev);
43708c2ecf20Sopenharmony_ci	DRM_INFO("PCIE GART of %uM enabled (table at 0x%016llX).\n",
43718c2ecf20Sopenharmony_ci		 (unsigned)(rdev->mc.gtt_size >> 20),
43728c2ecf20Sopenharmony_ci		 (unsigned long long)rdev->gart.table_addr);
43738c2ecf20Sopenharmony_ci	rdev->gart.ready = true;
43748c2ecf20Sopenharmony_ci	return 0;
43758c2ecf20Sopenharmony_ci}
43768c2ecf20Sopenharmony_ci
43778c2ecf20Sopenharmony_cistatic void si_pcie_gart_disable(struct radeon_device *rdev)
43788c2ecf20Sopenharmony_ci{
43798c2ecf20Sopenharmony_ci	unsigned i;
43808c2ecf20Sopenharmony_ci
43818c2ecf20Sopenharmony_ci	for (i = 1; i < 16; ++i) {
43828c2ecf20Sopenharmony_ci		uint32_t reg;
43838c2ecf20Sopenharmony_ci		if (i < 8)
43848c2ecf20Sopenharmony_ci			reg = VM_CONTEXT0_PAGE_TABLE_BASE_ADDR + (i << 2);
43858c2ecf20Sopenharmony_ci		else
43868c2ecf20Sopenharmony_ci			reg = VM_CONTEXT8_PAGE_TABLE_BASE_ADDR + ((i - 8) << 2);
43878c2ecf20Sopenharmony_ci		rdev->vm_manager.saved_table_addr[i] = RREG32(reg);
43888c2ecf20Sopenharmony_ci	}
43898c2ecf20Sopenharmony_ci
43908c2ecf20Sopenharmony_ci	/* Disable all tables */
43918c2ecf20Sopenharmony_ci	WREG32(VM_CONTEXT0_CNTL, 0);
43928c2ecf20Sopenharmony_ci	WREG32(VM_CONTEXT1_CNTL, 0);
43938c2ecf20Sopenharmony_ci	/* Setup TLB control */
43948c2ecf20Sopenharmony_ci	WREG32(MC_VM_MX_L1_TLB_CNTL, SYSTEM_ACCESS_MODE_NOT_IN_SYS |
43958c2ecf20Sopenharmony_ci	       SYSTEM_APERTURE_UNMAPPED_ACCESS_PASS_THRU);
43968c2ecf20Sopenharmony_ci	/* Setup L2 cache */
43978c2ecf20Sopenharmony_ci	WREG32(VM_L2_CNTL, ENABLE_L2_PTE_CACHE_LRU_UPDATE_BY_WRITE |
43988c2ecf20Sopenharmony_ci	       ENABLE_L2_PDE0_CACHE_LRU_UPDATE_BY_WRITE |
43998c2ecf20Sopenharmony_ci	       EFFECTIVE_L2_QUEUE_SIZE(7) |
44008c2ecf20Sopenharmony_ci	       CONTEXT1_IDENTITY_ACCESS_MODE(1));
44018c2ecf20Sopenharmony_ci	WREG32(VM_L2_CNTL2, 0);
44028c2ecf20Sopenharmony_ci	WREG32(VM_L2_CNTL3, L2_CACHE_BIGK_ASSOCIATIVITY |
44038c2ecf20Sopenharmony_ci	       L2_CACHE_BIGK_FRAGMENT_SIZE(0));
44048c2ecf20Sopenharmony_ci	radeon_gart_table_vram_unpin(rdev);
44058c2ecf20Sopenharmony_ci}
44068c2ecf20Sopenharmony_ci
44078c2ecf20Sopenharmony_cistatic void si_pcie_gart_fini(struct radeon_device *rdev)
44088c2ecf20Sopenharmony_ci{
44098c2ecf20Sopenharmony_ci	si_pcie_gart_disable(rdev);
44108c2ecf20Sopenharmony_ci	radeon_gart_table_vram_free(rdev);
44118c2ecf20Sopenharmony_ci	radeon_gart_fini(rdev);
44128c2ecf20Sopenharmony_ci}
44138c2ecf20Sopenharmony_ci
44148c2ecf20Sopenharmony_ci/* vm parser */
44158c2ecf20Sopenharmony_cistatic bool si_vm_reg_valid(u32 reg)
44168c2ecf20Sopenharmony_ci{
44178c2ecf20Sopenharmony_ci	/* context regs are fine */
44188c2ecf20Sopenharmony_ci	if (reg >= 0x28000)
44198c2ecf20Sopenharmony_ci		return true;
44208c2ecf20Sopenharmony_ci
44218c2ecf20Sopenharmony_ci	/* shader regs are also fine */
44228c2ecf20Sopenharmony_ci	if (reg >= 0xB000 && reg < 0xC000)
44238c2ecf20Sopenharmony_ci		return true;
44248c2ecf20Sopenharmony_ci
44258c2ecf20Sopenharmony_ci	/* check config regs */
44268c2ecf20Sopenharmony_ci	switch (reg) {
44278c2ecf20Sopenharmony_ci	case GRBM_GFX_INDEX:
44288c2ecf20Sopenharmony_ci	case CP_STRMOUT_CNTL:
44298c2ecf20Sopenharmony_ci	case VGT_VTX_VECT_EJECT_REG:
44308c2ecf20Sopenharmony_ci	case VGT_CACHE_INVALIDATION:
44318c2ecf20Sopenharmony_ci	case VGT_ESGS_RING_SIZE:
44328c2ecf20Sopenharmony_ci	case VGT_GSVS_RING_SIZE:
44338c2ecf20Sopenharmony_ci	case VGT_GS_VERTEX_REUSE:
44348c2ecf20Sopenharmony_ci	case VGT_PRIMITIVE_TYPE:
44358c2ecf20Sopenharmony_ci	case VGT_INDEX_TYPE:
44368c2ecf20Sopenharmony_ci	case VGT_NUM_INDICES:
44378c2ecf20Sopenharmony_ci	case VGT_NUM_INSTANCES:
44388c2ecf20Sopenharmony_ci	case VGT_TF_RING_SIZE:
44398c2ecf20Sopenharmony_ci	case VGT_HS_OFFCHIP_PARAM:
44408c2ecf20Sopenharmony_ci	case VGT_TF_MEMORY_BASE:
44418c2ecf20Sopenharmony_ci	case PA_CL_ENHANCE:
44428c2ecf20Sopenharmony_ci	case PA_SU_LINE_STIPPLE_VALUE:
44438c2ecf20Sopenharmony_ci	case PA_SC_LINE_STIPPLE_STATE:
44448c2ecf20Sopenharmony_ci	case PA_SC_ENHANCE:
44458c2ecf20Sopenharmony_ci	case SQC_CACHES:
44468c2ecf20Sopenharmony_ci	case SPI_STATIC_THREAD_MGMT_1:
44478c2ecf20Sopenharmony_ci	case SPI_STATIC_THREAD_MGMT_2:
44488c2ecf20Sopenharmony_ci	case SPI_STATIC_THREAD_MGMT_3:
44498c2ecf20Sopenharmony_ci	case SPI_PS_MAX_WAVE_ID:
44508c2ecf20Sopenharmony_ci	case SPI_CONFIG_CNTL:
44518c2ecf20Sopenharmony_ci	case SPI_CONFIG_CNTL_1:
44528c2ecf20Sopenharmony_ci	case TA_CNTL_AUX:
44538c2ecf20Sopenharmony_ci	case TA_CS_BC_BASE_ADDR:
44548c2ecf20Sopenharmony_ci		return true;
44558c2ecf20Sopenharmony_ci	default:
44568c2ecf20Sopenharmony_ci		DRM_ERROR("Invalid register 0x%x in CS\n", reg);
44578c2ecf20Sopenharmony_ci		return false;
44588c2ecf20Sopenharmony_ci	}
44598c2ecf20Sopenharmony_ci}
44608c2ecf20Sopenharmony_ci
44618c2ecf20Sopenharmony_cistatic int si_vm_packet3_ce_check(struct radeon_device *rdev,
44628c2ecf20Sopenharmony_ci				  u32 *ib, struct radeon_cs_packet *pkt)
44638c2ecf20Sopenharmony_ci{
44648c2ecf20Sopenharmony_ci	switch (pkt->opcode) {
44658c2ecf20Sopenharmony_ci	case PACKET3_NOP:
44668c2ecf20Sopenharmony_ci	case PACKET3_SET_BASE:
44678c2ecf20Sopenharmony_ci	case PACKET3_SET_CE_DE_COUNTERS:
44688c2ecf20Sopenharmony_ci	case PACKET3_LOAD_CONST_RAM:
44698c2ecf20Sopenharmony_ci	case PACKET3_WRITE_CONST_RAM:
44708c2ecf20Sopenharmony_ci	case PACKET3_WRITE_CONST_RAM_OFFSET:
44718c2ecf20Sopenharmony_ci	case PACKET3_DUMP_CONST_RAM:
44728c2ecf20Sopenharmony_ci	case PACKET3_INCREMENT_CE_COUNTER:
44738c2ecf20Sopenharmony_ci	case PACKET3_WAIT_ON_DE_COUNTER:
44748c2ecf20Sopenharmony_ci	case PACKET3_CE_WRITE:
44758c2ecf20Sopenharmony_ci		break;
44768c2ecf20Sopenharmony_ci	default:
44778c2ecf20Sopenharmony_ci		DRM_ERROR("Invalid CE packet3: 0x%x\n", pkt->opcode);
44788c2ecf20Sopenharmony_ci		return -EINVAL;
44798c2ecf20Sopenharmony_ci	}
44808c2ecf20Sopenharmony_ci	return 0;
44818c2ecf20Sopenharmony_ci}
44828c2ecf20Sopenharmony_ci
44838c2ecf20Sopenharmony_cistatic int si_vm_packet3_cp_dma_check(u32 *ib, u32 idx)
44848c2ecf20Sopenharmony_ci{
44858c2ecf20Sopenharmony_ci	u32 start_reg, reg, i;
44868c2ecf20Sopenharmony_ci	u32 command = ib[idx + 4];
44878c2ecf20Sopenharmony_ci	u32 info = ib[idx + 1];
44888c2ecf20Sopenharmony_ci	u32 idx_value = ib[idx];
44898c2ecf20Sopenharmony_ci	if (command & PACKET3_CP_DMA_CMD_SAS) {
44908c2ecf20Sopenharmony_ci		/* src address space is register */
44918c2ecf20Sopenharmony_ci		if (((info & 0x60000000) >> 29) == 0) {
44928c2ecf20Sopenharmony_ci			start_reg = idx_value << 2;
44938c2ecf20Sopenharmony_ci			if (command & PACKET3_CP_DMA_CMD_SAIC) {
44948c2ecf20Sopenharmony_ci				reg = start_reg;
44958c2ecf20Sopenharmony_ci				if (!si_vm_reg_valid(reg)) {
44968c2ecf20Sopenharmony_ci					DRM_ERROR("CP DMA Bad SRC register\n");
44978c2ecf20Sopenharmony_ci					return -EINVAL;
44988c2ecf20Sopenharmony_ci				}
44998c2ecf20Sopenharmony_ci			} else {
45008c2ecf20Sopenharmony_ci				for (i = 0; i < (command & 0x1fffff); i++) {
45018c2ecf20Sopenharmony_ci					reg = start_reg + (4 * i);
45028c2ecf20Sopenharmony_ci					if (!si_vm_reg_valid(reg)) {
45038c2ecf20Sopenharmony_ci						DRM_ERROR("CP DMA Bad SRC register\n");
45048c2ecf20Sopenharmony_ci						return -EINVAL;
45058c2ecf20Sopenharmony_ci					}
45068c2ecf20Sopenharmony_ci				}
45078c2ecf20Sopenharmony_ci			}
45088c2ecf20Sopenharmony_ci		}
45098c2ecf20Sopenharmony_ci	}
45108c2ecf20Sopenharmony_ci	if (command & PACKET3_CP_DMA_CMD_DAS) {
45118c2ecf20Sopenharmony_ci		/* dst address space is register */
45128c2ecf20Sopenharmony_ci		if (((info & 0x00300000) >> 20) == 0) {
45138c2ecf20Sopenharmony_ci			start_reg = ib[idx + 2];
45148c2ecf20Sopenharmony_ci			if (command & PACKET3_CP_DMA_CMD_DAIC) {
45158c2ecf20Sopenharmony_ci				reg = start_reg;
45168c2ecf20Sopenharmony_ci				if (!si_vm_reg_valid(reg)) {
45178c2ecf20Sopenharmony_ci					DRM_ERROR("CP DMA Bad DST register\n");
45188c2ecf20Sopenharmony_ci					return -EINVAL;
45198c2ecf20Sopenharmony_ci				}
45208c2ecf20Sopenharmony_ci			} else {
45218c2ecf20Sopenharmony_ci				for (i = 0; i < (command & 0x1fffff); i++) {
45228c2ecf20Sopenharmony_ci					reg = start_reg + (4 * i);
45238c2ecf20Sopenharmony_ci				if (!si_vm_reg_valid(reg)) {
45248c2ecf20Sopenharmony_ci						DRM_ERROR("CP DMA Bad DST register\n");
45258c2ecf20Sopenharmony_ci						return -EINVAL;
45268c2ecf20Sopenharmony_ci					}
45278c2ecf20Sopenharmony_ci				}
45288c2ecf20Sopenharmony_ci			}
45298c2ecf20Sopenharmony_ci		}
45308c2ecf20Sopenharmony_ci	}
45318c2ecf20Sopenharmony_ci	return 0;
45328c2ecf20Sopenharmony_ci}
45338c2ecf20Sopenharmony_ci
45348c2ecf20Sopenharmony_cistatic int si_vm_packet3_gfx_check(struct radeon_device *rdev,
45358c2ecf20Sopenharmony_ci				   u32 *ib, struct radeon_cs_packet *pkt)
45368c2ecf20Sopenharmony_ci{
45378c2ecf20Sopenharmony_ci	int r;
45388c2ecf20Sopenharmony_ci	u32 idx = pkt->idx + 1;
45398c2ecf20Sopenharmony_ci	u32 idx_value = ib[idx];
45408c2ecf20Sopenharmony_ci	u32 start_reg, end_reg, reg, i;
45418c2ecf20Sopenharmony_ci
45428c2ecf20Sopenharmony_ci	switch (pkt->opcode) {
45438c2ecf20Sopenharmony_ci	case PACKET3_NOP:
45448c2ecf20Sopenharmony_ci	case PACKET3_SET_BASE:
45458c2ecf20Sopenharmony_ci	case PACKET3_CLEAR_STATE:
45468c2ecf20Sopenharmony_ci	case PACKET3_INDEX_BUFFER_SIZE:
45478c2ecf20Sopenharmony_ci	case PACKET3_DISPATCH_DIRECT:
45488c2ecf20Sopenharmony_ci	case PACKET3_DISPATCH_INDIRECT:
45498c2ecf20Sopenharmony_ci	case PACKET3_ALLOC_GDS:
45508c2ecf20Sopenharmony_ci	case PACKET3_WRITE_GDS_RAM:
45518c2ecf20Sopenharmony_ci	case PACKET3_ATOMIC_GDS:
45528c2ecf20Sopenharmony_ci	case PACKET3_ATOMIC:
45538c2ecf20Sopenharmony_ci	case PACKET3_OCCLUSION_QUERY:
45548c2ecf20Sopenharmony_ci	case PACKET3_SET_PREDICATION:
45558c2ecf20Sopenharmony_ci	case PACKET3_COND_EXEC:
45568c2ecf20Sopenharmony_ci	case PACKET3_PRED_EXEC:
45578c2ecf20Sopenharmony_ci	case PACKET3_DRAW_INDIRECT:
45588c2ecf20Sopenharmony_ci	case PACKET3_DRAW_INDEX_INDIRECT:
45598c2ecf20Sopenharmony_ci	case PACKET3_INDEX_BASE:
45608c2ecf20Sopenharmony_ci	case PACKET3_DRAW_INDEX_2:
45618c2ecf20Sopenharmony_ci	case PACKET3_CONTEXT_CONTROL:
45628c2ecf20Sopenharmony_ci	case PACKET3_INDEX_TYPE:
45638c2ecf20Sopenharmony_ci	case PACKET3_DRAW_INDIRECT_MULTI:
45648c2ecf20Sopenharmony_ci	case PACKET3_DRAW_INDEX_AUTO:
45658c2ecf20Sopenharmony_ci	case PACKET3_DRAW_INDEX_IMMD:
45668c2ecf20Sopenharmony_ci	case PACKET3_NUM_INSTANCES:
45678c2ecf20Sopenharmony_ci	case PACKET3_DRAW_INDEX_MULTI_AUTO:
45688c2ecf20Sopenharmony_ci	case PACKET3_STRMOUT_BUFFER_UPDATE:
45698c2ecf20Sopenharmony_ci	case PACKET3_DRAW_INDEX_OFFSET_2:
45708c2ecf20Sopenharmony_ci	case PACKET3_DRAW_INDEX_MULTI_ELEMENT:
45718c2ecf20Sopenharmony_ci	case PACKET3_DRAW_INDEX_INDIRECT_MULTI:
45728c2ecf20Sopenharmony_ci	case PACKET3_MPEG_INDEX:
45738c2ecf20Sopenharmony_ci	case PACKET3_WAIT_REG_MEM:
45748c2ecf20Sopenharmony_ci	case PACKET3_MEM_WRITE:
45758c2ecf20Sopenharmony_ci	case PACKET3_PFP_SYNC_ME:
45768c2ecf20Sopenharmony_ci	case PACKET3_SURFACE_SYNC:
45778c2ecf20Sopenharmony_ci	case PACKET3_EVENT_WRITE:
45788c2ecf20Sopenharmony_ci	case PACKET3_EVENT_WRITE_EOP:
45798c2ecf20Sopenharmony_ci	case PACKET3_EVENT_WRITE_EOS:
45808c2ecf20Sopenharmony_ci	case PACKET3_SET_CONTEXT_REG:
45818c2ecf20Sopenharmony_ci	case PACKET3_SET_CONTEXT_REG_INDIRECT:
45828c2ecf20Sopenharmony_ci	case PACKET3_SET_SH_REG:
45838c2ecf20Sopenharmony_ci	case PACKET3_SET_SH_REG_OFFSET:
45848c2ecf20Sopenharmony_ci	case PACKET3_INCREMENT_DE_COUNTER:
45858c2ecf20Sopenharmony_ci	case PACKET3_WAIT_ON_CE_COUNTER:
45868c2ecf20Sopenharmony_ci	case PACKET3_WAIT_ON_AVAIL_BUFFER:
45878c2ecf20Sopenharmony_ci	case PACKET3_ME_WRITE:
45888c2ecf20Sopenharmony_ci		break;
45898c2ecf20Sopenharmony_ci	case PACKET3_COPY_DATA:
45908c2ecf20Sopenharmony_ci		if ((idx_value & 0xf00) == 0) {
45918c2ecf20Sopenharmony_ci			reg = ib[idx + 3] * 4;
45928c2ecf20Sopenharmony_ci			if (!si_vm_reg_valid(reg))
45938c2ecf20Sopenharmony_ci				return -EINVAL;
45948c2ecf20Sopenharmony_ci		}
45958c2ecf20Sopenharmony_ci		break;
45968c2ecf20Sopenharmony_ci	case PACKET3_WRITE_DATA:
45978c2ecf20Sopenharmony_ci		if ((idx_value & 0xf00) == 0) {
45988c2ecf20Sopenharmony_ci			start_reg = ib[idx + 1] * 4;
45998c2ecf20Sopenharmony_ci			if (idx_value & 0x10000) {
46008c2ecf20Sopenharmony_ci				if (!si_vm_reg_valid(start_reg))
46018c2ecf20Sopenharmony_ci					return -EINVAL;
46028c2ecf20Sopenharmony_ci			} else {
46038c2ecf20Sopenharmony_ci				for (i = 0; i < (pkt->count - 2); i++) {
46048c2ecf20Sopenharmony_ci					reg = start_reg + (4 * i);
46058c2ecf20Sopenharmony_ci					if (!si_vm_reg_valid(reg))
46068c2ecf20Sopenharmony_ci						return -EINVAL;
46078c2ecf20Sopenharmony_ci				}
46088c2ecf20Sopenharmony_ci			}
46098c2ecf20Sopenharmony_ci		}
46108c2ecf20Sopenharmony_ci		break;
46118c2ecf20Sopenharmony_ci	case PACKET3_COND_WRITE:
46128c2ecf20Sopenharmony_ci		if (idx_value & 0x100) {
46138c2ecf20Sopenharmony_ci			reg = ib[idx + 5] * 4;
46148c2ecf20Sopenharmony_ci			if (!si_vm_reg_valid(reg))
46158c2ecf20Sopenharmony_ci				return -EINVAL;
46168c2ecf20Sopenharmony_ci		}
46178c2ecf20Sopenharmony_ci		break;
46188c2ecf20Sopenharmony_ci	case PACKET3_COPY_DW:
46198c2ecf20Sopenharmony_ci		if (idx_value & 0x2) {
46208c2ecf20Sopenharmony_ci			reg = ib[idx + 3] * 4;
46218c2ecf20Sopenharmony_ci			if (!si_vm_reg_valid(reg))
46228c2ecf20Sopenharmony_ci				return -EINVAL;
46238c2ecf20Sopenharmony_ci		}
46248c2ecf20Sopenharmony_ci		break;
46258c2ecf20Sopenharmony_ci	case PACKET3_SET_CONFIG_REG:
46268c2ecf20Sopenharmony_ci		start_reg = (idx_value << 2) + PACKET3_SET_CONFIG_REG_START;
46278c2ecf20Sopenharmony_ci		end_reg = 4 * pkt->count + start_reg - 4;
46288c2ecf20Sopenharmony_ci		if ((start_reg < PACKET3_SET_CONFIG_REG_START) ||
46298c2ecf20Sopenharmony_ci		    (start_reg >= PACKET3_SET_CONFIG_REG_END) ||
46308c2ecf20Sopenharmony_ci		    (end_reg >= PACKET3_SET_CONFIG_REG_END)) {
46318c2ecf20Sopenharmony_ci			DRM_ERROR("bad PACKET3_SET_CONFIG_REG\n");
46328c2ecf20Sopenharmony_ci			return -EINVAL;
46338c2ecf20Sopenharmony_ci		}
46348c2ecf20Sopenharmony_ci		for (i = 0; i < pkt->count; i++) {
46358c2ecf20Sopenharmony_ci			reg = start_reg + (4 * i);
46368c2ecf20Sopenharmony_ci			if (!si_vm_reg_valid(reg))
46378c2ecf20Sopenharmony_ci				return -EINVAL;
46388c2ecf20Sopenharmony_ci		}
46398c2ecf20Sopenharmony_ci		break;
46408c2ecf20Sopenharmony_ci	case PACKET3_CP_DMA:
46418c2ecf20Sopenharmony_ci		r = si_vm_packet3_cp_dma_check(ib, idx);
46428c2ecf20Sopenharmony_ci		if (r)
46438c2ecf20Sopenharmony_ci			return r;
46448c2ecf20Sopenharmony_ci		break;
46458c2ecf20Sopenharmony_ci	default:
46468c2ecf20Sopenharmony_ci		DRM_ERROR("Invalid GFX packet3: 0x%x\n", pkt->opcode);
46478c2ecf20Sopenharmony_ci		return -EINVAL;
46488c2ecf20Sopenharmony_ci	}
46498c2ecf20Sopenharmony_ci	return 0;
46508c2ecf20Sopenharmony_ci}
46518c2ecf20Sopenharmony_ci
46528c2ecf20Sopenharmony_cistatic int si_vm_packet3_compute_check(struct radeon_device *rdev,
46538c2ecf20Sopenharmony_ci				       u32 *ib, struct radeon_cs_packet *pkt)
46548c2ecf20Sopenharmony_ci{
46558c2ecf20Sopenharmony_ci	int r;
46568c2ecf20Sopenharmony_ci	u32 idx = pkt->idx + 1;
46578c2ecf20Sopenharmony_ci	u32 idx_value = ib[idx];
46588c2ecf20Sopenharmony_ci	u32 start_reg, reg, i;
46598c2ecf20Sopenharmony_ci
46608c2ecf20Sopenharmony_ci	switch (pkt->opcode) {
46618c2ecf20Sopenharmony_ci	case PACKET3_NOP:
46628c2ecf20Sopenharmony_ci	case PACKET3_SET_BASE:
46638c2ecf20Sopenharmony_ci	case PACKET3_CLEAR_STATE:
46648c2ecf20Sopenharmony_ci	case PACKET3_DISPATCH_DIRECT:
46658c2ecf20Sopenharmony_ci	case PACKET3_DISPATCH_INDIRECT:
46668c2ecf20Sopenharmony_ci	case PACKET3_ALLOC_GDS:
46678c2ecf20Sopenharmony_ci	case PACKET3_WRITE_GDS_RAM:
46688c2ecf20Sopenharmony_ci	case PACKET3_ATOMIC_GDS:
46698c2ecf20Sopenharmony_ci	case PACKET3_ATOMIC:
46708c2ecf20Sopenharmony_ci	case PACKET3_OCCLUSION_QUERY:
46718c2ecf20Sopenharmony_ci	case PACKET3_SET_PREDICATION:
46728c2ecf20Sopenharmony_ci	case PACKET3_COND_EXEC:
46738c2ecf20Sopenharmony_ci	case PACKET3_PRED_EXEC:
46748c2ecf20Sopenharmony_ci	case PACKET3_CONTEXT_CONTROL:
46758c2ecf20Sopenharmony_ci	case PACKET3_STRMOUT_BUFFER_UPDATE:
46768c2ecf20Sopenharmony_ci	case PACKET3_WAIT_REG_MEM:
46778c2ecf20Sopenharmony_ci	case PACKET3_MEM_WRITE:
46788c2ecf20Sopenharmony_ci	case PACKET3_PFP_SYNC_ME:
46798c2ecf20Sopenharmony_ci	case PACKET3_SURFACE_SYNC:
46808c2ecf20Sopenharmony_ci	case PACKET3_EVENT_WRITE:
46818c2ecf20Sopenharmony_ci	case PACKET3_EVENT_WRITE_EOP:
46828c2ecf20Sopenharmony_ci	case PACKET3_EVENT_WRITE_EOS:
46838c2ecf20Sopenharmony_ci	case PACKET3_SET_CONTEXT_REG:
46848c2ecf20Sopenharmony_ci	case PACKET3_SET_CONTEXT_REG_INDIRECT:
46858c2ecf20Sopenharmony_ci	case PACKET3_SET_SH_REG:
46868c2ecf20Sopenharmony_ci	case PACKET3_SET_SH_REG_OFFSET:
46878c2ecf20Sopenharmony_ci	case PACKET3_INCREMENT_DE_COUNTER:
46888c2ecf20Sopenharmony_ci	case PACKET3_WAIT_ON_CE_COUNTER:
46898c2ecf20Sopenharmony_ci	case PACKET3_WAIT_ON_AVAIL_BUFFER:
46908c2ecf20Sopenharmony_ci	case PACKET3_ME_WRITE:
46918c2ecf20Sopenharmony_ci		break;
46928c2ecf20Sopenharmony_ci	case PACKET3_COPY_DATA:
46938c2ecf20Sopenharmony_ci		if ((idx_value & 0xf00) == 0) {
46948c2ecf20Sopenharmony_ci			reg = ib[idx + 3] * 4;
46958c2ecf20Sopenharmony_ci			if (!si_vm_reg_valid(reg))
46968c2ecf20Sopenharmony_ci				return -EINVAL;
46978c2ecf20Sopenharmony_ci		}
46988c2ecf20Sopenharmony_ci		break;
46998c2ecf20Sopenharmony_ci	case PACKET3_WRITE_DATA:
47008c2ecf20Sopenharmony_ci		if ((idx_value & 0xf00) == 0) {
47018c2ecf20Sopenharmony_ci			start_reg = ib[idx + 1] * 4;
47028c2ecf20Sopenharmony_ci			if (idx_value & 0x10000) {
47038c2ecf20Sopenharmony_ci				if (!si_vm_reg_valid(start_reg))
47048c2ecf20Sopenharmony_ci					return -EINVAL;
47058c2ecf20Sopenharmony_ci			} else {
47068c2ecf20Sopenharmony_ci				for (i = 0; i < (pkt->count - 2); i++) {
47078c2ecf20Sopenharmony_ci					reg = start_reg + (4 * i);
47088c2ecf20Sopenharmony_ci					if (!si_vm_reg_valid(reg))
47098c2ecf20Sopenharmony_ci						return -EINVAL;
47108c2ecf20Sopenharmony_ci				}
47118c2ecf20Sopenharmony_ci			}
47128c2ecf20Sopenharmony_ci		}
47138c2ecf20Sopenharmony_ci		break;
47148c2ecf20Sopenharmony_ci	case PACKET3_COND_WRITE:
47158c2ecf20Sopenharmony_ci		if (idx_value & 0x100) {
47168c2ecf20Sopenharmony_ci			reg = ib[idx + 5] * 4;
47178c2ecf20Sopenharmony_ci			if (!si_vm_reg_valid(reg))
47188c2ecf20Sopenharmony_ci				return -EINVAL;
47198c2ecf20Sopenharmony_ci		}
47208c2ecf20Sopenharmony_ci		break;
47218c2ecf20Sopenharmony_ci	case PACKET3_COPY_DW:
47228c2ecf20Sopenharmony_ci		if (idx_value & 0x2) {
47238c2ecf20Sopenharmony_ci			reg = ib[idx + 3] * 4;
47248c2ecf20Sopenharmony_ci			if (!si_vm_reg_valid(reg))
47258c2ecf20Sopenharmony_ci				return -EINVAL;
47268c2ecf20Sopenharmony_ci		}
47278c2ecf20Sopenharmony_ci		break;
47288c2ecf20Sopenharmony_ci	case PACKET3_CP_DMA:
47298c2ecf20Sopenharmony_ci		r = si_vm_packet3_cp_dma_check(ib, idx);
47308c2ecf20Sopenharmony_ci		if (r)
47318c2ecf20Sopenharmony_ci			return r;
47328c2ecf20Sopenharmony_ci		break;
47338c2ecf20Sopenharmony_ci	default:
47348c2ecf20Sopenharmony_ci		DRM_ERROR("Invalid Compute packet3: 0x%x\n", pkt->opcode);
47358c2ecf20Sopenharmony_ci		return -EINVAL;
47368c2ecf20Sopenharmony_ci	}
47378c2ecf20Sopenharmony_ci	return 0;
47388c2ecf20Sopenharmony_ci}
47398c2ecf20Sopenharmony_ci
47408c2ecf20Sopenharmony_ciint si_ib_parse(struct radeon_device *rdev, struct radeon_ib *ib)
47418c2ecf20Sopenharmony_ci{
47428c2ecf20Sopenharmony_ci	int ret = 0;
47438c2ecf20Sopenharmony_ci	u32 idx = 0, i;
47448c2ecf20Sopenharmony_ci	struct radeon_cs_packet pkt;
47458c2ecf20Sopenharmony_ci
47468c2ecf20Sopenharmony_ci	do {
47478c2ecf20Sopenharmony_ci		pkt.idx = idx;
47488c2ecf20Sopenharmony_ci		pkt.type = RADEON_CP_PACKET_GET_TYPE(ib->ptr[idx]);
47498c2ecf20Sopenharmony_ci		pkt.count = RADEON_CP_PACKET_GET_COUNT(ib->ptr[idx]);
47508c2ecf20Sopenharmony_ci		pkt.one_reg_wr = 0;
47518c2ecf20Sopenharmony_ci		switch (pkt.type) {
47528c2ecf20Sopenharmony_ci		case RADEON_PACKET_TYPE0:
47538c2ecf20Sopenharmony_ci			dev_err(rdev->dev, "Packet0 not allowed!\n");
47548c2ecf20Sopenharmony_ci			ret = -EINVAL;
47558c2ecf20Sopenharmony_ci			break;
47568c2ecf20Sopenharmony_ci		case RADEON_PACKET_TYPE2:
47578c2ecf20Sopenharmony_ci			idx += 1;
47588c2ecf20Sopenharmony_ci			break;
47598c2ecf20Sopenharmony_ci		case RADEON_PACKET_TYPE3:
47608c2ecf20Sopenharmony_ci			pkt.opcode = RADEON_CP_PACKET3_GET_OPCODE(ib->ptr[idx]);
47618c2ecf20Sopenharmony_ci			if (ib->is_const_ib)
47628c2ecf20Sopenharmony_ci				ret = si_vm_packet3_ce_check(rdev, ib->ptr, &pkt);
47638c2ecf20Sopenharmony_ci			else {
47648c2ecf20Sopenharmony_ci				switch (ib->ring) {
47658c2ecf20Sopenharmony_ci				case RADEON_RING_TYPE_GFX_INDEX:
47668c2ecf20Sopenharmony_ci					ret = si_vm_packet3_gfx_check(rdev, ib->ptr, &pkt);
47678c2ecf20Sopenharmony_ci					break;
47688c2ecf20Sopenharmony_ci				case CAYMAN_RING_TYPE_CP1_INDEX:
47698c2ecf20Sopenharmony_ci				case CAYMAN_RING_TYPE_CP2_INDEX:
47708c2ecf20Sopenharmony_ci					ret = si_vm_packet3_compute_check(rdev, ib->ptr, &pkt);
47718c2ecf20Sopenharmony_ci					break;
47728c2ecf20Sopenharmony_ci				default:
47738c2ecf20Sopenharmony_ci					dev_err(rdev->dev, "Non-PM4 ring %d !\n", ib->ring);
47748c2ecf20Sopenharmony_ci					ret = -EINVAL;
47758c2ecf20Sopenharmony_ci					break;
47768c2ecf20Sopenharmony_ci				}
47778c2ecf20Sopenharmony_ci			}
47788c2ecf20Sopenharmony_ci			idx += pkt.count + 2;
47798c2ecf20Sopenharmony_ci			break;
47808c2ecf20Sopenharmony_ci		default:
47818c2ecf20Sopenharmony_ci			dev_err(rdev->dev, "Unknown packet type %d !\n", pkt.type);
47828c2ecf20Sopenharmony_ci			ret = -EINVAL;
47838c2ecf20Sopenharmony_ci			break;
47848c2ecf20Sopenharmony_ci		}
47858c2ecf20Sopenharmony_ci		if (ret) {
47868c2ecf20Sopenharmony_ci			for (i = 0; i < ib->length_dw; i++) {
47878c2ecf20Sopenharmony_ci				if (i == idx)
47888c2ecf20Sopenharmony_ci					printk("\t0x%08x <---\n", ib->ptr[i]);
47898c2ecf20Sopenharmony_ci				else
47908c2ecf20Sopenharmony_ci					printk("\t0x%08x\n", ib->ptr[i]);
47918c2ecf20Sopenharmony_ci			}
47928c2ecf20Sopenharmony_ci			break;
47938c2ecf20Sopenharmony_ci		}
47948c2ecf20Sopenharmony_ci	} while (idx < ib->length_dw);
47958c2ecf20Sopenharmony_ci
47968c2ecf20Sopenharmony_ci	return ret;
47978c2ecf20Sopenharmony_ci}
47988c2ecf20Sopenharmony_ci
47998c2ecf20Sopenharmony_ci/*
48008c2ecf20Sopenharmony_ci * vm
48018c2ecf20Sopenharmony_ci */
48028c2ecf20Sopenharmony_ciint si_vm_init(struct radeon_device *rdev)
48038c2ecf20Sopenharmony_ci{
48048c2ecf20Sopenharmony_ci	/* number of VMs */
48058c2ecf20Sopenharmony_ci	rdev->vm_manager.nvm = 16;
48068c2ecf20Sopenharmony_ci	/* base offset of vram pages */
48078c2ecf20Sopenharmony_ci	rdev->vm_manager.vram_base_offset = 0;
48088c2ecf20Sopenharmony_ci
48098c2ecf20Sopenharmony_ci	return 0;
48108c2ecf20Sopenharmony_ci}
48118c2ecf20Sopenharmony_ci
48128c2ecf20Sopenharmony_civoid si_vm_fini(struct radeon_device *rdev)
48138c2ecf20Sopenharmony_ci{
48148c2ecf20Sopenharmony_ci}
48158c2ecf20Sopenharmony_ci
48168c2ecf20Sopenharmony_ci/**
48178c2ecf20Sopenharmony_ci * si_vm_decode_fault - print human readable fault info
48188c2ecf20Sopenharmony_ci *
48198c2ecf20Sopenharmony_ci * @rdev: radeon_device pointer
48208c2ecf20Sopenharmony_ci * @status: VM_CONTEXT1_PROTECTION_FAULT_STATUS register value
48218c2ecf20Sopenharmony_ci * @addr: VM_CONTEXT1_PROTECTION_FAULT_ADDR register value
48228c2ecf20Sopenharmony_ci *
48238c2ecf20Sopenharmony_ci * Print human readable fault information (SI).
48248c2ecf20Sopenharmony_ci */
48258c2ecf20Sopenharmony_cistatic void si_vm_decode_fault(struct radeon_device *rdev,
48268c2ecf20Sopenharmony_ci			       u32 status, u32 addr)
48278c2ecf20Sopenharmony_ci{
48288c2ecf20Sopenharmony_ci	u32 mc_id = (status & MEMORY_CLIENT_ID_MASK) >> MEMORY_CLIENT_ID_SHIFT;
48298c2ecf20Sopenharmony_ci	u32 vmid = (status & FAULT_VMID_MASK) >> FAULT_VMID_SHIFT;
48308c2ecf20Sopenharmony_ci	u32 protections = (status & PROTECTIONS_MASK) >> PROTECTIONS_SHIFT;
48318c2ecf20Sopenharmony_ci	char *block;
48328c2ecf20Sopenharmony_ci
48338c2ecf20Sopenharmony_ci	if (rdev->family == CHIP_TAHITI) {
48348c2ecf20Sopenharmony_ci		switch (mc_id) {
48358c2ecf20Sopenharmony_ci		case 160:
48368c2ecf20Sopenharmony_ci		case 144:
48378c2ecf20Sopenharmony_ci		case 96:
48388c2ecf20Sopenharmony_ci		case 80:
48398c2ecf20Sopenharmony_ci		case 224:
48408c2ecf20Sopenharmony_ci		case 208:
48418c2ecf20Sopenharmony_ci		case 32:
48428c2ecf20Sopenharmony_ci		case 16:
48438c2ecf20Sopenharmony_ci			block = "CB";
48448c2ecf20Sopenharmony_ci			break;
48458c2ecf20Sopenharmony_ci		case 161:
48468c2ecf20Sopenharmony_ci		case 145:
48478c2ecf20Sopenharmony_ci		case 97:
48488c2ecf20Sopenharmony_ci		case 81:
48498c2ecf20Sopenharmony_ci		case 225:
48508c2ecf20Sopenharmony_ci		case 209:
48518c2ecf20Sopenharmony_ci		case 33:
48528c2ecf20Sopenharmony_ci		case 17:
48538c2ecf20Sopenharmony_ci			block = "CB_FMASK";
48548c2ecf20Sopenharmony_ci			break;
48558c2ecf20Sopenharmony_ci		case 162:
48568c2ecf20Sopenharmony_ci		case 146:
48578c2ecf20Sopenharmony_ci		case 98:
48588c2ecf20Sopenharmony_ci		case 82:
48598c2ecf20Sopenharmony_ci		case 226:
48608c2ecf20Sopenharmony_ci		case 210:
48618c2ecf20Sopenharmony_ci		case 34:
48628c2ecf20Sopenharmony_ci		case 18:
48638c2ecf20Sopenharmony_ci			block = "CB_CMASK";
48648c2ecf20Sopenharmony_ci			break;
48658c2ecf20Sopenharmony_ci		case 163:
48668c2ecf20Sopenharmony_ci		case 147:
48678c2ecf20Sopenharmony_ci		case 99:
48688c2ecf20Sopenharmony_ci		case 83:
48698c2ecf20Sopenharmony_ci		case 227:
48708c2ecf20Sopenharmony_ci		case 211:
48718c2ecf20Sopenharmony_ci		case 35:
48728c2ecf20Sopenharmony_ci		case 19:
48738c2ecf20Sopenharmony_ci			block = "CB_IMMED";
48748c2ecf20Sopenharmony_ci			break;
48758c2ecf20Sopenharmony_ci		case 164:
48768c2ecf20Sopenharmony_ci		case 148:
48778c2ecf20Sopenharmony_ci		case 100:
48788c2ecf20Sopenharmony_ci		case 84:
48798c2ecf20Sopenharmony_ci		case 228:
48808c2ecf20Sopenharmony_ci		case 212:
48818c2ecf20Sopenharmony_ci		case 36:
48828c2ecf20Sopenharmony_ci		case 20:
48838c2ecf20Sopenharmony_ci			block = "DB";
48848c2ecf20Sopenharmony_ci			break;
48858c2ecf20Sopenharmony_ci		case 165:
48868c2ecf20Sopenharmony_ci		case 149:
48878c2ecf20Sopenharmony_ci		case 101:
48888c2ecf20Sopenharmony_ci		case 85:
48898c2ecf20Sopenharmony_ci		case 229:
48908c2ecf20Sopenharmony_ci		case 213:
48918c2ecf20Sopenharmony_ci		case 37:
48928c2ecf20Sopenharmony_ci		case 21:
48938c2ecf20Sopenharmony_ci			block = "DB_HTILE";
48948c2ecf20Sopenharmony_ci			break;
48958c2ecf20Sopenharmony_ci		case 167:
48968c2ecf20Sopenharmony_ci		case 151:
48978c2ecf20Sopenharmony_ci		case 103:
48988c2ecf20Sopenharmony_ci		case 87:
48998c2ecf20Sopenharmony_ci		case 231:
49008c2ecf20Sopenharmony_ci		case 215:
49018c2ecf20Sopenharmony_ci		case 39:
49028c2ecf20Sopenharmony_ci		case 23:
49038c2ecf20Sopenharmony_ci			block = "DB_STEN";
49048c2ecf20Sopenharmony_ci			break;
49058c2ecf20Sopenharmony_ci		case 72:
49068c2ecf20Sopenharmony_ci		case 68:
49078c2ecf20Sopenharmony_ci		case 64:
49088c2ecf20Sopenharmony_ci		case 8:
49098c2ecf20Sopenharmony_ci		case 4:
49108c2ecf20Sopenharmony_ci		case 0:
49118c2ecf20Sopenharmony_ci		case 136:
49128c2ecf20Sopenharmony_ci		case 132:
49138c2ecf20Sopenharmony_ci		case 128:
49148c2ecf20Sopenharmony_ci		case 200:
49158c2ecf20Sopenharmony_ci		case 196:
49168c2ecf20Sopenharmony_ci		case 192:
49178c2ecf20Sopenharmony_ci			block = "TC";
49188c2ecf20Sopenharmony_ci			break;
49198c2ecf20Sopenharmony_ci		case 112:
49208c2ecf20Sopenharmony_ci		case 48:
49218c2ecf20Sopenharmony_ci			block = "CP";
49228c2ecf20Sopenharmony_ci			break;
49238c2ecf20Sopenharmony_ci		case 49:
49248c2ecf20Sopenharmony_ci		case 177:
49258c2ecf20Sopenharmony_ci		case 50:
49268c2ecf20Sopenharmony_ci		case 178:
49278c2ecf20Sopenharmony_ci			block = "SH";
49288c2ecf20Sopenharmony_ci			break;
49298c2ecf20Sopenharmony_ci		case 53:
49308c2ecf20Sopenharmony_ci		case 190:
49318c2ecf20Sopenharmony_ci			block = "VGT";
49328c2ecf20Sopenharmony_ci			break;
49338c2ecf20Sopenharmony_ci		case 117:
49348c2ecf20Sopenharmony_ci			block = "IH";
49358c2ecf20Sopenharmony_ci			break;
49368c2ecf20Sopenharmony_ci		case 51:
49378c2ecf20Sopenharmony_ci		case 115:
49388c2ecf20Sopenharmony_ci			block = "RLC";
49398c2ecf20Sopenharmony_ci			break;
49408c2ecf20Sopenharmony_ci		case 119:
49418c2ecf20Sopenharmony_ci		case 183:
49428c2ecf20Sopenharmony_ci			block = "DMA0";
49438c2ecf20Sopenharmony_ci			break;
49448c2ecf20Sopenharmony_ci		case 61:
49458c2ecf20Sopenharmony_ci			block = "DMA1";
49468c2ecf20Sopenharmony_ci			break;
49478c2ecf20Sopenharmony_ci		case 248:
49488c2ecf20Sopenharmony_ci		case 120:
49498c2ecf20Sopenharmony_ci			block = "HDP";
49508c2ecf20Sopenharmony_ci			break;
49518c2ecf20Sopenharmony_ci		default:
49528c2ecf20Sopenharmony_ci			block = "unknown";
49538c2ecf20Sopenharmony_ci			break;
49548c2ecf20Sopenharmony_ci		}
49558c2ecf20Sopenharmony_ci	} else {
49568c2ecf20Sopenharmony_ci		switch (mc_id) {
49578c2ecf20Sopenharmony_ci		case 32:
49588c2ecf20Sopenharmony_ci		case 16:
49598c2ecf20Sopenharmony_ci		case 96:
49608c2ecf20Sopenharmony_ci		case 80:
49618c2ecf20Sopenharmony_ci		case 160:
49628c2ecf20Sopenharmony_ci		case 144:
49638c2ecf20Sopenharmony_ci		case 224:
49648c2ecf20Sopenharmony_ci		case 208:
49658c2ecf20Sopenharmony_ci			block = "CB";
49668c2ecf20Sopenharmony_ci			break;
49678c2ecf20Sopenharmony_ci		case 33:
49688c2ecf20Sopenharmony_ci		case 17:
49698c2ecf20Sopenharmony_ci		case 97:
49708c2ecf20Sopenharmony_ci		case 81:
49718c2ecf20Sopenharmony_ci		case 161:
49728c2ecf20Sopenharmony_ci		case 145:
49738c2ecf20Sopenharmony_ci		case 225:
49748c2ecf20Sopenharmony_ci		case 209:
49758c2ecf20Sopenharmony_ci			block = "CB_FMASK";
49768c2ecf20Sopenharmony_ci			break;
49778c2ecf20Sopenharmony_ci		case 34:
49788c2ecf20Sopenharmony_ci		case 18:
49798c2ecf20Sopenharmony_ci		case 98:
49808c2ecf20Sopenharmony_ci		case 82:
49818c2ecf20Sopenharmony_ci		case 162:
49828c2ecf20Sopenharmony_ci		case 146:
49838c2ecf20Sopenharmony_ci		case 226:
49848c2ecf20Sopenharmony_ci		case 210:
49858c2ecf20Sopenharmony_ci			block = "CB_CMASK";
49868c2ecf20Sopenharmony_ci			break;
49878c2ecf20Sopenharmony_ci		case 35:
49888c2ecf20Sopenharmony_ci		case 19:
49898c2ecf20Sopenharmony_ci		case 99:
49908c2ecf20Sopenharmony_ci		case 83:
49918c2ecf20Sopenharmony_ci		case 163:
49928c2ecf20Sopenharmony_ci		case 147:
49938c2ecf20Sopenharmony_ci		case 227:
49948c2ecf20Sopenharmony_ci		case 211:
49958c2ecf20Sopenharmony_ci			block = "CB_IMMED";
49968c2ecf20Sopenharmony_ci			break;
49978c2ecf20Sopenharmony_ci		case 36:
49988c2ecf20Sopenharmony_ci		case 20:
49998c2ecf20Sopenharmony_ci		case 100:
50008c2ecf20Sopenharmony_ci		case 84:
50018c2ecf20Sopenharmony_ci		case 164:
50028c2ecf20Sopenharmony_ci		case 148:
50038c2ecf20Sopenharmony_ci		case 228:
50048c2ecf20Sopenharmony_ci		case 212:
50058c2ecf20Sopenharmony_ci			block = "DB";
50068c2ecf20Sopenharmony_ci			break;
50078c2ecf20Sopenharmony_ci		case 37:
50088c2ecf20Sopenharmony_ci		case 21:
50098c2ecf20Sopenharmony_ci		case 101:
50108c2ecf20Sopenharmony_ci		case 85:
50118c2ecf20Sopenharmony_ci		case 165:
50128c2ecf20Sopenharmony_ci		case 149:
50138c2ecf20Sopenharmony_ci		case 229:
50148c2ecf20Sopenharmony_ci		case 213:
50158c2ecf20Sopenharmony_ci			block = "DB_HTILE";
50168c2ecf20Sopenharmony_ci			break;
50178c2ecf20Sopenharmony_ci		case 39:
50188c2ecf20Sopenharmony_ci		case 23:
50198c2ecf20Sopenharmony_ci		case 103:
50208c2ecf20Sopenharmony_ci		case 87:
50218c2ecf20Sopenharmony_ci		case 167:
50228c2ecf20Sopenharmony_ci		case 151:
50238c2ecf20Sopenharmony_ci		case 231:
50248c2ecf20Sopenharmony_ci		case 215:
50258c2ecf20Sopenharmony_ci			block = "DB_STEN";
50268c2ecf20Sopenharmony_ci			break;
50278c2ecf20Sopenharmony_ci		case 72:
50288c2ecf20Sopenharmony_ci		case 68:
50298c2ecf20Sopenharmony_ci		case 8:
50308c2ecf20Sopenharmony_ci		case 4:
50318c2ecf20Sopenharmony_ci		case 136:
50328c2ecf20Sopenharmony_ci		case 132:
50338c2ecf20Sopenharmony_ci		case 200:
50348c2ecf20Sopenharmony_ci		case 196:
50358c2ecf20Sopenharmony_ci			block = "TC";
50368c2ecf20Sopenharmony_ci			break;
50378c2ecf20Sopenharmony_ci		case 112:
50388c2ecf20Sopenharmony_ci		case 48:
50398c2ecf20Sopenharmony_ci			block = "CP";
50408c2ecf20Sopenharmony_ci			break;
50418c2ecf20Sopenharmony_ci		case 49:
50428c2ecf20Sopenharmony_ci		case 177:
50438c2ecf20Sopenharmony_ci		case 50:
50448c2ecf20Sopenharmony_ci		case 178:
50458c2ecf20Sopenharmony_ci			block = "SH";
50468c2ecf20Sopenharmony_ci			break;
50478c2ecf20Sopenharmony_ci		case 53:
50488c2ecf20Sopenharmony_ci			block = "VGT";
50498c2ecf20Sopenharmony_ci			break;
50508c2ecf20Sopenharmony_ci		case 117:
50518c2ecf20Sopenharmony_ci			block = "IH";
50528c2ecf20Sopenharmony_ci			break;
50538c2ecf20Sopenharmony_ci		case 51:
50548c2ecf20Sopenharmony_ci		case 115:
50558c2ecf20Sopenharmony_ci			block = "RLC";
50568c2ecf20Sopenharmony_ci			break;
50578c2ecf20Sopenharmony_ci		case 119:
50588c2ecf20Sopenharmony_ci		case 183:
50598c2ecf20Sopenharmony_ci			block = "DMA0";
50608c2ecf20Sopenharmony_ci			break;
50618c2ecf20Sopenharmony_ci		case 61:
50628c2ecf20Sopenharmony_ci			block = "DMA1";
50638c2ecf20Sopenharmony_ci			break;
50648c2ecf20Sopenharmony_ci		case 248:
50658c2ecf20Sopenharmony_ci		case 120:
50668c2ecf20Sopenharmony_ci			block = "HDP";
50678c2ecf20Sopenharmony_ci			break;
50688c2ecf20Sopenharmony_ci		default:
50698c2ecf20Sopenharmony_ci			block = "unknown";
50708c2ecf20Sopenharmony_ci			break;
50718c2ecf20Sopenharmony_ci		}
50728c2ecf20Sopenharmony_ci	}
50738c2ecf20Sopenharmony_ci
50748c2ecf20Sopenharmony_ci	printk("VM fault (0x%02x, vmid %d) at page %u, %s from %s (%d)\n",
50758c2ecf20Sopenharmony_ci	       protections, vmid, addr,
50768c2ecf20Sopenharmony_ci	       (status & MEMORY_CLIENT_RW_MASK) ? "write" : "read",
50778c2ecf20Sopenharmony_ci	       block, mc_id);
50788c2ecf20Sopenharmony_ci}
50798c2ecf20Sopenharmony_ci
50808c2ecf20Sopenharmony_civoid si_vm_flush(struct radeon_device *rdev, struct radeon_ring *ring,
50818c2ecf20Sopenharmony_ci		 unsigned vm_id, uint64_t pd_addr)
50828c2ecf20Sopenharmony_ci{
50838c2ecf20Sopenharmony_ci	/* write new base address */
50848c2ecf20Sopenharmony_ci	radeon_ring_write(ring, PACKET3(PACKET3_WRITE_DATA, 3));
50858c2ecf20Sopenharmony_ci	radeon_ring_write(ring, (WRITE_DATA_ENGINE_SEL(1) |
50868c2ecf20Sopenharmony_ci				 WRITE_DATA_DST_SEL(0)));
50878c2ecf20Sopenharmony_ci
50888c2ecf20Sopenharmony_ci	if (vm_id < 8) {
50898c2ecf20Sopenharmony_ci		radeon_ring_write(ring,
50908c2ecf20Sopenharmony_ci				  (VM_CONTEXT0_PAGE_TABLE_BASE_ADDR + (vm_id << 2)) >> 2);
50918c2ecf20Sopenharmony_ci	} else {
50928c2ecf20Sopenharmony_ci		radeon_ring_write(ring,
50938c2ecf20Sopenharmony_ci				  (VM_CONTEXT8_PAGE_TABLE_BASE_ADDR + ((vm_id - 8) << 2)) >> 2);
50948c2ecf20Sopenharmony_ci	}
50958c2ecf20Sopenharmony_ci	radeon_ring_write(ring, 0);
50968c2ecf20Sopenharmony_ci	radeon_ring_write(ring, pd_addr >> 12);
50978c2ecf20Sopenharmony_ci
50988c2ecf20Sopenharmony_ci	/* flush hdp cache */
50998c2ecf20Sopenharmony_ci	radeon_ring_write(ring, PACKET3(PACKET3_WRITE_DATA, 3));
51008c2ecf20Sopenharmony_ci	radeon_ring_write(ring, (WRITE_DATA_ENGINE_SEL(1) |
51018c2ecf20Sopenharmony_ci				 WRITE_DATA_DST_SEL(0)));
51028c2ecf20Sopenharmony_ci	radeon_ring_write(ring, HDP_MEM_COHERENCY_FLUSH_CNTL >> 2);
51038c2ecf20Sopenharmony_ci	radeon_ring_write(ring, 0);
51048c2ecf20Sopenharmony_ci	radeon_ring_write(ring, 0x1);
51058c2ecf20Sopenharmony_ci
51068c2ecf20Sopenharmony_ci	/* bits 0-15 are the VM contexts0-15 */
51078c2ecf20Sopenharmony_ci	radeon_ring_write(ring, PACKET3(PACKET3_WRITE_DATA, 3));
51088c2ecf20Sopenharmony_ci	radeon_ring_write(ring, (WRITE_DATA_ENGINE_SEL(1) |
51098c2ecf20Sopenharmony_ci				 WRITE_DATA_DST_SEL(0)));
51108c2ecf20Sopenharmony_ci	radeon_ring_write(ring, VM_INVALIDATE_REQUEST >> 2);
51118c2ecf20Sopenharmony_ci	radeon_ring_write(ring, 0);
51128c2ecf20Sopenharmony_ci	radeon_ring_write(ring, 1 << vm_id);
51138c2ecf20Sopenharmony_ci
51148c2ecf20Sopenharmony_ci	/* wait for the invalidate to complete */
51158c2ecf20Sopenharmony_ci	radeon_ring_write(ring, PACKET3(PACKET3_WAIT_REG_MEM, 5));
51168c2ecf20Sopenharmony_ci	radeon_ring_write(ring, (WAIT_REG_MEM_FUNCTION(0) |  /* always */
51178c2ecf20Sopenharmony_ci				 WAIT_REG_MEM_ENGINE(0))); /* me */
51188c2ecf20Sopenharmony_ci	radeon_ring_write(ring, VM_INVALIDATE_REQUEST >> 2);
51198c2ecf20Sopenharmony_ci	radeon_ring_write(ring, 0);
51208c2ecf20Sopenharmony_ci	radeon_ring_write(ring, 0); /* ref */
51218c2ecf20Sopenharmony_ci	radeon_ring_write(ring, 0); /* mask */
51228c2ecf20Sopenharmony_ci	radeon_ring_write(ring, 0x20); /* poll interval */
51238c2ecf20Sopenharmony_ci
51248c2ecf20Sopenharmony_ci	/* sync PFP to ME, otherwise we might get invalid PFP reads */
51258c2ecf20Sopenharmony_ci	radeon_ring_write(ring, PACKET3(PACKET3_PFP_SYNC_ME, 0));
51268c2ecf20Sopenharmony_ci	radeon_ring_write(ring, 0x0);
51278c2ecf20Sopenharmony_ci}
51288c2ecf20Sopenharmony_ci
51298c2ecf20Sopenharmony_ci/*
51308c2ecf20Sopenharmony_ci *  Power and clock gating
51318c2ecf20Sopenharmony_ci */
51328c2ecf20Sopenharmony_cistatic void si_wait_for_rlc_serdes(struct radeon_device *rdev)
51338c2ecf20Sopenharmony_ci{
51348c2ecf20Sopenharmony_ci	int i;
51358c2ecf20Sopenharmony_ci
51368c2ecf20Sopenharmony_ci	for (i = 0; i < rdev->usec_timeout; i++) {
51378c2ecf20Sopenharmony_ci		if (RREG32(RLC_SERDES_MASTER_BUSY_0) == 0)
51388c2ecf20Sopenharmony_ci			break;
51398c2ecf20Sopenharmony_ci		udelay(1);
51408c2ecf20Sopenharmony_ci	}
51418c2ecf20Sopenharmony_ci
51428c2ecf20Sopenharmony_ci	for (i = 0; i < rdev->usec_timeout; i++) {
51438c2ecf20Sopenharmony_ci		if (RREG32(RLC_SERDES_MASTER_BUSY_1) == 0)
51448c2ecf20Sopenharmony_ci			break;
51458c2ecf20Sopenharmony_ci		udelay(1);
51468c2ecf20Sopenharmony_ci	}
51478c2ecf20Sopenharmony_ci}
51488c2ecf20Sopenharmony_ci
51498c2ecf20Sopenharmony_cistatic void si_enable_gui_idle_interrupt(struct radeon_device *rdev,
51508c2ecf20Sopenharmony_ci					 bool enable)
51518c2ecf20Sopenharmony_ci{
51528c2ecf20Sopenharmony_ci	u32 tmp = RREG32(CP_INT_CNTL_RING0);
51538c2ecf20Sopenharmony_ci	u32 mask;
51548c2ecf20Sopenharmony_ci	int i;
51558c2ecf20Sopenharmony_ci
51568c2ecf20Sopenharmony_ci	if (enable)
51578c2ecf20Sopenharmony_ci		tmp |= (CNTX_BUSY_INT_ENABLE | CNTX_EMPTY_INT_ENABLE);
51588c2ecf20Sopenharmony_ci	else
51598c2ecf20Sopenharmony_ci		tmp &= ~(CNTX_BUSY_INT_ENABLE | CNTX_EMPTY_INT_ENABLE);
51608c2ecf20Sopenharmony_ci	WREG32(CP_INT_CNTL_RING0, tmp);
51618c2ecf20Sopenharmony_ci
51628c2ecf20Sopenharmony_ci	if (!enable) {
51638c2ecf20Sopenharmony_ci		/* read a gfx register */
51648c2ecf20Sopenharmony_ci		tmp = RREG32(DB_DEPTH_INFO);
51658c2ecf20Sopenharmony_ci
51668c2ecf20Sopenharmony_ci		mask = RLC_BUSY_STATUS | GFX_POWER_STATUS | GFX_CLOCK_STATUS | GFX_LS_STATUS;
51678c2ecf20Sopenharmony_ci		for (i = 0; i < rdev->usec_timeout; i++) {
51688c2ecf20Sopenharmony_ci			if ((RREG32(RLC_STAT) & mask) == (GFX_CLOCK_STATUS | GFX_POWER_STATUS))
51698c2ecf20Sopenharmony_ci				break;
51708c2ecf20Sopenharmony_ci			udelay(1);
51718c2ecf20Sopenharmony_ci		}
51728c2ecf20Sopenharmony_ci	}
51738c2ecf20Sopenharmony_ci}
51748c2ecf20Sopenharmony_ci
51758c2ecf20Sopenharmony_cistatic void si_set_uvd_dcm(struct radeon_device *rdev,
51768c2ecf20Sopenharmony_ci			   bool sw_mode)
51778c2ecf20Sopenharmony_ci{
51788c2ecf20Sopenharmony_ci	u32 tmp, tmp2;
51798c2ecf20Sopenharmony_ci
51808c2ecf20Sopenharmony_ci	tmp = RREG32(UVD_CGC_CTRL);
51818c2ecf20Sopenharmony_ci	tmp &= ~(CLK_OD_MASK | CG_DT_MASK);
51828c2ecf20Sopenharmony_ci	tmp |= DCM | CG_DT(1) | CLK_OD(4);
51838c2ecf20Sopenharmony_ci
51848c2ecf20Sopenharmony_ci	if (sw_mode) {
51858c2ecf20Sopenharmony_ci		tmp &= ~0x7ffff800;
51868c2ecf20Sopenharmony_ci		tmp2 = DYN_OR_EN | DYN_RR_EN | G_DIV_ID(7);
51878c2ecf20Sopenharmony_ci	} else {
51888c2ecf20Sopenharmony_ci		tmp |= 0x7ffff800;
51898c2ecf20Sopenharmony_ci		tmp2 = 0;
51908c2ecf20Sopenharmony_ci	}
51918c2ecf20Sopenharmony_ci
51928c2ecf20Sopenharmony_ci	WREG32(UVD_CGC_CTRL, tmp);
51938c2ecf20Sopenharmony_ci	WREG32_UVD_CTX(UVD_CGC_CTRL2, tmp2);
51948c2ecf20Sopenharmony_ci}
51958c2ecf20Sopenharmony_ci
51968c2ecf20Sopenharmony_civoid si_init_uvd_internal_cg(struct radeon_device *rdev)
51978c2ecf20Sopenharmony_ci{
51988c2ecf20Sopenharmony_ci	bool hw_mode = true;
51998c2ecf20Sopenharmony_ci
52008c2ecf20Sopenharmony_ci	if (hw_mode) {
52018c2ecf20Sopenharmony_ci		si_set_uvd_dcm(rdev, false);
52028c2ecf20Sopenharmony_ci	} else {
52038c2ecf20Sopenharmony_ci		u32 tmp = RREG32(UVD_CGC_CTRL);
52048c2ecf20Sopenharmony_ci		tmp &= ~DCM;
52058c2ecf20Sopenharmony_ci		WREG32(UVD_CGC_CTRL, tmp);
52068c2ecf20Sopenharmony_ci	}
52078c2ecf20Sopenharmony_ci}
52088c2ecf20Sopenharmony_ci
52098c2ecf20Sopenharmony_cistatic u32 si_halt_rlc(struct radeon_device *rdev)
52108c2ecf20Sopenharmony_ci{
52118c2ecf20Sopenharmony_ci	u32 data, orig;
52128c2ecf20Sopenharmony_ci
52138c2ecf20Sopenharmony_ci	orig = data = RREG32(RLC_CNTL);
52148c2ecf20Sopenharmony_ci
52158c2ecf20Sopenharmony_ci	if (data & RLC_ENABLE) {
52168c2ecf20Sopenharmony_ci		data &= ~RLC_ENABLE;
52178c2ecf20Sopenharmony_ci		WREG32(RLC_CNTL, data);
52188c2ecf20Sopenharmony_ci
52198c2ecf20Sopenharmony_ci		si_wait_for_rlc_serdes(rdev);
52208c2ecf20Sopenharmony_ci	}
52218c2ecf20Sopenharmony_ci
52228c2ecf20Sopenharmony_ci	return orig;
52238c2ecf20Sopenharmony_ci}
52248c2ecf20Sopenharmony_ci
52258c2ecf20Sopenharmony_cistatic void si_update_rlc(struct radeon_device *rdev, u32 rlc)
52268c2ecf20Sopenharmony_ci{
52278c2ecf20Sopenharmony_ci	u32 tmp;
52288c2ecf20Sopenharmony_ci
52298c2ecf20Sopenharmony_ci	tmp = RREG32(RLC_CNTL);
52308c2ecf20Sopenharmony_ci	if (tmp != rlc)
52318c2ecf20Sopenharmony_ci		WREG32(RLC_CNTL, rlc);
52328c2ecf20Sopenharmony_ci}
52338c2ecf20Sopenharmony_ci
52348c2ecf20Sopenharmony_cistatic void si_enable_dma_pg(struct radeon_device *rdev, bool enable)
52358c2ecf20Sopenharmony_ci{
52368c2ecf20Sopenharmony_ci	u32 data, orig;
52378c2ecf20Sopenharmony_ci
52388c2ecf20Sopenharmony_ci	orig = data = RREG32(DMA_PG);
52398c2ecf20Sopenharmony_ci	if (enable && (rdev->pg_flags & RADEON_PG_SUPPORT_SDMA))
52408c2ecf20Sopenharmony_ci		data |= PG_CNTL_ENABLE;
52418c2ecf20Sopenharmony_ci	else
52428c2ecf20Sopenharmony_ci		data &= ~PG_CNTL_ENABLE;
52438c2ecf20Sopenharmony_ci	if (orig != data)
52448c2ecf20Sopenharmony_ci		WREG32(DMA_PG, data);
52458c2ecf20Sopenharmony_ci}
52468c2ecf20Sopenharmony_ci
52478c2ecf20Sopenharmony_cistatic void si_init_dma_pg(struct radeon_device *rdev)
52488c2ecf20Sopenharmony_ci{
52498c2ecf20Sopenharmony_ci	u32 tmp;
52508c2ecf20Sopenharmony_ci
52518c2ecf20Sopenharmony_ci	WREG32(DMA_PGFSM_WRITE,  0x00002000);
52528c2ecf20Sopenharmony_ci	WREG32(DMA_PGFSM_CONFIG, 0x100010ff);
52538c2ecf20Sopenharmony_ci
52548c2ecf20Sopenharmony_ci	for (tmp = 0; tmp < 5; tmp++)
52558c2ecf20Sopenharmony_ci		WREG32(DMA_PGFSM_WRITE, 0);
52568c2ecf20Sopenharmony_ci}
52578c2ecf20Sopenharmony_ci
52588c2ecf20Sopenharmony_cistatic void si_enable_gfx_cgpg(struct radeon_device *rdev,
52598c2ecf20Sopenharmony_ci			       bool enable)
52608c2ecf20Sopenharmony_ci{
52618c2ecf20Sopenharmony_ci	u32 tmp;
52628c2ecf20Sopenharmony_ci
52638c2ecf20Sopenharmony_ci	if (enable && (rdev->pg_flags & RADEON_PG_SUPPORT_GFX_PG)) {
52648c2ecf20Sopenharmony_ci		tmp = RLC_PUD(0x10) | RLC_PDD(0x10) | RLC_TTPD(0x10) | RLC_MSD(0x10);
52658c2ecf20Sopenharmony_ci		WREG32(RLC_TTOP_D, tmp);
52668c2ecf20Sopenharmony_ci
52678c2ecf20Sopenharmony_ci		tmp = RREG32(RLC_PG_CNTL);
52688c2ecf20Sopenharmony_ci		tmp |= GFX_PG_ENABLE;
52698c2ecf20Sopenharmony_ci		WREG32(RLC_PG_CNTL, tmp);
52708c2ecf20Sopenharmony_ci
52718c2ecf20Sopenharmony_ci		tmp = RREG32(RLC_AUTO_PG_CTRL);
52728c2ecf20Sopenharmony_ci		tmp |= AUTO_PG_EN;
52738c2ecf20Sopenharmony_ci		WREG32(RLC_AUTO_PG_CTRL, tmp);
52748c2ecf20Sopenharmony_ci	} else {
52758c2ecf20Sopenharmony_ci		tmp = RREG32(RLC_AUTO_PG_CTRL);
52768c2ecf20Sopenharmony_ci		tmp &= ~AUTO_PG_EN;
52778c2ecf20Sopenharmony_ci		WREG32(RLC_AUTO_PG_CTRL, tmp);
52788c2ecf20Sopenharmony_ci
52798c2ecf20Sopenharmony_ci		tmp = RREG32(DB_RENDER_CONTROL);
52808c2ecf20Sopenharmony_ci	}
52818c2ecf20Sopenharmony_ci}
52828c2ecf20Sopenharmony_ci
52838c2ecf20Sopenharmony_cistatic void si_init_gfx_cgpg(struct radeon_device *rdev)
52848c2ecf20Sopenharmony_ci{
52858c2ecf20Sopenharmony_ci	u32 tmp;
52868c2ecf20Sopenharmony_ci
52878c2ecf20Sopenharmony_ci	WREG32(RLC_SAVE_AND_RESTORE_BASE, rdev->rlc.save_restore_gpu_addr >> 8);
52888c2ecf20Sopenharmony_ci
52898c2ecf20Sopenharmony_ci	tmp = RREG32(RLC_PG_CNTL);
52908c2ecf20Sopenharmony_ci	tmp |= GFX_PG_SRC;
52918c2ecf20Sopenharmony_ci	WREG32(RLC_PG_CNTL, tmp);
52928c2ecf20Sopenharmony_ci
52938c2ecf20Sopenharmony_ci	WREG32(RLC_CLEAR_STATE_RESTORE_BASE, rdev->rlc.clear_state_gpu_addr >> 8);
52948c2ecf20Sopenharmony_ci
52958c2ecf20Sopenharmony_ci	tmp = RREG32(RLC_AUTO_PG_CTRL);
52968c2ecf20Sopenharmony_ci
52978c2ecf20Sopenharmony_ci	tmp &= ~GRBM_REG_SGIT_MASK;
52988c2ecf20Sopenharmony_ci	tmp |= GRBM_REG_SGIT(0x700);
52998c2ecf20Sopenharmony_ci	tmp &= ~PG_AFTER_GRBM_REG_ST_MASK;
53008c2ecf20Sopenharmony_ci	WREG32(RLC_AUTO_PG_CTRL, tmp);
53018c2ecf20Sopenharmony_ci}
53028c2ecf20Sopenharmony_ci
53038c2ecf20Sopenharmony_cistatic u32 si_get_cu_active_bitmap(struct radeon_device *rdev, u32 se, u32 sh)
53048c2ecf20Sopenharmony_ci{
53058c2ecf20Sopenharmony_ci	u32 mask = 0, tmp, tmp1;
53068c2ecf20Sopenharmony_ci	int i;
53078c2ecf20Sopenharmony_ci
53088c2ecf20Sopenharmony_ci	si_select_se_sh(rdev, se, sh);
53098c2ecf20Sopenharmony_ci	tmp = RREG32(CC_GC_SHADER_ARRAY_CONFIG);
53108c2ecf20Sopenharmony_ci	tmp1 = RREG32(GC_USER_SHADER_ARRAY_CONFIG);
53118c2ecf20Sopenharmony_ci	si_select_se_sh(rdev, 0xffffffff, 0xffffffff);
53128c2ecf20Sopenharmony_ci
53138c2ecf20Sopenharmony_ci	tmp &= 0xffff0000;
53148c2ecf20Sopenharmony_ci
53158c2ecf20Sopenharmony_ci	tmp |= tmp1;
53168c2ecf20Sopenharmony_ci	tmp >>= 16;
53178c2ecf20Sopenharmony_ci
53188c2ecf20Sopenharmony_ci	for (i = 0; i < rdev->config.si.max_cu_per_sh; i ++) {
53198c2ecf20Sopenharmony_ci		mask <<= 1;
53208c2ecf20Sopenharmony_ci		mask |= 1;
53218c2ecf20Sopenharmony_ci	}
53228c2ecf20Sopenharmony_ci
53238c2ecf20Sopenharmony_ci	return (~tmp) & mask;
53248c2ecf20Sopenharmony_ci}
53258c2ecf20Sopenharmony_ci
53268c2ecf20Sopenharmony_cistatic void si_init_ao_cu_mask(struct radeon_device *rdev)
53278c2ecf20Sopenharmony_ci{
53288c2ecf20Sopenharmony_ci	u32 i, j, k, active_cu_number = 0;
53298c2ecf20Sopenharmony_ci	u32 mask, counter, cu_bitmap;
53308c2ecf20Sopenharmony_ci	u32 tmp = 0;
53318c2ecf20Sopenharmony_ci
53328c2ecf20Sopenharmony_ci	for (i = 0; i < rdev->config.si.max_shader_engines; i++) {
53338c2ecf20Sopenharmony_ci		for (j = 0; j < rdev->config.si.max_sh_per_se; j++) {
53348c2ecf20Sopenharmony_ci			mask = 1;
53358c2ecf20Sopenharmony_ci			cu_bitmap = 0;
53368c2ecf20Sopenharmony_ci			counter  = 0;
53378c2ecf20Sopenharmony_ci			for (k = 0; k < rdev->config.si.max_cu_per_sh; k++) {
53388c2ecf20Sopenharmony_ci				if (si_get_cu_active_bitmap(rdev, i, j) & mask) {
53398c2ecf20Sopenharmony_ci					if (counter < 2)
53408c2ecf20Sopenharmony_ci						cu_bitmap |= mask;
53418c2ecf20Sopenharmony_ci					counter++;
53428c2ecf20Sopenharmony_ci				}
53438c2ecf20Sopenharmony_ci				mask <<= 1;
53448c2ecf20Sopenharmony_ci			}
53458c2ecf20Sopenharmony_ci
53468c2ecf20Sopenharmony_ci			active_cu_number += counter;
53478c2ecf20Sopenharmony_ci			tmp |= (cu_bitmap << (i * 16 + j * 8));
53488c2ecf20Sopenharmony_ci		}
53498c2ecf20Sopenharmony_ci	}
53508c2ecf20Sopenharmony_ci
53518c2ecf20Sopenharmony_ci	WREG32(RLC_PG_AO_CU_MASK, tmp);
53528c2ecf20Sopenharmony_ci
53538c2ecf20Sopenharmony_ci	tmp = RREG32(RLC_MAX_PG_CU);
53548c2ecf20Sopenharmony_ci	tmp &= ~MAX_PU_CU_MASK;
53558c2ecf20Sopenharmony_ci	tmp |= MAX_PU_CU(active_cu_number);
53568c2ecf20Sopenharmony_ci	WREG32(RLC_MAX_PG_CU, tmp);
53578c2ecf20Sopenharmony_ci}
53588c2ecf20Sopenharmony_ci
53598c2ecf20Sopenharmony_cistatic void si_enable_cgcg(struct radeon_device *rdev,
53608c2ecf20Sopenharmony_ci			   bool enable)
53618c2ecf20Sopenharmony_ci{
53628c2ecf20Sopenharmony_ci	u32 data, orig, tmp;
53638c2ecf20Sopenharmony_ci
53648c2ecf20Sopenharmony_ci	orig = data = RREG32(RLC_CGCG_CGLS_CTRL);
53658c2ecf20Sopenharmony_ci
53668c2ecf20Sopenharmony_ci	if (enable && (rdev->cg_flags & RADEON_CG_SUPPORT_GFX_CGCG)) {
53678c2ecf20Sopenharmony_ci		si_enable_gui_idle_interrupt(rdev, true);
53688c2ecf20Sopenharmony_ci
53698c2ecf20Sopenharmony_ci		WREG32(RLC_GCPM_GENERAL_3, 0x00000080);
53708c2ecf20Sopenharmony_ci
53718c2ecf20Sopenharmony_ci		tmp = si_halt_rlc(rdev);
53728c2ecf20Sopenharmony_ci
53738c2ecf20Sopenharmony_ci		WREG32(RLC_SERDES_WR_MASTER_MASK_0, 0xffffffff);
53748c2ecf20Sopenharmony_ci		WREG32(RLC_SERDES_WR_MASTER_MASK_1, 0xffffffff);
53758c2ecf20Sopenharmony_ci		WREG32(RLC_SERDES_WR_CTRL, 0x00b000ff);
53768c2ecf20Sopenharmony_ci
53778c2ecf20Sopenharmony_ci		si_wait_for_rlc_serdes(rdev);
53788c2ecf20Sopenharmony_ci
53798c2ecf20Sopenharmony_ci		si_update_rlc(rdev, tmp);
53808c2ecf20Sopenharmony_ci
53818c2ecf20Sopenharmony_ci		WREG32(RLC_SERDES_WR_CTRL, 0x007000ff);
53828c2ecf20Sopenharmony_ci
53838c2ecf20Sopenharmony_ci		data |= CGCG_EN | CGLS_EN;
53848c2ecf20Sopenharmony_ci	} else {
53858c2ecf20Sopenharmony_ci		si_enable_gui_idle_interrupt(rdev, false);
53868c2ecf20Sopenharmony_ci
53878c2ecf20Sopenharmony_ci		RREG32(CB_CGTT_SCLK_CTRL);
53888c2ecf20Sopenharmony_ci		RREG32(CB_CGTT_SCLK_CTRL);
53898c2ecf20Sopenharmony_ci		RREG32(CB_CGTT_SCLK_CTRL);
53908c2ecf20Sopenharmony_ci		RREG32(CB_CGTT_SCLK_CTRL);
53918c2ecf20Sopenharmony_ci
53928c2ecf20Sopenharmony_ci		data &= ~(CGCG_EN | CGLS_EN);
53938c2ecf20Sopenharmony_ci	}
53948c2ecf20Sopenharmony_ci
53958c2ecf20Sopenharmony_ci	if (orig != data)
53968c2ecf20Sopenharmony_ci		WREG32(RLC_CGCG_CGLS_CTRL, data);
53978c2ecf20Sopenharmony_ci}
53988c2ecf20Sopenharmony_ci
53998c2ecf20Sopenharmony_cistatic void si_enable_mgcg(struct radeon_device *rdev,
54008c2ecf20Sopenharmony_ci			   bool enable)
54018c2ecf20Sopenharmony_ci{
54028c2ecf20Sopenharmony_ci	u32 data, orig, tmp = 0;
54038c2ecf20Sopenharmony_ci
54048c2ecf20Sopenharmony_ci	if (enable && (rdev->cg_flags & RADEON_CG_SUPPORT_GFX_MGCG)) {
54058c2ecf20Sopenharmony_ci		orig = data = RREG32(CGTS_SM_CTRL_REG);
54068c2ecf20Sopenharmony_ci		data = 0x96940200;
54078c2ecf20Sopenharmony_ci		if (orig != data)
54088c2ecf20Sopenharmony_ci			WREG32(CGTS_SM_CTRL_REG, data);
54098c2ecf20Sopenharmony_ci
54108c2ecf20Sopenharmony_ci		if (rdev->cg_flags & RADEON_CG_SUPPORT_GFX_CP_LS) {
54118c2ecf20Sopenharmony_ci			orig = data = RREG32(CP_MEM_SLP_CNTL);
54128c2ecf20Sopenharmony_ci			data |= CP_MEM_LS_EN;
54138c2ecf20Sopenharmony_ci			if (orig != data)
54148c2ecf20Sopenharmony_ci				WREG32(CP_MEM_SLP_CNTL, data);
54158c2ecf20Sopenharmony_ci		}
54168c2ecf20Sopenharmony_ci
54178c2ecf20Sopenharmony_ci		orig = data = RREG32(RLC_CGTT_MGCG_OVERRIDE);
54188c2ecf20Sopenharmony_ci		data &= 0xffffffc0;
54198c2ecf20Sopenharmony_ci		if (orig != data)
54208c2ecf20Sopenharmony_ci			WREG32(RLC_CGTT_MGCG_OVERRIDE, data);
54218c2ecf20Sopenharmony_ci
54228c2ecf20Sopenharmony_ci		tmp = si_halt_rlc(rdev);
54238c2ecf20Sopenharmony_ci
54248c2ecf20Sopenharmony_ci		WREG32(RLC_SERDES_WR_MASTER_MASK_0, 0xffffffff);
54258c2ecf20Sopenharmony_ci		WREG32(RLC_SERDES_WR_MASTER_MASK_1, 0xffffffff);
54268c2ecf20Sopenharmony_ci		WREG32(RLC_SERDES_WR_CTRL, 0x00d000ff);
54278c2ecf20Sopenharmony_ci
54288c2ecf20Sopenharmony_ci		si_update_rlc(rdev, tmp);
54298c2ecf20Sopenharmony_ci	} else {
54308c2ecf20Sopenharmony_ci		orig = data = RREG32(RLC_CGTT_MGCG_OVERRIDE);
54318c2ecf20Sopenharmony_ci		data |= 0x00000003;
54328c2ecf20Sopenharmony_ci		if (orig != data)
54338c2ecf20Sopenharmony_ci			WREG32(RLC_CGTT_MGCG_OVERRIDE, data);
54348c2ecf20Sopenharmony_ci
54358c2ecf20Sopenharmony_ci		data = RREG32(CP_MEM_SLP_CNTL);
54368c2ecf20Sopenharmony_ci		if (data & CP_MEM_LS_EN) {
54378c2ecf20Sopenharmony_ci			data &= ~CP_MEM_LS_EN;
54388c2ecf20Sopenharmony_ci			WREG32(CP_MEM_SLP_CNTL, data);
54398c2ecf20Sopenharmony_ci		}
54408c2ecf20Sopenharmony_ci		orig = data = RREG32(CGTS_SM_CTRL_REG);
54418c2ecf20Sopenharmony_ci		data |= LS_OVERRIDE | OVERRIDE;
54428c2ecf20Sopenharmony_ci		if (orig != data)
54438c2ecf20Sopenharmony_ci			WREG32(CGTS_SM_CTRL_REG, data);
54448c2ecf20Sopenharmony_ci
54458c2ecf20Sopenharmony_ci		tmp = si_halt_rlc(rdev);
54468c2ecf20Sopenharmony_ci
54478c2ecf20Sopenharmony_ci		WREG32(RLC_SERDES_WR_MASTER_MASK_0, 0xffffffff);
54488c2ecf20Sopenharmony_ci		WREG32(RLC_SERDES_WR_MASTER_MASK_1, 0xffffffff);
54498c2ecf20Sopenharmony_ci		WREG32(RLC_SERDES_WR_CTRL, 0x00e000ff);
54508c2ecf20Sopenharmony_ci
54518c2ecf20Sopenharmony_ci		si_update_rlc(rdev, tmp);
54528c2ecf20Sopenharmony_ci	}
54538c2ecf20Sopenharmony_ci}
54548c2ecf20Sopenharmony_ci
54558c2ecf20Sopenharmony_cistatic void si_enable_uvd_mgcg(struct radeon_device *rdev,
54568c2ecf20Sopenharmony_ci			       bool enable)
54578c2ecf20Sopenharmony_ci{
54588c2ecf20Sopenharmony_ci	u32 orig, data, tmp;
54598c2ecf20Sopenharmony_ci
54608c2ecf20Sopenharmony_ci	if (enable && (rdev->cg_flags & RADEON_CG_SUPPORT_UVD_MGCG)) {
54618c2ecf20Sopenharmony_ci		tmp = RREG32_UVD_CTX(UVD_CGC_MEM_CTRL);
54628c2ecf20Sopenharmony_ci		tmp |= 0x3fff;
54638c2ecf20Sopenharmony_ci		WREG32_UVD_CTX(UVD_CGC_MEM_CTRL, tmp);
54648c2ecf20Sopenharmony_ci
54658c2ecf20Sopenharmony_ci		orig = data = RREG32(UVD_CGC_CTRL);
54668c2ecf20Sopenharmony_ci		data |= DCM;
54678c2ecf20Sopenharmony_ci		if (orig != data)
54688c2ecf20Sopenharmony_ci			WREG32(UVD_CGC_CTRL, data);
54698c2ecf20Sopenharmony_ci
54708c2ecf20Sopenharmony_ci		WREG32_SMC(SMC_CG_IND_START + CG_CGTT_LOCAL_0, 0);
54718c2ecf20Sopenharmony_ci		WREG32_SMC(SMC_CG_IND_START + CG_CGTT_LOCAL_1, 0);
54728c2ecf20Sopenharmony_ci	} else {
54738c2ecf20Sopenharmony_ci		tmp = RREG32_UVD_CTX(UVD_CGC_MEM_CTRL);
54748c2ecf20Sopenharmony_ci		tmp &= ~0x3fff;
54758c2ecf20Sopenharmony_ci		WREG32_UVD_CTX(UVD_CGC_MEM_CTRL, tmp);
54768c2ecf20Sopenharmony_ci
54778c2ecf20Sopenharmony_ci		orig = data = RREG32(UVD_CGC_CTRL);
54788c2ecf20Sopenharmony_ci		data &= ~DCM;
54798c2ecf20Sopenharmony_ci		if (orig != data)
54808c2ecf20Sopenharmony_ci			WREG32(UVD_CGC_CTRL, data);
54818c2ecf20Sopenharmony_ci
54828c2ecf20Sopenharmony_ci		WREG32_SMC(SMC_CG_IND_START + CG_CGTT_LOCAL_0, 0xffffffff);
54838c2ecf20Sopenharmony_ci		WREG32_SMC(SMC_CG_IND_START + CG_CGTT_LOCAL_1, 0xffffffff);
54848c2ecf20Sopenharmony_ci	}
54858c2ecf20Sopenharmony_ci}
54868c2ecf20Sopenharmony_ci
54878c2ecf20Sopenharmony_cistatic const u32 mc_cg_registers[] =
54888c2ecf20Sopenharmony_ci{
54898c2ecf20Sopenharmony_ci	MC_HUB_MISC_HUB_CG,
54908c2ecf20Sopenharmony_ci	MC_HUB_MISC_SIP_CG,
54918c2ecf20Sopenharmony_ci	MC_HUB_MISC_VM_CG,
54928c2ecf20Sopenharmony_ci	MC_XPB_CLK_GAT,
54938c2ecf20Sopenharmony_ci	ATC_MISC_CG,
54948c2ecf20Sopenharmony_ci	MC_CITF_MISC_WR_CG,
54958c2ecf20Sopenharmony_ci	MC_CITF_MISC_RD_CG,
54968c2ecf20Sopenharmony_ci	MC_CITF_MISC_VM_CG,
54978c2ecf20Sopenharmony_ci	VM_L2_CG,
54988c2ecf20Sopenharmony_ci};
54998c2ecf20Sopenharmony_ci
55008c2ecf20Sopenharmony_cistatic void si_enable_mc_ls(struct radeon_device *rdev,
55018c2ecf20Sopenharmony_ci			    bool enable)
55028c2ecf20Sopenharmony_ci{
55038c2ecf20Sopenharmony_ci	int i;
55048c2ecf20Sopenharmony_ci	u32 orig, data;
55058c2ecf20Sopenharmony_ci
55068c2ecf20Sopenharmony_ci	for (i = 0; i < ARRAY_SIZE(mc_cg_registers); i++) {
55078c2ecf20Sopenharmony_ci		orig = data = RREG32(mc_cg_registers[i]);
55088c2ecf20Sopenharmony_ci		if (enable && (rdev->cg_flags & RADEON_CG_SUPPORT_MC_LS))
55098c2ecf20Sopenharmony_ci			data |= MC_LS_ENABLE;
55108c2ecf20Sopenharmony_ci		else
55118c2ecf20Sopenharmony_ci			data &= ~MC_LS_ENABLE;
55128c2ecf20Sopenharmony_ci		if (data != orig)
55138c2ecf20Sopenharmony_ci			WREG32(mc_cg_registers[i], data);
55148c2ecf20Sopenharmony_ci	}
55158c2ecf20Sopenharmony_ci}
55168c2ecf20Sopenharmony_ci
55178c2ecf20Sopenharmony_cistatic void si_enable_mc_mgcg(struct radeon_device *rdev,
55188c2ecf20Sopenharmony_ci			       bool enable)
55198c2ecf20Sopenharmony_ci{
55208c2ecf20Sopenharmony_ci	int i;
55218c2ecf20Sopenharmony_ci	u32 orig, data;
55228c2ecf20Sopenharmony_ci
55238c2ecf20Sopenharmony_ci	for (i = 0; i < ARRAY_SIZE(mc_cg_registers); i++) {
55248c2ecf20Sopenharmony_ci		orig = data = RREG32(mc_cg_registers[i]);
55258c2ecf20Sopenharmony_ci		if (enable && (rdev->cg_flags & RADEON_CG_SUPPORT_MC_MGCG))
55268c2ecf20Sopenharmony_ci			data |= MC_CG_ENABLE;
55278c2ecf20Sopenharmony_ci		else
55288c2ecf20Sopenharmony_ci			data &= ~MC_CG_ENABLE;
55298c2ecf20Sopenharmony_ci		if (data != orig)
55308c2ecf20Sopenharmony_ci			WREG32(mc_cg_registers[i], data);
55318c2ecf20Sopenharmony_ci	}
55328c2ecf20Sopenharmony_ci}
55338c2ecf20Sopenharmony_ci
55348c2ecf20Sopenharmony_cistatic void si_enable_dma_mgcg(struct radeon_device *rdev,
55358c2ecf20Sopenharmony_ci			       bool enable)
55368c2ecf20Sopenharmony_ci{
55378c2ecf20Sopenharmony_ci	u32 orig, data, offset;
55388c2ecf20Sopenharmony_ci	int i;
55398c2ecf20Sopenharmony_ci
55408c2ecf20Sopenharmony_ci	if (enable && (rdev->cg_flags & RADEON_CG_SUPPORT_SDMA_MGCG)) {
55418c2ecf20Sopenharmony_ci		for (i = 0; i < 2; i++) {
55428c2ecf20Sopenharmony_ci			if (i == 0)
55438c2ecf20Sopenharmony_ci				offset = DMA0_REGISTER_OFFSET;
55448c2ecf20Sopenharmony_ci			else
55458c2ecf20Sopenharmony_ci				offset = DMA1_REGISTER_OFFSET;
55468c2ecf20Sopenharmony_ci			orig = data = RREG32(DMA_POWER_CNTL + offset);
55478c2ecf20Sopenharmony_ci			data &= ~MEM_POWER_OVERRIDE;
55488c2ecf20Sopenharmony_ci			if (data != orig)
55498c2ecf20Sopenharmony_ci				WREG32(DMA_POWER_CNTL + offset, data);
55508c2ecf20Sopenharmony_ci			WREG32(DMA_CLK_CTRL + offset, 0x00000100);
55518c2ecf20Sopenharmony_ci		}
55528c2ecf20Sopenharmony_ci	} else {
55538c2ecf20Sopenharmony_ci		for (i = 0; i < 2; i++) {
55548c2ecf20Sopenharmony_ci			if (i == 0)
55558c2ecf20Sopenharmony_ci				offset = DMA0_REGISTER_OFFSET;
55568c2ecf20Sopenharmony_ci			else
55578c2ecf20Sopenharmony_ci				offset = DMA1_REGISTER_OFFSET;
55588c2ecf20Sopenharmony_ci			orig = data = RREG32(DMA_POWER_CNTL + offset);
55598c2ecf20Sopenharmony_ci			data |= MEM_POWER_OVERRIDE;
55608c2ecf20Sopenharmony_ci			if (data != orig)
55618c2ecf20Sopenharmony_ci				WREG32(DMA_POWER_CNTL + offset, data);
55628c2ecf20Sopenharmony_ci
55638c2ecf20Sopenharmony_ci			orig = data = RREG32(DMA_CLK_CTRL + offset);
55648c2ecf20Sopenharmony_ci			data = 0xff000000;
55658c2ecf20Sopenharmony_ci			if (data != orig)
55668c2ecf20Sopenharmony_ci				WREG32(DMA_CLK_CTRL + offset, data);
55678c2ecf20Sopenharmony_ci		}
55688c2ecf20Sopenharmony_ci	}
55698c2ecf20Sopenharmony_ci}
55708c2ecf20Sopenharmony_ci
55718c2ecf20Sopenharmony_cistatic void si_enable_bif_mgls(struct radeon_device *rdev,
55728c2ecf20Sopenharmony_ci			       bool enable)
55738c2ecf20Sopenharmony_ci{
55748c2ecf20Sopenharmony_ci	u32 orig, data;
55758c2ecf20Sopenharmony_ci
55768c2ecf20Sopenharmony_ci	orig = data = RREG32_PCIE(PCIE_CNTL2);
55778c2ecf20Sopenharmony_ci
55788c2ecf20Sopenharmony_ci	if (enable && (rdev->cg_flags & RADEON_CG_SUPPORT_BIF_LS))
55798c2ecf20Sopenharmony_ci		data |= SLV_MEM_LS_EN | MST_MEM_LS_EN |
55808c2ecf20Sopenharmony_ci			REPLAY_MEM_LS_EN | SLV_MEM_AGGRESSIVE_LS_EN;
55818c2ecf20Sopenharmony_ci	else
55828c2ecf20Sopenharmony_ci		data &= ~(SLV_MEM_LS_EN | MST_MEM_LS_EN |
55838c2ecf20Sopenharmony_ci			  REPLAY_MEM_LS_EN | SLV_MEM_AGGRESSIVE_LS_EN);
55848c2ecf20Sopenharmony_ci
55858c2ecf20Sopenharmony_ci	if (orig != data)
55868c2ecf20Sopenharmony_ci		WREG32_PCIE(PCIE_CNTL2, data);
55878c2ecf20Sopenharmony_ci}
55888c2ecf20Sopenharmony_ci
55898c2ecf20Sopenharmony_cistatic void si_enable_hdp_mgcg(struct radeon_device *rdev,
55908c2ecf20Sopenharmony_ci			       bool enable)
55918c2ecf20Sopenharmony_ci{
55928c2ecf20Sopenharmony_ci	u32 orig, data;
55938c2ecf20Sopenharmony_ci
55948c2ecf20Sopenharmony_ci	orig = data = RREG32(HDP_HOST_PATH_CNTL);
55958c2ecf20Sopenharmony_ci
55968c2ecf20Sopenharmony_ci	if (enable && (rdev->cg_flags & RADEON_CG_SUPPORT_HDP_MGCG))
55978c2ecf20Sopenharmony_ci		data &= ~CLOCK_GATING_DIS;
55988c2ecf20Sopenharmony_ci	else
55998c2ecf20Sopenharmony_ci		data |= CLOCK_GATING_DIS;
56008c2ecf20Sopenharmony_ci
56018c2ecf20Sopenharmony_ci	if (orig != data)
56028c2ecf20Sopenharmony_ci		WREG32(HDP_HOST_PATH_CNTL, data);
56038c2ecf20Sopenharmony_ci}
56048c2ecf20Sopenharmony_ci
56058c2ecf20Sopenharmony_cistatic void si_enable_hdp_ls(struct radeon_device *rdev,
56068c2ecf20Sopenharmony_ci			     bool enable)
56078c2ecf20Sopenharmony_ci{
56088c2ecf20Sopenharmony_ci	u32 orig, data;
56098c2ecf20Sopenharmony_ci
56108c2ecf20Sopenharmony_ci	orig = data = RREG32(HDP_MEM_POWER_LS);
56118c2ecf20Sopenharmony_ci
56128c2ecf20Sopenharmony_ci	if (enable && (rdev->cg_flags & RADEON_CG_SUPPORT_HDP_LS))
56138c2ecf20Sopenharmony_ci		data |= HDP_LS_ENABLE;
56148c2ecf20Sopenharmony_ci	else
56158c2ecf20Sopenharmony_ci		data &= ~HDP_LS_ENABLE;
56168c2ecf20Sopenharmony_ci
56178c2ecf20Sopenharmony_ci	if (orig != data)
56188c2ecf20Sopenharmony_ci		WREG32(HDP_MEM_POWER_LS, data);
56198c2ecf20Sopenharmony_ci}
56208c2ecf20Sopenharmony_ci
56218c2ecf20Sopenharmony_cistatic void si_update_cg(struct radeon_device *rdev,
56228c2ecf20Sopenharmony_ci			 u32 block, bool enable)
56238c2ecf20Sopenharmony_ci{
56248c2ecf20Sopenharmony_ci	if (block & RADEON_CG_BLOCK_GFX) {
56258c2ecf20Sopenharmony_ci		si_enable_gui_idle_interrupt(rdev, false);
56268c2ecf20Sopenharmony_ci		/* order matters! */
56278c2ecf20Sopenharmony_ci		if (enable) {
56288c2ecf20Sopenharmony_ci			si_enable_mgcg(rdev, true);
56298c2ecf20Sopenharmony_ci			si_enable_cgcg(rdev, true);
56308c2ecf20Sopenharmony_ci		} else {
56318c2ecf20Sopenharmony_ci			si_enable_cgcg(rdev, false);
56328c2ecf20Sopenharmony_ci			si_enable_mgcg(rdev, false);
56338c2ecf20Sopenharmony_ci		}
56348c2ecf20Sopenharmony_ci		si_enable_gui_idle_interrupt(rdev, true);
56358c2ecf20Sopenharmony_ci	}
56368c2ecf20Sopenharmony_ci
56378c2ecf20Sopenharmony_ci	if (block & RADEON_CG_BLOCK_MC) {
56388c2ecf20Sopenharmony_ci		si_enable_mc_mgcg(rdev, enable);
56398c2ecf20Sopenharmony_ci		si_enable_mc_ls(rdev, enable);
56408c2ecf20Sopenharmony_ci	}
56418c2ecf20Sopenharmony_ci
56428c2ecf20Sopenharmony_ci	if (block & RADEON_CG_BLOCK_SDMA) {
56438c2ecf20Sopenharmony_ci		si_enable_dma_mgcg(rdev, enable);
56448c2ecf20Sopenharmony_ci	}
56458c2ecf20Sopenharmony_ci
56468c2ecf20Sopenharmony_ci	if (block & RADEON_CG_BLOCK_BIF) {
56478c2ecf20Sopenharmony_ci		si_enable_bif_mgls(rdev, enable);
56488c2ecf20Sopenharmony_ci	}
56498c2ecf20Sopenharmony_ci
56508c2ecf20Sopenharmony_ci	if (block & RADEON_CG_BLOCK_UVD) {
56518c2ecf20Sopenharmony_ci		if (rdev->has_uvd) {
56528c2ecf20Sopenharmony_ci			si_enable_uvd_mgcg(rdev, enable);
56538c2ecf20Sopenharmony_ci		}
56548c2ecf20Sopenharmony_ci	}
56558c2ecf20Sopenharmony_ci
56568c2ecf20Sopenharmony_ci	if (block & RADEON_CG_BLOCK_HDP) {
56578c2ecf20Sopenharmony_ci		si_enable_hdp_mgcg(rdev, enable);
56588c2ecf20Sopenharmony_ci		si_enable_hdp_ls(rdev, enable);
56598c2ecf20Sopenharmony_ci	}
56608c2ecf20Sopenharmony_ci}
56618c2ecf20Sopenharmony_ci
56628c2ecf20Sopenharmony_cistatic void si_init_cg(struct radeon_device *rdev)
56638c2ecf20Sopenharmony_ci{
56648c2ecf20Sopenharmony_ci	si_update_cg(rdev, (RADEON_CG_BLOCK_GFX |
56658c2ecf20Sopenharmony_ci			    RADEON_CG_BLOCK_MC |
56668c2ecf20Sopenharmony_ci			    RADEON_CG_BLOCK_SDMA |
56678c2ecf20Sopenharmony_ci			    RADEON_CG_BLOCK_BIF |
56688c2ecf20Sopenharmony_ci			    RADEON_CG_BLOCK_HDP), true);
56698c2ecf20Sopenharmony_ci	if (rdev->has_uvd) {
56708c2ecf20Sopenharmony_ci		si_update_cg(rdev, RADEON_CG_BLOCK_UVD, true);
56718c2ecf20Sopenharmony_ci		si_init_uvd_internal_cg(rdev);
56728c2ecf20Sopenharmony_ci	}
56738c2ecf20Sopenharmony_ci}
56748c2ecf20Sopenharmony_ci
56758c2ecf20Sopenharmony_cistatic void si_fini_cg(struct radeon_device *rdev)
56768c2ecf20Sopenharmony_ci{
56778c2ecf20Sopenharmony_ci	if (rdev->has_uvd) {
56788c2ecf20Sopenharmony_ci		si_update_cg(rdev, RADEON_CG_BLOCK_UVD, false);
56798c2ecf20Sopenharmony_ci	}
56808c2ecf20Sopenharmony_ci	si_update_cg(rdev, (RADEON_CG_BLOCK_GFX |
56818c2ecf20Sopenharmony_ci			    RADEON_CG_BLOCK_MC |
56828c2ecf20Sopenharmony_ci			    RADEON_CG_BLOCK_SDMA |
56838c2ecf20Sopenharmony_ci			    RADEON_CG_BLOCK_BIF |
56848c2ecf20Sopenharmony_ci			    RADEON_CG_BLOCK_HDP), false);
56858c2ecf20Sopenharmony_ci}
56868c2ecf20Sopenharmony_ci
56878c2ecf20Sopenharmony_ciu32 si_get_csb_size(struct radeon_device *rdev)
56888c2ecf20Sopenharmony_ci{
56898c2ecf20Sopenharmony_ci	u32 count = 0;
56908c2ecf20Sopenharmony_ci	const struct cs_section_def *sect = NULL;
56918c2ecf20Sopenharmony_ci	const struct cs_extent_def *ext = NULL;
56928c2ecf20Sopenharmony_ci
56938c2ecf20Sopenharmony_ci	if (rdev->rlc.cs_data == NULL)
56948c2ecf20Sopenharmony_ci		return 0;
56958c2ecf20Sopenharmony_ci
56968c2ecf20Sopenharmony_ci	/* begin clear state */
56978c2ecf20Sopenharmony_ci	count += 2;
56988c2ecf20Sopenharmony_ci	/* context control state */
56998c2ecf20Sopenharmony_ci	count += 3;
57008c2ecf20Sopenharmony_ci
57018c2ecf20Sopenharmony_ci	for (sect = rdev->rlc.cs_data; sect->section != NULL; ++sect) {
57028c2ecf20Sopenharmony_ci		for (ext = sect->section; ext->extent != NULL; ++ext) {
57038c2ecf20Sopenharmony_ci			if (sect->id == SECT_CONTEXT)
57048c2ecf20Sopenharmony_ci				count += 2 + ext->reg_count;
57058c2ecf20Sopenharmony_ci			else
57068c2ecf20Sopenharmony_ci				return 0;
57078c2ecf20Sopenharmony_ci		}
57088c2ecf20Sopenharmony_ci	}
57098c2ecf20Sopenharmony_ci	/* pa_sc_raster_config */
57108c2ecf20Sopenharmony_ci	count += 3;
57118c2ecf20Sopenharmony_ci	/* end clear state */
57128c2ecf20Sopenharmony_ci	count += 2;
57138c2ecf20Sopenharmony_ci	/* clear state */
57148c2ecf20Sopenharmony_ci	count += 2;
57158c2ecf20Sopenharmony_ci
57168c2ecf20Sopenharmony_ci	return count;
57178c2ecf20Sopenharmony_ci}
57188c2ecf20Sopenharmony_ci
57198c2ecf20Sopenharmony_civoid si_get_csb_buffer(struct radeon_device *rdev, volatile u32 *buffer)
57208c2ecf20Sopenharmony_ci{
57218c2ecf20Sopenharmony_ci	u32 count = 0, i;
57228c2ecf20Sopenharmony_ci	const struct cs_section_def *sect = NULL;
57238c2ecf20Sopenharmony_ci	const struct cs_extent_def *ext = NULL;
57248c2ecf20Sopenharmony_ci
57258c2ecf20Sopenharmony_ci	if (rdev->rlc.cs_data == NULL)
57268c2ecf20Sopenharmony_ci		return;
57278c2ecf20Sopenharmony_ci	if (buffer == NULL)
57288c2ecf20Sopenharmony_ci		return;
57298c2ecf20Sopenharmony_ci
57308c2ecf20Sopenharmony_ci	buffer[count++] = cpu_to_le32(PACKET3(PACKET3_PREAMBLE_CNTL, 0));
57318c2ecf20Sopenharmony_ci	buffer[count++] = cpu_to_le32(PACKET3_PREAMBLE_BEGIN_CLEAR_STATE);
57328c2ecf20Sopenharmony_ci
57338c2ecf20Sopenharmony_ci	buffer[count++] = cpu_to_le32(PACKET3(PACKET3_CONTEXT_CONTROL, 1));
57348c2ecf20Sopenharmony_ci	buffer[count++] = cpu_to_le32(0x80000000);
57358c2ecf20Sopenharmony_ci	buffer[count++] = cpu_to_le32(0x80000000);
57368c2ecf20Sopenharmony_ci
57378c2ecf20Sopenharmony_ci	for (sect = rdev->rlc.cs_data; sect->section != NULL; ++sect) {
57388c2ecf20Sopenharmony_ci		for (ext = sect->section; ext->extent != NULL; ++ext) {
57398c2ecf20Sopenharmony_ci			if (sect->id == SECT_CONTEXT) {
57408c2ecf20Sopenharmony_ci				buffer[count++] =
57418c2ecf20Sopenharmony_ci					cpu_to_le32(PACKET3(PACKET3_SET_CONTEXT_REG, ext->reg_count));
57428c2ecf20Sopenharmony_ci				buffer[count++] = cpu_to_le32(ext->reg_index - 0xa000);
57438c2ecf20Sopenharmony_ci				for (i = 0; i < ext->reg_count; i++)
57448c2ecf20Sopenharmony_ci					buffer[count++] = cpu_to_le32(ext->extent[i]);
57458c2ecf20Sopenharmony_ci			} else {
57468c2ecf20Sopenharmony_ci				return;
57478c2ecf20Sopenharmony_ci			}
57488c2ecf20Sopenharmony_ci		}
57498c2ecf20Sopenharmony_ci	}
57508c2ecf20Sopenharmony_ci
57518c2ecf20Sopenharmony_ci	buffer[count++] = cpu_to_le32(PACKET3(PACKET3_SET_CONTEXT_REG, 1));
57528c2ecf20Sopenharmony_ci	buffer[count++] = cpu_to_le32(PA_SC_RASTER_CONFIG - PACKET3_SET_CONTEXT_REG_START);
57538c2ecf20Sopenharmony_ci	switch (rdev->family) {
57548c2ecf20Sopenharmony_ci	case CHIP_TAHITI:
57558c2ecf20Sopenharmony_ci	case CHIP_PITCAIRN:
57568c2ecf20Sopenharmony_ci		buffer[count++] = cpu_to_le32(0x2a00126a);
57578c2ecf20Sopenharmony_ci		break;
57588c2ecf20Sopenharmony_ci	case CHIP_VERDE:
57598c2ecf20Sopenharmony_ci		buffer[count++] = cpu_to_le32(0x0000124a);
57608c2ecf20Sopenharmony_ci		break;
57618c2ecf20Sopenharmony_ci	case CHIP_OLAND:
57628c2ecf20Sopenharmony_ci		buffer[count++] = cpu_to_le32(0x00000082);
57638c2ecf20Sopenharmony_ci		break;
57648c2ecf20Sopenharmony_ci	case CHIP_HAINAN:
57658c2ecf20Sopenharmony_ci		buffer[count++] = cpu_to_le32(0x00000000);
57668c2ecf20Sopenharmony_ci		break;
57678c2ecf20Sopenharmony_ci	default:
57688c2ecf20Sopenharmony_ci		buffer[count++] = cpu_to_le32(0x00000000);
57698c2ecf20Sopenharmony_ci		break;
57708c2ecf20Sopenharmony_ci	}
57718c2ecf20Sopenharmony_ci
57728c2ecf20Sopenharmony_ci	buffer[count++] = cpu_to_le32(PACKET3(PACKET3_PREAMBLE_CNTL, 0));
57738c2ecf20Sopenharmony_ci	buffer[count++] = cpu_to_le32(PACKET3_PREAMBLE_END_CLEAR_STATE);
57748c2ecf20Sopenharmony_ci
57758c2ecf20Sopenharmony_ci	buffer[count++] = cpu_to_le32(PACKET3(PACKET3_CLEAR_STATE, 0));
57768c2ecf20Sopenharmony_ci	buffer[count++] = cpu_to_le32(0);
57778c2ecf20Sopenharmony_ci}
57788c2ecf20Sopenharmony_ci
57798c2ecf20Sopenharmony_cistatic void si_init_pg(struct radeon_device *rdev)
57808c2ecf20Sopenharmony_ci{
57818c2ecf20Sopenharmony_ci	if (rdev->pg_flags) {
57828c2ecf20Sopenharmony_ci		if (rdev->pg_flags & RADEON_PG_SUPPORT_SDMA) {
57838c2ecf20Sopenharmony_ci			si_init_dma_pg(rdev);
57848c2ecf20Sopenharmony_ci		}
57858c2ecf20Sopenharmony_ci		si_init_ao_cu_mask(rdev);
57868c2ecf20Sopenharmony_ci		if (rdev->pg_flags & RADEON_PG_SUPPORT_GFX_PG) {
57878c2ecf20Sopenharmony_ci			si_init_gfx_cgpg(rdev);
57888c2ecf20Sopenharmony_ci		} else {
57898c2ecf20Sopenharmony_ci			WREG32(RLC_SAVE_AND_RESTORE_BASE, rdev->rlc.save_restore_gpu_addr >> 8);
57908c2ecf20Sopenharmony_ci			WREG32(RLC_CLEAR_STATE_RESTORE_BASE, rdev->rlc.clear_state_gpu_addr >> 8);
57918c2ecf20Sopenharmony_ci		}
57928c2ecf20Sopenharmony_ci		si_enable_dma_pg(rdev, true);
57938c2ecf20Sopenharmony_ci		si_enable_gfx_cgpg(rdev, true);
57948c2ecf20Sopenharmony_ci	} else {
57958c2ecf20Sopenharmony_ci		WREG32(RLC_SAVE_AND_RESTORE_BASE, rdev->rlc.save_restore_gpu_addr >> 8);
57968c2ecf20Sopenharmony_ci		WREG32(RLC_CLEAR_STATE_RESTORE_BASE, rdev->rlc.clear_state_gpu_addr >> 8);
57978c2ecf20Sopenharmony_ci	}
57988c2ecf20Sopenharmony_ci}
57998c2ecf20Sopenharmony_ci
58008c2ecf20Sopenharmony_cistatic void si_fini_pg(struct radeon_device *rdev)
58018c2ecf20Sopenharmony_ci{
58028c2ecf20Sopenharmony_ci	if (rdev->pg_flags) {
58038c2ecf20Sopenharmony_ci		si_enable_dma_pg(rdev, false);
58048c2ecf20Sopenharmony_ci		si_enable_gfx_cgpg(rdev, false);
58058c2ecf20Sopenharmony_ci	}
58068c2ecf20Sopenharmony_ci}
58078c2ecf20Sopenharmony_ci
58088c2ecf20Sopenharmony_ci/*
58098c2ecf20Sopenharmony_ci * RLC
58108c2ecf20Sopenharmony_ci */
58118c2ecf20Sopenharmony_civoid si_rlc_reset(struct radeon_device *rdev)
58128c2ecf20Sopenharmony_ci{
58138c2ecf20Sopenharmony_ci	u32 tmp = RREG32(GRBM_SOFT_RESET);
58148c2ecf20Sopenharmony_ci
58158c2ecf20Sopenharmony_ci	tmp |= SOFT_RESET_RLC;
58168c2ecf20Sopenharmony_ci	WREG32(GRBM_SOFT_RESET, tmp);
58178c2ecf20Sopenharmony_ci	udelay(50);
58188c2ecf20Sopenharmony_ci	tmp &= ~SOFT_RESET_RLC;
58198c2ecf20Sopenharmony_ci	WREG32(GRBM_SOFT_RESET, tmp);
58208c2ecf20Sopenharmony_ci	udelay(50);
58218c2ecf20Sopenharmony_ci}
58228c2ecf20Sopenharmony_ci
58238c2ecf20Sopenharmony_cistatic void si_rlc_stop(struct radeon_device *rdev)
58248c2ecf20Sopenharmony_ci{
58258c2ecf20Sopenharmony_ci	WREG32(RLC_CNTL, 0);
58268c2ecf20Sopenharmony_ci
58278c2ecf20Sopenharmony_ci	si_enable_gui_idle_interrupt(rdev, false);
58288c2ecf20Sopenharmony_ci
58298c2ecf20Sopenharmony_ci	si_wait_for_rlc_serdes(rdev);
58308c2ecf20Sopenharmony_ci}
58318c2ecf20Sopenharmony_ci
58328c2ecf20Sopenharmony_cistatic void si_rlc_start(struct radeon_device *rdev)
58338c2ecf20Sopenharmony_ci{
58348c2ecf20Sopenharmony_ci	WREG32(RLC_CNTL, RLC_ENABLE);
58358c2ecf20Sopenharmony_ci
58368c2ecf20Sopenharmony_ci	si_enable_gui_idle_interrupt(rdev, true);
58378c2ecf20Sopenharmony_ci
58388c2ecf20Sopenharmony_ci	udelay(50);
58398c2ecf20Sopenharmony_ci}
58408c2ecf20Sopenharmony_ci
58418c2ecf20Sopenharmony_cistatic bool si_lbpw_supported(struct radeon_device *rdev)
58428c2ecf20Sopenharmony_ci{
58438c2ecf20Sopenharmony_ci	u32 tmp;
58448c2ecf20Sopenharmony_ci
58458c2ecf20Sopenharmony_ci	/* Enable LBPW only for DDR3 */
58468c2ecf20Sopenharmony_ci	tmp = RREG32(MC_SEQ_MISC0);
58478c2ecf20Sopenharmony_ci	if ((tmp & 0xF0000000) == 0xB0000000)
58488c2ecf20Sopenharmony_ci		return true;
58498c2ecf20Sopenharmony_ci	return false;
58508c2ecf20Sopenharmony_ci}
58518c2ecf20Sopenharmony_ci
58528c2ecf20Sopenharmony_cistatic void si_enable_lbpw(struct radeon_device *rdev, bool enable)
58538c2ecf20Sopenharmony_ci{
58548c2ecf20Sopenharmony_ci	u32 tmp;
58558c2ecf20Sopenharmony_ci
58568c2ecf20Sopenharmony_ci	tmp = RREG32(RLC_LB_CNTL);
58578c2ecf20Sopenharmony_ci	if (enable)
58588c2ecf20Sopenharmony_ci		tmp |= LOAD_BALANCE_ENABLE;
58598c2ecf20Sopenharmony_ci	else
58608c2ecf20Sopenharmony_ci		tmp &= ~LOAD_BALANCE_ENABLE;
58618c2ecf20Sopenharmony_ci	WREG32(RLC_LB_CNTL, tmp);
58628c2ecf20Sopenharmony_ci
58638c2ecf20Sopenharmony_ci	if (!enable) {
58648c2ecf20Sopenharmony_ci		si_select_se_sh(rdev, 0xffffffff, 0xffffffff);
58658c2ecf20Sopenharmony_ci		WREG32(SPI_LB_CU_MASK, 0x00ff);
58668c2ecf20Sopenharmony_ci	}
58678c2ecf20Sopenharmony_ci}
58688c2ecf20Sopenharmony_ci
58698c2ecf20Sopenharmony_cistatic int si_rlc_resume(struct radeon_device *rdev)
58708c2ecf20Sopenharmony_ci{
58718c2ecf20Sopenharmony_ci	u32 i;
58728c2ecf20Sopenharmony_ci
58738c2ecf20Sopenharmony_ci	if (!rdev->rlc_fw)
58748c2ecf20Sopenharmony_ci		return -EINVAL;
58758c2ecf20Sopenharmony_ci
58768c2ecf20Sopenharmony_ci	si_rlc_stop(rdev);
58778c2ecf20Sopenharmony_ci
58788c2ecf20Sopenharmony_ci	si_rlc_reset(rdev);
58798c2ecf20Sopenharmony_ci
58808c2ecf20Sopenharmony_ci	si_init_pg(rdev);
58818c2ecf20Sopenharmony_ci
58828c2ecf20Sopenharmony_ci	si_init_cg(rdev);
58838c2ecf20Sopenharmony_ci
58848c2ecf20Sopenharmony_ci	WREG32(RLC_RL_BASE, 0);
58858c2ecf20Sopenharmony_ci	WREG32(RLC_RL_SIZE, 0);
58868c2ecf20Sopenharmony_ci	WREG32(RLC_LB_CNTL, 0);
58878c2ecf20Sopenharmony_ci	WREG32(RLC_LB_CNTR_MAX, 0xffffffff);
58888c2ecf20Sopenharmony_ci	WREG32(RLC_LB_CNTR_INIT, 0);
58898c2ecf20Sopenharmony_ci	WREG32(RLC_LB_INIT_CU_MASK, 0xffffffff);
58908c2ecf20Sopenharmony_ci
58918c2ecf20Sopenharmony_ci	WREG32(RLC_MC_CNTL, 0);
58928c2ecf20Sopenharmony_ci	WREG32(RLC_UCODE_CNTL, 0);
58938c2ecf20Sopenharmony_ci
58948c2ecf20Sopenharmony_ci	if (rdev->new_fw) {
58958c2ecf20Sopenharmony_ci		const struct rlc_firmware_header_v1_0 *hdr =
58968c2ecf20Sopenharmony_ci			(const struct rlc_firmware_header_v1_0 *)rdev->rlc_fw->data;
58978c2ecf20Sopenharmony_ci		u32 fw_size = le32_to_cpu(hdr->header.ucode_size_bytes) / 4;
58988c2ecf20Sopenharmony_ci		const __le32 *fw_data = (const __le32 *)
58998c2ecf20Sopenharmony_ci			(rdev->rlc_fw->data + le32_to_cpu(hdr->header.ucode_array_offset_bytes));
59008c2ecf20Sopenharmony_ci
59018c2ecf20Sopenharmony_ci		radeon_ucode_print_rlc_hdr(&hdr->header);
59028c2ecf20Sopenharmony_ci
59038c2ecf20Sopenharmony_ci		for (i = 0; i < fw_size; i++) {
59048c2ecf20Sopenharmony_ci			WREG32(RLC_UCODE_ADDR, i);
59058c2ecf20Sopenharmony_ci			WREG32(RLC_UCODE_DATA, le32_to_cpup(fw_data++));
59068c2ecf20Sopenharmony_ci		}
59078c2ecf20Sopenharmony_ci	} else {
59088c2ecf20Sopenharmony_ci		const __be32 *fw_data =
59098c2ecf20Sopenharmony_ci			(const __be32 *)rdev->rlc_fw->data;
59108c2ecf20Sopenharmony_ci		for (i = 0; i < SI_RLC_UCODE_SIZE; i++) {
59118c2ecf20Sopenharmony_ci			WREG32(RLC_UCODE_ADDR, i);
59128c2ecf20Sopenharmony_ci			WREG32(RLC_UCODE_DATA, be32_to_cpup(fw_data++));
59138c2ecf20Sopenharmony_ci		}
59148c2ecf20Sopenharmony_ci	}
59158c2ecf20Sopenharmony_ci	WREG32(RLC_UCODE_ADDR, 0);
59168c2ecf20Sopenharmony_ci
59178c2ecf20Sopenharmony_ci	si_enable_lbpw(rdev, si_lbpw_supported(rdev));
59188c2ecf20Sopenharmony_ci
59198c2ecf20Sopenharmony_ci	si_rlc_start(rdev);
59208c2ecf20Sopenharmony_ci
59218c2ecf20Sopenharmony_ci	return 0;
59228c2ecf20Sopenharmony_ci}
59238c2ecf20Sopenharmony_ci
59248c2ecf20Sopenharmony_cistatic void si_enable_interrupts(struct radeon_device *rdev)
59258c2ecf20Sopenharmony_ci{
59268c2ecf20Sopenharmony_ci	u32 ih_cntl = RREG32(IH_CNTL);
59278c2ecf20Sopenharmony_ci	u32 ih_rb_cntl = RREG32(IH_RB_CNTL);
59288c2ecf20Sopenharmony_ci
59298c2ecf20Sopenharmony_ci	ih_cntl |= ENABLE_INTR;
59308c2ecf20Sopenharmony_ci	ih_rb_cntl |= IH_RB_ENABLE;
59318c2ecf20Sopenharmony_ci	WREG32(IH_CNTL, ih_cntl);
59328c2ecf20Sopenharmony_ci	WREG32(IH_RB_CNTL, ih_rb_cntl);
59338c2ecf20Sopenharmony_ci	rdev->ih.enabled = true;
59348c2ecf20Sopenharmony_ci}
59358c2ecf20Sopenharmony_ci
59368c2ecf20Sopenharmony_cistatic void si_disable_interrupts(struct radeon_device *rdev)
59378c2ecf20Sopenharmony_ci{
59388c2ecf20Sopenharmony_ci	u32 ih_rb_cntl = RREG32(IH_RB_CNTL);
59398c2ecf20Sopenharmony_ci	u32 ih_cntl = RREG32(IH_CNTL);
59408c2ecf20Sopenharmony_ci
59418c2ecf20Sopenharmony_ci	ih_rb_cntl &= ~IH_RB_ENABLE;
59428c2ecf20Sopenharmony_ci	ih_cntl &= ~ENABLE_INTR;
59438c2ecf20Sopenharmony_ci	WREG32(IH_RB_CNTL, ih_rb_cntl);
59448c2ecf20Sopenharmony_ci	WREG32(IH_CNTL, ih_cntl);
59458c2ecf20Sopenharmony_ci	/* set rptr, wptr to 0 */
59468c2ecf20Sopenharmony_ci	WREG32(IH_RB_RPTR, 0);
59478c2ecf20Sopenharmony_ci	WREG32(IH_RB_WPTR, 0);
59488c2ecf20Sopenharmony_ci	rdev->ih.enabled = false;
59498c2ecf20Sopenharmony_ci	rdev->ih.rptr = 0;
59508c2ecf20Sopenharmony_ci}
59518c2ecf20Sopenharmony_ci
59528c2ecf20Sopenharmony_cistatic void si_disable_interrupt_state(struct radeon_device *rdev)
59538c2ecf20Sopenharmony_ci{
59548c2ecf20Sopenharmony_ci	int i;
59558c2ecf20Sopenharmony_ci	u32 tmp;
59568c2ecf20Sopenharmony_ci
59578c2ecf20Sopenharmony_ci	tmp = RREG32(CP_INT_CNTL_RING0) &
59588c2ecf20Sopenharmony_ci		(CNTX_BUSY_INT_ENABLE | CNTX_EMPTY_INT_ENABLE);
59598c2ecf20Sopenharmony_ci	WREG32(CP_INT_CNTL_RING0, tmp);
59608c2ecf20Sopenharmony_ci	WREG32(CP_INT_CNTL_RING1, 0);
59618c2ecf20Sopenharmony_ci	WREG32(CP_INT_CNTL_RING2, 0);
59628c2ecf20Sopenharmony_ci	tmp = RREG32(DMA_CNTL + DMA0_REGISTER_OFFSET) & ~TRAP_ENABLE;
59638c2ecf20Sopenharmony_ci	WREG32(DMA_CNTL + DMA0_REGISTER_OFFSET, tmp);
59648c2ecf20Sopenharmony_ci	tmp = RREG32(DMA_CNTL + DMA1_REGISTER_OFFSET) & ~TRAP_ENABLE;
59658c2ecf20Sopenharmony_ci	WREG32(DMA_CNTL + DMA1_REGISTER_OFFSET, tmp);
59668c2ecf20Sopenharmony_ci	WREG32(GRBM_INT_CNTL, 0);
59678c2ecf20Sopenharmony_ci	WREG32(SRBM_INT_CNTL, 0);
59688c2ecf20Sopenharmony_ci	for (i = 0; i < rdev->num_crtc; i++)
59698c2ecf20Sopenharmony_ci		WREG32(INT_MASK + crtc_offsets[i], 0);
59708c2ecf20Sopenharmony_ci	for (i = 0; i < rdev->num_crtc; i++)
59718c2ecf20Sopenharmony_ci		WREG32(GRPH_INT_CONTROL + crtc_offsets[i], 0);
59728c2ecf20Sopenharmony_ci
59738c2ecf20Sopenharmony_ci	if (!ASIC_IS_NODCE(rdev)) {
59748c2ecf20Sopenharmony_ci		WREG32(DAC_AUTODETECT_INT_CONTROL, 0);
59758c2ecf20Sopenharmony_ci
59768c2ecf20Sopenharmony_ci		for (i = 0; i < 6; i++)
59778c2ecf20Sopenharmony_ci			WREG32_AND(DC_HPDx_INT_CONTROL(i),
59788c2ecf20Sopenharmony_ci				   DC_HPDx_INT_POLARITY);
59798c2ecf20Sopenharmony_ci	}
59808c2ecf20Sopenharmony_ci}
59818c2ecf20Sopenharmony_ci
59828c2ecf20Sopenharmony_cistatic int si_irq_init(struct radeon_device *rdev)
59838c2ecf20Sopenharmony_ci{
59848c2ecf20Sopenharmony_ci	int ret = 0;
59858c2ecf20Sopenharmony_ci	int rb_bufsz;
59868c2ecf20Sopenharmony_ci	u32 interrupt_cntl, ih_cntl, ih_rb_cntl;
59878c2ecf20Sopenharmony_ci
59888c2ecf20Sopenharmony_ci	/* allocate ring */
59898c2ecf20Sopenharmony_ci	ret = r600_ih_ring_alloc(rdev);
59908c2ecf20Sopenharmony_ci	if (ret)
59918c2ecf20Sopenharmony_ci		return ret;
59928c2ecf20Sopenharmony_ci
59938c2ecf20Sopenharmony_ci	/* disable irqs */
59948c2ecf20Sopenharmony_ci	si_disable_interrupts(rdev);
59958c2ecf20Sopenharmony_ci
59968c2ecf20Sopenharmony_ci	/* init rlc */
59978c2ecf20Sopenharmony_ci	ret = si_rlc_resume(rdev);
59988c2ecf20Sopenharmony_ci	if (ret) {
59998c2ecf20Sopenharmony_ci		r600_ih_ring_fini(rdev);
60008c2ecf20Sopenharmony_ci		return ret;
60018c2ecf20Sopenharmony_ci	}
60028c2ecf20Sopenharmony_ci
60038c2ecf20Sopenharmony_ci	/* setup interrupt control */
60048c2ecf20Sopenharmony_ci	/* set dummy read address to dummy page address */
60058c2ecf20Sopenharmony_ci	WREG32(INTERRUPT_CNTL2, rdev->dummy_page.addr >> 8);
60068c2ecf20Sopenharmony_ci	interrupt_cntl = RREG32(INTERRUPT_CNTL);
60078c2ecf20Sopenharmony_ci	/* IH_DUMMY_RD_OVERRIDE=0 - dummy read disabled with msi, enabled without msi
60088c2ecf20Sopenharmony_ci	 * IH_DUMMY_RD_OVERRIDE=1 - dummy read controlled by IH_DUMMY_RD_EN
60098c2ecf20Sopenharmony_ci	 */
60108c2ecf20Sopenharmony_ci	interrupt_cntl &= ~IH_DUMMY_RD_OVERRIDE;
60118c2ecf20Sopenharmony_ci	/* IH_REQ_NONSNOOP_EN=1 if ring is in non-cacheable memory, e.g., vram */
60128c2ecf20Sopenharmony_ci	interrupt_cntl &= ~IH_REQ_NONSNOOP_EN;
60138c2ecf20Sopenharmony_ci	WREG32(INTERRUPT_CNTL, interrupt_cntl);
60148c2ecf20Sopenharmony_ci
60158c2ecf20Sopenharmony_ci	WREG32(IH_RB_BASE, rdev->ih.gpu_addr >> 8);
60168c2ecf20Sopenharmony_ci	rb_bufsz = order_base_2(rdev->ih.ring_size / 4);
60178c2ecf20Sopenharmony_ci
60188c2ecf20Sopenharmony_ci	ih_rb_cntl = (IH_WPTR_OVERFLOW_ENABLE |
60198c2ecf20Sopenharmony_ci		      IH_WPTR_OVERFLOW_CLEAR |
60208c2ecf20Sopenharmony_ci		      (rb_bufsz << 1));
60218c2ecf20Sopenharmony_ci
60228c2ecf20Sopenharmony_ci	if (rdev->wb.enabled)
60238c2ecf20Sopenharmony_ci		ih_rb_cntl |= IH_WPTR_WRITEBACK_ENABLE;
60248c2ecf20Sopenharmony_ci
60258c2ecf20Sopenharmony_ci	/* set the writeback address whether it's enabled or not */
60268c2ecf20Sopenharmony_ci	WREG32(IH_RB_WPTR_ADDR_LO, (rdev->wb.gpu_addr + R600_WB_IH_WPTR_OFFSET) & 0xFFFFFFFC);
60278c2ecf20Sopenharmony_ci	WREG32(IH_RB_WPTR_ADDR_HI, upper_32_bits(rdev->wb.gpu_addr + R600_WB_IH_WPTR_OFFSET) & 0xFF);
60288c2ecf20Sopenharmony_ci
60298c2ecf20Sopenharmony_ci	WREG32(IH_RB_CNTL, ih_rb_cntl);
60308c2ecf20Sopenharmony_ci
60318c2ecf20Sopenharmony_ci	/* set rptr, wptr to 0 */
60328c2ecf20Sopenharmony_ci	WREG32(IH_RB_RPTR, 0);
60338c2ecf20Sopenharmony_ci	WREG32(IH_RB_WPTR, 0);
60348c2ecf20Sopenharmony_ci
60358c2ecf20Sopenharmony_ci	/* Default settings for IH_CNTL (disabled at first) */
60368c2ecf20Sopenharmony_ci	ih_cntl = MC_WRREQ_CREDIT(0x10) | MC_WR_CLEAN_CNT(0x10) | MC_VMID(0);
60378c2ecf20Sopenharmony_ci	/* RPTR_REARM only works if msi's are enabled */
60388c2ecf20Sopenharmony_ci	if (rdev->msi_enabled)
60398c2ecf20Sopenharmony_ci		ih_cntl |= RPTR_REARM;
60408c2ecf20Sopenharmony_ci	WREG32(IH_CNTL, ih_cntl);
60418c2ecf20Sopenharmony_ci
60428c2ecf20Sopenharmony_ci	/* force the active interrupt state to all disabled */
60438c2ecf20Sopenharmony_ci	si_disable_interrupt_state(rdev);
60448c2ecf20Sopenharmony_ci
60458c2ecf20Sopenharmony_ci	pci_set_master(rdev->pdev);
60468c2ecf20Sopenharmony_ci
60478c2ecf20Sopenharmony_ci	/* enable irqs */
60488c2ecf20Sopenharmony_ci	si_enable_interrupts(rdev);
60498c2ecf20Sopenharmony_ci
60508c2ecf20Sopenharmony_ci	return ret;
60518c2ecf20Sopenharmony_ci}
60528c2ecf20Sopenharmony_ci
60538c2ecf20Sopenharmony_ci/* The order we write back each register here is important */
60548c2ecf20Sopenharmony_ciint si_irq_set(struct radeon_device *rdev)
60558c2ecf20Sopenharmony_ci{
60568c2ecf20Sopenharmony_ci	int i;
60578c2ecf20Sopenharmony_ci	u32 cp_int_cntl;
60588c2ecf20Sopenharmony_ci	u32 cp_int_cntl1 = 0, cp_int_cntl2 = 0;
60598c2ecf20Sopenharmony_ci	u32 grbm_int_cntl = 0;
60608c2ecf20Sopenharmony_ci	u32 dma_cntl, dma_cntl1;
60618c2ecf20Sopenharmony_ci	u32 thermal_int = 0;
60628c2ecf20Sopenharmony_ci
60638c2ecf20Sopenharmony_ci	if (!rdev->irq.installed) {
60648c2ecf20Sopenharmony_ci		WARN(1, "Can't enable IRQ/MSI because no handler is installed\n");
60658c2ecf20Sopenharmony_ci		return -EINVAL;
60668c2ecf20Sopenharmony_ci	}
60678c2ecf20Sopenharmony_ci	/* don't enable anything if the ih is disabled */
60688c2ecf20Sopenharmony_ci	if (!rdev->ih.enabled) {
60698c2ecf20Sopenharmony_ci		si_disable_interrupts(rdev);
60708c2ecf20Sopenharmony_ci		/* force the active interrupt state to all disabled */
60718c2ecf20Sopenharmony_ci		si_disable_interrupt_state(rdev);
60728c2ecf20Sopenharmony_ci		return 0;
60738c2ecf20Sopenharmony_ci	}
60748c2ecf20Sopenharmony_ci
60758c2ecf20Sopenharmony_ci	cp_int_cntl = RREG32(CP_INT_CNTL_RING0) &
60768c2ecf20Sopenharmony_ci		(CNTX_BUSY_INT_ENABLE | CNTX_EMPTY_INT_ENABLE);
60778c2ecf20Sopenharmony_ci
60788c2ecf20Sopenharmony_ci	dma_cntl = RREG32(DMA_CNTL + DMA0_REGISTER_OFFSET) & ~TRAP_ENABLE;
60798c2ecf20Sopenharmony_ci	dma_cntl1 = RREG32(DMA_CNTL + DMA1_REGISTER_OFFSET) & ~TRAP_ENABLE;
60808c2ecf20Sopenharmony_ci
60818c2ecf20Sopenharmony_ci	thermal_int = RREG32(CG_THERMAL_INT) &
60828c2ecf20Sopenharmony_ci		~(THERM_INT_MASK_HIGH | THERM_INT_MASK_LOW);
60838c2ecf20Sopenharmony_ci
60848c2ecf20Sopenharmony_ci	/* enable CP interrupts on all rings */
60858c2ecf20Sopenharmony_ci	if (atomic_read(&rdev->irq.ring_int[RADEON_RING_TYPE_GFX_INDEX])) {
60868c2ecf20Sopenharmony_ci		DRM_DEBUG("si_irq_set: sw int gfx\n");
60878c2ecf20Sopenharmony_ci		cp_int_cntl |= TIME_STAMP_INT_ENABLE;
60888c2ecf20Sopenharmony_ci	}
60898c2ecf20Sopenharmony_ci	if (atomic_read(&rdev->irq.ring_int[CAYMAN_RING_TYPE_CP1_INDEX])) {
60908c2ecf20Sopenharmony_ci		DRM_DEBUG("si_irq_set: sw int cp1\n");
60918c2ecf20Sopenharmony_ci		cp_int_cntl1 |= TIME_STAMP_INT_ENABLE;
60928c2ecf20Sopenharmony_ci	}
60938c2ecf20Sopenharmony_ci	if (atomic_read(&rdev->irq.ring_int[CAYMAN_RING_TYPE_CP2_INDEX])) {
60948c2ecf20Sopenharmony_ci		DRM_DEBUG("si_irq_set: sw int cp2\n");
60958c2ecf20Sopenharmony_ci		cp_int_cntl2 |= TIME_STAMP_INT_ENABLE;
60968c2ecf20Sopenharmony_ci	}
60978c2ecf20Sopenharmony_ci	if (atomic_read(&rdev->irq.ring_int[R600_RING_TYPE_DMA_INDEX])) {
60988c2ecf20Sopenharmony_ci		DRM_DEBUG("si_irq_set: sw int dma\n");
60998c2ecf20Sopenharmony_ci		dma_cntl |= TRAP_ENABLE;
61008c2ecf20Sopenharmony_ci	}
61018c2ecf20Sopenharmony_ci
61028c2ecf20Sopenharmony_ci	if (atomic_read(&rdev->irq.ring_int[CAYMAN_RING_TYPE_DMA1_INDEX])) {
61038c2ecf20Sopenharmony_ci		DRM_DEBUG("si_irq_set: sw int dma1\n");
61048c2ecf20Sopenharmony_ci		dma_cntl1 |= TRAP_ENABLE;
61058c2ecf20Sopenharmony_ci	}
61068c2ecf20Sopenharmony_ci
61078c2ecf20Sopenharmony_ci	WREG32(CP_INT_CNTL_RING0, cp_int_cntl);
61088c2ecf20Sopenharmony_ci	WREG32(CP_INT_CNTL_RING1, cp_int_cntl1);
61098c2ecf20Sopenharmony_ci	WREG32(CP_INT_CNTL_RING2, cp_int_cntl2);
61108c2ecf20Sopenharmony_ci
61118c2ecf20Sopenharmony_ci	WREG32(DMA_CNTL + DMA0_REGISTER_OFFSET, dma_cntl);
61128c2ecf20Sopenharmony_ci	WREG32(DMA_CNTL + DMA1_REGISTER_OFFSET, dma_cntl1);
61138c2ecf20Sopenharmony_ci
61148c2ecf20Sopenharmony_ci	WREG32(GRBM_INT_CNTL, grbm_int_cntl);
61158c2ecf20Sopenharmony_ci
61168c2ecf20Sopenharmony_ci	if (rdev->irq.dpm_thermal) {
61178c2ecf20Sopenharmony_ci		DRM_DEBUG("dpm thermal\n");
61188c2ecf20Sopenharmony_ci		thermal_int |= THERM_INT_MASK_HIGH | THERM_INT_MASK_LOW;
61198c2ecf20Sopenharmony_ci	}
61208c2ecf20Sopenharmony_ci
61218c2ecf20Sopenharmony_ci	for (i = 0; i < rdev->num_crtc; i++) {
61228c2ecf20Sopenharmony_ci		radeon_irq_kms_set_irq_n_enabled(
61238c2ecf20Sopenharmony_ci		    rdev, INT_MASK + crtc_offsets[i], VBLANK_INT_MASK,
61248c2ecf20Sopenharmony_ci		    rdev->irq.crtc_vblank_int[i] ||
61258c2ecf20Sopenharmony_ci		    atomic_read(&rdev->irq.pflip[i]), "vblank", i);
61268c2ecf20Sopenharmony_ci	}
61278c2ecf20Sopenharmony_ci
61288c2ecf20Sopenharmony_ci	for (i = 0; i < rdev->num_crtc; i++)
61298c2ecf20Sopenharmony_ci		WREG32(GRPH_INT_CONTROL + crtc_offsets[i], GRPH_PFLIP_INT_MASK);
61308c2ecf20Sopenharmony_ci
61318c2ecf20Sopenharmony_ci	if (!ASIC_IS_NODCE(rdev)) {
61328c2ecf20Sopenharmony_ci		for (i = 0; i < 6; i++) {
61338c2ecf20Sopenharmony_ci			radeon_irq_kms_set_irq_n_enabled(
61348c2ecf20Sopenharmony_ci			    rdev, DC_HPDx_INT_CONTROL(i),
61358c2ecf20Sopenharmony_ci			    DC_HPDx_INT_EN | DC_HPDx_RX_INT_EN,
61368c2ecf20Sopenharmony_ci			    rdev->irq.hpd[i], "HPD", i);
61378c2ecf20Sopenharmony_ci		}
61388c2ecf20Sopenharmony_ci	}
61398c2ecf20Sopenharmony_ci
61408c2ecf20Sopenharmony_ci	WREG32(CG_THERMAL_INT, thermal_int);
61418c2ecf20Sopenharmony_ci
61428c2ecf20Sopenharmony_ci	/* posting read */
61438c2ecf20Sopenharmony_ci	RREG32(SRBM_STATUS);
61448c2ecf20Sopenharmony_ci
61458c2ecf20Sopenharmony_ci	return 0;
61468c2ecf20Sopenharmony_ci}
61478c2ecf20Sopenharmony_ci
61488c2ecf20Sopenharmony_ci/* The order we write back each register here is important */
61498c2ecf20Sopenharmony_cistatic inline void si_irq_ack(struct radeon_device *rdev)
61508c2ecf20Sopenharmony_ci{
61518c2ecf20Sopenharmony_ci	int i, j;
61528c2ecf20Sopenharmony_ci	u32 *disp_int = rdev->irq.stat_regs.evergreen.disp_int;
61538c2ecf20Sopenharmony_ci	u32 *grph_int = rdev->irq.stat_regs.evergreen.grph_int;
61548c2ecf20Sopenharmony_ci
61558c2ecf20Sopenharmony_ci	if (ASIC_IS_NODCE(rdev))
61568c2ecf20Sopenharmony_ci		return;
61578c2ecf20Sopenharmony_ci
61588c2ecf20Sopenharmony_ci	for (i = 0; i < 6; i++) {
61598c2ecf20Sopenharmony_ci		disp_int[i] = RREG32(si_disp_int_status[i]);
61608c2ecf20Sopenharmony_ci		if (i < rdev->num_crtc)
61618c2ecf20Sopenharmony_ci			grph_int[i] = RREG32(GRPH_INT_STATUS + crtc_offsets[i]);
61628c2ecf20Sopenharmony_ci	}
61638c2ecf20Sopenharmony_ci
61648c2ecf20Sopenharmony_ci	/* We write back each interrupt register in pairs of two */
61658c2ecf20Sopenharmony_ci	for (i = 0; i < rdev->num_crtc; i += 2) {
61668c2ecf20Sopenharmony_ci		for (j = i; j < (i + 2); j++) {
61678c2ecf20Sopenharmony_ci			if (grph_int[j] & GRPH_PFLIP_INT_OCCURRED)
61688c2ecf20Sopenharmony_ci				WREG32(GRPH_INT_STATUS + crtc_offsets[j],
61698c2ecf20Sopenharmony_ci				       GRPH_PFLIP_INT_CLEAR);
61708c2ecf20Sopenharmony_ci		}
61718c2ecf20Sopenharmony_ci
61728c2ecf20Sopenharmony_ci		for (j = i; j < (i + 2); j++) {
61738c2ecf20Sopenharmony_ci			if (disp_int[j] & LB_D1_VBLANK_INTERRUPT)
61748c2ecf20Sopenharmony_ci				WREG32(VBLANK_STATUS + crtc_offsets[j],
61758c2ecf20Sopenharmony_ci				       VBLANK_ACK);
61768c2ecf20Sopenharmony_ci			if (disp_int[j] & LB_D1_VLINE_INTERRUPT)
61778c2ecf20Sopenharmony_ci				WREG32(VLINE_STATUS + crtc_offsets[j],
61788c2ecf20Sopenharmony_ci				       VLINE_ACK);
61798c2ecf20Sopenharmony_ci		}
61808c2ecf20Sopenharmony_ci	}
61818c2ecf20Sopenharmony_ci
61828c2ecf20Sopenharmony_ci	for (i = 0; i < 6; i++) {
61838c2ecf20Sopenharmony_ci		if (disp_int[i] & DC_HPD1_INTERRUPT)
61848c2ecf20Sopenharmony_ci			WREG32_OR(DC_HPDx_INT_CONTROL(i), DC_HPDx_INT_ACK);
61858c2ecf20Sopenharmony_ci	}
61868c2ecf20Sopenharmony_ci
61878c2ecf20Sopenharmony_ci	for (i = 0; i < 6; i++) {
61888c2ecf20Sopenharmony_ci		if (disp_int[i] & DC_HPD1_RX_INTERRUPT)
61898c2ecf20Sopenharmony_ci			WREG32_OR(DC_HPDx_INT_CONTROL(i), DC_HPDx_RX_INT_ACK);
61908c2ecf20Sopenharmony_ci	}
61918c2ecf20Sopenharmony_ci}
61928c2ecf20Sopenharmony_ci
61938c2ecf20Sopenharmony_cistatic void si_irq_disable(struct radeon_device *rdev)
61948c2ecf20Sopenharmony_ci{
61958c2ecf20Sopenharmony_ci	si_disable_interrupts(rdev);
61968c2ecf20Sopenharmony_ci	/* Wait and acknowledge irq */
61978c2ecf20Sopenharmony_ci	mdelay(1);
61988c2ecf20Sopenharmony_ci	si_irq_ack(rdev);
61998c2ecf20Sopenharmony_ci	si_disable_interrupt_state(rdev);
62008c2ecf20Sopenharmony_ci}
62018c2ecf20Sopenharmony_ci
62028c2ecf20Sopenharmony_cistatic void si_irq_suspend(struct radeon_device *rdev)
62038c2ecf20Sopenharmony_ci{
62048c2ecf20Sopenharmony_ci	si_irq_disable(rdev);
62058c2ecf20Sopenharmony_ci	si_rlc_stop(rdev);
62068c2ecf20Sopenharmony_ci}
62078c2ecf20Sopenharmony_ci
62088c2ecf20Sopenharmony_cistatic void si_irq_fini(struct radeon_device *rdev)
62098c2ecf20Sopenharmony_ci{
62108c2ecf20Sopenharmony_ci	si_irq_suspend(rdev);
62118c2ecf20Sopenharmony_ci	r600_ih_ring_fini(rdev);
62128c2ecf20Sopenharmony_ci}
62138c2ecf20Sopenharmony_ci
62148c2ecf20Sopenharmony_cistatic inline u32 si_get_ih_wptr(struct radeon_device *rdev)
62158c2ecf20Sopenharmony_ci{
62168c2ecf20Sopenharmony_ci	u32 wptr, tmp;
62178c2ecf20Sopenharmony_ci
62188c2ecf20Sopenharmony_ci	if (rdev->wb.enabled)
62198c2ecf20Sopenharmony_ci		wptr = le32_to_cpu(rdev->wb.wb[R600_WB_IH_WPTR_OFFSET/4]);
62208c2ecf20Sopenharmony_ci	else
62218c2ecf20Sopenharmony_ci		wptr = RREG32(IH_RB_WPTR);
62228c2ecf20Sopenharmony_ci
62238c2ecf20Sopenharmony_ci	if (wptr & RB_OVERFLOW) {
62248c2ecf20Sopenharmony_ci		wptr &= ~RB_OVERFLOW;
62258c2ecf20Sopenharmony_ci		/* When a ring buffer overflow happen start parsing interrupt
62268c2ecf20Sopenharmony_ci		 * from the last not overwritten vector (wptr + 16). Hopefully
62278c2ecf20Sopenharmony_ci		 * this should allow us to catchup.
62288c2ecf20Sopenharmony_ci		 */
62298c2ecf20Sopenharmony_ci		dev_warn(rdev->dev, "IH ring buffer overflow (0x%08X, 0x%08X, 0x%08X)\n",
62308c2ecf20Sopenharmony_ci			 wptr, rdev->ih.rptr, (wptr + 16) & rdev->ih.ptr_mask);
62318c2ecf20Sopenharmony_ci		rdev->ih.rptr = (wptr + 16) & rdev->ih.ptr_mask;
62328c2ecf20Sopenharmony_ci		tmp = RREG32(IH_RB_CNTL);
62338c2ecf20Sopenharmony_ci		tmp |= IH_WPTR_OVERFLOW_CLEAR;
62348c2ecf20Sopenharmony_ci		WREG32(IH_RB_CNTL, tmp);
62358c2ecf20Sopenharmony_ci	}
62368c2ecf20Sopenharmony_ci	return (wptr & rdev->ih.ptr_mask);
62378c2ecf20Sopenharmony_ci}
62388c2ecf20Sopenharmony_ci
62398c2ecf20Sopenharmony_ci/*        SI IV Ring
62408c2ecf20Sopenharmony_ci * Each IV ring entry is 128 bits:
62418c2ecf20Sopenharmony_ci * [7:0]    - interrupt source id
62428c2ecf20Sopenharmony_ci * [31:8]   - reserved
62438c2ecf20Sopenharmony_ci * [59:32]  - interrupt source data
62448c2ecf20Sopenharmony_ci * [63:60]  - reserved
62458c2ecf20Sopenharmony_ci * [71:64]  - RINGID
62468c2ecf20Sopenharmony_ci * [79:72]  - VMID
62478c2ecf20Sopenharmony_ci * [127:80] - reserved
62488c2ecf20Sopenharmony_ci */
62498c2ecf20Sopenharmony_ciint si_irq_process(struct radeon_device *rdev)
62508c2ecf20Sopenharmony_ci{
62518c2ecf20Sopenharmony_ci	u32 *disp_int = rdev->irq.stat_regs.evergreen.disp_int;
62528c2ecf20Sopenharmony_ci	u32 crtc_idx, hpd_idx;
62538c2ecf20Sopenharmony_ci	u32 mask;
62548c2ecf20Sopenharmony_ci	u32 wptr;
62558c2ecf20Sopenharmony_ci	u32 rptr;
62568c2ecf20Sopenharmony_ci	u32 src_id, src_data, ring_id;
62578c2ecf20Sopenharmony_ci	u32 ring_index;
62588c2ecf20Sopenharmony_ci	bool queue_hotplug = false;
62598c2ecf20Sopenharmony_ci	bool queue_dp = false;
62608c2ecf20Sopenharmony_ci	bool queue_thermal = false;
62618c2ecf20Sopenharmony_ci	u32 status, addr;
62628c2ecf20Sopenharmony_ci	const char *event_name;
62638c2ecf20Sopenharmony_ci
62648c2ecf20Sopenharmony_ci	if (!rdev->ih.enabled || rdev->shutdown)
62658c2ecf20Sopenharmony_ci		return IRQ_NONE;
62668c2ecf20Sopenharmony_ci
62678c2ecf20Sopenharmony_ci	wptr = si_get_ih_wptr(rdev);
62688c2ecf20Sopenharmony_ci
62698c2ecf20Sopenharmony_cirestart_ih:
62708c2ecf20Sopenharmony_ci	/* is somebody else already processing irqs? */
62718c2ecf20Sopenharmony_ci	if (atomic_xchg(&rdev->ih.lock, 1))
62728c2ecf20Sopenharmony_ci		return IRQ_NONE;
62738c2ecf20Sopenharmony_ci
62748c2ecf20Sopenharmony_ci	rptr = rdev->ih.rptr;
62758c2ecf20Sopenharmony_ci	DRM_DEBUG("si_irq_process start: rptr %d, wptr %d\n", rptr, wptr);
62768c2ecf20Sopenharmony_ci
62778c2ecf20Sopenharmony_ci	/* Order reading of wptr vs. reading of IH ring data */
62788c2ecf20Sopenharmony_ci	rmb();
62798c2ecf20Sopenharmony_ci
62808c2ecf20Sopenharmony_ci	/* display interrupts */
62818c2ecf20Sopenharmony_ci	si_irq_ack(rdev);
62828c2ecf20Sopenharmony_ci
62838c2ecf20Sopenharmony_ci	while (rptr != wptr) {
62848c2ecf20Sopenharmony_ci		/* wptr/rptr are in bytes! */
62858c2ecf20Sopenharmony_ci		ring_index = rptr / 4;
62868c2ecf20Sopenharmony_ci		src_id =  le32_to_cpu(rdev->ih.ring[ring_index]) & 0xff;
62878c2ecf20Sopenharmony_ci		src_data = le32_to_cpu(rdev->ih.ring[ring_index + 1]) & 0xfffffff;
62888c2ecf20Sopenharmony_ci		ring_id = le32_to_cpu(rdev->ih.ring[ring_index + 2]) & 0xff;
62898c2ecf20Sopenharmony_ci
62908c2ecf20Sopenharmony_ci		switch (src_id) {
62918c2ecf20Sopenharmony_ci		case 1: /* D1 vblank/vline */
62928c2ecf20Sopenharmony_ci		case 2: /* D2 vblank/vline */
62938c2ecf20Sopenharmony_ci		case 3: /* D3 vblank/vline */
62948c2ecf20Sopenharmony_ci		case 4: /* D4 vblank/vline */
62958c2ecf20Sopenharmony_ci		case 5: /* D5 vblank/vline */
62968c2ecf20Sopenharmony_ci		case 6: /* D6 vblank/vline */
62978c2ecf20Sopenharmony_ci			crtc_idx = src_id - 1;
62988c2ecf20Sopenharmony_ci
62998c2ecf20Sopenharmony_ci			if (src_data == 0) { /* vblank */
63008c2ecf20Sopenharmony_ci				mask = LB_D1_VBLANK_INTERRUPT;
63018c2ecf20Sopenharmony_ci				event_name = "vblank";
63028c2ecf20Sopenharmony_ci
63038c2ecf20Sopenharmony_ci				if (rdev->irq.crtc_vblank_int[crtc_idx]) {
63048c2ecf20Sopenharmony_ci					drm_handle_vblank(rdev->ddev, crtc_idx);
63058c2ecf20Sopenharmony_ci					rdev->pm.vblank_sync = true;
63068c2ecf20Sopenharmony_ci					wake_up(&rdev->irq.vblank_queue);
63078c2ecf20Sopenharmony_ci				}
63088c2ecf20Sopenharmony_ci				if (atomic_read(&rdev->irq.pflip[crtc_idx])) {
63098c2ecf20Sopenharmony_ci					radeon_crtc_handle_vblank(rdev,
63108c2ecf20Sopenharmony_ci								  crtc_idx);
63118c2ecf20Sopenharmony_ci				}
63128c2ecf20Sopenharmony_ci
63138c2ecf20Sopenharmony_ci			} else if (src_data == 1) { /* vline */
63148c2ecf20Sopenharmony_ci				mask = LB_D1_VLINE_INTERRUPT;
63158c2ecf20Sopenharmony_ci				event_name = "vline";
63168c2ecf20Sopenharmony_ci			} else {
63178c2ecf20Sopenharmony_ci				DRM_DEBUG("Unhandled interrupt: %d %d\n",
63188c2ecf20Sopenharmony_ci					  src_id, src_data);
63198c2ecf20Sopenharmony_ci				break;
63208c2ecf20Sopenharmony_ci			}
63218c2ecf20Sopenharmony_ci
63228c2ecf20Sopenharmony_ci			if (!(disp_int[crtc_idx] & mask)) {
63238c2ecf20Sopenharmony_ci				DRM_DEBUG("IH: D%d %s - IH event w/o asserted irq bit?\n",
63248c2ecf20Sopenharmony_ci					  crtc_idx + 1, event_name);
63258c2ecf20Sopenharmony_ci			}
63268c2ecf20Sopenharmony_ci
63278c2ecf20Sopenharmony_ci			disp_int[crtc_idx] &= ~mask;
63288c2ecf20Sopenharmony_ci			DRM_DEBUG("IH: D%d %s\n", crtc_idx + 1, event_name);
63298c2ecf20Sopenharmony_ci
63308c2ecf20Sopenharmony_ci			break;
63318c2ecf20Sopenharmony_ci		case 8: /* D1 page flip */
63328c2ecf20Sopenharmony_ci		case 10: /* D2 page flip */
63338c2ecf20Sopenharmony_ci		case 12: /* D3 page flip */
63348c2ecf20Sopenharmony_ci		case 14: /* D4 page flip */
63358c2ecf20Sopenharmony_ci		case 16: /* D5 page flip */
63368c2ecf20Sopenharmony_ci		case 18: /* D6 page flip */
63378c2ecf20Sopenharmony_ci			DRM_DEBUG("IH: D%d flip\n", ((src_id - 8) >> 1) + 1);
63388c2ecf20Sopenharmony_ci			if (radeon_use_pflipirq > 0)
63398c2ecf20Sopenharmony_ci				radeon_crtc_handle_flip(rdev, (src_id - 8) >> 1);
63408c2ecf20Sopenharmony_ci			break;
63418c2ecf20Sopenharmony_ci		case 42: /* HPD hotplug */
63428c2ecf20Sopenharmony_ci			if (src_data <= 5) {
63438c2ecf20Sopenharmony_ci				hpd_idx = src_data;
63448c2ecf20Sopenharmony_ci				mask = DC_HPD1_INTERRUPT;
63458c2ecf20Sopenharmony_ci				queue_hotplug = true;
63468c2ecf20Sopenharmony_ci				event_name = "HPD";
63478c2ecf20Sopenharmony_ci
63488c2ecf20Sopenharmony_ci			} else if (src_data <= 11) {
63498c2ecf20Sopenharmony_ci				hpd_idx = src_data - 6;
63508c2ecf20Sopenharmony_ci				mask = DC_HPD1_RX_INTERRUPT;
63518c2ecf20Sopenharmony_ci				queue_dp = true;
63528c2ecf20Sopenharmony_ci				event_name = "HPD_RX";
63538c2ecf20Sopenharmony_ci
63548c2ecf20Sopenharmony_ci			} else {
63558c2ecf20Sopenharmony_ci				DRM_DEBUG("Unhandled interrupt: %d %d\n",
63568c2ecf20Sopenharmony_ci					  src_id, src_data);
63578c2ecf20Sopenharmony_ci				break;
63588c2ecf20Sopenharmony_ci			}
63598c2ecf20Sopenharmony_ci
63608c2ecf20Sopenharmony_ci			if (!(disp_int[hpd_idx] & mask))
63618c2ecf20Sopenharmony_ci				DRM_DEBUG("IH: IH event w/o asserted irq bit?\n");
63628c2ecf20Sopenharmony_ci
63638c2ecf20Sopenharmony_ci			disp_int[hpd_idx] &= ~mask;
63648c2ecf20Sopenharmony_ci			DRM_DEBUG("IH: %s%d\n", event_name, hpd_idx + 1);
63658c2ecf20Sopenharmony_ci			break;
63668c2ecf20Sopenharmony_ci		case 96:
63678c2ecf20Sopenharmony_ci			DRM_ERROR("SRBM_READ_ERROR: 0x%x\n", RREG32(SRBM_READ_ERROR));
63688c2ecf20Sopenharmony_ci			WREG32(SRBM_INT_ACK, 0x1);
63698c2ecf20Sopenharmony_ci			break;
63708c2ecf20Sopenharmony_ci		case 124: /* UVD */
63718c2ecf20Sopenharmony_ci			DRM_DEBUG("IH: UVD int: 0x%08x\n", src_data);
63728c2ecf20Sopenharmony_ci			radeon_fence_process(rdev, R600_RING_TYPE_UVD_INDEX);
63738c2ecf20Sopenharmony_ci			break;
63748c2ecf20Sopenharmony_ci		case 146:
63758c2ecf20Sopenharmony_ci		case 147:
63768c2ecf20Sopenharmony_ci			addr = RREG32(VM_CONTEXT1_PROTECTION_FAULT_ADDR);
63778c2ecf20Sopenharmony_ci			status = RREG32(VM_CONTEXT1_PROTECTION_FAULT_STATUS);
63788c2ecf20Sopenharmony_ci			/* reset addr and status */
63798c2ecf20Sopenharmony_ci			WREG32_P(VM_CONTEXT1_CNTL2, 1, ~1);
63808c2ecf20Sopenharmony_ci			if (addr == 0x0 && status == 0x0)
63818c2ecf20Sopenharmony_ci				break;
63828c2ecf20Sopenharmony_ci			dev_err(rdev->dev, "GPU fault detected: %d 0x%08x\n", src_id, src_data);
63838c2ecf20Sopenharmony_ci			dev_err(rdev->dev, "  VM_CONTEXT1_PROTECTION_FAULT_ADDR   0x%08X\n",
63848c2ecf20Sopenharmony_ci				addr);
63858c2ecf20Sopenharmony_ci			dev_err(rdev->dev, "  VM_CONTEXT1_PROTECTION_FAULT_STATUS 0x%08X\n",
63868c2ecf20Sopenharmony_ci				status);
63878c2ecf20Sopenharmony_ci			si_vm_decode_fault(rdev, status, addr);
63888c2ecf20Sopenharmony_ci			break;
63898c2ecf20Sopenharmony_ci		case 176: /* RINGID0 CP_INT */
63908c2ecf20Sopenharmony_ci			radeon_fence_process(rdev, RADEON_RING_TYPE_GFX_INDEX);
63918c2ecf20Sopenharmony_ci			break;
63928c2ecf20Sopenharmony_ci		case 177: /* RINGID1 CP_INT */
63938c2ecf20Sopenharmony_ci			radeon_fence_process(rdev, CAYMAN_RING_TYPE_CP1_INDEX);
63948c2ecf20Sopenharmony_ci			break;
63958c2ecf20Sopenharmony_ci		case 178: /* RINGID2 CP_INT */
63968c2ecf20Sopenharmony_ci			radeon_fence_process(rdev, CAYMAN_RING_TYPE_CP2_INDEX);
63978c2ecf20Sopenharmony_ci			break;
63988c2ecf20Sopenharmony_ci		case 181: /* CP EOP event */
63998c2ecf20Sopenharmony_ci			DRM_DEBUG("IH: CP EOP\n");
64008c2ecf20Sopenharmony_ci			switch (ring_id) {
64018c2ecf20Sopenharmony_ci			case 0:
64028c2ecf20Sopenharmony_ci				radeon_fence_process(rdev, RADEON_RING_TYPE_GFX_INDEX);
64038c2ecf20Sopenharmony_ci				break;
64048c2ecf20Sopenharmony_ci			case 1:
64058c2ecf20Sopenharmony_ci				radeon_fence_process(rdev, CAYMAN_RING_TYPE_CP1_INDEX);
64068c2ecf20Sopenharmony_ci				break;
64078c2ecf20Sopenharmony_ci			case 2:
64088c2ecf20Sopenharmony_ci				radeon_fence_process(rdev, CAYMAN_RING_TYPE_CP2_INDEX);
64098c2ecf20Sopenharmony_ci				break;
64108c2ecf20Sopenharmony_ci			}
64118c2ecf20Sopenharmony_ci			break;
64128c2ecf20Sopenharmony_ci		case 224: /* DMA trap event */
64138c2ecf20Sopenharmony_ci			DRM_DEBUG("IH: DMA trap\n");
64148c2ecf20Sopenharmony_ci			radeon_fence_process(rdev, R600_RING_TYPE_DMA_INDEX);
64158c2ecf20Sopenharmony_ci			break;
64168c2ecf20Sopenharmony_ci		case 230: /* thermal low to high */
64178c2ecf20Sopenharmony_ci			DRM_DEBUG("IH: thermal low to high\n");
64188c2ecf20Sopenharmony_ci			rdev->pm.dpm.thermal.high_to_low = false;
64198c2ecf20Sopenharmony_ci			queue_thermal = true;
64208c2ecf20Sopenharmony_ci			break;
64218c2ecf20Sopenharmony_ci		case 231: /* thermal high to low */
64228c2ecf20Sopenharmony_ci			DRM_DEBUG("IH: thermal high to low\n");
64238c2ecf20Sopenharmony_ci			rdev->pm.dpm.thermal.high_to_low = true;
64248c2ecf20Sopenharmony_ci			queue_thermal = true;
64258c2ecf20Sopenharmony_ci			break;
64268c2ecf20Sopenharmony_ci		case 233: /* GUI IDLE */
64278c2ecf20Sopenharmony_ci			DRM_DEBUG("IH: GUI idle\n");
64288c2ecf20Sopenharmony_ci			break;
64298c2ecf20Sopenharmony_ci		case 244: /* DMA trap event */
64308c2ecf20Sopenharmony_ci			DRM_DEBUG("IH: DMA1 trap\n");
64318c2ecf20Sopenharmony_ci			radeon_fence_process(rdev, CAYMAN_RING_TYPE_DMA1_INDEX);
64328c2ecf20Sopenharmony_ci			break;
64338c2ecf20Sopenharmony_ci		default:
64348c2ecf20Sopenharmony_ci			DRM_DEBUG("Unhandled interrupt: %d %d\n", src_id, src_data);
64358c2ecf20Sopenharmony_ci			break;
64368c2ecf20Sopenharmony_ci		}
64378c2ecf20Sopenharmony_ci
64388c2ecf20Sopenharmony_ci		/* wptr/rptr are in bytes! */
64398c2ecf20Sopenharmony_ci		rptr += 16;
64408c2ecf20Sopenharmony_ci		rptr &= rdev->ih.ptr_mask;
64418c2ecf20Sopenharmony_ci		WREG32(IH_RB_RPTR, rptr);
64428c2ecf20Sopenharmony_ci	}
64438c2ecf20Sopenharmony_ci	if (queue_dp)
64448c2ecf20Sopenharmony_ci		schedule_work(&rdev->dp_work);
64458c2ecf20Sopenharmony_ci	if (queue_hotplug)
64468c2ecf20Sopenharmony_ci		schedule_delayed_work(&rdev->hotplug_work, 0);
64478c2ecf20Sopenharmony_ci	if (queue_thermal && rdev->pm.dpm_enabled)
64488c2ecf20Sopenharmony_ci		schedule_work(&rdev->pm.dpm.thermal.work);
64498c2ecf20Sopenharmony_ci	rdev->ih.rptr = rptr;
64508c2ecf20Sopenharmony_ci	WREG32(IH_RB_RPTR, rptr);
64518c2ecf20Sopenharmony_ci	atomic_set(&rdev->ih.lock, 0);
64528c2ecf20Sopenharmony_ci
64538c2ecf20Sopenharmony_ci	/* make sure wptr hasn't changed while processing */
64548c2ecf20Sopenharmony_ci	wptr = si_get_ih_wptr(rdev);
64558c2ecf20Sopenharmony_ci	if (wptr != rptr)
64568c2ecf20Sopenharmony_ci		goto restart_ih;
64578c2ecf20Sopenharmony_ci
64588c2ecf20Sopenharmony_ci	return IRQ_HANDLED;
64598c2ecf20Sopenharmony_ci}
64608c2ecf20Sopenharmony_ci
64618c2ecf20Sopenharmony_ci/*
64628c2ecf20Sopenharmony_ci * startup/shutdown callbacks
64638c2ecf20Sopenharmony_ci */
64648c2ecf20Sopenharmony_cistatic void si_uvd_init(struct radeon_device *rdev)
64658c2ecf20Sopenharmony_ci{
64668c2ecf20Sopenharmony_ci	int r;
64678c2ecf20Sopenharmony_ci
64688c2ecf20Sopenharmony_ci	if (!rdev->has_uvd)
64698c2ecf20Sopenharmony_ci		return;
64708c2ecf20Sopenharmony_ci
64718c2ecf20Sopenharmony_ci	r = radeon_uvd_init(rdev);
64728c2ecf20Sopenharmony_ci	if (r) {
64738c2ecf20Sopenharmony_ci		dev_err(rdev->dev, "failed UVD (%d) init.\n", r);
64748c2ecf20Sopenharmony_ci		/*
64758c2ecf20Sopenharmony_ci		 * At this point rdev->uvd.vcpu_bo is NULL which trickles down
64768c2ecf20Sopenharmony_ci		 * to early fails uvd_v2_2_resume() and thus nothing happens
64778c2ecf20Sopenharmony_ci		 * there. So it is pointless to try to go through that code
64788c2ecf20Sopenharmony_ci		 * hence why we disable uvd here.
64798c2ecf20Sopenharmony_ci		 */
64808c2ecf20Sopenharmony_ci		rdev->has_uvd = false;
64818c2ecf20Sopenharmony_ci		return;
64828c2ecf20Sopenharmony_ci	}
64838c2ecf20Sopenharmony_ci	rdev->ring[R600_RING_TYPE_UVD_INDEX].ring_obj = NULL;
64848c2ecf20Sopenharmony_ci	r600_ring_init(rdev, &rdev->ring[R600_RING_TYPE_UVD_INDEX], 4096);
64858c2ecf20Sopenharmony_ci}
64868c2ecf20Sopenharmony_ci
64878c2ecf20Sopenharmony_cistatic void si_uvd_start(struct radeon_device *rdev)
64888c2ecf20Sopenharmony_ci{
64898c2ecf20Sopenharmony_ci	int r;
64908c2ecf20Sopenharmony_ci
64918c2ecf20Sopenharmony_ci	if (!rdev->has_uvd)
64928c2ecf20Sopenharmony_ci		return;
64938c2ecf20Sopenharmony_ci
64948c2ecf20Sopenharmony_ci	r = uvd_v2_2_resume(rdev);
64958c2ecf20Sopenharmony_ci	if (r) {
64968c2ecf20Sopenharmony_ci		dev_err(rdev->dev, "failed UVD resume (%d).\n", r);
64978c2ecf20Sopenharmony_ci		goto error;
64988c2ecf20Sopenharmony_ci	}
64998c2ecf20Sopenharmony_ci	r = radeon_fence_driver_start_ring(rdev, R600_RING_TYPE_UVD_INDEX);
65008c2ecf20Sopenharmony_ci	if (r) {
65018c2ecf20Sopenharmony_ci		dev_err(rdev->dev, "failed initializing UVD fences (%d).\n", r);
65028c2ecf20Sopenharmony_ci		goto error;
65038c2ecf20Sopenharmony_ci	}
65048c2ecf20Sopenharmony_ci	return;
65058c2ecf20Sopenharmony_ci
65068c2ecf20Sopenharmony_cierror:
65078c2ecf20Sopenharmony_ci	rdev->ring[R600_RING_TYPE_UVD_INDEX].ring_size = 0;
65088c2ecf20Sopenharmony_ci}
65098c2ecf20Sopenharmony_ci
65108c2ecf20Sopenharmony_cistatic void si_uvd_resume(struct radeon_device *rdev)
65118c2ecf20Sopenharmony_ci{
65128c2ecf20Sopenharmony_ci	struct radeon_ring *ring;
65138c2ecf20Sopenharmony_ci	int r;
65148c2ecf20Sopenharmony_ci
65158c2ecf20Sopenharmony_ci	if (!rdev->has_uvd || !rdev->ring[R600_RING_TYPE_UVD_INDEX].ring_size)
65168c2ecf20Sopenharmony_ci		return;
65178c2ecf20Sopenharmony_ci
65188c2ecf20Sopenharmony_ci	ring = &rdev->ring[R600_RING_TYPE_UVD_INDEX];
65198c2ecf20Sopenharmony_ci	r = radeon_ring_init(rdev, ring, ring->ring_size, 0, PACKET0(UVD_NO_OP, 0));
65208c2ecf20Sopenharmony_ci	if (r) {
65218c2ecf20Sopenharmony_ci		dev_err(rdev->dev, "failed initializing UVD ring (%d).\n", r);
65228c2ecf20Sopenharmony_ci		return;
65238c2ecf20Sopenharmony_ci	}
65248c2ecf20Sopenharmony_ci	r = uvd_v1_0_init(rdev);
65258c2ecf20Sopenharmony_ci	if (r) {
65268c2ecf20Sopenharmony_ci		dev_err(rdev->dev, "failed initializing UVD (%d).\n", r);
65278c2ecf20Sopenharmony_ci		return;
65288c2ecf20Sopenharmony_ci	}
65298c2ecf20Sopenharmony_ci}
65308c2ecf20Sopenharmony_ci
65318c2ecf20Sopenharmony_cistatic void si_vce_init(struct radeon_device *rdev)
65328c2ecf20Sopenharmony_ci{
65338c2ecf20Sopenharmony_ci	int r;
65348c2ecf20Sopenharmony_ci
65358c2ecf20Sopenharmony_ci	if (!rdev->has_vce)
65368c2ecf20Sopenharmony_ci		return;
65378c2ecf20Sopenharmony_ci
65388c2ecf20Sopenharmony_ci	r = radeon_vce_init(rdev);
65398c2ecf20Sopenharmony_ci	if (r) {
65408c2ecf20Sopenharmony_ci		dev_err(rdev->dev, "failed VCE (%d) init.\n", r);
65418c2ecf20Sopenharmony_ci		/*
65428c2ecf20Sopenharmony_ci		 * At this point rdev->vce.vcpu_bo is NULL which trickles down
65438c2ecf20Sopenharmony_ci		 * to early fails si_vce_start() and thus nothing happens
65448c2ecf20Sopenharmony_ci		 * there. So it is pointless to try to go through that code
65458c2ecf20Sopenharmony_ci		 * hence why we disable vce here.
65468c2ecf20Sopenharmony_ci		 */
65478c2ecf20Sopenharmony_ci		rdev->has_vce = false;
65488c2ecf20Sopenharmony_ci		return;
65498c2ecf20Sopenharmony_ci	}
65508c2ecf20Sopenharmony_ci	rdev->ring[TN_RING_TYPE_VCE1_INDEX].ring_obj = NULL;
65518c2ecf20Sopenharmony_ci	r600_ring_init(rdev, &rdev->ring[TN_RING_TYPE_VCE1_INDEX], 4096);
65528c2ecf20Sopenharmony_ci	rdev->ring[TN_RING_TYPE_VCE2_INDEX].ring_obj = NULL;
65538c2ecf20Sopenharmony_ci	r600_ring_init(rdev, &rdev->ring[TN_RING_TYPE_VCE2_INDEX], 4096);
65548c2ecf20Sopenharmony_ci}
65558c2ecf20Sopenharmony_ci
65568c2ecf20Sopenharmony_cistatic void si_vce_start(struct radeon_device *rdev)
65578c2ecf20Sopenharmony_ci{
65588c2ecf20Sopenharmony_ci	int r;
65598c2ecf20Sopenharmony_ci
65608c2ecf20Sopenharmony_ci	if (!rdev->has_vce)
65618c2ecf20Sopenharmony_ci		return;
65628c2ecf20Sopenharmony_ci
65638c2ecf20Sopenharmony_ci	r = radeon_vce_resume(rdev);
65648c2ecf20Sopenharmony_ci	if (r) {
65658c2ecf20Sopenharmony_ci		dev_err(rdev->dev, "failed VCE resume (%d).\n", r);
65668c2ecf20Sopenharmony_ci		goto error;
65678c2ecf20Sopenharmony_ci	}
65688c2ecf20Sopenharmony_ci	r = vce_v1_0_resume(rdev);
65698c2ecf20Sopenharmony_ci	if (r) {
65708c2ecf20Sopenharmony_ci		dev_err(rdev->dev, "failed VCE resume (%d).\n", r);
65718c2ecf20Sopenharmony_ci		goto error;
65728c2ecf20Sopenharmony_ci	}
65738c2ecf20Sopenharmony_ci	r = radeon_fence_driver_start_ring(rdev, TN_RING_TYPE_VCE1_INDEX);
65748c2ecf20Sopenharmony_ci	if (r) {
65758c2ecf20Sopenharmony_ci		dev_err(rdev->dev, "failed initializing VCE1 fences (%d).\n", r);
65768c2ecf20Sopenharmony_ci		goto error;
65778c2ecf20Sopenharmony_ci	}
65788c2ecf20Sopenharmony_ci	r = radeon_fence_driver_start_ring(rdev, TN_RING_TYPE_VCE2_INDEX);
65798c2ecf20Sopenharmony_ci	if (r) {
65808c2ecf20Sopenharmony_ci		dev_err(rdev->dev, "failed initializing VCE2 fences (%d).\n", r);
65818c2ecf20Sopenharmony_ci		goto error;
65828c2ecf20Sopenharmony_ci	}
65838c2ecf20Sopenharmony_ci	return;
65848c2ecf20Sopenharmony_ci
65858c2ecf20Sopenharmony_cierror:
65868c2ecf20Sopenharmony_ci	rdev->ring[TN_RING_TYPE_VCE1_INDEX].ring_size = 0;
65878c2ecf20Sopenharmony_ci	rdev->ring[TN_RING_TYPE_VCE2_INDEX].ring_size = 0;
65888c2ecf20Sopenharmony_ci}
65898c2ecf20Sopenharmony_ci
65908c2ecf20Sopenharmony_cistatic void si_vce_resume(struct radeon_device *rdev)
65918c2ecf20Sopenharmony_ci{
65928c2ecf20Sopenharmony_ci	struct radeon_ring *ring;
65938c2ecf20Sopenharmony_ci	int r;
65948c2ecf20Sopenharmony_ci
65958c2ecf20Sopenharmony_ci	if (!rdev->has_vce || !rdev->ring[TN_RING_TYPE_VCE1_INDEX].ring_size)
65968c2ecf20Sopenharmony_ci		return;
65978c2ecf20Sopenharmony_ci
65988c2ecf20Sopenharmony_ci	ring = &rdev->ring[TN_RING_TYPE_VCE1_INDEX];
65998c2ecf20Sopenharmony_ci	r = radeon_ring_init(rdev, ring, ring->ring_size, 0, VCE_CMD_NO_OP);
66008c2ecf20Sopenharmony_ci	if (r) {
66018c2ecf20Sopenharmony_ci		dev_err(rdev->dev, "failed initializing VCE1 ring (%d).\n", r);
66028c2ecf20Sopenharmony_ci		return;
66038c2ecf20Sopenharmony_ci	}
66048c2ecf20Sopenharmony_ci	ring = &rdev->ring[TN_RING_TYPE_VCE2_INDEX];
66058c2ecf20Sopenharmony_ci	r = radeon_ring_init(rdev, ring, ring->ring_size, 0, VCE_CMD_NO_OP);
66068c2ecf20Sopenharmony_ci	if (r) {
66078c2ecf20Sopenharmony_ci		dev_err(rdev->dev, "failed initializing VCE1 ring (%d).\n", r);
66088c2ecf20Sopenharmony_ci		return;
66098c2ecf20Sopenharmony_ci	}
66108c2ecf20Sopenharmony_ci	r = vce_v1_0_init(rdev);
66118c2ecf20Sopenharmony_ci	if (r) {
66128c2ecf20Sopenharmony_ci		dev_err(rdev->dev, "failed initializing VCE (%d).\n", r);
66138c2ecf20Sopenharmony_ci		return;
66148c2ecf20Sopenharmony_ci	}
66158c2ecf20Sopenharmony_ci}
66168c2ecf20Sopenharmony_ci
66178c2ecf20Sopenharmony_cistatic int si_startup(struct radeon_device *rdev)
66188c2ecf20Sopenharmony_ci{
66198c2ecf20Sopenharmony_ci	struct radeon_ring *ring;
66208c2ecf20Sopenharmony_ci	int r;
66218c2ecf20Sopenharmony_ci
66228c2ecf20Sopenharmony_ci	/* enable pcie gen2/3 link */
66238c2ecf20Sopenharmony_ci	si_pcie_gen3_enable(rdev);
66248c2ecf20Sopenharmony_ci	/* enable aspm */
66258c2ecf20Sopenharmony_ci	si_program_aspm(rdev);
66268c2ecf20Sopenharmony_ci
66278c2ecf20Sopenharmony_ci	/* scratch needs to be initialized before MC */
66288c2ecf20Sopenharmony_ci	r = r600_vram_scratch_init(rdev);
66298c2ecf20Sopenharmony_ci	if (r)
66308c2ecf20Sopenharmony_ci		return r;
66318c2ecf20Sopenharmony_ci
66328c2ecf20Sopenharmony_ci	si_mc_program(rdev);
66338c2ecf20Sopenharmony_ci
66348c2ecf20Sopenharmony_ci	if (!rdev->pm.dpm_enabled) {
66358c2ecf20Sopenharmony_ci		r = si_mc_load_microcode(rdev);
66368c2ecf20Sopenharmony_ci		if (r) {
66378c2ecf20Sopenharmony_ci			DRM_ERROR("Failed to load MC firmware!\n");
66388c2ecf20Sopenharmony_ci			return r;
66398c2ecf20Sopenharmony_ci		}
66408c2ecf20Sopenharmony_ci	}
66418c2ecf20Sopenharmony_ci
66428c2ecf20Sopenharmony_ci	r = si_pcie_gart_enable(rdev);
66438c2ecf20Sopenharmony_ci	if (r)
66448c2ecf20Sopenharmony_ci		return r;
66458c2ecf20Sopenharmony_ci	si_gpu_init(rdev);
66468c2ecf20Sopenharmony_ci
66478c2ecf20Sopenharmony_ci	/* allocate rlc buffers */
66488c2ecf20Sopenharmony_ci	if (rdev->family == CHIP_VERDE) {
66498c2ecf20Sopenharmony_ci		rdev->rlc.reg_list = verde_rlc_save_restore_register_list;
66508c2ecf20Sopenharmony_ci		rdev->rlc.reg_list_size =
66518c2ecf20Sopenharmony_ci			(u32)ARRAY_SIZE(verde_rlc_save_restore_register_list);
66528c2ecf20Sopenharmony_ci	}
66538c2ecf20Sopenharmony_ci	rdev->rlc.cs_data = si_cs_data;
66548c2ecf20Sopenharmony_ci	r = sumo_rlc_init(rdev);
66558c2ecf20Sopenharmony_ci	if (r) {
66568c2ecf20Sopenharmony_ci		DRM_ERROR("Failed to init rlc BOs!\n");
66578c2ecf20Sopenharmony_ci		return r;
66588c2ecf20Sopenharmony_ci	}
66598c2ecf20Sopenharmony_ci
66608c2ecf20Sopenharmony_ci	/* allocate wb buffer */
66618c2ecf20Sopenharmony_ci	r = radeon_wb_init(rdev);
66628c2ecf20Sopenharmony_ci	if (r)
66638c2ecf20Sopenharmony_ci		return r;
66648c2ecf20Sopenharmony_ci
66658c2ecf20Sopenharmony_ci	r = radeon_fence_driver_start_ring(rdev, RADEON_RING_TYPE_GFX_INDEX);
66668c2ecf20Sopenharmony_ci	if (r) {
66678c2ecf20Sopenharmony_ci		dev_err(rdev->dev, "failed initializing CP fences (%d).\n", r);
66688c2ecf20Sopenharmony_ci		return r;
66698c2ecf20Sopenharmony_ci	}
66708c2ecf20Sopenharmony_ci
66718c2ecf20Sopenharmony_ci	r = radeon_fence_driver_start_ring(rdev, CAYMAN_RING_TYPE_CP1_INDEX);
66728c2ecf20Sopenharmony_ci	if (r) {
66738c2ecf20Sopenharmony_ci		dev_err(rdev->dev, "failed initializing CP fences (%d).\n", r);
66748c2ecf20Sopenharmony_ci		return r;
66758c2ecf20Sopenharmony_ci	}
66768c2ecf20Sopenharmony_ci
66778c2ecf20Sopenharmony_ci	r = radeon_fence_driver_start_ring(rdev, CAYMAN_RING_TYPE_CP2_INDEX);
66788c2ecf20Sopenharmony_ci	if (r) {
66798c2ecf20Sopenharmony_ci		dev_err(rdev->dev, "failed initializing CP fences (%d).\n", r);
66808c2ecf20Sopenharmony_ci		return r;
66818c2ecf20Sopenharmony_ci	}
66828c2ecf20Sopenharmony_ci
66838c2ecf20Sopenharmony_ci	r = radeon_fence_driver_start_ring(rdev, R600_RING_TYPE_DMA_INDEX);
66848c2ecf20Sopenharmony_ci	if (r) {
66858c2ecf20Sopenharmony_ci		dev_err(rdev->dev, "failed initializing DMA fences (%d).\n", r);
66868c2ecf20Sopenharmony_ci		return r;
66878c2ecf20Sopenharmony_ci	}
66888c2ecf20Sopenharmony_ci
66898c2ecf20Sopenharmony_ci	r = radeon_fence_driver_start_ring(rdev, CAYMAN_RING_TYPE_DMA1_INDEX);
66908c2ecf20Sopenharmony_ci	if (r) {
66918c2ecf20Sopenharmony_ci		dev_err(rdev->dev, "failed initializing DMA fences (%d).\n", r);
66928c2ecf20Sopenharmony_ci		return r;
66938c2ecf20Sopenharmony_ci	}
66948c2ecf20Sopenharmony_ci
66958c2ecf20Sopenharmony_ci	si_uvd_start(rdev);
66968c2ecf20Sopenharmony_ci	si_vce_start(rdev);
66978c2ecf20Sopenharmony_ci
66988c2ecf20Sopenharmony_ci	/* Enable IRQ */
66998c2ecf20Sopenharmony_ci	if (!rdev->irq.installed) {
67008c2ecf20Sopenharmony_ci		r = radeon_irq_kms_init(rdev);
67018c2ecf20Sopenharmony_ci		if (r)
67028c2ecf20Sopenharmony_ci			return r;
67038c2ecf20Sopenharmony_ci	}
67048c2ecf20Sopenharmony_ci
67058c2ecf20Sopenharmony_ci	r = si_irq_init(rdev);
67068c2ecf20Sopenharmony_ci	if (r) {
67078c2ecf20Sopenharmony_ci		DRM_ERROR("radeon: IH init failed (%d).\n", r);
67088c2ecf20Sopenharmony_ci		radeon_irq_kms_fini(rdev);
67098c2ecf20Sopenharmony_ci		return r;
67108c2ecf20Sopenharmony_ci	}
67118c2ecf20Sopenharmony_ci	si_irq_set(rdev);
67128c2ecf20Sopenharmony_ci
67138c2ecf20Sopenharmony_ci	ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX];
67148c2ecf20Sopenharmony_ci	r = radeon_ring_init(rdev, ring, ring->ring_size, RADEON_WB_CP_RPTR_OFFSET,
67158c2ecf20Sopenharmony_ci			     RADEON_CP_PACKET2);
67168c2ecf20Sopenharmony_ci	if (r)
67178c2ecf20Sopenharmony_ci		return r;
67188c2ecf20Sopenharmony_ci
67198c2ecf20Sopenharmony_ci	ring = &rdev->ring[CAYMAN_RING_TYPE_CP1_INDEX];
67208c2ecf20Sopenharmony_ci	r = radeon_ring_init(rdev, ring, ring->ring_size, RADEON_WB_CP1_RPTR_OFFSET,
67218c2ecf20Sopenharmony_ci			     RADEON_CP_PACKET2);
67228c2ecf20Sopenharmony_ci	if (r)
67238c2ecf20Sopenharmony_ci		return r;
67248c2ecf20Sopenharmony_ci
67258c2ecf20Sopenharmony_ci	ring = &rdev->ring[CAYMAN_RING_TYPE_CP2_INDEX];
67268c2ecf20Sopenharmony_ci	r = radeon_ring_init(rdev, ring, ring->ring_size, RADEON_WB_CP2_RPTR_OFFSET,
67278c2ecf20Sopenharmony_ci			     RADEON_CP_PACKET2);
67288c2ecf20Sopenharmony_ci	if (r)
67298c2ecf20Sopenharmony_ci		return r;
67308c2ecf20Sopenharmony_ci
67318c2ecf20Sopenharmony_ci	ring = &rdev->ring[R600_RING_TYPE_DMA_INDEX];
67328c2ecf20Sopenharmony_ci	r = radeon_ring_init(rdev, ring, ring->ring_size, R600_WB_DMA_RPTR_OFFSET,
67338c2ecf20Sopenharmony_ci			     DMA_PACKET(DMA_PACKET_NOP, 0, 0, 0, 0));
67348c2ecf20Sopenharmony_ci	if (r)
67358c2ecf20Sopenharmony_ci		return r;
67368c2ecf20Sopenharmony_ci
67378c2ecf20Sopenharmony_ci	ring = &rdev->ring[CAYMAN_RING_TYPE_DMA1_INDEX];
67388c2ecf20Sopenharmony_ci	r = radeon_ring_init(rdev, ring, ring->ring_size, CAYMAN_WB_DMA1_RPTR_OFFSET,
67398c2ecf20Sopenharmony_ci			     DMA_PACKET(DMA_PACKET_NOP, 0, 0, 0, 0));
67408c2ecf20Sopenharmony_ci	if (r)
67418c2ecf20Sopenharmony_ci		return r;
67428c2ecf20Sopenharmony_ci
67438c2ecf20Sopenharmony_ci	r = si_cp_load_microcode(rdev);
67448c2ecf20Sopenharmony_ci	if (r)
67458c2ecf20Sopenharmony_ci		return r;
67468c2ecf20Sopenharmony_ci	r = si_cp_resume(rdev);
67478c2ecf20Sopenharmony_ci	if (r)
67488c2ecf20Sopenharmony_ci		return r;
67498c2ecf20Sopenharmony_ci
67508c2ecf20Sopenharmony_ci	r = cayman_dma_resume(rdev);
67518c2ecf20Sopenharmony_ci	if (r)
67528c2ecf20Sopenharmony_ci		return r;
67538c2ecf20Sopenharmony_ci
67548c2ecf20Sopenharmony_ci	si_uvd_resume(rdev);
67558c2ecf20Sopenharmony_ci	si_vce_resume(rdev);
67568c2ecf20Sopenharmony_ci
67578c2ecf20Sopenharmony_ci	r = radeon_ib_pool_init(rdev);
67588c2ecf20Sopenharmony_ci	if (r) {
67598c2ecf20Sopenharmony_ci		dev_err(rdev->dev, "IB initialization failed (%d).\n", r);
67608c2ecf20Sopenharmony_ci		return r;
67618c2ecf20Sopenharmony_ci	}
67628c2ecf20Sopenharmony_ci
67638c2ecf20Sopenharmony_ci	r = radeon_vm_manager_init(rdev);
67648c2ecf20Sopenharmony_ci	if (r) {
67658c2ecf20Sopenharmony_ci		dev_err(rdev->dev, "vm manager initialization failed (%d).\n", r);
67668c2ecf20Sopenharmony_ci		return r;
67678c2ecf20Sopenharmony_ci	}
67688c2ecf20Sopenharmony_ci
67698c2ecf20Sopenharmony_ci	r = radeon_audio_init(rdev);
67708c2ecf20Sopenharmony_ci	if (r)
67718c2ecf20Sopenharmony_ci		return r;
67728c2ecf20Sopenharmony_ci
67738c2ecf20Sopenharmony_ci	return 0;
67748c2ecf20Sopenharmony_ci}
67758c2ecf20Sopenharmony_ci
67768c2ecf20Sopenharmony_ciint si_resume(struct radeon_device *rdev)
67778c2ecf20Sopenharmony_ci{
67788c2ecf20Sopenharmony_ci	int r;
67798c2ecf20Sopenharmony_ci
67808c2ecf20Sopenharmony_ci	/* Do not reset GPU before posting, on rv770 hw unlike on r500 hw,
67818c2ecf20Sopenharmony_ci	 * posting will perform necessary task to bring back GPU into good
67828c2ecf20Sopenharmony_ci	 * shape.
67838c2ecf20Sopenharmony_ci	 */
67848c2ecf20Sopenharmony_ci	/* post card */
67858c2ecf20Sopenharmony_ci	atom_asic_init(rdev->mode_info.atom_context);
67868c2ecf20Sopenharmony_ci
67878c2ecf20Sopenharmony_ci	/* init golden registers */
67888c2ecf20Sopenharmony_ci	si_init_golden_registers(rdev);
67898c2ecf20Sopenharmony_ci
67908c2ecf20Sopenharmony_ci	if (rdev->pm.pm_method == PM_METHOD_DPM)
67918c2ecf20Sopenharmony_ci		radeon_pm_resume(rdev);
67928c2ecf20Sopenharmony_ci
67938c2ecf20Sopenharmony_ci	rdev->accel_working = true;
67948c2ecf20Sopenharmony_ci	r = si_startup(rdev);
67958c2ecf20Sopenharmony_ci	if (r) {
67968c2ecf20Sopenharmony_ci		DRM_ERROR("si startup failed on resume\n");
67978c2ecf20Sopenharmony_ci		rdev->accel_working = false;
67988c2ecf20Sopenharmony_ci		return r;
67998c2ecf20Sopenharmony_ci	}
68008c2ecf20Sopenharmony_ci
68018c2ecf20Sopenharmony_ci	return r;
68028c2ecf20Sopenharmony_ci
68038c2ecf20Sopenharmony_ci}
68048c2ecf20Sopenharmony_ci
68058c2ecf20Sopenharmony_ciint si_suspend(struct radeon_device *rdev)
68068c2ecf20Sopenharmony_ci{
68078c2ecf20Sopenharmony_ci	radeon_pm_suspend(rdev);
68088c2ecf20Sopenharmony_ci	radeon_audio_fini(rdev);
68098c2ecf20Sopenharmony_ci	radeon_vm_manager_fini(rdev);
68108c2ecf20Sopenharmony_ci	si_cp_enable(rdev, false);
68118c2ecf20Sopenharmony_ci	cayman_dma_stop(rdev);
68128c2ecf20Sopenharmony_ci	if (rdev->has_uvd) {
68138c2ecf20Sopenharmony_ci		uvd_v1_0_fini(rdev);
68148c2ecf20Sopenharmony_ci		radeon_uvd_suspend(rdev);
68158c2ecf20Sopenharmony_ci	}
68168c2ecf20Sopenharmony_ci	if (rdev->has_vce)
68178c2ecf20Sopenharmony_ci		radeon_vce_suspend(rdev);
68188c2ecf20Sopenharmony_ci	si_fini_pg(rdev);
68198c2ecf20Sopenharmony_ci	si_fini_cg(rdev);
68208c2ecf20Sopenharmony_ci	si_irq_suspend(rdev);
68218c2ecf20Sopenharmony_ci	radeon_wb_disable(rdev);
68228c2ecf20Sopenharmony_ci	si_pcie_gart_disable(rdev);
68238c2ecf20Sopenharmony_ci	return 0;
68248c2ecf20Sopenharmony_ci}
68258c2ecf20Sopenharmony_ci
68268c2ecf20Sopenharmony_ci/* Plan is to move initialization in that function and use
68278c2ecf20Sopenharmony_ci * helper function so that radeon_device_init pretty much
68288c2ecf20Sopenharmony_ci * do nothing more than calling asic specific function. This
68298c2ecf20Sopenharmony_ci * should also allow to remove a bunch of callback function
68308c2ecf20Sopenharmony_ci * like vram_info.
68318c2ecf20Sopenharmony_ci */
68328c2ecf20Sopenharmony_ciint si_init(struct radeon_device *rdev)
68338c2ecf20Sopenharmony_ci{
68348c2ecf20Sopenharmony_ci	struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX];
68358c2ecf20Sopenharmony_ci	int r;
68368c2ecf20Sopenharmony_ci
68378c2ecf20Sopenharmony_ci	/* Read BIOS */
68388c2ecf20Sopenharmony_ci	if (!radeon_get_bios(rdev)) {
68398c2ecf20Sopenharmony_ci		if (ASIC_IS_AVIVO(rdev))
68408c2ecf20Sopenharmony_ci			return -EINVAL;
68418c2ecf20Sopenharmony_ci	}
68428c2ecf20Sopenharmony_ci	/* Must be an ATOMBIOS */
68438c2ecf20Sopenharmony_ci	if (!rdev->is_atom_bios) {
68448c2ecf20Sopenharmony_ci		dev_err(rdev->dev, "Expecting atombios for cayman GPU\n");
68458c2ecf20Sopenharmony_ci		return -EINVAL;
68468c2ecf20Sopenharmony_ci	}
68478c2ecf20Sopenharmony_ci	r = radeon_atombios_init(rdev);
68488c2ecf20Sopenharmony_ci	if (r)
68498c2ecf20Sopenharmony_ci		return r;
68508c2ecf20Sopenharmony_ci
68518c2ecf20Sopenharmony_ci	/* Post card if necessary */
68528c2ecf20Sopenharmony_ci	if (!radeon_card_posted(rdev)) {
68538c2ecf20Sopenharmony_ci		if (!rdev->bios) {
68548c2ecf20Sopenharmony_ci			dev_err(rdev->dev, "Card not posted and no BIOS - ignoring\n");
68558c2ecf20Sopenharmony_ci			return -EINVAL;
68568c2ecf20Sopenharmony_ci		}
68578c2ecf20Sopenharmony_ci		DRM_INFO("GPU not posted. posting now...\n");
68588c2ecf20Sopenharmony_ci		atom_asic_init(rdev->mode_info.atom_context);
68598c2ecf20Sopenharmony_ci	}
68608c2ecf20Sopenharmony_ci	/* init golden registers */
68618c2ecf20Sopenharmony_ci	si_init_golden_registers(rdev);
68628c2ecf20Sopenharmony_ci	/* Initialize scratch registers */
68638c2ecf20Sopenharmony_ci	si_scratch_init(rdev);
68648c2ecf20Sopenharmony_ci	/* Initialize surface registers */
68658c2ecf20Sopenharmony_ci	radeon_surface_init(rdev);
68668c2ecf20Sopenharmony_ci	/* Initialize clocks */
68678c2ecf20Sopenharmony_ci	radeon_get_clock_info(rdev->ddev);
68688c2ecf20Sopenharmony_ci
68698c2ecf20Sopenharmony_ci	/* Fence driver */
68708c2ecf20Sopenharmony_ci	r = radeon_fence_driver_init(rdev);
68718c2ecf20Sopenharmony_ci	if (r)
68728c2ecf20Sopenharmony_ci		return r;
68738c2ecf20Sopenharmony_ci
68748c2ecf20Sopenharmony_ci	/* initialize memory controller */
68758c2ecf20Sopenharmony_ci	r = si_mc_init(rdev);
68768c2ecf20Sopenharmony_ci	if (r)
68778c2ecf20Sopenharmony_ci		return r;
68788c2ecf20Sopenharmony_ci	/* Memory manager */
68798c2ecf20Sopenharmony_ci	r = radeon_bo_init(rdev);
68808c2ecf20Sopenharmony_ci	if (r)
68818c2ecf20Sopenharmony_ci		return r;
68828c2ecf20Sopenharmony_ci
68838c2ecf20Sopenharmony_ci	if (!rdev->me_fw || !rdev->pfp_fw || !rdev->ce_fw ||
68848c2ecf20Sopenharmony_ci	    !rdev->rlc_fw || !rdev->mc_fw) {
68858c2ecf20Sopenharmony_ci		r = si_init_microcode(rdev);
68868c2ecf20Sopenharmony_ci		if (r) {
68878c2ecf20Sopenharmony_ci			DRM_ERROR("Failed to load firmware!\n");
68888c2ecf20Sopenharmony_ci			return r;
68898c2ecf20Sopenharmony_ci		}
68908c2ecf20Sopenharmony_ci	}
68918c2ecf20Sopenharmony_ci
68928c2ecf20Sopenharmony_ci	/* Initialize power management */
68938c2ecf20Sopenharmony_ci	radeon_pm_init(rdev);
68948c2ecf20Sopenharmony_ci
68958c2ecf20Sopenharmony_ci	ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX];
68968c2ecf20Sopenharmony_ci	ring->ring_obj = NULL;
68978c2ecf20Sopenharmony_ci	r600_ring_init(rdev, ring, 1024 * 1024);
68988c2ecf20Sopenharmony_ci
68998c2ecf20Sopenharmony_ci	ring = &rdev->ring[CAYMAN_RING_TYPE_CP1_INDEX];
69008c2ecf20Sopenharmony_ci	ring->ring_obj = NULL;
69018c2ecf20Sopenharmony_ci	r600_ring_init(rdev, ring, 1024 * 1024);
69028c2ecf20Sopenharmony_ci
69038c2ecf20Sopenharmony_ci	ring = &rdev->ring[CAYMAN_RING_TYPE_CP2_INDEX];
69048c2ecf20Sopenharmony_ci	ring->ring_obj = NULL;
69058c2ecf20Sopenharmony_ci	r600_ring_init(rdev, ring, 1024 * 1024);
69068c2ecf20Sopenharmony_ci
69078c2ecf20Sopenharmony_ci	ring = &rdev->ring[R600_RING_TYPE_DMA_INDEX];
69088c2ecf20Sopenharmony_ci	ring->ring_obj = NULL;
69098c2ecf20Sopenharmony_ci	r600_ring_init(rdev, ring, 64 * 1024);
69108c2ecf20Sopenharmony_ci
69118c2ecf20Sopenharmony_ci	ring = &rdev->ring[CAYMAN_RING_TYPE_DMA1_INDEX];
69128c2ecf20Sopenharmony_ci	ring->ring_obj = NULL;
69138c2ecf20Sopenharmony_ci	r600_ring_init(rdev, ring, 64 * 1024);
69148c2ecf20Sopenharmony_ci
69158c2ecf20Sopenharmony_ci	si_uvd_init(rdev);
69168c2ecf20Sopenharmony_ci	si_vce_init(rdev);
69178c2ecf20Sopenharmony_ci
69188c2ecf20Sopenharmony_ci	rdev->ih.ring_obj = NULL;
69198c2ecf20Sopenharmony_ci	r600_ih_ring_init(rdev, 64 * 1024);
69208c2ecf20Sopenharmony_ci
69218c2ecf20Sopenharmony_ci	r = r600_pcie_gart_init(rdev);
69228c2ecf20Sopenharmony_ci	if (r)
69238c2ecf20Sopenharmony_ci		return r;
69248c2ecf20Sopenharmony_ci
69258c2ecf20Sopenharmony_ci	rdev->accel_working = true;
69268c2ecf20Sopenharmony_ci	r = si_startup(rdev);
69278c2ecf20Sopenharmony_ci	if (r) {
69288c2ecf20Sopenharmony_ci		dev_err(rdev->dev, "disabling GPU acceleration\n");
69298c2ecf20Sopenharmony_ci		si_cp_fini(rdev);
69308c2ecf20Sopenharmony_ci		cayman_dma_fini(rdev);
69318c2ecf20Sopenharmony_ci		si_irq_fini(rdev);
69328c2ecf20Sopenharmony_ci		sumo_rlc_fini(rdev);
69338c2ecf20Sopenharmony_ci		radeon_wb_fini(rdev);
69348c2ecf20Sopenharmony_ci		radeon_ib_pool_fini(rdev);
69358c2ecf20Sopenharmony_ci		radeon_vm_manager_fini(rdev);
69368c2ecf20Sopenharmony_ci		radeon_irq_kms_fini(rdev);
69378c2ecf20Sopenharmony_ci		si_pcie_gart_fini(rdev);
69388c2ecf20Sopenharmony_ci		rdev->accel_working = false;
69398c2ecf20Sopenharmony_ci	}
69408c2ecf20Sopenharmony_ci
69418c2ecf20Sopenharmony_ci	/* Don't start up if the MC ucode is missing.
69428c2ecf20Sopenharmony_ci	 * The default clocks and voltages before the MC ucode
69438c2ecf20Sopenharmony_ci	 * is loaded are not suffient for advanced operations.
69448c2ecf20Sopenharmony_ci	 */
69458c2ecf20Sopenharmony_ci	if (!rdev->mc_fw) {
69468c2ecf20Sopenharmony_ci		DRM_ERROR("radeon: MC ucode required for NI+.\n");
69478c2ecf20Sopenharmony_ci		return -EINVAL;
69488c2ecf20Sopenharmony_ci	}
69498c2ecf20Sopenharmony_ci
69508c2ecf20Sopenharmony_ci	return 0;
69518c2ecf20Sopenharmony_ci}
69528c2ecf20Sopenharmony_ci
69538c2ecf20Sopenharmony_civoid si_fini(struct radeon_device *rdev)
69548c2ecf20Sopenharmony_ci{
69558c2ecf20Sopenharmony_ci	radeon_pm_fini(rdev);
69568c2ecf20Sopenharmony_ci	si_cp_fini(rdev);
69578c2ecf20Sopenharmony_ci	cayman_dma_fini(rdev);
69588c2ecf20Sopenharmony_ci	si_fini_pg(rdev);
69598c2ecf20Sopenharmony_ci	si_fini_cg(rdev);
69608c2ecf20Sopenharmony_ci	si_irq_fini(rdev);
69618c2ecf20Sopenharmony_ci	sumo_rlc_fini(rdev);
69628c2ecf20Sopenharmony_ci	radeon_wb_fini(rdev);
69638c2ecf20Sopenharmony_ci	radeon_vm_manager_fini(rdev);
69648c2ecf20Sopenharmony_ci	radeon_ib_pool_fini(rdev);
69658c2ecf20Sopenharmony_ci	radeon_irq_kms_fini(rdev);
69668c2ecf20Sopenharmony_ci	if (rdev->has_uvd) {
69678c2ecf20Sopenharmony_ci		uvd_v1_0_fini(rdev);
69688c2ecf20Sopenharmony_ci		radeon_uvd_fini(rdev);
69698c2ecf20Sopenharmony_ci	}
69708c2ecf20Sopenharmony_ci	if (rdev->has_vce)
69718c2ecf20Sopenharmony_ci		radeon_vce_fini(rdev);
69728c2ecf20Sopenharmony_ci	si_pcie_gart_fini(rdev);
69738c2ecf20Sopenharmony_ci	r600_vram_scratch_fini(rdev);
69748c2ecf20Sopenharmony_ci	radeon_gem_fini(rdev);
69758c2ecf20Sopenharmony_ci	radeon_fence_driver_fini(rdev);
69768c2ecf20Sopenharmony_ci	radeon_bo_fini(rdev);
69778c2ecf20Sopenharmony_ci	radeon_atombios_fini(rdev);
69788c2ecf20Sopenharmony_ci	kfree(rdev->bios);
69798c2ecf20Sopenharmony_ci	rdev->bios = NULL;
69808c2ecf20Sopenharmony_ci}
69818c2ecf20Sopenharmony_ci
69828c2ecf20Sopenharmony_ci/**
69838c2ecf20Sopenharmony_ci * si_get_gpu_clock_counter - return GPU clock counter snapshot
69848c2ecf20Sopenharmony_ci *
69858c2ecf20Sopenharmony_ci * @rdev: radeon_device pointer
69868c2ecf20Sopenharmony_ci *
69878c2ecf20Sopenharmony_ci * Fetches a GPU clock counter snapshot (SI).
69888c2ecf20Sopenharmony_ci * Returns the 64 bit clock counter snapshot.
69898c2ecf20Sopenharmony_ci */
69908c2ecf20Sopenharmony_ciuint64_t si_get_gpu_clock_counter(struct radeon_device *rdev)
69918c2ecf20Sopenharmony_ci{
69928c2ecf20Sopenharmony_ci	uint64_t clock;
69938c2ecf20Sopenharmony_ci
69948c2ecf20Sopenharmony_ci	mutex_lock(&rdev->gpu_clock_mutex);
69958c2ecf20Sopenharmony_ci	WREG32(RLC_CAPTURE_GPU_CLOCK_COUNT, 1);
69968c2ecf20Sopenharmony_ci	clock = (uint64_t)RREG32(RLC_GPU_CLOCK_COUNT_LSB) |
69978c2ecf20Sopenharmony_ci		((uint64_t)RREG32(RLC_GPU_CLOCK_COUNT_MSB) << 32ULL);
69988c2ecf20Sopenharmony_ci	mutex_unlock(&rdev->gpu_clock_mutex);
69998c2ecf20Sopenharmony_ci	return clock;
70008c2ecf20Sopenharmony_ci}
70018c2ecf20Sopenharmony_ci
70028c2ecf20Sopenharmony_ciint si_set_uvd_clocks(struct radeon_device *rdev, u32 vclk, u32 dclk)
70038c2ecf20Sopenharmony_ci{
70048c2ecf20Sopenharmony_ci	unsigned fb_div = 0, vclk_div = 0, dclk_div = 0;
70058c2ecf20Sopenharmony_ci	int r;
70068c2ecf20Sopenharmony_ci
70078c2ecf20Sopenharmony_ci	/* bypass vclk and dclk with bclk */
70088c2ecf20Sopenharmony_ci	WREG32_P(CG_UPLL_FUNC_CNTL_2,
70098c2ecf20Sopenharmony_ci		VCLK_SRC_SEL(1) | DCLK_SRC_SEL(1),
70108c2ecf20Sopenharmony_ci		~(VCLK_SRC_SEL_MASK | DCLK_SRC_SEL_MASK));
70118c2ecf20Sopenharmony_ci
70128c2ecf20Sopenharmony_ci	/* put PLL in bypass mode */
70138c2ecf20Sopenharmony_ci	WREG32_P(CG_UPLL_FUNC_CNTL, UPLL_BYPASS_EN_MASK, ~UPLL_BYPASS_EN_MASK);
70148c2ecf20Sopenharmony_ci
70158c2ecf20Sopenharmony_ci	if (!vclk || !dclk) {
70168c2ecf20Sopenharmony_ci		/* keep the Bypass mode */
70178c2ecf20Sopenharmony_ci		return 0;
70188c2ecf20Sopenharmony_ci	}
70198c2ecf20Sopenharmony_ci
70208c2ecf20Sopenharmony_ci	r = radeon_uvd_calc_upll_dividers(rdev, vclk, dclk, 125000, 250000,
70218c2ecf20Sopenharmony_ci					  16384, 0x03FFFFFF, 0, 128, 5,
70228c2ecf20Sopenharmony_ci					  &fb_div, &vclk_div, &dclk_div);
70238c2ecf20Sopenharmony_ci	if (r)
70248c2ecf20Sopenharmony_ci		return r;
70258c2ecf20Sopenharmony_ci
70268c2ecf20Sopenharmony_ci	/* set RESET_ANTI_MUX to 0 */
70278c2ecf20Sopenharmony_ci	WREG32_P(CG_UPLL_FUNC_CNTL_5, 0, ~RESET_ANTI_MUX_MASK);
70288c2ecf20Sopenharmony_ci
70298c2ecf20Sopenharmony_ci	/* set VCO_MODE to 1 */
70308c2ecf20Sopenharmony_ci	WREG32_P(CG_UPLL_FUNC_CNTL, UPLL_VCO_MODE_MASK, ~UPLL_VCO_MODE_MASK);
70318c2ecf20Sopenharmony_ci
70328c2ecf20Sopenharmony_ci	/* disable sleep mode */
70338c2ecf20Sopenharmony_ci	WREG32_P(CG_UPLL_FUNC_CNTL, 0, ~UPLL_SLEEP_MASK);
70348c2ecf20Sopenharmony_ci
70358c2ecf20Sopenharmony_ci	/* deassert UPLL_RESET */
70368c2ecf20Sopenharmony_ci	WREG32_P(CG_UPLL_FUNC_CNTL, 0, ~UPLL_RESET_MASK);
70378c2ecf20Sopenharmony_ci
70388c2ecf20Sopenharmony_ci	mdelay(1);
70398c2ecf20Sopenharmony_ci
70408c2ecf20Sopenharmony_ci	r = radeon_uvd_send_upll_ctlreq(rdev, CG_UPLL_FUNC_CNTL);
70418c2ecf20Sopenharmony_ci	if (r)
70428c2ecf20Sopenharmony_ci		return r;
70438c2ecf20Sopenharmony_ci
70448c2ecf20Sopenharmony_ci	/* assert UPLL_RESET again */
70458c2ecf20Sopenharmony_ci	WREG32_P(CG_UPLL_FUNC_CNTL, UPLL_RESET_MASK, ~UPLL_RESET_MASK);
70468c2ecf20Sopenharmony_ci
70478c2ecf20Sopenharmony_ci	/* disable spread spectrum. */
70488c2ecf20Sopenharmony_ci	WREG32_P(CG_UPLL_SPREAD_SPECTRUM, 0, ~SSEN_MASK);
70498c2ecf20Sopenharmony_ci
70508c2ecf20Sopenharmony_ci	/* set feedback divider */
70518c2ecf20Sopenharmony_ci	WREG32_P(CG_UPLL_FUNC_CNTL_3, UPLL_FB_DIV(fb_div), ~UPLL_FB_DIV_MASK);
70528c2ecf20Sopenharmony_ci
70538c2ecf20Sopenharmony_ci	/* set ref divider to 0 */
70548c2ecf20Sopenharmony_ci	WREG32_P(CG_UPLL_FUNC_CNTL, 0, ~UPLL_REF_DIV_MASK);
70558c2ecf20Sopenharmony_ci
70568c2ecf20Sopenharmony_ci	if (fb_div < 307200)
70578c2ecf20Sopenharmony_ci		WREG32_P(CG_UPLL_FUNC_CNTL_4, 0, ~UPLL_SPARE_ISPARE9);
70588c2ecf20Sopenharmony_ci	else
70598c2ecf20Sopenharmony_ci		WREG32_P(CG_UPLL_FUNC_CNTL_4, UPLL_SPARE_ISPARE9, ~UPLL_SPARE_ISPARE9);
70608c2ecf20Sopenharmony_ci
70618c2ecf20Sopenharmony_ci	/* set PDIV_A and PDIV_B */
70628c2ecf20Sopenharmony_ci	WREG32_P(CG_UPLL_FUNC_CNTL_2,
70638c2ecf20Sopenharmony_ci		UPLL_PDIV_A(vclk_div) | UPLL_PDIV_B(dclk_div),
70648c2ecf20Sopenharmony_ci		~(UPLL_PDIV_A_MASK | UPLL_PDIV_B_MASK));
70658c2ecf20Sopenharmony_ci
70668c2ecf20Sopenharmony_ci	/* give the PLL some time to settle */
70678c2ecf20Sopenharmony_ci	mdelay(15);
70688c2ecf20Sopenharmony_ci
70698c2ecf20Sopenharmony_ci	/* deassert PLL_RESET */
70708c2ecf20Sopenharmony_ci	WREG32_P(CG_UPLL_FUNC_CNTL, 0, ~UPLL_RESET_MASK);
70718c2ecf20Sopenharmony_ci
70728c2ecf20Sopenharmony_ci	mdelay(15);
70738c2ecf20Sopenharmony_ci
70748c2ecf20Sopenharmony_ci	/* switch from bypass mode to normal mode */
70758c2ecf20Sopenharmony_ci	WREG32_P(CG_UPLL_FUNC_CNTL, 0, ~UPLL_BYPASS_EN_MASK);
70768c2ecf20Sopenharmony_ci
70778c2ecf20Sopenharmony_ci	r = radeon_uvd_send_upll_ctlreq(rdev, CG_UPLL_FUNC_CNTL);
70788c2ecf20Sopenharmony_ci	if (r)
70798c2ecf20Sopenharmony_ci		return r;
70808c2ecf20Sopenharmony_ci
70818c2ecf20Sopenharmony_ci	/* switch VCLK and DCLK selection */
70828c2ecf20Sopenharmony_ci	WREG32_P(CG_UPLL_FUNC_CNTL_2,
70838c2ecf20Sopenharmony_ci		VCLK_SRC_SEL(2) | DCLK_SRC_SEL(2),
70848c2ecf20Sopenharmony_ci		~(VCLK_SRC_SEL_MASK | DCLK_SRC_SEL_MASK));
70858c2ecf20Sopenharmony_ci
70868c2ecf20Sopenharmony_ci	mdelay(100);
70878c2ecf20Sopenharmony_ci
70888c2ecf20Sopenharmony_ci	return 0;
70898c2ecf20Sopenharmony_ci}
70908c2ecf20Sopenharmony_ci
70918c2ecf20Sopenharmony_cistatic void si_pcie_gen3_enable(struct radeon_device *rdev)
70928c2ecf20Sopenharmony_ci{
70938c2ecf20Sopenharmony_ci	struct pci_dev *root = rdev->pdev->bus->self;
70948c2ecf20Sopenharmony_ci	enum pci_bus_speed speed_cap;
70958c2ecf20Sopenharmony_ci	u32 speed_cntl, current_data_rate;
70968c2ecf20Sopenharmony_ci	int i;
70978c2ecf20Sopenharmony_ci	u16 tmp16;
70988c2ecf20Sopenharmony_ci
70998c2ecf20Sopenharmony_ci	if (pci_is_root_bus(rdev->pdev->bus))
71008c2ecf20Sopenharmony_ci		return;
71018c2ecf20Sopenharmony_ci
71028c2ecf20Sopenharmony_ci	if (radeon_pcie_gen2 == 0)
71038c2ecf20Sopenharmony_ci		return;
71048c2ecf20Sopenharmony_ci
71058c2ecf20Sopenharmony_ci	if (rdev->flags & RADEON_IS_IGP)
71068c2ecf20Sopenharmony_ci		return;
71078c2ecf20Sopenharmony_ci
71088c2ecf20Sopenharmony_ci	if (!(rdev->flags & RADEON_IS_PCIE))
71098c2ecf20Sopenharmony_ci		return;
71108c2ecf20Sopenharmony_ci
71118c2ecf20Sopenharmony_ci	speed_cap = pcie_get_speed_cap(root);
71128c2ecf20Sopenharmony_ci	if (speed_cap == PCI_SPEED_UNKNOWN)
71138c2ecf20Sopenharmony_ci		return;
71148c2ecf20Sopenharmony_ci
71158c2ecf20Sopenharmony_ci	if ((speed_cap != PCIE_SPEED_8_0GT) &&
71168c2ecf20Sopenharmony_ci	    (speed_cap != PCIE_SPEED_5_0GT))
71178c2ecf20Sopenharmony_ci		return;
71188c2ecf20Sopenharmony_ci
71198c2ecf20Sopenharmony_ci	speed_cntl = RREG32_PCIE_PORT(PCIE_LC_SPEED_CNTL);
71208c2ecf20Sopenharmony_ci	current_data_rate = (speed_cntl & LC_CURRENT_DATA_RATE_MASK) >>
71218c2ecf20Sopenharmony_ci		LC_CURRENT_DATA_RATE_SHIFT;
71228c2ecf20Sopenharmony_ci	if (speed_cap == PCIE_SPEED_8_0GT) {
71238c2ecf20Sopenharmony_ci		if (current_data_rate == 2) {
71248c2ecf20Sopenharmony_ci			DRM_INFO("PCIE gen 3 link speeds already enabled\n");
71258c2ecf20Sopenharmony_ci			return;
71268c2ecf20Sopenharmony_ci		}
71278c2ecf20Sopenharmony_ci		DRM_INFO("enabling PCIE gen 3 link speeds, disable with radeon.pcie_gen2=0\n");
71288c2ecf20Sopenharmony_ci	} else if (speed_cap == PCIE_SPEED_5_0GT) {
71298c2ecf20Sopenharmony_ci		if (current_data_rate == 1) {
71308c2ecf20Sopenharmony_ci			DRM_INFO("PCIE gen 2 link speeds already enabled\n");
71318c2ecf20Sopenharmony_ci			return;
71328c2ecf20Sopenharmony_ci		}
71338c2ecf20Sopenharmony_ci		DRM_INFO("enabling PCIE gen 2 link speeds, disable with radeon.pcie_gen2=0\n");
71348c2ecf20Sopenharmony_ci	}
71358c2ecf20Sopenharmony_ci
71368c2ecf20Sopenharmony_ci	if (!pci_is_pcie(root) || !pci_is_pcie(rdev->pdev))
71378c2ecf20Sopenharmony_ci		return;
71388c2ecf20Sopenharmony_ci
71398c2ecf20Sopenharmony_ci	if (speed_cap == PCIE_SPEED_8_0GT) {
71408c2ecf20Sopenharmony_ci		/* re-try equalization if gen3 is not already enabled */
71418c2ecf20Sopenharmony_ci		if (current_data_rate != 2) {
71428c2ecf20Sopenharmony_ci			u16 bridge_cfg, gpu_cfg;
71438c2ecf20Sopenharmony_ci			u16 bridge_cfg2, gpu_cfg2;
71448c2ecf20Sopenharmony_ci			u32 max_lw, current_lw, tmp;
71458c2ecf20Sopenharmony_ci
71468c2ecf20Sopenharmony_ci			pcie_capability_set_word(root, PCI_EXP_LNKCTL, PCI_EXP_LNKCTL_HAWD);
71478c2ecf20Sopenharmony_ci			pcie_capability_set_word(rdev->pdev, PCI_EXP_LNKCTL, PCI_EXP_LNKCTL_HAWD);
71488c2ecf20Sopenharmony_ci
71498c2ecf20Sopenharmony_ci			tmp = RREG32_PCIE(PCIE_LC_STATUS1);
71508c2ecf20Sopenharmony_ci			max_lw = (tmp & LC_DETECTED_LINK_WIDTH_MASK) >> LC_DETECTED_LINK_WIDTH_SHIFT;
71518c2ecf20Sopenharmony_ci			current_lw = (tmp & LC_OPERATING_LINK_WIDTH_MASK) >> LC_OPERATING_LINK_WIDTH_SHIFT;
71528c2ecf20Sopenharmony_ci
71538c2ecf20Sopenharmony_ci			if (current_lw < max_lw) {
71548c2ecf20Sopenharmony_ci				tmp = RREG32_PCIE_PORT(PCIE_LC_LINK_WIDTH_CNTL);
71558c2ecf20Sopenharmony_ci				if (tmp & LC_RENEGOTIATION_SUPPORT) {
71568c2ecf20Sopenharmony_ci					tmp &= ~(LC_LINK_WIDTH_MASK | LC_UPCONFIGURE_DIS);
71578c2ecf20Sopenharmony_ci					tmp |= (max_lw << LC_LINK_WIDTH_SHIFT);
71588c2ecf20Sopenharmony_ci					tmp |= LC_UPCONFIGURE_SUPPORT | LC_RENEGOTIATE_EN | LC_RECONFIG_NOW;
71598c2ecf20Sopenharmony_ci					WREG32_PCIE_PORT(PCIE_LC_LINK_WIDTH_CNTL, tmp);
71608c2ecf20Sopenharmony_ci				}
71618c2ecf20Sopenharmony_ci			}
71628c2ecf20Sopenharmony_ci
71638c2ecf20Sopenharmony_ci			for (i = 0; i < 10; i++) {
71648c2ecf20Sopenharmony_ci				/* check status */
71658c2ecf20Sopenharmony_ci				pcie_capability_read_word(rdev->pdev,
71668c2ecf20Sopenharmony_ci							  PCI_EXP_DEVSTA,
71678c2ecf20Sopenharmony_ci							  &tmp16);
71688c2ecf20Sopenharmony_ci				if (tmp16 & PCI_EXP_DEVSTA_TRPND)
71698c2ecf20Sopenharmony_ci					break;
71708c2ecf20Sopenharmony_ci
71718c2ecf20Sopenharmony_ci				pcie_capability_read_word(root, PCI_EXP_LNKCTL,
71728c2ecf20Sopenharmony_ci							  &bridge_cfg);
71738c2ecf20Sopenharmony_ci				pcie_capability_read_word(rdev->pdev,
71748c2ecf20Sopenharmony_ci							  PCI_EXP_LNKCTL,
71758c2ecf20Sopenharmony_ci							  &gpu_cfg);
71768c2ecf20Sopenharmony_ci
71778c2ecf20Sopenharmony_ci				pcie_capability_read_word(root, PCI_EXP_LNKCTL2,
71788c2ecf20Sopenharmony_ci							  &bridge_cfg2);
71798c2ecf20Sopenharmony_ci				pcie_capability_read_word(rdev->pdev,
71808c2ecf20Sopenharmony_ci							  PCI_EXP_LNKCTL2,
71818c2ecf20Sopenharmony_ci							  &gpu_cfg2);
71828c2ecf20Sopenharmony_ci
71838c2ecf20Sopenharmony_ci				tmp = RREG32_PCIE_PORT(PCIE_LC_CNTL4);
71848c2ecf20Sopenharmony_ci				tmp |= LC_SET_QUIESCE;
71858c2ecf20Sopenharmony_ci				WREG32_PCIE_PORT(PCIE_LC_CNTL4, tmp);
71868c2ecf20Sopenharmony_ci
71878c2ecf20Sopenharmony_ci				tmp = RREG32_PCIE_PORT(PCIE_LC_CNTL4);
71888c2ecf20Sopenharmony_ci				tmp |= LC_REDO_EQ;
71898c2ecf20Sopenharmony_ci				WREG32_PCIE_PORT(PCIE_LC_CNTL4, tmp);
71908c2ecf20Sopenharmony_ci
71918c2ecf20Sopenharmony_ci				msleep(100);
71928c2ecf20Sopenharmony_ci
71938c2ecf20Sopenharmony_ci				/* linkctl */
71948c2ecf20Sopenharmony_ci				pcie_capability_clear_and_set_word(root, PCI_EXP_LNKCTL,
71958c2ecf20Sopenharmony_ci								   PCI_EXP_LNKCTL_HAWD,
71968c2ecf20Sopenharmony_ci								   bridge_cfg &
71978c2ecf20Sopenharmony_ci								   PCI_EXP_LNKCTL_HAWD);
71988c2ecf20Sopenharmony_ci				pcie_capability_clear_and_set_word(rdev->pdev, PCI_EXP_LNKCTL,
71998c2ecf20Sopenharmony_ci								   PCI_EXP_LNKCTL_HAWD,
72008c2ecf20Sopenharmony_ci								   gpu_cfg &
72018c2ecf20Sopenharmony_ci								   PCI_EXP_LNKCTL_HAWD);
72028c2ecf20Sopenharmony_ci
72038c2ecf20Sopenharmony_ci				/* linkctl2 */
72048c2ecf20Sopenharmony_ci				pcie_capability_read_word(root, PCI_EXP_LNKCTL2,
72058c2ecf20Sopenharmony_ci							  &tmp16);
72068c2ecf20Sopenharmony_ci				tmp16 &= ~(PCI_EXP_LNKCTL2_ENTER_COMP |
72078c2ecf20Sopenharmony_ci					   PCI_EXP_LNKCTL2_TX_MARGIN);
72088c2ecf20Sopenharmony_ci				tmp16 |= (bridge_cfg2 &
72098c2ecf20Sopenharmony_ci					  (PCI_EXP_LNKCTL2_ENTER_COMP |
72108c2ecf20Sopenharmony_ci					   PCI_EXP_LNKCTL2_TX_MARGIN));
72118c2ecf20Sopenharmony_ci				pcie_capability_write_word(root,
72128c2ecf20Sopenharmony_ci							   PCI_EXP_LNKCTL2,
72138c2ecf20Sopenharmony_ci							   tmp16);
72148c2ecf20Sopenharmony_ci
72158c2ecf20Sopenharmony_ci				pcie_capability_read_word(rdev->pdev,
72168c2ecf20Sopenharmony_ci							  PCI_EXP_LNKCTL2,
72178c2ecf20Sopenharmony_ci							  &tmp16);
72188c2ecf20Sopenharmony_ci				tmp16 &= ~(PCI_EXP_LNKCTL2_ENTER_COMP |
72198c2ecf20Sopenharmony_ci					   PCI_EXP_LNKCTL2_TX_MARGIN);
72208c2ecf20Sopenharmony_ci				tmp16 |= (gpu_cfg2 &
72218c2ecf20Sopenharmony_ci					  (PCI_EXP_LNKCTL2_ENTER_COMP |
72228c2ecf20Sopenharmony_ci					   PCI_EXP_LNKCTL2_TX_MARGIN));
72238c2ecf20Sopenharmony_ci				pcie_capability_write_word(rdev->pdev,
72248c2ecf20Sopenharmony_ci							   PCI_EXP_LNKCTL2,
72258c2ecf20Sopenharmony_ci							   tmp16);
72268c2ecf20Sopenharmony_ci
72278c2ecf20Sopenharmony_ci				tmp = RREG32_PCIE_PORT(PCIE_LC_CNTL4);
72288c2ecf20Sopenharmony_ci				tmp &= ~LC_SET_QUIESCE;
72298c2ecf20Sopenharmony_ci				WREG32_PCIE_PORT(PCIE_LC_CNTL4, tmp);
72308c2ecf20Sopenharmony_ci			}
72318c2ecf20Sopenharmony_ci		}
72328c2ecf20Sopenharmony_ci	}
72338c2ecf20Sopenharmony_ci
72348c2ecf20Sopenharmony_ci	/* set the link speed */
72358c2ecf20Sopenharmony_ci	speed_cntl |= LC_FORCE_EN_SW_SPEED_CHANGE | LC_FORCE_DIS_HW_SPEED_CHANGE;
72368c2ecf20Sopenharmony_ci	speed_cntl &= ~LC_FORCE_DIS_SW_SPEED_CHANGE;
72378c2ecf20Sopenharmony_ci	WREG32_PCIE_PORT(PCIE_LC_SPEED_CNTL, speed_cntl);
72388c2ecf20Sopenharmony_ci
72398c2ecf20Sopenharmony_ci	pcie_capability_read_word(rdev->pdev, PCI_EXP_LNKCTL2, &tmp16);
72408c2ecf20Sopenharmony_ci	tmp16 &= ~PCI_EXP_LNKCTL2_TLS;
72418c2ecf20Sopenharmony_ci	if (speed_cap == PCIE_SPEED_8_0GT)
72428c2ecf20Sopenharmony_ci		tmp16 |= PCI_EXP_LNKCTL2_TLS_8_0GT; /* gen3 */
72438c2ecf20Sopenharmony_ci	else if (speed_cap == PCIE_SPEED_5_0GT)
72448c2ecf20Sopenharmony_ci		tmp16 |= PCI_EXP_LNKCTL2_TLS_5_0GT; /* gen2 */
72458c2ecf20Sopenharmony_ci	else
72468c2ecf20Sopenharmony_ci		tmp16 |= PCI_EXP_LNKCTL2_TLS_2_5GT; /* gen1 */
72478c2ecf20Sopenharmony_ci	pcie_capability_write_word(rdev->pdev, PCI_EXP_LNKCTL2, tmp16);
72488c2ecf20Sopenharmony_ci
72498c2ecf20Sopenharmony_ci	speed_cntl = RREG32_PCIE_PORT(PCIE_LC_SPEED_CNTL);
72508c2ecf20Sopenharmony_ci	speed_cntl |= LC_INITIATE_LINK_SPEED_CHANGE;
72518c2ecf20Sopenharmony_ci	WREG32_PCIE_PORT(PCIE_LC_SPEED_CNTL, speed_cntl);
72528c2ecf20Sopenharmony_ci
72538c2ecf20Sopenharmony_ci	for (i = 0; i < rdev->usec_timeout; i++) {
72548c2ecf20Sopenharmony_ci		speed_cntl = RREG32_PCIE_PORT(PCIE_LC_SPEED_CNTL);
72558c2ecf20Sopenharmony_ci		if ((speed_cntl & LC_INITIATE_LINK_SPEED_CHANGE) == 0)
72568c2ecf20Sopenharmony_ci			break;
72578c2ecf20Sopenharmony_ci		udelay(1);
72588c2ecf20Sopenharmony_ci	}
72598c2ecf20Sopenharmony_ci}
72608c2ecf20Sopenharmony_ci
72618c2ecf20Sopenharmony_cistatic void si_program_aspm(struct radeon_device *rdev)
72628c2ecf20Sopenharmony_ci{
72638c2ecf20Sopenharmony_ci	u32 data, orig;
72648c2ecf20Sopenharmony_ci	bool disable_l0s = false, disable_l1 = false, disable_plloff_in_l1 = false;
72658c2ecf20Sopenharmony_ci	bool disable_clkreq = false;
72668c2ecf20Sopenharmony_ci
72678c2ecf20Sopenharmony_ci	if (radeon_aspm == 0)
72688c2ecf20Sopenharmony_ci		return;
72698c2ecf20Sopenharmony_ci
72708c2ecf20Sopenharmony_ci	if (!(rdev->flags & RADEON_IS_PCIE))
72718c2ecf20Sopenharmony_ci		return;
72728c2ecf20Sopenharmony_ci
72738c2ecf20Sopenharmony_ci	orig = data = RREG32_PCIE_PORT(PCIE_LC_N_FTS_CNTL);
72748c2ecf20Sopenharmony_ci	data &= ~LC_XMIT_N_FTS_MASK;
72758c2ecf20Sopenharmony_ci	data |= LC_XMIT_N_FTS(0x24) | LC_XMIT_N_FTS_OVERRIDE_EN;
72768c2ecf20Sopenharmony_ci	if (orig != data)
72778c2ecf20Sopenharmony_ci		WREG32_PCIE_PORT(PCIE_LC_N_FTS_CNTL, data);
72788c2ecf20Sopenharmony_ci
72798c2ecf20Sopenharmony_ci	orig = data = RREG32_PCIE_PORT(PCIE_LC_CNTL3);
72808c2ecf20Sopenharmony_ci	data |= LC_GO_TO_RECOVERY;
72818c2ecf20Sopenharmony_ci	if (orig != data)
72828c2ecf20Sopenharmony_ci		WREG32_PCIE_PORT(PCIE_LC_CNTL3, data);
72838c2ecf20Sopenharmony_ci
72848c2ecf20Sopenharmony_ci	orig = data = RREG32_PCIE(PCIE_P_CNTL);
72858c2ecf20Sopenharmony_ci	data |= P_IGNORE_EDB_ERR;
72868c2ecf20Sopenharmony_ci	if (orig != data)
72878c2ecf20Sopenharmony_ci		WREG32_PCIE(PCIE_P_CNTL, data);
72888c2ecf20Sopenharmony_ci
72898c2ecf20Sopenharmony_ci	orig = data = RREG32_PCIE_PORT(PCIE_LC_CNTL);
72908c2ecf20Sopenharmony_ci	data &= ~(LC_L0S_INACTIVITY_MASK | LC_L1_INACTIVITY_MASK);
72918c2ecf20Sopenharmony_ci	data |= LC_PMI_TO_L1_DIS;
72928c2ecf20Sopenharmony_ci	if (!disable_l0s)
72938c2ecf20Sopenharmony_ci		data |= LC_L0S_INACTIVITY(7);
72948c2ecf20Sopenharmony_ci
72958c2ecf20Sopenharmony_ci	if (!disable_l1) {
72968c2ecf20Sopenharmony_ci		data |= LC_L1_INACTIVITY(7);
72978c2ecf20Sopenharmony_ci		data &= ~LC_PMI_TO_L1_DIS;
72988c2ecf20Sopenharmony_ci		if (orig != data)
72998c2ecf20Sopenharmony_ci			WREG32_PCIE_PORT(PCIE_LC_CNTL, data);
73008c2ecf20Sopenharmony_ci
73018c2ecf20Sopenharmony_ci		if (!disable_plloff_in_l1) {
73028c2ecf20Sopenharmony_ci			bool clk_req_support;
73038c2ecf20Sopenharmony_ci
73048c2ecf20Sopenharmony_ci			orig = data = RREG32_PIF_PHY0(PB0_PIF_PWRDOWN_0);
73058c2ecf20Sopenharmony_ci			data &= ~(PLL_POWER_STATE_IN_OFF_0_MASK | PLL_POWER_STATE_IN_TXS2_0_MASK);
73068c2ecf20Sopenharmony_ci			data |= PLL_POWER_STATE_IN_OFF_0(7) | PLL_POWER_STATE_IN_TXS2_0(7);
73078c2ecf20Sopenharmony_ci			if (orig != data)
73088c2ecf20Sopenharmony_ci				WREG32_PIF_PHY0(PB0_PIF_PWRDOWN_0, data);
73098c2ecf20Sopenharmony_ci
73108c2ecf20Sopenharmony_ci			orig = data = RREG32_PIF_PHY0(PB0_PIF_PWRDOWN_1);
73118c2ecf20Sopenharmony_ci			data &= ~(PLL_POWER_STATE_IN_OFF_1_MASK | PLL_POWER_STATE_IN_TXS2_1_MASK);
73128c2ecf20Sopenharmony_ci			data |= PLL_POWER_STATE_IN_OFF_1(7) | PLL_POWER_STATE_IN_TXS2_1(7);
73138c2ecf20Sopenharmony_ci			if (orig != data)
73148c2ecf20Sopenharmony_ci				WREG32_PIF_PHY0(PB0_PIF_PWRDOWN_1, data);
73158c2ecf20Sopenharmony_ci
73168c2ecf20Sopenharmony_ci			orig = data = RREG32_PIF_PHY1(PB1_PIF_PWRDOWN_0);
73178c2ecf20Sopenharmony_ci			data &= ~(PLL_POWER_STATE_IN_OFF_0_MASK | PLL_POWER_STATE_IN_TXS2_0_MASK);
73188c2ecf20Sopenharmony_ci			data |= PLL_POWER_STATE_IN_OFF_0(7) | PLL_POWER_STATE_IN_TXS2_0(7);
73198c2ecf20Sopenharmony_ci			if (orig != data)
73208c2ecf20Sopenharmony_ci				WREG32_PIF_PHY1(PB1_PIF_PWRDOWN_0, data);
73218c2ecf20Sopenharmony_ci
73228c2ecf20Sopenharmony_ci			orig = data = RREG32_PIF_PHY1(PB1_PIF_PWRDOWN_1);
73238c2ecf20Sopenharmony_ci			data &= ~(PLL_POWER_STATE_IN_OFF_1_MASK | PLL_POWER_STATE_IN_TXS2_1_MASK);
73248c2ecf20Sopenharmony_ci			data |= PLL_POWER_STATE_IN_OFF_1(7) | PLL_POWER_STATE_IN_TXS2_1(7);
73258c2ecf20Sopenharmony_ci			if (orig != data)
73268c2ecf20Sopenharmony_ci				WREG32_PIF_PHY1(PB1_PIF_PWRDOWN_1, data);
73278c2ecf20Sopenharmony_ci
73288c2ecf20Sopenharmony_ci			if ((rdev->family != CHIP_OLAND) && (rdev->family != CHIP_HAINAN)) {
73298c2ecf20Sopenharmony_ci				orig = data = RREG32_PIF_PHY0(PB0_PIF_PWRDOWN_0);
73308c2ecf20Sopenharmony_ci				data &= ~PLL_RAMP_UP_TIME_0_MASK;
73318c2ecf20Sopenharmony_ci				if (orig != data)
73328c2ecf20Sopenharmony_ci					WREG32_PIF_PHY0(PB0_PIF_PWRDOWN_0, data);
73338c2ecf20Sopenharmony_ci
73348c2ecf20Sopenharmony_ci				orig = data = RREG32_PIF_PHY0(PB0_PIF_PWRDOWN_1);
73358c2ecf20Sopenharmony_ci				data &= ~PLL_RAMP_UP_TIME_1_MASK;
73368c2ecf20Sopenharmony_ci				if (orig != data)
73378c2ecf20Sopenharmony_ci					WREG32_PIF_PHY0(PB0_PIF_PWRDOWN_1, data);
73388c2ecf20Sopenharmony_ci
73398c2ecf20Sopenharmony_ci				orig = data = RREG32_PIF_PHY0(PB0_PIF_PWRDOWN_2);
73408c2ecf20Sopenharmony_ci				data &= ~PLL_RAMP_UP_TIME_2_MASK;
73418c2ecf20Sopenharmony_ci				if (orig != data)
73428c2ecf20Sopenharmony_ci					WREG32_PIF_PHY0(PB0_PIF_PWRDOWN_2, data);
73438c2ecf20Sopenharmony_ci
73448c2ecf20Sopenharmony_ci				orig = data = RREG32_PIF_PHY0(PB0_PIF_PWRDOWN_3);
73458c2ecf20Sopenharmony_ci				data &= ~PLL_RAMP_UP_TIME_3_MASK;
73468c2ecf20Sopenharmony_ci				if (orig != data)
73478c2ecf20Sopenharmony_ci					WREG32_PIF_PHY0(PB0_PIF_PWRDOWN_3, data);
73488c2ecf20Sopenharmony_ci
73498c2ecf20Sopenharmony_ci				orig = data = RREG32_PIF_PHY1(PB1_PIF_PWRDOWN_0);
73508c2ecf20Sopenharmony_ci				data &= ~PLL_RAMP_UP_TIME_0_MASK;
73518c2ecf20Sopenharmony_ci				if (orig != data)
73528c2ecf20Sopenharmony_ci					WREG32_PIF_PHY1(PB1_PIF_PWRDOWN_0, data);
73538c2ecf20Sopenharmony_ci
73548c2ecf20Sopenharmony_ci				orig = data = RREG32_PIF_PHY1(PB1_PIF_PWRDOWN_1);
73558c2ecf20Sopenharmony_ci				data &= ~PLL_RAMP_UP_TIME_1_MASK;
73568c2ecf20Sopenharmony_ci				if (orig != data)
73578c2ecf20Sopenharmony_ci					WREG32_PIF_PHY1(PB1_PIF_PWRDOWN_1, data);
73588c2ecf20Sopenharmony_ci
73598c2ecf20Sopenharmony_ci				orig = data = RREG32_PIF_PHY1(PB1_PIF_PWRDOWN_2);
73608c2ecf20Sopenharmony_ci				data &= ~PLL_RAMP_UP_TIME_2_MASK;
73618c2ecf20Sopenharmony_ci				if (orig != data)
73628c2ecf20Sopenharmony_ci					WREG32_PIF_PHY1(PB1_PIF_PWRDOWN_2, data);
73638c2ecf20Sopenharmony_ci
73648c2ecf20Sopenharmony_ci				orig = data = RREG32_PIF_PHY1(PB1_PIF_PWRDOWN_3);
73658c2ecf20Sopenharmony_ci				data &= ~PLL_RAMP_UP_TIME_3_MASK;
73668c2ecf20Sopenharmony_ci				if (orig != data)
73678c2ecf20Sopenharmony_ci					WREG32_PIF_PHY1(PB1_PIF_PWRDOWN_3, data);
73688c2ecf20Sopenharmony_ci			}
73698c2ecf20Sopenharmony_ci			orig = data = RREG32_PCIE_PORT(PCIE_LC_LINK_WIDTH_CNTL);
73708c2ecf20Sopenharmony_ci			data &= ~LC_DYN_LANES_PWR_STATE_MASK;
73718c2ecf20Sopenharmony_ci			data |= LC_DYN_LANES_PWR_STATE(3);
73728c2ecf20Sopenharmony_ci			if (orig != data)
73738c2ecf20Sopenharmony_ci				WREG32_PCIE_PORT(PCIE_LC_LINK_WIDTH_CNTL, data);
73748c2ecf20Sopenharmony_ci
73758c2ecf20Sopenharmony_ci			orig = data = RREG32_PIF_PHY0(PB0_PIF_CNTL);
73768c2ecf20Sopenharmony_ci			data &= ~LS2_EXIT_TIME_MASK;
73778c2ecf20Sopenharmony_ci			if ((rdev->family == CHIP_OLAND) || (rdev->family == CHIP_HAINAN))
73788c2ecf20Sopenharmony_ci				data |= LS2_EXIT_TIME(5);
73798c2ecf20Sopenharmony_ci			if (orig != data)
73808c2ecf20Sopenharmony_ci				WREG32_PIF_PHY0(PB0_PIF_CNTL, data);
73818c2ecf20Sopenharmony_ci
73828c2ecf20Sopenharmony_ci			orig = data = RREG32_PIF_PHY1(PB1_PIF_CNTL);
73838c2ecf20Sopenharmony_ci			data &= ~LS2_EXIT_TIME_MASK;
73848c2ecf20Sopenharmony_ci			if ((rdev->family == CHIP_OLAND) || (rdev->family == CHIP_HAINAN))
73858c2ecf20Sopenharmony_ci				data |= LS2_EXIT_TIME(5);
73868c2ecf20Sopenharmony_ci			if (orig != data)
73878c2ecf20Sopenharmony_ci				WREG32_PIF_PHY1(PB1_PIF_CNTL, data);
73888c2ecf20Sopenharmony_ci
73898c2ecf20Sopenharmony_ci			if (!disable_clkreq &&
73908c2ecf20Sopenharmony_ci			    !pci_is_root_bus(rdev->pdev->bus)) {
73918c2ecf20Sopenharmony_ci				struct pci_dev *root = rdev->pdev->bus->self;
73928c2ecf20Sopenharmony_ci				u32 lnkcap;
73938c2ecf20Sopenharmony_ci
73948c2ecf20Sopenharmony_ci				clk_req_support = false;
73958c2ecf20Sopenharmony_ci				pcie_capability_read_dword(root, PCI_EXP_LNKCAP, &lnkcap);
73968c2ecf20Sopenharmony_ci				if (lnkcap & PCI_EXP_LNKCAP_CLKPM)
73978c2ecf20Sopenharmony_ci					clk_req_support = true;
73988c2ecf20Sopenharmony_ci			} else {
73998c2ecf20Sopenharmony_ci				clk_req_support = false;
74008c2ecf20Sopenharmony_ci			}
74018c2ecf20Sopenharmony_ci
74028c2ecf20Sopenharmony_ci			if (clk_req_support) {
74038c2ecf20Sopenharmony_ci				orig = data = RREG32_PCIE_PORT(PCIE_LC_CNTL2);
74048c2ecf20Sopenharmony_ci				data |= LC_ALLOW_PDWN_IN_L1 | LC_ALLOW_PDWN_IN_L23;
74058c2ecf20Sopenharmony_ci				if (orig != data)
74068c2ecf20Sopenharmony_ci					WREG32_PCIE_PORT(PCIE_LC_CNTL2, data);
74078c2ecf20Sopenharmony_ci
74088c2ecf20Sopenharmony_ci				orig = data = RREG32(THM_CLK_CNTL);
74098c2ecf20Sopenharmony_ci				data &= ~(CMON_CLK_SEL_MASK | TMON_CLK_SEL_MASK);
74108c2ecf20Sopenharmony_ci				data |= CMON_CLK_SEL(1) | TMON_CLK_SEL(1);
74118c2ecf20Sopenharmony_ci				if (orig != data)
74128c2ecf20Sopenharmony_ci					WREG32(THM_CLK_CNTL, data);
74138c2ecf20Sopenharmony_ci
74148c2ecf20Sopenharmony_ci				orig = data = RREG32(MISC_CLK_CNTL);
74158c2ecf20Sopenharmony_ci				data &= ~(DEEP_SLEEP_CLK_SEL_MASK | ZCLK_SEL_MASK);
74168c2ecf20Sopenharmony_ci				data |= DEEP_SLEEP_CLK_SEL(1) | ZCLK_SEL(1);
74178c2ecf20Sopenharmony_ci				if (orig != data)
74188c2ecf20Sopenharmony_ci					WREG32(MISC_CLK_CNTL, data);
74198c2ecf20Sopenharmony_ci
74208c2ecf20Sopenharmony_ci				orig = data = RREG32(CG_CLKPIN_CNTL);
74218c2ecf20Sopenharmony_ci				data &= ~BCLK_AS_XCLK;
74228c2ecf20Sopenharmony_ci				if (orig != data)
74238c2ecf20Sopenharmony_ci					WREG32(CG_CLKPIN_CNTL, data);
74248c2ecf20Sopenharmony_ci
74258c2ecf20Sopenharmony_ci				orig = data = RREG32(CG_CLKPIN_CNTL_2);
74268c2ecf20Sopenharmony_ci				data &= ~FORCE_BIF_REFCLK_EN;
74278c2ecf20Sopenharmony_ci				if (orig != data)
74288c2ecf20Sopenharmony_ci					WREG32(CG_CLKPIN_CNTL_2, data);
74298c2ecf20Sopenharmony_ci
74308c2ecf20Sopenharmony_ci				orig = data = RREG32(MPLL_BYPASSCLK_SEL);
74318c2ecf20Sopenharmony_ci				data &= ~MPLL_CLKOUT_SEL_MASK;
74328c2ecf20Sopenharmony_ci				data |= MPLL_CLKOUT_SEL(4);
74338c2ecf20Sopenharmony_ci				if (orig != data)
74348c2ecf20Sopenharmony_ci					WREG32(MPLL_BYPASSCLK_SEL, data);
74358c2ecf20Sopenharmony_ci
74368c2ecf20Sopenharmony_ci				orig = data = RREG32(SPLL_CNTL_MODE);
74378c2ecf20Sopenharmony_ci				data &= ~SPLL_REFCLK_SEL_MASK;
74388c2ecf20Sopenharmony_ci				if (orig != data)
74398c2ecf20Sopenharmony_ci					WREG32(SPLL_CNTL_MODE, data);
74408c2ecf20Sopenharmony_ci			}
74418c2ecf20Sopenharmony_ci		}
74428c2ecf20Sopenharmony_ci	} else {
74438c2ecf20Sopenharmony_ci		if (orig != data)
74448c2ecf20Sopenharmony_ci			WREG32_PCIE_PORT(PCIE_LC_CNTL, data);
74458c2ecf20Sopenharmony_ci	}
74468c2ecf20Sopenharmony_ci
74478c2ecf20Sopenharmony_ci	orig = data = RREG32_PCIE(PCIE_CNTL2);
74488c2ecf20Sopenharmony_ci	data |= SLV_MEM_LS_EN | MST_MEM_LS_EN | REPLAY_MEM_LS_EN;
74498c2ecf20Sopenharmony_ci	if (orig != data)
74508c2ecf20Sopenharmony_ci		WREG32_PCIE(PCIE_CNTL2, data);
74518c2ecf20Sopenharmony_ci
74528c2ecf20Sopenharmony_ci	if (!disable_l0s) {
74538c2ecf20Sopenharmony_ci		data = RREG32_PCIE_PORT(PCIE_LC_N_FTS_CNTL);
74548c2ecf20Sopenharmony_ci		if((data & LC_N_FTS_MASK) == LC_N_FTS_MASK) {
74558c2ecf20Sopenharmony_ci			data = RREG32_PCIE(PCIE_LC_STATUS1);
74568c2ecf20Sopenharmony_ci			if ((data & LC_REVERSE_XMIT) && (data & LC_REVERSE_RCVR)) {
74578c2ecf20Sopenharmony_ci				orig = data = RREG32_PCIE_PORT(PCIE_LC_CNTL);
74588c2ecf20Sopenharmony_ci				data &= ~LC_L0S_INACTIVITY_MASK;
74598c2ecf20Sopenharmony_ci				if (orig != data)
74608c2ecf20Sopenharmony_ci					WREG32_PCIE_PORT(PCIE_LC_CNTL, data);
74618c2ecf20Sopenharmony_ci			}
74628c2ecf20Sopenharmony_ci		}
74638c2ecf20Sopenharmony_ci	}
74648c2ecf20Sopenharmony_ci}
74658c2ecf20Sopenharmony_ci
74668c2ecf20Sopenharmony_cistatic int si_vce_send_vcepll_ctlreq(struct radeon_device *rdev)
74678c2ecf20Sopenharmony_ci{
74688c2ecf20Sopenharmony_ci	unsigned i;
74698c2ecf20Sopenharmony_ci
74708c2ecf20Sopenharmony_ci	/* make sure VCEPLL_CTLREQ is deasserted */
74718c2ecf20Sopenharmony_ci	WREG32_SMC_P(CG_VCEPLL_FUNC_CNTL, 0, ~UPLL_CTLREQ_MASK);
74728c2ecf20Sopenharmony_ci
74738c2ecf20Sopenharmony_ci	mdelay(10);
74748c2ecf20Sopenharmony_ci
74758c2ecf20Sopenharmony_ci	/* assert UPLL_CTLREQ */
74768c2ecf20Sopenharmony_ci	WREG32_SMC_P(CG_VCEPLL_FUNC_CNTL, UPLL_CTLREQ_MASK, ~UPLL_CTLREQ_MASK);
74778c2ecf20Sopenharmony_ci
74788c2ecf20Sopenharmony_ci	/* wait for CTLACK and CTLACK2 to get asserted */
74798c2ecf20Sopenharmony_ci	for (i = 0; i < 100; ++i) {
74808c2ecf20Sopenharmony_ci		uint32_t mask = UPLL_CTLACK_MASK | UPLL_CTLACK2_MASK;
74818c2ecf20Sopenharmony_ci		if ((RREG32_SMC(CG_VCEPLL_FUNC_CNTL) & mask) == mask)
74828c2ecf20Sopenharmony_ci			break;
74838c2ecf20Sopenharmony_ci		mdelay(10);
74848c2ecf20Sopenharmony_ci	}
74858c2ecf20Sopenharmony_ci
74868c2ecf20Sopenharmony_ci	/* deassert UPLL_CTLREQ */
74878c2ecf20Sopenharmony_ci	WREG32_SMC_P(CG_VCEPLL_FUNC_CNTL, 0, ~UPLL_CTLREQ_MASK);
74888c2ecf20Sopenharmony_ci
74898c2ecf20Sopenharmony_ci	if (i == 100) {
74908c2ecf20Sopenharmony_ci		DRM_ERROR("Timeout setting UVD clocks!\n");
74918c2ecf20Sopenharmony_ci		return -ETIMEDOUT;
74928c2ecf20Sopenharmony_ci	}
74938c2ecf20Sopenharmony_ci
74948c2ecf20Sopenharmony_ci	return 0;
74958c2ecf20Sopenharmony_ci}
74968c2ecf20Sopenharmony_ci
74978c2ecf20Sopenharmony_ciint si_set_vce_clocks(struct radeon_device *rdev, u32 evclk, u32 ecclk)
74988c2ecf20Sopenharmony_ci{
74998c2ecf20Sopenharmony_ci	unsigned fb_div = 0, evclk_div = 0, ecclk_div = 0;
75008c2ecf20Sopenharmony_ci	int r;
75018c2ecf20Sopenharmony_ci
75028c2ecf20Sopenharmony_ci	/* bypass evclk and ecclk with bclk */
75038c2ecf20Sopenharmony_ci	WREG32_SMC_P(CG_VCEPLL_FUNC_CNTL_2,
75048c2ecf20Sopenharmony_ci		     EVCLK_SRC_SEL(1) | ECCLK_SRC_SEL(1),
75058c2ecf20Sopenharmony_ci		     ~(EVCLK_SRC_SEL_MASK | ECCLK_SRC_SEL_MASK));
75068c2ecf20Sopenharmony_ci
75078c2ecf20Sopenharmony_ci	/* put PLL in bypass mode */
75088c2ecf20Sopenharmony_ci	WREG32_SMC_P(CG_VCEPLL_FUNC_CNTL, VCEPLL_BYPASS_EN_MASK,
75098c2ecf20Sopenharmony_ci		     ~VCEPLL_BYPASS_EN_MASK);
75108c2ecf20Sopenharmony_ci
75118c2ecf20Sopenharmony_ci	if (!evclk || !ecclk) {
75128c2ecf20Sopenharmony_ci		/* keep the Bypass mode, put PLL to sleep */
75138c2ecf20Sopenharmony_ci		WREG32_SMC_P(CG_VCEPLL_FUNC_CNTL, VCEPLL_SLEEP_MASK,
75148c2ecf20Sopenharmony_ci			     ~VCEPLL_SLEEP_MASK);
75158c2ecf20Sopenharmony_ci		return 0;
75168c2ecf20Sopenharmony_ci	}
75178c2ecf20Sopenharmony_ci
75188c2ecf20Sopenharmony_ci	r = radeon_uvd_calc_upll_dividers(rdev, evclk, ecclk, 125000, 250000,
75198c2ecf20Sopenharmony_ci					  16384, 0x03FFFFFF, 0, 128, 5,
75208c2ecf20Sopenharmony_ci					  &fb_div, &evclk_div, &ecclk_div);
75218c2ecf20Sopenharmony_ci	if (r)
75228c2ecf20Sopenharmony_ci		return r;
75238c2ecf20Sopenharmony_ci
75248c2ecf20Sopenharmony_ci	/* set RESET_ANTI_MUX to 0 */
75258c2ecf20Sopenharmony_ci	WREG32_SMC_P(CG_VCEPLL_FUNC_CNTL_5, 0, ~RESET_ANTI_MUX_MASK);
75268c2ecf20Sopenharmony_ci
75278c2ecf20Sopenharmony_ci	/* set VCO_MODE to 1 */
75288c2ecf20Sopenharmony_ci	WREG32_SMC_P(CG_VCEPLL_FUNC_CNTL, VCEPLL_VCO_MODE_MASK,
75298c2ecf20Sopenharmony_ci		     ~VCEPLL_VCO_MODE_MASK);
75308c2ecf20Sopenharmony_ci
75318c2ecf20Sopenharmony_ci	/* toggle VCEPLL_SLEEP to 1 then back to 0 */
75328c2ecf20Sopenharmony_ci	WREG32_SMC_P(CG_VCEPLL_FUNC_CNTL, VCEPLL_SLEEP_MASK,
75338c2ecf20Sopenharmony_ci		     ~VCEPLL_SLEEP_MASK);
75348c2ecf20Sopenharmony_ci	WREG32_SMC_P(CG_VCEPLL_FUNC_CNTL, 0, ~VCEPLL_SLEEP_MASK);
75358c2ecf20Sopenharmony_ci
75368c2ecf20Sopenharmony_ci	/* deassert VCEPLL_RESET */
75378c2ecf20Sopenharmony_ci	WREG32_SMC_P(CG_VCEPLL_FUNC_CNTL, 0, ~VCEPLL_RESET_MASK);
75388c2ecf20Sopenharmony_ci
75398c2ecf20Sopenharmony_ci	mdelay(1);
75408c2ecf20Sopenharmony_ci
75418c2ecf20Sopenharmony_ci	r = si_vce_send_vcepll_ctlreq(rdev);
75428c2ecf20Sopenharmony_ci	if (r)
75438c2ecf20Sopenharmony_ci		return r;
75448c2ecf20Sopenharmony_ci
75458c2ecf20Sopenharmony_ci	/* assert VCEPLL_RESET again */
75468c2ecf20Sopenharmony_ci	WREG32_SMC_P(CG_VCEPLL_FUNC_CNTL, VCEPLL_RESET_MASK, ~VCEPLL_RESET_MASK);
75478c2ecf20Sopenharmony_ci
75488c2ecf20Sopenharmony_ci	/* disable spread spectrum. */
75498c2ecf20Sopenharmony_ci	WREG32_SMC_P(CG_VCEPLL_SPREAD_SPECTRUM, 0, ~SSEN_MASK);
75508c2ecf20Sopenharmony_ci
75518c2ecf20Sopenharmony_ci	/* set feedback divider */
75528c2ecf20Sopenharmony_ci	WREG32_SMC_P(CG_VCEPLL_FUNC_CNTL_3, VCEPLL_FB_DIV(fb_div), ~VCEPLL_FB_DIV_MASK);
75538c2ecf20Sopenharmony_ci
75548c2ecf20Sopenharmony_ci	/* set ref divider to 0 */
75558c2ecf20Sopenharmony_ci	WREG32_SMC_P(CG_VCEPLL_FUNC_CNTL, 0, ~VCEPLL_REF_DIV_MASK);
75568c2ecf20Sopenharmony_ci
75578c2ecf20Sopenharmony_ci	/* set PDIV_A and PDIV_B */
75588c2ecf20Sopenharmony_ci	WREG32_SMC_P(CG_VCEPLL_FUNC_CNTL_2,
75598c2ecf20Sopenharmony_ci		     VCEPLL_PDIV_A(evclk_div) | VCEPLL_PDIV_B(ecclk_div),
75608c2ecf20Sopenharmony_ci		     ~(VCEPLL_PDIV_A_MASK | VCEPLL_PDIV_B_MASK));
75618c2ecf20Sopenharmony_ci
75628c2ecf20Sopenharmony_ci	/* give the PLL some time to settle */
75638c2ecf20Sopenharmony_ci	mdelay(15);
75648c2ecf20Sopenharmony_ci
75658c2ecf20Sopenharmony_ci	/* deassert PLL_RESET */
75668c2ecf20Sopenharmony_ci	WREG32_SMC_P(CG_VCEPLL_FUNC_CNTL, 0, ~VCEPLL_RESET_MASK);
75678c2ecf20Sopenharmony_ci
75688c2ecf20Sopenharmony_ci	mdelay(15);
75698c2ecf20Sopenharmony_ci
75708c2ecf20Sopenharmony_ci	/* switch from bypass mode to normal mode */
75718c2ecf20Sopenharmony_ci	WREG32_SMC_P(CG_VCEPLL_FUNC_CNTL, 0, ~VCEPLL_BYPASS_EN_MASK);
75728c2ecf20Sopenharmony_ci
75738c2ecf20Sopenharmony_ci	r = si_vce_send_vcepll_ctlreq(rdev);
75748c2ecf20Sopenharmony_ci	if (r)
75758c2ecf20Sopenharmony_ci		return r;
75768c2ecf20Sopenharmony_ci
75778c2ecf20Sopenharmony_ci	/* switch VCLK and DCLK selection */
75788c2ecf20Sopenharmony_ci	WREG32_SMC_P(CG_VCEPLL_FUNC_CNTL_2,
75798c2ecf20Sopenharmony_ci		     EVCLK_SRC_SEL(16) | ECCLK_SRC_SEL(16),
75808c2ecf20Sopenharmony_ci		     ~(EVCLK_SRC_SEL_MASK | ECCLK_SRC_SEL_MASK));
75818c2ecf20Sopenharmony_ci
75828c2ecf20Sopenharmony_ci	mdelay(100);
75838c2ecf20Sopenharmony_ci
75848c2ecf20Sopenharmony_ci	return 0;
75858c2ecf20Sopenharmony_ci}
7586