xref: /dflybsd-src/sys/dev/drm/radeon/si.c (revision 3f2dd94a569761201b5b0a18b2f697f97fe1b9dc)
1926deccbSFrançois Tigeot /*
2926deccbSFrançois Tigeot  * Copyright 2011 Advanced Micro Devices, Inc.
3926deccbSFrançois Tigeot  *
4926deccbSFrançois Tigeot  * Permission is hereby granted, free of charge, to any person obtaining a
5926deccbSFrançois Tigeot  * copy of this software and associated documentation files (the "Software"),
6926deccbSFrançois Tigeot  * to deal in the Software without restriction, including without limitation
7926deccbSFrançois Tigeot  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8926deccbSFrançois Tigeot  * and/or sell copies of the Software, and to permit persons to whom the
9926deccbSFrançois Tigeot  * Software is furnished to do so, subject to the following conditions:
10926deccbSFrançois Tigeot  *
11926deccbSFrançois Tigeot  * The above copyright notice and this permission notice shall be included in
12926deccbSFrançois Tigeot  * all copies or substantial portions of the Software.
13926deccbSFrançois Tigeot  *
14926deccbSFrançois Tigeot  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15926deccbSFrançois Tigeot  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16926deccbSFrançois Tigeot  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
17926deccbSFrançois Tigeot  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18926deccbSFrançois Tigeot  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19926deccbSFrançois Tigeot  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20926deccbSFrançois Tigeot  * OTHER DEALINGS IN THE SOFTWARE.
21926deccbSFrançois Tigeot  *
22926deccbSFrançois Tigeot  * Authors: Alex Deucher
23926deccbSFrançois Tigeot  */
2457e252bfSMichael Neumann #include <linux/firmware.h>
25*3f2dd94aSFrançois Tigeot #include <linux/slab.h>
26fcd4983fSzrj #include <linux/module.h>
27fcd4983fSzrj #include <drm/drmP.h>
28926deccbSFrançois Tigeot #include "radeon.h"
29926deccbSFrançois Tigeot #include "radeon_asic.h"
30c59a5c48SFrançois Tigeot #include "radeon_audio.h"
3183b4b9b9SFrançois Tigeot #include <drm/radeon_drm.h>
32926deccbSFrançois Tigeot #include "sid.h"
33926deccbSFrançois Tigeot #include "atom.h"
34926deccbSFrançois Tigeot #include "si_blit_shaders.h"
3557e252bfSMichael Neumann #include "clearstate_si.h"
3657e252bfSMichael Neumann #include "radeon_ucode.h"
37926deccbSFrançois Tigeot 
38b403bed8SMichael Neumann 
39fcd4983fSzrj MODULE_FIRMWARE("radeon/TAHITI_pfp.bin");
40fcd4983fSzrj MODULE_FIRMWARE("radeon/TAHITI_me.bin");
4157e252bfSMichael Neumann MODULE_FIRMWARE("radeon/TAHITI_ce.bin");
4257e252bfSMichael Neumann MODULE_FIRMWARE("radeon/TAHITI_mc.bin");
43c6f73aabSFrançois Tigeot MODULE_FIRMWARE("radeon/TAHITI_mc2.bin");
4457e252bfSMichael Neumann MODULE_FIRMWARE("radeon/TAHITI_rlc.bin");
4557e252bfSMichael Neumann MODULE_FIRMWARE("radeon/TAHITI_smc.bin");
46cb754608SImre Vadász 
47cb754608SImre Vadász MODULE_FIRMWARE("radeon/tahiti_pfp.bin");
48cb754608SImre Vadász MODULE_FIRMWARE("radeon/tahiti_me.bin");
49cb754608SImre Vadász MODULE_FIRMWARE("radeon/tahiti_ce.bin");
50cb754608SImre Vadász MODULE_FIRMWARE("radeon/tahiti_mc.bin");
51cb754608SImre Vadász MODULE_FIRMWARE("radeon/tahiti_rlc.bin");
52cb754608SImre Vadász MODULE_FIRMWARE("radeon/tahiti_smc.bin");
53cb754608SImre Vadász 
5457e252bfSMichael Neumann MODULE_FIRMWARE("radeon/PITCAIRN_pfp.bin");
5557e252bfSMichael Neumann MODULE_FIRMWARE("radeon/PITCAIRN_me.bin");
5657e252bfSMichael Neumann MODULE_FIRMWARE("radeon/PITCAIRN_ce.bin");
5757e252bfSMichael Neumann MODULE_FIRMWARE("radeon/PITCAIRN_mc.bin");
58c6f73aabSFrançois Tigeot MODULE_FIRMWARE("radeon/PITCAIRN_mc2.bin");
5957e252bfSMichael Neumann MODULE_FIRMWARE("radeon/PITCAIRN_rlc.bin");
6057e252bfSMichael Neumann MODULE_FIRMWARE("radeon/PITCAIRN_smc.bin");
61cb754608SImre Vadász 
62cb754608SImre Vadász MODULE_FIRMWARE("radeon/pitcairn_pfp.bin");
63cb754608SImre Vadász MODULE_FIRMWARE("radeon/pitcairn_me.bin");
64cb754608SImre Vadász MODULE_FIRMWARE("radeon/pitcairn_ce.bin");
65cb754608SImre Vadász MODULE_FIRMWARE("radeon/pitcairn_mc.bin");
66cb754608SImre Vadász MODULE_FIRMWARE("radeon/pitcairn_rlc.bin");
67cb754608SImre Vadász MODULE_FIRMWARE("radeon/pitcairn_smc.bin");
681dedbd3bSFrançois Tigeot MODULE_FIRMWARE("radeon/pitcairn_k_smc.bin");
69cb754608SImre Vadász 
7057e252bfSMichael Neumann MODULE_FIRMWARE("radeon/VERDE_pfp.bin");
7157e252bfSMichael Neumann MODULE_FIRMWARE("radeon/VERDE_me.bin");
7257e252bfSMichael Neumann MODULE_FIRMWARE("radeon/VERDE_ce.bin");
7357e252bfSMichael Neumann MODULE_FIRMWARE("radeon/VERDE_mc.bin");
74c6f73aabSFrançois Tigeot MODULE_FIRMWARE("radeon/VERDE_mc2.bin");
7557e252bfSMichael Neumann MODULE_FIRMWARE("radeon/VERDE_rlc.bin");
7657e252bfSMichael Neumann MODULE_FIRMWARE("radeon/VERDE_smc.bin");
77cb754608SImre Vadász 
78cb754608SImre Vadász MODULE_FIRMWARE("radeon/verde_pfp.bin");
79cb754608SImre Vadász MODULE_FIRMWARE("radeon/verde_me.bin");
80cb754608SImre Vadász MODULE_FIRMWARE("radeon/verde_ce.bin");
81cb754608SImre Vadász MODULE_FIRMWARE("radeon/verde_mc.bin");
82cb754608SImre Vadász MODULE_FIRMWARE("radeon/verde_rlc.bin");
83cb754608SImre Vadász MODULE_FIRMWARE("radeon/verde_smc.bin");
841dedbd3bSFrançois Tigeot MODULE_FIRMWARE("radeon/verde_k_smc.bin");
85cb754608SImre Vadász 
8657e252bfSMichael Neumann MODULE_FIRMWARE("radeon/OLAND_pfp.bin");
8757e252bfSMichael Neumann MODULE_FIRMWARE("radeon/OLAND_me.bin");
8857e252bfSMichael Neumann MODULE_FIRMWARE("radeon/OLAND_ce.bin");
8957e252bfSMichael Neumann MODULE_FIRMWARE("radeon/OLAND_mc.bin");
90c6f73aabSFrançois Tigeot MODULE_FIRMWARE("radeon/OLAND_mc2.bin");
9157e252bfSMichael Neumann MODULE_FIRMWARE("radeon/OLAND_rlc.bin");
9257e252bfSMichael Neumann MODULE_FIRMWARE("radeon/OLAND_smc.bin");
93cb754608SImre Vadász 
94cb754608SImre Vadász MODULE_FIRMWARE("radeon/oland_pfp.bin");
95cb754608SImre Vadász MODULE_FIRMWARE("radeon/oland_me.bin");
96cb754608SImre Vadász MODULE_FIRMWARE("radeon/oland_ce.bin");
97cb754608SImre Vadász MODULE_FIRMWARE("radeon/oland_mc.bin");
98cb754608SImre Vadász MODULE_FIRMWARE("radeon/oland_rlc.bin");
99cb754608SImre Vadász MODULE_FIRMWARE("radeon/oland_smc.bin");
1001dedbd3bSFrançois Tigeot MODULE_FIRMWARE("radeon/oland_k_smc.bin");
101cb754608SImre Vadász 
10257e252bfSMichael Neumann MODULE_FIRMWARE("radeon/HAINAN_pfp.bin");
10357e252bfSMichael Neumann MODULE_FIRMWARE("radeon/HAINAN_me.bin");
10457e252bfSMichael Neumann MODULE_FIRMWARE("radeon/HAINAN_ce.bin");
10557e252bfSMichael Neumann MODULE_FIRMWARE("radeon/HAINAN_mc.bin");
106c6f73aabSFrançois Tigeot MODULE_FIRMWARE("radeon/HAINAN_mc2.bin");
10757e252bfSMichael Neumann MODULE_FIRMWARE("radeon/HAINAN_rlc.bin");
10857e252bfSMichael Neumann MODULE_FIRMWARE("radeon/HAINAN_smc.bin");
10957e252bfSMichael Neumann 
110cb754608SImre Vadász MODULE_FIRMWARE("radeon/hainan_pfp.bin");
111cb754608SImre Vadász MODULE_FIRMWARE("radeon/hainan_me.bin");
112cb754608SImre Vadász MODULE_FIRMWARE("radeon/hainan_ce.bin");
113cb754608SImre Vadász MODULE_FIRMWARE("radeon/hainan_mc.bin");
114cb754608SImre Vadász MODULE_FIRMWARE("radeon/hainan_rlc.bin");
115cb754608SImre Vadász MODULE_FIRMWARE("radeon/hainan_smc.bin");
1161dedbd3bSFrançois Tigeot MODULE_FIRMWARE("radeon/hainan_k_smc.bin");
1174be47400SFrançois Tigeot MODULE_FIRMWARE("radeon/banks_k_2_smc.bin");
1184be47400SFrançois Tigeot 
1194be47400SFrançois Tigeot MODULE_FIRMWARE("radeon/si58_mc.bin");
120cb754608SImre Vadász 
121c6f73aabSFrançois Tigeot static u32 si_get_cu_active_bitmap(struct radeon_device *rdev, u32 se, u32 sh);
12257e252bfSMichael Neumann static void si_pcie_gen3_enable(struct radeon_device *rdev);
12357e252bfSMichael Neumann static void si_program_aspm(struct radeon_device *rdev);
1244cd92098Szrj static void si_enable_gui_idle_interrupt(struct radeon_device *rdev,
1254cd92098Szrj 					 bool enable);
126c6f73aabSFrançois Tigeot static void si_init_pg(struct radeon_device *rdev);
127c6f73aabSFrançois Tigeot static void si_init_cg(struct radeon_device *rdev);
1284cd92098Szrj static void si_fini_pg(struct radeon_device *rdev);
1294cd92098Szrj static void si_fini_cg(struct radeon_device *rdev);
1304cd92098Szrj static void si_rlc_stop(struct radeon_device *rdev);
13157e252bfSMichael Neumann 
132*3f2dd94aSFrançois Tigeot static const u32 crtc_offsets[] =
133*3f2dd94aSFrançois Tigeot {
134*3f2dd94aSFrançois Tigeot 	EVERGREEN_CRTC0_REGISTER_OFFSET,
135*3f2dd94aSFrançois Tigeot 	EVERGREEN_CRTC1_REGISTER_OFFSET,
136*3f2dd94aSFrançois Tigeot 	EVERGREEN_CRTC2_REGISTER_OFFSET,
137*3f2dd94aSFrançois Tigeot 	EVERGREEN_CRTC3_REGISTER_OFFSET,
138*3f2dd94aSFrançois Tigeot 	EVERGREEN_CRTC4_REGISTER_OFFSET,
139*3f2dd94aSFrançois Tigeot 	EVERGREEN_CRTC5_REGISTER_OFFSET
140*3f2dd94aSFrançois Tigeot };
141*3f2dd94aSFrançois Tigeot 
142*3f2dd94aSFrançois Tigeot static const u32 si_disp_int_status[] =
143*3f2dd94aSFrançois Tigeot {
144*3f2dd94aSFrançois Tigeot 	DISP_INTERRUPT_STATUS,
145*3f2dd94aSFrançois Tigeot 	DISP_INTERRUPT_STATUS_CONTINUE,
146*3f2dd94aSFrançois Tigeot 	DISP_INTERRUPT_STATUS_CONTINUE2,
147*3f2dd94aSFrançois Tigeot 	DISP_INTERRUPT_STATUS_CONTINUE3,
148*3f2dd94aSFrançois Tigeot 	DISP_INTERRUPT_STATUS_CONTINUE4,
149*3f2dd94aSFrançois Tigeot 	DISP_INTERRUPT_STATUS_CONTINUE5
150*3f2dd94aSFrançois Tigeot };
151*3f2dd94aSFrançois Tigeot 
152*3f2dd94aSFrançois Tigeot #define DC_HPDx_CONTROL(x)        (DC_HPD1_CONTROL     + (x * 0xc))
153*3f2dd94aSFrançois Tigeot #define DC_HPDx_INT_CONTROL(x)    (DC_HPD1_INT_CONTROL + (x * 0xc))
154*3f2dd94aSFrançois Tigeot #define DC_HPDx_INT_STATUS_REG(x) (DC_HPD1_INT_STATUS  + (x * 0xc))
155*3f2dd94aSFrançois Tigeot 
15657e252bfSMichael Neumann static const u32 verde_rlc_save_restore_register_list[] =
15757e252bfSMichael Neumann {
15857e252bfSMichael Neumann 	(0x8000 << 16) | (0x98f4 >> 2),
15957e252bfSMichael Neumann 	0x00000000,
16057e252bfSMichael Neumann 	(0x8040 << 16) | (0x98f4 >> 2),
16157e252bfSMichael Neumann 	0x00000000,
16257e252bfSMichael Neumann 	(0x8000 << 16) | (0xe80 >> 2),
16357e252bfSMichael Neumann 	0x00000000,
16457e252bfSMichael Neumann 	(0x8040 << 16) | (0xe80 >> 2),
16557e252bfSMichael Neumann 	0x00000000,
16657e252bfSMichael Neumann 	(0x8000 << 16) | (0x89bc >> 2),
16757e252bfSMichael Neumann 	0x00000000,
16857e252bfSMichael Neumann 	(0x8040 << 16) | (0x89bc >> 2),
16957e252bfSMichael Neumann 	0x00000000,
17057e252bfSMichael Neumann 	(0x8000 << 16) | (0x8c1c >> 2),
17157e252bfSMichael Neumann 	0x00000000,
17257e252bfSMichael Neumann 	(0x8040 << 16) | (0x8c1c >> 2),
17357e252bfSMichael Neumann 	0x00000000,
17457e252bfSMichael Neumann 	(0x9c00 << 16) | (0x98f0 >> 2),
17557e252bfSMichael Neumann 	0x00000000,
17657e252bfSMichael Neumann 	(0x9c00 << 16) | (0xe7c >> 2),
17757e252bfSMichael Neumann 	0x00000000,
17857e252bfSMichael Neumann 	(0x8000 << 16) | (0x9148 >> 2),
17957e252bfSMichael Neumann 	0x00000000,
18057e252bfSMichael Neumann 	(0x8040 << 16) | (0x9148 >> 2),
18157e252bfSMichael Neumann 	0x00000000,
18257e252bfSMichael Neumann 	(0x9c00 << 16) | (0x9150 >> 2),
18357e252bfSMichael Neumann 	0x00000000,
18457e252bfSMichael Neumann 	(0x9c00 << 16) | (0x897c >> 2),
18557e252bfSMichael Neumann 	0x00000000,
18657e252bfSMichael Neumann 	(0x9c00 << 16) | (0x8d8c >> 2),
18757e252bfSMichael Neumann 	0x00000000,
18857e252bfSMichael Neumann 	(0x9c00 << 16) | (0xac54 >> 2),
18957e252bfSMichael Neumann 	0X00000000,
19057e252bfSMichael Neumann 	0x3,
19157e252bfSMichael Neumann 	(0x9c00 << 16) | (0x98f8 >> 2),
19257e252bfSMichael Neumann 	0x00000000,
19357e252bfSMichael Neumann 	(0x9c00 << 16) | (0x9910 >> 2),
19457e252bfSMichael Neumann 	0x00000000,
19557e252bfSMichael Neumann 	(0x9c00 << 16) | (0x9914 >> 2),
19657e252bfSMichael Neumann 	0x00000000,
19757e252bfSMichael Neumann 	(0x9c00 << 16) | (0x9918 >> 2),
19857e252bfSMichael Neumann 	0x00000000,
19957e252bfSMichael Neumann 	(0x9c00 << 16) | (0x991c >> 2),
20057e252bfSMichael Neumann 	0x00000000,
20157e252bfSMichael Neumann 	(0x9c00 << 16) | (0x9920 >> 2),
20257e252bfSMichael Neumann 	0x00000000,
20357e252bfSMichael Neumann 	(0x9c00 << 16) | (0x9924 >> 2),
20457e252bfSMichael Neumann 	0x00000000,
20557e252bfSMichael Neumann 	(0x9c00 << 16) | (0x9928 >> 2),
20657e252bfSMichael Neumann 	0x00000000,
20757e252bfSMichael Neumann 	(0x9c00 << 16) | (0x992c >> 2),
20857e252bfSMichael Neumann 	0x00000000,
20957e252bfSMichael Neumann 	(0x9c00 << 16) | (0x9930 >> 2),
21057e252bfSMichael Neumann 	0x00000000,
21157e252bfSMichael Neumann 	(0x9c00 << 16) | (0x9934 >> 2),
21257e252bfSMichael Neumann 	0x00000000,
21357e252bfSMichael Neumann 	(0x9c00 << 16) | (0x9938 >> 2),
21457e252bfSMichael Neumann 	0x00000000,
21557e252bfSMichael Neumann 	(0x9c00 << 16) | (0x993c >> 2),
21657e252bfSMichael Neumann 	0x00000000,
21757e252bfSMichael Neumann 	(0x9c00 << 16) | (0x9940 >> 2),
21857e252bfSMichael Neumann 	0x00000000,
21957e252bfSMichael Neumann 	(0x9c00 << 16) | (0x9944 >> 2),
22057e252bfSMichael Neumann 	0x00000000,
22157e252bfSMichael Neumann 	(0x9c00 << 16) | (0x9948 >> 2),
22257e252bfSMichael Neumann 	0x00000000,
22357e252bfSMichael Neumann 	(0x9c00 << 16) | (0x994c >> 2),
22457e252bfSMichael Neumann 	0x00000000,
22557e252bfSMichael Neumann 	(0x9c00 << 16) | (0x9950 >> 2),
22657e252bfSMichael Neumann 	0x00000000,
22757e252bfSMichael Neumann 	(0x9c00 << 16) | (0x9954 >> 2),
22857e252bfSMichael Neumann 	0x00000000,
22957e252bfSMichael Neumann 	(0x9c00 << 16) | (0x9958 >> 2),
23057e252bfSMichael Neumann 	0x00000000,
23157e252bfSMichael Neumann 	(0x9c00 << 16) | (0x995c >> 2),
23257e252bfSMichael Neumann 	0x00000000,
23357e252bfSMichael Neumann 	(0x9c00 << 16) | (0x9960 >> 2),
23457e252bfSMichael Neumann 	0x00000000,
23557e252bfSMichael Neumann 	(0x9c00 << 16) | (0x9964 >> 2),
23657e252bfSMichael Neumann 	0x00000000,
23757e252bfSMichael Neumann 	(0x9c00 << 16) | (0x9968 >> 2),
23857e252bfSMichael Neumann 	0x00000000,
23957e252bfSMichael Neumann 	(0x9c00 << 16) | (0x996c >> 2),
24057e252bfSMichael Neumann 	0x00000000,
24157e252bfSMichael Neumann 	(0x9c00 << 16) | (0x9970 >> 2),
24257e252bfSMichael Neumann 	0x00000000,
24357e252bfSMichael Neumann 	(0x9c00 << 16) | (0x9974 >> 2),
24457e252bfSMichael Neumann 	0x00000000,
24557e252bfSMichael Neumann 	(0x9c00 << 16) | (0x9978 >> 2),
24657e252bfSMichael Neumann 	0x00000000,
24757e252bfSMichael Neumann 	(0x9c00 << 16) | (0x997c >> 2),
24857e252bfSMichael Neumann 	0x00000000,
24957e252bfSMichael Neumann 	(0x9c00 << 16) | (0x9980 >> 2),
25057e252bfSMichael Neumann 	0x00000000,
25157e252bfSMichael Neumann 	(0x9c00 << 16) | (0x9984 >> 2),
25257e252bfSMichael Neumann 	0x00000000,
25357e252bfSMichael Neumann 	(0x9c00 << 16) | (0x9988 >> 2),
25457e252bfSMichael Neumann 	0x00000000,
25557e252bfSMichael Neumann 	(0x9c00 << 16) | (0x998c >> 2),
25657e252bfSMichael Neumann 	0x00000000,
25757e252bfSMichael Neumann 	(0x9c00 << 16) | (0x8c00 >> 2),
25857e252bfSMichael Neumann 	0x00000000,
25957e252bfSMichael Neumann 	(0x9c00 << 16) | (0x8c14 >> 2),
26057e252bfSMichael Neumann 	0x00000000,
26157e252bfSMichael Neumann 	(0x9c00 << 16) | (0x8c04 >> 2),
26257e252bfSMichael Neumann 	0x00000000,
26357e252bfSMichael Neumann 	(0x9c00 << 16) | (0x8c08 >> 2),
26457e252bfSMichael Neumann 	0x00000000,
26557e252bfSMichael Neumann 	(0x8000 << 16) | (0x9b7c >> 2),
26657e252bfSMichael Neumann 	0x00000000,
26757e252bfSMichael Neumann 	(0x8040 << 16) | (0x9b7c >> 2),
26857e252bfSMichael Neumann 	0x00000000,
26957e252bfSMichael Neumann 	(0x8000 << 16) | (0xe84 >> 2),
27057e252bfSMichael Neumann 	0x00000000,
27157e252bfSMichael Neumann 	(0x8040 << 16) | (0xe84 >> 2),
27257e252bfSMichael Neumann 	0x00000000,
27357e252bfSMichael Neumann 	(0x8000 << 16) | (0x89c0 >> 2),
27457e252bfSMichael Neumann 	0x00000000,
27557e252bfSMichael Neumann 	(0x8040 << 16) | (0x89c0 >> 2),
27657e252bfSMichael Neumann 	0x00000000,
27757e252bfSMichael Neumann 	(0x8000 << 16) | (0x914c >> 2),
27857e252bfSMichael Neumann 	0x00000000,
27957e252bfSMichael Neumann 	(0x8040 << 16) | (0x914c >> 2),
28057e252bfSMichael Neumann 	0x00000000,
28157e252bfSMichael Neumann 	(0x8000 << 16) | (0x8c20 >> 2),
28257e252bfSMichael Neumann 	0x00000000,
28357e252bfSMichael Neumann 	(0x8040 << 16) | (0x8c20 >> 2),
28457e252bfSMichael Neumann 	0x00000000,
28557e252bfSMichael Neumann 	(0x8000 << 16) | (0x9354 >> 2),
28657e252bfSMichael Neumann 	0x00000000,
28757e252bfSMichael Neumann 	(0x8040 << 16) | (0x9354 >> 2),
28857e252bfSMichael Neumann 	0x00000000,
28957e252bfSMichael Neumann 	(0x9c00 << 16) | (0x9060 >> 2),
29057e252bfSMichael Neumann 	0x00000000,
29157e252bfSMichael Neumann 	(0x9c00 << 16) | (0x9364 >> 2),
29257e252bfSMichael Neumann 	0x00000000,
29357e252bfSMichael Neumann 	(0x9c00 << 16) | (0x9100 >> 2),
29457e252bfSMichael Neumann 	0x00000000,
29557e252bfSMichael Neumann 	(0x9c00 << 16) | (0x913c >> 2),
29657e252bfSMichael Neumann 	0x00000000,
29757e252bfSMichael Neumann 	(0x8000 << 16) | (0x90e0 >> 2),
29857e252bfSMichael Neumann 	0x00000000,
29957e252bfSMichael Neumann 	(0x8000 << 16) | (0x90e4 >> 2),
30057e252bfSMichael Neumann 	0x00000000,
30157e252bfSMichael Neumann 	(0x8000 << 16) | (0x90e8 >> 2),
30257e252bfSMichael Neumann 	0x00000000,
30357e252bfSMichael Neumann 	(0x8040 << 16) | (0x90e0 >> 2),
30457e252bfSMichael Neumann 	0x00000000,
30557e252bfSMichael Neumann 	(0x8040 << 16) | (0x90e4 >> 2),
30657e252bfSMichael Neumann 	0x00000000,
30757e252bfSMichael Neumann 	(0x8040 << 16) | (0x90e8 >> 2),
30857e252bfSMichael Neumann 	0x00000000,
30957e252bfSMichael Neumann 	(0x9c00 << 16) | (0x8bcc >> 2),
31057e252bfSMichael Neumann 	0x00000000,
31157e252bfSMichael Neumann 	(0x9c00 << 16) | (0x8b24 >> 2),
31257e252bfSMichael Neumann 	0x00000000,
31357e252bfSMichael Neumann 	(0x9c00 << 16) | (0x88c4 >> 2),
31457e252bfSMichael Neumann 	0x00000000,
31557e252bfSMichael Neumann 	(0x9c00 << 16) | (0x8e50 >> 2),
31657e252bfSMichael Neumann 	0x00000000,
31757e252bfSMichael Neumann 	(0x9c00 << 16) | (0x8c0c >> 2),
31857e252bfSMichael Neumann 	0x00000000,
31957e252bfSMichael Neumann 	(0x9c00 << 16) | (0x8e58 >> 2),
32057e252bfSMichael Neumann 	0x00000000,
32157e252bfSMichael Neumann 	(0x9c00 << 16) | (0x8e5c >> 2),
32257e252bfSMichael Neumann 	0x00000000,
32357e252bfSMichael Neumann 	(0x9c00 << 16) | (0x9508 >> 2),
32457e252bfSMichael Neumann 	0x00000000,
32557e252bfSMichael Neumann 	(0x9c00 << 16) | (0x950c >> 2),
32657e252bfSMichael Neumann 	0x00000000,
32757e252bfSMichael Neumann 	(0x9c00 << 16) | (0x9494 >> 2),
32857e252bfSMichael Neumann 	0x00000000,
32957e252bfSMichael Neumann 	(0x9c00 << 16) | (0xac0c >> 2),
33057e252bfSMichael Neumann 	0x00000000,
33157e252bfSMichael Neumann 	(0x9c00 << 16) | (0xac10 >> 2),
33257e252bfSMichael Neumann 	0x00000000,
33357e252bfSMichael Neumann 	(0x9c00 << 16) | (0xac14 >> 2),
33457e252bfSMichael Neumann 	0x00000000,
33557e252bfSMichael Neumann 	(0x9c00 << 16) | (0xae00 >> 2),
33657e252bfSMichael Neumann 	0x00000000,
33757e252bfSMichael Neumann 	(0x9c00 << 16) | (0xac08 >> 2),
33857e252bfSMichael Neumann 	0x00000000,
33957e252bfSMichael Neumann 	(0x9c00 << 16) | (0x88d4 >> 2),
34057e252bfSMichael Neumann 	0x00000000,
34157e252bfSMichael Neumann 	(0x9c00 << 16) | (0x88c8 >> 2),
34257e252bfSMichael Neumann 	0x00000000,
34357e252bfSMichael Neumann 	(0x9c00 << 16) | (0x88cc >> 2),
34457e252bfSMichael Neumann 	0x00000000,
34557e252bfSMichael Neumann 	(0x9c00 << 16) | (0x89b0 >> 2),
34657e252bfSMichael Neumann 	0x00000000,
34757e252bfSMichael Neumann 	(0x9c00 << 16) | (0x8b10 >> 2),
34857e252bfSMichael Neumann 	0x00000000,
34957e252bfSMichael Neumann 	(0x9c00 << 16) | (0x8a14 >> 2),
35057e252bfSMichael Neumann 	0x00000000,
35157e252bfSMichael Neumann 	(0x9c00 << 16) | (0x9830 >> 2),
35257e252bfSMichael Neumann 	0x00000000,
35357e252bfSMichael Neumann 	(0x9c00 << 16) | (0x9834 >> 2),
35457e252bfSMichael Neumann 	0x00000000,
35557e252bfSMichael Neumann 	(0x9c00 << 16) | (0x9838 >> 2),
35657e252bfSMichael Neumann 	0x00000000,
35757e252bfSMichael Neumann 	(0x9c00 << 16) | (0x9a10 >> 2),
35857e252bfSMichael Neumann 	0x00000000,
35957e252bfSMichael Neumann 	(0x8000 << 16) | (0x9870 >> 2),
36057e252bfSMichael Neumann 	0x00000000,
36157e252bfSMichael Neumann 	(0x8000 << 16) | (0x9874 >> 2),
36257e252bfSMichael Neumann 	0x00000000,
36357e252bfSMichael Neumann 	(0x8001 << 16) | (0x9870 >> 2),
36457e252bfSMichael Neumann 	0x00000000,
36557e252bfSMichael Neumann 	(0x8001 << 16) | (0x9874 >> 2),
36657e252bfSMichael Neumann 	0x00000000,
36757e252bfSMichael Neumann 	(0x8040 << 16) | (0x9870 >> 2),
36857e252bfSMichael Neumann 	0x00000000,
36957e252bfSMichael Neumann 	(0x8040 << 16) | (0x9874 >> 2),
37057e252bfSMichael Neumann 	0x00000000,
37157e252bfSMichael Neumann 	(0x8041 << 16) | (0x9870 >> 2),
37257e252bfSMichael Neumann 	0x00000000,
37357e252bfSMichael Neumann 	(0x8041 << 16) | (0x9874 >> 2),
37457e252bfSMichael Neumann 	0x00000000,
37557e252bfSMichael Neumann 	0x00000000
37657e252bfSMichael Neumann };
377b403bed8SMichael Neumann 
378f43cf1b1SMichael Neumann static const u32 tahiti_golden_rlc_registers[] =
379f43cf1b1SMichael Neumann {
380f43cf1b1SMichael Neumann 	0xc424, 0xffffffff, 0x00601005,
381f43cf1b1SMichael Neumann 	0xc47c, 0xffffffff, 0x10104040,
382f43cf1b1SMichael Neumann 	0xc488, 0xffffffff, 0x0100000a,
383f43cf1b1SMichael Neumann 	0xc314, 0xffffffff, 0x00000800,
384f43cf1b1SMichael Neumann 	0xc30c, 0xffffffff, 0x800000f4,
385f43cf1b1SMichael Neumann 	0xf4a8, 0xffffffff, 0x00000000
386f43cf1b1SMichael Neumann };
387f43cf1b1SMichael Neumann 
388f43cf1b1SMichael Neumann static const u32 tahiti_golden_registers[] =
389f43cf1b1SMichael Neumann {
390f43cf1b1SMichael Neumann 	0x9a10, 0x00010000, 0x00018208,
391f43cf1b1SMichael Neumann 	0x9830, 0xffffffff, 0x00000000,
392f43cf1b1SMichael Neumann 	0x9834, 0xf00fffff, 0x00000400,
393f43cf1b1SMichael Neumann 	0x9838, 0x0002021c, 0x00020200,
394f43cf1b1SMichael Neumann 	0xc78, 0x00000080, 0x00000000,
395f43cf1b1SMichael Neumann 	0xd030, 0x000300c0, 0x00800040,
396f43cf1b1SMichael Neumann 	0xd830, 0x000300c0, 0x00800040,
397f43cf1b1SMichael Neumann 	0x5bb0, 0x000000f0, 0x00000070,
398f43cf1b1SMichael Neumann 	0x5bc0, 0x00200000, 0x50100000,
399f43cf1b1SMichael Neumann 	0x7030, 0x31000311, 0x00000011,
400f43cf1b1SMichael Neumann 	0x277c, 0x00000003, 0x000007ff,
401f43cf1b1SMichael Neumann 	0x240c, 0x000007ff, 0x00000000,
402f43cf1b1SMichael Neumann 	0x8a14, 0xf000001f, 0x00000007,
403f43cf1b1SMichael Neumann 	0x8b24, 0xffffffff, 0x00ffffff,
404f43cf1b1SMichael Neumann 	0x8b10, 0x0000ff0f, 0x00000000,
405f43cf1b1SMichael Neumann 	0x28a4c, 0x07ffffff, 0x4e000000,
406f43cf1b1SMichael Neumann 	0x28350, 0x3f3f3fff, 0x2a00126a,
407f43cf1b1SMichael Neumann 	0x30, 0x000000ff, 0x0040,
408f43cf1b1SMichael Neumann 	0x34, 0x00000040, 0x00004040,
409f43cf1b1SMichael Neumann 	0x9100, 0x07ffffff, 0x03000000,
410f43cf1b1SMichael Neumann 	0x8e88, 0x01ff1f3f, 0x00000000,
411f43cf1b1SMichael Neumann 	0x8e84, 0x01ff1f3f, 0x00000000,
412f43cf1b1SMichael Neumann 	0x9060, 0x0000007f, 0x00000020,
413f43cf1b1SMichael Neumann 	0x9508, 0x00010000, 0x00010000,
414f43cf1b1SMichael Neumann 	0xac14, 0x00000200, 0x000002fb,
415f43cf1b1SMichael Neumann 	0xac10, 0xffffffff, 0x0000543b,
416f43cf1b1SMichael Neumann 	0xac0c, 0xffffffff, 0xa9210876,
417f43cf1b1SMichael Neumann 	0x88d0, 0xffffffff, 0x000fff40,
418f43cf1b1SMichael Neumann 	0x88d4, 0x0000001f, 0x00000010,
419f43cf1b1SMichael Neumann 	0x1410, 0x20000000, 0x20fffed8,
420f43cf1b1SMichael Neumann 	0x15c0, 0x000c0fc0, 0x000c0400
421f43cf1b1SMichael Neumann };
422f43cf1b1SMichael Neumann 
423f43cf1b1SMichael Neumann static const u32 tahiti_golden_registers2[] =
424f43cf1b1SMichael Neumann {
425f43cf1b1SMichael Neumann 	0xc64, 0x00000001, 0x00000001
426f43cf1b1SMichael Neumann };
427f43cf1b1SMichael Neumann 
428f43cf1b1SMichael Neumann static const u32 pitcairn_golden_rlc_registers[] =
429f43cf1b1SMichael Neumann {
430f43cf1b1SMichael Neumann 	0xc424, 0xffffffff, 0x00601004,
431f43cf1b1SMichael Neumann 	0xc47c, 0xffffffff, 0x10102020,
432f43cf1b1SMichael Neumann 	0xc488, 0xffffffff, 0x01000020,
433f43cf1b1SMichael Neumann 	0xc314, 0xffffffff, 0x00000800,
434f43cf1b1SMichael Neumann 	0xc30c, 0xffffffff, 0x800000a4
435f43cf1b1SMichael Neumann };
436f43cf1b1SMichael Neumann 
437f43cf1b1SMichael Neumann static const u32 pitcairn_golden_registers[] =
438f43cf1b1SMichael Neumann {
439f43cf1b1SMichael Neumann 	0x9a10, 0x00010000, 0x00018208,
440f43cf1b1SMichael Neumann 	0x9830, 0xffffffff, 0x00000000,
441f43cf1b1SMichael Neumann 	0x9834, 0xf00fffff, 0x00000400,
442f43cf1b1SMichael Neumann 	0x9838, 0x0002021c, 0x00020200,
443f43cf1b1SMichael Neumann 	0xc78, 0x00000080, 0x00000000,
444f43cf1b1SMichael Neumann 	0xd030, 0x000300c0, 0x00800040,
445f43cf1b1SMichael Neumann 	0xd830, 0x000300c0, 0x00800040,
446f43cf1b1SMichael Neumann 	0x5bb0, 0x000000f0, 0x00000070,
447f43cf1b1SMichael Neumann 	0x5bc0, 0x00200000, 0x50100000,
448f43cf1b1SMichael Neumann 	0x7030, 0x31000311, 0x00000011,
449f43cf1b1SMichael Neumann 	0x2ae4, 0x00073ffe, 0x000022a2,
450f43cf1b1SMichael Neumann 	0x240c, 0x000007ff, 0x00000000,
451f43cf1b1SMichael Neumann 	0x8a14, 0xf000001f, 0x00000007,
452f43cf1b1SMichael Neumann 	0x8b24, 0xffffffff, 0x00ffffff,
453f43cf1b1SMichael Neumann 	0x8b10, 0x0000ff0f, 0x00000000,
454f43cf1b1SMichael Neumann 	0x28a4c, 0x07ffffff, 0x4e000000,
455f43cf1b1SMichael Neumann 	0x28350, 0x3f3f3fff, 0x2a00126a,
456f43cf1b1SMichael Neumann 	0x30, 0x000000ff, 0x0040,
457f43cf1b1SMichael Neumann 	0x34, 0x00000040, 0x00004040,
458f43cf1b1SMichael Neumann 	0x9100, 0x07ffffff, 0x03000000,
459f43cf1b1SMichael Neumann 	0x9060, 0x0000007f, 0x00000020,
460f43cf1b1SMichael Neumann 	0x9508, 0x00010000, 0x00010000,
461f43cf1b1SMichael Neumann 	0xac14, 0x000003ff, 0x000000f7,
462f43cf1b1SMichael Neumann 	0xac10, 0xffffffff, 0x00000000,
463f43cf1b1SMichael Neumann 	0xac0c, 0xffffffff, 0x32761054,
464f43cf1b1SMichael Neumann 	0x88d4, 0x0000001f, 0x00000010,
465f43cf1b1SMichael Neumann 	0x15c0, 0x000c0fc0, 0x000c0400
466f43cf1b1SMichael Neumann };
467f43cf1b1SMichael Neumann 
468f43cf1b1SMichael Neumann static const u32 verde_golden_rlc_registers[] =
469f43cf1b1SMichael Neumann {
470f43cf1b1SMichael Neumann 	0xc424, 0xffffffff, 0x033f1005,
471f43cf1b1SMichael Neumann 	0xc47c, 0xffffffff, 0x10808020,
472f43cf1b1SMichael Neumann 	0xc488, 0xffffffff, 0x00800008,
473f43cf1b1SMichael Neumann 	0xc314, 0xffffffff, 0x00001000,
474f43cf1b1SMichael Neumann 	0xc30c, 0xffffffff, 0x80010014
475f43cf1b1SMichael Neumann };
476f43cf1b1SMichael Neumann 
477f43cf1b1SMichael Neumann static const u32 verde_golden_registers[] =
478f43cf1b1SMichael Neumann {
479f43cf1b1SMichael Neumann 	0x9a10, 0x00010000, 0x00018208,
480f43cf1b1SMichael Neumann 	0x9830, 0xffffffff, 0x00000000,
481f43cf1b1SMichael Neumann 	0x9834, 0xf00fffff, 0x00000400,
482f43cf1b1SMichael Neumann 	0x9838, 0x0002021c, 0x00020200,
483f43cf1b1SMichael Neumann 	0xc78, 0x00000080, 0x00000000,
484f43cf1b1SMichael Neumann 	0xd030, 0x000300c0, 0x00800040,
485f43cf1b1SMichael Neumann 	0xd030, 0x000300c0, 0x00800040,
486f43cf1b1SMichael Neumann 	0xd830, 0x000300c0, 0x00800040,
487f43cf1b1SMichael Neumann 	0xd830, 0x000300c0, 0x00800040,
488f43cf1b1SMichael Neumann 	0x5bb0, 0x000000f0, 0x00000070,
489f43cf1b1SMichael Neumann 	0x5bc0, 0x00200000, 0x50100000,
490f43cf1b1SMichael Neumann 	0x7030, 0x31000311, 0x00000011,
491f43cf1b1SMichael Neumann 	0x2ae4, 0x00073ffe, 0x000022a2,
492f43cf1b1SMichael Neumann 	0x2ae4, 0x00073ffe, 0x000022a2,
493f43cf1b1SMichael Neumann 	0x2ae4, 0x00073ffe, 0x000022a2,
494f43cf1b1SMichael Neumann 	0x240c, 0x000007ff, 0x00000000,
495f43cf1b1SMichael Neumann 	0x240c, 0x000007ff, 0x00000000,
496f43cf1b1SMichael Neumann 	0x240c, 0x000007ff, 0x00000000,
497f43cf1b1SMichael Neumann 	0x8a14, 0xf000001f, 0x00000007,
498f43cf1b1SMichael Neumann 	0x8a14, 0xf000001f, 0x00000007,
499f43cf1b1SMichael Neumann 	0x8a14, 0xf000001f, 0x00000007,
500f43cf1b1SMichael Neumann 	0x8b24, 0xffffffff, 0x00ffffff,
501f43cf1b1SMichael Neumann 	0x8b10, 0x0000ff0f, 0x00000000,
502f43cf1b1SMichael Neumann 	0x28a4c, 0x07ffffff, 0x4e000000,
503f43cf1b1SMichael Neumann 	0x28350, 0x3f3f3fff, 0x0000124a,
504f43cf1b1SMichael Neumann 	0x28350, 0x3f3f3fff, 0x0000124a,
505f43cf1b1SMichael Neumann 	0x28350, 0x3f3f3fff, 0x0000124a,
506f43cf1b1SMichael Neumann 	0x30, 0x000000ff, 0x0040,
507f43cf1b1SMichael Neumann 	0x34, 0x00000040, 0x00004040,
508f43cf1b1SMichael Neumann 	0x9100, 0x07ffffff, 0x03000000,
509f43cf1b1SMichael Neumann 	0x9100, 0x07ffffff, 0x03000000,
510f43cf1b1SMichael Neumann 	0x8e88, 0x01ff1f3f, 0x00000000,
511f43cf1b1SMichael Neumann 	0x8e88, 0x01ff1f3f, 0x00000000,
512f43cf1b1SMichael Neumann 	0x8e88, 0x01ff1f3f, 0x00000000,
513f43cf1b1SMichael Neumann 	0x8e84, 0x01ff1f3f, 0x00000000,
514f43cf1b1SMichael Neumann 	0x8e84, 0x01ff1f3f, 0x00000000,
515f43cf1b1SMichael Neumann 	0x8e84, 0x01ff1f3f, 0x00000000,
516f43cf1b1SMichael Neumann 	0x9060, 0x0000007f, 0x00000020,
517f43cf1b1SMichael Neumann 	0x9508, 0x00010000, 0x00010000,
518f43cf1b1SMichael Neumann 	0xac14, 0x000003ff, 0x00000003,
519f43cf1b1SMichael Neumann 	0xac14, 0x000003ff, 0x00000003,
520f43cf1b1SMichael Neumann 	0xac14, 0x000003ff, 0x00000003,
521f43cf1b1SMichael Neumann 	0xac10, 0xffffffff, 0x00000000,
522f43cf1b1SMichael Neumann 	0xac10, 0xffffffff, 0x00000000,
523f43cf1b1SMichael Neumann 	0xac10, 0xffffffff, 0x00000000,
524f43cf1b1SMichael Neumann 	0xac0c, 0xffffffff, 0x00001032,
525f43cf1b1SMichael Neumann 	0xac0c, 0xffffffff, 0x00001032,
526f43cf1b1SMichael Neumann 	0xac0c, 0xffffffff, 0x00001032,
527f43cf1b1SMichael Neumann 	0x88d4, 0x0000001f, 0x00000010,
528f43cf1b1SMichael Neumann 	0x88d4, 0x0000001f, 0x00000010,
529f43cf1b1SMichael Neumann 	0x88d4, 0x0000001f, 0x00000010,
530f43cf1b1SMichael Neumann 	0x15c0, 0x000c0fc0, 0x000c0400
531f43cf1b1SMichael Neumann };
532f43cf1b1SMichael Neumann 
533f43cf1b1SMichael Neumann static const u32 oland_golden_rlc_registers[] =
534f43cf1b1SMichael Neumann {
535f43cf1b1SMichael Neumann 	0xc424, 0xffffffff, 0x00601005,
536f43cf1b1SMichael Neumann 	0xc47c, 0xffffffff, 0x10104040,
537f43cf1b1SMichael Neumann 	0xc488, 0xffffffff, 0x0100000a,
538f43cf1b1SMichael Neumann 	0xc314, 0xffffffff, 0x00000800,
539f43cf1b1SMichael Neumann 	0xc30c, 0xffffffff, 0x800000f4
540f43cf1b1SMichael Neumann };
541f43cf1b1SMichael Neumann 
542f43cf1b1SMichael Neumann static const u32 oland_golden_registers[] =
543f43cf1b1SMichael Neumann {
544f43cf1b1SMichael Neumann 	0x9a10, 0x00010000, 0x00018208,
545f43cf1b1SMichael Neumann 	0x9830, 0xffffffff, 0x00000000,
546f43cf1b1SMichael Neumann 	0x9834, 0xf00fffff, 0x00000400,
547f43cf1b1SMichael Neumann 	0x9838, 0x0002021c, 0x00020200,
548f43cf1b1SMichael Neumann 	0xc78, 0x00000080, 0x00000000,
549f43cf1b1SMichael Neumann 	0xd030, 0x000300c0, 0x00800040,
550f43cf1b1SMichael Neumann 	0xd830, 0x000300c0, 0x00800040,
551f43cf1b1SMichael Neumann 	0x5bb0, 0x000000f0, 0x00000070,
552f43cf1b1SMichael Neumann 	0x5bc0, 0x00200000, 0x50100000,
553f43cf1b1SMichael Neumann 	0x7030, 0x31000311, 0x00000011,
554f43cf1b1SMichael Neumann 	0x2ae4, 0x00073ffe, 0x000022a2,
555f43cf1b1SMichael Neumann 	0x240c, 0x000007ff, 0x00000000,
556f43cf1b1SMichael Neumann 	0x8a14, 0xf000001f, 0x00000007,
557f43cf1b1SMichael Neumann 	0x8b24, 0xffffffff, 0x00ffffff,
558f43cf1b1SMichael Neumann 	0x8b10, 0x0000ff0f, 0x00000000,
559f43cf1b1SMichael Neumann 	0x28a4c, 0x07ffffff, 0x4e000000,
560f43cf1b1SMichael Neumann 	0x28350, 0x3f3f3fff, 0x00000082,
561f43cf1b1SMichael Neumann 	0x30, 0x000000ff, 0x0040,
562f43cf1b1SMichael Neumann 	0x34, 0x00000040, 0x00004040,
563f43cf1b1SMichael Neumann 	0x9100, 0x07ffffff, 0x03000000,
564f43cf1b1SMichael Neumann 	0x9060, 0x0000007f, 0x00000020,
565f43cf1b1SMichael Neumann 	0x9508, 0x00010000, 0x00010000,
566f43cf1b1SMichael Neumann 	0xac14, 0x000003ff, 0x000000f3,
567f43cf1b1SMichael Neumann 	0xac10, 0xffffffff, 0x00000000,
568f43cf1b1SMichael Neumann 	0xac0c, 0xffffffff, 0x00003210,
569f43cf1b1SMichael Neumann 	0x88d4, 0x0000001f, 0x00000010,
570f43cf1b1SMichael Neumann 	0x15c0, 0x000c0fc0, 0x000c0400
571f43cf1b1SMichael Neumann };
572f43cf1b1SMichael Neumann 
573f43cf1b1SMichael Neumann static const u32 hainan_golden_registers[] =
574f43cf1b1SMichael Neumann {
575f43cf1b1SMichael Neumann 	0x9a10, 0x00010000, 0x00018208,
576f43cf1b1SMichael Neumann 	0x9830, 0xffffffff, 0x00000000,
577f43cf1b1SMichael Neumann 	0x9834, 0xf00fffff, 0x00000400,
578f43cf1b1SMichael Neumann 	0x9838, 0x0002021c, 0x00020200,
579f43cf1b1SMichael Neumann 	0xd0c0, 0xff000fff, 0x00000100,
580f43cf1b1SMichael Neumann 	0xd030, 0x000300c0, 0x00800040,
581f43cf1b1SMichael Neumann 	0xd8c0, 0xff000fff, 0x00000100,
582f43cf1b1SMichael Neumann 	0xd830, 0x000300c0, 0x00800040,
583f43cf1b1SMichael Neumann 	0x2ae4, 0x00073ffe, 0x000022a2,
584f43cf1b1SMichael Neumann 	0x240c, 0x000007ff, 0x00000000,
585f43cf1b1SMichael Neumann 	0x8a14, 0xf000001f, 0x00000007,
586f43cf1b1SMichael Neumann 	0x8b24, 0xffffffff, 0x00ffffff,
587f43cf1b1SMichael Neumann 	0x8b10, 0x0000ff0f, 0x00000000,
588f43cf1b1SMichael Neumann 	0x28a4c, 0x07ffffff, 0x4e000000,
589f43cf1b1SMichael Neumann 	0x28350, 0x3f3f3fff, 0x00000000,
590f43cf1b1SMichael Neumann 	0x30, 0x000000ff, 0x0040,
591f43cf1b1SMichael Neumann 	0x34, 0x00000040, 0x00004040,
592f43cf1b1SMichael Neumann 	0x9100, 0x03e00000, 0x03600000,
593f43cf1b1SMichael Neumann 	0x9060, 0x0000007f, 0x00000020,
594f43cf1b1SMichael Neumann 	0x9508, 0x00010000, 0x00010000,
595f43cf1b1SMichael Neumann 	0xac14, 0x000003ff, 0x000000f1,
596f43cf1b1SMichael Neumann 	0xac10, 0xffffffff, 0x00000000,
597f43cf1b1SMichael Neumann 	0xac0c, 0xffffffff, 0x00003210,
598f43cf1b1SMichael Neumann 	0x88d4, 0x0000001f, 0x00000010,
599f43cf1b1SMichael Neumann 	0x15c0, 0x000c0fc0, 0x000c0400
600f43cf1b1SMichael Neumann };
601f43cf1b1SMichael Neumann 
602f43cf1b1SMichael Neumann static const u32 hainan_golden_registers2[] =
603f43cf1b1SMichael Neumann {
604f43cf1b1SMichael Neumann 	0x98f8, 0xffffffff, 0x02010001
605f43cf1b1SMichael Neumann };
606f43cf1b1SMichael Neumann 
607f43cf1b1SMichael Neumann static const u32 tahiti_mgcg_cgcg_init[] =
608f43cf1b1SMichael Neumann {
609f43cf1b1SMichael Neumann 	0xc400, 0xffffffff, 0xfffffffc,
610f43cf1b1SMichael Neumann 	0x802c, 0xffffffff, 0xe0000000,
611f43cf1b1SMichael Neumann 	0x9a60, 0xffffffff, 0x00000100,
612f43cf1b1SMichael Neumann 	0x92a4, 0xffffffff, 0x00000100,
613f43cf1b1SMichael Neumann 	0xc164, 0xffffffff, 0x00000100,
614f43cf1b1SMichael Neumann 	0x9774, 0xffffffff, 0x00000100,
615f43cf1b1SMichael Neumann 	0x8984, 0xffffffff, 0x06000100,
616f43cf1b1SMichael Neumann 	0x8a18, 0xffffffff, 0x00000100,
617f43cf1b1SMichael Neumann 	0x92a0, 0xffffffff, 0x00000100,
618f43cf1b1SMichael Neumann 	0xc380, 0xffffffff, 0x00000100,
619f43cf1b1SMichael Neumann 	0x8b28, 0xffffffff, 0x00000100,
620f43cf1b1SMichael Neumann 	0x9144, 0xffffffff, 0x00000100,
621f43cf1b1SMichael Neumann 	0x8d88, 0xffffffff, 0x00000100,
622f43cf1b1SMichael Neumann 	0x8d8c, 0xffffffff, 0x00000100,
623f43cf1b1SMichael Neumann 	0x9030, 0xffffffff, 0x00000100,
624f43cf1b1SMichael Neumann 	0x9034, 0xffffffff, 0x00000100,
625f43cf1b1SMichael Neumann 	0x9038, 0xffffffff, 0x00000100,
626f43cf1b1SMichael Neumann 	0x903c, 0xffffffff, 0x00000100,
627f43cf1b1SMichael Neumann 	0xad80, 0xffffffff, 0x00000100,
628f43cf1b1SMichael Neumann 	0xac54, 0xffffffff, 0x00000100,
629f43cf1b1SMichael Neumann 	0x897c, 0xffffffff, 0x06000100,
630f43cf1b1SMichael Neumann 	0x9868, 0xffffffff, 0x00000100,
631f43cf1b1SMichael Neumann 	0x9510, 0xffffffff, 0x00000100,
632f43cf1b1SMichael Neumann 	0xaf04, 0xffffffff, 0x00000100,
633f43cf1b1SMichael Neumann 	0xae04, 0xffffffff, 0x00000100,
634f43cf1b1SMichael Neumann 	0x949c, 0xffffffff, 0x00000100,
635f43cf1b1SMichael Neumann 	0x802c, 0xffffffff, 0xe0000000,
636f43cf1b1SMichael Neumann 	0x9160, 0xffffffff, 0x00010000,
637f43cf1b1SMichael Neumann 	0x9164, 0xffffffff, 0x00030002,
638f43cf1b1SMichael Neumann 	0x9168, 0xffffffff, 0x00040007,
639f43cf1b1SMichael Neumann 	0x916c, 0xffffffff, 0x00060005,
640f43cf1b1SMichael Neumann 	0x9170, 0xffffffff, 0x00090008,
641f43cf1b1SMichael Neumann 	0x9174, 0xffffffff, 0x00020001,
642f43cf1b1SMichael Neumann 	0x9178, 0xffffffff, 0x00040003,
643f43cf1b1SMichael Neumann 	0x917c, 0xffffffff, 0x00000007,
644f43cf1b1SMichael Neumann 	0x9180, 0xffffffff, 0x00060005,
645f43cf1b1SMichael Neumann 	0x9184, 0xffffffff, 0x00090008,
646f43cf1b1SMichael Neumann 	0x9188, 0xffffffff, 0x00030002,
647f43cf1b1SMichael Neumann 	0x918c, 0xffffffff, 0x00050004,
648f43cf1b1SMichael Neumann 	0x9190, 0xffffffff, 0x00000008,
649f43cf1b1SMichael Neumann 	0x9194, 0xffffffff, 0x00070006,
650f43cf1b1SMichael Neumann 	0x9198, 0xffffffff, 0x000a0009,
651f43cf1b1SMichael Neumann 	0x919c, 0xffffffff, 0x00040003,
652f43cf1b1SMichael Neumann 	0x91a0, 0xffffffff, 0x00060005,
653f43cf1b1SMichael Neumann 	0x91a4, 0xffffffff, 0x00000009,
654f43cf1b1SMichael Neumann 	0x91a8, 0xffffffff, 0x00080007,
655f43cf1b1SMichael Neumann 	0x91ac, 0xffffffff, 0x000b000a,
656f43cf1b1SMichael Neumann 	0x91b0, 0xffffffff, 0x00050004,
657f43cf1b1SMichael Neumann 	0x91b4, 0xffffffff, 0x00070006,
658f43cf1b1SMichael Neumann 	0x91b8, 0xffffffff, 0x0008000b,
659f43cf1b1SMichael Neumann 	0x91bc, 0xffffffff, 0x000a0009,
660f43cf1b1SMichael Neumann 	0x91c0, 0xffffffff, 0x000d000c,
661f43cf1b1SMichael Neumann 	0x91c4, 0xffffffff, 0x00060005,
662f43cf1b1SMichael Neumann 	0x91c8, 0xffffffff, 0x00080007,
663f43cf1b1SMichael Neumann 	0x91cc, 0xffffffff, 0x0000000b,
664f43cf1b1SMichael Neumann 	0x91d0, 0xffffffff, 0x000a0009,
665f43cf1b1SMichael Neumann 	0x91d4, 0xffffffff, 0x000d000c,
666f43cf1b1SMichael Neumann 	0x91d8, 0xffffffff, 0x00070006,
667f43cf1b1SMichael Neumann 	0x91dc, 0xffffffff, 0x00090008,
668f43cf1b1SMichael Neumann 	0x91e0, 0xffffffff, 0x0000000c,
669f43cf1b1SMichael Neumann 	0x91e4, 0xffffffff, 0x000b000a,
670f43cf1b1SMichael Neumann 	0x91e8, 0xffffffff, 0x000e000d,
671f43cf1b1SMichael Neumann 	0x91ec, 0xffffffff, 0x00080007,
672f43cf1b1SMichael Neumann 	0x91f0, 0xffffffff, 0x000a0009,
673f43cf1b1SMichael Neumann 	0x91f4, 0xffffffff, 0x0000000d,
674f43cf1b1SMichael Neumann 	0x91f8, 0xffffffff, 0x000c000b,
675f43cf1b1SMichael Neumann 	0x91fc, 0xffffffff, 0x000f000e,
676f43cf1b1SMichael Neumann 	0x9200, 0xffffffff, 0x00090008,
677f43cf1b1SMichael Neumann 	0x9204, 0xffffffff, 0x000b000a,
678f43cf1b1SMichael Neumann 	0x9208, 0xffffffff, 0x000c000f,
679f43cf1b1SMichael Neumann 	0x920c, 0xffffffff, 0x000e000d,
680f43cf1b1SMichael Neumann 	0x9210, 0xffffffff, 0x00110010,
681f43cf1b1SMichael Neumann 	0x9214, 0xffffffff, 0x000a0009,
682f43cf1b1SMichael Neumann 	0x9218, 0xffffffff, 0x000c000b,
683f43cf1b1SMichael Neumann 	0x921c, 0xffffffff, 0x0000000f,
684f43cf1b1SMichael Neumann 	0x9220, 0xffffffff, 0x000e000d,
685f43cf1b1SMichael Neumann 	0x9224, 0xffffffff, 0x00110010,
686f43cf1b1SMichael Neumann 	0x9228, 0xffffffff, 0x000b000a,
687f43cf1b1SMichael Neumann 	0x922c, 0xffffffff, 0x000d000c,
688f43cf1b1SMichael Neumann 	0x9230, 0xffffffff, 0x00000010,
689f43cf1b1SMichael Neumann 	0x9234, 0xffffffff, 0x000f000e,
690f43cf1b1SMichael Neumann 	0x9238, 0xffffffff, 0x00120011,
691f43cf1b1SMichael Neumann 	0x923c, 0xffffffff, 0x000c000b,
692f43cf1b1SMichael Neumann 	0x9240, 0xffffffff, 0x000e000d,
693f43cf1b1SMichael Neumann 	0x9244, 0xffffffff, 0x00000011,
694f43cf1b1SMichael Neumann 	0x9248, 0xffffffff, 0x0010000f,
695f43cf1b1SMichael Neumann 	0x924c, 0xffffffff, 0x00130012,
696f43cf1b1SMichael Neumann 	0x9250, 0xffffffff, 0x000d000c,
697f43cf1b1SMichael Neumann 	0x9254, 0xffffffff, 0x000f000e,
698f43cf1b1SMichael Neumann 	0x9258, 0xffffffff, 0x00100013,
699f43cf1b1SMichael Neumann 	0x925c, 0xffffffff, 0x00120011,
700f43cf1b1SMichael Neumann 	0x9260, 0xffffffff, 0x00150014,
701f43cf1b1SMichael Neumann 	0x9264, 0xffffffff, 0x000e000d,
702f43cf1b1SMichael Neumann 	0x9268, 0xffffffff, 0x0010000f,
703f43cf1b1SMichael Neumann 	0x926c, 0xffffffff, 0x00000013,
704f43cf1b1SMichael Neumann 	0x9270, 0xffffffff, 0x00120011,
705f43cf1b1SMichael Neumann 	0x9274, 0xffffffff, 0x00150014,
706f43cf1b1SMichael Neumann 	0x9278, 0xffffffff, 0x000f000e,
707f43cf1b1SMichael Neumann 	0x927c, 0xffffffff, 0x00110010,
708f43cf1b1SMichael Neumann 	0x9280, 0xffffffff, 0x00000014,
709f43cf1b1SMichael Neumann 	0x9284, 0xffffffff, 0x00130012,
710f43cf1b1SMichael Neumann 	0x9288, 0xffffffff, 0x00160015,
711f43cf1b1SMichael Neumann 	0x928c, 0xffffffff, 0x0010000f,
712f43cf1b1SMichael Neumann 	0x9290, 0xffffffff, 0x00120011,
713f43cf1b1SMichael Neumann 	0x9294, 0xffffffff, 0x00000015,
714f43cf1b1SMichael Neumann 	0x9298, 0xffffffff, 0x00140013,
715f43cf1b1SMichael Neumann 	0x929c, 0xffffffff, 0x00170016,
716f43cf1b1SMichael Neumann 	0x9150, 0xffffffff, 0x96940200,
717f43cf1b1SMichael Neumann 	0x8708, 0xffffffff, 0x00900100,
718f43cf1b1SMichael Neumann 	0xc478, 0xffffffff, 0x00000080,
719f43cf1b1SMichael Neumann 	0xc404, 0xffffffff, 0x0020003f,
720f43cf1b1SMichael Neumann 	0x30, 0xffffffff, 0x0000001c,
721f43cf1b1SMichael Neumann 	0x34, 0x000f0000, 0x000f0000,
722f43cf1b1SMichael Neumann 	0x160c, 0xffffffff, 0x00000100,
723f43cf1b1SMichael Neumann 	0x1024, 0xffffffff, 0x00000100,
724f43cf1b1SMichael Neumann 	0x102c, 0x00000101, 0x00000000,
725f43cf1b1SMichael Neumann 	0x20a8, 0xffffffff, 0x00000104,
726f43cf1b1SMichael Neumann 	0x264c, 0x000c0000, 0x000c0000,
727f43cf1b1SMichael Neumann 	0x2648, 0x000c0000, 0x000c0000,
728f43cf1b1SMichael Neumann 	0x55e4, 0xff000fff, 0x00000100,
729f43cf1b1SMichael Neumann 	0x55e8, 0x00000001, 0x00000001,
730f43cf1b1SMichael Neumann 	0x2f50, 0x00000001, 0x00000001,
731f43cf1b1SMichael Neumann 	0x30cc, 0xc0000fff, 0x00000104,
732f43cf1b1SMichael Neumann 	0xc1e4, 0x00000001, 0x00000001,
733f43cf1b1SMichael Neumann 	0xd0c0, 0xfffffff0, 0x00000100,
734f43cf1b1SMichael Neumann 	0xd8c0, 0xfffffff0, 0x00000100
735f43cf1b1SMichael Neumann };
736f43cf1b1SMichael Neumann 
737f43cf1b1SMichael Neumann static const u32 pitcairn_mgcg_cgcg_init[] =
738f43cf1b1SMichael Neumann {
739f43cf1b1SMichael Neumann 	0xc400, 0xffffffff, 0xfffffffc,
740f43cf1b1SMichael Neumann 	0x802c, 0xffffffff, 0xe0000000,
741f43cf1b1SMichael Neumann 	0x9a60, 0xffffffff, 0x00000100,
742f43cf1b1SMichael Neumann 	0x92a4, 0xffffffff, 0x00000100,
743f43cf1b1SMichael Neumann 	0xc164, 0xffffffff, 0x00000100,
744f43cf1b1SMichael Neumann 	0x9774, 0xffffffff, 0x00000100,
745f43cf1b1SMichael Neumann 	0x8984, 0xffffffff, 0x06000100,
746f43cf1b1SMichael Neumann 	0x8a18, 0xffffffff, 0x00000100,
747f43cf1b1SMichael Neumann 	0x92a0, 0xffffffff, 0x00000100,
748f43cf1b1SMichael Neumann 	0xc380, 0xffffffff, 0x00000100,
749f43cf1b1SMichael Neumann 	0x8b28, 0xffffffff, 0x00000100,
750f43cf1b1SMichael Neumann 	0x9144, 0xffffffff, 0x00000100,
751f43cf1b1SMichael Neumann 	0x8d88, 0xffffffff, 0x00000100,
752f43cf1b1SMichael Neumann 	0x8d8c, 0xffffffff, 0x00000100,
753f43cf1b1SMichael Neumann 	0x9030, 0xffffffff, 0x00000100,
754f43cf1b1SMichael Neumann 	0x9034, 0xffffffff, 0x00000100,
755f43cf1b1SMichael Neumann 	0x9038, 0xffffffff, 0x00000100,
756f43cf1b1SMichael Neumann 	0x903c, 0xffffffff, 0x00000100,
757f43cf1b1SMichael Neumann 	0xad80, 0xffffffff, 0x00000100,
758f43cf1b1SMichael Neumann 	0xac54, 0xffffffff, 0x00000100,
759f43cf1b1SMichael Neumann 	0x897c, 0xffffffff, 0x06000100,
760f43cf1b1SMichael Neumann 	0x9868, 0xffffffff, 0x00000100,
761f43cf1b1SMichael Neumann 	0x9510, 0xffffffff, 0x00000100,
762f43cf1b1SMichael Neumann 	0xaf04, 0xffffffff, 0x00000100,
763f43cf1b1SMichael Neumann 	0xae04, 0xffffffff, 0x00000100,
764f43cf1b1SMichael Neumann 	0x949c, 0xffffffff, 0x00000100,
765f43cf1b1SMichael Neumann 	0x802c, 0xffffffff, 0xe0000000,
766f43cf1b1SMichael Neumann 	0x9160, 0xffffffff, 0x00010000,
767f43cf1b1SMichael Neumann 	0x9164, 0xffffffff, 0x00030002,
768f43cf1b1SMichael Neumann 	0x9168, 0xffffffff, 0x00040007,
769f43cf1b1SMichael Neumann 	0x916c, 0xffffffff, 0x00060005,
770f43cf1b1SMichael Neumann 	0x9170, 0xffffffff, 0x00090008,
771f43cf1b1SMichael Neumann 	0x9174, 0xffffffff, 0x00020001,
772f43cf1b1SMichael Neumann 	0x9178, 0xffffffff, 0x00040003,
773f43cf1b1SMichael Neumann 	0x917c, 0xffffffff, 0x00000007,
774f43cf1b1SMichael Neumann 	0x9180, 0xffffffff, 0x00060005,
775f43cf1b1SMichael Neumann 	0x9184, 0xffffffff, 0x00090008,
776f43cf1b1SMichael Neumann 	0x9188, 0xffffffff, 0x00030002,
777f43cf1b1SMichael Neumann 	0x918c, 0xffffffff, 0x00050004,
778f43cf1b1SMichael Neumann 	0x9190, 0xffffffff, 0x00000008,
779f43cf1b1SMichael Neumann 	0x9194, 0xffffffff, 0x00070006,
780f43cf1b1SMichael Neumann 	0x9198, 0xffffffff, 0x000a0009,
781f43cf1b1SMichael Neumann 	0x919c, 0xffffffff, 0x00040003,
782f43cf1b1SMichael Neumann 	0x91a0, 0xffffffff, 0x00060005,
783f43cf1b1SMichael Neumann 	0x91a4, 0xffffffff, 0x00000009,
784f43cf1b1SMichael Neumann 	0x91a8, 0xffffffff, 0x00080007,
785f43cf1b1SMichael Neumann 	0x91ac, 0xffffffff, 0x000b000a,
786f43cf1b1SMichael Neumann 	0x91b0, 0xffffffff, 0x00050004,
787f43cf1b1SMichael Neumann 	0x91b4, 0xffffffff, 0x00070006,
788f43cf1b1SMichael Neumann 	0x91b8, 0xffffffff, 0x0008000b,
789f43cf1b1SMichael Neumann 	0x91bc, 0xffffffff, 0x000a0009,
790f43cf1b1SMichael Neumann 	0x91c0, 0xffffffff, 0x000d000c,
791f43cf1b1SMichael Neumann 	0x9200, 0xffffffff, 0x00090008,
792f43cf1b1SMichael Neumann 	0x9204, 0xffffffff, 0x000b000a,
793f43cf1b1SMichael Neumann 	0x9208, 0xffffffff, 0x000c000f,
794f43cf1b1SMichael Neumann 	0x920c, 0xffffffff, 0x000e000d,
795f43cf1b1SMichael Neumann 	0x9210, 0xffffffff, 0x00110010,
796f43cf1b1SMichael Neumann 	0x9214, 0xffffffff, 0x000a0009,
797f43cf1b1SMichael Neumann 	0x9218, 0xffffffff, 0x000c000b,
798f43cf1b1SMichael Neumann 	0x921c, 0xffffffff, 0x0000000f,
799f43cf1b1SMichael Neumann 	0x9220, 0xffffffff, 0x000e000d,
800f43cf1b1SMichael Neumann 	0x9224, 0xffffffff, 0x00110010,
801f43cf1b1SMichael Neumann 	0x9228, 0xffffffff, 0x000b000a,
802f43cf1b1SMichael Neumann 	0x922c, 0xffffffff, 0x000d000c,
803f43cf1b1SMichael Neumann 	0x9230, 0xffffffff, 0x00000010,
804f43cf1b1SMichael Neumann 	0x9234, 0xffffffff, 0x000f000e,
805f43cf1b1SMichael Neumann 	0x9238, 0xffffffff, 0x00120011,
806f43cf1b1SMichael Neumann 	0x923c, 0xffffffff, 0x000c000b,
807f43cf1b1SMichael Neumann 	0x9240, 0xffffffff, 0x000e000d,
808f43cf1b1SMichael Neumann 	0x9244, 0xffffffff, 0x00000011,
809f43cf1b1SMichael Neumann 	0x9248, 0xffffffff, 0x0010000f,
810f43cf1b1SMichael Neumann 	0x924c, 0xffffffff, 0x00130012,
811f43cf1b1SMichael Neumann 	0x9250, 0xffffffff, 0x000d000c,
812f43cf1b1SMichael Neumann 	0x9254, 0xffffffff, 0x000f000e,
813f43cf1b1SMichael Neumann 	0x9258, 0xffffffff, 0x00100013,
814f43cf1b1SMichael Neumann 	0x925c, 0xffffffff, 0x00120011,
815f43cf1b1SMichael Neumann 	0x9260, 0xffffffff, 0x00150014,
816f43cf1b1SMichael Neumann 	0x9150, 0xffffffff, 0x96940200,
817f43cf1b1SMichael Neumann 	0x8708, 0xffffffff, 0x00900100,
818f43cf1b1SMichael Neumann 	0xc478, 0xffffffff, 0x00000080,
819f43cf1b1SMichael Neumann 	0xc404, 0xffffffff, 0x0020003f,
820f43cf1b1SMichael Neumann 	0x30, 0xffffffff, 0x0000001c,
821f43cf1b1SMichael Neumann 	0x34, 0x000f0000, 0x000f0000,
822f43cf1b1SMichael Neumann 	0x160c, 0xffffffff, 0x00000100,
823f43cf1b1SMichael Neumann 	0x1024, 0xffffffff, 0x00000100,
824f43cf1b1SMichael Neumann 	0x102c, 0x00000101, 0x00000000,
825f43cf1b1SMichael Neumann 	0x20a8, 0xffffffff, 0x00000104,
826f43cf1b1SMichael Neumann 	0x55e4, 0xff000fff, 0x00000100,
827f43cf1b1SMichael Neumann 	0x55e8, 0x00000001, 0x00000001,
828f43cf1b1SMichael Neumann 	0x2f50, 0x00000001, 0x00000001,
829f43cf1b1SMichael Neumann 	0x30cc, 0xc0000fff, 0x00000104,
830f43cf1b1SMichael Neumann 	0xc1e4, 0x00000001, 0x00000001,
831f43cf1b1SMichael Neumann 	0xd0c0, 0xfffffff0, 0x00000100,
832f43cf1b1SMichael Neumann 	0xd8c0, 0xfffffff0, 0x00000100
833f43cf1b1SMichael Neumann };
834f43cf1b1SMichael Neumann 
835f43cf1b1SMichael Neumann static const u32 verde_mgcg_cgcg_init[] =
836f43cf1b1SMichael Neumann {
837f43cf1b1SMichael Neumann 	0xc400, 0xffffffff, 0xfffffffc,
838f43cf1b1SMichael Neumann 	0x802c, 0xffffffff, 0xe0000000,
839f43cf1b1SMichael Neumann 	0x9a60, 0xffffffff, 0x00000100,
840f43cf1b1SMichael Neumann 	0x92a4, 0xffffffff, 0x00000100,
841f43cf1b1SMichael Neumann 	0xc164, 0xffffffff, 0x00000100,
842f43cf1b1SMichael Neumann 	0x9774, 0xffffffff, 0x00000100,
843f43cf1b1SMichael Neumann 	0x8984, 0xffffffff, 0x06000100,
844f43cf1b1SMichael Neumann 	0x8a18, 0xffffffff, 0x00000100,
845f43cf1b1SMichael Neumann 	0x92a0, 0xffffffff, 0x00000100,
846f43cf1b1SMichael Neumann 	0xc380, 0xffffffff, 0x00000100,
847f43cf1b1SMichael Neumann 	0x8b28, 0xffffffff, 0x00000100,
848f43cf1b1SMichael Neumann 	0x9144, 0xffffffff, 0x00000100,
849f43cf1b1SMichael Neumann 	0x8d88, 0xffffffff, 0x00000100,
850f43cf1b1SMichael Neumann 	0x8d8c, 0xffffffff, 0x00000100,
851f43cf1b1SMichael Neumann 	0x9030, 0xffffffff, 0x00000100,
852f43cf1b1SMichael Neumann 	0x9034, 0xffffffff, 0x00000100,
853f43cf1b1SMichael Neumann 	0x9038, 0xffffffff, 0x00000100,
854f43cf1b1SMichael Neumann 	0x903c, 0xffffffff, 0x00000100,
855f43cf1b1SMichael Neumann 	0xad80, 0xffffffff, 0x00000100,
856f43cf1b1SMichael Neumann 	0xac54, 0xffffffff, 0x00000100,
857f43cf1b1SMichael Neumann 	0x897c, 0xffffffff, 0x06000100,
858f43cf1b1SMichael Neumann 	0x9868, 0xffffffff, 0x00000100,
859f43cf1b1SMichael Neumann 	0x9510, 0xffffffff, 0x00000100,
860f43cf1b1SMichael Neumann 	0xaf04, 0xffffffff, 0x00000100,
861f43cf1b1SMichael Neumann 	0xae04, 0xffffffff, 0x00000100,
862f43cf1b1SMichael Neumann 	0x949c, 0xffffffff, 0x00000100,
863f43cf1b1SMichael Neumann 	0x802c, 0xffffffff, 0xe0000000,
864f43cf1b1SMichael Neumann 	0x9160, 0xffffffff, 0x00010000,
865f43cf1b1SMichael Neumann 	0x9164, 0xffffffff, 0x00030002,
866f43cf1b1SMichael Neumann 	0x9168, 0xffffffff, 0x00040007,
867f43cf1b1SMichael Neumann 	0x916c, 0xffffffff, 0x00060005,
868f43cf1b1SMichael Neumann 	0x9170, 0xffffffff, 0x00090008,
869f43cf1b1SMichael Neumann 	0x9174, 0xffffffff, 0x00020001,
870f43cf1b1SMichael Neumann 	0x9178, 0xffffffff, 0x00040003,
871f43cf1b1SMichael Neumann 	0x917c, 0xffffffff, 0x00000007,
872f43cf1b1SMichael Neumann 	0x9180, 0xffffffff, 0x00060005,
873f43cf1b1SMichael Neumann 	0x9184, 0xffffffff, 0x00090008,
874f43cf1b1SMichael Neumann 	0x9188, 0xffffffff, 0x00030002,
875f43cf1b1SMichael Neumann 	0x918c, 0xffffffff, 0x00050004,
876f43cf1b1SMichael Neumann 	0x9190, 0xffffffff, 0x00000008,
877f43cf1b1SMichael Neumann 	0x9194, 0xffffffff, 0x00070006,
878f43cf1b1SMichael Neumann 	0x9198, 0xffffffff, 0x000a0009,
879f43cf1b1SMichael Neumann 	0x919c, 0xffffffff, 0x00040003,
880f43cf1b1SMichael Neumann 	0x91a0, 0xffffffff, 0x00060005,
881f43cf1b1SMichael Neumann 	0x91a4, 0xffffffff, 0x00000009,
882f43cf1b1SMichael Neumann 	0x91a8, 0xffffffff, 0x00080007,
883f43cf1b1SMichael Neumann 	0x91ac, 0xffffffff, 0x000b000a,
884f43cf1b1SMichael Neumann 	0x91b0, 0xffffffff, 0x00050004,
885f43cf1b1SMichael Neumann 	0x91b4, 0xffffffff, 0x00070006,
886f43cf1b1SMichael Neumann 	0x91b8, 0xffffffff, 0x0008000b,
887f43cf1b1SMichael Neumann 	0x91bc, 0xffffffff, 0x000a0009,
888f43cf1b1SMichael Neumann 	0x91c0, 0xffffffff, 0x000d000c,
889f43cf1b1SMichael Neumann 	0x9200, 0xffffffff, 0x00090008,
890f43cf1b1SMichael Neumann 	0x9204, 0xffffffff, 0x000b000a,
891f43cf1b1SMichael Neumann 	0x9208, 0xffffffff, 0x000c000f,
892f43cf1b1SMichael Neumann 	0x920c, 0xffffffff, 0x000e000d,
893f43cf1b1SMichael Neumann 	0x9210, 0xffffffff, 0x00110010,
894f43cf1b1SMichael Neumann 	0x9214, 0xffffffff, 0x000a0009,
895f43cf1b1SMichael Neumann 	0x9218, 0xffffffff, 0x000c000b,
896f43cf1b1SMichael Neumann 	0x921c, 0xffffffff, 0x0000000f,
897f43cf1b1SMichael Neumann 	0x9220, 0xffffffff, 0x000e000d,
898f43cf1b1SMichael Neumann 	0x9224, 0xffffffff, 0x00110010,
899f43cf1b1SMichael Neumann 	0x9228, 0xffffffff, 0x000b000a,
900f43cf1b1SMichael Neumann 	0x922c, 0xffffffff, 0x000d000c,
901f43cf1b1SMichael Neumann 	0x9230, 0xffffffff, 0x00000010,
902f43cf1b1SMichael Neumann 	0x9234, 0xffffffff, 0x000f000e,
903f43cf1b1SMichael Neumann 	0x9238, 0xffffffff, 0x00120011,
904f43cf1b1SMichael Neumann 	0x923c, 0xffffffff, 0x000c000b,
905f43cf1b1SMichael Neumann 	0x9240, 0xffffffff, 0x000e000d,
906f43cf1b1SMichael Neumann 	0x9244, 0xffffffff, 0x00000011,
907f43cf1b1SMichael Neumann 	0x9248, 0xffffffff, 0x0010000f,
908f43cf1b1SMichael Neumann 	0x924c, 0xffffffff, 0x00130012,
909f43cf1b1SMichael Neumann 	0x9250, 0xffffffff, 0x000d000c,
910f43cf1b1SMichael Neumann 	0x9254, 0xffffffff, 0x000f000e,
911f43cf1b1SMichael Neumann 	0x9258, 0xffffffff, 0x00100013,
912f43cf1b1SMichael Neumann 	0x925c, 0xffffffff, 0x00120011,
913f43cf1b1SMichael Neumann 	0x9260, 0xffffffff, 0x00150014,
914f43cf1b1SMichael Neumann 	0x9150, 0xffffffff, 0x96940200,
915f43cf1b1SMichael Neumann 	0x8708, 0xffffffff, 0x00900100,
916f43cf1b1SMichael Neumann 	0xc478, 0xffffffff, 0x00000080,
917f43cf1b1SMichael Neumann 	0xc404, 0xffffffff, 0x0020003f,
918f43cf1b1SMichael Neumann 	0x30, 0xffffffff, 0x0000001c,
919f43cf1b1SMichael Neumann 	0x34, 0x000f0000, 0x000f0000,
920f43cf1b1SMichael Neumann 	0x160c, 0xffffffff, 0x00000100,
921f43cf1b1SMichael Neumann 	0x1024, 0xffffffff, 0x00000100,
922f43cf1b1SMichael Neumann 	0x102c, 0x00000101, 0x00000000,
923f43cf1b1SMichael Neumann 	0x20a8, 0xffffffff, 0x00000104,
924f43cf1b1SMichael Neumann 	0x264c, 0x000c0000, 0x000c0000,
925f43cf1b1SMichael Neumann 	0x2648, 0x000c0000, 0x000c0000,
926f43cf1b1SMichael Neumann 	0x55e4, 0xff000fff, 0x00000100,
927f43cf1b1SMichael Neumann 	0x55e8, 0x00000001, 0x00000001,
928f43cf1b1SMichael Neumann 	0x2f50, 0x00000001, 0x00000001,
929f43cf1b1SMichael Neumann 	0x30cc, 0xc0000fff, 0x00000104,
930f43cf1b1SMichael Neumann 	0xc1e4, 0x00000001, 0x00000001,
931f43cf1b1SMichael Neumann 	0xd0c0, 0xfffffff0, 0x00000100,
932f43cf1b1SMichael Neumann 	0xd8c0, 0xfffffff0, 0x00000100
933f43cf1b1SMichael Neumann };
934f43cf1b1SMichael Neumann 
935f43cf1b1SMichael Neumann static const u32 oland_mgcg_cgcg_init[] =
936f43cf1b1SMichael Neumann {
937f43cf1b1SMichael Neumann 	0xc400, 0xffffffff, 0xfffffffc,
938f43cf1b1SMichael Neumann 	0x802c, 0xffffffff, 0xe0000000,
939f43cf1b1SMichael Neumann 	0x9a60, 0xffffffff, 0x00000100,
940f43cf1b1SMichael Neumann 	0x92a4, 0xffffffff, 0x00000100,
941f43cf1b1SMichael Neumann 	0xc164, 0xffffffff, 0x00000100,
942f43cf1b1SMichael Neumann 	0x9774, 0xffffffff, 0x00000100,
943f43cf1b1SMichael Neumann 	0x8984, 0xffffffff, 0x06000100,
944f43cf1b1SMichael Neumann 	0x8a18, 0xffffffff, 0x00000100,
945f43cf1b1SMichael Neumann 	0x92a0, 0xffffffff, 0x00000100,
946f43cf1b1SMichael Neumann 	0xc380, 0xffffffff, 0x00000100,
947f43cf1b1SMichael Neumann 	0x8b28, 0xffffffff, 0x00000100,
948f43cf1b1SMichael Neumann 	0x9144, 0xffffffff, 0x00000100,
949f43cf1b1SMichael Neumann 	0x8d88, 0xffffffff, 0x00000100,
950f43cf1b1SMichael Neumann 	0x8d8c, 0xffffffff, 0x00000100,
951f43cf1b1SMichael Neumann 	0x9030, 0xffffffff, 0x00000100,
952f43cf1b1SMichael Neumann 	0x9034, 0xffffffff, 0x00000100,
953f43cf1b1SMichael Neumann 	0x9038, 0xffffffff, 0x00000100,
954f43cf1b1SMichael Neumann 	0x903c, 0xffffffff, 0x00000100,
955f43cf1b1SMichael Neumann 	0xad80, 0xffffffff, 0x00000100,
956f43cf1b1SMichael Neumann 	0xac54, 0xffffffff, 0x00000100,
957f43cf1b1SMichael Neumann 	0x897c, 0xffffffff, 0x06000100,
958f43cf1b1SMichael Neumann 	0x9868, 0xffffffff, 0x00000100,
959f43cf1b1SMichael Neumann 	0x9510, 0xffffffff, 0x00000100,
960f43cf1b1SMichael Neumann 	0xaf04, 0xffffffff, 0x00000100,
961f43cf1b1SMichael Neumann 	0xae04, 0xffffffff, 0x00000100,
962f43cf1b1SMichael Neumann 	0x949c, 0xffffffff, 0x00000100,
963f43cf1b1SMichael Neumann 	0x802c, 0xffffffff, 0xe0000000,
964f43cf1b1SMichael Neumann 	0x9160, 0xffffffff, 0x00010000,
965f43cf1b1SMichael Neumann 	0x9164, 0xffffffff, 0x00030002,
966f43cf1b1SMichael Neumann 	0x9168, 0xffffffff, 0x00040007,
967f43cf1b1SMichael Neumann 	0x916c, 0xffffffff, 0x00060005,
968f43cf1b1SMichael Neumann 	0x9170, 0xffffffff, 0x00090008,
969f43cf1b1SMichael Neumann 	0x9174, 0xffffffff, 0x00020001,
970f43cf1b1SMichael Neumann 	0x9178, 0xffffffff, 0x00040003,
971f43cf1b1SMichael Neumann 	0x917c, 0xffffffff, 0x00000007,
972f43cf1b1SMichael Neumann 	0x9180, 0xffffffff, 0x00060005,
973f43cf1b1SMichael Neumann 	0x9184, 0xffffffff, 0x00090008,
974f43cf1b1SMichael Neumann 	0x9188, 0xffffffff, 0x00030002,
975f43cf1b1SMichael Neumann 	0x918c, 0xffffffff, 0x00050004,
976f43cf1b1SMichael Neumann 	0x9190, 0xffffffff, 0x00000008,
977f43cf1b1SMichael Neumann 	0x9194, 0xffffffff, 0x00070006,
978f43cf1b1SMichael Neumann 	0x9198, 0xffffffff, 0x000a0009,
979f43cf1b1SMichael Neumann 	0x919c, 0xffffffff, 0x00040003,
980f43cf1b1SMichael Neumann 	0x91a0, 0xffffffff, 0x00060005,
981f43cf1b1SMichael Neumann 	0x91a4, 0xffffffff, 0x00000009,
982f43cf1b1SMichael Neumann 	0x91a8, 0xffffffff, 0x00080007,
983f43cf1b1SMichael Neumann 	0x91ac, 0xffffffff, 0x000b000a,
984f43cf1b1SMichael Neumann 	0x91b0, 0xffffffff, 0x00050004,
985f43cf1b1SMichael Neumann 	0x91b4, 0xffffffff, 0x00070006,
986f43cf1b1SMichael Neumann 	0x91b8, 0xffffffff, 0x0008000b,
987f43cf1b1SMichael Neumann 	0x91bc, 0xffffffff, 0x000a0009,
988f43cf1b1SMichael Neumann 	0x91c0, 0xffffffff, 0x000d000c,
989f43cf1b1SMichael Neumann 	0x91c4, 0xffffffff, 0x00060005,
990f43cf1b1SMichael Neumann 	0x91c8, 0xffffffff, 0x00080007,
991f43cf1b1SMichael Neumann 	0x91cc, 0xffffffff, 0x0000000b,
992f43cf1b1SMichael Neumann 	0x91d0, 0xffffffff, 0x000a0009,
993f43cf1b1SMichael Neumann 	0x91d4, 0xffffffff, 0x000d000c,
994f43cf1b1SMichael Neumann 	0x9150, 0xffffffff, 0x96940200,
995f43cf1b1SMichael Neumann 	0x8708, 0xffffffff, 0x00900100,
996f43cf1b1SMichael Neumann 	0xc478, 0xffffffff, 0x00000080,
997f43cf1b1SMichael Neumann 	0xc404, 0xffffffff, 0x0020003f,
998f43cf1b1SMichael Neumann 	0x30, 0xffffffff, 0x0000001c,
999f43cf1b1SMichael Neumann 	0x34, 0x000f0000, 0x000f0000,
1000f43cf1b1SMichael Neumann 	0x160c, 0xffffffff, 0x00000100,
1001f43cf1b1SMichael Neumann 	0x1024, 0xffffffff, 0x00000100,
1002f43cf1b1SMichael Neumann 	0x102c, 0x00000101, 0x00000000,
1003f43cf1b1SMichael Neumann 	0x20a8, 0xffffffff, 0x00000104,
1004f43cf1b1SMichael Neumann 	0x264c, 0x000c0000, 0x000c0000,
1005f43cf1b1SMichael Neumann 	0x2648, 0x000c0000, 0x000c0000,
1006f43cf1b1SMichael Neumann 	0x55e4, 0xff000fff, 0x00000100,
1007f43cf1b1SMichael Neumann 	0x55e8, 0x00000001, 0x00000001,
1008f43cf1b1SMichael Neumann 	0x2f50, 0x00000001, 0x00000001,
1009f43cf1b1SMichael Neumann 	0x30cc, 0xc0000fff, 0x00000104,
1010f43cf1b1SMichael Neumann 	0xc1e4, 0x00000001, 0x00000001,
1011f43cf1b1SMichael Neumann 	0xd0c0, 0xfffffff0, 0x00000100,
1012f43cf1b1SMichael Neumann 	0xd8c0, 0xfffffff0, 0x00000100
1013f43cf1b1SMichael Neumann };
1014f43cf1b1SMichael Neumann 
1015f43cf1b1SMichael Neumann static const u32 hainan_mgcg_cgcg_init[] =
1016f43cf1b1SMichael Neumann {
1017f43cf1b1SMichael Neumann 	0xc400, 0xffffffff, 0xfffffffc,
1018f43cf1b1SMichael Neumann 	0x802c, 0xffffffff, 0xe0000000,
1019f43cf1b1SMichael Neumann 	0x9a60, 0xffffffff, 0x00000100,
1020f43cf1b1SMichael Neumann 	0x92a4, 0xffffffff, 0x00000100,
1021f43cf1b1SMichael Neumann 	0xc164, 0xffffffff, 0x00000100,
1022f43cf1b1SMichael Neumann 	0x9774, 0xffffffff, 0x00000100,
1023f43cf1b1SMichael Neumann 	0x8984, 0xffffffff, 0x06000100,
1024f43cf1b1SMichael Neumann 	0x8a18, 0xffffffff, 0x00000100,
1025f43cf1b1SMichael Neumann 	0x92a0, 0xffffffff, 0x00000100,
1026f43cf1b1SMichael Neumann 	0xc380, 0xffffffff, 0x00000100,
1027f43cf1b1SMichael Neumann 	0x8b28, 0xffffffff, 0x00000100,
1028f43cf1b1SMichael Neumann 	0x9144, 0xffffffff, 0x00000100,
1029f43cf1b1SMichael Neumann 	0x8d88, 0xffffffff, 0x00000100,
1030f43cf1b1SMichael Neumann 	0x8d8c, 0xffffffff, 0x00000100,
1031f43cf1b1SMichael Neumann 	0x9030, 0xffffffff, 0x00000100,
1032f43cf1b1SMichael Neumann 	0x9034, 0xffffffff, 0x00000100,
1033f43cf1b1SMichael Neumann 	0x9038, 0xffffffff, 0x00000100,
1034f43cf1b1SMichael Neumann 	0x903c, 0xffffffff, 0x00000100,
1035f43cf1b1SMichael Neumann 	0xad80, 0xffffffff, 0x00000100,
1036f43cf1b1SMichael Neumann 	0xac54, 0xffffffff, 0x00000100,
1037f43cf1b1SMichael Neumann 	0x897c, 0xffffffff, 0x06000100,
1038f43cf1b1SMichael Neumann 	0x9868, 0xffffffff, 0x00000100,
1039f43cf1b1SMichael Neumann 	0x9510, 0xffffffff, 0x00000100,
1040f43cf1b1SMichael Neumann 	0xaf04, 0xffffffff, 0x00000100,
1041f43cf1b1SMichael Neumann 	0xae04, 0xffffffff, 0x00000100,
1042f43cf1b1SMichael Neumann 	0x949c, 0xffffffff, 0x00000100,
1043f43cf1b1SMichael Neumann 	0x802c, 0xffffffff, 0xe0000000,
1044f43cf1b1SMichael Neumann 	0x9160, 0xffffffff, 0x00010000,
1045f43cf1b1SMichael Neumann 	0x9164, 0xffffffff, 0x00030002,
1046f43cf1b1SMichael Neumann 	0x9168, 0xffffffff, 0x00040007,
1047f43cf1b1SMichael Neumann 	0x916c, 0xffffffff, 0x00060005,
1048f43cf1b1SMichael Neumann 	0x9170, 0xffffffff, 0x00090008,
1049f43cf1b1SMichael Neumann 	0x9174, 0xffffffff, 0x00020001,
1050f43cf1b1SMichael Neumann 	0x9178, 0xffffffff, 0x00040003,
1051f43cf1b1SMichael Neumann 	0x917c, 0xffffffff, 0x00000007,
1052f43cf1b1SMichael Neumann 	0x9180, 0xffffffff, 0x00060005,
1053f43cf1b1SMichael Neumann 	0x9184, 0xffffffff, 0x00090008,
1054f43cf1b1SMichael Neumann 	0x9188, 0xffffffff, 0x00030002,
1055f43cf1b1SMichael Neumann 	0x918c, 0xffffffff, 0x00050004,
1056f43cf1b1SMichael Neumann 	0x9190, 0xffffffff, 0x00000008,
1057f43cf1b1SMichael Neumann 	0x9194, 0xffffffff, 0x00070006,
1058f43cf1b1SMichael Neumann 	0x9198, 0xffffffff, 0x000a0009,
1059f43cf1b1SMichael Neumann 	0x919c, 0xffffffff, 0x00040003,
1060f43cf1b1SMichael Neumann 	0x91a0, 0xffffffff, 0x00060005,
1061f43cf1b1SMichael Neumann 	0x91a4, 0xffffffff, 0x00000009,
1062f43cf1b1SMichael Neumann 	0x91a8, 0xffffffff, 0x00080007,
1063f43cf1b1SMichael Neumann 	0x91ac, 0xffffffff, 0x000b000a,
1064f43cf1b1SMichael Neumann 	0x91b0, 0xffffffff, 0x00050004,
1065f43cf1b1SMichael Neumann 	0x91b4, 0xffffffff, 0x00070006,
1066f43cf1b1SMichael Neumann 	0x91b8, 0xffffffff, 0x0008000b,
1067f43cf1b1SMichael Neumann 	0x91bc, 0xffffffff, 0x000a0009,
1068f43cf1b1SMichael Neumann 	0x91c0, 0xffffffff, 0x000d000c,
1069f43cf1b1SMichael Neumann 	0x91c4, 0xffffffff, 0x00060005,
1070f43cf1b1SMichael Neumann 	0x91c8, 0xffffffff, 0x00080007,
1071f43cf1b1SMichael Neumann 	0x91cc, 0xffffffff, 0x0000000b,
1072f43cf1b1SMichael Neumann 	0x91d0, 0xffffffff, 0x000a0009,
1073f43cf1b1SMichael Neumann 	0x91d4, 0xffffffff, 0x000d000c,
1074f43cf1b1SMichael Neumann 	0x9150, 0xffffffff, 0x96940200,
1075f43cf1b1SMichael Neumann 	0x8708, 0xffffffff, 0x00900100,
1076f43cf1b1SMichael Neumann 	0xc478, 0xffffffff, 0x00000080,
1077f43cf1b1SMichael Neumann 	0xc404, 0xffffffff, 0x0020003f,
1078f43cf1b1SMichael Neumann 	0x30, 0xffffffff, 0x0000001c,
1079f43cf1b1SMichael Neumann 	0x34, 0x000f0000, 0x000f0000,
1080f43cf1b1SMichael Neumann 	0x160c, 0xffffffff, 0x00000100,
1081f43cf1b1SMichael Neumann 	0x1024, 0xffffffff, 0x00000100,
1082f43cf1b1SMichael Neumann 	0x20a8, 0xffffffff, 0x00000104,
1083f43cf1b1SMichael Neumann 	0x264c, 0x000c0000, 0x000c0000,
1084f43cf1b1SMichael Neumann 	0x2648, 0x000c0000, 0x000c0000,
1085f43cf1b1SMichael Neumann 	0x2f50, 0x00000001, 0x00000001,
1086f43cf1b1SMichael Neumann 	0x30cc, 0xc0000fff, 0x00000104,
1087f43cf1b1SMichael Neumann 	0xc1e4, 0x00000001, 0x00000001,
1088f43cf1b1SMichael Neumann 	0xd0c0, 0xfffffff0, 0x00000100,
1089f43cf1b1SMichael Neumann 	0xd8c0, 0xfffffff0, 0x00000100
1090f43cf1b1SMichael Neumann };
1091f43cf1b1SMichael Neumann 
1092f43cf1b1SMichael Neumann static u32 verde_pg_init[] =
1093f43cf1b1SMichael Neumann {
1094f43cf1b1SMichael Neumann 	0x353c, 0xffffffff, 0x40000,
1095f43cf1b1SMichael Neumann 	0x3538, 0xffffffff, 0x200010ff,
1096f43cf1b1SMichael Neumann 	0x353c, 0xffffffff, 0x0,
1097f43cf1b1SMichael Neumann 	0x353c, 0xffffffff, 0x0,
1098f43cf1b1SMichael Neumann 	0x353c, 0xffffffff, 0x0,
1099f43cf1b1SMichael Neumann 	0x353c, 0xffffffff, 0x0,
1100f43cf1b1SMichael Neumann 	0x353c, 0xffffffff, 0x0,
1101f43cf1b1SMichael Neumann 	0x353c, 0xffffffff, 0x7007,
1102f43cf1b1SMichael Neumann 	0x3538, 0xffffffff, 0x300010ff,
1103f43cf1b1SMichael Neumann 	0x353c, 0xffffffff, 0x0,
1104f43cf1b1SMichael Neumann 	0x353c, 0xffffffff, 0x0,
1105f43cf1b1SMichael Neumann 	0x353c, 0xffffffff, 0x0,
1106f43cf1b1SMichael Neumann 	0x353c, 0xffffffff, 0x0,
1107f43cf1b1SMichael Neumann 	0x353c, 0xffffffff, 0x0,
1108f43cf1b1SMichael Neumann 	0x353c, 0xffffffff, 0x400000,
1109f43cf1b1SMichael Neumann 	0x3538, 0xffffffff, 0x100010ff,
1110f43cf1b1SMichael Neumann 	0x353c, 0xffffffff, 0x0,
1111f43cf1b1SMichael Neumann 	0x353c, 0xffffffff, 0x0,
1112f43cf1b1SMichael Neumann 	0x353c, 0xffffffff, 0x0,
1113f43cf1b1SMichael Neumann 	0x353c, 0xffffffff, 0x0,
1114f43cf1b1SMichael Neumann 	0x353c, 0xffffffff, 0x0,
1115f43cf1b1SMichael Neumann 	0x353c, 0xffffffff, 0x120200,
1116f43cf1b1SMichael Neumann 	0x3538, 0xffffffff, 0x500010ff,
1117f43cf1b1SMichael Neumann 	0x353c, 0xffffffff, 0x0,
1118f43cf1b1SMichael Neumann 	0x353c, 0xffffffff, 0x0,
1119f43cf1b1SMichael Neumann 	0x353c, 0xffffffff, 0x0,
1120f43cf1b1SMichael Neumann 	0x353c, 0xffffffff, 0x0,
1121f43cf1b1SMichael Neumann 	0x353c, 0xffffffff, 0x0,
1122f43cf1b1SMichael Neumann 	0x353c, 0xffffffff, 0x1e1e16,
1123f43cf1b1SMichael Neumann 	0x3538, 0xffffffff, 0x600010ff,
1124f43cf1b1SMichael Neumann 	0x353c, 0xffffffff, 0x0,
1125f43cf1b1SMichael Neumann 	0x353c, 0xffffffff, 0x0,
1126f43cf1b1SMichael Neumann 	0x353c, 0xffffffff, 0x0,
1127f43cf1b1SMichael Neumann 	0x353c, 0xffffffff, 0x0,
1128f43cf1b1SMichael Neumann 	0x353c, 0xffffffff, 0x0,
1129f43cf1b1SMichael Neumann 	0x353c, 0xffffffff, 0x171f1e,
1130f43cf1b1SMichael Neumann 	0x3538, 0xffffffff, 0x700010ff,
1131f43cf1b1SMichael Neumann 	0x353c, 0xffffffff, 0x0,
1132f43cf1b1SMichael Neumann 	0x353c, 0xffffffff, 0x0,
1133f43cf1b1SMichael Neumann 	0x353c, 0xffffffff, 0x0,
1134f43cf1b1SMichael Neumann 	0x353c, 0xffffffff, 0x0,
1135f43cf1b1SMichael Neumann 	0x353c, 0xffffffff, 0x0,
1136f43cf1b1SMichael Neumann 	0x353c, 0xffffffff, 0x0,
1137f43cf1b1SMichael Neumann 	0x3538, 0xffffffff, 0x9ff,
1138f43cf1b1SMichael Neumann 	0x3500, 0xffffffff, 0x0,
1139f43cf1b1SMichael Neumann 	0x3504, 0xffffffff, 0x10000800,
1140f43cf1b1SMichael Neumann 	0x3504, 0xffffffff, 0xf,
1141f43cf1b1SMichael Neumann 	0x3504, 0xffffffff, 0xf,
1142f43cf1b1SMichael Neumann 	0x3500, 0xffffffff, 0x4,
1143f43cf1b1SMichael Neumann 	0x3504, 0xffffffff, 0x1000051e,
1144f43cf1b1SMichael Neumann 	0x3504, 0xffffffff, 0xffff,
1145f43cf1b1SMichael Neumann 	0x3504, 0xffffffff, 0xffff,
1146f43cf1b1SMichael Neumann 	0x3500, 0xffffffff, 0x8,
1147f43cf1b1SMichael Neumann 	0x3504, 0xffffffff, 0x80500,
1148f43cf1b1SMichael Neumann 	0x3500, 0xffffffff, 0x12,
1149f43cf1b1SMichael Neumann 	0x3504, 0xffffffff, 0x9050c,
1150f43cf1b1SMichael Neumann 	0x3500, 0xffffffff, 0x1d,
1151f43cf1b1SMichael Neumann 	0x3504, 0xffffffff, 0xb052c,
1152f43cf1b1SMichael Neumann 	0x3500, 0xffffffff, 0x2a,
1153f43cf1b1SMichael Neumann 	0x3504, 0xffffffff, 0x1053e,
1154f43cf1b1SMichael Neumann 	0x3500, 0xffffffff, 0x2d,
1155f43cf1b1SMichael Neumann 	0x3504, 0xffffffff, 0x10546,
1156f43cf1b1SMichael Neumann 	0x3500, 0xffffffff, 0x30,
1157f43cf1b1SMichael Neumann 	0x3504, 0xffffffff, 0xa054e,
1158f43cf1b1SMichael Neumann 	0x3500, 0xffffffff, 0x3c,
1159f43cf1b1SMichael Neumann 	0x3504, 0xffffffff, 0x1055f,
1160f43cf1b1SMichael Neumann 	0x3500, 0xffffffff, 0x3f,
1161f43cf1b1SMichael Neumann 	0x3504, 0xffffffff, 0x10567,
1162f43cf1b1SMichael Neumann 	0x3500, 0xffffffff, 0x42,
1163f43cf1b1SMichael Neumann 	0x3504, 0xffffffff, 0x1056f,
1164f43cf1b1SMichael Neumann 	0x3500, 0xffffffff, 0x45,
1165f43cf1b1SMichael Neumann 	0x3504, 0xffffffff, 0x10572,
1166f43cf1b1SMichael Neumann 	0x3500, 0xffffffff, 0x48,
1167f43cf1b1SMichael Neumann 	0x3504, 0xffffffff, 0x20575,
1168f43cf1b1SMichael Neumann 	0x3500, 0xffffffff, 0x4c,
1169f43cf1b1SMichael Neumann 	0x3504, 0xffffffff, 0x190801,
1170f43cf1b1SMichael Neumann 	0x3500, 0xffffffff, 0x67,
1171f43cf1b1SMichael Neumann 	0x3504, 0xffffffff, 0x1082a,
1172f43cf1b1SMichael Neumann 	0x3500, 0xffffffff, 0x6a,
1173f43cf1b1SMichael Neumann 	0x3504, 0xffffffff, 0x1b082d,
1174f43cf1b1SMichael Neumann 	0x3500, 0xffffffff, 0x87,
1175f43cf1b1SMichael Neumann 	0x3504, 0xffffffff, 0x310851,
1176f43cf1b1SMichael Neumann 	0x3500, 0xffffffff, 0xba,
1177f43cf1b1SMichael Neumann 	0x3504, 0xffffffff, 0x891,
1178f43cf1b1SMichael Neumann 	0x3500, 0xffffffff, 0xbc,
1179f43cf1b1SMichael Neumann 	0x3504, 0xffffffff, 0x893,
1180f43cf1b1SMichael Neumann 	0x3500, 0xffffffff, 0xbe,
1181f43cf1b1SMichael Neumann 	0x3504, 0xffffffff, 0x20895,
1182f43cf1b1SMichael Neumann 	0x3500, 0xffffffff, 0xc2,
1183f43cf1b1SMichael Neumann 	0x3504, 0xffffffff, 0x20899,
1184f43cf1b1SMichael Neumann 	0x3500, 0xffffffff, 0xc6,
1185f43cf1b1SMichael Neumann 	0x3504, 0xffffffff, 0x2089d,
1186f43cf1b1SMichael Neumann 	0x3500, 0xffffffff, 0xca,
1187f43cf1b1SMichael Neumann 	0x3504, 0xffffffff, 0x8a1,
1188f43cf1b1SMichael Neumann 	0x3500, 0xffffffff, 0xcc,
1189f43cf1b1SMichael Neumann 	0x3504, 0xffffffff, 0x8a3,
1190f43cf1b1SMichael Neumann 	0x3500, 0xffffffff, 0xce,
1191f43cf1b1SMichael Neumann 	0x3504, 0xffffffff, 0x308a5,
1192f43cf1b1SMichael Neumann 	0x3500, 0xffffffff, 0xd3,
1193f43cf1b1SMichael Neumann 	0x3504, 0xffffffff, 0x6d08cd,
1194f43cf1b1SMichael Neumann 	0x3500, 0xffffffff, 0x142,
1195f43cf1b1SMichael Neumann 	0x3504, 0xffffffff, 0x2000095a,
1196f43cf1b1SMichael Neumann 	0x3504, 0xffffffff, 0x1,
1197f43cf1b1SMichael Neumann 	0x3500, 0xffffffff, 0x144,
1198f43cf1b1SMichael Neumann 	0x3504, 0xffffffff, 0x301f095b,
1199f43cf1b1SMichael Neumann 	0x3500, 0xffffffff, 0x165,
1200f43cf1b1SMichael Neumann 	0x3504, 0xffffffff, 0xc094d,
1201f43cf1b1SMichael Neumann 	0x3500, 0xffffffff, 0x173,
1202f43cf1b1SMichael Neumann 	0x3504, 0xffffffff, 0xf096d,
1203f43cf1b1SMichael Neumann 	0x3500, 0xffffffff, 0x184,
1204f43cf1b1SMichael Neumann 	0x3504, 0xffffffff, 0x15097f,
1205f43cf1b1SMichael Neumann 	0x3500, 0xffffffff, 0x19b,
1206f43cf1b1SMichael Neumann 	0x3504, 0xffffffff, 0xc0998,
1207f43cf1b1SMichael Neumann 	0x3500, 0xffffffff, 0x1a9,
1208f43cf1b1SMichael Neumann 	0x3504, 0xffffffff, 0x409a7,
1209f43cf1b1SMichael Neumann 	0x3500, 0xffffffff, 0x1af,
1210f43cf1b1SMichael Neumann 	0x3504, 0xffffffff, 0xcdc,
1211f43cf1b1SMichael Neumann 	0x3500, 0xffffffff, 0x1b1,
1212f43cf1b1SMichael Neumann 	0x3504, 0xffffffff, 0x800,
1213f43cf1b1SMichael Neumann 	0x3508, 0xffffffff, 0x6c9b2000,
1214f43cf1b1SMichael Neumann 	0x3510, 0xfc00, 0x2000,
1215f43cf1b1SMichael Neumann 	0x3544, 0xffffffff, 0xfc0,
1216f43cf1b1SMichael Neumann 	0x28d4, 0x00000100, 0x100
1217f43cf1b1SMichael Neumann };
1218f43cf1b1SMichael Neumann 
si_init_golden_registers(struct radeon_device * rdev)1219f43cf1b1SMichael Neumann static void si_init_golden_registers(struct radeon_device *rdev)
1220f43cf1b1SMichael Neumann {
1221f43cf1b1SMichael Neumann 	switch (rdev->family) {
1222f43cf1b1SMichael Neumann 	case CHIP_TAHITI:
1223f43cf1b1SMichael Neumann 		radeon_program_register_sequence(rdev,
1224f43cf1b1SMichael Neumann 						 tahiti_golden_registers,
1225f43cf1b1SMichael Neumann 						 (const u32)ARRAY_SIZE(tahiti_golden_registers));
1226f43cf1b1SMichael Neumann 		radeon_program_register_sequence(rdev,
1227f43cf1b1SMichael Neumann 						 tahiti_golden_rlc_registers,
1228f43cf1b1SMichael Neumann 						 (const u32)ARRAY_SIZE(tahiti_golden_rlc_registers));
1229f43cf1b1SMichael Neumann 		radeon_program_register_sequence(rdev,
1230f43cf1b1SMichael Neumann 						 tahiti_mgcg_cgcg_init,
1231f43cf1b1SMichael Neumann 						 (const u32)ARRAY_SIZE(tahiti_mgcg_cgcg_init));
1232f43cf1b1SMichael Neumann 		radeon_program_register_sequence(rdev,
1233f43cf1b1SMichael Neumann 						 tahiti_golden_registers2,
1234f43cf1b1SMichael Neumann 						 (const u32)ARRAY_SIZE(tahiti_golden_registers2));
1235f43cf1b1SMichael Neumann 		break;
1236f43cf1b1SMichael Neumann 	case CHIP_PITCAIRN:
1237f43cf1b1SMichael Neumann 		radeon_program_register_sequence(rdev,
1238f43cf1b1SMichael Neumann 						 pitcairn_golden_registers,
1239f43cf1b1SMichael Neumann 						 (const u32)ARRAY_SIZE(pitcairn_golden_registers));
1240f43cf1b1SMichael Neumann 		radeon_program_register_sequence(rdev,
1241f43cf1b1SMichael Neumann 						 pitcairn_golden_rlc_registers,
1242f43cf1b1SMichael Neumann 						 (const u32)ARRAY_SIZE(pitcairn_golden_rlc_registers));
1243f43cf1b1SMichael Neumann 		radeon_program_register_sequence(rdev,
1244f43cf1b1SMichael Neumann 						 pitcairn_mgcg_cgcg_init,
1245f43cf1b1SMichael Neumann 						 (const u32)ARRAY_SIZE(pitcairn_mgcg_cgcg_init));
1246f43cf1b1SMichael Neumann 		break;
1247f43cf1b1SMichael Neumann 	case CHIP_VERDE:
1248f43cf1b1SMichael Neumann 		radeon_program_register_sequence(rdev,
1249f43cf1b1SMichael Neumann 						 verde_golden_registers,
1250f43cf1b1SMichael Neumann 						 (const u32)ARRAY_SIZE(verde_golden_registers));
1251f43cf1b1SMichael Neumann 		radeon_program_register_sequence(rdev,
1252f43cf1b1SMichael Neumann 						 verde_golden_rlc_registers,
1253f43cf1b1SMichael Neumann 						 (const u32)ARRAY_SIZE(verde_golden_rlc_registers));
1254f43cf1b1SMichael Neumann 		radeon_program_register_sequence(rdev,
1255f43cf1b1SMichael Neumann 						 verde_mgcg_cgcg_init,
1256f43cf1b1SMichael Neumann 						 (const u32)ARRAY_SIZE(verde_mgcg_cgcg_init));
1257f43cf1b1SMichael Neumann 		radeon_program_register_sequence(rdev,
1258f43cf1b1SMichael Neumann 						 verde_pg_init,
1259f43cf1b1SMichael Neumann 						 (const u32)ARRAY_SIZE(verde_pg_init));
1260f43cf1b1SMichael Neumann 		break;
1261f43cf1b1SMichael Neumann 	case CHIP_OLAND:
1262f43cf1b1SMichael Neumann 		radeon_program_register_sequence(rdev,
1263f43cf1b1SMichael Neumann 						 oland_golden_registers,
1264f43cf1b1SMichael Neumann 						 (const u32)ARRAY_SIZE(oland_golden_registers));
1265f43cf1b1SMichael Neumann 		radeon_program_register_sequence(rdev,
1266f43cf1b1SMichael Neumann 						 oland_golden_rlc_registers,
1267f43cf1b1SMichael Neumann 						 (const u32)ARRAY_SIZE(oland_golden_rlc_registers));
1268f43cf1b1SMichael Neumann 		radeon_program_register_sequence(rdev,
1269f43cf1b1SMichael Neumann 						 oland_mgcg_cgcg_init,
1270f43cf1b1SMichael Neumann 						 (const u32)ARRAY_SIZE(oland_mgcg_cgcg_init));
1271f43cf1b1SMichael Neumann 		break;
1272f43cf1b1SMichael Neumann 	case CHIP_HAINAN:
1273f43cf1b1SMichael Neumann 		radeon_program_register_sequence(rdev,
1274f43cf1b1SMichael Neumann 						 hainan_golden_registers,
1275f43cf1b1SMichael Neumann 						 (const u32)ARRAY_SIZE(hainan_golden_registers));
1276f43cf1b1SMichael Neumann 		radeon_program_register_sequence(rdev,
1277f43cf1b1SMichael Neumann 						 hainan_golden_registers2,
1278f43cf1b1SMichael Neumann 						 (const u32)ARRAY_SIZE(hainan_golden_registers2));
1279f43cf1b1SMichael Neumann 		radeon_program_register_sequence(rdev,
1280f43cf1b1SMichael Neumann 						 hainan_mgcg_cgcg_init,
1281f43cf1b1SMichael Neumann 						 (const u32)ARRAY_SIZE(hainan_mgcg_cgcg_init));
1282f43cf1b1SMichael Neumann 		break;
1283f43cf1b1SMichael Neumann 	default:
1284f43cf1b1SMichael Neumann 		break;
1285f43cf1b1SMichael Neumann 	}
1286f43cf1b1SMichael Neumann }
1287f43cf1b1SMichael Neumann 
1288c59a5c48SFrançois Tigeot /**
1289c59a5c48SFrançois Tigeot  * si_get_allowed_info_register - fetch the register for the info ioctl
1290c59a5c48SFrançois Tigeot  *
1291c59a5c48SFrançois Tigeot  * @rdev: radeon_device pointer
1292c59a5c48SFrançois Tigeot  * @reg: register offset in bytes
1293c59a5c48SFrançois Tigeot  * @val: register value
1294c59a5c48SFrançois Tigeot  *
1295c59a5c48SFrançois Tigeot  * Returns 0 for success or -EINVAL for an invalid register
1296c59a5c48SFrançois Tigeot  *
1297c59a5c48SFrançois Tigeot  */
si_get_allowed_info_register(struct radeon_device * rdev,u32 reg,u32 * val)1298c59a5c48SFrançois Tigeot int si_get_allowed_info_register(struct radeon_device *rdev,
1299c59a5c48SFrançois Tigeot 				 u32 reg, u32 *val)
1300c59a5c48SFrançois Tigeot {
1301c59a5c48SFrançois Tigeot 	switch (reg) {
1302c59a5c48SFrançois Tigeot 	case GRBM_STATUS:
1303c59a5c48SFrançois Tigeot 	case GRBM_STATUS2:
1304c59a5c48SFrançois Tigeot 	case GRBM_STATUS_SE0:
1305c59a5c48SFrançois Tigeot 	case GRBM_STATUS_SE1:
1306c59a5c48SFrançois Tigeot 	case SRBM_STATUS:
1307c59a5c48SFrançois Tigeot 	case SRBM_STATUS2:
1308c59a5c48SFrançois Tigeot 	case (DMA_STATUS_REG + DMA0_REGISTER_OFFSET):
1309c59a5c48SFrançois Tigeot 	case (DMA_STATUS_REG + DMA1_REGISTER_OFFSET):
1310c59a5c48SFrançois Tigeot 	case UVD_STATUS:
1311c59a5c48SFrançois Tigeot 		*val = RREG32(reg);
1312c59a5c48SFrançois Tigeot 		return 0;
1313c59a5c48SFrançois Tigeot 	default:
1314c59a5c48SFrançois Tigeot 		return -EINVAL;
1315c59a5c48SFrançois Tigeot 	}
1316c59a5c48SFrançois Tigeot }
1317c59a5c48SFrançois Tigeot 
1318b403bed8SMichael Neumann #define PCIE_BUS_CLK                10000
1319b403bed8SMichael Neumann #define TCLK                        (PCIE_BUS_CLK / 10)
1320b403bed8SMichael Neumann 
1321b403bed8SMichael Neumann /**
1322b403bed8SMichael Neumann  * si_get_xclk - get the xclk
1323b403bed8SMichael Neumann  *
1324b403bed8SMichael Neumann  * @rdev: radeon_device pointer
1325b403bed8SMichael Neumann  *
1326b403bed8SMichael Neumann  * Returns the reference clock used by the gfx engine
1327b403bed8SMichael Neumann  * (SI).
1328b403bed8SMichael Neumann  */
si_get_xclk(struct radeon_device * rdev)1329b403bed8SMichael Neumann u32 si_get_xclk(struct radeon_device *rdev)
1330b403bed8SMichael Neumann {
1331b403bed8SMichael Neumann 	u32 reference_clock = rdev->clock.spll.reference_freq;
1332b403bed8SMichael Neumann 	u32 tmp;
1333b403bed8SMichael Neumann 
1334b403bed8SMichael Neumann 	tmp = RREG32(CG_CLKPIN_CNTL_2);
1335b403bed8SMichael Neumann 	if (tmp & MUX_TCLK_TO_XCLK)
1336b403bed8SMichael Neumann 		return TCLK;
1337b403bed8SMichael Neumann 
1338b403bed8SMichael Neumann 	tmp = RREG32(CG_CLKPIN_CNTL);
1339b403bed8SMichael Neumann 	if (tmp & XTALIN_DIVIDE)
1340b403bed8SMichael Neumann 		return reference_clock / 4;
1341b403bed8SMichael Neumann 
1342b403bed8SMichael Neumann 	return reference_clock;
1343b403bed8SMichael Neumann }
1344926deccbSFrançois Tigeot 
1345926deccbSFrançois Tigeot /* get temperature in millidegrees */
si_get_temp(struct radeon_device * rdev)1346926deccbSFrançois Tigeot int si_get_temp(struct radeon_device *rdev)
1347926deccbSFrançois Tigeot {
1348926deccbSFrançois Tigeot 	u32 temp;
1349926deccbSFrançois Tigeot 	int actual_temp = 0;
1350926deccbSFrançois Tigeot 
1351926deccbSFrançois Tigeot 	temp = (RREG32(CG_MULT_THERMAL_STATUS) & CTF_TEMP_MASK) >>
1352926deccbSFrançois Tigeot 		CTF_TEMP_SHIFT;
1353926deccbSFrançois Tigeot 
1354926deccbSFrançois Tigeot 	if (temp & 0x200)
1355926deccbSFrançois Tigeot 		actual_temp = 255;
1356926deccbSFrançois Tigeot 	else
1357926deccbSFrançois Tigeot 		actual_temp = temp & 0x1ff;
1358926deccbSFrançois Tigeot 
1359926deccbSFrançois Tigeot 	actual_temp = (actual_temp * 1000);
1360926deccbSFrançois Tigeot 
1361926deccbSFrançois Tigeot 	return actual_temp;
1362926deccbSFrançois Tigeot }
1363926deccbSFrançois Tigeot 
1364926deccbSFrançois Tigeot #define TAHITI_IO_MC_REGS_SIZE 36
1365926deccbSFrançois Tigeot 
1366926deccbSFrançois Tigeot static const u32 tahiti_io_mc_regs[TAHITI_IO_MC_REGS_SIZE][2] = {
1367926deccbSFrançois Tigeot 	{0x0000006f, 0x03044000},
1368926deccbSFrançois Tigeot 	{0x00000070, 0x0480c018},
1369926deccbSFrançois Tigeot 	{0x00000071, 0x00000040},
1370926deccbSFrançois Tigeot 	{0x00000072, 0x01000000},
1371926deccbSFrançois Tigeot 	{0x00000074, 0x000000ff},
1372926deccbSFrançois Tigeot 	{0x00000075, 0x00143400},
1373926deccbSFrançois Tigeot 	{0x00000076, 0x08ec0800},
1374926deccbSFrançois Tigeot 	{0x00000077, 0x040000cc},
1375926deccbSFrançois Tigeot 	{0x00000079, 0x00000000},
1376926deccbSFrançois Tigeot 	{0x0000007a, 0x21000409},
1377926deccbSFrançois Tigeot 	{0x0000007c, 0x00000000},
1378926deccbSFrançois Tigeot 	{0x0000007d, 0xe8000000},
1379926deccbSFrançois Tigeot 	{0x0000007e, 0x044408a8},
1380926deccbSFrançois Tigeot 	{0x0000007f, 0x00000003},
1381926deccbSFrançois Tigeot 	{0x00000080, 0x00000000},
1382926deccbSFrançois Tigeot 	{0x00000081, 0x01000000},
1383926deccbSFrançois Tigeot 	{0x00000082, 0x02000000},
1384926deccbSFrançois Tigeot 	{0x00000083, 0x00000000},
1385926deccbSFrançois Tigeot 	{0x00000084, 0xe3f3e4f4},
1386926deccbSFrançois Tigeot 	{0x00000085, 0x00052024},
1387926deccbSFrançois Tigeot 	{0x00000087, 0x00000000},
1388926deccbSFrançois Tigeot 	{0x00000088, 0x66036603},
1389926deccbSFrançois Tigeot 	{0x00000089, 0x01000000},
1390926deccbSFrançois Tigeot 	{0x0000008b, 0x1c0a0000},
1391926deccbSFrançois Tigeot 	{0x0000008c, 0xff010000},
1392926deccbSFrançois Tigeot 	{0x0000008e, 0xffffefff},
1393926deccbSFrançois Tigeot 	{0x0000008f, 0xfff3efff},
1394926deccbSFrançois Tigeot 	{0x00000090, 0xfff3efbf},
1395926deccbSFrançois Tigeot 	{0x00000094, 0x00101101},
1396926deccbSFrançois Tigeot 	{0x00000095, 0x00000fff},
1397926deccbSFrançois Tigeot 	{0x00000096, 0x00116fff},
1398926deccbSFrançois Tigeot 	{0x00000097, 0x60010000},
1399926deccbSFrançois Tigeot 	{0x00000098, 0x10010000},
1400926deccbSFrançois Tigeot 	{0x00000099, 0x00006000},
1401926deccbSFrançois Tigeot 	{0x0000009a, 0x00001000},
1402926deccbSFrançois Tigeot 	{0x0000009f, 0x00a77400}
1403926deccbSFrançois Tigeot };
1404926deccbSFrançois Tigeot 
1405926deccbSFrançois Tigeot static const u32 pitcairn_io_mc_regs[TAHITI_IO_MC_REGS_SIZE][2] = {
1406926deccbSFrançois Tigeot 	{0x0000006f, 0x03044000},
1407926deccbSFrançois Tigeot 	{0x00000070, 0x0480c018},
1408926deccbSFrançois Tigeot 	{0x00000071, 0x00000040},
1409926deccbSFrançois Tigeot 	{0x00000072, 0x01000000},
1410926deccbSFrançois Tigeot 	{0x00000074, 0x000000ff},
1411926deccbSFrançois Tigeot 	{0x00000075, 0x00143400},
1412926deccbSFrançois Tigeot 	{0x00000076, 0x08ec0800},
1413926deccbSFrançois Tigeot 	{0x00000077, 0x040000cc},
1414926deccbSFrançois Tigeot 	{0x00000079, 0x00000000},
1415926deccbSFrançois Tigeot 	{0x0000007a, 0x21000409},
1416926deccbSFrançois Tigeot 	{0x0000007c, 0x00000000},
1417926deccbSFrançois Tigeot 	{0x0000007d, 0xe8000000},
1418926deccbSFrançois Tigeot 	{0x0000007e, 0x044408a8},
1419926deccbSFrançois Tigeot 	{0x0000007f, 0x00000003},
1420926deccbSFrançois Tigeot 	{0x00000080, 0x00000000},
1421926deccbSFrançois Tigeot 	{0x00000081, 0x01000000},
1422926deccbSFrançois Tigeot 	{0x00000082, 0x02000000},
1423926deccbSFrançois Tigeot 	{0x00000083, 0x00000000},
1424926deccbSFrançois Tigeot 	{0x00000084, 0xe3f3e4f4},
1425926deccbSFrançois Tigeot 	{0x00000085, 0x00052024},
1426926deccbSFrançois Tigeot 	{0x00000087, 0x00000000},
1427926deccbSFrançois Tigeot 	{0x00000088, 0x66036603},
1428926deccbSFrançois Tigeot 	{0x00000089, 0x01000000},
1429926deccbSFrançois Tigeot 	{0x0000008b, 0x1c0a0000},
1430926deccbSFrançois Tigeot 	{0x0000008c, 0xff010000},
1431926deccbSFrançois Tigeot 	{0x0000008e, 0xffffefff},
1432926deccbSFrançois Tigeot 	{0x0000008f, 0xfff3efff},
1433926deccbSFrançois Tigeot 	{0x00000090, 0xfff3efbf},
1434926deccbSFrançois Tigeot 	{0x00000094, 0x00101101},
1435926deccbSFrançois Tigeot 	{0x00000095, 0x00000fff},
1436926deccbSFrançois Tigeot 	{0x00000096, 0x00116fff},
1437926deccbSFrançois Tigeot 	{0x00000097, 0x60010000},
1438926deccbSFrançois Tigeot 	{0x00000098, 0x10010000},
1439926deccbSFrançois Tigeot 	{0x00000099, 0x00006000},
1440926deccbSFrançois Tigeot 	{0x0000009a, 0x00001000},
1441926deccbSFrançois Tigeot 	{0x0000009f, 0x00a47400}
1442926deccbSFrançois Tigeot };
1443926deccbSFrançois Tigeot 
1444926deccbSFrançois Tigeot static const u32 verde_io_mc_regs[TAHITI_IO_MC_REGS_SIZE][2] = {
1445926deccbSFrançois Tigeot 	{0x0000006f, 0x03044000},
1446926deccbSFrançois Tigeot 	{0x00000070, 0x0480c018},
1447926deccbSFrançois Tigeot 	{0x00000071, 0x00000040},
1448926deccbSFrançois Tigeot 	{0x00000072, 0x01000000},
1449926deccbSFrançois Tigeot 	{0x00000074, 0x000000ff},
1450926deccbSFrançois Tigeot 	{0x00000075, 0x00143400},
1451926deccbSFrançois Tigeot 	{0x00000076, 0x08ec0800},
1452926deccbSFrançois Tigeot 	{0x00000077, 0x040000cc},
1453926deccbSFrançois Tigeot 	{0x00000079, 0x00000000},
1454926deccbSFrançois Tigeot 	{0x0000007a, 0x21000409},
1455926deccbSFrançois Tigeot 	{0x0000007c, 0x00000000},
1456926deccbSFrançois Tigeot 	{0x0000007d, 0xe8000000},
1457926deccbSFrançois Tigeot 	{0x0000007e, 0x044408a8},
1458926deccbSFrançois Tigeot 	{0x0000007f, 0x00000003},
1459926deccbSFrançois Tigeot 	{0x00000080, 0x00000000},
1460926deccbSFrançois Tigeot 	{0x00000081, 0x01000000},
1461926deccbSFrançois Tigeot 	{0x00000082, 0x02000000},
1462926deccbSFrançois Tigeot 	{0x00000083, 0x00000000},
1463926deccbSFrançois Tigeot 	{0x00000084, 0xe3f3e4f4},
1464926deccbSFrançois Tigeot 	{0x00000085, 0x00052024},
1465926deccbSFrançois Tigeot 	{0x00000087, 0x00000000},
1466926deccbSFrançois Tigeot 	{0x00000088, 0x66036603},
1467926deccbSFrançois Tigeot 	{0x00000089, 0x01000000},
1468926deccbSFrançois Tigeot 	{0x0000008b, 0x1c0a0000},
1469926deccbSFrançois Tigeot 	{0x0000008c, 0xff010000},
1470926deccbSFrançois Tigeot 	{0x0000008e, 0xffffefff},
1471926deccbSFrançois Tigeot 	{0x0000008f, 0xfff3efff},
1472926deccbSFrançois Tigeot 	{0x00000090, 0xfff3efbf},
1473926deccbSFrançois Tigeot 	{0x00000094, 0x00101101},
1474926deccbSFrançois Tigeot 	{0x00000095, 0x00000fff},
1475926deccbSFrançois Tigeot 	{0x00000096, 0x00116fff},
1476926deccbSFrançois Tigeot 	{0x00000097, 0x60010000},
1477926deccbSFrançois Tigeot 	{0x00000098, 0x10010000},
1478926deccbSFrançois Tigeot 	{0x00000099, 0x00006000},
1479926deccbSFrançois Tigeot 	{0x0000009a, 0x00001000},
1480926deccbSFrançois Tigeot 	{0x0000009f, 0x00a37400}
1481926deccbSFrançois Tigeot };
1482926deccbSFrançois Tigeot 
1483b403bed8SMichael Neumann static const u32 oland_io_mc_regs[TAHITI_IO_MC_REGS_SIZE][2] = {
1484b403bed8SMichael Neumann 	{0x0000006f, 0x03044000},
1485b403bed8SMichael Neumann 	{0x00000070, 0x0480c018},
1486b403bed8SMichael Neumann 	{0x00000071, 0x00000040},
1487b403bed8SMichael Neumann 	{0x00000072, 0x01000000},
1488b403bed8SMichael Neumann 	{0x00000074, 0x000000ff},
1489b403bed8SMichael Neumann 	{0x00000075, 0x00143400},
1490b403bed8SMichael Neumann 	{0x00000076, 0x08ec0800},
1491b403bed8SMichael Neumann 	{0x00000077, 0x040000cc},
1492b403bed8SMichael Neumann 	{0x00000079, 0x00000000},
1493b403bed8SMichael Neumann 	{0x0000007a, 0x21000409},
1494b403bed8SMichael Neumann 	{0x0000007c, 0x00000000},
1495b403bed8SMichael Neumann 	{0x0000007d, 0xe8000000},
1496b403bed8SMichael Neumann 	{0x0000007e, 0x044408a8},
1497b403bed8SMichael Neumann 	{0x0000007f, 0x00000003},
1498b403bed8SMichael Neumann 	{0x00000080, 0x00000000},
1499b403bed8SMichael Neumann 	{0x00000081, 0x01000000},
1500b403bed8SMichael Neumann 	{0x00000082, 0x02000000},
1501b403bed8SMichael Neumann 	{0x00000083, 0x00000000},
1502b403bed8SMichael Neumann 	{0x00000084, 0xe3f3e4f4},
1503b403bed8SMichael Neumann 	{0x00000085, 0x00052024},
1504b403bed8SMichael Neumann 	{0x00000087, 0x00000000},
1505b403bed8SMichael Neumann 	{0x00000088, 0x66036603},
1506b403bed8SMichael Neumann 	{0x00000089, 0x01000000},
1507b403bed8SMichael Neumann 	{0x0000008b, 0x1c0a0000},
1508b403bed8SMichael Neumann 	{0x0000008c, 0xff010000},
1509b403bed8SMichael Neumann 	{0x0000008e, 0xffffefff},
1510b403bed8SMichael Neumann 	{0x0000008f, 0xfff3efff},
1511b403bed8SMichael Neumann 	{0x00000090, 0xfff3efbf},
1512b403bed8SMichael Neumann 	{0x00000094, 0x00101101},
1513b403bed8SMichael Neumann 	{0x00000095, 0x00000fff},
1514b403bed8SMichael Neumann 	{0x00000096, 0x00116fff},
1515b403bed8SMichael Neumann 	{0x00000097, 0x60010000},
1516b403bed8SMichael Neumann 	{0x00000098, 0x10010000},
1517b403bed8SMichael Neumann 	{0x00000099, 0x00006000},
1518b403bed8SMichael Neumann 	{0x0000009a, 0x00001000},
1519b403bed8SMichael Neumann 	{0x0000009f, 0x00a17730}
1520b403bed8SMichael Neumann };
1521b403bed8SMichael Neumann 
1522f43cf1b1SMichael Neumann static const u32 hainan_io_mc_regs[TAHITI_IO_MC_REGS_SIZE][2] = {
1523f43cf1b1SMichael Neumann 	{0x0000006f, 0x03044000},
1524f43cf1b1SMichael Neumann 	{0x00000070, 0x0480c018},
1525f43cf1b1SMichael Neumann 	{0x00000071, 0x00000040},
1526f43cf1b1SMichael Neumann 	{0x00000072, 0x01000000},
1527f43cf1b1SMichael Neumann 	{0x00000074, 0x000000ff},
1528f43cf1b1SMichael Neumann 	{0x00000075, 0x00143400},
1529f43cf1b1SMichael Neumann 	{0x00000076, 0x08ec0800},
1530f43cf1b1SMichael Neumann 	{0x00000077, 0x040000cc},
1531f43cf1b1SMichael Neumann 	{0x00000079, 0x00000000},
1532f43cf1b1SMichael Neumann 	{0x0000007a, 0x21000409},
1533f43cf1b1SMichael Neumann 	{0x0000007c, 0x00000000},
1534f43cf1b1SMichael Neumann 	{0x0000007d, 0xe8000000},
1535f43cf1b1SMichael Neumann 	{0x0000007e, 0x044408a8},
1536f43cf1b1SMichael Neumann 	{0x0000007f, 0x00000003},
1537f43cf1b1SMichael Neumann 	{0x00000080, 0x00000000},
1538f43cf1b1SMichael Neumann 	{0x00000081, 0x01000000},
1539f43cf1b1SMichael Neumann 	{0x00000082, 0x02000000},
1540f43cf1b1SMichael Neumann 	{0x00000083, 0x00000000},
1541f43cf1b1SMichael Neumann 	{0x00000084, 0xe3f3e4f4},
1542f43cf1b1SMichael Neumann 	{0x00000085, 0x00052024},
1543f43cf1b1SMichael Neumann 	{0x00000087, 0x00000000},
1544f43cf1b1SMichael Neumann 	{0x00000088, 0x66036603},
1545f43cf1b1SMichael Neumann 	{0x00000089, 0x01000000},
1546f43cf1b1SMichael Neumann 	{0x0000008b, 0x1c0a0000},
1547f43cf1b1SMichael Neumann 	{0x0000008c, 0xff010000},
1548f43cf1b1SMichael Neumann 	{0x0000008e, 0xffffefff},
1549f43cf1b1SMichael Neumann 	{0x0000008f, 0xfff3efff},
1550f43cf1b1SMichael Neumann 	{0x00000090, 0xfff3efbf},
1551f43cf1b1SMichael Neumann 	{0x00000094, 0x00101101},
1552f43cf1b1SMichael Neumann 	{0x00000095, 0x00000fff},
1553f43cf1b1SMichael Neumann 	{0x00000096, 0x00116fff},
1554f43cf1b1SMichael Neumann 	{0x00000097, 0x60010000},
1555f43cf1b1SMichael Neumann 	{0x00000098, 0x10010000},
1556f43cf1b1SMichael Neumann 	{0x00000099, 0x00006000},
1557f43cf1b1SMichael Neumann 	{0x0000009a, 0x00001000},
1558f43cf1b1SMichael Neumann 	{0x0000009f, 0x00a07730}
1559f43cf1b1SMichael Neumann };
1560f43cf1b1SMichael Neumann 
1561926deccbSFrançois Tigeot /* ucode loading */
si_mc_load_microcode(struct radeon_device * rdev)1562c6f73aabSFrançois Tigeot int si_mc_load_microcode(struct radeon_device *rdev)
1563926deccbSFrançois Tigeot {
1564cb754608SImre Vadász 	const __be32 *fw_data = NULL;
1565cb754608SImre Vadász 	const __le32 *new_fw_data = NULL;
15661dedbd3bSFrançois Tigeot 	u32 running;
1567cb754608SImre Vadász 	u32 *io_mc_regs = NULL;
1568cb754608SImre Vadász 	const __le32 *new_io_mc_regs = NULL;
1569c6f73aabSFrançois Tigeot 	int i, regs_size, ucode_size;
1570926deccbSFrançois Tigeot 
1571926deccbSFrançois Tigeot 	if (!rdev->mc_fw)
1572926deccbSFrançois Tigeot 		return -EINVAL;
1573926deccbSFrançois Tigeot 
1574cb754608SImre Vadász 	if (rdev->new_fw) {
1575cb754608SImre Vadász 		const struct mc_firmware_header_v1_0 *hdr =
1576cb754608SImre Vadász 			(const struct mc_firmware_header_v1_0 *)rdev->mc_fw->data;
1577cb754608SImre Vadász 
1578cb754608SImre Vadász 		radeon_ucode_print_mc_hdr(&hdr->header);
1579cb754608SImre Vadász 		regs_size = le32_to_cpu(hdr->io_debug_size_bytes) / (4 * 2);
1580cb754608SImre Vadász 		new_io_mc_regs = (const __le32 *)
1581c59a5c48SFrançois Tigeot 			(rdev->mc_fw->data + le32_to_cpu(hdr->io_debug_array_offset_bytes));
1582cb754608SImre Vadász 		ucode_size = le32_to_cpu(hdr->header.ucode_size_bytes) / 4;
1583cb754608SImre Vadász 		new_fw_data = (const __le32 *)
1584c59a5c48SFrançois Tigeot 			(rdev->mc_fw->data + le32_to_cpu(hdr->header.ucode_array_offset_bytes));
1585cb754608SImre Vadász 	} else {
1586c6f73aabSFrançois Tigeot 		ucode_size = rdev->mc_fw->datasize / 4;
1587c6f73aabSFrançois Tigeot 
1588926deccbSFrançois Tigeot 		switch (rdev->family) {
1589926deccbSFrançois Tigeot 		case CHIP_TAHITI:
1590926deccbSFrançois Tigeot 			io_mc_regs = (u32 *)&tahiti_io_mc_regs;
1591926deccbSFrançois Tigeot 			regs_size = TAHITI_IO_MC_REGS_SIZE;
1592926deccbSFrançois Tigeot 			break;
1593926deccbSFrançois Tigeot 		case CHIP_PITCAIRN:
1594926deccbSFrançois Tigeot 			io_mc_regs = (u32 *)&pitcairn_io_mc_regs;
1595926deccbSFrançois Tigeot 			regs_size = TAHITI_IO_MC_REGS_SIZE;
1596926deccbSFrançois Tigeot 			break;
1597926deccbSFrançois Tigeot 		case CHIP_VERDE:
1598926deccbSFrançois Tigeot 		default:
1599926deccbSFrançois Tigeot 			io_mc_regs = (u32 *)&verde_io_mc_regs;
1600926deccbSFrançois Tigeot 			regs_size = TAHITI_IO_MC_REGS_SIZE;
1601926deccbSFrançois Tigeot 			break;
1602b403bed8SMichael Neumann 		case CHIP_OLAND:
1603b403bed8SMichael Neumann 			io_mc_regs = (u32 *)&oland_io_mc_regs;
1604b403bed8SMichael Neumann 			regs_size = TAHITI_IO_MC_REGS_SIZE;
1605b403bed8SMichael Neumann 			break;
1606f43cf1b1SMichael Neumann 		case CHIP_HAINAN:
1607f43cf1b1SMichael Neumann 			io_mc_regs = (u32 *)&hainan_io_mc_regs;
1608f43cf1b1SMichael Neumann 			regs_size = TAHITI_IO_MC_REGS_SIZE;
1609f43cf1b1SMichael Neumann 			break;
1610926deccbSFrançois Tigeot 		}
1611cb754608SImre Vadász 		fw_data = (const __be32 *)rdev->mc_fw->data;
1612cb754608SImre Vadász 	}
1613926deccbSFrançois Tigeot 
1614926deccbSFrançois Tigeot 	running = RREG32(MC_SEQ_SUP_CNTL) & RUN_MASK;
1615926deccbSFrançois Tigeot 
1616926deccbSFrançois Tigeot 	if (running == 0) {
1617926deccbSFrançois Tigeot 		/* reset the engine and set to writable */
1618926deccbSFrançois Tigeot 		WREG32(MC_SEQ_SUP_CNTL, 0x00000008);
1619926deccbSFrançois Tigeot 		WREG32(MC_SEQ_SUP_CNTL, 0x00000010);
1620926deccbSFrançois Tigeot 
1621926deccbSFrançois Tigeot 		/* load mc io regs */
1622926deccbSFrançois Tigeot 		for (i = 0; i < regs_size; i++) {
1623cb754608SImre Vadász 			if (rdev->new_fw) {
1624cb754608SImre Vadász 				WREG32(MC_SEQ_IO_DEBUG_INDEX, le32_to_cpup(new_io_mc_regs++));
1625cb754608SImre Vadász 				WREG32(MC_SEQ_IO_DEBUG_DATA, le32_to_cpup(new_io_mc_regs++));
1626cb754608SImre Vadász 			} else {
1627926deccbSFrançois Tigeot 				WREG32(MC_SEQ_IO_DEBUG_INDEX, io_mc_regs[(i << 1)]);
1628926deccbSFrançois Tigeot 				WREG32(MC_SEQ_IO_DEBUG_DATA, io_mc_regs[(i << 1) + 1]);
1629926deccbSFrançois Tigeot 			}
1630cb754608SImre Vadász 		}
1631926deccbSFrançois Tigeot 		/* load the MC ucode */
1632cb754608SImre Vadász 		for (i = 0; i < ucode_size; i++) {
1633cb754608SImre Vadász 			if (rdev->new_fw)
1634cb754608SImre Vadász 				WREG32(MC_SEQ_SUP_PGM, le32_to_cpup(new_fw_data++));
1635cb754608SImre Vadász 			else
1636926deccbSFrançois Tigeot 				WREG32(MC_SEQ_SUP_PGM, be32_to_cpup(fw_data++));
1637cb754608SImre Vadász 		}
1638926deccbSFrançois Tigeot 
1639926deccbSFrançois Tigeot 		/* put the engine back into the active state */
1640926deccbSFrançois Tigeot 		WREG32(MC_SEQ_SUP_CNTL, 0x00000008);
1641926deccbSFrançois Tigeot 		WREG32(MC_SEQ_SUP_CNTL, 0x00000004);
1642926deccbSFrançois Tigeot 		WREG32(MC_SEQ_SUP_CNTL, 0x00000001);
1643926deccbSFrançois Tigeot 
1644926deccbSFrançois Tigeot 		/* wait for training to complete */
1645926deccbSFrançois Tigeot 		for (i = 0; i < rdev->usec_timeout; i++) {
1646926deccbSFrançois Tigeot 			if (RREG32(MC_SEQ_TRAIN_WAKEUP_CNTL) & TRAIN_DONE_D0)
1647926deccbSFrançois Tigeot 				break;
1648c4ef309bSzrj 			udelay(1);
1649926deccbSFrançois Tigeot 		}
1650926deccbSFrançois Tigeot 		for (i = 0; i < rdev->usec_timeout; i++) {
1651926deccbSFrançois Tigeot 			if (RREG32(MC_SEQ_TRAIN_WAKEUP_CNTL) & TRAIN_DONE_D1)
1652926deccbSFrançois Tigeot 				break;
1653c4ef309bSzrj 			udelay(1);
1654926deccbSFrançois Tigeot 		}
1655926deccbSFrançois Tigeot 	}
1656926deccbSFrançois Tigeot 
1657926deccbSFrançois Tigeot 	return 0;
1658926deccbSFrançois Tigeot }
1659926deccbSFrançois Tigeot 
si_init_microcode(struct radeon_device * rdev)1660926deccbSFrançois Tigeot static int si_init_microcode(struct radeon_device *rdev)
1661926deccbSFrançois Tigeot {
1662926deccbSFrançois Tigeot 	const char *chip_name;
1663cb754608SImre Vadász 	const char *new_chip_name;
1664926deccbSFrançois Tigeot 	size_t pfp_req_size, me_req_size, ce_req_size, rlc_req_size, mc_req_size;
1665c6f73aabSFrançois Tigeot 	size_t smc_req_size, mc2_req_size;
1666926deccbSFrançois Tigeot 	char fw_name[30];
1667926deccbSFrançois Tigeot 	int err;
1668cb754608SImre Vadász 	int new_fw = 0;
16691dedbd3bSFrançois Tigeot 	bool new_smc = false;
16704be47400SFrançois Tigeot 	bool si58_fw = false;
16714be47400SFrançois Tigeot 	bool banks2_fw = false;
1672926deccbSFrançois Tigeot 
1673926deccbSFrançois Tigeot 	DRM_DEBUG("\n");
1674926deccbSFrançois Tigeot 
1675926deccbSFrançois Tigeot 	switch (rdev->family) {
1676926deccbSFrançois Tigeot 	case CHIP_TAHITI:
1677926deccbSFrançois Tigeot 		chip_name = "TAHITI";
1678cb754608SImre Vadász 		new_chip_name = "tahiti";
1679926deccbSFrançois Tigeot 		pfp_req_size = SI_PFP_UCODE_SIZE * 4;
1680926deccbSFrançois Tigeot 		me_req_size = SI_PM4_UCODE_SIZE * 4;
1681926deccbSFrançois Tigeot 		ce_req_size = SI_CE_UCODE_SIZE * 4;
1682926deccbSFrançois Tigeot 		rlc_req_size = SI_RLC_UCODE_SIZE * 4;
1683926deccbSFrançois Tigeot 		mc_req_size = SI_MC_UCODE_SIZE * 4;
1684c6f73aabSFrançois Tigeot 		mc2_req_size = TAHITI_MC_UCODE_SIZE * 4;
168557e252bfSMichael Neumann 		smc_req_size = ALIGN(TAHITI_SMC_UCODE_SIZE, 4);
1686926deccbSFrançois Tigeot 		break;
1687926deccbSFrançois Tigeot 	case CHIP_PITCAIRN:
1688926deccbSFrançois Tigeot 		chip_name = "PITCAIRN";
16894be47400SFrançois Tigeot 		if ((rdev->pdev->revision == 0x81) &&
16904be47400SFrançois Tigeot 		    ((rdev->pdev->device == 0x6810) ||
16914be47400SFrançois Tigeot 		     (rdev->pdev->device == 0x6811)))
16921dedbd3bSFrançois Tigeot 			new_smc = true;
1693cb754608SImre Vadász 		new_chip_name = "pitcairn";
1694926deccbSFrançois Tigeot 		pfp_req_size = SI_PFP_UCODE_SIZE * 4;
1695926deccbSFrançois Tigeot 		me_req_size = SI_PM4_UCODE_SIZE * 4;
1696926deccbSFrançois Tigeot 		ce_req_size = SI_CE_UCODE_SIZE * 4;
1697926deccbSFrançois Tigeot 		rlc_req_size = SI_RLC_UCODE_SIZE * 4;
1698926deccbSFrançois Tigeot 		mc_req_size = SI_MC_UCODE_SIZE * 4;
1699c6f73aabSFrançois Tigeot 		mc2_req_size = PITCAIRN_MC_UCODE_SIZE * 4;
170057e252bfSMichael Neumann 		smc_req_size = ALIGN(PITCAIRN_SMC_UCODE_SIZE, 4);
1701926deccbSFrançois Tigeot 		break;
1702926deccbSFrançois Tigeot 	case CHIP_VERDE:
1703926deccbSFrançois Tigeot 		chip_name = "VERDE";
17044be47400SFrançois Tigeot 		if (((rdev->pdev->device == 0x6820) &&
17054be47400SFrançois Tigeot 		     ((rdev->pdev->revision == 0x81) ||
17064be47400SFrançois Tigeot 		      (rdev->pdev->revision == 0x83))) ||
17074be47400SFrançois Tigeot 		    ((rdev->pdev->device == 0x6821) &&
17084be47400SFrançois Tigeot 		     ((rdev->pdev->revision == 0x83) ||
17094be47400SFrançois Tigeot 		      (rdev->pdev->revision == 0x87))) ||
17104be47400SFrançois Tigeot 		    ((rdev->pdev->revision == 0x87) &&
17114be47400SFrançois Tigeot 		     ((rdev->pdev->device == 0x6823) ||
17124be47400SFrançois Tigeot 		      (rdev->pdev->device == 0x682b))))
17131dedbd3bSFrançois Tigeot 			new_smc = true;
1714cb754608SImre Vadász 		new_chip_name = "verde";
1715926deccbSFrançois Tigeot 		pfp_req_size = SI_PFP_UCODE_SIZE * 4;
1716926deccbSFrançois Tigeot 		me_req_size = SI_PM4_UCODE_SIZE * 4;
1717926deccbSFrançois Tigeot 		ce_req_size = SI_CE_UCODE_SIZE * 4;
1718926deccbSFrançois Tigeot 		rlc_req_size = SI_RLC_UCODE_SIZE * 4;
1719926deccbSFrançois Tigeot 		mc_req_size = SI_MC_UCODE_SIZE * 4;
1720c6f73aabSFrançois Tigeot 		mc2_req_size = VERDE_MC_UCODE_SIZE * 4;
172157e252bfSMichael Neumann 		smc_req_size = ALIGN(VERDE_SMC_UCODE_SIZE, 4);
1722926deccbSFrançois Tigeot 		break;
1723b403bed8SMichael Neumann 	case CHIP_OLAND:
1724b403bed8SMichael Neumann 		chip_name = "OLAND";
17254be47400SFrançois Tigeot 		if (((rdev->pdev->revision == 0x81) &&
17264be47400SFrançois Tigeot 		     ((rdev->pdev->device == 0x6600) ||
17271dedbd3bSFrançois Tigeot 		      (rdev->pdev->device == 0x6604) ||
17284be47400SFrançois Tigeot 		      (rdev->pdev->device == 0x6605) ||
17294be47400SFrançois Tigeot 		      (rdev->pdev->device == 0x6610))) ||
17304be47400SFrançois Tigeot 		    ((rdev->pdev->revision == 0x83) &&
17314be47400SFrançois Tigeot 		     (rdev->pdev->device == 0x6610)))
17321dedbd3bSFrançois Tigeot 			new_smc = true;
1733cb754608SImre Vadász 		new_chip_name = "oland";
1734b403bed8SMichael Neumann 		pfp_req_size = SI_PFP_UCODE_SIZE * 4;
1735b403bed8SMichael Neumann 		me_req_size = SI_PM4_UCODE_SIZE * 4;
1736b403bed8SMichael Neumann 		ce_req_size = SI_CE_UCODE_SIZE * 4;
1737b403bed8SMichael Neumann 		rlc_req_size = SI_RLC_UCODE_SIZE * 4;
1738c6f73aabSFrançois Tigeot 		mc_req_size = mc2_req_size = OLAND_MC_UCODE_SIZE * 4;
173957e252bfSMichael Neumann 		smc_req_size = ALIGN(OLAND_SMC_UCODE_SIZE, 4);
1740b403bed8SMichael Neumann 		break;
1741f43cf1b1SMichael Neumann 	case CHIP_HAINAN:
1742f43cf1b1SMichael Neumann 		chip_name = "HAINAN";
17434be47400SFrançois Tigeot 		if (((rdev->pdev->revision == 0x81) &&
17444be47400SFrançois Tigeot 		     (rdev->pdev->device == 0x6660)) ||
17454be47400SFrançois Tigeot 		    ((rdev->pdev->revision == 0x83) &&
17464be47400SFrançois Tigeot 		     ((rdev->pdev->device == 0x6660) ||
17474be47400SFrançois Tigeot 		      (rdev->pdev->device == 0x6663) ||
17481dedbd3bSFrançois Tigeot 		      (rdev->pdev->device == 0x6665) ||
17494be47400SFrançois Tigeot 		      (rdev->pdev->device == 0x6667))))
17501dedbd3bSFrançois Tigeot 			new_smc = true;
17514be47400SFrançois Tigeot 		else if ((rdev->pdev->revision == 0xc3) &&
17524be47400SFrançois Tigeot 			 (rdev->pdev->device == 0x6665))
17534be47400SFrançois Tigeot 			banks2_fw = true;
1754cb754608SImre Vadász 		new_chip_name = "hainan";
1755f43cf1b1SMichael Neumann 		pfp_req_size = SI_PFP_UCODE_SIZE * 4;
1756f43cf1b1SMichael Neumann 		me_req_size = SI_PM4_UCODE_SIZE * 4;
1757f43cf1b1SMichael Neumann 		ce_req_size = SI_CE_UCODE_SIZE * 4;
1758f43cf1b1SMichael Neumann 		rlc_req_size = SI_RLC_UCODE_SIZE * 4;
1759c6f73aabSFrançois Tigeot 		mc_req_size = mc2_req_size = OLAND_MC_UCODE_SIZE * 4;
176057e252bfSMichael Neumann 		smc_req_size = ALIGN(HAINAN_SMC_UCODE_SIZE, 4);
1761f43cf1b1SMichael Neumann 		break;
1762c4ef309bSzrj 	default: BUG();
1763926deccbSFrançois Tigeot 	}
1764926deccbSFrançois Tigeot 
17654be47400SFrançois Tigeot 	/* this memory configuration requires special firmware */
17664be47400SFrançois Tigeot 	if (((RREG32(MC_SEQ_MISC0) & 0xff000000) >> 24) == 0x58)
17674be47400SFrançois Tigeot 		si58_fw = true;
17684be47400SFrançois Tigeot 
1769cb754608SImre Vadász 	DRM_INFO("Loading %s Microcode\n", new_chip_name);
1770926deccbSFrançois Tigeot 
1771cb754608SImre Vadász 	ksnprintf(fw_name, sizeof(fw_name), "radeonkmsfw_%s_pfp", new_chip_name);
177271187b16SFrançois Tigeot 	err = request_firmware(&rdev->pfp_fw, fw_name, rdev->dev);
1773cb754608SImre Vadász 	if (err) {
1774926deccbSFrançois Tigeot 		ksnprintf(fw_name, sizeof(fw_name), "radeonkmsfw_%s_pfp", chip_name);
177571187b16SFrançois Tigeot 		err = request_firmware(&rdev->pfp_fw, fw_name, rdev->dev);
1776fcd4983fSzrj 		if (err)
1777926deccbSFrançois Tigeot 			goto out;
1778926deccbSFrançois Tigeot 		if (rdev->pfp_fw->datasize != pfp_req_size) {
1779*3f2dd94aSFrançois Tigeot 			pr_err("si_cp: Bogus length %zu in firmware \"%s\"\n",
1780926deccbSFrançois Tigeot 			       rdev->pfp_fw->datasize, fw_name);
1781926deccbSFrançois Tigeot 			err = -EINVAL;
1782926deccbSFrançois Tigeot 			goto out;
1783926deccbSFrançois Tigeot 		}
1784cb754608SImre Vadász 	} else {
1785cb754608SImre Vadász 		err = radeon_ucode_validate(rdev->pfp_fw);
1786cb754608SImre Vadász 		if (err) {
1787a85cb24fSFrançois Tigeot 			pr_err("si_cp: validation failed for firmware \"%s\"\n",
1788cb754608SImre Vadász 			       fw_name);
1789cb754608SImre Vadász 			goto out;
1790cb754608SImre Vadász 		} else {
1791cb754608SImre Vadász 			new_fw++;
1792cb754608SImre Vadász 		}
1793cb754608SImre Vadász 	}
1794926deccbSFrançois Tigeot 
1795cb754608SImre Vadász 	ksnprintf(fw_name, sizeof(fw_name), "radeonkmsfw_%s_me", new_chip_name);
179671187b16SFrançois Tigeot 	err = request_firmware(&rdev->me_fw, fw_name, rdev->dev);
1797cb754608SImre Vadász 	if (err) {
1798926deccbSFrançois Tigeot 		ksnprintf(fw_name, sizeof(fw_name), "radeonkmsfw_%s_me", chip_name);
179971187b16SFrançois Tigeot 		err = request_firmware(&rdev->me_fw, fw_name, rdev->dev);
1800fcd4983fSzrj 		if (err)
1801926deccbSFrançois Tigeot 			goto out;
1802926deccbSFrançois Tigeot 		if (rdev->me_fw->datasize != me_req_size) {
1803*3f2dd94aSFrançois Tigeot 			pr_err("si_cp: Bogus length %zu in firmware \"%s\"\n",
1804926deccbSFrançois Tigeot 			       rdev->me_fw->datasize, fw_name);
1805926deccbSFrançois Tigeot 			err = -EINVAL;
1806926deccbSFrançois Tigeot 		}
1807cb754608SImre Vadász 	} else {
1808cb754608SImre Vadász 		err = radeon_ucode_validate(rdev->me_fw);
1809cb754608SImre Vadász 		if (err) {
1810*3f2dd94aSFrançois Tigeot 			pr_err("si_cp: validation failed for firmware \"%s\"\n",
1811cb754608SImre Vadász 			       fw_name);
1812cb754608SImre Vadász 			goto out;
1813cb754608SImre Vadász 		} else {
1814cb754608SImre Vadász 			new_fw++;
1815cb754608SImre Vadász 		}
1816cb754608SImre Vadász 	}
1817926deccbSFrançois Tigeot 
1818cb754608SImre Vadász 	ksnprintf(fw_name, sizeof(fw_name), "radeonkmsfw_%s_ce", new_chip_name);
181971187b16SFrançois Tigeot 	err = request_firmware(&rdev->ce_fw, fw_name, rdev->dev);
1820cb754608SImre Vadász 	if (err) {
1821926deccbSFrançois Tigeot 		ksnprintf(fw_name, sizeof(fw_name), "radeonkmsfw_%s_ce", chip_name);
182271187b16SFrançois Tigeot 		err = request_firmware(&rdev->ce_fw, fw_name, rdev->dev);
1823fcd4983fSzrj 		if (err)
1824926deccbSFrançois Tigeot 			goto out;
1825926deccbSFrançois Tigeot 		if (rdev->ce_fw->datasize != ce_req_size) {
1826*3f2dd94aSFrançois Tigeot 			pr_err("si_cp: Bogus length %zu in firmware \"%s\"\n",
1827926deccbSFrançois Tigeot 			       rdev->ce_fw->datasize, fw_name);
1828926deccbSFrançois Tigeot 			err = -EINVAL;
1829926deccbSFrançois Tigeot 		}
1830cb754608SImre Vadász 	} else {
1831cb754608SImre Vadász 		err = radeon_ucode_validate(rdev->ce_fw);
1832cb754608SImre Vadász 		if (err) {
1833*3f2dd94aSFrançois Tigeot 			pr_err("si_cp: validation failed for firmware \"%s\"\n",
1834cb754608SImre Vadász 			       fw_name);
1835cb754608SImre Vadász 			goto out;
1836cb754608SImre Vadász 		} else {
1837cb754608SImre Vadász 			new_fw++;
1838cb754608SImre Vadász 		}
1839cb754608SImre Vadász 	}
1840926deccbSFrançois Tigeot 
1841cb754608SImre Vadász 	ksnprintf(fw_name, sizeof(fw_name), "radeonkmsfw_%s_rlc", new_chip_name);
184271187b16SFrançois Tigeot 	err = request_firmware(&rdev->rlc_fw, fw_name, rdev->dev);
1843cb754608SImre Vadász 	if (err) {
1844cb754608SImre Vadász 		ksnprintf(fw_name, sizeof(fw_name), "radeonkmsfw_%s_rlc", chip_name);
184571187b16SFrançois Tigeot 		err = request_firmware(&rdev->rlc_fw, fw_name, rdev->dev);
1846fcd4983fSzrj 		if (err)
1847926deccbSFrançois Tigeot 			goto out;
1848926deccbSFrançois Tigeot 		if (rdev->rlc_fw->datasize != rlc_req_size) {
1849*3f2dd94aSFrançois Tigeot 			pr_err("si_rlc: Bogus length %zu in firmware \"%s\"\n",
1850926deccbSFrançois Tigeot 			       rdev->rlc_fw->datasize, fw_name);
1851926deccbSFrançois Tigeot 			err = -EINVAL;
1852926deccbSFrançois Tigeot 		}
1853cb754608SImre Vadász 	} else {
1854cb754608SImre Vadász 		err = radeon_ucode_validate(rdev->rlc_fw);
1855cb754608SImre Vadász 		if (err) {
1856*3f2dd94aSFrançois Tigeot 			pr_err("si_cp: validation failed for firmware \"%s\"\n",
1857cb754608SImre Vadász 			       fw_name);
1858cb754608SImre Vadász 			goto out;
1859cb754608SImre Vadász 		} else {
1860cb754608SImre Vadász 			new_fw++;
1861cb754608SImre Vadász 		}
1862cb754608SImre Vadász 	}
1863926deccbSFrançois Tigeot 
18644be47400SFrançois Tigeot 	if (si58_fw)
1865a85cb24fSFrançois Tigeot 		snprintf(fw_name, sizeof(fw_name), "radeonkmsfw_si58_mc");
18664be47400SFrançois Tigeot 	else
1867a85cb24fSFrançois Tigeot 		snprintf(fw_name, sizeof(fw_name), "radeonkmsfw_%s_mc", new_chip_name);
186871187b16SFrançois Tigeot 	err = request_firmware(&rdev->mc_fw, fw_name, rdev->dev);
1869cb754608SImre Vadász 	if (err) {
1870c6f73aabSFrançois Tigeot 		ksnprintf(fw_name, sizeof(fw_name), "radeonkmsfw_%s_mc2", chip_name);
187171187b16SFrançois Tigeot 		err = request_firmware(&rdev->mc_fw, fw_name, rdev->dev);
1872c6f73aabSFrançois Tigeot 		if (err) {
1873926deccbSFrançois Tigeot 			ksnprintf(fw_name, sizeof(fw_name), "radeonkmsfw_%s_mc", chip_name);
187471187b16SFrançois Tigeot 			err = request_firmware(&rdev->mc_fw, fw_name, rdev->dev);
1875fcd4983fSzrj 			if (err)
1876926deccbSFrançois Tigeot 				goto out;
1877c6f73aabSFrançois Tigeot 		}
1878c6f73aabSFrançois Tigeot 		if ((rdev->mc_fw->datasize != mc_req_size) &&
1879c6f73aabSFrançois Tigeot 		    (rdev->mc_fw->datasize != mc2_req_size)) {
1880*3f2dd94aSFrançois Tigeot 			pr_err("si_mc: Bogus length %zu in firmware \"%s\"\n",
1881926deccbSFrançois Tigeot 			       rdev->mc_fw->datasize, fw_name);
1882926deccbSFrançois Tigeot 			err = -EINVAL;
1883926deccbSFrançois Tigeot 		}
1884c6f73aabSFrançois Tigeot 		DRM_INFO("%s: %zu bytes\n", fw_name, rdev->mc_fw->datasize);
1885cb754608SImre Vadász 	} else {
1886cb754608SImre Vadász 		err = radeon_ucode_validate(rdev->mc_fw);
1887cb754608SImre Vadász 		if (err) {
1888a85cb24fSFrançois Tigeot 			pr_err("si_cp: validation failed for firmware \"%s\"\n",
1889cb754608SImre Vadász 			       fw_name);
1890cb754608SImre Vadász 			goto out;
1891cb754608SImre Vadász 		} else {
1892cb754608SImre Vadász 			new_fw++;
1893cb754608SImre Vadász 		}
1894cb754608SImre Vadász 	}
1895926deccbSFrançois Tigeot 
18964be47400SFrançois Tigeot 	if (banks2_fw)
18974be47400SFrançois Tigeot 		snprintf(fw_name, sizeof(fw_name), "radeonkmsfw_banks_k_2_smc");
18984be47400SFrançois Tigeot 	else if (new_smc)
18991dedbd3bSFrançois Tigeot 		ksnprintf(fw_name, sizeof(fw_name), "radeonkmsfw_%s_k_smc", new_chip_name);
19001dedbd3bSFrançois Tigeot 	else
1901cb754608SImre Vadász 		ksnprintf(fw_name, sizeof(fw_name), "radeonkmsfw_%s_smc", new_chip_name);
190271187b16SFrançois Tigeot 	err = request_firmware(&rdev->smc_fw, fw_name, rdev->dev);
1903cb754608SImre Vadász 	if (err) {
190457e252bfSMichael Neumann 		ksnprintf(fw_name, sizeof(fw_name), "radeonkmsfw_%s_smc", chip_name);
190571187b16SFrançois Tigeot 		err = request_firmware(&rdev->smc_fw, fw_name, rdev->dev);
190657e252bfSMichael Neumann 		if (err) {
1907*3f2dd94aSFrançois Tigeot 			pr_err("smc: error loading firmware \"%s\"\n", fw_name);
190857e252bfSMichael Neumann 			release_firmware(rdev->smc_fw);
190957e252bfSMichael Neumann 			rdev->smc_fw = NULL;
19104cd92098Szrj 			err = 0;
191157e252bfSMichael Neumann 		} else if (rdev->smc_fw->datasize != smc_req_size) {
1912*3f2dd94aSFrançois Tigeot 			pr_err("si_smc: Bogus length %zu in firmware \"%s\"\n",
191357e252bfSMichael Neumann 			       rdev->smc_fw->datasize, fw_name);
191457e252bfSMichael Neumann 			err = -EINVAL;
191557e252bfSMichael Neumann 		}
1916cb754608SImre Vadász 	} else {
1917cb754608SImre Vadász 		err = radeon_ucode_validate(rdev->smc_fw);
1918cb754608SImre Vadász 		if (err) {
1919*3f2dd94aSFrançois Tigeot 			pr_err("si_cp: validation failed for firmware \"%s\"\n",
1920cb754608SImre Vadász 			       fw_name);
1921cb754608SImre Vadász 			goto out;
1922cb754608SImre Vadász 		} else {
1923cb754608SImre Vadász 			new_fw++;
1924cb754608SImre Vadász 		}
1925cb754608SImre Vadász 	}
192657e252bfSMichael Neumann 
1927cb754608SImre Vadász 	if (new_fw == 0) {
1928cb754608SImre Vadász 		rdev->new_fw = false;
1929cb754608SImre Vadász 	} else if (new_fw < 6) {
1930a85cb24fSFrançois Tigeot 		pr_err("si_fw: mixing new and old firmware!\n");
1931cb754608SImre Vadász 		err = -EINVAL;
1932cb754608SImre Vadász 	} else {
1933cb754608SImre Vadász 		rdev->new_fw = true;
1934cb754608SImre Vadász 	}
1935926deccbSFrançois Tigeot out:
1936926deccbSFrançois Tigeot 	if (err) {
1937926deccbSFrançois Tigeot 		if (err != -EINVAL)
1938a85cb24fSFrançois Tigeot 			pr_err("si_cp: Failed to load firmware \"%s\"\n",
1939926deccbSFrançois Tigeot 			       fw_name);
1940fcd4983fSzrj 		release_firmware(rdev->pfp_fw);
1941926deccbSFrançois Tigeot 		rdev->pfp_fw = NULL;
1942fcd4983fSzrj 		release_firmware(rdev->me_fw);
1943926deccbSFrançois Tigeot 		rdev->me_fw = NULL;
1944fcd4983fSzrj 		release_firmware(rdev->ce_fw);
1945926deccbSFrançois Tigeot 		rdev->ce_fw = NULL;
1946fcd4983fSzrj 		release_firmware(rdev->rlc_fw);
1947926deccbSFrançois Tigeot 		rdev->rlc_fw = NULL;
1948fcd4983fSzrj 		release_firmware(rdev->mc_fw);
1949926deccbSFrançois Tigeot 		rdev->mc_fw = NULL;
1950fcd4983fSzrj 		release_firmware(rdev->smc_fw);
195157e252bfSMichael Neumann 		rdev->smc_fw = NULL;
195257e252bfSMichael Neumann 	}
1953926deccbSFrançois Tigeot 	return err;
1954926deccbSFrançois Tigeot }
1955926deccbSFrançois Tigeot 
1956926deccbSFrançois Tigeot /* watermark setup */
dce6_line_buffer_adjust(struct radeon_device * rdev,struct radeon_crtc * radeon_crtc,struct drm_display_mode * mode,struct drm_display_mode * other_mode)1957926deccbSFrançois Tigeot static u32 dce6_line_buffer_adjust(struct radeon_device *rdev,
1958926deccbSFrançois Tigeot 				   struct radeon_crtc *radeon_crtc,
1959926deccbSFrançois Tigeot 				   struct drm_display_mode *mode,
1960926deccbSFrançois Tigeot 				   struct drm_display_mode *other_mode)
1961926deccbSFrançois Tigeot {
19624cd92098Szrj 	u32 tmp, buffer_alloc, i;
19634cd92098Szrj 	u32 pipe_offset = radeon_crtc->crtc_id * 0x20;
1964926deccbSFrançois Tigeot 	/*
1965926deccbSFrançois Tigeot 	 * Line Buffer Setup
1966926deccbSFrançois Tigeot 	 * There are 3 line buffers, each one shared by 2 display controllers.
1967926deccbSFrançois Tigeot 	 * DC_LB_MEMORY_SPLIT controls how that line buffer is shared between
1968926deccbSFrançois Tigeot 	 * the display controllers.  The paritioning is done via one of four
1969926deccbSFrançois Tigeot 	 * preset allocations specified in bits 21:20:
1970926deccbSFrançois Tigeot 	 *  0 - half lb
1971926deccbSFrançois Tigeot 	 *  2 - whole lb, other crtc must be disabled
1972926deccbSFrançois Tigeot 	 */
1973926deccbSFrançois Tigeot 	/* this can get tricky if we have two large displays on a paired group
1974926deccbSFrançois Tigeot 	 * of crtcs.  Ideally for multiple large displays we'd assign them to
1975926deccbSFrançois Tigeot 	 * non-linked crtcs for maximum line buffer allocation.
1976926deccbSFrançois Tigeot 	 */
1977926deccbSFrançois Tigeot 	if (radeon_crtc->base.enabled && mode) {
19784cd92098Szrj 		if (other_mode) {
1979926deccbSFrançois Tigeot 			tmp = 0; /* 1/2 */
19804cd92098Szrj 			buffer_alloc = 1;
19814cd92098Szrj 		} else {
1982926deccbSFrançois Tigeot 			tmp = 2; /* whole */
19834cd92098Szrj 			buffer_alloc = 2;
19844cd92098Szrj 		}
19854cd92098Szrj 	} else {
1986926deccbSFrançois Tigeot 		tmp = 0;
19874cd92098Szrj 		buffer_alloc = 0;
19884cd92098Szrj 	}
1989926deccbSFrançois Tigeot 
1990926deccbSFrançois Tigeot 	WREG32(DC_LB_MEMORY_SPLIT + radeon_crtc->crtc_offset,
1991926deccbSFrançois Tigeot 	       DC_LB_MEMORY_CONFIG(tmp));
1992926deccbSFrançois Tigeot 
19934cd92098Szrj 	WREG32(PIPE0_DMIF_BUFFER_CONTROL + pipe_offset,
19944cd92098Szrj 	       DMIF_BUFFERS_ALLOCATED(buffer_alloc));
19954cd92098Szrj 	for (i = 0; i < rdev->usec_timeout; i++) {
19964cd92098Szrj 		if (RREG32(PIPE0_DMIF_BUFFER_CONTROL + pipe_offset) &
19974cd92098Szrj 		    DMIF_BUFFERS_ALLOCATED_COMPLETED)
19984cd92098Szrj 			break;
19994cd92098Szrj 		udelay(1);
20004cd92098Szrj 	}
20014cd92098Szrj 
2002926deccbSFrançois Tigeot 	if (radeon_crtc->base.enabled && mode) {
2003926deccbSFrançois Tigeot 		switch (tmp) {
2004926deccbSFrançois Tigeot 		case 0:
2005926deccbSFrançois Tigeot 		default:
2006926deccbSFrançois Tigeot 			return 4096 * 2;
2007926deccbSFrançois Tigeot 		case 2:
2008926deccbSFrançois Tigeot 			return 8192 * 2;
2009926deccbSFrançois Tigeot 		}
2010926deccbSFrançois Tigeot 	}
2011926deccbSFrançois Tigeot 
2012926deccbSFrançois Tigeot 	/* controller not enabled, so no lb used */
2013926deccbSFrançois Tigeot 	return 0;
2014926deccbSFrançois Tigeot }
2015926deccbSFrançois Tigeot 
si_get_number_of_dram_channels(struct radeon_device * rdev)2016926deccbSFrançois Tigeot static u32 si_get_number_of_dram_channels(struct radeon_device *rdev)
2017926deccbSFrançois Tigeot {
2018926deccbSFrançois Tigeot 	u32 tmp = RREG32(MC_SHARED_CHMAP);
2019926deccbSFrançois Tigeot 
2020926deccbSFrançois Tigeot 	switch ((tmp & NOOFCHAN_MASK) >> NOOFCHAN_SHIFT) {
2021926deccbSFrançois Tigeot 	case 0:
2022926deccbSFrançois Tigeot 	default:
2023926deccbSFrançois Tigeot 		return 1;
2024926deccbSFrançois Tigeot 	case 1:
2025926deccbSFrançois Tigeot 		return 2;
2026926deccbSFrançois Tigeot 	case 2:
2027926deccbSFrançois Tigeot 		return 4;
2028926deccbSFrançois Tigeot 	case 3:
2029926deccbSFrançois Tigeot 		return 8;
2030926deccbSFrançois Tigeot 	case 4:
2031926deccbSFrançois Tigeot 		return 3;
2032926deccbSFrançois Tigeot 	case 5:
2033926deccbSFrançois Tigeot 		return 6;
2034926deccbSFrançois Tigeot 	case 6:
2035926deccbSFrançois Tigeot 		return 10;
2036926deccbSFrançois Tigeot 	case 7:
2037926deccbSFrançois Tigeot 		return 12;
2038926deccbSFrançois Tigeot 	case 8:
2039926deccbSFrançois Tigeot 		return 16;
2040926deccbSFrançois Tigeot 	}
2041926deccbSFrançois Tigeot }
2042926deccbSFrançois Tigeot 
2043926deccbSFrançois Tigeot struct dce6_wm_params {
2044926deccbSFrançois Tigeot 	u32 dram_channels; /* number of dram channels */
2045926deccbSFrançois Tigeot 	u32 yclk;          /* bandwidth per dram data pin in kHz */
2046926deccbSFrançois Tigeot 	u32 sclk;          /* engine clock in kHz */
2047926deccbSFrançois Tigeot 	u32 disp_clk;      /* display clock in kHz */
2048926deccbSFrançois Tigeot 	u32 src_width;     /* viewport width */
2049926deccbSFrançois Tigeot 	u32 active_time;   /* active display time in ns */
2050926deccbSFrançois Tigeot 	u32 blank_time;    /* blank time in ns */
2051926deccbSFrançois Tigeot 	bool interlaced;    /* mode is interlaced */
2052926deccbSFrançois Tigeot 	fixed20_12 vsc;    /* vertical scale ratio */
2053926deccbSFrançois Tigeot 	u32 num_heads;     /* number of active crtcs */
2054926deccbSFrançois Tigeot 	u32 bytes_per_pixel; /* bytes per pixel display + overlay */
2055926deccbSFrançois Tigeot 	u32 lb_size;       /* line buffer allocated to pipe */
2056926deccbSFrançois Tigeot 	u32 vtaps;         /* vertical scaler taps */
2057926deccbSFrançois Tigeot };
2058926deccbSFrançois Tigeot 
dce6_dram_bandwidth(struct dce6_wm_params * wm)2059926deccbSFrançois Tigeot static u32 dce6_dram_bandwidth(struct dce6_wm_params *wm)
2060926deccbSFrançois Tigeot {
2061926deccbSFrançois Tigeot 	/* Calculate raw DRAM Bandwidth */
2062926deccbSFrançois Tigeot 	fixed20_12 dram_efficiency; /* 0.7 */
2063926deccbSFrançois Tigeot 	fixed20_12 yclk, dram_channels, bandwidth;
2064926deccbSFrançois Tigeot 	fixed20_12 a;
2065926deccbSFrançois Tigeot 
2066926deccbSFrançois Tigeot 	a.full = dfixed_const(1000);
2067926deccbSFrançois Tigeot 	yclk.full = dfixed_const(wm->yclk);
2068926deccbSFrançois Tigeot 	yclk.full = dfixed_div(yclk, a);
2069926deccbSFrançois Tigeot 	dram_channels.full = dfixed_const(wm->dram_channels * 4);
2070926deccbSFrançois Tigeot 	a.full = dfixed_const(10);
2071926deccbSFrançois Tigeot 	dram_efficiency.full = dfixed_const(7);
2072926deccbSFrançois Tigeot 	dram_efficiency.full = dfixed_div(dram_efficiency, a);
2073926deccbSFrançois Tigeot 	bandwidth.full = dfixed_mul(dram_channels, yclk);
2074926deccbSFrançois Tigeot 	bandwidth.full = dfixed_mul(bandwidth, dram_efficiency);
2075926deccbSFrançois Tigeot 
2076926deccbSFrançois Tigeot 	return dfixed_trunc(bandwidth);
2077926deccbSFrançois Tigeot }
2078926deccbSFrançois Tigeot 
dce6_dram_bandwidth_for_display(struct dce6_wm_params * wm)2079926deccbSFrançois Tigeot static u32 dce6_dram_bandwidth_for_display(struct dce6_wm_params *wm)
2080926deccbSFrançois Tigeot {
2081926deccbSFrançois Tigeot 	/* Calculate DRAM Bandwidth and the part allocated to display. */
2082926deccbSFrançois Tigeot 	fixed20_12 disp_dram_allocation; /* 0.3 to 0.7 */
2083926deccbSFrançois Tigeot 	fixed20_12 yclk, dram_channels, bandwidth;
2084926deccbSFrançois Tigeot 	fixed20_12 a;
2085926deccbSFrançois Tigeot 
2086926deccbSFrançois Tigeot 	a.full = dfixed_const(1000);
2087926deccbSFrançois Tigeot 	yclk.full = dfixed_const(wm->yclk);
2088926deccbSFrançois Tigeot 	yclk.full = dfixed_div(yclk, a);
2089926deccbSFrançois Tigeot 	dram_channels.full = dfixed_const(wm->dram_channels * 4);
2090926deccbSFrançois Tigeot 	a.full = dfixed_const(10);
2091926deccbSFrançois Tigeot 	disp_dram_allocation.full = dfixed_const(3); /* XXX worse case value 0.3 */
2092926deccbSFrançois Tigeot 	disp_dram_allocation.full = dfixed_div(disp_dram_allocation, a);
2093926deccbSFrançois Tigeot 	bandwidth.full = dfixed_mul(dram_channels, yclk);
2094926deccbSFrançois Tigeot 	bandwidth.full = dfixed_mul(bandwidth, disp_dram_allocation);
2095926deccbSFrançois Tigeot 
2096926deccbSFrançois Tigeot 	return dfixed_trunc(bandwidth);
2097926deccbSFrançois Tigeot }
2098926deccbSFrançois Tigeot 
dce6_data_return_bandwidth(struct dce6_wm_params * wm)2099926deccbSFrançois Tigeot static u32 dce6_data_return_bandwidth(struct dce6_wm_params *wm)
2100926deccbSFrançois Tigeot {
2101926deccbSFrançois Tigeot 	/* Calculate the display Data return Bandwidth */
2102926deccbSFrançois Tigeot 	fixed20_12 return_efficiency; /* 0.8 */
2103926deccbSFrançois Tigeot 	fixed20_12 sclk, bandwidth;
2104926deccbSFrançois Tigeot 	fixed20_12 a;
2105926deccbSFrançois Tigeot 
2106926deccbSFrançois Tigeot 	a.full = dfixed_const(1000);
2107926deccbSFrançois Tigeot 	sclk.full = dfixed_const(wm->sclk);
2108926deccbSFrançois Tigeot 	sclk.full = dfixed_div(sclk, a);
2109926deccbSFrançois Tigeot 	a.full = dfixed_const(10);
2110926deccbSFrançois Tigeot 	return_efficiency.full = dfixed_const(8);
2111926deccbSFrançois Tigeot 	return_efficiency.full = dfixed_div(return_efficiency, a);
2112926deccbSFrançois Tigeot 	a.full = dfixed_const(32);
2113926deccbSFrançois Tigeot 	bandwidth.full = dfixed_mul(a, sclk);
2114926deccbSFrançois Tigeot 	bandwidth.full = dfixed_mul(bandwidth, return_efficiency);
2115926deccbSFrançois Tigeot 
2116926deccbSFrançois Tigeot 	return dfixed_trunc(bandwidth);
2117926deccbSFrançois Tigeot }
2118926deccbSFrançois Tigeot 
dce6_get_dmif_bytes_per_request(struct dce6_wm_params * wm)2119926deccbSFrançois Tigeot static u32 dce6_get_dmif_bytes_per_request(struct dce6_wm_params *wm)
2120926deccbSFrançois Tigeot {
2121926deccbSFrançois Tigeot 	return 32;
2122926deccbSFrançois Tigeot }
2123926deccbSFrançois Tigeot 
dce6_dmif_request_bandwidth(struct dce6_wm_params * wm)2124926deccbSFrançois Tigeot static u32 dce6_dmif_request_bandwidth(struct dce6_wm_params *wm)
2125926deccbSFrançois Tigeot {
2126926deccbSFrançois Tigeot 	/* Calculate the DMIF Request Bandwidth */
2127926deccbSFrançois Tigeot 	fixed20_12 disp_clk_request_efficiency; /* 0.8 */
2128926deccbSFrançois Tigeot 	fixed20_12 disp_clk, sclk, bandwidth;
2129926deccbSFrançois Tigeot 	fixed20_12 a, b1, b2;
2130926deccbSFrançois Tigeot 	u32 min_bandwidth;
2131926deccbSFrançois Tigeot 
2132926deccbSFrançois Tigeot 	a.full = dfixed_const(1000);
2133926deccbSFrançois Tigeot 	disp_clk.full = dfixed_const(wm->disp_clk);
2134926deccbSFrançois Tigeot 	disp_clk.full = dfixed_div(disp_clk, a);
2135926deccbSFrançois Tigeot 	a.full = dfixed_const(dce6_get_dmif_bytes_per_request(wm) / 2);
2136926deccbSFrançois Tigeot 	b1.full = dfixed_mul(a, disp_clk);
2137926deccbSFrançois Tigeot 
2138926deccbSFrançois Tigeot 	a.full = dfixed_const(1000);
2139926deccbSFrançois Tigeot 	sclk.full = dfixed_const(wm->sclk);
2140926deccbSFrançois Tigeot 	sclk.full = dfixed_div(sclk, a);
2141926deccbSFrançois Tigeot 	a.full = dfixed_const(dce6_get_dmif_bytes_per_request(wm));
2142926deccbSFrançois Tigeot 	b2.full = dfixed_mul(a, sclk);
2143926deccbSFrançois Tigeot 
2144926deccbSFrançois Tigeot 	a.full = dfixed_const(10);
2145926deccbSFrançois Tigeot 	disp_clk_request_efficiency.full = dfixed_const(8);
2146926deccbSFrançois Tigeot 	disp_clk_request_efficiency.full = dfixed_div(disp_clk_request_efficiency, a);
2147926deccbSFrançois Tigeot 
2148926deccbSFrançois Tigeot 	min_bandwidth = min(dfixed_trunc(b1), dfixed_trunc(b2));
2149926deccbSFrançois Tigeot 
2150926deccbSFrançois Tigeot 	a.full = dfixed_const(min_bandwidth);
2151926deccbSFrançois Tigeot 	bandwidth.full = dfixed_mul(a, disp_clk_request_efficiency);
2152926deccbSFrançois Tigeot 
2153926deccbSFrançois Tigeot 	return dfixed_trunc(bandwidth);
2154926deccbSFrançois Tigeot }
2155926deccbSFrançois Tigeot 
dce6_available_bandwidth(struct dce6_wm_params * wm)2156926deccbSFrançois Tigeot static u32 dce6_available_bandwidth(struct dce6_wm_params *wm)
2157926deccbSFrançois Tigeot {
2158926deccbSFrançois Tigeot 	/* Calculate the Available bandwidth. Display can use this temporarily but not in average. */
2159926deccbSFrançois Tigeot 	u32 dram_bandwidth = dce6_dram_bandwidth(wm);
2160926deccbSFrançois Tigeot 	u32 data_return_bandwidth = dce6_data_return_bandwidth(wm);
2161926deccbSFrançois Tigeot 	u32 dmif_req_bandwidth = dce6_dmif_request_bandwidth(wm);
2162926deccbSFrançois Tigeot 
2163926deccbSFrançois Tigeot 	return min(dram_bandwidth, min(data_return_bandwidth, dmif_req_bandwidth));
2164926deccbSFrançois Tigeot }
2165926deccbSFrançois Tigeot 
dce6_average_bandwidth(struct dce6_wm_params * wm)2166926deccbSFrançois Tigeot static u32 dce6_average_bandwidth(struct dce6_wm_params *wm)
2167926deccbSFrançois Tigeot {
2168926deccbSFrançois Tigeot 	/* Calculate the display mode Average Bandwidth
2169926deccbSFrançois Tigeot 	 * DisplayMode should contain the source and destination dimensions,
2170926deccbSFrançois Tigeot 	 * timing, etc.
2171926deccbSFrançois Tigeot 	 */
2172926deccbSFrançois Tigeot 	fixed20_12 bpp;
2173926deccbSFrançois Tigeot 	fixed20_12 line_time;
2174926deccbSFrançois Tigeot 	fixed20_12 src_width;
2175926deccbSFrançois Tigeot 	fixed20_12 bandwidth;
2176926deccbSFrançois Tigeot 	fixed20_12 a;
2177926deccbSFrançois Tigeot 
2178926deccbSFrançois Tigeot 	a.full = dfixed_const(1000);
2179926deccbSFrançois Tigeot 	line_time.full = dfixed_const(wm->active_time + wm->blank_time);
2180926deccbSFrançois Tigeot 	line_time.full = dfixed_div(line_time, a);
2181926deccbSFrançois Tigeot 	bpp.full = dfixed_const(wm->bytes_per_pixel);
2182926deccbSFrançois Tigeot 	src_width.full = dfixed_const(wm->src_width);
2183926deccbSFrançois Tigeot 	bandwidth.full = dfixed_mul(src_width, bpp);
2184926deccbSFrançois Tigeot 	bandwidth.full = dfixed_mul(bandwidth, wm->vsc);
2185926deccbSFrançois Tigeot 	bandwidth.full = dfixed_div(bandwidth, line_time);
2186926deccbSFrançois Tigeot 
2187926deccbSFrançois Tigeot 	return dfixed_trunc(bandwidth);
2188926deccbSFrançois Tigeot }
2189926deccbSFrançois Tigeot 
dce6_latency_watermark(struct dce6_wm_params * wm)2190926deccbSFrançois Tigeot static u32 dce6_latency_watermark(struct dce6_wm_params *wm)
2191926deccbSFrançois Tigeot {
2192926deccbSFrançois Tigeot 	/* First calcualte the latency in ns */
2193926deccbSFrançois Tigeot 	u32 mc_latency = 2000; /* 2000 ns. */
2194926deccbSFrançois Tigeot 	u32 available_bandwidth = dce6_available_bandwidth(wm);
2195926deccbSFrançois Tigeot 	u32 worst_chunk_return_time = (512 * 8 * 1000) / available_bandwidth;
2196926deccbSFrançois Tigeot 	u32 cursor_line_pair_return_time = (128 * 4 * 1000) / available_bandwidth;
2197926deccbSFrançois Tigeot 	u32 dc_latency = 40000000 / wm->disp_clk; /* dc pipe latency */
2198926deccbSFrançois Tigeot 	u32 other_heads_data_return_time = ((wm->num_heads + 1) * worst_chunk_return_time) +
2199926deccbSFrançois Tigeot 		(wm->num_heads * cursor_line_pair_return_time);
2200926deccbSFrançois Tigeot 	u32 latency = mc_latency + other_heads_data_return_time + dc_latency;
2201926deccbSFrançois Tigeot 	u32 max_src_lines_per_dst_line, lb_fill_bw, line_fill_time;
2202926deccbSFrançois Tigeot 	u32 tmp, dmif_size = 12288;
2203926deccbSFrançois Tigeot 	fixed20_12 a, b, c;
2204926deccbSFrançois Tigeot 
2205926deccbSFrançois Tigeot 	if (wm->num_heads == 0)
2206926deccbSFrançois Tigeot 		return 0;
2207926deccbSFrançois Tigeot 
2208926deccbSFrançois Tigeot 	a.full = dfixed_const(2);
2209926deccbSFrançois Tigeot 	b.full = dfixed_const(1);
2210926deccbSFrançois Tigeot 	if ((wm->vsc.full > a.full) ||
2211926deccbSFrançois Tigeot 	    ((wm->vsc.full > b.full) && (wm->vtaps >= 3)) ||
2212926deccbSFrançois Tigeot 	    (wm->vtaps >= 5) ||
2213926deccbSFrançois Tigeot 	    ((wm->vsc.full >= a.full) && wm->interlaced))
2214926deccbSFrançois Tigeot 		max_src_lines_per_dst_line = 4;
2215926deccbSFrançois Tigeot 	else
2216926deccbSFrançois Tigeot 		max_src_lines_per_dst_line = 2;
2217926deccbSFrançois Tigeot 
2218926deccbSFrançois Tigeot 	a.full = dfixed_const(available_bandwidth);
2219926deccbSFrançois Tigeot 	b.full = dfixed_const(wm->num_heads);
2220926deccbSFrançois Tigeot 	a.full = dfixed_div(a, b);
2221a85cb24fSFrançois Tigeot 	tmp = div_u64((u64) dmif_size * (u64) wm->disp_clk, mc_latency + 512);
2222a85cb24fSFrançois Tigeot 	tmp = min(dfixed_trunc(a), tmp);
2223926deccbSFrançois Tigeot 
2224a85cb24fSFrançois Tigeot 	lb_fill_bw = min(tmp, wm->disp_clk * wm->bytes_per_pixel / 1000);
2225926deccbSFrançois Tigeot 
2226926deccbSFrançois Tigeot 	a.full = dfixed_const(max_src_lines_per_dst_line * wm->src_width * wm->bytes_per_pixel);
2227926deccbSFrançois Tigeot 	b.full = dfixed_const(1000);
2228926deccbSFrançois Tigeot 	c.full = dfixed_const(lb_fill_bw);
2229926deccbSFrançois Tigeot 	b.full = dfixed_div(c, b);
2230926deccbSFrançois Tigeot 	a.full = dfixed_div(a, b);
2231926deccbSFrançois Tigeot 	line_fill_time = dfixed_trunc(a);
2232926deccbSFrançois Tigeot 
2233926deccbSFrançois Tigeot 	if (line_fill_time < wm->active_time)
2234926deccbSFrançois Tigeot 		return latency;
2235926deccbSFrançois Tigeot 	else
2236926deccbSFrançois Tigeot 		return latency + (line_fill_time - wm->active_time);
2237926deccbSFrançois Tigeot 
2238926deccbSFrançois Tigeot }
2239926deccbSFrançois Tigeot 
dce6_average_bandwidth_vs_dram_bandwidth_for_display(struct dce6_wm_params * wm)2240926deccbSFrançois Tigeot static bool dce6_average_bandwidth_vs_dram_bandwidth_for_display(struct dce6_wm_params *wm)
2241926deccbSFrançois Tigeot {
2242926deccbSFrançois Tigeot 	if (dce6_average_bandwidth(wm) <=
2243926deccbSFrançois Tigeot 	    (dce6_dram_bandwidth_for_display(wm) / wm->num_heads))
2244926deccbSFrançois Tigeot 		return true;
2245926deccbSFrançois Tigeot 	else
2246926deccbSFrançois Tigeot 		return false;
2247926deccbSFrançois Tigeot };
2248926deccbSFrançois Tigeot 
dce6_average_bandwidth_vs_available_bandwidth(struct dce6_wm_params * wm)2249926deccbSFrançois Tigeot static bool dce6_average_bandwidth_vs_available_bandwidth(struct dce6_wm_params *wm)
2250926deccbSFrançois Tigeot {
2251926deccbSFrançois Tigeot 	if (dce6_average_bandwidth(wm) <=
2252926deccbSFrançois Tigeot 	    (dce6_available_bandwidth(wm) / wm->num_heads))
2253926deccbSFrançois Tigeot 		return true;
2254926deccbSFrançois Tigeot 	else
2255926deccbSFrançois Tigeot 		return false;
2256926deccbSFrançois Tigeot };
2257926deccbSFrançois Tigeot 
dce6_check_latency_hiding(struct dce6_wm_params * wm)2258926deccbSFrançois Tigeot static bool dce6_check_latency_hiding(struct dce6_wm_params *wm)
2259926deccbSFrançois Tigeot {
2260926deccbSFrançois Tigeot 	u32 lb_partitions = wm->lb_size / wm->src_width;
2261926deccbSFrançois Tigeot 	u32 line_time = wm->active_time + wm->blank_time;
2262926deccbSFrançois Tigeot 	u32 latency_tolerant_lines;
2263926deccbSFrançois Tigeot 	u32 latency_hiding;
2264926deccbSFrançois Tigeot 	fixed20_12 a;
2265926deccbSFrançois Tigeot 
2266926deccbSFrançois Tigeot 	a.full = dfixed_const(1);
2267926deccbSFrançois Tigeot 	if (wm->vsc.full > a.full)
2268926deccbSFrançois Tigeot 		latency_tolerant_lines = 1;
2269926deccbSFrançois Tigeot 	else {
2270926deccbSFrançois Tigeot 		if (lb_partitions <= (wm->vtaps + 1))
2271926deccbSFrançois Tigeot 			latency_tolerant_lines = 1;
2272926deccbSFrançois Tigeot 		else
2273926deccbSFrançois Tigeot 			latency_tolerant_lines = 2;
2274926deccbSFrançois Tigeot 	}
2275926deccbSFrançois Tigeot 
2276926deccbSFrançois Tigeot 	latency_hiding = (latency_tolerant_lines * line_time + wm->blank_time);
2277926deccbSFrançois Tigeot 
2278926deccbSFrançois Tigeot 	if (dce6_latency_watermark(wm) <= latency_hiding)
2279926deccbSFrançois Tigeot 		return true;
2280926deccbSFrançois Tigeot 	else
2281926deccbSFrançois Tigeot 		return false;
2282926deccbSFrançois Tigeot }
2283926deccbSFrançois Tigeot 
dce6_program_watermarks(struct radeon_device * rdev,struct radeon_crtc * radeon_crtc,u32 lb_size,u32 num_heads)2284926deccbSFrançois Tigeot static void dce6_program_watermarks(struct radeon_device *rdev,
2285926deccbSFrançois Tigeot 					 struct radeon_crtc *radeon_crtc,
2286926deccbSFrançois Tigeot 					 u32 lb_size, u32 num_heads)
2287926deccbSFrançois Tigeot {
2288926deccbSFrançois Tigeot 	struct drm_display_mode *mode = &radeon_crtc->base.mode;
228957e252bfSMichael Neumann 	struct dce6_wm_params wm_low, wm_high;
229057e252bfSMichael Neumann 	u32 dram_channels;
2291a85cb24fSFrançois Tigeot 	u32 active_time;
2292926deccbSFrançois Tigeot 	u32 line_time = 0;
2293926deccbSFrançois Tigeot 	u32 latency_watermark_a = 0, latency_watermark_b = 0;
2294926deccbSFrançois Tigeot 	u32 priority_a_mark = 0, priority_b_mark = 0;
2295926deccbSFrançois Tigeot 	u32 priority_a_cnt = PRIORITY_OFF;
2296926deccbSFrançois Tigeot 	u32 priority_b_cnt = PRIORITY_OFF;
2297926deccbSFrançois Tigeot 	u32 tmp, arb_control3;
2298926deccbSFrançois Tigeot 	fixed20_12 a, b, c;
2299926deccbSFrançois Tigeot 
2300926deccbSFrançois Tigeot 	if (radeon_crtc->base.enabled && num_heads && mode) {
2301a85cb24fSFrançois Tigeot 		active_time = (u32) div_u64((u64)mode->crtc_hdisplay * 1000000,
2302a85cb24fSFrançois Tigeot 					    (u32)mode->clock);
2303a85cb24fSFrançois Tigeot 		line_time = (u32) div_u64((u64)mode->crtc_htotal * 1000000,
2304a85cb24fSFrançois Tigeot 					  (u32)mode->clock);
2305a85cb24fSFrançois Tigeot 		line_time = min(line_time, (u32)65535);
2306926deccbSFrançois Tigeot 		priority_a_cnt = 0;
2307926deccbSFrançois Tigeot 		priority_b_cnt = 0;
2308926deccbSFrançois Tigeot 
2309926deccbSFrançois Tigeot 		if (rdev->family == CHIP_ARUBA)
231057e252bfSMichael Neumann 			dram_channels = evergreen_get_number_of_dram_channels(rdev);
2311926deccbSFrançois Tigeot 		else
231257e252bfSMichael Neumann 			dram_channels = si_get_number_of_dram_channels(rdev);
231357e252bfSMichael Neumann 
231457e252bfSMichael Neumann 		/* watermark for high clocks */
231557e252bfSMichael Neumann 		if ((rdev->pm.pm_method == PM_METHOD_DPM) && rdev->pm.dpm_enabled) {
231657e252bfSMichael Neumann 			wm_high.yclk =
231757e252bfSMichael Neumann 				radeon_dpm_get_mclk(rdev, false) * 10;
231857e252bfSMichael Neumann 			wm_high.sclk =
231957e252bfSMichael Neumann 				radeon_dpm_get_sclk(rdev, false) * 10;
232057e252bfSMichael Neumann 		} else {
232157e252bfSMichael Neumann 			wm_high.yclk = rdev->pm.current_mclk * 10;
232257e252bfSMichael Neumann 			wm_high.sclk = rdev->pm.current_sclk * 10;
232357e252bfSMichael Neumann 		}
232457e252bfSMichael Neumann 
232557e252bfSMichael Neumann 		wm_high.disp_clk = mode->clock;
232657e252bfSMichael Neumann 		wm_high.src_width = mode->crtc_hdisplay;
2327a85cb24fSFrançois Tigeot 		wm_high.active_time = active_time;
232857e252bfSMichael Neumann 		wm_high.blank_time = line_time - wm_high.active_time;
232957e252bfSMichael Neumann 		wm_high.interlaced = false;
233057e252bfSMichael Neumann 		if (mode->flags & DRM_MODE_FLAG_INTERLACE)
233157e252bfSMichael Neumann 			wm_high.interlaced = true;
233257e252bfSMichael Neumann 		wm_high.vsc = radeon_crtc->vsc;
233357e252bfSMichael Neumann 		wm_high.vtaps = 1;
233457e252bfSMichael Neumann 		if (radeon_crtc->rmx_type != RMX_OFF)
233557e252bfSMichael Neumann 			wm_high.vtaps = 2;
233657e252bfSMichael Neumann 		wm_high.bytes_per_pixel = 4; /* XXX: get this from fb config */
233757e252bfSMichael Neumann 		wm_high.lb_size = lb_size;
233857e252bfSMichael Neumann 		wm_high.dram_channels = dram_channels;
233957e252bfSMichael Neumann 		wm_high.num_heads = num_heads;
234057e252bfSMichael Neumann 
234157e252bfSMichael Neumann 		/* watermark for low clocks */
234257e252bfSMichael Neumann 		if ((rdev->pm.pm_method == PM_METHOD_DPM) && rdev->pm.dpm_enabled) {
234357e252bfSMichael Neumann 			wm_low.yclk =
234457e252bfSMichael Neumann 				radeon_dpm_get_mclk(rdev, true) * 10;
234557e252bfSMichael Neumann 			wm_low.sclk =
234657e252bfSMichael Neumann 				radeon_dpm_get_sclk(rdev, true) * 10;
234757e252bfSMichael Neumann 		} else {
234857e252bfSMichael Neumann 			wm_low.yclk = rdev->pm.current_mclk * 10;
234957e252bfSMichael Neumann 			wm_low.sclk = rdev->pm.current_sclk * 10;
235057e252bfSMichael Neumann 		}
235157e252bfSMichael Neumann 
235257e252bfSMichael Neumann 		wm_low.disp_clk = mode->clock;
235357e252bfSMichael Neumann 		wm_low.src_width = mode->crtc_hdisplay;
2354a85cb24fSFrançois Tigeot 		wm_low.active_time = active_time;
235557e252bfSMichael Neumann 		wm_low.blank_time = line_time - wm_low.active_time;
235657e252bfSMichael Neumann 		wm_low.interlaced = false;
235757e252bfSMichael Neumann 		if (mode->flags & DRM_MODE_FLAG_INTERLACE)
235857e252bfSMichael Neumann 			wm_low.interlaced = true;
235957e252bfSMichael Neumann 		wm_low.vsc = radeon_crtc->vsc;
236057e252bfSMichael Neumann 		wm_low.vtaps = 1;
236157e252bfSMichael Neumann 		if (radeon_crtc->rmx_type != RMX_OFF)
236257e252bfSMichael Neumann 			wm_low.vtaps = 2;
236357e252bfSMichael Neumann 		wm_low.bytes_per_pixel = 4; /* XXX: get this from fb config */
236457e252bfSMichael Neumann 		wm_low.lb_size = lb_size;
236557e252bfSMichael Neumann 		wm_low.dram_channels = dram_channels;
236657e252bfSMichael Neumann 		wm_low.num_heads = num_heads;
2367926deccbSFrançois Tigeot 
2368926deccbSFrançois Tigeot 		/* set for high clocks */
236957e252bfSMichael Neumann 		latency_watermark_a = min(dce6_latency_watermark(&wm_high), (u32)65535);
2370926deccbSFrançois Tigeot 		/* set for low clocks */
237157e252bfSMichael Neumann 		latency_watermark_b = min(dce6_latency_watermark(&wm_low), (u32)65535);
2372926deccbSFrançois Tigeot 
2373926deccbSFrançois Tigeot 		/* possibly force display priority to high */
2374926deccbSFrançois Tigeot 		/* should really do this at mode validation time... */
237557e252bfSMichael Neumann 		if (!dce6_average_bandwidth_vs_dram_bandwidth_for_display(&wm_high) ||
237657e252bfSMichael Neumann 		    !dce6_average_bandwidth_vs_available_bandwidth(&wm_high) ||
237757e252bfSMichael Neumann 		    !dce6_check_latency_hiding(&wm_high) ||
237857e252bfSMichael Neumann 		    (rdev->disp_priority == 2)) {
237957e252bfSMichael Neumann 			DRM_DEBUG_KMS("force priority to high\n");
238057e252bfSMichael Neumann 			priority_a_cnt |= PRIORITY_ALWAYS_ON;
238157e252bfSMichael Neumann 			priority_b_cnt |= PRIORITY_ALWAYS_ON;
238257e252bfSMichael Neumann 		}
238357e252bfSMichael Neumann 		if (!dce6_average_bandwidth_vs_dram_bandwidth_for_display(&wm_low) ||
238457e252bfSMichael Neumann 		    !dce6_average_bandwidth_vs_available_bandwidth(&wm_low) ||
238557e252bfSMichael Neumann 		    !dce6_check_latency_hiding(&wm_low) ||
2386926deccbSFrançois Tigeot 		    (rdev->disp_priority == 2)) {
2387926deccbSFrançois Tigeot 			DRM_DEBUG_KMS("force priority to high\n");
2388926deccbSFrançois Tigeot 			priority_a_cnt |= PRIORITY_ALWAYS_ON;
2389926deccbSFrançois Tigeot 			priority_b_cnt |= PRIORITY_ALWAYS_ON;
2390926deccbSFrançois Tigeot 		}
2391926deccbSFrançois Tigeot 
2392926deccbSFrançois Tigeot 		a.full = dfixed_const(1000);
2393926deccbSFrançois Tigeot 		b.full = dfixed_const(mode->clock);
2394926deccbSFrançois Tigeot 		b.full = dfixed_div(b, a);
2395926deccbSFrançois Tigeot 		c.full = dfixed_const(latency_watermark_a);
2396926deccbSFrançois Tigeot 		c.full = dfixed_mul(c, b);
2397926deccbSFrançois Tigeot 		c.full = dfixed_mul(c, radeon_crtc->hsc);
2398926deccbSFrançois Tigeot 		c.full = dfixed_div(c, a);
2399926deccbSFrançois Tigeot 		a.full = dfixed_const(16);
2400926deccbSFrançois Tigeot 		c.full = dfixed_div(c, a);
2401926deccbSFrançois Tigeot 		priority_a_mark = dfixed_trunc(c);
2402926deccbSFrançois Tigeot 		priority_a_cnt |= priority_a_mark & PRIORITY_MARK_MASK;
2403926deccbSFrançois Tigeot 
2404926deccbSFrançois Tigeot 		a.full = dfixed_const(1000);
2405926deccbSFrançois Tigeot 		b.full = dfixed_const(mode->clock);
2406926deccbSFrançois Tigeot 		b.full = dfixed_div(b, a);
2407926deccbSFrançois Tigeot 		c.full = dfixed_const(latency_watermark_b);
2408926deccbSFrançois Tigeot 		c.full = dfixed_mul(c, b);
2409926deccbSFrançois Tigeot 		c.full = dfixed_mul(c, radeon_crtc->hsc);
2410926deccbSFrançois Tigeot 		c.full = dfixed_div(c, a);
2411926deccbSFrançois Tigeot 		a.full = dfixed_const(16);
2412926deccbSFrançois Tigeot 		c.full = dfixed_div(c, a);
2413926deccbSFrançois Tigeot 		priority_b_mark = dfixed_trunc(c);
2414926deccbSFrançois Tigeot 		priority_b_cnt |= priority_b_mark & PRIORITY_MARK_MASK;
2415c59a5c48SFrançois Tigeot 
2416c59a5c48SFrançois Tigeot 		/* Save number of lines the linebuffer leads before the scanout */
2417c59a5c48SFrançois Tigeot 		radeon_crtc->lb_vblank_lead_lines = DIV_ROUND_UP(lb_size, mode->crtc_hdisplay);
2418926deccbSFrançois Tigeot 	}
2419926deccbSFrançois Tigeot 
2420926deccbSFrançois Tigeot 	/* select wm A */
2421926deccbSFrançois Tigeot 	arb_control3 = RREG32(DPG_PIPE_ARBITRATION_CONTROL3 + radeon_crtc->crtc_offset);
2422926deccbSFrançois Tigeot 	tmp = arb_control3;
2423926deccbSFrançois Tigeot 	tmp &= ~LATENCY_WATERMARK_MASK(3);
2424926deccbSFrançois Tigeot 	tmp |= LATENCY_WATERMARK_MASK(1);
2425926deccbSFrançois Tigeot 	WREG32(DPG_PIPE_ARBITRATION_CONTROL3 + radeon_crtc->crtc_offset, tmp);
2426926deccbSFrançois Tigeot 	WREG32(DPG_PIPE_LATENCY_CONTROL + radeon_crtc->crtc_offset,
2427926deccbSFrançois Tigeot 	       (LATENCY_LOW_WATERMARK(latency_watermark_a) |
2428926deccbSFrançois Tigeot 		LATENCY_HIGH_WATERMARK(line_time)));
2429926deccbSFrançois Tigeot 	/* select wm B */
2430926deccbSFrançois Tigeot 	tmp = RREG32(DPG_PIPE_ARBITRATION_CONTROL3 + radeon_crtc->crtc_offset);
2431926deccbSFrançois Tigeot 	tmp &= ~LATENCY_WATERMARK_MASK(3);
2432926deccbSFrançois Tigeot 	tmp |= LATENCY_WATERMARK_MASK(2);
2433926deccbSFrançois Tigeot 	WREG32(DPG_PIPE_ARBITRATION_CONTROL3 + radeon_crtc->crtc_offset, tmp);
2434926deccbSFrançois Tigeot 	WREG32(DPG_PIPE_LATENCY_CONTROL + radeon_crtc->crtc_offset,
2435926deccbSFrançois Tigeot 	       (LATENCY_LOW_WATERMARK(latency_watermark_b) |
2436926deccbSFrançois Tigeot 		LATENCY_HIGH_WATERMARK(line_time)));
2437926deccbSFrançois Tigeot 	/* restore original selection */
2438926deccbSFrançois Tigeot 	WREG32(DPG_PIPE_ARBITRATION_CONTROL3 + radeon_crtc->crtc_offset, arb_control3);
2439926deccbSFrançois Tigeot 
2440926deccbSFrançois Tigeot 	/* write the priority marks */
2441926deccbSFrançois Tigeot 	WREG32(PRIORITY_A_CNT + radeon_crtc->crtc_offset, priority_a_cnt);
2442926deccbSFrançois Tigeot 	WREG32(PRIORITY_B_CNT + radeon_crtc->crtc_offset, priority_b_cnt);
2443926deccbSFrançois Tigeot 
244457e252bfSMichael Neumann 	/* save values for DPM */
244557e252bfSMichael Neumann 	radeon_crtc->line_time = line_time;
244657e252bfSMichael Neumann 	radeon_crtc->wm_high = latency_watermark_a;
244757e252bfSMichael Neumann 	radeon_crtc->wm_low = latency_watermark_b;
2448926deccbSFrançois Tigeot }
2449926deccbSFrançois Tigeot 
dce6_bandwidth_update(struct radeon_device * rdev)2450926deccbSFrançois Tigeot void dce6_bandwidth_update(struct radeon_device *rdev)
2451926deccbSFrançois Tigeot {
2452926deccbSFrançois Tigeot 	struct drm_display_mode *mode0 = NULL;
2453926deccbSFrançois Tigeot 	struct drm_display_mode *mode1 = NULL;
2454926deccbSFrançois Tigeot 	u32 num_heads = 0, lb_size;
2455926deccbSFrançois Tigeot 	int i;
2456926deccbSFrançois Tigeot 
2457591d5043SFrançois Tigeot 	if (!rdev->mode_info.mode_config_initialized)
2458591d5043SFrançois Tigeot 		return;
2459591d5043SFrançois Tigeot 
2460926deccbSFrançois Tigeot 	radeon_update_display_priority(rdev);
2461926deccbSFrançois Tigeot 
2462926deccbSFrançois Tigeot 	for (i = 0; i < rdev->num_crtc; i++) {
2463926deccbSFrançois Tigeot 		if (rdev->mode_info.crtcs[i]->base.enabled)
2464926deccbSFrançois Tigeot 			num_heads++;
2465926deccbSFrançois Tigeot 	}
2466926deccbSFrançois Tigeot 	for (i = 0; i < rdev->num_crtc; i += 2) {
2467926deccbSFrançois Tigeot 		mode0 = &rdev->mode_info.crtcs[i]->base.mode;
2468926deccbSFrançois Tigeot 		mode1 = &rdev->mode_info.crtcs[i+1]->base.mode;
2469926deccbSFrançois Tigeot 		lb_size = dce6_line_buffer_adjust(rdev, rdev->mode_info.crtcs[i], mode0, mode1);
2470926deccbSFrançois Tigeot 		dce6_program_watermarks(rdev, rdev->mode_info.crtcs[i], lb_size, num_heads);
2471926deccbSFrançois Tigeot 		lb_size = dce6_line_buffer_adjust(rdev, rdev->mode_info.crtcs[i+1], mode1, mode0);
2472926deccbSFrançois Tigeot 		dce6_program_watermarks(rdev, rdev->mode_info.crtcs[i+1], lb_size, num_heads);
2473926deccbSFrançois Tigeot 	}
2474926deccbSFrançois Tigeot }
2475926deccbSFrançois Tigeot 
2476926deccbSFrançois Tigeot /*
2477926deccbSFrançois Tigeot  * Core functions
2478926deccbSFrançois Tigeot  */
si_tiling_mode_table_init(struct radeon_device * rdev)2479926deccbSFrançois Tigeot static void si_tiling_mode_table_init(struct radeon_device *rdev)
2480926deccbSFrançois Tigeot {
2481d78d3a22SFrançois Tigeot 	u32 *tile = rdev->config.si.tile_mode_array;
2482d78d3a22SFrançois Tigeot 	const u32 num_tile_mode_states =
2483d78d3a22SFrançois Tigeot 			ARRAY_SIZE(rdev->config.si.tile_mode_array);
2484d78d3a22SFrançois Tigeot 	u32 reg_offset, split_equal_to_row_size;
2485926deccbSFrançois Tigeot 
2486926deccbSFrançois Tigeot 	switch (rdev->config.si.mem_row_size_in_kb) {
2487926deccbSFrançois Tigeot 	case 1:
2488926deccbSFrançois Tigeot 		split_equal_to_row_size = ADDR_SURF_TILE_SPLIT_1KB;
2489926deccbSFrançois Tigeot 		break;
2490926deccbSFrançois Tigeot 	case 2:
2491926deccbSFrançois Tigeot 	default:
2492926deccbSFrançois Tigeot 		split_equal_to_row_size = ADDR_SURF_TILE_SPLIT_2KB;
2493926deccbSFrançois Tigeot 		break;
2494926deccbSFrançois Tigeot 	case 4:
2495926deccbSFrançois Tigeot 		split_equal_to_row_size = ADDR_SURF_TILE_SPLIT_4KB;
2496926deccbSFrançois Tigeot 		break;
2497926deccbSFrançois Tigeot 	}
2498926deccbSFrançois Tigeot 
2499d78d3a22SFrançois Tigeot 	for (reg_offset = 0; reg_offset < num_tile_mode_states; reg_offset++)
2500d78d3a22SFrançois Tigeot 		tile[reg_offset] = 0;
2501d78d3a22SFrançois Tigeot 
2502d78d3a22SFrançois Tigeot 	switch(rdev->family) {
2503d78d3a22SFrançois Tigeot 	case CHIP_TAHITI:
2504d78d3a22SFrançois Tigeot 	case CHIP_PITCAIRN:
2505d78d3a22SFrançois Tigeot 		/* non-AA compressed depth or any compressed stencil */
2506d78d3a22SFrançois Tigeot 		tile[0] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
2507926deccbSFrançois Tigeot 			   MICRO_TILE_MODE(ADDR_SURF_DEPTH_MICRO_TILING) |
2508926deccbSFrançois Tigeot 			   PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) |
2509926deccbSFrançois Tigeot 			   TILE_SPLIT(ADDR_SURF_TILE_SPLIT_64B) |
2510926deccbSFrançois Tigeot 			   NUM_BANKS(ADDR_SURF_16_BANK) |
2511926deccbSFrançois Tigeot 			   BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
2512926deccbSFrançois Tigeot 			   BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) |
2513926deccbSFrançois Tigeot 			   MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2));
2514d78d3a22SFrançois Tigeot 		/* 2xAA/4xAA compressed depth only */
2515d78d3a22SFrançois Tigeot 		tile[1] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
2516926deccbSFrançois Tigeot 			   MICRO_TILE_MODE(ADDR_SURF_DEPTH_MICRO_TILING) |
2517926deccbSFrançois Tigeot 			   PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) |
2518926deccbSFrançois Tigeot 			   TILE_SPLIT(ADDR_SURF_TILE_SPLIT_128B) |
2519926deccbSFrançois Tigeot 			   NUM_BANKS(ADDR_SURF_16_BANK) |
2520926deccbSFrançois Tigeot 			   BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
2521926deccbSFrançois Tigeot 			   BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) |
2522926deccbSFrançois Tigeot 			   MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2));
2523d78d3a22SFrançois Tigeot 		/* 8xAA compressed depth only */
2524d78d3a22SFrançois Tigeot 		tile[2] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
2525926deccbSFrançois Tigeot 			   MICRO_TILE_MODE(ADDR_SURF_DEPTH_MICRO_TILING) |
2526926deccbSFrançois Tigeot 			   PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) |
2527926deccbSFrançois Tigeot 			   TILE_SPLIT(ADDR_SURF_TILE_SPLIT_256B) |
2528926deccbSFrançois Tigeot 			   NUM_BANKS(ADDR_SURF_16_BANK) |
2529926deccbSFrançois Tigeot 			   BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
2530926deccbSFrançois Tigeot 			   BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) |
2531926deccbSFrançois Tigeot 			   MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2));
2532d78d3a22SFrançois Tigeot 		/* 2xAA/4xAA compressed depth with stencil (for depth buffer) */
2533d78d3a22SFrançois Tigeot 		tile[3] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
2534926deccbSFrançois Tigeot 			   MICRO_TILE_MODE(ADDR_SURF_DEPTH_MICRO_TILING) |
2535926deccbSFrançois Tigeot 			   PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) |
2536926deccbSFrançois Tigeot 			   TILE_SPLIT(ADDR_SURF_TILE_SPLIT_128B) |
2537926deccbSFrançois Tigeot 			   NUM_BANKS(ADDR_SURF_16_BANK) |
2538926deccbSFrançois Tigeot 			   BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
2539926deccbSFrançois Tigeot 			   BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) |
2540926deccbSFrançois Tigeot 			   MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2));
2541d78d3a22SFrançois Tigeot 		/* Maps w/ a dimension less than the 2D macro-tile dimensions (for mipmapped depth textures) */
2542d78d3a22SFrançois Tigeot 		tile[4] = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) |
2543926deccbSFrançois Tigeot 			   MICRO_TILE_MODE(ADDR_SURF_DEPTH_MICRO_TILING) |
2544926deccbSFrançois Tigeot 			   PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) |
2545926deccbSFrançois Tigeot 			   TILE_SPLIT(ADDR_SURF_TILE_SPLIT_64B) |
2546926deccbSFrançois Tigeot 			   NUM_BANKS(ADDR_SURF_16_BANK) |
2547926deccbSFrançois Tigeot 			   BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
2548926deccbSFrançois Tigeot 			   BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) |
2549926deccbSFrançois Tigeot 			   MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2));
2550d78d3a22SFrançois Tigeot 		/* Uncompressed 16bpp depth - and stencil buffer allocated with it */
2551d78d3a22SFrançois Tigeot 		tile[5] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
2552926deccbSFrançois Tigeot 			   MICRO_TILE_MODE(ADDR_SURF_DEPTH_MICRO_TILING) |
2553926deccbSFrançois Tigeot 			   PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) |
2554926deccbSFrançois Tigeot 			   TILE_SPLIT(split_equal_to_row_size) |
2555926deccbSFrançois Tigeot 			   NUM_BANKS(ADDR_SURF_16_BANK) |
2556926deccbSFrançois Tigeot 			   BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
2557926deccbSFrançois Tigeot 			   BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) |
2558926deccbSFrançois Tigeot 			   MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2));
2559d78d3a22SFrançois Tigeot 		/* Uncompressed 32bpp depth - and stencil buffer allocated with it */
2560d78d3a22SFrançois Tigeot 		tile[6] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
2561926deccbSFrançois Tigeot 			   MICRO_TILE_MODE(ADDR_SURF_DEPTH_MICRO_TILING) |
2562926deccbSFrançois Tigeot 			   PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) |
2563926deccbSFrançois Tigeot 			   TILE_SPLIT(split_equal_to_row_size) |
2564926deccbSFrançois Tigeot 			   NUM_BANKS(ADDR_SURF_16_BANK) |
2565926deccbSFrançois Tigeot 			   BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
2566926deccbSFrançois Tigeot 			   BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) |
2567926deccbSFrançois Tigeot 			   MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1));
2568d78d3a22SFrançois Tigeot 		/* Uncompressed 8bpp stencil without depth (drivers typically do not use) */
2569d78d3a22SFrançois Tigeot 		tile[7] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
2570926deccbSFrançois Tigeot 			   MICRO_TILE_MODE(ADDR_SURF_DEPTH_MICRO_TILING) |
2571926deccbSFrançois Tigeot 			   PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) |
2572926deccbSFrançois Tigeot 			   TILE_SPLIT(split_equal_to_row_size) |
2573926deccbSFrançois Tigeot 			   NUM_BANKS(ADDR_SURF_16_BANK) |
2574926deccbSFrançois Tigeot 			   BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
2575926deccbSFrançois Tigeot 			   BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) |
2576926deccbSFrançois Tigeot 			   MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2));
2577d78d3a22SFrançois Tigeot 		/* 1D and 1D Array Surfaces */
2578d78d3a22SFrançois Tigeot 		tile[8] = (ARRAY_MODE(ARRAY_LINEAR_ALIGNED) |
2579926deccbSFrançois Tigeot 			   MICRO_TILE_MODE(ADDR_SURF_DISPLAY_MICRO_TILING) |
2580926deccbSFrançois Tigeot 			   PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) |
2581926deccbSFrançois Tigeot 			   TILE_SPLIT(ADDR_SURF_TILE_SPLIT_64B) |
2582926deccbSFrançois Tigeot 			   NUM_BANKS(ADDR_SURF_16_BANK) |
2583926deccbSFrançois Tigeot 			   BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
2584926deccbSFrançois Tigeot 			   BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) |
2585926deccbSFrançois Tigeot 			   MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2));
2586d78d3a22SFrançois Tigeot 		/* Displayable maps. */
2587d78d3a22SFrançois Tigeot 		tile[9] = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) |
2588926deccbSFrançois Tigeot 			   MICRO_TILE_MODE(ADDR_SURF_DISPLAY_MICRO_TILING) |
2589926deccbSFrançois Tigeot 			   PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) |
2590926deccbSFrançois Tigeot 			   TILE_SPLIT(ADDR_SURF_TILE_SPLIT_64B) |
2591926deccbSFrançois Tigeot 			   NUM_BANKS(ADDR_SURF_16_BANK) |
2592926deccbSFrançois Tigeot 			   BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
2593926deccbSFrançois Tigeot 			   BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) |
2594926deccbSFrançois Tigeot 			   MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2));
2595d78d3a22SFrançois Tigeot 		/* Display 8bpp. */
2596d78d3a22SFrançois Tigeot 		tile[10] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
2597926deccbSFrançois Tigeot 			   MICRO_TILE_MODE(ADDR_SURF_DISPLAY_MICRO_TILING) |
2598926deccbSFrançois Tigeot 			   PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) |
2599926deccbSFrançois Tigeot 			   TILE_SPLIT(ADDR_SURF_TILE_SPLIT_256B) |
2600926deccbSFrançois Tigeot 			   NUM_BANKS(ADDR_SURF_16_BANK) |
2601926deccbSFrançois Tigeot 			   BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
2602926deccbSFrançois Tigeot 			   BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) |
2603926deccbSFrançois Tigeot 			   MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2));
2604d78d3a22SFrançois Tigeot 		/* Display 16bpp. */
2605d78d3a22SFrançois Tigeot 		tile[11] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
2606926deccbSFrançois Tigeot 			   MICRO_TILE_MODE(ADDR_SURF_DISPLAY_MICRO_TILING) |
2607926deccbSFrançois Tigeot 			   PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) |
2608926deccbSFrançois Tigeot 			   TILE_SPLIT(ADDR_SURF_TILE_SPLIT_256B) |
2609926deccbSFrançois Tigeot 			   NUM_BANKS(ADDR_SURF_16_BANK) |
2610926deccbSFrançois Tigeot 			   BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
2611926deccbSFrançois Tigeot 			   BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) |
2612926deccbSFrançois Tigeot 			   MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2));
2613d78d3a22SFrançois Tigeot 		/* Display 32bpp. */
2614d78d3a22SFrançois Tigeot 		tile[12] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
2615926deccbSFrançois Tigeot 			   MICRO_TILE_MODE(ADDR_SURF_DISPLAY_MICRO_TILING) |
2616926deccbSFrançois Tigeot 			   PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) |
2617926deccbSFrançois Tigeot 			   TILE_SPLIT(ADDR_SURF_TILE_SPLIT_512B) |
2618926deccbSFrançois Tigeot 			   NUM_BANKS(ADDR_SURF_16_BANK) |
2619926deccbSFrançois Tigeot 			   BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
2620926deccbSFrançois Tigeot 			   BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) |
2621926deccbSFrançois Tigeot 			   MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1));
2622d78d3a22SFrançois Tigeot 		/* Thin. */
2623d78d3a22SFrançois Tigeot 		tile[13] = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) |
2624926deccbSFrançois Tigeot 			   MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) |
2625926deccbSFrançois Tigeot 			   PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) |
2626926deccbSFrançois Tigeot 			   TILE_SPLIT(ADDR_SURF_TILE_SPLIT_64B) |
2627926deccbSFrançois Tigeot 			   NUM_BANKS(ADDR_SURF_16_BANK) |
2628926deccbSFrançois Tigeot 			   BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
2629926deccbSFrançois Tigeot 			   BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) |
2630926deccbSFrançois Tigeot 			   MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2));
2631d78d3a22SFrançois Tigeot 		/* Thin 8 bpp. */
2632d78d3a22SFrançois Tigeot 		tile[14] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
2633926deccbSFrançois Tigeot 			   MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) |
2634926deccbSFrançois Tigeot 			   PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) |
2635926deccbSFrançois Tigeot 			   TILE_SPLIT(ADDR_SURF_TILE_SPLIT_256B) |
2636926deccbSFrançois Tigeot 			   NUM_BANKS(ADDR_SURF_16_BANK) |
2637926deccbSFrançois Tigeot 			   BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
2638926deccbSFrançois Tigeot 			   BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) |
2639926deccbSFrançois Tigeot 			   MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1));
2640d78d3a22SFrançois Tigeot 		/* Thin 16 bpp. */
2641d78d3a22SFrançois Tigeot 		tile[15] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
2642926deccbSFrançois Tigeot 			   MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) |
2643926deccbSFrançois Tigeot 			   PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) |
2644926deccbSFrançois Tigeot 			   TILE_SPLIT(ADDR_SURF_TILE_SPLIT_256B) |
2645926deccbSFrançois Tigeot 			   NUM_BANKS(ADDR_SURF_16_BANK) |
2646926deccbSFrançois Tigeot 			   BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
2647926deccbSFrançois Tigeot 			   BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) |
2648926deccbSFrançois Tigeot 			   MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1));
2649d78d3a22SFrançois Tigeot 		/* Thin 32 bpp. */
2650d78d3a22SFrançois Tigeot 		tile[16] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
2651926deccbSFrançois Tigeot 			   MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) |
2652926deccbSFrançois Tigeot 			   PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) |
2653926deccbSFrançois Tigeot 			   TILE_SPLIT(ADDR_SURF_TILE_SPLIT_512B) |
2654926deccbSFrançois Tigeot 			   NUM_BANKS(ADDR_SURF_16_BANK) |
2655926deccbSFrançois Tigeot 			   BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
2656926deccbSFrançois Tigeot 			   BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) |
2657926deccbSFrançois Tigeot 			   MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1));
2658d78d3a22SFrançois Tigeot 		/* Thin 64 bpp. */
2659d78d3a22SFrançois Tigeot 		tile[17] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
2660926deccbSFrançois Tigeot 			   MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) |
2661926deccbSFrançois Tigeot 			   PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) |
2662926deccbSFrançois Tigeot 			   TILE_SPLIT(split_equal_to_row_size) |
2663926deccbSFrançois Tigeot 			   NUM_BANKS(ADDR_SURF_16_BANK) |
2664926deccbSFrançois Tigeot 			   BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
2665926deccbSFrançois Tigeot 			   BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) |
2666926deccbSFrançois Tigeot 			   MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1));
2667d78d3a22SFrançois Tigeot 		/* 8 bpp PRT. */
2668d78d3a22SFrançois Tigeot 		tile[21] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
2669926deccbSFrançois Tigeot 			   MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) |
2670926deccbSFrançois Tigeot 			   PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) |
2671926deccbSFrançois Tigeot 			   TILE_SPLIT(ADDR_SURF_TILE_SPLIT_256B) |
2672926deccbSFrançois Tigeot 			   NUM_BANKS(ADDR_SURF_16_BANK) |
2673926deccbSFrançois Tigeot 			   BANK_WIDTH(ADDR_SURF_BANK_WIDTH_2) |
2674926deccbSFrançois Tigeot 			   BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) |
2675926deccbSFrançois Tigeot 			   MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2));
2676d78d3a22SFrançois Tigeot 		/* 16 bpp PRT */
2677d78d3a22SFrançois Tigeot 		tile[22] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
2678926deccbSFrançois Tigeot 			   MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) |
2679926deccbSFrançois Tigeot 			   PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) |
2680926deccbSFrançois Tigeot 			   TILE_SPLIT(ADDR_SURF_TILE_SPLIT_256B) |
2681926deccbSFrançois Tigeot 			   NUM_BANKS(ADDR_SURF_16_BANK) |
2682926deccbSFrançois Tigeot 			   BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
2683926deccbSFrançois Tigeot 			   BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) |
2684926deccbSFrançois Tigeot 			   MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4));
2685d78d3a22SFrançois Tigeot 		/* 32 bpp PRT */
2686d78d3a22SFrançois Tigeot 		tile[23] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
2687926deccbSFrançois Tigeot 			   MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) |
2688926deccbSFrançois Tigeot 			   PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) |
2689926deccbSFrançois Tigeot 			   TILE_SPLIT(ADDR_SURF_TILE_SPLIT_256B) |
2690926deccbSFrançois Tigeot 			   NUM_BANKS(ADDR_SURF_16_BANK) |
2691926deccbSFrançois Tigeot 			   BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
2692926deccbSFrançois Tigeot 			   BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) |
2693926deccbSFrançois Tigeot 			   MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2));
2694d78d3a22SFrançois Tigeot 		/* 64 bpp PRT */
2695d78d3a22SFrançois Tigeot 		tile[24] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
2696926deccbSFrançois Tigeot 			   MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) |
2697926deccbSFrançois Tigeot 			   PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) |
2698926deccbSFrançois Tigeot 			   TILE_SPLIT(ADDR_SURF_TILE_SPLIT_512B) |
2699926deccbSFrançois Tigeot 			   NUM_BANKS(ADDR_SURF_16_BANK) |
2700926deccbSFrançois Tigeot 			   BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
2701926deccbSFrançois Tigeot 			   BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) |
2702926deccbSFrançois Tigeot 			   MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2));
2703d78d3a22SFrançois Tigeot 		/* 128 bpp PRT */
2704d78d3a22SFrançois Tigeot 		tile[25] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
2705926deccbSFrançois Tigeot 			   MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) |
2706926deccbSFrançois Tigeot 			   PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) |
2707926deccbSFrançois Tigeot 			   TILE_SPLIT(ADDR_SURF_TILE_SPLIT_1KB) |
2708926deccbSFrançois Tigeot 			   NUM_BANKS(ADDR_SURF_8_BANK) |
2709926deccbSFrançois Tigeot 			   BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
2710926deccbSFrançois Tigeot 			   BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) |
2711926deccbSFrançois Tigeot 			   MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1));
2712d78d3a22SFrançois Tigeot 
2713d78d3a22SFrançois Tigeot 		for (reg_offset = 0; reg_offset < num_tile_mode_states; reg_offset++)
2714d78d3a22SFrançois Tigeot 			WREG32(GB_TILE_MODE0 + (reg_offset * 4), tile[reg_offset]);
2715926deccbSFrançois Tigeot 		break;
2716d78d3a22SFrançois Tigeot 
2717d78d3a22SFrançois Tigeot 	case CHIP_VERDE:
2718d78d3a22SFrançois Tigeot 	case CHIP_OLAND:
2719d78d3a22SFrançois Tigeot 	case CHIP_HAINAN:
2720d78d3a22SFrançois Tigeot 		/* non-AA compressed depth or any compressed stencil */
2721d78d3a22SFrançois Tigeot 		tile[0] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
2722ee479021SImre Vadász 			   MICRO_TILE_MODE(ADDR_SURF_DEPTH_MICRO_TILING) |
2723ee479021SImre Vadász 			   PIPE_CONFIG(ADDR_SURF_P4_8x16) |
2724ee479021SImre Vadász 			   TILE_SPLIT(ADDR_SURF_TILE_SPLIT_64B) |
2725ee479021SImre Vadász 			   NUM_BANKS(ADDR_SURF_16_BANK) |
2726ee479021SImre Vadász 			   BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
2727ee479021SImre Vadász 			   BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) |
2728ee479021SImre Vadász 			   MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4));
2729d78d3a22SFrançois Tigeot 		/* 2xAA/4xAA compressed depth only */
2730d78d3a22SFrançois Tigeot 		tile[1] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
2731ee479021SImre Vadász 			   MICRO_TILE_MODE(ADDR_SURF_DEPTH_MICRO_TILING) |
2732ee479021SImre Vadász 			   PIPE_CONFIG(ADDR_SURF_P4_8x16) |
2733ee479021SImre Vadász 			   TILE_SPLIT(ADDR_SURF_TILE_SPLIT_128B) |
2734ee479021SImre Vadász 			   NUM_BANKS(ADDR_SURF_16_BANK) |
2735ee479021SImre Vadász 			   BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
2736ee479021SImre Vadász 			   BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) |
2737ee479021SImre Vadász 			   MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4));
2738d78d3a22SFrançois Tigeot 		/* 8xAA compressed depth only */
2739d78d3a22SFrançois Tigeot 		tile[2] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
2740ee479021SImre Vadász 			   MICRO_TILE_MODE(ADDR_SURF_DEPTH_MICRO_TILING) |
2741ee479021SImre Vadász 			   PIPE_CONFIG(ADDR_SURF_P4_8x16) |
2742ee479021SImre Vadász 			   TILE_SPLIT(ADDR_SURF_TILE_SPLIT_256B) |
2743ee479021SImre Vadász 			   NUM_BANKS(ADDR_SURF_16_BANK) |
2744ee479021SImre Vadász 			   BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
2745ee479021SImre Vadász 			   BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) |
2746ee479021SImre Vadász 			   MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4));
2747d78d3a22SFrançois Tigeot 		/* 2xAA/4xAA compressed depth with stencil (for depth buffer) */
2748d78d3a22SFrançois Tigeot 		tile[3] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
2749ee479021SImre Vadász 			   MICRO_TILE_MODE(ADDR_SURF_DEPTH_MICRO_TILING) |
2750ee479021SImre Vadász 			   PIPE_CONFIG(ADDR_SURF_P4_8x16) |
2751ee479021SImre Vadász 			   TILE_SPLIT(ADDR_SURF_TILE_SPLIT_128B) |
2752ee479021SImre Vadász 			   NUM_BANKS(ADDR_SURF_16_BANK) |
2753ee479021SImre Vadász 			   BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
2754ee479021SImre Vadász 			   BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) |
2755ee479021SImre Vadász 			   MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4));
2756d78d3a22SFrançois Tigeot 		/* Maps w/ a dimension less than the 2D macro-tile dimensions (for mipmapped depth textures) */
2757d78d3a22SFrançois Tigeot 		tile[4] = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) |
2758ee479021SImre Vadász 			   MICRO_TILE_MODE(ADDR_SURF_DEPTH_MICRO_TILING) |
2759ee479021SImre Vadász 			   PIPE_CONFIG(ADDR_SURF_P4_8x16) |
2760ee479021SImre Vadász 			   TILE_SPLIT(ADDR_SURF_TILE_SPLIT_64B) |
2761ee479021SImre Vadász 			   NUM_BANKS(ADDR_SURF_16_BANK) |
2762ee479021SImre Vadász 			   BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
2763ee479021SImre Vadász 			   BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) |
2764ee479021SImre Vadász 			   MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2));
2765d78d3a22SFrançois Tigeot 		/* Uncompressed 16bpp depth - and stencil buffer allocated with it */
2766d78d3a22SFrançois Tigeot 		tile[5] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
2767ee479021SImre Vadász 			   MICRO_TILE_MODE(ADDR_SURF_DEPTH_MICRO_TILING) |
2768ee479021SImre Vadász 			   PIPE_CONFIG(ADDR_SURF_P4_8x16) |
2769ee479021SImre Vadász 			   TILE_SPLIT(split_equal_to_row_size) |
2770ee479021SImre Vadász 			   NUM_BANKS(ADDR_SURF_16_BANK) |
2771ee479021SImre Vadász 			   BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
2772ee479021SImre Vadász 			   BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) |
2773ee479021SImre Vadász 			   MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2));
2774d78d3a22SFrançois Tigeot 		/* Uncompressed 32bpp depth - and stencil buffer allocated with it */
2775d78d3a22SFrançois Tigeot 		tile[6] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
2776ee479021SImre Vadász 			   MICRO_TILE_MODE(ADDR_SURF_DEPTH_MICRO_TILING) |
2777ee479021SImre Vadász 			   PIPE_CONFIG(ADDR_SURF_P4_8x16) |
2778ee479021SImre Vadász 			   TILE_SPLIT(split_equal_to_row_size) |
2779ee479021SImre Vadász 			   NUM_BANKS(ADDR_SURF_16_BANK) |
2780ee479021SImre Vadász 			   BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
2781ee479021SImre Vadász 			   BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) |
2782ee479021SImre Vadász 			   MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2));
2783d78d3a22SFrançois Tigeot 		/* Uncompressed 8bpp stencil without depth (drivers typically do not use) */
2784d78d3a22SFrançois Tigeot 		tile[7] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
2785ee479021SImre Vadász 			   MICRO_TILE_MODE(ADDR_SURF_DEPTH_MICRO_TILING) |
2786ee479021SImre Vadász 			   PIPE_CONFIG(ADDR_SURF_P4_8x16) |
2787ee479021SImre Vadász 			   TILE_SPLIT(split_equal_to_row_size) |
2788ee479021SImre Vadász 			   NUM_BANKS(ADDR_SURF_16_BANK) |
2789ee479021SImre Vadász 			   BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
2790ee479021SImre Vadász 			   BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) |
2791ee479021SImre Vadász 			   MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4));
2792d78d3a22SFrançois Tigeot 		/* 1D and 1D Array Surfaces */
2793d78d3a22SFrançois Tigeot 		tile[8] = (ARRAY_MODE(ARRAY_LINEAR_ALIGNED) |
2794ee479021SImre Vadász 			   MICRO_TILE_MODE(ADDR_SURF_DISPLAY_MICRO_TILING) |
2795ee479021SImre Vadász 			   PIPE_CONFIG(ADDR_SURF_P4_8x16) |
2796ee479021SImre Vadász 			   TILE_SPLIT(ADDR_SURF_TILE_SPLIT_64B) |
2797ee479021SImre Vadász 			   NUM_BANKS(ADDR_SURF_16_BANK) |
2798ee479021SImre Vadász 			   BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
2799ee479021SImre Vadász 			   BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) |
2800ee479021SImre Vadász 			   MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2));
2801d78d3a22SFrançois Tigeot 		/* Displayable maps. */
2802d78d3a22SFrançois Tigeot 		tile[9] = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) |
2803ee479021SImre Vadász 			   MICRO_TILE_MODE(ADDR_SURF_DISPLAY_MICRO_TILING) |
2804ee479021SImre Vadász 			   PIPE_CONFIG(ADDR_SURF_P4_8x16) |
2805ee479021SImre Vadász 			   TILE_SPLIT(ADDR_SURF_TILE_SPLIT_64B) |
2806ee479021SImre Vadász 			   NUM_BANKS(ADDR_SURF_16_BANK) |
2807ee479021SImre Vadász 			   BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
2808ee479021SImre Vadász 			   BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) |
2809ee479021SImre Vadász 			   MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2));
2810d78d3a22SFrançois Tigeot 		/* Display 8bpp. */
2811d78d3a22SFrançois Tigeot 		tile[10] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
2812ee479021SImre Vadász 			   MICRO_TILE_MODE(ADDR_SURF_DISPLAY_MICRO_TILING) |
2813ee479021SImre Vadász 			   PIPE_CONFIG(ADDR_SURF_P4_8x16) |
2814ee479021SImre Vadász 			   TILE_SPLIT(ADDR_SURF_TILE_SPLIT_256B) |
2815ee479021SImre Vadász 			   NUM_BANKS(ADDR_SURF_16_BANK) |
2816ee479021SImre Vadász 			   BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
2817ee479021SImre Vadász 			   BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) |
2818ee479021SImre Vadász 			   MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4));
2819d78d3a22SFrançois Tigeot 		/* Display 16bpp. */
2820d78d3a22SFrançois Tigeot 		tile[11] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
2821ee479021SImre Vadász 			   MICRO_TILE_MODE(ADDR_SURF_DISPLAY_MICRO_TILING) |
2822ee479021SImre Vadász 			   PIPE_CONFIG(ADDR_SURF_P4_8x16) |
2823ee479021SImre Vadász 			   TILE_SPLIT(ADDR_SURF_TILE_SPLIT_256B) |
2824ee479021SImre Vadász 			   NUM_BANKS(ADDR_SURF_16_BANK) |
2825ee479021SImre Vadász 			   BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
2826ee479021SImre Vadász 			   BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) |
2827ee479021SImre Vadász 			   MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2));
2828d78d3a22SFrançois Tigeot 		/* Display 32bpp. */
2829d78d3a22SFrançois Tigeot 		tile[12] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
2830ee479021SImre Vadász 			   MICRO_TILE_MODE(ADDR_SURF_DISPLAY_MICRO_TILING) |
2831ee479021SImre Vadász 			   PIPE_CONFIG(ADDR_SURF_P4_8x16) |
2832ee479021SImre Vadász 			   TILE_SPLIT(ADDR_SURF_TILE_SPLIT_512B) |
2833ee479021SImre Vadász 			   NUM_BANKS(ADDR_SURF_16_BANK) |
2834ee479021SImre Vadász 			   BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
2835ee479021SImre Vadász 			   BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) |
2836ee479021SImre Vadász 			   MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2));
2837d78d3a22SFrançois Tigeot 		/* Thin. */
2838d78d3a22SFrançois Tigeot 		tile[13] = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) |
2839ee479021SImre Vadász 			   MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) |
2840ee479021SImre Vadász 			   PIPE_CONFIG(ADDR_SURF_P4_8x16) |
2841ee479021SImre Vadász 			   TILE_SPLIT(ADDR_SURF_TILE_SPLIT_64B) |
2842ee479021SImre Vadász 			   NUM_BANKS(ADDR_SURF_16_BANK) |
2843ee479021SImre Vadász 			   BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
2844ee479021SImre Vadász 			   BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) |
2845ee479021SImre Vadász 			   MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2));
2846d78d3a22SFrançois Tigeot 		/* Thin 8 bpp. */
2847d78d3a22SFrançois Tigeot 		tile[14] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
2848ee479021SImre Vadász 			   MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) |
2849ee479021SImre Vadász 			   PIPE_CONFIG(ADDR_SURF_P4_8x16) |
2850ee479021SImre Vadász 			   TILE_SPLIT(ADDR_SURF_TILE_SPLIT_256B) |
2851ee479021SImre Vadász 			   NUM_BANKS(ADDR_SURF_16_BANK) |
2852ee479021SImre Vadász 			   BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
2853ee479021SImre Vadász 			   BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) |
2854ee479021SImre Vadász 			   MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2));
2855d78d3a22SFrançois Tigeot 		/* Thin 16 bpp. */
2856d78d3a22SFrançois Tigeot 		tile[15] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
2857ee479021SImre Vadász 			   MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) |
2858ee479021SImre Vadász 			   PIPE_CONFIG(ADDR_SURF_P4_8x16) |
2859ee479021SImre Vadász 			   TILE_SPLIT(ADDR_SURF_TILE_SPLIT_256B) |
2860ee479021SImre Vadász 			   NUM_BANKS(ADDR_SURF_16_BANK) |
2861ee479021SImre Vadász 			   BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
2862ee479021SImre Vadász 			   BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) |
2863ee479021SImre Vadász 			   MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2));
2864d78d3a22SFrançois Tigeot 		/* Thin 32 bpp. */
2865d78d3a22SFrançois Tigeot 		tile[16] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
2866ee479021SImre Vadász 			   MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) |
2867ee479021SImre Vadász 			   PIPE_CONFIG(ADDR_SURF_P4_8x16) |
2868ee479021SImre Vadász 			   TILE_SPLIT(ADDR_SURF_TILE_SPLIT_512B) |
2869ee479021SImre Vadász 			   NUM_BANKS(ADDR_SURF_16_BANK) |
2870ee479021SImre Vadász 			   BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
2871ee479021SImre Vadász 			   BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) |
2872ee479021SImre Vadász 			   MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2));
2873d78d3a22SFrançois Tigeot 		/* Thin 64 bpp. */
2874d78d3a22SFrançois Tigeot 		tile[17] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
2875ee479021SImre Vadász 			   MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) |
2876ee479021SImre Vadász 			   PIPE_CONFIG(ADDR_SURF_P4_8x16) |
2877ee479021SImre Vadász 			   TILE_SPLIT(split_equal_to_row_size) |
2878ee479021SImre Vadász 			   NUM_BANKS(ADDR_SURF_16_BANK) |
2879ee479021SImre Vadász 			   BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
2880ee479021SImre Vadász 			   BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) |
2881ee479021SImre Vadász 			   MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2));
2882d78d3a22SFrançois Tigeot 		/* 8 bpp PRT. */
2883d78d3a22SFrançois Tigeot 		tile[21] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
2884ee479021SImre Vadász 			   MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) |
2885ee479021SImre Vadász 			   PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) |
2886ee479021SImre Vadász 			   TILE_SPLIT(ADDR_SURF_TILE_SPLIT_256B) |
2887ee479021SImre Vadász 			   NUM_BANKS(ADDR_SURF_16_BANK) |
2888ee479021SImre Vadász 			   BANK_WIDTH(ADDR_SURF_BANK_WIDTH_2) |
2889ee479021SImre Vadász 			   BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) |
2890ee479021SImre Vadász 			   MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2));
2891d78d3a22SFrançois Tigeot 		/* 16 bpp PRT */
2892d78d3a22SFrançois Tigeot 		tile[22] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
2893ee479021SImre Vadász 			   MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) |
2894ee479021SImre Vadász 			   PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) |
2895ee479021SImre Vadász 			   TILE_SPLIT(ADDR_SURF_TILE_SPLIT_256B) |
2896ee479021SImre Vadász 			   NUM_BANKS(ADDR_SURF_16_BANK) |
2897ee479021SImre Vadász 			   BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
2898ee479021SImre Vadász 			   BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) |
2899ee479021SImre Vadász 			   MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4));
2900d78d3a22SFrançois Tigeot 		/* 32 bpp PRT */
2901d78d3a22SFrançois Tigeot 		tile[23] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
2902ee479021SImre Vadász 			   MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) |
2903ee479021SImre Vadász 			   PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) |
2904ee479021SImre Vadász 			   TILE_SPLIT(ADDR_SURF_TILE_SPLIT_256B) |
2905ee479021SImre Vadász 			   NUM_BANKS(ADDR_SURF_16_BANK) |
2906ee479021SImre Vadász 			   BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
2907ee479021SImre Vadász 			   BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) |
2908ee479021SImre Vadász 			   MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2));
2909d78d3a22SFrançois Tigeot 		/* 64 bpp PRT */
2910d78d3a22SFrançois Tigeot 		tile[24] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
2911ee479021SImre Vadász 			   MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) |
2912ee479021SImre Vadász 			   PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) |
2913ee479021SImre Vadász 			   TILE_SPLIT(ADDR_SURF_TILE_SPLIT_512B) |
2914ee479021SImre Vadász 			   NUM_BANKS(ADDR_SURF_16_BANK) |
2915ee479021SImre Vadász 			   BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
2916ee479021SImre Vadász 			   BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) |
2917ee479021SImre Vadász 			   MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2));
2918d78d3a22SFrançois Tigeot 		/* 128 bpp PRT */
2919d78d3a22SFrançois Tigeot 		tile[25] = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
2920ee479021SImre Vadász 			   MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) |
2921ee479021SImre Vadász 			   PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) |
2922ee479021SImre Vadász 			   TILE_SPLIT(ADDR_SURF_TILE_SPLIT_1KB) |
2923ee479021SImre Vadász 			   NUM_BANKS(ADDR_SURF_8_BANK) |
2924ee479021SImre Vadász 			   BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
2925ee479021SImre Vadász 			   BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) |
2926ee479021SImre Vadász 			   MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1));
2927d78d3a22SFrançois Tigeot 
2928d78d3a22SFrançois Tigeot 		for (reg_offset = 0; reg_offset < num_tile_mode_states; reg_offset++)
2929d78d3a22SFrançois Tigeot 			WREG32(GB_TILE_MODE0 + (reg_offset * 4), tile[reg_offset]);
2930ee479021SImre Vadász 		break;
2931d78d3a22SFrançois Tigeot 
2932ee479021SImre Vadász 	default:
2933ee479021SImre Vadász 		DRM_ERROR("unknown asic: 0x%x\n", rdev->family);
2934a7a95252SDavid Shao 	}
2935d78d3a22SFrançois Tigeot }
2936926deccbSFrançois Tigeot 
si_select_se_sh(struct radeon_device * rdev,u32 se_num,u32 sh_num)2937926deccbSFrançois Tigeot static void si_select_se_sh(struct radeon_device *rdev,
2938926deccbSFrançois Tigeot 			    u32 se_num, u32 sh_num)
2939926deccbSFrançois Tigeot {
2940926deccbSFrançois Tigeot 	u32 data = INSTANCE_BROADCAST_WRITES;
2941926deccbSFrançois Tigeot 
2942926deccbSFrançois Tigeot 	if ((se_num == 0xffffffff) && (sh_num == 0xffffffff))
2943f43cf1b1SMichael Neumann 		data |= SH_BROADCAST_WRITES | SE_BROADCAST_WRITES;
2944926deccbSFrançois Tigeot 	else if (se_num == 0xffffffff)
2945926deccbSFrançois Tigeot 		data |= SE_BROADCAST_WRITES | SH_INDEX(sh_num);
2946926deccbSFrançois Tigeot 	else if (sh_num == 0xffffffff)
2947926deccbSFrançois Tigeot 		data |= SH_BROADCAST_WRITES | SE_INDEX(se_num);
2948926deccbSFrançois Tigeot 	else
2949926deccbSFrançois Tigeot 		data |= SH_INDEX(sh_num) | SE_INDEX(se_num);
2950926deccbSFrançois Tigeot 	WREG32(GRBM_GFX_INDEX, data);
2951926deccbSFrançois Tigeot }
2952926deccbSFrançois Tigeot 
si_create_bitmask(u32 bit_width)2953926deccbSFrançois Tigeot static u32 si_create_bitmask(u32 bit_width)
2954926deccbSFrançois Tigeot {
2955926deccbSFrançois Tigeot 	u32 i, mask = 0;
2956926deccbSFrançois Tigeot 
2957926deccbSFrançois Tigeot 	for (i = 0; i < bit_width; i++) {
2958926deccbSFrançois Tigeot 		mask <<= 1;
2959926deccbSFrançois Tigeot 		mask |= 1;
2960926deccbSFrançois Tigeot 	}
2961926deccbSFrançois Tigeot 	return mask;
2962926deccbSFrançois Tigeot }
2963926deccbSFrançois Tigeot 
si_get_cu_enabled(struct radeon_device * rdev,u32 cu_per_sh)2964926deccbSFrançois Tigeot static u32 si_get_cu_enabled(struct radeon_device *rdev, u32 cu_per_sh)
2965926deccbSFrançois Tigeot {
2966926deccbSFrançois Tigeot 	u32 data, mask;
2967926deccbSFrançois Tigeot 
2968926deccbSFrançois Tigeot 	data = RREG32(CC_GC_SHADER_ARRAY_CONFIG);
2969926deccbSFrançois Tigeot 	if (data & 1)
2970926deccbSFrançois Tigeot 		data &= INACTIVE_CUS_MASK;
2971926deccbSFrançois Tigeot 	else
2972926deccbSFrançois Tigeot 		data = 0;
2973926deccbSFrançois Tigeot 	data |= RREG32(GC_USER_SHADER_ARRAY_CONFIG);
2974926deccbSFrançois Tigeot 
2975926deccbSFrançois Tigeot 	data >>= INACTIVE_CUS_SHIFT;
2976926deccbSFrançois Tigeot 
2977926deccbSFrançois Tigeot 	mask = si_create_bitmask(cu_per_sh);
2978926deccbSFrançois Tigeot 
2979926deccbSFrançois Tigeot 	return ~data & mask;
2980926deccbSFrançois Tigeot }
2981926deccbSFrançois Tigeot 
si_setup_spi(struct radeon_device * rdev,u32 se_num,u32 sh_per_se,u32 cu_per_sh)2982926deccbSFrançois Tigeot static void si_setup_spi(struct radeon_device *rdev,
2983926deccbSFrançois Tigeot 			 u32 se_num, u32 sh_per_se,
2984926deccbSFrançois Tigeot 			 u32 cu_per_sh)
2985926deccbSFrançois Tigeot {
2986926deccbSFrançois Tigeot 	int i, j, k;
2987926deccbSFrançois Tigeot 	u32 data, mask, active_cu;
2988926deccbSFrançois Tigeot 
2989926deccbSFrançois Tigeot 	for (i = 0; i < se_num; i++) {
2990926deccbSFrançois Tigeot 		for (j = 0; j < sh_per_se; j++) {
2991926deccbSFrançois Tigeot 			si_select_se_sh(rdev, i, j);
2992926deccbSFrançois Tigeot 			data = RREG32(SPI_STATIC_THREAD_MGMT_3);
2993926deccbSFrançois Tigeot 			active_cu = si_get_cu_enabled(rdev, cu_per_sh);
2994926deccbSFrançois Tigeot 
2995926deccbSFrançois Tigeot 			mask = 1;
2996926deccbSFrançois Tigeot 			for (k = 0; k < 16; k++) {
2997926deccbSFrançois Tigeot 				mask <<= k;
2998926deccbSFrançois Tigeot 				if (active_cu & mask) {
2999926deccbSFrançois Tigeot 					data &= ~mask;
3000926deccbSFrançois Tigeot 					WREG32(SPI_STATIC_THREAD_MGMT_3, data);
3001926deccbSFrançois Tigeot 					break;
3002926deccbSFrançois Tigeot 				}
3003926deccbSFrançois Tigeot 			}
3004926deccbSFrançois Tigeot 		}
3005926deccbSFrançois Tigeot 	}
3006926deccbSFrançois Tigeot 	si_select_se_sh(rdev, 0xffffffff, 0xffffffff);
3007926deccbSFrançois Tigeot }
3008926deccbSFrançois Tigeot 
si_get_rb_disabled(struct radeon_device * rdev,u32 max_rb_num_per_se,u32 sh_per_se)3009926deccbSFrançois Tigeot static u32 si_get_rb_disabled(struct radeon_device *rdev,
3010c6f73aabSFrançois Tigeot 			      u32 max_rb_num_per_se,
3011926deccbSFrançois Tigeot 			      u32 sh_per_se)
3012926deccbSFrançois Tigeot {
3013926deccbSFrançois Tigeot 	u32 data, mask;
3014926deccbSFrançois Tigeot 
3015926deccbSFrançois Tigeot 	data = RREG32(CC_RB_BACKEND_DISABLE);
3016926deccbSFrançois Tigeot 	if (data & 1)
3017926deccbSFrançois Tigeot 		data &= BACKEND_DISABLE_MASK;
3018926deccbSFrançois Tigeot 	else
3019926deccbSFrançois Tigeot 		data = 0;
3020926deccbSFrançois Tigeot 	data |= RREG32(GC_USER_RB_BACKEND_DISABLE);
3021926deccbSFrançois Tigeot 
3022926deccbSFrançois Tigeot 	data >>= BACKEND_DISABLE_SHIFT;
3023926deccbSFrançois Tigeot 
3024c6f73aabSFrançois Tigeot 	mask = si_create_bitmask(max_rb_num_per_se / sh_per_se);
3025926deccbSFrançois Tigeot 
3026926deccbSFrançois Tigeot 	return data & mask;
3027926deccbSFrançois Tigeot }
3028926deccbSFrançois Tigeot 
si_setup_rb(struct radeon_device * rdev,u32 se_num,u32 sh_per_se,u32 max_rb_num_per_se)3029926deccbSFrançois Tigeot static void si_setup_rb(struct radeon_device *rdev,
3030926deccbSFrançois Tigeot 			u32 se_num, u32 sh_per_se,
3031c6f73aabSFrançois Tigeot 			u32 max_rb_num_per_se)
3032926deccbSFrançois Tigeot {
3033926deccbSFrançois Tigeot 	int i, j;
3034926deccbSFrançois Tigeot 	u32 data, mask;
3035926deccbSFrançois Tigeot 	u32 disabled_rbs = 0;
3036926deccbSFrançois Tigeot 	u32 enabled_rbs = 0;
3037926deccbSFrançois Tigeot 
3038926deccbSFrançois Tigeot 	for (i = 0; i < se_num; i++) {
3039926deccbSFrançois Tigeot 		for (j = 0; j < sh_per_se; j++) {
3040926deccbSFrançois Tigeot 			si_select_se_sh(rdev, i, j);
3041c6f73aabSFrançois Tigeot 			data = si_get_rb_disabled(rdev, max_rb_num_per_se, sh_per_se);
3042926deccbSFrançois Tigeot 			disabled_rbs |= data << ((i * sh_per_se + j) * TAHITI_RB_BITMAP_WIDTH_PER_SH);
3043926deccbSFrançois Tigeot 		}
3044926deccbSFrançois Tigeot 	}
3045926deccbSFrançois Tigeot 	si_select_se_sh(rdev, 0xffffffff, 0xffffffff);
3046926deccbSFrançois Tigeot 
3047926deccbSFrançois Tigeot 	mask = 1;
3048c6f73aabSFrançois Tigeot 	for (i = 0; i < max_rb_num_per_se * se_num; i++) {
3049926deccbSFrançois Tigeot 		if (!(disabled_rbs & mask))
3050926deccbSFrançois Tigeot 			enabled_rbs |= mask;
3051926deccbSFrançois Tigeot 		mask <<= 1;
3052926deccbSFrançois Tigeot 	}
3053926deccbSFrançois Tigeot 
3054c6f73aabSFrançois Tigeot 	rdev->config.si.backend_enable_mask = enabled_rbs;
3055c6f73aabSFrançois Tigeot 
3056926deccbSFrançois Tigeot 	for (i = 0; i < se_num; i++) {
3057926deccbSFrançois Tigeot 		si_select_se_sh(rdev, i, 0xffffffff);
3058926deccbSFrançois Tigeot 		data = 0;
3059926deccbSFrançois Tigeot 		for (j = 0; j < sh_per_se; j++) {
3060926deccbSFrançois Tigeot 			switch (enabled_rbs & 3) {
3061926deccbSFrançois Tigeot 			case 1:
3062926deccbSFrançois Tigeot 				data |= (RASTER_CONFIG_RB_MAP_0 << (i * sh_per_se + j) * 2);
3063926deccbSFrançois Tigeot 				break;
3064926deccbSFrançois Tigeot 			case 2:
3065926deccbSFrançois Tigeot 				data |= (RASTER_CONFIG_RB_MAP_3 << (i * sh_per_se + j) * 2);
3066926deccbSFrançois Tigeot 				break;
3067926deccbSFrançois Tigeot 			case 3:
3068926deccbSFrançois Tigeot 			default:
3069926deccbSFrançois Tigeot 				data |= (RASTER_CONFIG_RB_MAP_2 << (i * sh_per_se + j) * 2);
3070926deccbSFrançois Tigeot 				break;
3071926deccbSFrançois Tigeot 			}
3072926deccbSFrançois Tigeot 			enabled_rbs >>= 2;
3073926deccbSFrançois Tigeot 		}
3074926deccbSFrançois Tigeot 		WREG32(PA_SC_RASTER_CONFIG, data);
3075926deccbSFrançois Tigeot 	}
3076926deccbSFrançois Tigeot 	si_select_se_sh(rdev, 0xffffffff, 0xffffffff);
3077926deccbSFrançois Tigeot }
3078926deccbSFrançois Tigeot 
si_gpu_init(struct radeon_device * rdev)3079926deccbSFrançois Tigeot static void si_gpu_init(struct radeon_device *rdev)
3080926deccbSFrançois Tigeot {
3081926deccbSFrançois Tigeot 	u32 gb_addr_config = 0;
3082926deccbSFrançois Tigeot 	u32 mc_shared_chmap, mc_arb_ramcfg;
3083926deccbSFrançois Tigeot 	u32 sx_debug_1;
3084926deccbSFrançois Tigeot 	u32 hdp_host_path_cntl;
3085926deccbSFrançois Tigeot 	u32 tmp;
3086926deccbSFrançois Tigeot 	int i, j;
3087926deccbSFrançois Tigeot 
3088926deccbSFrançois Tigeot 	switch (rdev->family) {
3089926deccbSFrançois Tigeot 	case CHIP_TAHITI:
3090926deccbSFrançois Tigeot 		rdev->config.si.max_shader_engines = 2;
3091926deccbSFrançois Tigeot 		rdev->config.si.max_tile_pipes = 12;
3092926deccbSFrançois Tigeot 		rdev->config.si.max_cu_per_sh = 8;
3093926deccbSFrançois Tigeot 		rdev->config.si.max_sh_per_se = 2;
3094926deccbSFrançois Tigeot 		rdev->config.si.max_backends_per_se = 4;
3095926deccbSFrançois Tigeot 		rdev->config.si.max_texture_channel_caches = 12;
3096926deccbSFrançois Tigeot 		rdev->config.si.max_gprs = 256;
3097926deccbSFrançois Tigeot 		rdev->config.si.max_gs_threads = 32;
3098926deccbSFrançois Tigeot 		rdev->config.si.max_hw_contexts = 8;
3099926deccbSFrançois Tigeot 
3100926deccbSFrançois Tigeot 		rdev->config.si.sc_prim_fifo_size_frontend = 0x20;
3101926deccbSFrançois Tigeot 		rdev->config.si.sc_prim_fifo_size_backend = 0x100;
3102926deccbSFrançois Tigeot 		rdev->config.si.sc_hiz_tile_fifo_size = 0x30;
3103926deccbSFrançois Tigeot 		rdev->config.si.sc_earlyz_tile_fifo_size = 0x130;
3104926deccbSFrançois Tigeot 		gb_addr_config = TAHITI_GB_ADDR_CONFIG_GOLDEN;
3105926deccbSFrançois Tigeot 		break;
3106926deccbSFrançois Tigeot 	case CHIP_PITCAIRN:
3107926deccbSFrançois Tigeot 		rdev->config.si.max_shader_engines = 2;
3108926deccbSFrançois Tigeot 		rdev->config.si.max_tile_pipes = 8;
3109926deccbSFrançois Tigeot 		rdev->config.si.max_cu_per_sh = 5;
3110926deccbSFrançois Tigeot 		rdev->config.si.max_sh_per_se = 2;
3111926deccbSFrançois Tigeot 		rdev->config.si.max_backends_per_se = 4;
3112926deccbSFrançois Tigeot 		rdev->config.si.max_texture_channel_caches = 8;
3113926deccbSFrançois Tigeot 		rdev->config.si.max_gprs = 256;
3114926deccbSFrançois Tigeot 		rdev->config.si.max_gs_threads = 32;
3115926deccbSFrançois Tigeot 		rdev->config.si.max_hw_contexts = 8;
3116926deccbSFrançois Tigeot 
3117926deccbSFrançois Tigeot 		rdev->config.si.sc_prim_fifo_size_frontend = 0x20;
3118926deccbSFrançois Tigeot 		rdev->config.si.sc_prim_fifo_size_backend = 0x100;
3119926deccbSFrançois Tigeot 		rdev->config.si.sc_hiz_tile_fifo_size = 0x30;
3120926deccbSFrançois Tigeot 		rdev->config.si.sc_earlyz_tile_fifo_size = 0x130;
3121926deccbSFrançois Tigeot 		gb_addr_config = TAHITI_GB_ADDR_CONFIG_GOLDEN;
3122926deccbSFrançois Tigeot 		break;
3123926deccbSFrançois Tigeot 	case CHIP_VERDE:
3124926deccbSFrançois Tigeot 	default:
3125926deccbSFrançois Tigeot 		rdev->config.si.max_shader_engines = 1;
3126926deccbSFrançois Tigeot 		rdev->config.si.max_tile_pipes = 4;
3127f43cf1b1SMichael Neumann 		rdev->config.si.max_cu_per_sh = 5;
3128926deccbSFrançois Tigeot 		rdev->config.si.max_sh_per_se = 2;
3129926deccbSFrançois Tigeot 		rdev->config.si.max_backends_per_se = 4;
3130926deccbSFrançois Tigeot 		rdev->config.si.max_texture_channel_caches = 4;
3131926deccbSFrançois Tigeot 		rdev->config.si.max_gprs = 256;
3132926deccbSFrançois Tigeot 		rdev->config.si.max_gs_threads = 32;
3133926deccbSFrançois Tigeot 		rdev->config.si.max_hw_contexts = 8;
3134926deccbSFrançois Tigeot 
3135926deccbSFrançois Tigeot 		rdev->config.si.sc_prim_fifo_size_frontend = 0x20;
3136926deccbSFrançois Tigeot 		rdev->config.si.sc_prim_fifo_size_backend = 0x40;
3137926deccbSFrançois Tigeot 		rdev->config.si.sc_hiz_tile_fifo_size = 0x30;
3138926deccbSFrançois Tigeot 		rdev->config.si.sc_earlyz_tile_fifo_size = 0x130;
3139926deccbSFrançois Tigeot 		gb_addr_config = VERDE_GB_ADDR_CONFIG_GOLDEN;
3140926deccbSFrançois Tigeot 		break;
3141b403bed8SMichael Neumann 	case CHIP_OLAND:
3142b403bed8SMichael Neumann 		rdev->config.si.max_shader_engines = 1;
3143b403bed8SMichael Neumann 		rdev->config.si.max_tile_pipes = 4;
3144b403bed8SMichael Neumann 		rdev->config.si.max_cu_per_sh = 6;
3145b403bed8SMichael Neumann 		rdev->config.si.max_sh_per_se = 1;
3146b403bed8SMichael Neumann 		rdev->config.si.max_backends_per_se = 2;
3147b403bed8SMichael Neumann 		rdev->config.si.max_texture_channel_caches = 4;
3148b403bed8SMichael Neumann 		rdev->config.si.max_gprs = 256;
3149b403bed8SMichael Neumann 		rdev->config.si.max_gs_threads = 16;
3150b403bed8SMichael Neumann 		rdev->config.si.max_hw_contexts = 8;
3151b403bed8SMichael Neumann 
3152b403bed8SMichael Neumann 		rdev->config.si.sc_prim_fifo_size_frontend = 0x20;
3153b403bed8SMichael Neumann 		rdev->config.si.sc_prim_fifo_size_backend = 0x40;
3154b403bed8SMichael Neumann 		rdev->config.si.sc_hiz_tile_fifo_size = 0x30;
3155b403bed8SMichael Neumann 		rdev->config.si.sc_earlyz_tile_fifo_size = 0x130;
3156b403bed8SMichael Neumann 		gb_addr_config = VERDE_GB_ADDR_CONFIG_GOLDEN;
3157b403bed8SMichael Neumann 		break;
3158f43cf1b1SMichael Neumann 	case CHIP_HAINAN:
3159f43cf1b1SMichael Neumann 		rdev->config.si.max_shader_engines = 1;
3160f43cf1b1SMichael Neumann 		rdev->config.si.max_tile_pipes = 4;
3161f43cf1b1SMichael Neumann 		rdev->config.si.max_cu_per_sh = 5;
3162f43cf1b1SMichael Neumann 		rdev->config.si.max_sh_per_se = 1;
3163f43cf1b1SMichael Neumann 		rdev->config.si.max_backends_per_se = 1;
3164f43cf1b1SMichael Neumann 		rdev->config.si.max_texture_channel_caches = 2;
3165f43cf1b1SMichael Neumann 		rdev->config.si.max_gprs = 256;
3166f43cf1b1SMichael Neumann 		rdev->config.si.max_gs_threads = 16;
3167f43cf1b1SMichael Neumann 		rdev->config.si.max_hw_contexts = 8;
3168f43cf1b1SMichael Neumann 
3169f43cf1b1SMichael Neumann 		rdev->config.si.sc_prim_fifo_size_frontend = 0x20;
3170f43cf1b1SMichael Neumann 		rdev->config.si.sc_prim_fifo_size_backend = 0x40;
3171f43cf1b1SMichael Neumann 		rdev->config.si.sc_hiz_tile_fifo_size = 0x30;
3172f43cf1b1SMichael Neumann 		rdev->config.si.sc_earlyz_tile_fifo_size = 0x130;
3173f43cf1b1SMichael Neumann 		gb_addr_config = HAINAN_GB_ADDR_CONFIG_GOLDEN;
3174f43cf1b1SMichael Neumann 		break;
3175926deccbSFrançois Tigeot 	}
3176926deccbSFrançois Tigeot 
3177926deccbSFrançois Tigeot 	/* Initialize HDP */
3178926deccbSFrançois Tigeot 	for (i = 0, j = 0; i < 32; i++, j += 0x18) {
3179926deccbSFrançois Tigeot 		WREG32((0x2c14 + j), 0x00000000);
3180926deccbSFrançois Tigeot 		WREG32((0x2c18 + j), 0x00000000);
3181926deccbSFrançois Tigeot 		WREG32((0x2c1c + j), 0x00000000);
3182926deccbSFrançois Tigeot 		WREG32((0x2c20 + j), 0x00000000);
3183926deccbSFrançois Tigeot 		WREG32((0x2c24 + j), 0x00000000);
3184926deccbSFrançois Tigeot 	}
3185926deccbSFrançois Tigeot 
3186926deccbSFrançois Tigeot 	WREG32(GRBM_CNTL, GRBM_READ_TIMEOUT(0xff));
3187c59a5c48SFrançois Tigeot 	WREG32(SRBM_INT_CNTL, 1);
3188c59a5c48SFrançois Tigeot 	WREG32(SRBM_INT_ACK, 1);
3189926deccbSFrançois Tigeot 
3190926deccbSFrançois Tigeot 	evergreen_fix_pci_max_read_req_size(rdev);
3191926deccbSFrançois Tigeot 
3192926deccbSFrançois Tigeot 	WREG32(BIF_FB_EN, FB_READ_EN | FB_WRITE_EN);
3193926deccbSFrançois Tigeot 
3194926deccbSFrançois Tigeot 	mc_shared_chmap = RREG32(MC_SHARED_CHMAP);
3195926deccbSFrançois Tigeot 	mc_arb_ramcfg = RREG32(MC_ARB_RAMCFG);
3196926deccbSFrançois Tigeot 
3197926deccbSFrançois Tigeot 	rdev->config.si.num_tile_pipes = rdev->config.si.max_tile_pipes;
3198926deccbSFrançois Tigeot 	rdev->config.si.mem_max_burst_length_bytes = 256;
3199926deccbSFrançois Tigeot 	tmp = (mc_arb_ramcfg & NOOFCOLS_MASK) >> NOOFCOLS_SHIFT;
3200926deccbSFrançois Tigeot 	rdev->config.si.mem_row_size_in_kb = (4 * (1 << (8 + tmp))) / 1024;
3201926deccbSFrançois Tigeot 	if (rdev->config.si.mem_row_size_in_kb > 4)
3202926deccbSFrançois Tigeot 		rdev->config.si.mem_row_size_in_kb = 4;
3203926deccbSFrançois Tigeot 	/* XXX use MC settings? */
3204926deccbSFrançois Tigeot 	rdev->config.si.shader_engine_tile_size = 32;
3205926deccbSFrançois Tigeot 	rdev->config.si.num_gpus = 1;
3206926deccbSFrançois Tigeot 	rdev->config.si.multi_gpu_tile_size = 64;
3207926deccbSFrançois Tigeot 
3208926deccbSFrançois Tigeot 	/* fix up row size */
3209926deccbSFrançois Tigeot 	gb_addr_config &= ~ROW_SIZE_MASK;
3210926deccbSFrançois Tigeot 	switch (rdev->config.si.mem_row_size_in_kb) {
3211926deccbSFrançois Tigeot 	case 1:
3212926deccbSFrançois Tigeot 	default:
3213926deccbSFrançois Tigeot 		gb_addr_config |= ROW_SIZE(0);
3214926deccbSFrançois Tigeot 		break;
3215926deccbSFrançois Tigeot 	case 2:
3216926deccbSFrançois Tigeot 		gb_addr_config |= ROW_SIZE(1);
3217926deccbSFrançois Tigeot 		break;
3218926deccbSFrançois Tigeot 	case 4:
3219926deccbSFrançois Tigeot 		gb_addr_config |= ROW_SIZE(2);
3220926deccbSFrançois Tigeot 		break;
3221926deccbSFrançois Tigeot 	}
3222926deccbSFrançois Tigeot 
3223926deccbSFrançois Tigeot 	/* setup tiling info dword.  gb_addr_config is not adequate since it does
3224926deccbSFrançois Tigeot 	 * not have bank info, so create a custom tiling dword.
3225926deccbSFrançois Tigeot 	 * bits 3:0   num_pipes
3226926deccbSFrançois Tigeot 	 * bits 7:4   num_banks
3227926deccbSFrançois Tigeot 	 * bits 11:8  group_size
3228926deccbSFrançois Tigeot 	 * bits 15:12 row_size
3229926deccbSFrançois Tigeot 	 */
3230926deccbSFrançois Tigeot 	rdev->config.si.tile_config = 0;
3231926deccbSFrançois Tigeot 	switch (rdev->config.si.num_tile_pipes) {
3232926deccbSFrançois Tigeot 	case 1:
3233926deccbSFrançois Tigeot 		rdev->config.si.tile_config |= (0 << 0);
3234926deccbSFrançois Tigeot 		break;
3235926deccbSFrançois Tigeot 	case 2:
3236926deccbSFrançois Tigeot 		rdev->config.si.tile_config |= (1 << 0);
3237926deccbSFrançois Tigeot 		break;
3238926deccbSFrançois Tigeot 	case 4:
3239926deccbSFrançois Tigeot 		rdev->config.si.tile_config |= (2 << 0);
3240926deccbSFrançois Tigeot 		break;
3241926deccbSFrançois Tigeot 	case 8:
3242926deccbSFrançois Tigeot 	default:
3243926deccbSFrançois Tigeot 		/* XXX what about 12? */
3244926deccbSFrançois Tigeot 		rdev->config.si.tile_config |= (3 << 0);
3245926deccbSFrançois Tigeot 		break;
3246926deccbSFrançois Tigeot 	}
3247926deccbSFrançois Tigeot 	switch ((mc_arb_ramcfg & NOOFBANK_MASK) >> NOOFBANK_SHIFT) {
3248926deccbSFrançois Tigeot 	case 0: /* four banks */
3249926deccbSFrançois Tigeot 		rdev->config.si.tile_config |= 0 << 4;
3250926deccbSFrançois Tigeot 		break;
3251926deccbSFrançois Tigeot 	case 1: /* eight banks */
3252926deccbSFrançois Tigeot 		rdev->config.si.tile_config |= 1 << 4;
3253926deccbSFrançois Tigeot 		break;
3254926deccbSFrançois Tigeot 	case 2: /* sixteen banks */
3255926deccbSFrançois Tigeot 	default:
3256926deccbSFrançois Tigeot 		rdev->config.si.tile_config |= 2 << 4;
3257926deccbSFrançois Tigeot 		break;
3258926deccbSFrançois Tigeot 	}
3259926deccbSFrançois Tigeot 	rdev->config.si.tile_config |=
3260926deccbSFrançois Tigeot 		((gb_addr_config & PIPE_INTERLEAVE_SIZE_MASK) >> PIPE_INTERLEAVE_SIZE_SHIFT) << 8;
3261926deccbSFrançois Tigeot 	rdev->config.si.tile_config |=
3262926deccbSFrançois Tigeot 		((gb_addr_config & ROW_SIZE_MASK) >> ROW_SIZE_SHIFT) << 12;
3263926deccbSFrançois Tigeot 
3264926deccbSFrançois Tigeot 	WREG32(GB_ADDR_CONFIG, gb_addr_config);
3265926deccbSFrançois Tigeot 	WREG32(DMIF_ADDR_CONFIG, gb_addr_config);
3266f43cf1b1SMichael Neumann 	WREG32(DMIF_ADDR_CALC, gb_addr_config);
3267926deccbSFrançois Tigeot 	WREG32(HDP_ADDR_CONFIG, gb_addr_config);
3268926deccbSFrançois Tigeot 	WREG32(DMA_TILING_CONFIG + DMA0_REGISTER_OFFSET, gb_addr_config);
3269926deccbSFrançois Tigeot 	WREG32(DMA_TILING_CONFIG + DMA1_REGISTER_OFFSET, gb_addr_config);
3270f43cf1b1SMichael Neumann 	if (rdev->has_uvd) {
3271f43cf1b1SMichael Neumann 		WREG32(UVD_UDEC_ADDR_CONFIG, gb_addr_config);
3272f43cf1b1SMichael Neumann 		WREG32(UVD_UDEC_DB_ADDR_CONFIG, gb_addr_config);
3273f43cf1b1SMichael Neumann 		WREG32(UVD_UDEC_DBW_ADDR_CONFIG, gb_addr_config);
3274f43cf1b1SMichael Neumann 	}
3275926deccbSFrançois Tigeot 
3276926deccbSFrançois Tigeot 	si_tiling_mode_table_init(rdev);
3277926deccbSFrançois Tigeot 
3278926deccbSFrançois Tigeot 	si_setup_rb(rdev, rdev->config.si.max_shader_engines,
3279926deccbSFrançois Tigeot 		    rdev->config.si.max_sh_per_se,
3280926deccbSFrançois Tigeot 		    rdev->config.si.max_backends_per_se);
3281926deccbSFrançois Tigeot 
3282926deccbSFrançois Tigeot 	si_setup_spi(rdev, rdev->config.si.max_shader_engines,
3283926deccbSFrançois Tigeot 		     rdev->config.si.max_sh_per_se,
3284926deccbSFrançois Tigeot 		     rdev->config.si.max_cu_per_sh);
3285926deccbSFrançois Tigeot 
3286c6f73aabSFrançois Tigeot 	rdev->config.si.active_cus = 0;
3287c6f73aabSFrançois Tigeot 	for (i = 0; i < rdev->config.si.max_shader_engines; i++) {
3288c6f73aabSFrançois Tigeot 		for (j = 0; j < rdev->config.si.max_sh_per_se; j++) {
3289c6f73aabSFrançois Tigeot 			rdev->config.si.active_cus +=
3290c6f73aabSFrançois Tigeot 				hweight32(si_get_cu_active_bitmap(rdev, i, j));
3291c6f73aabSFrançois Tigeot 		}
3292c6f73aabSFrançois Tigeot 	}
3293926deccbSFrançois Tigeot 
3294926deccbSFrançois Tigeot 	/* set HW defaults for 3D engine */
3295926deccbSFrançois Tigeot 	WREG32(CP_QUEUE_THRESHOLDS, (ROQ_IB1_START(0x16) |
3296926deccbSFrançois Tigeot 				     ROQ_IB2_START(0x2b)));
3297926deccbSFrançois Tigeot 	WREG32(CP_MEQ_THRESHOLDS, MEQ1_START(0x30) | MEQ2_START(0x60));
3298926deccbSFrançois Tigeot 
3299926deccbSFrançois Tigeot 	sx_debug_1 = RREG32(SX_DEBUG_1);
3300926deccbSFrançois Tigeot 	WREG32(SX_DEBUG_1, sx_debug_1);
3301926deccbSFrançois Tigeot 
3302926deccbSFrançois Tigeot 	WREG32(SPI_CONFIG_CNTL_1, VTX_DONE_DELAY(4));
3303926deccbSFrançois Tigeot 
3304926deccbSFrançois Tigeot 	WREG32(PA_SC_FIFO_SIZE, (SC_FRONTEND_PRIM_FIFO_SIZE(rdev->config.si.sc_prim_fifo_size_frontend) |
3305926deccbSFrançois Tigeot 				 SC_BACKEND_PRIM_FIFO_SIZE(rdev->config.si.sc_prim_fifo_size_backend) |
3306926deccbSFrançois Tigeot 				 SC_HIZ_TILE_FIFO_SIZE(rdev->config.si.sc_hiz_tile_fifo_size) |
3307926deccbSFrançois Tigeot 				 SC_EARLYZ_TILE_FIFO_SIZE(rdev->config.si.sc_earlyz_tile_fifo_size)));
3308926deccbSFrançois Tigeot 
3309926deccbSFrançois Tigeot 	WREG32(VGT_NUM_INSTANCES, 1);
3310926deccbSFrançois Tigeot 
3311926deccbSFrançois Tigeot 	WREG32(CP_PERFMON_CNTL, 0);
3312926deccbSFrançois Tigeot 
3313926deccbSFrançois Tigeot 	WREG32(SQ_CONFIG, 0);
3314926deccbSFrançois Tigeot 
3315926deccbSFrançois Tigeot 	WREG32(PA_SC_FORCE_EOV_MAX_CNTS, (FORCE_EOV_MAX_CLK_CNT(4095) |
3316926deccbSFrançois Tigeot 					  FORCE_EOV_MAX_REZ_CNT(255)));
3317926deccbSFrançois Tigeot 
3318926deccbSFrançois Tigeot 	WREG32(VGT_CACHE_INVALIDATION, CACHE_INVALIDATION(VC_AND_TC) |
3319926deccbSFrançois Tigeot 	       AUTO_INVLD_EN(ES_AND_GS_AUTO));
3320926deccbSFrançois Tigeot 
3321926deccbSFrançois Tigeot 	WREG32(VGT_GS_VERTEX_REUSE, 16);
3322926deccbSFrançois Tigeot 	WREG32(PA_SC_LINE_STIPPLE_STATE, 0);
3323926deccbSFrançois Tigeot 
3324926deccbSFrançois Tigeot 	WREG32(CB_PERFCOUNTER0_SELECT0, 0);
3325926deccbSFrançois Tigeot 	WREG32(CB_PERFCOUNTER0_SELECT1, 0);
3326926deccbSFrançois Tigeot 	WREG32(CB_PERFCOUNTER1_SELECT0, 0);
3327926deccbSFrançois Tigeot 	WREG32(CB_PERFCOUNTER1_SELECT1, 0);
3328926deccbSFrançois Tigeot 	WREG32(CB_PERFCOUNTER2_SELECT0, 0);
3329926deccbSFrançois Tigeot 	WREG32(CB_PERFCOUNTER2_SELECT1, 0);
3330926deccbSFrançois Tigeot 	WREG32(CB_PERFCOUNTER3_SELECT0, 0);
3331926deccbSFrançois Tigeot 	WREG32(CB_PERFCOUNTER3_SELECT1, 0);
3332926deccbSFrançois Tigeot 
3333926deccbSFrançois Tigeot 	tmp = RREG32(HDP_MISC_CNTL);
3334926deccbSFrançois Tigeot 	tmp |= HDP_FLUSH_INVALIDATE_CACHE;
3335926deccbSFrançois Tigeot 	WREG32(HDP_MISC_CNTL, tmp);
3336926deccbSFrançois Tigeot 
3337926deccbSFrançois Tigeot 	hdp_host_path_cntl = RREG32(HDP_HOST_PATH_CNTL);
3338926deccbSFrançois Tigeot 	WREG32(HDP_HOST_PATH_CNTL, hdp_host_path_cntl);
3339926deccbSFrançois Tigeot 
3340926deccbSFrançois Tigeot 	WREG32(PA_CL_ENHANCE, CLIP_VTX_REORDER_ENA | NUM_CLIP_SEQ(3));
3341926deccbSFrançois Tigeot 
3342c4ef309bSzrj 	udelay(50);
3343926deccbSFrançois Tigeot }
3344926deccbSFrançois Tigeot 
3345926deccbSFrançois Tigeot /*
3346926deccbSFrançois Tigeot  * GPU scratch registers helpers function.
3347926deccbSFrançois Tigeot  */
si_scratch_init(struct radeon_device * rdev)3348926deccbSFrançois Tigeot static void si_scratch_init(struct radeon_device *rdev)
3349926deccbSFrançois Tigeot {
3350926deccbSFrançois Tigeot 	int i;
3351926deccbSFrançois Tigeot 
3352926deccbSFrançois Tigeot 	rdev->scratch.num_reg = 7;
3353926deccbSFrançois Tigeot 	rdev->scratch.reg_base = SCRATCH_REG0;
3354926deccbSFrançois Tigeot 	for (i = 0; i < rdev->scratch.num_reg; i++) {
3355926deccbSFrançois Tigeot 		rdev->scratch.free[i] = true;
3356926deccbSFrançois Tigeot 		rdev->scratch.reg[i] = rdev->scratch.reg_base + (i * 4);
3357926deccbSFrançois Tigeot 	}
3358926deccbSFrançois Tigeot }
3359926deccbSFrançois Tigeot 
si_fence_ring_emit(struct radeon_device * rdev,struct radeon_fence * fence)3360926deccbSFrançois Tigeot void si_fence_ring_emit(struct radeon_device *rdev,
3361926deccbSFrançois Tigeot 			struct radeon_fence *fence)
3362926deccbSFrançois Tigeot {
3363926deccbSFrançois Tigeot 	struct radeon_ring *ring = &rdev->ring[fence->ring];
3364926deccbSFrançois Tigeot 	u64 addr = rdev->fence_drv[fence->ring].gpu_addr;
3365926deccbSFrançois Tigeot 
3366926deccbSFrançois Tigeot 	/* flush read cache over gart */
3367926deccbSFrançois Tigeot 	radeon_ring_write(ring, PACKET3(PACKET3_SET_CONFIG_REG, 1));
3368926deccbSFrançois Tigeot 	radeon_ring_write(ring, (CP_COHER_CNTL2 - PACKET3_SET_CONFIG_REG_START) >> 2);
3369926deccbSFrançois Tigeot 	radeon_ring_write(ring, 0);
3370926deccbSFrançois Tigeot 	radeon_ring_write(ring, PACKET3(PACKET3_SURFACE_SYNC, 3));
3371926deccbSFrançois Tigeot 	radeon_ring_write(ring, PACKET3_TCL1_ACTION_ENA |
3372926deccbSFrançois Tigeot 			  PACKET3_TC_ACTION_ENA |
3373926deccbSFrançois Tigeot 			  PACKET3_SH_KCACHE_ACTION_ENA |
3374926deccbSFrançois Tigeot 			  PACKET3_SH_ICACHE_ACTION_ENA);
3375926deccbSFrançois Tigeot 	radeon_ring_write(ring, 0xFFFFFFFF);
3376926deccbSFrançois Tigeot 	radeon_ring_write(ring, 0);
3377926deccbSFrançois Tigeot 	radeon_ring_write(ring, 10); /* poll interval */
3378926deccbSFrançois Tigeot 	/* EVENT_WRITE_EOP - flush caches, send int */
3379926deccbSFrançois Tigeot 	radeon_ring_write(ring, PACKET3(PACKET3_EVENT_WRITE_EOP, 4));
3380926deccbSFrançois Tigeot 	radeon_ring_write(ring, EVENT_TYPE(CACHE_FLUSH_AND_INV_TS_EVENT) | EVENT_INDEX(5));
3381c6f73aabSFrançois Tigeot 	radeon_ring_write(ring, lower_32_bits(addr));
3382926deccbSFrançois Tigeot 	radeon_ring_write(ring, (upper_32_bits(addr) & 0xff) | DATA_SEL(1) | INT_SEL(2));
3383926deccbSFrançois Tigeot 	radeon_ring_write(ring, fence->seq);
3384926deccbSFrançois Tigeot 	radeon_ring_write(ring, 0);
3385926deccbSFrançois Tigeot }
3386926deccbSFrançois Tigeot 
3387926deccbSFrançois Tigeot /*
3388926deccbSFrançois Tigeot  * IB stuff
3389926deccbSFrançois Tigeot  */
si_ring_ib_execute(struct radeon_device * rdev,struct radeon_ib * ib)3390926deccbSFrançois Tigeot void si_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib)
3391926deccbSFrançois Tigeot {
3392926deccbSFrançois Tigeot 	struct radeon_ring *ring = &rdev->ring[ib->ring];
33937dcf36dcSFrançois Tigeot 	unsigned vm_id = ib->vm ? ib->vm->ids[ib->ring].id : 0;
3394926deccbSFrançois Tigeot 	u32 header;
3395926deccbSFrançois Tigeot 
3396926deccbSFrançois Tigeot 	if (ib->is_const_ib) {
3397926deccbSFrançois Tigeot 		/* set switch buffer packet before const IB */
3398926deccbSFrançois Tigeot 		radeon_ring_write(ring, PACKET3(PACKET3_SWITCH_BUFFER, 0));
3399926deccbSFrançois Tigeot 		radeon_ring_write(ring, 0);
3400926deccbSFrançois Tigeot 
3401926deccbSFrançois Tigeot 		header = PACKET3(PACKET3_INDIRECT_BUFFER_CONST, 2);
3402926deccbSFrançois Tigeot 	} else {
3403926deccbSFrançois Tigeot 		u32 next_rptr;
3404926deccbSFrançois Tigeot 		if (ring->rptr_save_reg) {
3405926deccbSFrançois Tigeot 			next_rptr = ring->wptr + 3 + 4 + 8;
3406926deccbSFrançois Tigeot 			radeon_ring_write(ring, PACKET3(PACKET3_SET_CONFIG_REG, 1));
3407926deccbSFrançois Tigeot 			radeon_ring_write(ring, ((ring->rptr_save_reg -
3408926deccbSFrançois Tigeot 						  PACKET3_SET_CONFIG_REG_START) >> 2));
3409926deccbSFrançois Tigeot 			radeon_ring_write(ring, next_rptr);
3410926deccbSFrançois Tigeot 		} else if (rdev->wb.enabled) {
3411926deccbSFrançois Tigeot 			next_rptr = ring->wptr + 5 + 4 + 8;
3412926deccbSFrançois Tigeot 			radeon_ring_write(ring, PACKET3(PACKET3_WRITE_DATA, 3));
3413926deccbSFrançois Tigeot 			radeon_ring_write(ring, (1 << 8));
3414926deccbSFrançois Tigeot 			radeon_ring_write(ring, ring->next_rptr_gpu_addr & 0xfffffffc);
3415c6f73aabSFrançois Tigeot 			radeon_ring_write(ring, upper_32_bits(ring->next_rptr_gpu_addr));
3416926deccbSFrançois Tigeot 			radeon_ring_write(ring, next_rptr);
3417926deccbSFrançois Tigeot 		}
3418926deccbSFrançois Tigeot 
3419926deccbSFrançois Tigeot 		header = PACKET3(PACKET3_INDIRECT_BUFFER, 2);
3420926deccbSFrançois Tigeot 	}
3421926deccbSFrançois Tigeot 
3422926deccbSFrançois Tigeot 	radeon_ring_write(ring, header);
3423926deccbSFrançois Tigeot 	radeon_ring_write(ring,
3424926deccbSFrançois Tigeot #ifdef __BIG_ENDIAN
3425926deccbSFrançois Tigeot 			  (2 << 0) |
3426926deccbSFrançois Tigeot #endif
3427926deccbSFrançois Tigeot 			  (ib->gpu_addr & 0xFFFFFFFC));
3428926deccbSFrançois Tigeot 	radeon_ring_write(ring, upper_32_bits(ib->gpu_addr) & 0xFFFF);
34297dcf36dcSFrançois Tigeot 	radeon_ring_write(ring, ib->length_dw | (vm_id << 24));
3430926deccbSFrançois Tigeot 
3431926deccbSFrançois Tigeot 	if (!ib->is_const_ib) {
3432926deccbSFrançois Tigeot 		/* flush read cache over gart for this vmid */
3433926deccbSFrançois Tigeot 		radeon_ring_write(ring, PACKET3(PACKET3_SET_CONFIG_REG, 1));
3434926deccbSFrançois Tigeot 		radeon_ring_write(ring, (CP_COHER_CNTL2 - PACKET3_SET_CONFIG_REG_START) >> 2);
34357dcf36dcSFrançois Tigeot 		radeon_ring_write(ring, vm_id);
3436926deccbSFrançois Tigeot 		radeon_ring_write(ring, PACKET3(PACKET3_SURFACE_SYNC, 3));
3437926deccbSFrançois Tigeot 		radeon_ring_write(ring, PACKET3_TCL1_ACTION_ENA |
3438926deccbSFrançois Tigeot 				  PACKET3_TC_ACTION_ENA |
3439926deccbSFrançois Tigeot 				  PACKET3_SH_KCACHE_ACTION_ENA |
3440926deccbSFrançois Tigeot 				  PACKET3_SH_ICACHE_ACTION_ENA);
3441926deccbSFrançois Tigeot 		radeon_ring_write(ring, 0xFFFFFFFF);
3442926deccbSFrançois Tigeot 		radeon_ring_write(ring, 0);
3443926deccbSFrançois Tigeot 		radeon_ring_write(ring, 10); /* poll interval */
3444926deccbSFrançois Tigeot 	}
3445926deccbSFrançois Tigeot }
3446926deccbSFrançois Tigeot 
3447926deccbSFrançois Tigeot /*
3448926deccbSFrançois Tigeot  * CP.
3449926deccbSFrançois Tigeot  */
si_cp_enable(struct radeon_device * rdev,bool enable)3450926deccbSFrançois Tigeot static void si_cp_enable(struct radeon_device *rdev, bool enable)
3451926deccbSFrançois Tigeot {
3452926deccbSFrançois Tigeot 	if (enable)
3453926deccbSFrançois Tigeot 		WREG32(CP_ME_CNTL, 0);
3454926deccbSFrançois Tigeot 	else {
3455c6f73aabSFrançois Tigeot 		if (rdev->asic->copy.copy_ring_index == RADEON_RING_TYPE_GFX_INDEX)
3456926deccbSFrançois Tigeot 			radeon_ttm_set_active_vram_size(rdev, rdev->mc.visible_vram_size);
3457926deccbSFrançois Tigeot 		WREG32(CP_ME_CNTL, (CP_ME_HALT | CP_PFP_HALT | CP_CE_HALT));
3458926deccbSFrançois Tigeot 		WREG32(SCRATCH_UMSK, 0);
3459926deccbSFrançois Tigeot 		rdev->ring[RADEON_RING_TYPE_GFX_INDEX].ready = false;
3460926deccbSFrançois Tigeot 		rdev->ring[CAYMAN_RING_TYPE_CP1_INDEX].ready = false;
3461926deccbSFrançois Tigeot 		rdev->ring[CAYMAN_RING_TYPE_CP2_INDEX].ready = false;
3462926deccbSFrançois Tigeot 	}
3463c4ef309bSzrj 	udelay(50);
3464926deccbSFrançois Tigeot }
3465926deccbSFrançois Tigeot 
si_cp_load_microcode(struct radeon_device * rdev)3466926deccbSFrançois Tigeot static int si_cp_load_microcode(struct radeon_device *rdev)
3467926deccbSFrançois Tigeot {
3468926deccbSFrançois Tigeot 	int i;
3469926deccbSFrançois Tigeot 
3470cb754608SImre Vadász 	if (!rdev->me_fw || !rdev->pfp_fw || !rdev->ce_fw)
3471926deccbSFrançois Tigeot 		return -EINVAL;
3472926deccbSFrançois Tigeot 
3473926deccbSFrançois Tigeot 	si_cp_enable(rdev, false);
3474926deccbSFrançois Tigeot 
3475cb754608SImre Vadász 	if (rdev->new_fw) {
3476cb754608SImre Vadász 		const struct gfx_firmware_header_v1_0 *pfp_hdr =
3477cb754608SImre Vadász 			(const struct gfx_firmware_header_v1_0 *)rdev->pfp_fw->data;
3478cb754608SImre Vadász 		const struct gfx_firmware_header_v1_0 *ce_hdr =
3479cb754608SImre Vadász 			(const struct gfx_firmware_header_v1_0 *)rdev->ce_fw->data;
3480cb754608SImre Vadász 		const struct gfx_firmware_header_v1_0 *me_hdr =
3481cb754608SImre Vadász 			(const struct gfx_firmware_header_v1_0 *)rdev->me_fw->data;
3482cb754608SImre Vadász 		const __le32 *fw_data;
3483cb754608SImre Vadász 		u32 fw_size;
3484cb754608SImre Vadász 
3485cb754608SImre Vadász 		radeon_ucode_print_gfx_hdr(&pfp_hdr->header);
3486cb754608SImre Vadász 		radeon_ucode_print_gfx_hdr(&ce_hdr->header);
3487cb754608SImre Vadász 		radeon_ucode_print_gfx_hdr(&me_hdr->header);
3488cb754608SImre Vadász 
3489cb754608SImre Vadász 		/* PFP */
3490cb754608SImre Vadász 		fw_data = (const __le32 *)
3491c59a5c48SFrançois Tigeot 			(rdev->pfp_fw->data + le32_to_cpu(pfp_hdr->header.ucode_array_offset_bytes));
3492cb754608SImre Vadász 		fw_size = le32_to_cpu(pfp_hdr->header.ucode_size_bytes) / 4;
3493cb754608SImre Vadász 		WREG32(CP_PFP_UCODE_ADDR, 0);
3494cb754608SImre Vadász 		for (i = 0; i < fw_size; i++)
3495cb754608SImre Vadász 			WREG32(CP_PFP_UCODE_DATA, le32_to_cpup(fw_data++));
3496cb754608SImre Vadász 		WREG32(CP_PFP_UCODE_ADDR, 0);
3497cb754608SImre Vadász 
3498cb754608SImre Vadász 		/* CE */
3499cb754608SImre Vadász 		fw_data = (const __le32 *)
3500c59a5c48SFrançois Tigeot 			(rdev->ce_fw->data + le32_to_cpu(ce_hdr->header.ucode_array_offset_bytes));
3501cb754608SImre Vadász 		fw_size = le32_to_cpu(ce_hdr->header.ucode_size_bytes) / 4;
3502cb754608SImre Vadász 		WREG32(CP_CE_UCODE_ADDR, 0);
3503cb754608SImre Vadász 		for (i = 0; i < fw_size; i++)
3504cb754608SImre Vadász 			WREG32(CP_CE_UCODE_DATA, le32_to_cpup(fw_data++));
3505cb754608SImre Vadász 		WREG32(CP_CE_UCODE_ADDR, 0);
3506cb754608SImre Vadász 
3507cb754608SImre Vadász 		/* ME */
3508cb754608SImre Vadász 		fw_data = (const __be32 *)
3509c59a5c48SFrançois Tigeot 			(rdev->me_fw->data + le32_to_cpu(me_hdr->header.ucode_array_offset_bytes));
3510cb754608SImre Vadász 		fw_size = le32_to_cpu(me_hdr->header.ucode_size_bytes) / 4;
3511cb754608SImre Vadász 		WREG32(CP_ME_RAM_WADDR, 0);
3512cb754608SImre Vadász 		for (i = 0; i < fw_size; i++)
3513cb754608SImre Vadász 			WREG32(CP_ME_RAM_DATA, le32_to_cpup(fw_data++));
3514cb754608SImre Vadász 		WREG32(CP_ME_RAM_WADDR, 0);
3515cb754608SImre Vadász 	} else {
3516cb754608SImre Vadász 		const __be32 *fw_data;
3517cb754608SImre Vadász 
3518926deccbSFrançois Tigeot 		/* PFP */
3519926deccbSFrançois Tigeot 		fw_data = (const __be32 *)rdev->pfp_fw->data;
3520926deccbSFrançois Tigeot 		WREG32(CP_PFP_UCODE_ADDR, 0);
3521926deccbSFrançois Tigeot 		for (i = 0; i < SI_PFP_UCODE_SIZE; i++)
3522926deccbSFrançois Tigeot 			WREG32(CP_PFP_UCODE_DATA, be32_to_cpup(fw_data++));
3523926deccbSFrançois Tigeot 		WREG32(CP_PFP_UCODE_ADDR, 0);
3524926deccbSFrançois Tigeot 
3525926deccbSFrançois Tigeot 		/* CE */
3526926deccbSFrançois Tigeot 		fw_data = (const __be32 *)rdev->ce_fw->data;
3527926deccbSFrançois Tigeot 		WREG32(CP_CE_UCODE_ADDR, 0);
3528926deccbSFrançois Tigeot 		for (i = 0; i < SI_CE_UCODE_SIZE; i++)
3529926deccbSFrançois Tigeot 			WREG32(CP_CE_UCODE_DATA, be32_to_cpup(fw_data++));
3530926deccbSFrançois Tigeot 		WREG32(CP_CE_UCODE_ADDR, 0);
3531926deccbSFrançois Tigeot 
3532926deccbSFrançois Tigeot 		/* ME */
3533926deccbSFrançois Tigeot 		fw_data = (const __be32 *)rdev->me_fw->data;
3534926deccbSFrançois Tigeot 		WREG32(CP_ME_RAM_WADDR, 0);
3535926deccbSFrançois Tigeot 		for (i = 0; i < SI_PM4_UCODE_SIZE; i++)
3536926deccbSFrançois Tigeot 			WREG32(CP_ME_RAM_DATA, be32_to_cpup(fw_data++));
3537926deccbSFrançois Tigeot 		WREG32(CP_ME_RAM_WADDR, 0);
3538cb754608SImre Vadász 	}
3539926deccbSFrançois Tigeot 
3540926deccbSFrançois Tigeot 	WREG32(CP_PFP_UCODE_ADDR, 0);
3541926deccbSFrançois Tigeot 	WREG32(CP_CE_UCODE_ADDR, 0);
3542926deccbSFrançois Tigeot 	WREG32(CP_ME_RAM_WADDR, 0);
3543926deccbSFrançois Tigeot 	WREG32(CP_ME_RAM_RADDR, 0);
3544926deccbSFrançois Tigeot 	return 0;
3545926deccbSFrançois Tigeot }
3546926deccbSFrançois Tigeot 
si_cp_start(struct radeon_device * rdev)3547926deccbSFrançois Tigeot static int si_cp_start(struct radeon_device *rdev)
3548926deccbSFrançois Tigeot {
3549926deccbSFrançois Tigeot 	struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX];
3550926deccbSFrançois Tigeot 	int r, i;
3551926deccbSFrançois Tigeot 
3552926deccbSFrançois Tigeot 	r = radeon_ring_lock(rdev, ring, 7 + 4);
3553926deccbSFrançois Tigeot 	if (r) {
3554926deccbSFrançois Tigeot 		DRM_ERROR("radeon: cp failed to lock ring (%d).\n", r);
3555926deccbSFrançois Tigeot 		return r;
3556926deccbSFrançois Tigeot 	}
3557926deccbSFrançois Tigeot 	/* init the CP */
3558926deccbSFrançois Tigeot 	radeon_ring_write(ring, PACKET3(PACKET3_ME_INITIALIZE, 5));
3559926deccbSFrançois Tigeot 	radeon_ring_write(ring, 0x1);
3560926deccbSFrançois Tigeot 	radeon_ring_write(ring, 0x0);
3561926deccbSFrançois Tigeot 	radeon_ring_write(ring, rdev->config.si.max_hw_contexts - 1);
3562926deccbSFrançois Tigeot 	radeon_ring_write(ring, PACKET3_ME_INITIALIZE_DEVICE_ID(1));
3563926deccbSFrançois Tigeot 	radeon_ring_write(ring, 0);
3564926deccbSFrançois Tigeot 	radeon_ring_write(ring, 0);
3565926deccbSFrançois Tigeot 
3566926deccbSFrançois Tigeot 	/* init the CE partitions */
3567926deccbSFrançois Tigeot 	radeon_ring_write(ring, PACKET3(PACKET3_SET_BASE, 2));
3568926deccbSFrançois Tigeot 	radeon_ring_write(ring, PACKET3_BASE_INDEX(CE_PARTITION_BASE));
3569926deccbSFrançois Tigeot 	radeon_ring_write(ring, 0xc000);
3570926deccbSFrançois Tigeot 	radeon_ring_write(ring, 0xe000);
3571c6f73aabSFrançois Tigeot 	radeon_ring_unlock_commit(rdev, ring, false);
3572926deccbSFrançois Tigeot 
3573926deccbSFrançois Tigeot 	si_cp_enable(rdev, true);
3574926deccbSFrançois Tigeot 
3575926deccbSFrançois Tigeot 	r = radeon_ring_lock(rdev, ring, si_default_size + 10);
3576926deccbSFrançois Tigeot 	if (r) {
3577926deccbSFrançois Tigeot 		DRM_ERROR("radeon: cp failed to lock ring (%d).\n", r);
3578926deccbSFrançois Tigeot 		return r;
3579926deccbSFrançois Tigeot 	}
3580926deccbSFrançois Tigeot 
3581926deccbSFrançois Tigeot 	/* setup clear context state */
3582926deccbSFrançois Tigeot 	radeon_ring_write(ring, PACKET3(PACKET3_PREAMBLE_CNTL, 0));
3583926deccbSFrançois Tigeot 	radeon_ring_write(ring, PACKET3_PREAMBLE_BEGIN_CLEAR_STATE);
3584926deccbSFrançois Tigeot 
3585926deccbSFrançois Tigeot 	for (i = 0; i < si_default_size; i++)
3586926deccbSFrançois Tigeot 		radeon_ring_write(ring, si_default_state[i]);
3587926deccbSFrançois Tigeot 
3588926deccbSFrançois Tigeot 	radeon_ring_write(ring, PACKET3(PACKET3_PREAMBLE_CNTL, 0));
3589926deccbSFrançois Tigeot 	radeon_ring_write(ring, PACKET3_PREAMBLE_END_CLEAR_STATE);
3590926deccbSFrançois Tigeot 
3591926deccbSFrançois Tigeot 	/* set clear context state */
3592926deccbSFrançois Tigeot 	radeon_ring_write(ring, PACKET3(PACKET3_CLEAR_STATE, 0));
3593926deccbSFrançois Tigeot 	radeon_ring_write(ring, 0);
3594926deccbSFrançois Tigeot 
3595926deccbSFrançois Tigeot 	radeon_ring_write(ring, PACKET3(PACKET3_SET_CONTEXT_REG, 2));
3596926deccbSFrançois Tigeot 	radeon_ring_write(ring, 0x00000316);
3597926deccbSFrançois Tigeot 	radeon_ring_write(ring, 0x0000000e); /* VGT_VERTEX_REUSE_BLOCK_CNTL */
3598926deccbSFrançois Tigeot 	radeon_ring_write(ring, 0x00000010); /* VGT_OUT_DEALLOC_CNTL */
3599926deccbSFrançois Tigeot 
3600c6f73aabSFrançois Tigeot 	radeon_ring_unlock_commit(rdev, ring, false);
3601926deccbSFrançois Tigeot 
3602926deccbSFrançois Tigeot 	for (i = RADEON_RING_TYPE_GFX_INDEX; i <= CAYMAN_RING_TYPE_CP2_INDEX; ++i) {
3603926deccbSFrançois Tigeot 		ring = &rdev->ring[i];
3604926deccbSFrançois Tigeot 		r = radeon_ring_lock(rdev, ring, 2);
3605926deccbSFrançois Tigeot 
3606926deccbSFrançois Tigeot 		/* clear the compute context state */
3607926deccbSFrançois Tigeot 		radeon_ring_write(ring, PACKET3_COMPUTE(PACKET3_CLEAR_STATE, 0));
3608926deccbSFrançois Tigeot 		radeon_ring_write(ring, 0);
3609926deccbSFrançois Tigeot 
3610c6f73aabSFrançois Tigeot 		radeon_ring_unlock_commit(rdev, ring, false);
3611926deccbSFrançois Tigeot 	}
3612926deccbSFrançois Tigeot 
3613926deccbSFrançois Tigeot 	return 0;
3614926deccbSFrançois Tigeot }
3615926deccbSFrançois Tigeot 
si_cp_fini(struct radeon_device * rdev)3616926deccbSFrançois Tigeot static void si_cp_fini(struct radeon_device *rdev)
3617926deccbSFrançois Tigeot {
3618926deccbSFrançois Tigeot 	struct radeon_ring *ring;
3619926deccbSFrançois Tigeot 	si_cp_enable(rdev, false);
3620926deccbSFrançois Tigeot 
3621926deccbSFrançois Tigeot 	ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX];
3622926deccbSFrançois Tigeot 	radeon_ring_fini(rdev, ring);
3623926deccbSFrançois Tigeot 	radeon_scratch_free(rdev, ring->rptr_save_reg);
3624926deccbSFrançois Tigeot 
3625926deccbSFrançois Tigeot 	ring = &rdev->ring[CAYMAN_RING_TYPE_CP1_INDEX];
3626926deccbSFrançois Tigeot 	radeon_ring_fini(rdev, ring);
3627926deccbSFrançois Tigeot 	radeon_scratch_free(rdev, ring->rptr_save_reg);
3628926deccbSFrançois Tigeot 
3629926deccbSFrançois Tigeot 	ring = &rdev->ring[CAYMAN_RING_TYPE_CP2_INDEX];
3630926deccbSFrançois Tigeot 	radeon_ring_fini(rdev, ring);
3631926deccbSFrançois Tigeot 	radeon_scratch_free(rdev, ring->rptr_save_reg);
3632926deccbSFrançois Tigeot }
3633926deccbSFrançois Tigeot 
si_cp_resume(struct radeon_device * rdev)3634926deccbSFrançois Tigeot static int si_cp_resume(struct radeon_device *rdev)
3635926deccbSFrançois Tigeot {
3636926deccbSFrançois Tigeot 	struct radeon_ring *ring;
3637926deccbSFrançois Tigeot 	u32 tmp;
3638926deccbSFrançois Tigeot 	u32 rb_bufsz;
3639926deccbSFrançois Tigeot 	int r;
3640926deccbSFrançois Tigeot 
36414cd92098Szrj 	si_enable_gui_idle_interrupt(rdev, false);
3642926deccbSFrançois Tigeot 
3643926deccbSFrançois Tigeot 	WREG32(CP_SEM_WAIT_TIMER, 0x0);
3644926deccbSFrançois Tigeot 	WREG32(CP_SEM_INCOMPLETE_TIMER_CNTL, 0x0);
3645926deccbSFrançois Tigeot 
3646926deccbSFrançois Tigeot 	/* Set the write pointer delay */
3647926deccbSFrançois Tigeot 	WREG32(CP_RB_WPTR_DELAY, 0);
3648926deccbSFrançois Tigeot 
3649926deccbSFrançois Tigeot 	WREG32(CP_DEBUG, 0);
3650926deccbSFrançois Tigeot 	WREG32(SCRATCH_ADDR, ((rdev->wb.gpu_addr + RADEON_WB_SCRATCH_OFFSET) >> 8) & 0xFFFFFFFF);
3651926deccbSFrançois Tigeot 
3652926deccbSFrançois Tigeot 	/* ring 0 - compute and gfx */
3653926deccbSFrançois Tigeot 	/* Set ring buffer size */
3654926deccbSFrançois Tigeot 	ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX];
36554cd92098Szrj 	rb_bufsz = order_base_2(ring->ring_size / 8);
36564cd92098Szrj 	tmp = (order_base_2(RADEON_GPU_PAGE_SIZE/8) << 8) | rb_bufsz;
3657926deccbSFrançois Tigeot #ifdef __BIG_ENDIAN
3658926deccbSFrançois Tigeot 	tmp |= BUF_SWAP_32BIT;
3659926deccbSFrançois Tigeot #endif
3660926deccbSFrançois Tigeot 	WREG32(CP_RB0_CNTL, tmp);
3661926deccbSFrançois Tigeot 
3662926deccbSFrançois Tigeot 	/* Initialize the ring buffer's read and write pointers */
3663926deccbSFrançois Tigeot 	WREG32(CP_RB0_CNTL, tmp | RB_RPTR_WR_ENA);
3664926deccbSFrançois Tigeot 	ring->wptr = 0;
3665926deccbSFrançois Tigeot 	WREG32(CP_RB0_WPTR, ring->wptr);
3666926deccbSFrançois Tigeot 
3667926deccbSFrançois Tigeot 	/* set the wb address whether it's enabled or not */
3668926deccbSFrançois Tigeot 	WREG32(CP_RB0_RPTR_ADDR, (rdev->wb.gpu_addr + RADEON_WB_CP_RPTR_OFFSET) & 0xFFFFFFFC);
3669926deccbSFrançois Tigeot 	WREG32(CP_RB0_RPTR_ADDR_HI, upper_32_bits(rdev->wb.gpu_addr + RADEON_WB_CP_RPTR_OFFSET) & 0xFF);
3670926deccbSFrançois Tigeot 
3671926deccbSFrançois Tigeot 	if (rdev->wb.enabled)
3672926deccbSFrançois Tigeot 		WREG32(SCRATCH_UMSK, 0xff);
3673926deccbSFrançois Tigeot 	else {
3674926deccbSFrançois Tigeot 		tmp |= RB_NO_UPDATE;
3675926deccbSFrançois Tigeot 		WREG32(SCRATCH_UMSK, 0);
3676926deccbSFrançois Tigeot 	}
3677926deccbSFrançois Tigeot 
3678c4ef309bSzrj 	mdelay(1);
3679926deccbSFrançois Tigeot 	WREG32(CP_RB0_CNTL, tmp);
3680926deccbSFrançois Tigeot 
3681926deccbSFrançois Tigeot 	WREG32(CP_RB0_BASE, ring->gpu_addr >> 8);
3682926deccbSFrançois Tigeot 
3683926deccbSFrançois Tigeot 	/* ring1  - compute only */
3684926deccbSFrançois Tigeot 	/* Set ring buffer size */
3685926deccbSFrançois Tigeot 	ring = &rdev->ring[CAYMAN_RING_TYPE_CP1_INDEX];
36864cd92098Szrj 	rb_bufsz = order_base_2(ring->ring_size / 8);
36874cd92098Szrj 	tmp = (order_base_2(RADEON_GPU_PAGE_SIZE/8) << 8) | rb_bufsz;
3688926deccbSFrançois Tigeot #ifdef __BIG_ENDIAN
3689926deccbSFrançois Tigeot 	tmp |= BUF_SWAP_32BIT;
3690926deccbSFrançois Tigeot #endif
3691926deccbSFrançois Tigeot 	WREG32(CP_RB1_CNTL, tmp);
3692926deccbSFrançois Tigeot 
3693926deccbSFrançois Tigeot 	/* Initialize the ring buffer's read and write pointers */
3694926deccbSFrançois Tigeot 	WREG32(CP_RB1_CNTL, tmp | RB_RPTR_WR_ENA);
3695926deccbSFrançois Tigeot 	ring->wptr = 0;
3696926deccbSFrançois Tigeot 	WREG32(CP_RB1_WPTR, ring->wptr);
3697926deccbSFrançois Tigeot 
3698926deccbSFrançois Tigeot 	/* set the wb address whether it's enabled or not */
3699926deccbSFrançois Tigeot 	WREG32(CP_RB1_RPTR_ADDR, (rdev->wb.gpu_addr + RADEON_WB_CP1_RPTR_OFFSET) & 0xFFFFFFFC);
3700926deccbSFrançois Tigeot 	WREG32(CP_RB1_RPTR_ADDR_HI, upper_32_bits(rdev->wb.gpu_addr + RADEON_WB_CP1_RPTR_OFFSET) & 0xFF);
3701926deccbSFrançois Tigeot 
3702c4ef309bSzrj 	mdelay(1);
3703926deccbSFrançois Tigeot 	WREG32(CP_RB1_CNTL, tmp);
3704926deccbSFrançois Tigeot 
3705926deccbSFrançois Tigeot 	WREG32(CP_RB1_BASE, ring->gpu_addr >> 8);
3706926deccbSFrançois Tigeot 
3707926deccbSFrançois Tigeot 	/* ring2 - compute only */
3708926deccbSFrançois Tigeot 	/* Set ring buffer size */
3709926deccbSFrançois Tigeot 	ring = &rdev->ring[CAYMAN_RING_TYPE_CP2_INDEX];
37104cd92098Szrj 	rb_bufsz = order_base_2(ring->ring_size / 8);
37114cd92098Szrj 	tmp = (order_base_2(RADEON_GPU_PAGE_SIZE/8) << 8) | rb_bufsz;
3712926deccbSFrançois Tigeot #ifdef __BIG_ENDIAN
3713926deccbSFrançois Tigeot 	tmp |= BUF_SWAP_32BIT;
3714926deccbSFrançois Tigeot #endif
3715926deccbSFrançois Tigeot 	WREG32(CP_RB2_CNTL, tmp);
3716926deccbSFrançois Tigeot 
3717926deccbSFrançois Tigeot 	/* Initialize the ring buffer's read and write pointers */
3718926deccbSFrançois Tigeot 	WREG32(CP_RB2_CNTL, tmp | RB_RPTR_WR_ENA);
3719926deccbSFrançois Tigeot 	ring->wptr = 0;
3720926deccbSFrançois Tigeot 	WREG32(CP_RB2_WPTR, ring->wptr);
3721926deccbSFrançois Tigeot 
3722926deccbSFrançois Tigeot 	/* set the wb address whether it's enabled or not */
3723926deccbSFrançois Tigeot 	WREG32(CP_RB2_RPTR_ADDR, (rdev->wb.gpu_addr + RADEON_WB_CP2_RPTR_OFFSET) & 0xFFFFFFFC);
3724926deccbSFrançois Tigeot 	WREG32(CP_RB2_RPTR_ADDR_HI, upper_32_bits(rdev->wb.gpu_addr + RADEON_WB_CP2_RPTR_OFFSET) & 0xFF);
3725926deccbSFrançois Tigeot 
3726c4ef309bSzrj 	mdelay(1);
3727926deccbSFrançois Tigeot 	WREG32(CP_RB2_CNTL, tmp);
3728926deccbSFrançois Tigeot 
3729926deccbSFrançois Tigeot 	WREG32(CP_RB2_BASE, ring->gpu_addr >> 8);
3730926deccbSFrançois Tigeot 
3731926deccbSFrançois Tigeot 	/* start the rings */
3732926deccbSFrançois Tigeot 	si_cp_start(rdev);
3733926deccbSFrançois Tigeot 	rdev->ring[RADEON_RING_TYPE_GFX_INDEX].ready = true;
3734926deccbSFrançois Tigeot 	rdev->ring[CAYMAN_RING_TYPE_CP1_INDEX].ready = true;
3735926deccbSFrançois Tigeot 	rdev->ring[CAYMAN_RING_TYPE_CP2_INDEX].ready = true;
3736926deccbSFrançois Tigeot 	r = radeon_ring_test(rdev, RADEON_RING_TYPE_GFX_INDEX, &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]);
3737926deccbSFrançois Tigeot 	if (r) {
3738926deccbSFrançois Tigeot 		rdev->ring[RADEON_RING_TYPE_GFX_INDEX].ready = false;
3739926deccbSFrançois Tigeot 		rdev->ring[CAYMAN_RING_TYPE_CP1_INDEX].ready = false;
3740926deccbSFrançois Tigeot 		rdev->ring[CAYMAN_RING_TYPE_CP2_INDEX].ready = false;
3741926deccbSFrançois Tigeot 		return r;
3742926deccbSFrançois Tigeot 	}
3743926deccbSFrançois Tigeot 	r = radeon_ring_test(rdev, CAYMAN_RING_TYPE_CP1_INDEX, &rdev->ring[CAYMAN_RING_TYPE_CP1_INDEX]);
3744926deccbSFrançois Tigeot 	if (r) {
3745926deccbSFrançois Tigeot 		rdev->ring[CAYMAN_RING_TYPE_CP1_INDEX].ready = false;
3746926deccbSFrançois Tigeot 	}
3747926deccbSFrançois Tigeot 	r = radeon_ring_test(rdev, CAYMAN_RING_TYPE_CP2_INDEX, &rdev->ring[CAYMAN_RING_TYPE_CP2_INDEX]);
3748926deccbSFrançois Tigeot 	if (r) {
3749926deccbSFrançois Tigeot 		rdev->ring[CAYMAN_RING_TYPE_CP2_INDEX].ready = false;
3750926deccbSFrançois Tigeot 	}
3751926deccbSFrançois Tigeot 
37524cd92098Szrj 	si_enable_gui_idle_interrupt(rdev, true);
37534cd92098Szrj 
3754c6f73aabSFrançois Tigeot 	if (rdev->asic->copy.copy_ring_index == RADEON_RING_TYPE_GFX_INDEX)
3755c6f73aabSFrançois Tigeot 		radeon_ttm_set_active_vram_size(rdev, rdev->mc.real_vram_size);
3756c6f73aabSFrançois Tigeot 
3757926deccbSFrançois Tigeot 	return 0;
3758926deccbSFrançois Tigeot }
3759926deccbSFrançois Tigeot 
si_gpu_check_soft_reset(struct radeon_device * rdev)37604cd92098Szrj u32 si_gpu_check_soft_reset(struct radeon_device *rdev)
3761926deccbSFrançois Tigeot {
3762b403bed8SMichael Neumann 	u32 reset_mask = 0;
3763b403bed8SMichael Neumann 	u32 tmp;
3764926deccbSFrançois Tigeot 
3765b403bed8SMichael Neumann 	/* GRBM_STATUS */
3766b403bed8SMichael Neumann 	tmp = RREG32(GRBM_STATUS);
3767b403bed8SMichael Neumann 	if (tmp & (PA_BUSY | SC_BUSY |
3768b403bed8SMichael Neumann 		   BCI_BUSY | SX_BUSY |
3769b403bed8SMichael Neumann 		   TA_BUSY | VGT_BUSY |
3770b403bed8SMichael Neumann 		   DB_BUSY | CB_BUSY |
3771b403bed8SMichael Neumann 		   GDS_BUSY | SPI_BUSY |
3772b403bed8SMichael Neumann 		   IA_BUSY | IA_BUSY_NO_DMA))
3773b403bed8SMichael Neumann 		reset_mask |= RADEON_RESET_GFX;
3774b403bed8SMichael Neumann 
3775b403bed8SMichael Neumann 	if (tmp & (CF_RQ_PENDING | PF_RQ_PENDING |
3776b403bed8SMichael Neumann 		   CP_BUSY | CP_COHERENCY_BUSY))
3777b403bed8SMichael Neumann 		reset_mask |= RADEON_RESET_CP;
3778b403bed8SMichael Neumann 
3779b403bed8SMichael Neumann 	if (tmp & GRBM_EE_BUSY)
3780b403bed8SMichael Neumann 		reset_mask |= RADEON_RESET_GRBM | RADEON_RESET_GFX | RADEON_RESET_CP;
3781b403bed8SMichael Neumann 
3782b403bed8SMichael Neumann 	/* GRBM_STATUS2 */
3783b403bed8SMichael Neumann 	tmp = RREG32(GRBM_STATUS2);
3784b403bed8SMichael Neumann 	if (tmp & (RLC_RQ_PENDING | RLC_BUSY))
3785b403bed8SMichael Neumann 		reset_mask |= RADEON_RESET_RLC;
3786b403bed8SMichael Neumann 
3787b403bed8SMichael Neumann 	/* DMA_STATUS_REG 0 */
3788b403bed8SMichael Neumann 	tmp = RREG32(DMA_STATUS_REG + DMA0_REGISTER_OFFSET);
3789b403bed8SMichael Neumann 	if (!(tmp & DMA_IDLE))
3790b403bed8SMichael Neumann 		reset_mask |= RADEON_RESET_DMA;
3791b403bed8SMichael Neumann 
3792b403bed8SMichael Neumann 	/* DMA_STATUS_REG 1 */
3793b403bed8SMichael Neumann 	tmp = RREG32(DMA_STATUS_REG + DMA1_REGISTER_OFFSET);
3794b403bed8SMichael Neumann 	if (!(tmp & DMA_IDLE))
3795b403bed8SMichael Neumann 		reset_mask |= RADEON_RESET_DMA1;
3796b403bed8SMichael Neumann 
3797b403bed8SMichael Neumann 	/* SRBM_STATUS2 */
3798b403bed8SMichael Neumann 	tmp = RREG32(SRBM_STATUS2);
3799b403bed8SMichael Neumann 	if (tmp & DMA_BUSY)
3800b403bed8SMichael Neumann 		reset_mask |= RADEON_RESET_DMA;
3801b403bed8SMichael Neumann 
3802b403bed8SMichael Neumann 	if (tmp & DMA1_BUSY)
3803b403bed8SMichael Neumann 		reset_mask |= RADEON_RESET_DMA1;
3804b403bed8SMichael Neumann 
3805b403bed8SMichael Neumann 	/* SRBM_STATUS */
3806b403bed8SMichael Neumann 	tmp = RREG32(SRBM_STATUS);
3807b403bed8SMichael Neumann 
3808b403bed8SMichael Neumann 	if (tmp & IH_BUSY)
3809b403bed8SMichael Neumann 		reset_mask |= RADEON_RESET_IH;
3810b403bed8SMichael Neumann 
3811b403bed8SMichael Neumann 	if (tmp & SEM_BUSY)
3812b403bed8SMichael Neumann 		reset_mask |= RADEON_RESET_SEM;
3813b403bed8SMichael Neumann 
3814b403bed8SMichael Neumann 	if (tmp & GRBM_RQ_PENDING)
3815b403bed8SMichael Neumann 		reset_mask |= RADEON_RESET_GRBM;
3816b403bed8SMichael Neumann 
3817b403bed8SMichael Neumann 	if (tmp & VMC_BUSY)
3818b403bed8SMichael Neumann 		reset_mask |= RADEON_RESET_VMC;
3819b403bed8SMichael Neumann 
3820b403bed8SMichael Neumann 	if (tmp & (MCB_BUSY | MCB_NON_DISPLAY_BUSY |
3821b403bed8SMichael Neumann 		   MCC_BUSY | MCD_BUSY))
3822b403bed8SMichael Neumann 		reset_mask |= RADEON_RESET_MC;
3823b403bed8SMichael Neumann 
3824b403bed8SMichael Neumann 	if (evergreen_is_display_hung(rdev))
3825b403bed8SMichael Neumann 		reset_mask |= RADEON_RESET_DISPLAY;
3826b403bed8SMichael Neumann 
3827b403bed8SMichael Neumann 	/* VM_L2_STATUS */
3828b403bed8SMichael Neumann 	tmp = RREG32(VM_L2_STATUS);
3829b403bed8SMichael Neumann 	if (tmp & L2_BUSY)
3830b403bed8SMichael Neumann 		reset_mask |= RADEON_RESET_VMC;
3831b403bed8SMichael Neumann 
3832b403bed8SMichael Neumann 	/* Skip MC reset as it's mostly likely not hung, just busy */
3833b403bed8SMichael Neumann 	if (reset_mask & RADEON_RESET_MC) {
3834b403bed8SMichael Neumann 		DRM_DEBUG("MC busy: 0x%08X, clearing.\n", reset_mask);
3835b403bed8SMichael Neumann 		reset_mask &= ~RADEON_RESET_MC;
3836926deccbSFrançois Tigeot 	}
3837926deccbSFrançois Tigeot 
3838b403bed8SMichael Neumann 	return reset_mask;
3839b403bed8SMichael Neumann }
3840926deccbSFrançois Tigeot 
si_gpu_soft_reset(struct radeon_device * rdev,u32 reset_mask)3841b403bed8SMichael Neumann static void si_gpu_soft_reset(struct radeon_device *rdev, u32 reset_mask)
3842b403bed8SMichael Neumann {
3843b403bed8SMichael Neumann 	struct evergreen_mc_save save;
3844b403bed8SMichael Neumann 	u32 grbm_soft_reset = 0, srbm_soft_reset = 0;
3845b403bed8SMichael Neumann 	u32 tmp;
3846b403bed8SMichael Neumann 
3847b403bed8SMichael Neumann 	if (reset_mask == 0)
3848926deccbSFrançois Tigeot 		return;
3849926deccbSFrançois Tigeot 
3850b403bed8SMichael Neumann 	dev_info(rdev->dev, "GPU softreset: 0x%08X\n", reset_mask);
3851b403bed8SMichael Neumann 
3852b403bed8SMichael Neumann 	evergreen_print_gpu_status_regs(rdev);
3853b403bed8SMichael Neumann 	dev_info(rdev->dev, "  VM_CONTEXT1_PROTECTION_FAULT_ADDR   0x%08X\n",
3854b403bed8SMichael Neumann 		 RREG32(VM_CONTEXT1_PROTECTION_FAULT_ADDR));
3855b403bed8SMichael Neumann 	dev_info(rdev->dev, "  VM_CONTEXT1_PROTECTION_FAULT_STATUS 0x%08X\n",
3856b403bed8SMichael Neumann 		 RREG32(VM_CONTEXT1_PROTECTION_FAULT_STATUS));
3857926deccbSFrançois Tigeot 
38584cd92098Szrj 	/* disable PG/CG */
38594cd92098Szrj 	si_fini_pg(rdev);
38604cd92098Szrj 	si_fini_cg(rdev);
38614cd92098Szrj 
38624cd92098Szrj 	/* stop the rlc */
38634cd92098Szrj 	si_rlc_stop(rdev);
38644cd92098Szrj 
3865926deccbSFrançois Tigeot 	/* Disable CP parsing/prefetching */
3866926deccbSFrançois Tigeot 	WREG32(CP_ME_CNTL, CP_ME_HALT | CP_PFP_HALT | CP_CE_HALT);
3867926deccbSFrançois Tigeot 
3868b403bed8SMichael Neumann 	if (reset_mask & RADEON_RESET_DMA) {
3869b403bed8SMichael Neumann 		/* dma0 */
3870b403bed8SMichael Neumann 		tmp = RREG32(DMA_RB_CNTL + DMA0_REGISTER_OFFSET);
3871b403bed8SMichael Neumann 		tmp &= ~DMA_RB_ENABLE;
3872b403bed8SMichael Neumann 		WREG32(DMA_RB_CNTL + DMA0_REGISTER_OFFSET, tmp);
3873b403bed8SMichael Neumann 	}
3874b403bed8SMichael Neumann 	if (reset_mask & RADEON_RESET_DMA1) {
3875b403bed8SMichael Neumann 		/* dma1 */
3876b403bed8SMichael Neumann 		tmp = RREG32(DMA_RB_CNTL + DMA1_REGISTER_OFFSET);
3877b403bed8SMichael Neumann 		tmp &= ~DMA_RB_ENABLE;
3878b403bed8SMichael Neumann 		WREG32(DMA_RB_CNTL + DMA1_REGISTER_OFFSET, tmp);
3879b403bed8SMichael Neumann 	}
3880b403bed8SMichael Neumann 
3881c4ef309bSzrj 	udelay(50);
3882b403bed8SMichael Neumann 
3883b403bed8SMichael Neumann 	evergreen_mc_stop(rdev, &save);
3884b403bed8SMichael Neumann 	if (evergreen_mc_wait_for_idle(rdev)) {
3885b403bed8SMichael Neumann 		dev_warn(rdev->dev, "Wait for MC idle timedout !\n");
3886b403bed8SMichael Neumann 	}
3887b403bed8SMichael Neumann 
3888b403bed8SMichael Neumann 	if (reset_mask & (RADEON_RESET_GFX | RADEON_RESET_COMPUTE | RADEON_RESET_CP)) {
3889b403bed8SMichael Neumann 		grbm_soft_reset = SOFT_RESET_CB |
3890926deccbSFrançois Tigeot 			SOFT_RESET_DB |
3891926deccbSFrançois Tigeot 			SOFT_RESET_GDS |
3892926deccbSFrançois Tigeot 			SOFT_RESET_PA |
3893926deccbSFrançois Tigeot 			SOFT_RESET_SC |
3894926deccbSFrançois Tigeot 			SOFT_RESET_BCI |
3895926deccbSFrançois Tigeot 			SOFT_RESET_SPI |
3896926deccbSFrançois Tigeot 			SOFT_RESET_SX |
3897926deccbSFrançois Tigeot 			SOFT_RESET_TC |
3898926deccbSFrançois Tigeot 			SOFT_RESET_TA |
3899926deccbSFrançois Tigeot 			SOFT_RESET_VGT |
3900b403bed8SMichael Neumann 			SOFT_RESET_IA;
3901926deccbSFrançois Tigeot 	}
3902926deccbSFrançois Tigeot 
3903b403bed8SMichael Neumann 	if (reset_mask & RADEON_RESET_CP) {
3904b403bed8SMichael Neumann 		grbm_soft_reset |= SOFT_RESET_CP | SOFT_RESET_VGT;
3905926deccbSFrançois Tigeot 
3906b403bed8SMichael Neumann 		srbm_soft_reset |= SOFT_RESET_GRBM;
3907926deccbSFrançois Tigeot 	}
3908926deccbSFrançois Tigeot 
3909926deccbSFrançois Tigeot 	if (reset_mask & RADEON_RESET_DMA)
3910b403bed8SMichael Neumann 		srbm_soft_reset |= SOFT_RESET_DMA;
3911b403bed8SMichael Neumann 
3912b403bed8SMichael Neumann 	if (reset_mask & RADEON_RESET_DMA1)
3913b403bed8SMichael Neumann 		srbm_soft_reset |= SOFT_RESET_DMA1;
3914b403bed8SMichael Neumann 
3915b403bed8SMichael Neumann 	if (reset_mask & RADEON_RESET_DISPLAY)
3916b403bed8SMichael Neumann 		srbm_soft_reset |= SOFT_RESET_DC;
3917b403bed8SMichael Neumann 
3918b403bed8SMichael Neumann 	if (reset_mask & RADEON_RESET_RLC)
3919b403bed8SMichael Neumann 		grbm_soft_reset |= SOFT_RESET_RLC;
3920b403bed8SMichael Neumann 
3921b403bed8SMichael Neumann 	if (reset_mask & RADEON_RESET_SEM)
3922b403bed8SMichael Neumann 		srbm_soft_reset |= SOFT_RESET_SEM;
3923b403bed8SMichael Neumann 
3924b403bed8SMichael Neumann 	if (reset_mask & RADEON_RESET_IH)
3925b403bed8SMichael Neumann 		srbm_soft_reset |= SOFT_RESET_IH;
3926b403bed8SMichael Neumann 
3927b403bed8SMichael Neumann 	if (reset_mask & RADEON_RESET_GRBM)
3928b403bed8SMichael Neumann 		srbm_soft_reset |= SOFT_RESET_GRBM;
3929b403bed8SMichael Neumann 
3930b403bed8SMichael Neumann 	if (reset_mask & RADEON_RESET_VMC)
3931b403bed8SMichael Neumann 		srbm_soft_reset |= SOFT_RESET_VMC;
3932b403bed8SMichael Neumann 
3933b403bed8SMichael Neumann 	if (reset_mask & RADEON_RESET_MC)
3934b403bed8SMichael Neumann 		srbm_soft_reset |= SOFT_RESET_MC;
3935b403bed8SMichael Neumann 
3936b403bed8SMichael Neumann 	if (grbm_soft_reset) {
3937b403bed8SMichael Neumann 		tmp = RREG32(GRBM_SOFT_RESET);
3938b403bed8SMichael Neumann 		tmp |= grbm_soft_reset;
3939b403bed8SMichael Neumann 		dev_info(rdev->dev, "GRBM_SOFT_RESET=0x%08X\n", tmp);
3940b403bed8SMichael Neumann 		WREG32(GRBM_SOFT_RESET, tmp);
3941b403bed8SMichael Neumann 		tmp = RREG32(GRBM_SOFT_RESET);
3942b403bed8SMichael Neumann 
3943c4ef309bSzrj 		udelay(50);
3944b403bed8SMichael Neumann 
3945b403bed8SMichael Neumann 		tmp &= ~grbm_soft_reset;
3946b403bed8SMichael Neumann 		WREG32(GRBM_SOFT_RESET, tmp);
3947b403bed8SMichael Neumann 		tmp = RREG32(GRBM_SOFT_RESET);
3948b403bed8SMichael Neumann 	}
3949b403bed8SMichael Neumann 
3950b403bed8SMichael Neumann 	if (srbm_soft_reset) {
3951b403bed8SMichael Neumann 		tmp = RREG32(SRBM_SOFT_RESET);
3952b403bed8SMichael Neumann 		tmp |= srbm_soft_reset;
3953b403bed8SMichael Neumann 		dev_info(rdev->dev, "SRBM_SOFT_RESET=0x%08X\n", tmp);
3954b403bed8SMichael Neumann 		WREG32(SRBM_SOFT_RESET, tmp);
3955b403bed8SMichael Neumann 		tmp = RREG32(SRBM_SOFT_RESET);
3956b403bed8SMichael Neumann 
3957c4ef309bSzrj 		udelay(50);
3958b403bed8SMichael Neumann 
3959b403bed8SMichael Neumann 		tmp &= ~srbm_soft_reset;
3960b403bed8SMichael Neumann 		WREG32(SRBM_SOFT_RESET, tmp);
3961b403bed8SMichael Neumann 		tmp = RREG32(SRBM_SOFT_RESET);
3962b403bed8SMichael Neumann 	}
3963926deccbSFrançois Tigeot 
3964926deccbSFrançois Tigeot 	/* Wait a little for things to settle down */
3965c4ef309bSzrj 	udelay(50);
3966926deccbSFrançois Tigeot 
3967926deccbSFrançois Tigeot 	evergreen_mc_resume(rdev, &save);
3968c4ef309bSzrj 	udelay(50);
3969b403bed8SMichael Neumann 
3970b403bed8SMichael Neumann 	evergreen_print_gpu_status_regs(rdev);
3971926deccbSFrançois Tigeot }
3972926deccbSFrançois Tigeot 
si_set_clk_bypass_mode(struct radeon_device * rdev)3973c6f73aabSFrançois Tigeot static void si_set_clk_bypass_mode(struct radeon_device *rdev)
3974c6f73aabSFrançois Tigeot {
3975c6f73aabSFrançois Tigeot 	u32 tmp, i;
3976c6f73aabSFrançois Tigeot 
3977c6f73aabSFrançois Tigeot 	tmp = RREG32(CG_SPLL_FUNC_CNTL);
3978c6f73aabSFrançois Tigeot 	tmp |= SPLL_BYPASS_EN;
3979c6f73aabSFrançois Tigeot 	WREG32(CG_SPLL_FUNC_CNTL, tmp);
3980c6f73aabSFrançois Tigeot 
3981c6f73aabSFrançois Tigeot 	tmp = RREG32(CG_SPLL_FUNC_CNTL_2);
3982c6f73aabSFrançois Tigeot 	tmp |= SPLL_CTLREQ_CHG;
3983c6f73aabSFrançois Tigeot 	WREG32(CG_SPLL_FUNC_CNTL_2, tmp);
3984c6f73aabSFrançois Tigeot 
3985c6f73aabSFrançois Tigeot 	for (i = 0; i < rdev->usec_timeout; i++) {
3986c6f73aabSFrançois Tigeot 		if (RREG32(SPLL_STATUS) & SPLL_CHG_STATUS)
3987c6f73aabSFrançois Tigeot 			break;
3988c6f73aabSFrançois Tigeot 		udelay(1);
3989c6f73aabSFrançois Tigeot 	}
3990c6f73aabSFrançois Tigeot 
3991c6f73aabSFrançois Tigeot 	tmp = RREG32(CG_SPLL_FUNC_CNTL_2);
3992c6f73aabSFrançois Tigeot 	tmp &= ~(SPLL_CTLREQ_CHG | SCLK_MUX_UPDATE);
3993c6f73aabSFrançois Tigeot 	WREG32(CG_SPLL_FUNC_CNTL_2, tmp);
3994c6f73aabSFrançois Tigeot 
3995c6f73aabSFrançois Tigeot 	tmp = RREG32(MPLL_CNTL_MODE);
3996c6f73aabSFrançois Tigeot 	tmp &= ~MPLL_MCLK_SEL;
3997c6f73aabSFrançois Tigeot 	WREG32(MPLL_CNTL_MODE, tmp);
3998c6f73aabSFrançois Tigeot }
3999c6f73aabSFrançois Tigeot 
si_spll_powerdown(struct radeon_device * rdev)4000c6f73aabSFrançois Tigeot static void si_spll_powerdown(struct radeon_device *rdev)
4001c6f73aabSFrançois Tigeot {
4002c6f73aabSFrançois Tigeot 	u32 tmp;
4003c6f73aabSFrançois Tigeot 
4004c6f73aabSFrançois Tigeot 	tmp = RREG32(SPLL_CNTL_MODE);
4005c6f73aabSFrançois Tigeot 	tmp |= SPLL_SW_DIR_CONTROL;
4006c6f73aabSFrançois Tigeot 	WREG32(SPLL_CNTL_MODE, tmp);
4007c6f73aabSFrançois Tigeot 
4008c6f73aabSFrançois Tigeot 	tmp = RREG32(CG_SPLL_FUNC_CNTL);
4009c6f73aabSFrançois Tigeot 	tmp |= SPLL_RESET;
4010c6f73aabSFrançois Tigeot 	WREG32(CG_SPLL_FUNC_CNTL, tmp);
4011c6f73aabSFrançois Tigeot 
4012c6f73aabSFrançois Tigeot 	tmp = RREG32(CG_SPLL_FUNC_CNTL);
4013c6f73aabSFrançois Tigeot 	tmp |= SPLL_SLEEP;
4014c6f73aabSFrançois Tigeot 	WREG32(CG_SPLL_FUNC_CNTL, tmp);
4015c6f73aabSFrançois Tigeot 
4016c6f73aabSFrançois Tigeot 	tmp = RREG32(SPLL_CNTL_MODE);
4017c6f73aabSFrançois Tigeot 	tmp &= ~SPLL_SW_DIR_CONTROL;
4018c6f73aabSFrançois Tigeot 	WREG32(SPLL_CNTL_MODE, tmp);
4019c6f73aabSFrançois Tigeot }
4020c6f73aabSFrançois Tigeot 
si_gpu_pci_config_reset(struct radeon_device * rdev)4021c6f73aabSFrançois Tigeot static void si_gpu_pci_config_reset(struct radeon_device *rdev)
4022c6f73aabSFrançois Tigeot {
4023c6f73aabSFrançois Tigeot 	struct evergreen_mc_save save;
4024c6f73aabSFrançois Tigeot 	u32 tmp, i;
4025c6f73aabSFrançois Tigeot 
4026c6f73aabSFrançois Tigeot 	dev_info(rdev->dev, "GPU pci config reset\n");
4027c6f73aabSFrançois Tigeot 
4028c6f73aabSFrançois Tigeot 	/* disable dpm? */
4029c6f73aabSFrançois Tigeot 
4030c6f73aabSFrançois Tigeot 	/* disable cg/pg */
4031c6f73aabSFrançois Tigeot 	si_fini_pg(rdev);
4032c6f73aabSFrançois Tigeot 	si_fini_cg(rdev);
4033c6f73aabSFrançois Tigeot 
4034c6f73aabSFrançois Tigeot 	/* Disable CP parsing/prefetching */
4035c6f73aabSFrançois Tigeot 	WREG32(CP_ME_CNTL, CP_ME_HALT | CP_PFP_HALT | CP_CE_HALT);
4036c6f73aabSFrançois Tigeot 	/* dma0 */
4037c6f73aabSFrançois Tigeot 	tmp = RREG32(DMA_RB_CNTL + DMA0_REGISTER_OFFSET);
4038c6f73aabSFrançois Tigeot 	tmp &= ~DMA_RB_ENABLE;
4039c6f73aabSFrançois Tigeot 	WREG32(DMA_RB_CNTL + DMA0_REGISTER_OFFSET, tmp);
4040c6f73aabSFrançois Tigeot 	/* dma1 */
4041c6f73aabSFrançois Tigeot 	tmp = RREG32(DMA_RB_CNTL + DMA1_REGISTER_OFFSET);
4042c6f73aabSFrançois Tigeot 	tmp &= ~DMA_RB_ENABLE;
4043c6f73aabSFrançois Tigeot 	WREG32(DMA_RB_CNTL + DMA1_REGISTER_OFFSET, tmp);
4044c6f73aabSFrançois Tigeot 	/* XXX other engines? */
4045c6f73aabSFrançois Tigeot 
4046c6f73aabSFrançois Tigeot 	/* halt the rlc, disable cp internal ints */
4047c6f73aabSFrançois Tigeot 	si_rlc_stop(rdev);
4048c6f73aabSFrançois Tigeot 
4049c6f73aabSFrançois Tigeot 	udelay(50);
4050c6f73aabSFrançois Tigeot 
4051c6f73aabSFrançois Tigeot 	/* disable mem access */
4052c6f73aabSFrançois Tigeot 	evergreen_mc_stop(rdev, &save);
4053c6f73aabSFrançois Tigeot 	if (evergreen_mc_wait_for_idle(rdev)) {
4054c6f73aabSFrançois Tigeot 		dev_warn(rdev->dev, "Wait for MC idle timed out !\n");
4055c6f73aabSFrançois Tigeot 	}
4056c6f73aabSFrançois Tigeot 
4057c6f73aabSFrançois Tigeot 	/* set mclk/sclk to bypass */
4058c6f73aabSFrançois Tigeot 	si_set_clk_bypass_mode(rdev);
4059c6f73aabSFrançois Tigeot 	/* powerdown spll */
4060c6f73aabSFrançois Tigeot 	si_spll_powerdown(rdev);
4061c6f73aabSFrançois Tigeot 	/* disable BM */
4062c59a5c48SFrançois Tigeot 	pci_clear_master(rdev->pdev);
4063c6f73aabSFrançois Tigeot 	/* reset */
4064c6f73aabSFrançois Tigeot 	radeon_pci_config_reset(rdev);
4065c6f73aabSFrançois Tigeot 	/* wait for asic to come out of reset */
4066c6f73aabSFrançois Tigeot 	for (i = 0; i < rdev->usec_timeout; i++) {
4067c6f73aabSFrançois Tigeot 		if (RREG32(CONFIG_MEMSIZE) != 0xffffffff)
4068c6f73aabSFrançois Tigeot 			break;
4069c6f73aabSFrançois Tigeot 		udelay(1);
4070c6f73aabSFrançois Tigeot 	}
4071c6f73aabSFrançois Tigeot }
4072c6f73aabSFrançois Tigeot 
si_asic_reset(struct radeon_device * rdev,bool hard)4073d78d3a22SFrançois Tigeot int si_asic_reset(struct radeon_device *rdev, bool hard)
4074926deccbSFrançois Tigeot {
4075b403bed8SMichael Neumann 	u32 reset_mask;
4076b403bed8SMichael Neumann 
4077d78d3a22SFrançois Tigeot 	if (hard) {
4078d78d3a22SFrançois Tigeot 		si_gpu_pci_config_reset(rdev);
4079d78d3a22SFrançois Tigeot 		return 0;
4080d78d3a22SFrançois Tigeot 	}
4081d78d3a22SFrançois Tigeot 
4082b403bed8SMichael Neumann 	reset_mask = si_gpu_check_soft_reset(rdev);
4083b403bed8SMichael Neumann 
4084b403bed8SMichael Neumann 	if (reset_mask)
4085b403bed8SMichael Neumann 		r600_set_bios_scratch_engine_hung(rdev, true);
4086b403bed8SMichael Neumann 
4087c6f73aabSFrançois Tigeot 	/* try soft reset */
4088b403bed8SMichael Neumann 	si_gpu_soft_reset(rdev, reset_mask);
4089b403bed8SMichael Neumann 
4090b403bed8SMichael Neumann 	reset_mask = si_gpu_check_soft_reset(rdev);
4091b403bed8SMichael Neumann 
4092c6f73aabSFrançois Tigeot 	/* try pci config reset */
4093c6f73aabSFrançois Tigeot 	if (reset_mask && radeon_hard_reset)
4094c6f73aabSFrançois Tigeot 		si_gpu_pci_config_reset(rdev);
4095c6f73aabSFrançois Tigeot 
4096c6f73aabSFrançois Tigeot 	reset_mask = si_gpu_check_soft_reset(rdev);
4097c6f73aabSFrançois Tigeot 
4098b403bed8SMichael Neumann 	if (!reset_mask)
4099b403bed8SMichael Neumann 		r600_set_bios_scratch_engine_hung(rdev, false);
4100b403bed8SMichael Neumann 
4101b403bed8SMichael Neumann 	return 0;
4102b403bed8SMichael Neumann }
4103b403bed8SMichael Neumann 
4104b403bed8SMichael Neumann /**
4105b403bed8SMichael Neumann  * si_gfx_is_lockup - Check if the GFX engine is locked up
4106b403bed8SMichael Neumann  *
4107b403bed8SMichael Neumann  * @rdev: radeon_device pointer
4108b403bed8SMichael Neumann  * @ring: radeon_ring structure holding ring information
4109b403bed8SMichael Neumann  *
4110b403bed8SMichael Neumann  * Check if the GFX engine is locked up.
4111b403bed8SMichael Neumann  * Returns true if the engine appears to be locked up, false if not.
4112b403bed8SMichael Neumann  */
si_gfx_is_lockup(struct radeon_device * rdev,struct radeon_ring * ring)4113b403bed8SMichael Neumann bool si_gfx_is_lockup(struct radeon_device *rdev, struct radeon_ring *ring)
4114b403bed8SMichael Neumann {
4115b403bed8SMichael Neumann 	u32 reset_mask = si_gpu_check_soft_reset(rdev);
4116b403bed8SMichael Neumann 
4117b403bed8SMichael Neumann 	if (!(reset_mask & (RADEON_RESET_GFX |
4118926deccbSFrançois Tigeot 			    RADEON_RESET_COMPUTE |
4119b403bed8SMichael Neumann 			    RADEON_RESET_CP))) {
4120c6f73aabSFrançois Tigeot 		radeon_ring_lockup_update(rdev, ring);
4121b403bed8SMichael Neumann 		return false;
4122b403bed8SMichael Neumann 	}
4123b403bed8SMichael Neumann 	return radeon_ring_test_lockup(rdev, ring);
4124b403bed8SMichael Neumann }
4125b403bed8SMichael Neumann 
4126926deccbSFrançois Tigeot /* MC */
si_mc_program(struct radeon_device * rdev)4127926deccbSFrançois Tigeot static void si_mc_program(struct radeon_device *rdev)
4128926deccbSFrançois Tigeot {
4129926deccbSFrançois Tigeot 	struct evergreen_mc_save save;
4130926deccbSFrançois Tigeot 	u32 tmp;
4131926deccbSFrançois Tigeot 	int i, j;
4132926deccbSFrançois Tigeot 
4133926deccbSFrançois Tigeot 	/* Initialize HDP */
4134926deccbSFrançois Tigeot 	for (i = 0, j = 0; i < 32; i++, j += 0x18) {
4135926deccbSFrançois Tigeot 		WREG32((0x2c14 + j), 0x00000000);
4136926deccbSFrançois Tigeot 		WREG32((0x2c18 + j), 0x00000000);
4137926deccbSFrançois Tigeot 		WREG32((0x2c1c + j), 0x00000000);
4138926deccbSFrançois Tigeot 		WREG32((0x2c20 + j), 0x00000000);
4139926deccbSFrançois Tigeot 		WREG32((0x2c24 + j), 0x00000000);
4140926deccbSFrançois Tigeot 	}
4141926deccbSFrançois Tigeot 	WREG32(HDP_REG_COHERENCY_FLUSH_CNTL, 0);
4142926deccbSFrançois Tigeot 
4143926deccbSFrançois Tigeot 	evergreen_mc_stop(rdev, &save);
4144926deccbSFrançois Tigeot 	if (radeon_mc_wait_for_idle(rdev)) {
4145926deccbSFrançois Tigeot 		dev_warn(rdev->dev, "Wait for MC idle timedout !\n");
4146926deccbSFrançois Tigeot 	}
4147f43cf1b1SMichael Neumann 	if (!ASIC_IS_NODCE(rdev))
4148926deccbSFrançois Tigeot 		/* Lockout access through VGA aperture*/
4149926deccbSFrançois Tigeot 		WREG32(VGA_HDP_CONTROL, VGA_MEMORY_DISABLE);
4150926deccbSFrançois Tigeot 	/* Update configuration */
4151926deccbSFrançois Tigeot 	WREG32(MC_VM_SYSTEM_APERTURE_LOW_ADDR,
4152926deccbSFrançois Tigeot 	       rdev->mc.vram_start >> 12);
4153926deccbSFrançois Tigeot 	WREG32(MC_VM_SYSTEM_APERTURE_HIGH_ADDR,
4154926deccbSFrançois Tigeot 	       rdev->mc.vram_end >> 12);
4155926deccbSFrançois Tigeot 	WREG32(MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR,
4156926deccbSFrançois Tigeot 	       rdev->vram_scratch.gpu_addr >> 12);
4157926deccbSFrançois Tigeot 	tmp = ((rdev->mc.vram_end >> 24) & 0xFFFF) << 16;
4158926deccbSFrançois Tigeot 	tmp |= ((rdev->mc.vram_start >> 24) & 0xFFFF);
4159926deccbSFrançois Tigeot 	WREG32(MC_VM_FB_LOCATION, tmp);
4160926deccbSFrançois Tigeot 	/* XXX double check these! */
4161926deccbSFrançois Tigeot 	WREG32(HDP_NONSURFACE_BASE, (rdev->mc.vram_start >> 8));
4162926deccbSFrançois Tigeot 	WREG32(HDP_NONSURFACE_INFO, (2 << 7) | (1 << 30));
4163926deccbSFrançois Tigeot 	WREG32(HDP_NONSURFACE_SIZE, 0x3FFFFFFF);
4164926deccbSFrançois Tigeot 	WREG32(MC_VM_AGP_BASE, 0);
4165926deccbSFrançois Tigeot 	WREG32(MC_VM_AGP_TOP, 0x0FFFFFFF);
4166926deccbSFrançois Tigeot 	WREG32(MC_VM_AGP_BOT, 0x0FFFFFFF);
4167926deccbSFrançois Tigeot 	if (radeon_mc_wait_for_idle(rdev)) {
4168926deccbSFrançois Tigeot 		dev_warn(rdev->dev, "Wait for MC idle timedout !\n");
4169926deccbSFrançois Tigeot 	}
4170926deccbSFrançois Tigeot 	evergreen_mc_resume(rdev, &save);
4171f43cf1b1SMichael Neumann 	if (!ASIC_IS_NODCE(rdev)) {
4172926deccbSFrançois Tigeot 		/* we need to own VRAM, so turn off the VGA renderer here
4173926deccbSFrançois Tigeot 		 * to stop it overwriting our objects */
4174926deccbSFrançois Tigeot 		rv515_vga_render_disable(rdev);
4175926deccbSFrançois Tigeot 	}
4176926deccbSFrançois Tigeot }
4177926deccbSFrançois Tigeot 
si_vram_gtt_location(struct radeon_device * rdev,struct radeon_mc * mc)417857e252bfSMichael Neumann void si_vram_gtt_location(struct radeon_device *rdev,
4179926deccbSFrançois Tigeot 			  struct radeon_mc *mc)
4180926deccbSFrançois Tigeot {
4181926deccbSFrançois Tigeot 	if (mc->mc_vram_size > 0xFFC0000000ULL) {
4182926deccbSFrançois Tigeot 		/* leave room for at least 1024M GTT */
4183926deccbSFrançois Tigeot 		dev_warn(rdev->dev, "limiting VRAM\n");
4184926deccbSFrançois Tigeot 		mc->real_vram_size = 0xFFC0000000ULL;
4185926deccbSFrançois Tigeot 		mc->mc_vram_size = 0xFFC0000000ULL;
4186926deccbSFrançois Tigeot 	}
4187f43cf1b1SMichael Neumann 	radeon_vram_location(rdev, &rdev->mc, 0);
4188926deccbSFrançois Tigeot 	rdev->mc.gtt_base_align = 0;
4189f43cf1b1SMichael Neumann 	radeon_gtt_location(rdev, mc);
4190926deccbSFrançois Tigeot }
4191926deccbSFrançois Tigeot 
si_mc_init(struct radeon_device * rdev)4192926deccbSFrançois Tigeot static int si_mc_init(struct radeon_device *rdev)
4193926deccbSFrançois Tigeot {
4194926deccbSFrançois Tigeot 	u32 tmp;
4195926deccbSFrançois Tigeot 	int chansize, numchan;
4196926deccbSFrançois Tigeot 
4197926deccbSFrançois Tigeot 	/* Get VRAM informations */
4198926deccbSFrançois Tigeot 	rdev->mc.vram_is_ddr = true;
4199926deccbSFrançois Tigeot 	tmp = RREG32(MC_ARB_RAMCFG);
4200926deccbSFrançois Tigeot 	if (tmp & CHANSIZE_OVERRIDE) {
4201926deccbSFrançois Tigeot 		chansize = 16;
4202926deccbSFrançois Tigeot 	} else if (tmp & CHANSIZE_MASK) {
4203926deccbSFrançois Tigeot 		chansize = 64;
4204926deccbSFrançois Tigeot 	} else {
4205926deccbSFrançois Tigeot 		chansize = 32;
4206926deccbSFrançois Tigeot 	}
4207926deccbSFrançois Tigeot 	tmp = RREG32(MC_SHARED_CHMAP);
4208926deccbSFrançois Tigeot 	switch ((tmp & NOOFCHAN_MASK) >> NOOFCHAN_SHIFT) {
4209926deccbSFrançois Tigeot 	case 0:
4210926deccbSFrançois Tigeot 	default:
4211926deccbSFrançois Tigeot 		numchan = 1;
4212926deccbSFrançois Tigeot 		break;
4213926deccbSFrançois Tigeot 	case 1:
4214926deccbSFrançois Tigeot 		numchan = 2;
4215926deccbSFrançois Tigeot 		break;
4216926deccbSFrançois Tigeot 	case 2:
4217926deccbSFrançois Tigeot 		numchan = 4;
4218926deccbSFrançois Tigeot 		break;
4219926deccbSFrançois Tigeot 	case 3:
4220926deccbSFrançois Tigeot 		numchan = 8;
4221926deccbSFrançois Tigeot 		break;
4222926deccbSFrançois Tigeot 	case 4:
4223926deccbSFrançois Tigeot 		numchan = 3;
4224926deccbSFrançois Tigeot 		break;
4225926deccbSFrançois Tigeot 	case 5:
4226926deccbSFrançois Tigeot 		numchan = 6;
4227926deccbSFrançois Tigeot 		break;
4228926deccbSFrançois Tigeot 	case 6:
4229926deccbSFrançois Tigeot 		numchan = 10;
4230926deccbSFrançois Tigeot 		break;
4231926deccbSFrançois Tigeot 	case 7:
4232926deccbSFrançois Tigeot 		numchan = 12;
4233926deccbSFrançois Tigeot 		break;
4234926deccbSFrançois Tigeot 	case 8:
4235926deccbSFrançois Tigeot 		numchan = 16;
4236926deccbSFrançois Tigeot 		break;
4237926deccbSFrançois Tigeot 	}
4238926deccbSFrançois Tigeot 	rdev->mc.vram_width = numchan * chansize;
4239926deccbSFrançois Tigeot 	/* Could aper size report 0 ? */
42404a26d795SImre Vadasz 	rdev->mc.aper_base = pci_resource_start(rdev->pdev, 0);
42414a26d795SImre Vadasz 	rdev->mc.aper_size = pci_resource_len(rdev->pdev, 0);
4242926deccbSFrançois Tigeot 	/* size in MB on si */
4243c6f73aabSFrançois Tigeot 	tmp = RREG32(CONFIG_MEMSIZE);
4244c6f73aabSFrançois Tigeot 	/* some boards may have garbage in the upper 16 bits */
4245c6f73aabSFrançois Tigeot 	if (tmp & 0xffff0000) {
4246c6f73aabSFrançois Tigeot 		DRM_INFO("Probable bad vram size: 0x%08x\n", tmp);
4247c6f73aabSFrançois Tigeot 		if (tmp & 0xffff)
4248c6f73aabSFrançois Tigeot 			tmp &= 0xffff;
4249c6f73aabSFrançois Tigeot 	}
4250c6f73aabSFrançois Tigeot 	rdev->mc.mc_vram_size = tmp * 1024ULL * 1024ULL;
4251c6f73aabSFrançois Tigeot 	rdev->mc.real_vram_size = rdev->mc.mc_vram_size;
4252926deccbSFrançois Tigeot 	rdev->mc.visible_vram_size = rdev->mc.aper_size;
4253926deccbSFrançois Tigeot 	si_vram_gtt_location(rdev, &rdev->mc);
4254926deccbSFrançois Tigeot 	radeon_update_bandwidth_info(rdev);
4255926deccbSFrançois Tigeot 
4256926deccbSFrançois Tigeot 	return 0;
4257926deccbSFrançois Tigeot }
4258926deccbSFrançois Tigeot 
4259926deccbSFrançois Tigeot /*
4260926deccbSFrançois Tigeot  * GART
4261926deccbSFrançois Tigeot  */
si_pcie_gart_tlb_flush(struct radeon_device * rdev)4262926deccbSFrançois Tigeot void si_pcie_gart_tlb_flush(struct radeon_device *rdev)
4263926deccbSFrançois Tigeot {
4264926deccbSFrançois Tigeot 	/* flush hdp cache */
4265926deccbSFrançois Tigeot 	WREG32(HDP_MEM_COHERENCY_FLUSH_CNTL, 0x1);
4266926deccbSFrançois Tigeot 
4267926deccbSFrançois Tigeot 	/* bits 0-15 are the VM contexts0-15 */
4268926deccbSFrançois Tigeot 	WREG32(VM_INVALIDATE_REQUEST, 1);
4269926deccbSFrançois Tigeot }
4270926deccbSFrançois Tigeot 
si_pcie_gart_enable(struct radeon_device * rdev)4271926deccbSFrançois Tigeot static int si_pcie_gart_enable(struct radeon_device *rdev)
4272926deccbSFrançois Tigeot {
4273926deccbSFrançois Tigeot 	int r, i;
4274926deccbSFrançois Tigeot 
4275926deccbSFrançois Tigeot 	if (rdev->gart.robj == NULL) {
4276926deccbSFrançois Tigeot 		dev_err(rdev->dev, "No VRAM object for PCIE GART.\n");
4277926deccbSFrançois Tigeot 		return -EINVAL;
4278926deccbSFrançois Tigeot 	}
4279926deccbSFrançois Tigeot 	r = radeon_gart_table_vram_pin(rdev);
4280926deccbSFrançois Tigeot 	if (r)
4281926deccbSFrançois Tigeot 		return r;
4282926deccbSFrançois Tigeot 	/* Setup TLB control */
4283926deccbSFrançois Tigeot 	WREG32(MC_VM_MX_L1_TLB_CNTL,
4284926deccbSFrançois Tigeot 	       (0xA << 7) |
4285926deccbSFrançois Tigeot 	       ENABLE_L1_TLB |
4286c6f73aabSFrançois Tigeot 	       ENABLE_L1_FRAGMENT_PROCESSING |
4287926deccbSFrançois Tigeot 	       SYSTEM_ACCESS_MODE_NOT_IN_SYS |
4288926deccbSFrançois Tigeot 	       ENABLE_ADVANCED_DRIVER_MODEL |
4289926deccbSFrançois Tigeot 	       SYSTEM_APERTURE_UNMAPPED_ACCESS_PASS_THRU);
4290926deccbSFrançois Tigeot 	/* Setup L2 cache */
4291926deccbSFrançois Tigeot 	WREG32(VM_L2_CNTL, ENABLE_L2_CACHE |
4292c6f73aabSFrançois Tigeot 	       ENABLE_L2_FRAGMENT_PROCESSING |
4293926deccbSFrançois Tigeot 	       ENABLE_L2_PTE_CACHE_LRU_UPDATE_BY_WRITE |
4294926deccbSFrançois Tigeot 	       ENABLE_L2_PDE0_CACHE_LRU_UPDATE_BY_WRITE |
4295926deccbSFrançois Tigeot 	       EFFECTIVE_L2_QUEUE_SIZE(7) |
4296926deccbSFrançois Tigeot 	       CONTEXT1_IDENTITY_ACCESS_MODE(1));
4297926deccbSFrançois Tigeot 	WREG32(VM_L2_CNTL2, INVALIDATE_ALL_L1_TLBS | INVALIDATE_L2_CACHE);
4298926deccbSFrançois Tigeot 	WREG32(VM_L2_CNTL3, L2_CACHE_BIGK_ASSOCIATIVITY |
4299c6f73aabSFrançois Tigeot 	       BANK_SELECT(4) |
4300c6f73aabSFrançois Tigeot 	       L2_CACHE_BIGK_FRAGMENT_SIZE(4));
4301926deccbSFrançois Tigeot 	/* setup context0 */
4302926deccbSFrançois Tigeot 	WREG32(VM_CONTEXT0_PAGE_TABLE_START_ADDR, rdev->mc.gtt_start >> 12);
4303926deccbSFrançois Tigeot 	WREG32(VM_CONTEXT0_PAGE_TABLE_END_ADDR, rdev->mc.gtt_end >> 12);
4304926deccbSFrançois Tigeot 	WREG32(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR, rdev->gart.table_addr >> 12);
4305926deccbSFrançois Tigeot 	WREG32(VM_CONTEXT0_PROTECTION_FAULT_DEFAULT_ADDR,
4306926deccbSFrançois Tigeot 			(u32)(rdev->dummy_page.addr >> 12));
4307926deccbSFrançois Tigeot 	WREG32(VM_CONTEXT0_CNTL2, 0);
4308926deccbSFrançois Tigeot 	WREG32(VM_CONTEXT0_CNTL, (ENABLE_CONTEXT | PAGE_TABLE_DEPTH(0) |
4309926deccbSFrançois Tigeot 				  RANGE_PROTECTION_FAULT_ENABLE_DEFAULT));
4310926deccbSFrançois Tigeot 
4311926deccbSFrançois Tigeot 	WREG32(0x15D4, 0);
4312926deccbSFrançois Tigeot 	WREG32(0x15D8, 0);
4313926deccbSFrançois Tigeot 	WREG32(0x15DC, 0);
4314926deccbSFrançois Tigeot 
4315926deccbSFrançois Tigeot 	/* empty context1-15 */
4316926deccbSFrançois Tigeot 	/* set vm size, must be a multiple of 4 */
4317926deccbSFrançois Tigeot 	WREG32(VM_CONTEXT1_PAGE_TABLE_START_ADDR, 0);
4318c59a5c48SFrançois Tigeot 	WREG32(VM_CONTEXT1_PAGE_TABLE_END_ADDR, rdev->vm_manager.max_pfn - 1);
4319926deccbSFrançois Tigeot 	/* Assign the pt base to something valid for now; the pts used for
4320926deccbSFrançois Tigeot 	 * the VMs are determined by the application and setup and assigned
4321926deccbSFrançois Tigeot 	 * on the fly in the vm part of radeon_gart.c
4322926deccbSFrançois Tigeot 	 */
4323926deccbSFrançois Tigeot 	for (i = 1; i < 16; i++) {
4324926deccbSFrançois Tigeot 		if (i < 8)
4325926deccbSFrançois Tigeot 			WREG32(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR + (i << 2),
4326c6f73aabSFrançois Tigeot 			       rdev->vm_manager.saved_table_addr[i]);
4327926deccbSFrançois Tigeot 		else
4328926deccbSFrançois Tigeot 			WREG32(VM_CONTEXT8_PAGE_TABLE_BASE_ADDR + ((i - 8) << 2),
4329c6f73aabSFrançois Tigeot 			       rdev->vm_manager.saved_table_addr[i]);
4330926deccbSFrançois Tigeot 	}
4331926deccbSFrançois Tigeot 
4332926deccbSFrançois Tigeot 	/* enable context1-15 */
4333926deccbSFrançois Tigeot 	WREG32(VM_CONTEXT1_PROTECTION_FAULT_DEFAULT_ADDR,
4334926deccbSFrançois Tigeot 	       (u32)(rdev->dummy_page.addr >> 12));
4335926deccbSFrançois Tigeot 	WREG32(VM_CONTEXT1_CNTL2, 4);
4336926deccbSFrançois Tigeot 	WREG32(VM_CONTEXT1_CNTL, ENABLE_CONTEXT | PAGE_TABLE_DEPTH(1) |
4337c6f73aabSFrançois Tigeot 				PAGE_TABLE_BLOCK_SIZE(radeon_vm_block_size - 9) |
4338926deccbSFrançois Tigeot 				RANGE_PROTECTION_FAULT_ENABLE_INTERRUPT |
4339926deccbSFrançois Tigeot 				RANGE_PROTECTION_FAULT_ENABLE_DEFAULT |
4340926deccbSFrançois Tigeot 				DUMMY_PAGE_PROTECTION_FAULT_ENABLE_INTERRUPT |
4341926deccbSFrançois Tigeot 				DUMMY_PAGE_PROTECTION_FAULT_ENABLE_DEFAULT |
4342926deccbSFrançois Tigeot 				PDE0_PROTECTION_FAULT_ENABLE_INTERRUPT |
4343926deccbSFrançois Tigeot 				PDE0_PROTECTION_FAULT_ENABLE_DEFAULT |
4344926deccbSFrançois Tigeot 				VALID_PROTECTION_FAULT_ENABLE_INTERRUPT |
4345926deccbSFrançois Tigeot 				VALID_PROTECTION_FAULT_ENABLE_DEFAULT |
4346926deccbSFrançois Tigeot 				READ_PROTECTION_FAULT_ENABLE_INTERRUPT |
4347926deccbSFrançois Tigeot 				READ_PROTECTION_FAULT_ENABLE_DEFAULT |
4348926deccbSFrançois Tigeot 				WRITE_PROTECTION_FAULT_ENABLE_INTERRUPT |
4349926deccbSFrançois Tigeot 				WRITE_PROTECTION_FAULT_ENABLE_DEFAULT);
4350926deccbSFrançois Tigeot 
4351926deccbSFrançois Tigeot 	si_pcie_gart_tlb_flush(rdev);
4352926deccbSFrançois Tigeot 	DRM_INFO("PCIE GART of %uM enabled (table at 0x%016llX).\n",
4353926deccbSFrançois Tigeot 		 (unsigned)(rdev->mc.gtt_size >> 20),
4354926deccbSFrançois Tigeot 		 (unsigned long long)rdev->gart.table_addr);
4355926deccbSFrançois Tigeot 	rdev->gart.ready = true;
4356926deccbSFrançois Tigeot 	return 0;
4357926deccbSFrançois Tigeot }
4358926deccbSFrançois Tigeot 
si_pcie_gart_disable(struct radeon_device * rdev)4359926deccbSFrançois Tigeot static void si_pcie_gart_disable(struct radeon_device *rdev)
4360926deccbSFrançois Tigeot {
4361c6f73aabSFrançois Tigeot 	unsigned i;
4362c6f73aabSFrançois Tigeot 
4363c6f73aabSFrançois Tigeot 	for (i = 1; i < 16; ++i) {
4364c6f73aabSFrançois Tigeot 		uint32_t reg;
4365c6f73aabSFrançois Tigeot 		if (i < 8)
4366c6f73aabSFrançois Tigeot 			reg = VM_CONTEXT0_PAGE_TABLE_BASE_ADDR + (i << 2);
4367c6f73aabSFrançois Tigeot 		else
4368c6f73aabSFrançois Tigeot 			reg = VM_CONTEXT8_PAGE_TABLE_BASE_ADDR + ((i - 8) << 2);
4369c6f73aabSFrançois Tigeot 		rdev->vm_manager.saved_table_addr[i] = RREG32(reg);
4370c6f73aabSFrançois Tigeot 	}
4371c6f73aabSFrançois Tigeot 
4372926deccbSFrançois Tigeot 	/* Disable all tables */
4373926deccbSFrançois Tigeot 	WREG32(VM_CONTEXT0_CNTL, 0);
4374926deccbSFrançois Tigeot 	WREG32(VM_CONTEXT1_CNTL, 0);
4375926deccbSFrançois Tigeot 	/* Setup TLB control */
4376926deccbSFrançois Tigeot 	WREG32(MC_VM_MX_L1_TLB_CNTL, SYSTEM_ACCESS_MODE_NOT_IN_SYS |
4377926deccbSFrançois Tigeot 	       SYSTEM_APERTURE_UNMAPPED_ACCESS_PASS_THRU);
4378926deccbSFrançois Tigeot 	/* Setup L2 cache */
4379926deccbSFrançois Tigeot 	WREG32(VM_L2_CNTL, ENABLE_L2_PTE_CACHE_LRU_UPDATE_BY_WRITE |
4380926deccbSFrançois Tigeot 	       ENABLE_L2_PDE0_CACHE_LRU_UPDATE_BY_WRITE |
4381926deccbSFrançois Tigeot 	       EFFECTIVE_L2_QUEUE_SIZE(7) |
4382926deccbSFrançois Tigeot 	       CONTEXT1_IDENTITY_ACCESS_MODE(1));
4383926deccbSFrançois Tigeot 	WREG32(VM_L2_CNTL2, 0);
4384926deccbSFrançois Tigeot 	WREG32(VM_L2_CNTL3, L2_CACHE_BIGK_ASSOCIATIVITY |
4385926deccbSFrançois Tigeot 	       L2_CACHE_BIGK_FRAGMENT_SIZE(0));
4386926deccbSFrançois Tigeot 	radeon_gart_table_vram_unpin(rdev);
4387926deccbSFrançois Tigeot }
4388926deccbSFrançois Tigeot 
si_pcie_gart_fini(struct radeon_device * rdev)4389926deccbSFrançois Tigeot static void si_pcie_gart_fini(struct radeon_device *rdev)
4390926deccbSFrançois Tigeot {
4391926deccbSFrançois Tigeot 	si_pcie_gart_disable(rdev);
4392926deccbSFrançois Tigeot 	radeon_gart_table_vram_free(rdev);
4393926deccbSFrançois Tigeot 	radeon_gart_fini(rdev);
4394926deccbSFrançois Tigeot }
4395926deccbSFrançois Tigeot 
4396926deccbSFrançois Tigeot /* vm parser */
si_vm_reg_valid(u32 reg)4397926deccbSFrançois Tigeot static bool si_vm_reg_valid(u32 reg)
4398926deccbSFrançois Tigeot {
4399926deccbSFrançois Tigeot 	/* context regs are fine */
4400926deccbSFrançois Tigeot 	if (reg >= 0x28000)
4401926deccbSFrançois Tigeot 		return true;
4402926deccbSFrançois Tigeot 
4403d78d3a22SFrançois Tigeot 	/* shader regs are also fine */
4404d78d3a22SFrançois Tigeot 	if (reg >= 0xB000 && reg < 0xC000)
4405d78d3a22SFrançois Tigeot 		return true;
4406d78d3a22SFrançois Tigeot 
4407926deccbSFrançois Tigeot 	/* check config regs */
4408926deccbSFrançois Tigeot 	switch (reg) {
4409926deccbSFrançois Tigeot 	case GRBM_GFX_INDEX:
4410926deccbSFrançois Tigeot 	case CP_STRMOUT_CNTL:
4411926deccbSFrançois Tigeot 	case VGT_VTX_VECT_EJECT_REG:
4412926deccbSFrançois Tigeot 	case VGT_CACHE_INVALIDATION:
4413926deccbSFrançois Tigeot 	case VGT_ESGS_RING_SIZE:
4414926deccbSFrançois Tigeot 	case VGT_GSVS_RING_SIZE:
4415926deccbSFrançois Tigeot 	case VGT_GS_VERTEX_REUSE:
4416926deccbSFrançois Tigeot 	case VGT_PRIMITIVE_TYPE:
4417926deccbSFrançois Tigeot 	case VGT_INDEX_TYPE:
4418926deccbSFrançois Tigeot 	case VGT_NUM_INDICES:
4419926deccbSFrançois Tigeot 	case VGT_NUM_INSTANCES:
4420926deccbSFrançois Tigeot 	case VGT_TF_RING_SIZE:
4421926deccbSFrançois Tigeot 	case VGT_HS_OFFCHIP_PARAM:
4422926deccbSFrançois Tigeot 	case VGT_TF_MEMORY_BASE:
4423926deccbSFrançois Tigeot 	case PA_CL_ENHANCE:
4424926deccbSFrançois Tigeot 	case PA_SU_LINE_STIPPLE_VALUE:
4425926deccbSFrançois Tigeot 	case PA_SC_LINE_STIPPLE_STATE:
4426926deccbSFrançois Tigeot 	case PA_SC_ENHANCE:
4427926deccbSFrançois Tigeot 	case SQC_CACHES:
4428926deccbSFrançois Tigeot 	case SPI_STATIC_THREAD_MGMT_1:
4429926deccbSFrançois Tigeot 	case SPI_STATIC_THREAD_MGMT_2:
4430926deccbSFrançois Tigeot 	case SPI_STATIC_THREAD_MGMT_3:
4431926deccbSFrançois Tigeot 	case SPI_PS_MAX_WAVE_ID:
4432926deccbSFrançois Tigeot 	case SPI_CONFIG_CNTL:
4433926deccbSFrançois Tigeot 	case SPI_CONFIG_CNTL_1:
4434926deccbSFrançois Tigeot 	case TA_CNTL_AUX:
44351dedbd3bSFrançois Tigeot 	case TA_CS_BC_BASE_ADDR:
4436926deccbSFrançois Tigeot 		return true;
4437926deccbSFrançois Tigeot 	default:
4438926deccbSFrançois Tigeot 		DRM_ERROR("Invalid register 0x%x in CS\n", reg);
4439926deccbSFrançois Tigeot 		return false;
4440926deccbSFrançois Tigeot 	}
4441926deccbSFrançois Tigeot }
4442926deccbSFrançois Tigeot 
si_vm_packet3_ce_check(struct radeon_device * rdev,u32 * ib,struct radeon_cs_packet * pkt)4443926deccbSFrançois Tigeot static int si_vm_packet3_ce_check(struct radeon_device *rdev,
4444926deccbSFrançois Tigeot 				  u32 *ib, struct radeon_cs_packet *pkt)
4445926deccbSFrançois Tigeot {
4446926deccbSFrançois Tigeot 	switch (pkt->opcode) {
4447926deccbSFrançois Tigeot 	case PACKET3_NOP:
4448926deccbSFrançois Tigeot 	case PACKET3_SET_BASE:
4449926deccbSFrançois Tigeot 	case PACKET3_SET_CE_DE_COUNTERS:
4450926deccbSFrançois Tigeot 	case PACKET3_LOAD_CONST_RAM:
4451926deccbSFrançois Tigeot 	case PACKET3_WRITE_CONST_RAM:
4452926deccbSFrançois Tigeot 	case PACKET3_WRITE_CONST_RAM_OFFSET:
4453926deccbSFrançois Tigeot 	case PACKET3_DUMP_CONST_RAM:
4454926deccbSFrançois Tigeot 	case PACKET3_INCREMENT_CE_COUNTER:
4455926deccbSFrançois Tigeot 	case PACKET3_WAIT_ON_DE_COUNTER:
4456926deccbSFrançois Tigeot 	case PACKET3_CE_WRITE:
4457926deccbSFrançois Tigeot 		break;
4458926deccbSFrançois Tigeot 	default:
4459926deccbSFrançois Tigeot 		DRM_ERROR("Invalid CE packet3: 0x%x\n", pkt->opcode);
4460926deccbSFrançois Tigeot 		return -EINVAL;
4461926deccbSFrançois Tigeot 	}
4462926deccbSFrançois Tigeot 	return 0;
4463926deccbSFrançois Tigeot }
4464926deccbSFrançois Tigeot 
si_vm_packet3_cp_dma_check(u32 * ib,u32 idx)44654cd92098Szrj static int si_vm_packet3_cp_dma_check(u32 *ib, u32 idx)
44664cd92098Szrj {
44674cd92098Szrj 	u32 start_reg, reg, i;
44684cd92098Szrj 	u32 command = ib[idx + 4];
44694cd92098Szrj 	u32 info = ib[idx + 1];
44704cd92098Szrj 	u32 idx_value = ib[idx];
44714cd92098Szrj 	if (command & PACKET3_CP_DMA_CMD_SAS) {
44724cd92098Szrj 		/* src address space is register */
44734cd92098Szrj 		if (((info & 0x60000000) >> 29) == 0) {
44744cd92098Szrj 			start_reg = idx_value << 2;
44754cd92098Szrj 			if (command & PACKET3_CP_DMA_CMD_SAIC) {
44764cd92098Szrj 				reg = start_reg;
44774cd92098Szrj 				if (!si_vm_reg_valid(reg)) {
44784cd92098Szrj 					DRM_ERROR("CP DMA Bad SRC register\n");
44794cd92098Szrj 					return -EINVAL;
44804cd92098Szrj 				}
44814cd92098Szrj 			} else {
44824cd92098Szrj 				for (i = 0; i < (command & 0x1fffff); i++) {
44834cd92098Szrj 					reg = start_reg + (4 * i);
44844cd92098Szrj 					if (!si_vm_reg_valid(reg)) {
44854cd92098Szrj 						DRM_ERROR("CP DMA Bad SRC register\n");
44864cd92098Szrj 						return -EINVAL;
44874cd92098Szrj 					}
44884cd92098Szrj 				}
44894cd92098Szrj 			}
44904cd92098Szrj 		}
44914cd92098Szrj 	}
44924cd92098Szrj 	if (command & PACKET3_CP_DMA_CMD_DAS) {
44934cd92098Szrj 		/* dst address space is register */
44944cd92098Szrj 		if (((info & 0x00300000) >> 20) == 0) {
44954cd92098Szrj 			start_reg = ib[idx + 2];
44964cd92098Szrj 			if (command & PACKET3_CP_DMA_CMD_DAIC) {
44974cd92098Szrj 				reg = start_reg;
44984cd92098Szrj 				if (!si_vm_reg_valid(reg)) {
44994cd92098Szrj 					DRM_ERROR("CP DMA Bad DST register\n");
45004cd92098Szrj 					return -EINVAL;
45014cd92098Szrj 				}
45024cd92098Szrj 			} else {
45034cd92098Szrj 				for (i = 0; i < (command & 0x1fffff); i++) {
45044cd92098Szrj 					reg = start_reg + (4 * i);
45054cd92098Szrj 				if (!si_vm_reg_valid(reg)) {
45064cd92098Szrj 						DRM_ERROR("CP DMA Bad DST register\n");
45074cd92098Szrj 						return -EINVAL;
45084cd92098Szrj 					}
45094cd92098Szrj 				}
45104cd92098Szrj 			}
45114cd92098Szrj 		}
45124cd92098Szrj 	}
45134cd92098Szrj 	return 0;
45144cd92098Szrj }
45154cd92098Szrj 
si_vm_packet3_gfx_check(struct radeon_device * rdev,u32 * ib,struct radeon_cs_packet * pkt)4516926deccbSFrançois Tigeot static int si_vm_packet3_gfx_check(struct radeon_device *rdev,
4517926deccbSFrançois Tigeot 				   u32 *ib, struct radeon_cs_packet *pkt)
4518926deccbSFrançois Tigeot {
45194cd92098Szrj 	int r;
4520926deccbSFrançois Tigeot 	u32 idx = pkt->idx + 1;
4521926deccbSFrançois Tigeot 	u32 idx_value = ib[idx];
4522926deccbSFrançois Tigeot 	u32 start_reg, end_reg, reg, i;
4523926deccbSFrançois Tigeot 
4524926deccbSFrançois Tigeot 	switch (pkt->opcode) {
4525926deccbSFrançois Tigeot 	case PACKET3_NOP:
4526926deccbSFrançois Tigeot 	case PACKET3_SET_BASE:
4527926deccbSFrançois Tigeot 	case PACKET3_CLEAR_STATE:
4528926deccbSFrançois Tigeot 	case PACKET3_INDEX_BUFFER_SIZE:
4529926deccbSFrançois Tigeot 	case PACKET3_DISPATCH_DIRECT:
4530926deccbSFrançois Tigeot 	case PACKET3_DISPATCH_INDIRECT:
4531926deccbSFrançois Tigeot 	case PACKET3_ALLOC_GDS:
4532926deccbSFrançois Tigeot 	case PACKET3_WRITE_GDS_RAM:
4533926deccbSFrançois Tigeot 	case PACKET3_ATOMIC_GDS:
4534926deccbSFrançois Tigeot 	case PACKET3_ATOMIC:
4535926deccbSFrançois Tigeot 	case PACKET3_OCCLUSION_QUERY:
4536926deccbSFrançois Tigeot 	case PACKET3_SET_PREDICATION:
4537926deccbSFrançois Tigeot 	case PACKET3_COND_EXEC:
4538926deccbSFrançois Tigeot 	case PACKET3_PRED_EXEC:
4539926deccbSFrançois Tigeot 	case PACKET3_DRAW_INDIRECT:
4540926deccbSFrançois Tigeot 	case PACKET3_DRAW_INDEX_INDIRECT:
4541926deccbSFrançois Tigeot 	case PACKET3_INDEX_BASE:
4542926deccbSFrançois Tigeot 	case PACKET3_DRAW_INDEX_2:
4543926deccbSFrançois Tigeot 	case PACKET3_CONTEXT_CONTROL:
4544926deccbSFrançois Tigeot 	case PACKET3_INDEX_TYPE:
4545926deccbSFrançois Tigeot 	case PACKET3_DRAW_INDIRECT_MULTI:
4546926deccbSFrançois Tigeot 	case PACKET3_DRAW_INDEX_AUTO:
4547926deccbSFrançois Tigeot 	case PACKET3_DRAW_INDEX_IMMD:
4548926deccbSFrançois Tigeot 	case PACKET3_NUM_INSTANCES:
4549926deccbSFrançois Tigeot 	case PACKET3_DRAW_INDEX_MULTI_AUTO:
4550926deccbSFrançois Tigeot 	case PACKET3_STRMOUT_BUFFER_UPDATE:
4551926deccbSFrançois Tigeot 	case PACKET3_DRAW_INDEX_OFFSET_2:
4552926deccbSFrançois Tigeot 	case PACKET3_DRAW_INDEX_MULTI_ELEMENT:
4553926deccbSFrançois Tigeot 	case PACKET3_DRAW_INDEX_INDIRECT_MULTI:
4554926deccbSFrançois Tigeot 	case PACKET3_MPEG_INDEX:
4555926deccbSFrançois Tigeot 	case PACKET3_WAIT_REG_MEM:
4556926deccbSFrançois Tigeot 	case PACKET3_MEM_WRITE:
4557926deccbSFrançois Tigeot 	case PACKET3_PFP_SYNC_ME:
4558926deccbSFrançois Tigeot 	case PACKET3_SURFACE_SYNC:
4559926deccbSFrançois Tigeot 	case PACKET3_EVENT_WRITE:
4560926deccbSFrançois Tigeot 	case PACKET3_EVENT_WRITE_EOP:
4561926deccbSFrançois Tigeot 	case PACKET3_EVENT_WRITE_EOS:
4562926deccbSFrançois Tigeot 	case PACKET3_SET_CONTEXT_REG:
4563926deccbSFrançois Tigeot 	case PACKET3_SET_CONTEXT_REG_INDIRECT:
4564926deccbSFrançois Tigeot 	case PACKET3_SET_SH_REG:
4565926deccbSFrançois Tigeot 	case PACKET3_SET_SH_REG_OFFSET:
4566926deccbSFrançois Tigeot 	case PACKET3_INCREMENT_DE_COUNTER:
4567926deccbSFrançois Tigeot 	case PACKET3_WAIT_ON_CE_COUNTER:
4568926deccbSFrançois Tigeot 	case PACKET3_WAIT_ON_AVAIL_BUFFER:
4569926deccbSFrançois Tigeot 	case PACKET3_ME_WRITE:
4570926deccbSFrançois Tigeot 		break;
4571926deccbSFrançois Tigeot 	case PACKET3_COPY_DATA:
4572926deccbSFrançois Tigeot 		if ((idx_value & 0xf00) == 0) {
4573926deccbSFrançois Tigeot 			reg = ib[idx + 3] * 4;
4574926deccbSFrançois Tigeot 			if (!si_vm_reg_valid(reg))
4575926deccbSFrançois Tigeot 				return -EINVAL;
4576926deccbSFrançois Tigeot 		}
4577926deccbSFrançois Tigeot 		break;
4578926deccbSFrançois Tigeot 	case PACKET3_WRITE_DATA:
4579926deccbSFrançois Tigeot 		if ((idx_value & 0xf00) == 0) {
4580926deccbSFrançois Tigeot 			start_reg = ib[idx + 1] * 4;
4581926deccbSFrançois Tigeot 			if (idx_value & 0x10000) {
4582926deccbSFrançois Tigeot 				if (!si_vm_reg_valid(start_reg))
4583926deccbSFrançois Tigeot 					return -EINVAL;
4584926deccbSFrançois Tigeot 			} else {
4585926deccbSFrançois Tigeot 				for (i = 0; i < (pkt->count - 2); i++) {
4586926deccbSFrançois Tigeot 					reg = start_reg + (4 * i);
4587926deccbSFrançois Tigeot 					if (!si_vm_reg_valid(reg))
4588926deccbSFrançois Tigeot 						return -EINVAL;
4589926deccbSFrançois Tigeot 				}
4590926deccbSFrançois Tigeot 			}
4591926deccbSFrançois Tigeot 		}
4592926deccbSFrançois Tigeot 		break;
4593926deccbSFrançois Tigeot 	case PACKET3_COND_WRITE:
4594926deccbSFrançois Tigeot 		if (idx_value & 0x100) {
4595926deccbSFrançois Tigeot 			reg = ib[idx + 5] * 4;
4596926deccbSFrançois Tigeot 			if (!si_vm_reg_valid(reg))
4597926deccbSFrançois Tigeot 				return -EINVAL;
4598926deccbSFrançois Tigeot 		}
4599926deccbSFrançois Tigeot 		break;
4600926deccbSFrançois Tigeot 	case PACKET3_COPY_DW:
4601926deccbSFrançois Tigeot 		if (idx_value & 0x2) {
4602926deccbSFrançois Tigeot 			reg = ib[idx + 3] * 4;
4603926deccbSFrançois Tigeot 			if (!si_vm_reg_valid(reg))
4604926deccbSFrançois Tigeot 				return -EINVAL;
4605926deccbSFrançois Tigeot 		}
4606926deccbSFrançois Tigeot 		break;
4607926deccbSFrançois Tigeot 	case PACKET3_SET_CONFIG_REG:
4608926deccbSFrançois Tigeot 		start_reg = (idx_value << 2) + PACKET3_SET_CONFIG_REG_START;
4609926deccbSFrançois Tigeot 		end_reg = 4 * pkt->count + start_reg - 4;
4610926deccbSFrançois Tigeot 		if ((start_reg < PACKET3_SET_CONFIG_REG_START) ||
4611926deccbSFrançois Tigeot 		    (start_reg >= PACKET3_SET_CONFIG_REG_END) ||
4612926deccbSFrançois Tigeot 		    (end_reg >= PACKET3_SET_CONFIG_REG_END)) {
4613926deccbSFrançois Tigeot 			DRM_ERROR("bad PACKET3_SET_CONFIG_REG\n");
4614926deccbSFrançois Tigeot 			return -EINVAL;
4615926deccbSFrançois Tigeot 		}
4616926deccbSFrançois Tigeot 		for (i = 0; i < pkt->count; i++) {
4617926deccbSFrançois Tigeot 			reg = start_reg + (4 * i);
4618926deccbSFrançois Tigeot 			if (!si_vm_reg_valid(reg))
4619926deccbSFrançois Tigeot 				return -EINVAL;
4620926deccbSFrançois Tigeot 		}
4621926deccbSFrançois Tigeot 		break;
4622926deccbSFrançois Tigeot 	case PACKET3_CP_DMA:
46234cd92098Szrj 		r = si_vm_packet3_cp_dma_check(ib, idx);
46244cd92098Szrj 		if (r)
46254cd92098Szrj 			return r;
4626926deccbSFrançois Tigeot 		break;
4627926deccbSFrançois Tigeot 	default:
4628926deccbSFrançois Tigeot 		DRM_ERROR("Invalid GFX packet3: 0x%x\n", pkt->opcode);
4629926deccbSFrançois Tigeot 		return -EINVAL;
4630926deccbSFrançois Tigeot 	}
4631926deccbSFrançois Tigeot 	return 0;
4632926deccbSFrançois Tigeot }
4633926deccbSFrançois Tigeot 
si_vm_packet3_compute_check(struct radeon_device * rdev,u32 * ib,struct radeon_cs_packet * pkt)4634926deccbSFrançois Tigeot static int si_vm_packet3_compute_check(struct radeon_device *rdev,
4635926deccbSFrançois Tigeot 				       u32 *ib, struct radeon_cs_packet *pkt)
4636926deccbSFrançois Tigeot {
46374cd92098Szrj 	int r;
4638926deccbSFrançois Tigeot 	u32 idx = pkt->idx + 1;
4639926deccbSFrançois Tigeot 	u32 idx_value = ib[idx];
4640926deccbSFrançois Tigeot 	u32 start_reg, reg, i;
4641926deccbSFrançois Tigeot 
4642926deccbSFrançois Tigeot 	switch (pkt->opcode) {
4643926deccbSFrançois Tigeot 	case PACKET3_NOP:
4644926deccbSFrançois Tigeot 	case PACKET3_SET_BASE:
4645926deccbSFrançois Tigeot 	case PACKET3_CLEAR_STATE:
4646926deccbSFrançois Tigeot 	case PACKET3_DISPATCH_DIRECT:
4647926deccbSFrançois Tigeot 	case PACKET3_DISPATCH_INDIRECT:
4648926deccbSFrançois Tigeot 	case PACKET3_ALLOC_GDS:
4649926deccbSFrançois Tigeot 	case PACKET3_WRITE_GDS_RAM:
4650926deccbSFrançois Tigeot 	case PACKET3_ATOMIC_GDS:
4651926deccbSFrançois Tigeot 	case PACKET3_ATOMIC:
4652926deccbSFrançois Tigeot 	case PACKET3_OCCLUSION_QUERY:
4653926deccbSFrançois Tigeot 	case PACKET3_SET_PREDICATION:
4654926deccbSFrançois Tigeot 	case PACKET3_COND_EXEC:
4655926deccbSFrançois Tigeot 	case PACKET3_PRED_EXEC:
4656926deccbSFrançois Tigeot 	case PACKET3_CONTEXT_CONTROL:
4657926deccbSFrançois Tigeot 	case PACKET3_STRMOUT_BUFFER_UPDATE:
4658926deccbSFrançois Tigeot 	case PACKET3_WAIT_REG_MEM:
4659926deccbSFrançois Tigeot 	case PACKET3_MEM_WRITE:
4660926deccbSFrançois Tigeot 	case PACKET3_PFP_SYNC_ME:
4661926deccbSFrançois Tigeot 	case PACKET3_SURFACE_SYNC:
4662926deccbSFrançois Tigeot 	case PACKET3_EVENT_WRITE:
4663926deccbSFrançois Tigeot 	case PACKET3_EVENT_WRITE_EOP:
4664926deccbSFrançois Tigeot 	case PACKET3_EVENT_WRITE_EOS:
4665926deccbSFrançois Tigeot 	case PACKET3_SET_CONTEXT_REG:
4666926deccbSFrançois Tigeot 	case PACKET3_SET_CONTEXT_REG_INDIRECT:
4667926deccbSFrançois Tigeot 	case PACKET3_SET_SH_REG:
4668926deccbSFrançois Tigeot 	case PACKET3_SET_SH_REG_OFFSET:
4669926deccbSFrançois Tigeot 	case PACKET3_INCREMENT_DE_COUNTER:
4670926deccbSFrançois Tigeot 	case PACKET3_WAIT_ON_CE_COUNTER:
4671926deccbSFrançois Tigeot 	case PACKET3_WAIT_ON_AVAIL_BUFFER:
4672926deccbSFrançois Tigeot 	case PACKET3_ME_WRITE:
4673926deccbSFrançois Tigeot 		break;
4674926deccbSFrançois Tigeot 	case PACKET3_COPY_DATA:
4675926deccbSFrançois Tigeot 		if ((idx_value & 0xf00) == 0) {
4676926deccbSFrançois Tigeot 			reg = ib[idx + 3] * 4;
4677926deccbSFrançois Tigeot 			if (!si_vm_reg_valid(reg))
4678926deccbSFrançois Tigeot 				return -EINVAL;
4679926deccbSFrançois Tigeot 		}
4680926deccbSFrançois Tigeot 		break;
4681926deccbSFrançois Tigeot 	case PACKET3_WRITE_DATA:
4682926deccbSFrançois Tigeot 		if ((idx_value & 0xf00) == 0) {
4683926deccbSFrançois Tigeot 			start_reg = ib[idx + 1] * 4;
4684926deccbSFrançois Tigeot 			if (idx_value & 0x10000) {
4685926deccbSFrançois Tigeot 				if (!si_vm_reg_valid(start_reg))
4686926deccbSFrançois Tigeot 					return -EINVAL;
4687926deccbSFrançois Tigeot 			} else {
4688926deccbSFrançois Tigeot 				for (i = 0; i < (pkt->count - 2); i++) {
4689926deccbSFrançois Tigeot 					reg = start_reg + (4 * i);
4690926deccbSFrançois Tigeot 					if (!si_vm_reg_valid(reg))
4691926deccbSFrançois Tigeot 						return -EINVAL;
4692926deccbSFrançois Tigeot 				}
4693926deccbSFrançois Tigeot 			}
4694926deccbSFrançois Tigeot 		}
4695926deccbSFrançois Tigeot 		break;
4696926deccbSFrançois Tigeot 	case PACKET3_COND_WRITE:
4697926deccbSFrançois Tigeot 		if (idx_value & 0x100) {
4698926deccbSFrançois Tigeot 			reg = ib[idx + 5] * 4;
4699926deccbSFrançois Tigeot 			if (!si_vm_reg_valid(reg))
4700926deccbSFrançois Tigeot 				return -EINVAL;
4701926deccbSFrançois Tigeot 		}
4702926deccbSFrançois Tigeot 		break;
4703926deccbSFrançois Tigeot 	case PACKET3_COPY_DW:
4704926deccbSFrançois Tigeot 		if (idx_value & 0x2) {
4705926deccbSFrançois Tigeot 			reg = ib[idx + 3] * 4;
4706926deccbSFrançois Tigeot 			if (!si_vm_reg_valid(reg))
4707926deccbSFrançois Tigeot 				return -EINVAL;
4708926deccbSFrançois Tigeot 		}
4709926deccbSFrançois Tigeot 		break;
47104cd92098Szrj 	case PACKET3_CP_DMA:
47114cd92098Szrj 		r = si_vm_packet3_cp_dma_check(ib, idx);
47124cd92098Szrj 		if (r)
47134cd92098Szrj 			return r;
47144cd92098Szrj 		break;
4715926deccbSFrançois Tigeot 	default:
4716926deccbSFrançois Tigeot 		DRM_ERROR("Invalid Compute packet3: 0x%x\n", pkt->opcode);
4717926deccbSFrançois Tigeot 		return -EINVAL;
4718926deccbSFrançois Tigeot 	}
4719926deccbSFrançois Tigeot 	return 0;
4720926deccbSFrançois Tigeot }
4721926deccbSFrançois Tigeot 
si_ib_parse(struct radeon_device * rdev,struct radeon_ib * ib)4722926deccbSFrançois Tigeot int si_ib_parse(struct radeon_device *rdev, struct radeon_ib *ib)
4723926deccbSFrançois Tigeot {
4724926deccbSFrançois Tigeot 	int ret = 0;
4725591d5043SFrançois Tigeot 	u32 idx = 0, i;
4726926deccbSFrançois Tigeot 	struct radeon_cs_packet pkt;
4727926deccbSFrançois Tigeot 
4728926deccbSFrançois Tigeot 	do {
4729926deccbSFrançois Tigeot 		pkt.idx = idx;
4730b403bed8SMichael Neumann 		pkt.type = RADEON_CP_PACKET_GET_TYPE(ib->ptr[idx]);
4731b403bed8SMichael Neumann 		pkt.count = RADEON_CP_PACKET_GET_COUNT(ib->ptr[idx]);
4732926deccbSFrançois Tigeot 		pkt.one_reg_wr = 0;
4733926deccbSFrançois Tigeot 		switch (pkt.type) {
4734b403bed8SMichael Neumann 		case RADEON_PACKET_TYPE0:
4735926deccbSFrançois Tigeot 			dev_err(rdev->dev, "Packet0 not allowed!\n");
4736926deccbSFrançois Tigeot 			ret = -EINVAL;
4737926deccbSFrançois Tigeot 			break;
4738b403bed8SMichael Neumann 		case RADEON_PACKET_TYPE2:
4739926deccbSFrançois Tigeot 			idx += 1;
4740926deccbSFrançois Tigeot 			break;
4741b403bed8SMichael Neumann 		case RADEON_PACKET_TYPE3:
4742b403bed8SMichael Neumann 			pkt.opcode = RADEON_CP_PACKET3_GET_OPCODE(ib->ptr[idx]);
4743926deccbSFrançois Tigeot 			if (ib->is_const_ib)
4744926deccbSFrançois Tigeot 				ret = si_vm_packet3_ce_check(rdev, ib->ptr, &pkt);
4745926deccbSFrançois Tigeot 			else {
4746926deccbSFrançois Tigeot 				switch (ib->ring) {
4747926deccbSFrançois Tigeot 				case RADEON_RING_TYPE_GFX_INDEX:
4748926deccbSFrançois Tigeot 					ret = si_vm_packet3_gfx_check(rdev, ib->ptr, &pkt);
4749926deccbSFrançois Tigeot 					break;
4750926deccbSFrançois Tigeot 				case CAYMAN_RING_TYPE_CP1_INDEX:
4751926deccbSFrançois Tigeot 				case CAYMAN_RING_TYPE_CP2_INDEX:
4752926deccbSFrançois Tigeot 					ret = si_vm_packet3_compute_check(rdev, ib->ptr, &pkt);
4753926deccbSFrançois Tigeot 					break;
4754926deccbSFrançois Tigeot 				default:
4755926deccbSFrançois Tigeot 					dev_err(rdev->dev, "Non-PM4 ring %d !\n", ib->ring);
4756926deccbSFrançois Tigeot 					ret = -EINVAL;
4757926deccbSFrançois Tigeot 					break;
4758926deccbSFrançois Tigeot 				}
4759926deccbSFrançois Tigeot 			}
4760926deccbSFrançois Tigeot 			idx += pkt.count + 2;
4761926deccbSFrançois Tigeot 			break;
4762926deccbSFrançois Tigeot 		default:
4763926deccbSFrançois Tigeot 			dev_err(rdev->dev, "Unknown packet type %d !\n", pkt.type);
4764926deccbSFrançois Tigeot 			ret = -EINVAL;
4765926deccbSFrançois Tigeot 			break;
4766926deccbSFrançois Tigeot 		}
4767c59a5c48SFrançois Tigeot 		if (ret) {
4768c59a5c48SFrançois Tigeot 			for (i = 0; i < ib->length_dw; i++) {
4769c59a5c48SFrançois Tigeot 				if (i == idx)
4770c59a5c48SFrançois Tigeot 					printk("\t0x%08x <---\n", ib->ptr[i]);
4771c59a5c48SFrançois Tigeot 				else
4772c59a5c48SFrançois Tigeot 					printk("\t0x%08x\n", ib->ptr[i]);
4773c59a5c48SFrançois Tigeot 			}
4774926deccbSFrançois Tigeot 			break;
4775c59a5c48SFrançois Tigeot 		}
4776926deccbSFrançois Tigeot 	} while (idx < ib->length_dw);
4777926deccbSFrançois Tigeot 
4778926deccbSFrançois Tigeot 	return ret;
4779926deccbSFrançois Tigeot }
4780926deccbSFrançois Tigeot 
4781926deccbSFrançois Tigeot /*
4782926deccbSFrançois Tigeot  * vm
4783926deccbSFrançois Tigeot  */
si_vm_init(struct radeon_device * rdev)4784926deccbSFrançois Tigeot int si_vm_init(struct radeon_device *rdev)
4785926deccbSFrançois Tigeot {
4786926deccbSFrançois Tigeot 	/* number of VMs */
4787926deccbSFrançois Tigeot 	rdev->vm_manager.nvm = 16;
4788926deccbSFrançois Tigeot 	/* base offset of vram pages */
4789926deccbSFrançois Tigeot 	rdev->vm_manager.vram_base_offset = 0;
4790926deccbSFrançois Tigeot 
4791926deccbSFrançois Tigeot 	return 0;
4792926deccbSFrançois Tigeot }
4793926deccbSFrançois Tigeot 
si_vm_fini(struct radeon_device * rdev)4794926deccbSFrançois Tigeot void si_vm_fini(struct radeon_device *rdev)
4795926deccbSFrançois Tigeot {
4796926deccbSFrançois Tigeot }
4797926deccbSFrançois Tigeot 
4798926deccbSFrançois Tigeot /**
479957e252bfSMichael Neumann  * si_vm_decode_fault - print human readable fault info
480057e252bfSMichael Neumann  *
480157e252bfSMichael Neumann  * @rdev: radeon_device pointer
480257e252bfSMichael Neumann  * @status: VM_CONTEXT1_PROTECTION_FAULT_STATUS register value
480357e252bfSMichael Neumann  * @addr: VM_CONTEXT1_PROTECTION_FAULT_ADDR register value
480457e252bfSMichael Neumann  *
480557e252bfSMichael Neumann  * Print human readable fault information (SI).
480657e252bfSMichael Neumann  */
si_vm_decode_fault(struct radeon_device * rdev,u32 status,u32 addr)480757e252bfSMichael Neumann static void si_vm_decode_fault(struct radeon_device *rdev,
480857e252bfSMichael Neumann 			       u32 status, u32 addr)
480957e252bfSMichael Neumann {
481057e252bfSMichael Neumann 	u32 mc_id = (status & MEMORY_CLIENT_ID_MASK) >> MEMORY_CLIENT_ID_SHIFT;
481157e252bfSMichael Neumann 	u32 vmid = (status & FAULT_VMID_MASK) >> FAULT_VMID_SHIFT;
481257e252bfSMichael Neumann 	u32 protections = (status & PROTECTIONS_MASK) >> PROTECTIONS_SHIFT;
481357e252bfSMichael Neumann 	char *block;
481457e252bfSMichael Neumann 
481557e252bfSMichael Neumann 	if (rdev->family == CHIP_TAHITI) {
481657e252bfSMichael Neumann 		switch (mc_id) {
481757e252bfSMichael Neumann 		case 160:
481857e252bfSMichael Neumann 		case 144:
481957e252bfSMichael Neumann 		case 96:
482057e252bfSMichael Neumann 		case 80:
482157e252bfSMichael Neumann 		case 224:
482257e252bfSMichael Neumann 		case 208:
482357e252bfSMichael Neumann 		case 32:
482457e252bfSMichael Neumann 		case 16:
482557e252bfSMichael Neumann 			block = "CB";
482657e252bfSMichael Neumann 			break;
482757e252bfSMichael Neumann 		case 161:
482857e252bfSMichael Neumann 		case 145:
482957e252bfSMichael Neumann 		case 97:
483057e252bfSMichael Neumann 		case 81:
483157e252bfSMichael Neumann 		case 225:
483257e252bfSMichael Neumann 		case 209:
483357e252bfSMichael Neumann 		case 33:
483457e252bfSMichael Neumann 		case 17:
483557e252bfSMichael Neumann 			block = "CB_FMASK";
483657e252bfSMichael Neumann 			break;
483757e252bfSMichael Neumann 		case 162:
483857e252bfSMichael Neumann 		case 146:
483957e252bfSMichael Neumann 		case 98:
484057e252bfSMichael Neumann 		case 82:
484157e252bfSMichael Neumann 		case 226:
484257e252bfSMichael Neumann 		case 210:
484357e252bfSMichael Neumann 		case 34:
484457e252bfSMichael Neumann 		case 18:
484557e252bfSMichael Neumann 			block = "CB_CMASK";
484657e252bfSMichael Neumann 			break;
484757e252bfSMichael Neumann 		case 163:
484857e252bfSMichael Neumann 		case 147:
484957e252bfSMichael Neumann 		case 99:
485057e252bfSMichael Neumann 		case 83:
485157e252bfSMichael Neumann 		case 227:
485257e252bfSMichael Neumann 		case 211:
485357e252bfSMichael Neumann 		case 35:
485457e252bfSMichael Neumann 		case 19:
485557e252bfSMichael Neumann 			block = "CB_IMMED";
485657e252bfSMichael Neumann 			break;
485757e252bfSMichael Neumann 		case 164:
485857e252bfSMichael Neumann 		case 148:
485957e252bfSMichael Neumann 		case 100:
486057e252bfSMichael Neumann 		case 84:
486157e252bfSMichael Neumann 		case 228:
486257e252bfSMichael Neumann 		case 212:
486357e252bfSMichael Neumann 		case 36:
486457e252bfSMichael Neumann 		case 20:
486557e252bfSMichael Neumann 			block = "DB";
486657e252bfSMichael Neumann 			break;
486757e252bfSMichael Neumann 		case 165:
486857e252bfSMichael Neumann 		case 149:
486957e252bfSMichael Neumann 		case 101:
487057e252bfSMichael Neumann 		case 85:
487157e252bfSMichael Neumann 		case 229:
487257e252bfSMichael Neumann 		case 213:
487357e252bfSMichael Neumann 		case 37:
487457e252bfSMichael Neumann 		case 21:
487557e252bfSMichael Neumann 			block = "DB_HTILE";
487657e252bfSMichael Neumann 			break;
487757e252bfSMichael Neumann 		case 167:
487857e252bfSMichael Neumann 		case 151:
487957e252bfSMichael Neumann 		case 103:
488057e252bfSMichael Neumann 		case 87:
488157e252bfSMichael Neumann 		case 231:
488257e252bfSMichael Neumann 		case 215:
488357e252bfSMichael Neumann 		case 39:
488457e252bfSMichael Neumann 		case 23:
488557e252bfSMichael Neumann 			block = "DB_STEN";
488657e252bfSMichael Neumann 			break;
488757e252bfSMichael Neumann 		case 72:
488857e252bfSMichael Neumann 		case 68:
488957e252bfSMichael Neumann 		case 64:
489057e252bfSMichael Neumann 		case 8:
489157e252bfSMichael Neumann 		case 4:
489257e252bfSMichael Neumann 		case 0:
489357e252bfSMichael Neumann 		case 136:
489457e252bfSMichael Neumann 		case 132:
489557e252bfSMichael Neumann 		case 128:
489657e252bfSMichael Neumann 		case 200:
489757e252bfSMichael Neumann 		case 196:
489857e252bfSMichael Neumann 		case 192:
489957e252bfSMichael Neumann 			block = "TC";
490057e252bfSMichael Neumann 			break;
490157e252bfSMichael Neumann 		case 112:
490257e252bfSMichael Neumann 		case 48:
490357e252bfSMichael Neumann 			block = "CP";
490457e252bfSMichael Neumann 			break;
490557e252bfSMichael Neumann 		case 49:
490657e252bfSMichael Neumann 		case 177:
490757e252bfSMichael Neumann 		case 50:
490857e252bfSMichael Neumann 		case 178:
490957e252bfSMichael Neumann 			block = "SH";
491057e252bfSMichael Neumann 			break;
491157e252bfSMichael Neumann 		case 53:
491257e252bfSMichael Neumann 		case 190:
491357e252bfSMichael Neumann 			block = "VGT";
491457e252bfSMichael Neumann 			break;
491557e252bfSMichael Neumann 		case 117:
491657e252bfSMichael Neumann 			block = "IH";
491757e252bfSMichael Neumann 			break;
491857e252bfSMichael Neumann 		case 51:
491957e252bfSMichael Neumann 		case 115:
492057e252bfSMichael Neumann 			block = "RLC";
492157e252bfSMichael Neumann 			break;
492257e252bfSMichael Neumann 		case 119:
492357e252bfSMichael Neumann 		case 183:
492457e252bfSMichael Neumann 			block = "DMA0";
492557e252bfSMichael Neumann 			break;
492657e252bfSMichael Neumann 		case 61:
492757e252bfSMichael Neumann 			block = "DMA1";
492857e252bfSMichael Neumann 			break;
492957e252bfSMichael Neumann 		case 248:
493057e252bfSMichael Neumann 		case 120:
493157e252bfSMichael Neumann 			block = "HDP";
493257e252bfSMichael Neumann 			break;
493357e252bfSMichael Neumann 		default:
493457e252bfSMichael Neumann 			block = "unknown";
493557e252bfSMichael Neumann 			break;
493657e252bfSMichael Neumann 		}
493757e252bfSMichael Neumann 	} else {
493857e252bfSMichael Neumann 		switch (mc_id) {
493957e252bfSMichael Neumann 		case 32:
494057e252bfSMichael Neumann 		case 16:
494157e252bfSMichael Neumann 		case 96:
494257e252bfSMichael Neumann 		case 80:
494357e252bfSMichael Neumann 		case 160:
494457e252bfSMichael Neumann 		case 144:
494557e252bfSMichael Neumann 		case 224:
494657e252bfSMichael Neumann 		case 208:
494757e252bfSMichael Neumann 			block = "CB";
494857e252bfSMichael Neumann 			break;
494957e252bfSMichael Neumann 		case 33:
495057e252bfSMichael Neumann 		case 17:
495157e252bfSMichael Neumann 		case 97:
495257e252bfSMichael Neumann 		case 81:
495357e252bfSMichael Neumann 		case 161:
495457e252bfSMichael Neumann 		case 145:
495557e252bfSMichael Neumann 		case 225:
495657e252bfSMichael Neumann 		case 209:
495757e252bfSMichael Neumann 			block = "CB_FMASK";
495857e252bfSMichael Neumann 			break;
495957e252bfSMichael Neumann 		case 34:
496057e252bfSMichael Neumann 		case 18:
496157e252bfSMichael Neumann 		case 98:
496257e252bfSMichael Neumann 		case 82:
496357e252bfSMichael Neumann 		case 162:
496457e252bfSMichael Neumann 		case 146:
496557e252bfSMichael Neumann 		case 226:
496657e252bfSMichael Neumann 		case 210:
496757e252bfSMichael Neumann 			block = "CB_CMASK";
496857e252bfSMichael Neumann 			break;
496957e252bfSMichael Neumann 		case 35:
497057e252bfSMichael Neumann 		case 19:
497157e252bfSMichael Neumann 		case 99:
497257e252bfSMichael Neumann 		case 83:
497357e252bfSMichael Neumann 		case 163:
497457e252bfSMichael Neumann 		case 147:
497557e252bfSMichael Neumann 		case 227:
497657e252bfSMichael Neumann 		case 211:
497757e252bfSMichael Neumann 			block = "CB_IMMED";
497857e252bfSMichael Neumann 			break;
497957e252bfSMichael Neumann 		case 36:
498057e252bfSMichael Neumann 		case 20:
498157e252bfSMichael Neumann 		case 100:
498257e252bfSMichael Neumann 		case 84:
498357e252bfSMichael Neumann 		case 164:
498457e252bfSMichael Neumann 		case 148:
498557e252bfSMichael Neumann 		case 228:
498657e252bfSMichael Neumann 		case 212:
498757e252bfSMichael Neumann 			block = "DB";
498857e252bfSMichael Neumann 			break;
498957e252bfSMichael Neumann 		case 37:
499057e252bfSMichael Neumann 		case 21:
499157e252bfSMichael Neumann 		case 101:
499257e252bfSMichael Neumann 		case 85:
499357e252bfSMichael Neumann 		case 165:
499457e252bfSMichael Neumann 		case 149:
499557e252bfSMichael Neumann 		case 229:
499657e252bfSMichael Neumann 		case 213:
499757e252bfSMichael Neumann 			block = "DB_HTILE";
499857e252bfSMichael Neumann 			break;
499957e252bfSMichael Neumann 		case 39:
500057e252bfSMichael Neumann 		case 23:
500157e252bfSMichael Neumann 		case 103:
500257e252bfSMichael Neumann 		case 87:
500357e252bfSMichael Neumann 		case 167:
500457e252bfSMichael Neumann 		case 151:
500557e252bfSMichael Neumann 		case 231:
500657e252bfSMichael Neumann 		case 215:
500757e252bfSMichael Neumann 			block = "DB_STEN";
500857e252bfSMichael Neumann 			break;
500957e252bfSMichael Neumann 		case 72:
501057e252bfSMichael Neumann 		case 68:
501157e252bfSMichael Neumann 		case 8:
501257e252bfSMichael Neumann 		case 4:
501357e252bfSMichael Neumann 		case 136:
501457e252bfSMichael Neumann 		case 132:
501557e252bfSMichael Neumann 		case 200:
501657e252bfSMichael Neumann 		case 196:
501757e252bfSMichael Neumann 			block = "TC";
501857e252bfSMichael Neumann 			break;
501957e252bfSMichael Neumann 		case 112:
502057e252bfSMichael Neumann 		case 48:
502157e252bfSMichael Neumann 			block = "CP";
502257e252bfSMichael Neumann 			break;
502357e252bfSMichael Neumann 		case 49:
502457e252bfSMichael Neumann 		case 177:
502557e252bfSMichael Neumann 		case 50:
502657e252bfSMichael Neumann 		case 178:
502757e252bfSMichael Neumann 			block = "SH";
502857e252bfSMichael Neumann 			break;
502957e252bfSMichael Neumann 		case 53:
503057e252bfSMichael Neumann 			block = "VGT";
503157e252bfSMichael Neumann 			break;
503257e252bfSMichael Neumann 		case 117:
503357e252bfSMichael Neumann 			block = "IH";
503457e252bfSMichael Neumann 			break;
503557e252bfSMichael Neumann 		case 51:
503657e252bfSMichael Neumann 		case 115:
503757e252bfSMichael Neumann 			block = "RLC";
503857e252bfSMichael Neumann 			break;
503957e252bfSMichael Neumann 		case 119:
504057e252bfSMichael Neumann 		case 183:
504157e252bfSMichael Neumann 			block = "DMA0";
504257e252bfSMichael Neumann 			break;
504357e252bfSMichael Neumann 		case 61:
504457e252bfSMichael Neumann 			block = "DMA1";
504557e252bfSMichael Neumann 			break;
504657e252bfSMichael Neumann 		case 248:
504757e252bfSMichael Neumann 		case 120:
504857e252bfSMichael Neumann 			block = "HDP";
504957e252bfSMichael Neumann 			break;
505057e252bfSMichael Neumann 		default:
505157e252bfSMichael Neumann 			block = "unknown";
505257e252bfSMichael Neumann 			break;
505357e252bfSMichael Neumann 		}
505457e252bfSMichael Neumann 	}
505557e252bfSMichael Neumann 
505657e252bfSMichael Neumann 	printk("VM fault (0x%02x, vmid %d) at page %u, %s from %s (%d)\n",
505757e252bfSMichael Neumann 	       protections, vmid, addr,
505857e252bfSMichael Neumann 	       (status & MEMORY_CLIENT_RW_MASK) ? "write" : "read",
505957e252bfSMichael Neumann 	       block, mc_id);
506057e252bfSMichael Neumann }
506157e252bfSMichael Neumann 
si_vm_flush(struct radeon_device * rdev,struct radeon_ring * ring,unsigned vm_id,uint64_t pd_addr)50627dcf36dcSFrançois Tigeot void si_vm_flush(struct radeon_device *rdev, struct radeon_ring *ring,
50637dcf36dcSFrançois Tigeot 		 unsigned vm_id, uint64_t pd_addr)
5064926deccbSFrançois Tigeot {
5065926deccbSFrançois Tigeot 	/* write new base address */
5066926deccbSFrançois Tigeot 	radeon_ring_write(ring, PACKET3(PACKET3_WRITE_DATA, 3));
5067c6f73aabSFrançois Tigeot 	radeon_ring_write(ring, (WRITE_DATA_ENGINE_SEL(1) |
5068926deccbSFrançois Tigeot 				 WRITE_DATA_DST_SEL(0)));
5069926deccbSFrançois Tigeot 
50707dcf36dcSFrançois Tigeot 	if (vm_id < 8) {
5071926deccbSFrançois Tigeot 		radeon_ring_write(ring,
50727dcf36dcSFrançois Tigeot 				  (VM_CONTEXT0_PAGE_TABLE_BASE_ADDR + (vm_id << 2)) >> 2);
5073926deccbSFrançois Tigeot 	} else {
5074926deccbSFrançois Tigeot 		radeon_ring_write(ring,
50757dcf36dcSFrançois Tigeot 				  (VM_CONTEXT8_PAGE_TABLE_BASE_ADDR + ((vm_id - 8) << 2)) >> 2);
5076926deccbSFrançois Tigeot 	}
5077926deccbSFrançois Tigeot 	radeon_ring_write(ring, 0);
50787dcf36dcSFrançois Tigeot 	radeon_ring_write(ring, pd_addr >> 12);
5079926deccbSFrançois Tigeot 
5080926deccbSFrançois Tigeot 	/* flush hdp cache */
5081926deccbSFrançois Tigeot 	radeon_ring_write(ring, PACKET3(PACKET3_WRITE_DATA, 3));
5082c6f73aabSFrançois Tigeot 	radeon_ring_write(ring, (WRITE_DATA_ENGINE_SEL(1) |
5083926deccbSFrançois Tigeot 				 WRITE_DATA_DST_SEL(0)));
5084926deccbSFrançois Tigeot 	radeon_ring_write(ring, HDP_MEM_COHERENCY_FLUSH_CNTL >> 2);
5085926deccbSFrançois Tigeot 	radeon_ring_write(ring, 0);
5086926deccbSFrançois Tigeot 	radeon_ring_write(ring, 0x1);
5087926deccbSFrançois Tigeot 
5088926deccbSFrançois Tigeot 	/* bits 0-15 are the VM contexts0-15 */
5089926deccbSFrançois Tigeot 	radeon_ring_write(ring, PACKET3(PACKET3_WRITE_DATA, 3));
5090c6f73aabSFrançois Tigeot 	radeon_ring_write(ring, (WRITE_DATA_ENGINE_SEL(1) |
5091926deccbSFrançois Tigeot 				 WRITE_DATA_DST_SEL(0)));
5092926deccbSFrançois Tigeot 	radeon_ring_write(ring, VM_INVALIDATE_REQUEST >> 2);
5093926deccbSFrançois Tigeot 	radeon_ring_write(ring, 0);
50947dcf36dcSFrançois Tigeot 	radeon_ring_write(ring, 1 << vm_id);
50957dcf36dcSFrançois Tigeot 
50967dcf36dcSFrançois Tigeot 	/* wait for the invalidate to complete */
50977dcf36dcSFrançois Tigeot 	radeon_ring_write(ring, PACKET3(PACKET3_WAIT_REG_MEM, 5));
50987dcf36dcSFrançois Tigeot 	radeon_ring_write(ring, (WAIT_REG_MEM_FUNCTION(0) |  /* always */
50997dcf36dcSFrançois Tigeot 				 WAIT_REG_MEM_ENGINE(0))); /* me */
51007dcf36dcSFrançois Tigeot 	radeon_ring_write(ring, VM_INVALIDATE_REQUEST >> 2);
51017dcf36dcSFrançois Tigeot 	radeon_ring_write(ring, 0);
51027dcf36dcSFrançois Tigeot 	radeon_ring_write(ring, 0); /* ref */
51037dcf36dcSFrançois Tigeot 	radeon_ring_write(ring, 0); /* mask */
51047dcf36dcSFrançois Tigeot 	radeon_ring_write(ring, 0x20); /* poll interval */
5105926deccbSFrançois Tigeot 
5106926deccbSFrançois Tigeot 	/* sync PFP to ME, otherwise we might get invalid PFP reads */
5107926deccbSFrançois Tigeot 	radeon_ring_write(ring, PACKET3(PACKET3_PFP_SYNC_ME, 0));
5108926deccbSFrançois Tigeot 	radeon_ring_write(ring, 0x0);
5109926deccbSFrançois Tigeot }
5110926deccbSFrançois Tigeot 
5111926deccbSFrançois Tigeot /*
511257e252bfSMichael Neumann  *  Power and clock gating
511357e252bfSMichael Neumann  */
si_wait_for_rlc_serdes(struct radeon_device * rdev)511457e252bfSMichael Neumann static void si_wait_for_rlc_serdes(struct radeon_device *rdev)
511557e252bfSMichael Neumann {
511657e252bfSMichael Neumann 	int i;
511757e252bfSMichael Neumann 
511857e252bfSMichael Neumann 	for (i = 0; i < rdev->usec_timeout; i++) {
511957e252bfSMichael Neumann 		if (RREG32(RLC_SERDES_MASTER_BUSY_0) == 0)
512057e252bfSMichael Neumann 			break;
5121c4ef309bSzrj 		udelay(1);
512257e252bfSMichael Neumann 	}
512357e252bfSMichael Neumann 
512457e252bfSMichael Neumann 	for (i = 0; i < rdev->usec_timeout; i++) {
512557e252bfSMichael Neumann 		if (RREG32(RLC_SERDES_MASTER_BUSY_1) == 0)
512657e252bfSMichael Neumann 			break;
5127c4ef309bSzrj 		udelay(1);
512857e252bfSMichael Neumann 	}
512957e252bfSMichael Neumann }
513057e252bfSMichael Neumann 
si_enable_gui_idle_interrupt(struct radeon_device * rdev,bool enable)513157e252bfSMichael Neumann static void si_enable_gui_idle_interrupt(struct radeon_device *rdev,
513257e252bfSMichael Neumann 					 bool enable)
513357e252bfSMichael Neumann {
513457e252bfSMichael Neumann 	u32 tmp = RREG32(CP_INT_CNTL_RING0);
513557e252bfSMichael Neumann 	u32 mask;
513657e252bfSMichael Neumann 	int i;
513757e252bfSMichael Neumann 
513857e252bfSMichael Neumann 	if (enable)
513957e252bfSMichael Neumann 		tmp |= (CNTX_BUSY_INT_ENABLE | CNTX_EMPTY_INT_ENABLE);
514057e252bfSMichael Neumann 	else
514157e252bfSMichael Neumann 		tmp &= ~(CNTX_BUSY_INT_ENABLE | CNTX_EMPTY_INT_ENABLE);
514257e252bfSMichael Neumann 	WREG32(CP_INT_CNTL_RING0, tmp);
514357e252bfSMichael Neumann 
514457e252bfSMichael Neumann 	if (!enable) {
514557e252bfSMichael Neumann 		/* read a gfx register */
514657e252bfSMichael Neumann 		tmp = RREG32(DB_DEPTH_INFO);
514757e252bfSMichael Neumann 
514857e252bfSMichael Neumann 		mask = RLC_BUSY_STATUS | GFX_POWER_STATUS | GFX_CLOCK_STATUS | GFX_LS_STATUS;
514957e252bfSMichael Neumann 		for (i = 0; i < rdev->usec_timeout; i++) {
515057e252bfSMichael Neumann 			if ((RREG32(RLC_STAT) & mask) == (GFX_CLOCK_STATUS | GFX_POWER_STATUS))
515157e252bfSMichael Neumann 				break;
5152c4ef309bSzrj 			udelay(1);
515357e252bfSMichael Neumann 		}
515457e252bfSMichael Neumann 	}
515557e252bfSMichael Neumann }
515657e252bfSMichael Neumann 
si_set_uvd_dcm(struct radeon_device * rdev,bool sw_mode)515757e252bfSMichael Neumann static void si_set_uvd_dcm(struct radeon_device *rdev,
515857e252bfSMichael Neumann 			   bool sw_mode)
515957e252bfSMichael Neumann {
516057e252bfSMichael Neumann 	u32 tmp, tmp2;
516157e252bfSMichael Neumann 
516257e252bfSMichael Neumann 	tmp = RREG32(UVD_CGC_CTRL);
516357e252bfSMichael Neumann 	tmp &= ~(CLK_OD_MASK | CG_DT_MASK);
516457e252bfSMichael Neumann 	tmp |= DCM | CG_DT(1) | CLK_OD(4);
516557e252bfSMichael Neumann 
516657e252bfSMichael Neumann 	if (sw_mode) {
516757e252bfSMichael Neumann 		tmp &= ~0x7ffff800;
516857e252bfSMichael Neumann 		tmp2 = DYN_OR_EN | DYN_RR_EN | G_DIV_ID(7);
516957e252bfSMichael Neumann 	} else {
517057e252bfSMichael Neumann 		tmp |= 0x7ffff800;
517157e252bfSMichael Neumann 		tmp2 = 0;
517257e252bfSMichael Neumann 	}
517357e252bfSMichael Neumann 
517457e252bfSMichael Neumann 	WREG32(UVD_CGC_CTRL, tmp);
517557e252bfSMichael Neumann 	WREG32_UVD_CTX(UVD_CGC_CTRL2, tmp2);
517657e252bfSMichael Neumann }
517757e252bfSMichael Neumann 
si_init_uvd_internal_cg(struct radeon_device * rdev)51784cd92098Szrj void si_init_uvd_internal_cg(struct radeon_device *rdev)
517957e252bfSMichael Neumann {
518057e252bfSMichael Neumann 	bool hw_mode = true;
518157e252bfSMichael Neumann 
518257e252bfSMichael Neumann 	if (hw_mode) {
518357e252bfSMichael Neumann 		si_set_uvd_dcm(rdev, false);
518457e252bfSMichael Neumann 	} else {
518557e252bfSMichael Neumann 		u32 tmp = RREG32(UVD_CGC_CTRL);
518657e252bfSMichael Neumann 		tmp &= ~DCM;
518757e252bfSMichael Neumann 		WREG32(UVD_CGC_CTRL, tmp);
518857e252bfSMichael Neumann 	}
518957e252bfSMichael Neumann }
519057e252bfSMichael Neumann 
si_halt_rlc(struct radeon_device * rdev)519157e252bfSMichael Neumann static u32 si_halt_rlc(struct radeon_device *rdev)
519257e252bfSMichael Neumann {
519357e252bfSMichael Neumann 	u32 data, orig;
519457e252bfSMichael Neumann 
519557e252bfSMichael Neumann 	orig = data = RREG32(RLC_CNTL);
519657e252bfSMichael Neumann 
519757e252bfSMichael Neumann 	if (data & RLC_ENABLE) {
519857e252bfSMichael Neumann 		data &= ~RLC_ENABLE;
519957e252bfSMichael Neumann 		WREG32(RLC_CNTL, data);
520057e252bfSMichael Neumann 
520157e252bfSMichael Neumann 		si_wait_for_rlc_serdes(rdev);
520257e252bfSMichael Neumann 	}
520357e252bfSMichael Neumann 
520457e252bfSMichael Neumann 	return orig;
520557e252bfSMichael Neumann }
520657e252bfSMichael Neumann 
si_update_rlc(struct radeon_device * rdev,u32 rlc)520757e252bfSMichael Neumann static void si_update_rlc(struct radeon_device *rdev, u32 rlc)
520857e252bfSMichael Neumann {
520957e252bfSMichael Neumann 	u32 tmp;
521057e252bfSMichael Neumann 
521157e252bfSMichael Neumann 	tmp = RREG32(RLC_CNTL);
521257e252bfSMichael Neumann 	if (tmp != rlc)
521357e252bfSMichael Neumann 		WREG32(RLC_CNTL, rlc);
521457e252bfSMichael Neumann }
521557e252bfSMichael Neumann 
si_enable_dma_pg(struct radeon_device * rdev,bool enable)521657e252bfSMichael Neumann static void si_enable_dma_pg(struct radeon_device *rdev, bool enable)
521757e252bfSMichael Neumann {
521857e252bfSMichael Neumann 	u32 data, orig;
521957e252bfSMichael Neumann 
522057e252bfSMichael Neumann 	orig = data = RREG32(DMA_PG);
52214cd92098Szrj 	if (enable && (rdev->pg_flags & RADEON_PG_SUPPORT_SDMA))
522257e252bfSMichael Neumann 		data |= PG_CNTL_ENABLE;
522357e252bfSMichael Neumann 	else
522457e252bfSMichael Neumann 		data &= ~PG_CNTL_ENABLE;
522557e252bfSMichael Neumann 	if (orig != data)
522657e252bfSMichael Neumann 		WREG32(DMA_PG, data);
522757e252bfSMichael Neumann }
522857e252bfSMichael Neumann 
si_init_dma_pg(struct radeon_device * rdev)522957e252bfSMichael Neumann static void si_init_dma_pg(struct radeon_device *rdev)
523057e252bfSMichael Neumann {
523157e252bfSMichael Neumann 	u32 tmp;
523257e252bfSMichael Neumann 
523357e252bfSMichael Neumann 	WREG32(DMA_PGFSM_WRITE,  0x00002000);
523457e252bfSMichael Neumann 	WREG32(DMA_PGFSM_CONFIG, 0x100010ff);
523557e252bfSMichael Neumann 
523657e252bfSMichael Neumann 	for (tmp = 0; tmp < 5; tmp++)
523757e252bfSMichael Neumann 		WREG32(DMA_PGFSM_WRITE, 0);
523857e252bfSMichael Neumann }
523957e252bfSMichael Neumann 
si_enable_gfx_cgpg(struct radeon_device * rdev,bool enable)524057e252bfSMichael Neumann static void si_enable_gfx_cgpg(struct radeon_device *rdev,
524157e252bfSMichael Neumann 			       bool enable)
524257e252bfSMichael Neumann {
524357e252bfSMichael Neumann 	u32 tmp;
524457e252bfSMichael Neumann 
52454cd92098Szrj 	if (enable && (rdev->pg_flags & RADEON_PG_SUPPORT_GFX_PG)) {
524657e252bfSMichael Neumann 		tmp = RLC_PUD(0x10) | RLC_PDD(0x10) | RLC_TTPD(0x10) | RLC_MSD(0x10);
524757e252bfSMichael Neumann 		WREG32(RLC_TTOP_D, tmp);
524857e252bfSMichael Neumann 
524957e252bfSMichael Neumann 		tmp = RREG32(RLC_PG_CNTL);
525057e252bfSMichael Neumann 		tmp |= GFX_PG_ENABLE;
525157e252bfSMichael Neumann 		WREG32(RLC_PG_CNTL, tmp);
525257e252bfSMichael Neumann 
525357e252bfSMichael Neumann 		tmp = RREG32(RLC_AUTO_PG_CTRL);
525457e252bfSMichael Neumann 		tmp |= AUTO_PG_EN;
525557e252bfSMichael Neumann 		WREG32(RLC_AUTO_PG_CTRL, tmp);
525657e252bfSMichael Neumann 	} else {
525757e252bfSMichael Neumann 		tmp = RREG32(RLC_AUTO_PG_CTRL);
525857e252bfSMichael Neumann 		tmp &= ~AUTO_PG_EN;
525957e252bfSMichael Neumann 		WREG32(RLC_AUTO_PG_CTRL, tmp);
526057e252bfSMichael Neumann 
526157e252bfSMichael Neumann 		tmp = RREG32(DB_RENDER_CONTROL);
526257e252bfSMichael Neumann 	}
526357e252bfSMichael Neumann }
526457e252bfSMichael Neumann 
si_init_gfx_cgpg(struct radeon_device * rdev)526557e252bfSMichael Neumann static void si_init_gfx_cgpg(struct radeon_device *rdev)
526657e252bfSMichael Neumann {
526757e252bfSMichael Neumann 	u32 tmp;
526857e252bfSMichael Neumann 
526957e252bfSMichael Neumann 	WREG32(RLC_SAVE_AND_RESTORE_BASE, rdev->rlc.save_restore_gpu_addr >> 8);
527057e252bfSMichael Neumann 
527157e252bfSMichael Neumann 	tmp = RREG32(RLC_PG_CNTL);
527257e252bfSMichael Neumann 	tmp |= GFX_PG_SRC;
527357e252bfSMichael Neumann 	WREG32(RLC_PG_CNTL, tmp);
527457e252bfSMichael Neumann 
527557e252bfSMichael Neumann 	WREG32(RLC_CLEAR_STATE_RESTORE_BASE, rdev->rlc.clear_state_gpu_addr >> 8);
527657e252bfSMichael Neumann 
527757e252bfSMichael Neumann 	tmp = RREG32(RLC_AUTO_PG_CTRL);
527857e252bfSMichael Neumann 
527957e252bfSMichael Neumann 	tmp &= ~GRBM_REG_SGIT_MASK;
528057e252bfSMichael Neumann 	tmp |= GRBM_REG_SGIT(0x700);
528157e252bfSMichael Neumann 	tmp &= ~PG_AFTER_GRBM_REG_ST_MASK;
528257e252bfSMichael Neumann 	WREG32(RLC_AUTO_PG_CTRL, tmp);
528357e252bfSMichael Neumann }
528457e252bfSMichael Neumann 
si_get_cu_active_bitmap(struct radeon_device * rdev,u32 se,u32 sh)528557e252bfSMichael Neumann static u32 si_get_cu_active_bitmap(struct radeon_device *rdev, u32 se, u32 sh)
528657e252bfSMichael Neumann {
528757e252bfSMichael Neumann 	u32 mask = 0, tmp, tmp1;
528857e252bfSMichael Neumann 	int i;
528957e252bfSMichael Neumann 
529057e252bfSMichael Neumann 	si_select_se_sh(rdev, se, sh);
529157e252bfSMichael Neumann 	tmp = RREG32(CC_GC_SHADER_ARRAY_CONFIG);
529257e252bfSMichael Neumann 	tmp1 = RREG32(GC_USER_SHADER_ARRAY_CONFIG);
529357e252bfSMichael Neumann 	si_select_se_sh(rdev, 0xffffffff, 0xffffffff);
529457e252bfSMichael Neumann 
529557e252bfSMichael Neumann 	tmp &= 0xffff0000;
529657e252bfSMichael Neumann 
529757e252bfSMichael Neumann 	tmp |= tmp1;
529857e252bfSMichael Neumann 	tmp >>= 16;
529957e252bfSMichael Neumann 
530057e252bfSMichael Neumann 	for (i = 0; i < rdev->config.si.max_cu_per_sh; i ++) {
530157e252bfSMichael Neumann 		mask <<= 1;
530257e252bfSMichael Neumann 		mask |= 1;
530357e252bfSMichael Neumann 	}
530457e252bfSMichael Neumann 
530557e252bfSMichael Neumann 	return (~tmp) & mask;
530657e252bfSMichael Neumann }
530757e252bfSMichael Neumann 
si_init_ao_cu_mask(struct radeon_device * rdev)530857e252bfSMichael Neumann static void si_init_ao_cu_mask(struct radeon_device *rdev)
530957e252bfSMichael Neumann {
531057e252bfSMichael Neumann 	u32 i, j, k, active_cu_number = 0;
531157e252bfSMichael Neumann 	u32 mask, counter, cu_bitmap;
531257e252bfSMichael Neumann 	u32 tmp = 0;
531357e252bfSMichael Neumann 
531457e252bfSMichael Neumann 	for (i = 0; i < rdev->config.si.max_shader_engines; i++) {
531557e252bfSMichael Neumann 		for (j = 0; j < rdev->config.si.max_sh_per_se; j++) {
531657e252bfSMichael Neumann 			mask = 1;
531757e252bfSMichael Neumann 			cu_bitmap = 0;
531857e252bfSMichael Neumann 			counter  = 0;
531957e252bfSMichael Neumann 			for (k = 0; k < rdev->config.si.max_cu_per_sh; k++) {
532057e252bfSMichael Neumann 				if (si_get_cu_active_bitmap(rdev, i, j) & mask) {
532157e252bfSMichael Neumann 					if (counter < 2)
532257e252bfSMichael Neumann 						cu_bitmap |= mask;
532357e252bfSMichael Neumann 					counter++;
532457e252bfSMichael Neumann 				}
532557e252bfSMichael Neumann 				mask <<= 1;
532657e252bfSMichael Neumann 			}
532757e252bfSMichael Neumann 
532857e252bfSMichael Neumann 			active_cu_number += counter;
532957e252bfSMichael Neumann 			tmp |= (cu_bitmap << (i * 16 + j * 8));
533057e252bfSMichael Neumann 		}
533157e252bfSMichael Neumann 	}
533257e252bfSMichael Neumann 
533357e252bfSMichael Neumann 	WREG32(RLC_PG_AO_CU_MASK, tmp);
533457e252bfSMichael Neumann 
533557e252bfSMichael Neumann 	tmp = RREG32(RLC_MAX_PG_CU);
533657e252bfSMichael Neumann 	tmp &= ~MAX_PU_CU_MASK;
533757e252bfSMichael Neumann 	tmp |= MAX_PU_CU(active_cu_number);
533857e252bfSMichael Neumann 	WREG32(RLC_MAX_PG_CU, tmp);
533957e252bfSMichael Neumann }
534057e252bfSMichael Neumann 
si_enable_cgcg(struct radeon_device * rdev,bool enable)534157e252bfSMichael Neumann static void si_enable_cgcg(struct radeon_device *rdev,
534257e252bfSMichael Neumann 			   bool enable)
534357e252bfSMichael Neumann {
534457e252bfSMichael Neumann 	u32 data, orig, tmp;
534557e252bfSMichael Neumann 
534657e252bfSMichael Neumann 	orig = data = RREG32(RLC_CGCG_CGLS_CTRL);
534757e252bfSMichael Neumann 
53484cd92098Szrj 	if (enable && (rdev->cg_flags & RADEON_CG_SUPPORT_GFX_CGCG)) {
53494cd92098Szrj 		si_enable_gui_idle_interrupt(rdev, true);
535057e252bfSMichael Neumann 
535157e252bfSMichael Neumann 		WREG32(RLC_GCPM_GENERAL_3, 0x00000080);
535257e252bfSMichael Neumann 
535357e252bfSMichael Neumann 		tmp = si_halt_rlc(rdev);
535457e252bfSMichael Neumann 
535557e252bfSMichael Neumann 		WREG32(RLC_SERDES_WR_MASTER_MASK_0, 0xffffffff);
535657e252bfSMichael Neumann 		WREG32(RLC_SERDES_WR_MASTER_MASK_1, 0xffffffff);
535757e252bfSMichael Neumann 		WREG32(RLC_SERDES_WR_CTRL, 0x00b000ff);
535857e252bfSMichael Neumann 
535957e252bfSMichael Neumann 		si_wait_for_rlc_serdes(rdev);
536057e252bfSMichael Neumann 
536157e252bfSMichael Neumann 		si_update_rlc(rdev, tmp);
536257e252bfSMichael Neumann 
536357e252bfSMichael Neumann 		WREG32(RLC_SERDES_WR_CTRL, 0x007000ff);
536457e252bfSMichael Neumann 
536557e252bfSMichael Neumann 		data |= CGCG_EN | CGLS_EN;
536657e252bfSMichael Neumann 	} else {
53674cd92098Szrj 		si_enable_gui_idle_interrupt(rdev, false);
53684cd92098Szrj 
536957e252bfSMichael Neumann 		RREG32(CB_CGTT_SCLK_CTRL);
537057e252bfSMichael Neumann 		RREG32(CB_CGTT_SCLK_CTRL);
537157e252bfSMichael Neumann 		RREG32(CB_CGTT_SCLK_CTRL);
537257e252bfSMichael Neumann 		RREG32(CB_CGTT_SCLK_CTRL);
537357e252bfSMichael Neumann 
537457e252bfSMichael Neumann 		data &= ~(CGCG_EN | CGLS_EN);
537557e252bfSMichael Neumann 	}
537657e252bfSMichael Neumann 
537757e252bfSMichael Neumann 	if (orig != data)
537857e252bfSMichael Neumann 		WREG32(RLC_CGCG_CGLS_CTRL, data);
537957e252bfSMichael Neumann }
538057e252bfSMichael Neumann 
si_enable_mgcg(struct radeon_device * rdev,bool enable)538157e252bfSMichael Neumann static void si_enable_mgcg(struct radeon_device *rdev,
538257e252bfSMichael Neumann 			   bool enable)
538357e252bfSMichael Neumann {
538457e252bfSMichael Neumann 	u32 data, orig, tmp = 0;
538557e252bfSMichael Neumann 
53864cd92098Szrj 	if (enable && (rdev->cg_flags & RADEON_CG_SUPPORT_GFX_MGCG)) {
538757e252bfSMichael Neumann 		orig = data = RREG32(CGTS_SM_CTRL_REG);
538857e252bfSMichael Neumann 		data = 0x96940200;
538957e252bfSMichael Neumann 		if (orig != data)
539057e252bfSMichael Neumann 			WREG32(CGTS_SM_CTRL_REG, data);
539157e252bfSMichael Neumann 
53924cd92098Szrj 		if (rdev->cg_flags & RADEON_CG_SUPPORT_GFX_CP_LS) {
539357e252bfSMichael Neumann 			orig = data = RREG32(CP_MEM_SLP_CNTL);
539457e252bfSMichael Neumann 			data |= CP_MEM_LS_EN;
539557e252bfSMichael Neumann 			if (orig != data)
539657e252bfSMichael Neumann 				WREG32(CP_MEM_SLP_CNTL, data);
53974cd92098Szrj 		}
539857e252bfSMichael Neumann 
539957e252bfSMichael Neumann 		orig = data = RREG32(RLC_CGTT_MGCG_OVERRIDE);
540057e252bfSMichael Neumann 		data &= 0xffffffc0;
540157e252bfSMichael Neumann 		if (orig != data)
540257e252bfSMichael Neumann 			WREG32(RLC_CGTT_MGCG_OVERRIDE, data);
540357e252bfSMichael Neumann 
540457e252bfSMichael Neumann 		tmp = si_halt_rlc(rdev);
540557e252bfSMichael Neumann 
540657e252bfSMichael Neumann 		WREG32(RLC_SERDES_WR_MASTER_MASK_0, 0xffffffff);
540757e252bfSMichael Neumann 		WREG32(RLC_SERDES_WR_MASTER_MASK_1, 0xffffffff);
540857e252bfSMichael Neumann 		WREG32(RLC_SERDES_WR_CTRL, 0x00d000ff);
540957e252bfSMichael Neumann 
541057e252bfSMichael Neumann 		si_update_rlc(rdev, tmp);
541157e252bfSMichael Neumann 	} else {
541257e252bfSMichael Neumann 		orig = data = RREG32(RLC_CGTT_MGCG_OVERRIDE);
541357e252bfSMichael Neumann 		data |= 0x00000003;
541457e252bfSMichael Neumann 		if (orig != data)
541557e252bfSMichael Neumann 			WREG32(RLC_CGTT_MGCG_OVERRIDE, data);
541657e252bfSMichael Neumann 
541757e252bfSMichael Neumann 		data = RREG32(CP_MEM_SLP_CNTL);
541857e252bfSMichael Neumann 		if (data & CP_MEM_LS_EN) {
541957e252bfSMichael Neumann 			data &= ~CP_MEM_LS_EN;
542057e252bfSMichael Neumann 			WREG32(CP_MEM_SLP_CNTL, data);
542157e252bfSMichael Neumann 		}
542257e252bfSMichael Neumann 		orig = data = RREG32(CGTS_SM_CTRL_REG);
542357e252bfSMichael Neumann 		data |= LS_OVERRIDE | OVERRIDE;
542457e252bfSMichael Neumann 		if (orig != data)
542557e252bfSMichael Neumann 			WREG32(CGTS_SM_CTRL_REG, data);
542657e252bfSMichael Neumann 
542757e252bfSMichael Neumann 		tmp = si_halt_rlc(rdev);
542857e252bfSMichael Neumann 
542957e252bfSMichael Neumann 		WREG32(RLC_SERDES_WR_MASTER_MASK_0, 0xffffffff);
543057e252bfSMichael Neumann 		WREG32(RLC_SERDES_WR_MASTER_MASK_1, 0xffffffff);
543157e252bfSMichael Neumann 		WREG32(RLC_SERDES_WR_CTRL, 0x00e000ff);
543257e252bfSMichael Neumann 
543357e252bfSMichael Neumann 		si_update_rlc(rdev, tmp);
543457e252bfSMichael Neumann 	}
543557e252bfSMichael Neumann }
543657e252bfSMichael Neumann 
si_enable_uvd_mgcg(struct radeon_device * rdev,bool enable)543757e252bfSMichael Neumann static void si_enable_uvd_mgcg(struct radeon_device *rdev,
543857e252bfSMichael Neumann 			       bool enable)
543957e252bfSMichael Neumann {
544057e252bfSMichael Neumann 	u32 orig, data, tmp;
544157e252bfSMichael Neumann 
54424cd92098Szrj 	if (enable && (rdev->cg_flags & RADEON_CG_SUPPORT_UVD_MGCG)) {
544357e252bfSMichael Neumann 		tmp = RREG32_UVD_CTX(UVD_CGC_MEM_CTRL);
544457e252bfSMichael Neumann 		tmp |= 0x3fff;
544557e252bfSMichael Neumann 		WREG32_UVD_CTX(UVD_CGC_MEM_CTRL, tmp);
544657e252bfSMichael Neumann 
544757e252bfSMichael Neumann 		orig = data = RREG32(UVD_CGC_CTRL);
544857e252bfSMichael Neumann 		data |= DCM;
544957e252bfSMichael Neumann 		if (orig != data)
545057e252bfSMichael Neumann 			WREG32(UVD_CGC_CTRL, data);
545157e252bfSMichael Neumann 
545257e252bfSMichael Neumann 		WREG32_SMC(SMC_CG_IND_START + CG_CGTT_LOCAL_0, 0);
545357e252bfSMichael Neumann 		WREG32_SMC(SMC_CG_IND_START + CG_CGTT_LOCAL_1, 0);
545457e252bfSMichael Neumann 	} else {
545557e252bfSMichael Neumann 		tmp = RREG32_UVD_CTX(UVD_CGC_MEM_CTRL);
545657e252bfSMichael Neumann 		tmp &= ~0x3fff;
545757e252bfSMichael Neumann 		WREG32_UVD_CTX(UVD_CGC_MEM_CTRL, tmp);
545857e252bfSMichael Neumann 
545957e252bfSMichael Neumann 		orig = data = RREG32(UVD_CGC_CTRL);
546057e252bfSMichael Neumann 		data &= ~DCM;
546157e252bfSMichael Neumann 		if (orig != data)
546257e252bfSMichael Neumann 			WREG32(UVD_CGC_CTRL, data);
546357e252bfSMichael Neumann 
546457e252bfSMichael Neumann 		WREG32_SMC(SMC_CG_IND_START + CG_CGTT_LOCAL_0, 0xffffffff);
546557e252bfSMichael Neumann 		WREG32_SMC(SMC_CG_IND_START + CG_CGTT_LOCAL_1, 0xffffffff);
546657e252bfSMichael Neumann 	}
546757e252bfSMichael Neumann }
546857e252bfSMichael Neumann 
546957e252bfSMichael Neumann static const u32 mc_cg_registers[] =
547057e252bfSMichael Neumann {
547157e252bfSMichael Neumann 	MC_HUB_MISC_HUB_CG,
547257e252bfSMichael Neumann 	MC_HUB_MISC_SIP_CG,
547357e252bfSMichael Neumann 	MC_HUB_MISC_VM_CG,
547457e252bfSMichael Neumann 	MC_XPB_CLK_GAT,
547557e252bfSMichael Neumann 	ATC_MISC_CG,
547657e252bfSMichael Neumann 	MC_CITF_MISC_WR_CG,
547757e252bfSMichael Neumann 	MC_CITF_MISC_RD_CG,
547857e252bfSMichael Neumann 	MC_CITF_MISC_VM_CG,
547957e252bfSMichael Neumann 	VM_L2_CG,
548057e252bfSMichael Neumann };
548157e252bfSMichael Neumann 
si_enable_mc_ls(struct radeon_device * rdev,bool enable)548257e252bfSMichael Neumann static void si_enable_mc_ls(struct radeon_device *rdev,
548357e252bfSMichael Neumann 			    bool enable)
548457e252bfSMichael Neumann {
548557e252bfSMichael Neumann 	int i;
548657e252bfSMichael Neumann 	u32 orig, data;
548757e252bfSMichael Neumann 
548857e252bfSMichael Neumann 	for (i = 0; i < ARRAY_SIZE(mc_cg_registers); i++) {
548957e252bfSMichael Neumann 		orig = data = RREG32(mc_cg_registers[i]);
54904cd92098Szrj 		if (enable && (rdev->cg_flags & RADEON_CG_SUPPORT_MC_LS))
549157e252bfSMichael Neumann 			data |= MC_LS_ENABLE;
549257e252bfSMichael Neumann 		else
549357e252bfSMichael Neumann 			data &= ~MC_LS_ENABLE;
549457e252bfSMichael Neumann 		if (data != orig)
549557e252bfSMichael Neumann 			WREG32(mc_cg_registers[i], data);
549657e252bfSMichael Neumann 	}
549757e252bfSMichael Neumann }
549857e252bfSMichael Neumann 
si_enable_mc_mgcg(struct radeon_device * rdev,bool enable)54994cd92098Szrj static void si_enable_mc_mgcg(struct radeon_device *rdev,
55004cd92098Szrj 			       bool enable)
55014cd92098Szrj {
55024cd92098Szrj 	int i;
55034cd92098Szrj 	u32 orig, data;
55044cd92098Szrj 
55054cd92098Szrj 	for (i = 0; i < ARRAY_SIZE(mc_cg_registers); i++) {
55064cd92098Szrj 		orig = data = RREG32(mc_cg_registers[i]);
55074cd92098Szrj 		if (enable && (rdev->cg_flags & RADEON_CG_SUPPORT_MC_MGCG))
55084cd92098Szrj 			data |= MC_CG_ENABLE;
55094cd92098Szrj 		else
55104cd92098Szrj 			data &= ~MC_CG_ENABLE;
55114cd92098Szrj 		if (data != orig)
55124cd92098Szrj 			WREG32(mc_cg_registers[i], data);
55134cd92098Szrj 	}
55144cd92098Szrj }
55154cd92098Szrj 
si_enable_dma_mgcg(struct radeon_device * rdev,bool enable)55164cd92098Szrj static void si_enable_dma_mgcg(struct radeon_device *rdev,
55174cd92098Szrj 			       bool enable)
55184cd92098Szrj {
55194cd92098Szrj 	u32 orig, data, offset;
55204cd92098Szrj 	int i;
55214cd92098Szrj 
55224cd92098Szrj 	if (enable && (rdev->cg_flags & RADEON_CG_SUPPORT_SDMA_MGCG)) {
55234cd92098Szrj 		for (i = 0; i < 2; i++) {
55244cd92098Szrj 			if (i == 0)
55254cd92098Szrj 				offset = DMA0_REGISTER_OFFSET;
55264cd92098Szrj 			else
55274cd92098Szrj 				offset = DMA1_REGISTER_OFFSET;
55284cd92098Szrj 			orig = data = RREG32(DMA_POWER_CNTL + offset);
55294cd92098Szrj 			data &= ~MEM_POWER_OVERRIDE;
55304cd92098Szrj 			if (data != orig)
55314cd92098Szrj 				WREG32(DMA_POWER_CNTL + offset, data);
55324cd92098Szrj 			WREG32(DMA_CLK_CTRL + offset, 0x00000100);
55334cd92098Szrj 		}
55344cd92098Szrj 	} else {
55354cd92098Szrj 		for (i = 0; i < 2; i++) {
55364cd92098Szrj 			if (i == 0)
55374cd92098Szrj 				offset = DMA0_REGISTER_OFFSET;
55384cd92098Szrj 			else
55394cd92098Szrj 				offset = DMA1_REGISTER_OFFSET;
55404cd92098Szrj 			orig = data = RREG32(DMA_POWER_CNTL + offset);
55414cd92098Szrj 			data |= MEM_POWER_OVERRIDE;
55424cd92098Szrj 			if (data != orig)
55434cd92098Szrj 				WREG32(DMA_POWER_CNTL + offset, data);
55444cd92098Szrj 
55454cd92098Szrj 			orig = data = RREG32(DMA_CLK_CTRL + offset);
55464cd92098Szrj 			data = 0xff000000;
55474cd92098Szrj 			if (data != orig)
55484cd92098Szrj 				WREG32(DMA_CLK_CTRL + offset, data);
55494cd92098Szrj 		}
55504cd92098Szrj 	}
55514cd92098Szrj }
55524cd92098Szrj 
si_enable_bif_mgls(struct radeon_device * rdev,bool enable)55534cd92098Szrj static void si_enable_bif_mgls(struct radeon_device *rdev,
55544cd92098Szrj 			       bool enable)
55554cd92098Szrj {
55564cd92098Szrj 	u32 orig, data;
55574cd92098Szrj 
55584cd92098Szrj 	orig = data = RREG32_PCIE(PCIE_CNTL2);
55594cd92098Szrj 
55604cd92098Szrj 	if (enable && (rdev->cg_flags & RADEON_CG_SUPPORT_BIF_LS))
55614cd92098Szrj 		data |= SLV_MEM_LS_EN | MST_MEM_LS_EN |
55624cd92098Szrj 			REPLAY_MEM_LS_EN | SLV_MEM_AGGRESSIVE_LS_EN;
55634cd92098Szrj 	else
55644cd92098Szrj 		data &= ~(SLV_MEM_LS_EN | MST_MEM_LS_EN |
55654cd92098Szrj 			  REPLAY_MEM_LS_EN | SLV_MEM_AGGRESSIVE_LS_EN);
55664cd92098Szrj 
55674cd92098Szrj 	if (orig != data)
55684cd92098Szrj 		WREG32_PCIE(PCIE_CNTL2, data);
55694cd92098Szrj }
55704cd92098Szrj 
si_enable_hdp_mgcg(struct radeon_device * rdev,bool enable)55714cd92098Szrj static void si_enable_hdp_mgcg(struct radeon_device *rdev,
55724cd92098Szrj 			       bool enable)
55734cd92098Szrj {
55744cd92098Szrj 	u32 orig, data;
55754cd92098Szrj 
55764cd92098Szrj 	orig = data = RREG32(HDP_HOST_PATH_CNTL);
55774cd92098Szrj 
55784cd92098Szrj 	if (enable && (rdev->cg_flags & RADEON_CG_SUPPORT_HDP_MGCG))
55794cd92098Szrj 		data &= ~CLOCK_GATING_DIS;
55804cd92098Szrj 	else
55814cd92098Szrj 		data |= CLOCK_GATING_DIS;
55824cd92098Szrj 
55834cd92098Szrj 	if (orig != data)
55844cd92098Szrj 		WREG32(HDP_HOST_PATH_CNTL, data);
55854cd92098Szrj }
55864cd92098Szrj 
si_enable_hdp_ls(struct radeon_device * rdev,bool enable)55874cd92098Szrj static void si_enable_hdp_ls(struct radeon_device *rdev,
55884cd92098Szrj 			     bool enable)
55894cd92098Szrj {
55904cd92098Szrj 	u32 orig, data;
55914cd92098Szrj 
55924cd92098Szrj 	orig = data = RREG32(HDP_MEM_POWER_LS);
55934cd92098Szrj 
55944cd92098Szrj 	if (enable && (rdev->cg_flags & RADEON_CG_SUPPORT_HDP_LS))
55954cd92098Szrj 		data |= HDP_LS_ENABLE;
55964cd92098Szrj 	else
55974cd92098Szrj 		data &= ~HDP_LS_ENABLE;
55984cd92098Szrj 
55994cd92098Szrj 	if (orig != data)
56004cd92098Szrj 		WREG32(HDP_MEM_POWER_LS, data);
56014cd92098Szrj }
56024cd92098Szrj 
si_update_cg(struct radeon_device * rdev,u32 block,bool enable)5603c6f73aabSFrançois Tigeot static void si_update_cg(struct radeon_device *rdev,
56044cd92098Szrj 			 u32 block, bool enable)
56054cd92098Szrj {
56064cd92098Szrj 	if (block & RADEON_CG_BLOCK_GFX) {
56074cd92098Szrj 		si_enable_gui_idle_interrupt(rdev, false);
56084cd92098Szrj 		/* order matters! */
56094cd92098Szrj 		if (enable) {
56104cd92098Szrj 			si_enable_mgcg(rdev, true);
56114cd92098Szrj 			si_enable_cgcg(rdev, true);
56124cd92098Szrj 		} else {
56134cd92098Szrj 			si_enable_cgcg(rdev, false);
56144cd92098Szrj 			si_enable_mgcg(rdev, false);
56154cd92098Szrj 		}
56164cd92098Szrj 		si_enable_gui_idle_interrupt(rdev, true);
56174cd92098Szrj 	}
56184cd92098Szrj 
56194cd92098Szrj 	if (block & RADEON_CG_BLOCK_MC) {
56204cd92098Szrj 		si_enable_mc_mgcg(rdev, enable);
56214cd92098Szrj 		si_enable_mc_ls(rdev, enable);
56224cd92098Szrj 	}
56234cd92098Szrj 
56244cd92098Szrj 	if (block & RADEON_CG_BLOCK_SDMA) {
56254cd92098Szrj 		si_enable_dma_mgcg(rdev, enable);
56264cd92098Szrj 	}
56274cd92098Szrj 
56284cd92098Szrj 	if (block & RADEON_CG_BLOCK_BIF) {
56294cd92098Szrj 		si_enable_bif_mgls(rdev, enable);
56304cd92098Szrj 	}
56314cd92098Szrj 
56324cd92098Szrj 	if (block & RADEON_CG_BLOCK_UVD) {
56334cd92098Szrj 		if (rdev->has_uvd) {
56344cd92098Szrj 			si_enable_uvd_mgcg(rdev, enable);
56354cd92098Szrj 		}
56364cd92098Szrj 	}
56374cd92098Szrj 
56384cd92098Szrj 	if (block & RADEON_CG_BLOCK_HDP) {
56394cd92098Szrj 		si_enable_hdp_mgcg(rdev, enable);
56404cd92098Szrj 		si_enable_hdp_ls(rdev, enable);
56414cd92098Szrj 	}
56424cd92098Szrj }
564357e252bfSMichael Neumann 
si_init_cg(struct radeon_device * rdev)564457e252bfSMichael Neumann static void si_init_cg(struct radeon_device *rdev)
564557e252bfSMichael Neumann {
56464cd92098Szrj 	si_update_cg(rdev, (RADEON_CG_BLOCK_GFX |
56474cd92098Szrj 			    RADEON_CG_BLOCK_MC |
56484cd92098Szrj 			    RADEON_CG_BLOCK_SDMA |
56494cd92098Szrj 			    RADEON_CG_BLOCK_BIF |
56504cd92098Szrj 			    RADEON_CG_BLOCK_HDP), true);
565157e252bfSMichael Neumann 	if (rdev->has_uvd) {
56524cd92098Szrj 		si_update_cg(rdev, RADEON_CG_BLOCK_UVD, true);
565357e252bfSMichael Neumann 		si_init_uvd_internal_cg(rdev);
565457e252bfSMichael Neumann 	}
565557e252bfSMichael Neumann }
565657e252bfSMichael Neumann 
si_fini_cg(struct radeon_device * rdev)565757e252bfSMichael Neumann static void si_fini_cg(struct radeon_device *rdev)
565857e252bfSMichael Neumann {
56594cd92098Szrj 	if (rdev->has_uvd) {
56604cd92098Szrj 		si_update_cg(rdev, RADEON_CG_BLOCK_UVD, false);
56614cd92098Szrj 	}
56624cd92098Szrj 	si_update_cg(rdev, (RADEON_CG_BLOCK_GFX |
56634cd92098Szrj 			    RADEON_CG_BLOCK_MC |
56644cd92098Szrj 			    RADEON_CG_BLOCK_SDMA |
56654cd92098Szrj 			    RADEON_CG_BLOCK_BIF |
56664cd92098Szrj 			    RADEON_CG_BLOCK_HDP), false);
56674cd92098Szrj }
56684cd92098Szrj 
si_get_csb_size(struct radeon_device * rdev)56694cd92098Szrj u32 si_get_csb_size(struct radeon_device *rdev)
56704cd92098Szrj {
56714cd92098Szrj 	u32 count = 0;
56724cd92098Szrj 	const struct cs_section_def *sect = NULL;
56734cd92098Szrj 	const struct cs_extent_def *ext = NULL;
56744cd92098Szrj 
56754cd92098Szrj 	if (rdev->rlc.cs_data == NULL)
56764cd92098Szrj 		return 0;
56774cd92098Szrj 
56784cd92098Szrj 	/* begin clear state */
56794cd92098Szrj 	count += 2;
56804cd92098Szrj 	/* context control state */
56814cd92098Szrj 	count += 3;
56824cd92098Szrj 
56834cd92098Szrj 	for (sect = rdev->rlc.cs_data; sect->section != NULL; ++sect) {
56844cd92098Szrj 		for (ext = sect->section; ext->extent != NULL; ++ext) {
56854cd92098Szrj 			if (sect->id == SECT_CONTEXT)
56864cd92098Szrj 				count += 2 + ext->reg_count;
56874cd92098Szrj 			else
56884cd92098Szrj 				return 0;
56894cd92098Szrj 		}
56904cd92098Szrj 	}
56914cd92098Szrj 	/* pa_sc_raster_config */
56924cd92098Szrj 	count += 3;
56934cd92098Szrj 	/* end clear state */
56944cd92098Szrj 	count += 2;
56954cd92098Szrj 	/* clear state */
56964cd92098Szrj 	count += 2;
56974cd92098Szrj 
56984cd92098Szrj 	return count;
56994cd92098Szrj }
57004cd92098Szrj 
si_get_csb_buffer(struct radeon_device * rdev,volatile u32 * buffer)57014cd92098Szrj void si_get_csb_buffer(struct radeon_device *rdev, volatile u32 *buffer)
57024cd92098Szrj {
57034cd92098Szrj 	u32 count = 0, i;
57044cd92098Szrj 	const struct cs_section_def *sect = NULL;
57054cd92098Szrj 	const struct cs_extent_def *ext = NULL;
57064cd92098Szrj 
57074cd92098Szrj 	if (rdev->rlc.cs_data == NULL)
57084cd92098Szrj 		return;
57094cd92098Szrj 	if (buffer == NULL)
57104cd92098Szrj 		return;
57114cd92098Szrj 
5712c6f73aabSFrançois Tigeot 	buffer[count++] = cpu_to_le32(PACKET3(PACKET3_PREAMBLE_CNTL, 0));
5713c6f73aabSFrançois Tigeot 	buffer[count++] = cpu_to_le32(PACKET3_PREAMBLE_BEGIN_CLEAR_STATE);
57144cd92098Szrj 
5715c6f73aabSFrançois Tigeot 	buffer[count++] = cpu_to_le32(PACKET3(PACKET3_CONTEXT_CONTROL, 1));
5716c6f73aabSFrançois Tigeot 	buffer[count++] = cpu_to_le32(0x80000000);
5717c6f73aabSFrançois Tigeot 	buffer[count++] = cpu_to_le32(0x80000000);
57184cd92098Szrj 
57194cd92098Szrj 	for (sect = rdev->rlc.cs_data; sect->section != NULL; ++sect) {
57204cd92098Szrj 		for (ext = sect->section; ext->extent != NULL; ++ext) {
57214cd92098Szrj 			if (sect->id == SECT_CONTEXT) {
5722c6f73aabSFrançois Tigeot 				buffer[count++] =
5723c6f73aabSFrançois Tigeot 					cpu_to_le32(PACKET3(PACKET3_SET_CONTEXT_REG, ext->reg_count));
5724c6f73aabSFrançois Tigeot 				buffer[count++] = cpu_to_le32(ext->reg_index - 0xa000);
57254cd92098Szrj 				for (i = 0; i < ext->reg_count; i++)
5726c6f73aabSFrançois Tigeot 					buffer[count++] = cpu_to_le32(ext->extent[i]);
57274cd92098Szrj 			} else {
57284cd92098Szrj 				return;
57294cd92098Szrj 			}
57304cd92098Szrj 		}
57314cd92098Szrj 	}
57324cd92098Szrj 
5733c6f73aabSFrançois Tigeot 	buffer[count++] = cpu_to_le32(PACKET3(PACKET3_SET_CONTEXT_REG, 1));
5734c6f73aabSFrançois Tigeot 	buffer[count++] = cpu_to_le32(PA_SC_RASTER_CONFIG - PACKET3_SET_CONTEXT_REG_START);
57354cd92098Szrj 	switch (rdev->family) {
57364cd92098Szrj 	case CHIP_TAHITI:
57374cd92098Szrj 	case CHIP_PITCAIRN:
5738c6f73aabSFrançois Tigeot 		buffer[count++] = cpu_to_le32(0x2a00126a);
57394cd92098Szrj 		break;
57404cd92098Szrj 	case CHIP_VERDE:
5741c6f73aabSFrançois Tigeot 		buffer[count++] = cpu_to_le32(0x0000124a);
57424cd92098Szrj 		break;
57434cd92098Szrj 	case CHIP_OLAND:
5744c6f73aabSFrançois Tigeot 		buffer[count++] = cpu_to_le32(0x00000082);
57454cd92098Szrj 		break;
57464cd92098Szrj 	case CHIP_HAINAN:
5747c6f73aabSFrançois Tigeot 		buffer[count++] = cpu_to_le32(0x00000000);
57484cd92098Szrj 		break;
57494cd92098Szrj 	default:
5750c6f73aabSFrançois Tigeot 		buffer[count++] = cpu_to_le32(0x00000000);
57514cd92098Szrj 		break;
57524cd92098Szrj 	}
57534cd92098Szrj 
5754c6f73aabSFrançois Tigeot 	buffer[count++] = cpu_to_le32(PACKET3(PACKET3_PREAMBLE_CNTL, 0));
5755c6f73aabSFrançois Tigeot 	buffer[count++] = cpu_to_le32(PACKET3_PREAMBLE_END_CLEAR_STATE);
57564cd92098Szrj 
5757c6f73aabSFrançois Tigeot 	buffer[count++] = cpu_to_le32(PACKET3(PACKET3_CLEAR_STATE, 0));
5758c6f73aabSFrançois Tigeot 	buffer[count++] = cpu_to_le32(0);
575957e252bfSMichael Neumann }
576057e252bfSMichael Neumann 
si_init_pg(struct radeon_device * rdev)576157e252bfSMichael Neumann static void si_init_pg(struct radeon_device *rdev)
576257e252bfSMichael Neumann {
57634cd92098Szrj 	if (rdev->pg_flags) {
57644cd92098Szrj 		if (rdev->pg_flags & RADEON_PG_SUPPORT_SDMA) {
576557e252bfSMichael Neumann 			si_init_dma_pg(rdev);
57664cd92098Szrj 		}
57674cd92098Szrj 		si_init_ao_cu_mask(rdev);
57684cd92098Szrj 		if (rdev->pg_flags & RADEON_PG_SUPPORT_GFX_PG) {
576957e252bfSMichael Neumann 			si_init_gfx_cgpg(rdev);
5770c6f73aabSFrançois Tigeot 		} else {
5771c6f73aabSFrançois Tigeot 			WREG32(RLC_SAVE_AND_RESTORE_BASE, rdev->rlc.save_restore_gpu_addr >> 8);
5772c6f73aabSFrançois Tigeot 			WREG32(RLC_CLEAR_STATE_RESTORE_BASE, rdev->rlc.clear_state_gpu_addr >> 8);
57734cd92098Szrj 		}
57744cd92098Szrj 		si_enable_dma_pg(rdev, true);
577557e252bfSMichael Neumann 		si_enable_gfx_cgpg(rdev, true);
577657e252bfSMichael Neumann 	} else {
577757e252bfSMichael Neumann 		WREG32(RLC_SAVE_AND_RESTORE_BASE, rdev->rlc.save_restore_gpu_addr >> 8);
577857e252bfSMichael Neumann 		WREG32(RLC_CLEAR_STATE_RESTORE_BASE, rdev->rlc.clear_state_gpu_addr >> 8);
577957e252bfSMichael Neumann 	}
578057e252bfSMichael Neumann }
578157e252bfSMichael Neumann 
si_fini_pg(struct radeon_device * rdev)578257e252bfSMichael Neumann static void si_fini_pg(struct radeon_device *rdev)
578357e252bfSMichael Neumann {
57844cd92098Szrj 	if (rdev->pg_flags) {
578557e252bfSMichael Neumann 		si_enable_dma_pg(rdev, false);
578657e252bfSMichael Neumann 		si_enable_gfx_cgpg(rdev, false);
578757e252bfSMichael Neumann 	}
578857e252bfSMichael Neumann }
578957e252bfSMichael Neumann 
579057e252bfSMichael Neumann /*
5791926deccbSFrançois Tigeot  * RLC
5792926deccbSFrançois Tigeot  */
si_rlc_reset(struct radeon_device * rdev)57934cd92098Szrj void si_rlc_reset(struct radeon_device *rdev)
579457e252bfSMichael Neumann {
579557e252bfSMichael Neumann 	u32 tmp = RREG32(GRBM_SOFT_RESET);
579657e252bfSMichael Neumann 
579757e252bfSMichael Neumann 	tmp |= SOFT_RESET_RLC;
579857e252bfSMichael Neumann 	WREG32(GRBM_SOFT_RESET, tmp);
5799c4ef309bSzrj 	udelay(50);
580057e252bfSMichael Neumann 	tmp &= ~SOFT_RESET_RLC;
580157e252bfSMichael Neumann 	WREG32(GRBM_SOFT_RESET, tmp);
5802c4ef309bSzrj 	udelay(50);
580357e252bfSMichael Neumann }
580457e252bfSMichael Neumann 
si_rlc_stop(struct radeon_device * rdev)5805926deccbSFrançois Tigeot static void si_rlc_stop(struct radeon_device *rdev)
5806926deccbSFrançois Tigeot {
5807926deccbSFrançois Tigeot 	WREG32(RLC_CNTL, 0);
580857e252bfSMichael Neumann 
580957e252bfSMichael Neumann 	si_enable_gui_idle_interrupt(rdev, false);
581057e252bfSMichael Neumann 
581157e252bfSMichael Neumann 	si_wait_for_rlc_serdes(rdev);
5812926deccbSFrançois Tigeot }
5813926deccbSFrançois Tigeot 
si_rlc_start(struct radeon_device * rdev)5814926deccbSFrançois Tigeot static void si_rlc_start(struct radeon_device *rdev)
5815926deccbSFrançois Tigeot {
5816926deccbSFrançois Tigeot 	WREG32(RLC_CNTL, RLC_ENABLE);
581757e252bfSMichael Neumann 
581857e252bfSMichael Neumann 	si_enable_gui_idle_interrupt(rdev, true);
581957e252bfSMichael Neumann 
5820c4ef309bSzrj 	udelay(50);
582157e252bfSMichael Neumann }
582257e252bfSMichael Neumann 
si_lbpw_supported(struct radeon_device * rdev)582357e252bfSMichael Neumann static bool si_lbpw_supported(struct radeon_device *rdev)
582457e252bfSMichael Neumann {
582557e252bfSMichael Neumann 	u32 tmp;
582657e252bfSMichael Neumann 
582757e252bfSMichael Neumann 	/* Enable LBPW only for DDR3 */
582857e252bfSMichael Neumann 	tmp = RREG32(MC_SEQ_MISC0);
582957e252bfSMichael Neumann 	if ((tmp & 0xF0000000) == 0xB0000000)
583057e252bfSMichael Neumann 		return true;
583157e252bfSMichael Neumann 	return false;
583257e252bfSMichael Neumann }
583357e252bfSMichael Neumann 
si_enable_lbpw(struct radeon_device * rdev,bool enable)583457e252bfSMichael Neumann static void si_enable_lbpw(struct radeon_device *rdev, bool enable)
583557e252bfSMichael Neumann {
583657e252bfSMichael Neumann 	u32 tmp;
583757e252bfSMichael Neumann 
583857e252bfSMichael Neumann 	tmp = RREG32(RLC_LB_CNTL);
583957e252bfSMichael Neumann 	if (enable)
584057e252bfSMichael Neumann 		tmp |= LOAD_BALANCE_ENABLE;
584157e252bfSMichael Neumann 	else
584257e252bfSMichael Neumann 		tmp &= ~LOAD_BALANCE_ENABLE;
584357e252bfSMichael Neumann 	WREG32(RLC_LB_CNTL, tmp);
584457e252bfSMichael Neumann 
584557e252bfSMichael Neumann 	if (!enable) {
584657e252bfSMichael Neumann 		si_select_se_sh(rdev, 0xffffffff, 0xffffffff);
584757e252bfSMichael Neumann 		WREG32(SPI_LB_CU_MASK, 0x00ff);
584857e252bfSMichael Neumann 	}
5849926deccbSFrançois Tigeot }
5850926deccbSFrançois Tigeot 
si_rlc_resume(struct radeon_device * rdev)5851926deccbSFrançois Tigeot static int si_rlc_resume(struct radeon_device *rdev)
5852926deccbSFrançois Tigeot {
5853926deccbSFrançois Tigeot 	u32 i;
5854926deccbSFrançois Tigeot 
5855926deccbSFrançois Tigeot 	if (!rdev->rlc_fw)
5856926deccbSFrançois Tigeot 		return -EINVAL;
5857926deccbSFrançois Tigeot 
5858926deccbSFrançois Tigeot 	si_rlc_stop(rdev);
5859926deccbSFrançois Tigeot 
586057e252bfSMichael Neumann 	si_rlc_reset(rdev);
586157e252bfSMichael Neumann 
586257e252bfSMichael Neumann 	si_init_pg(rdev);
586357e252bfSMichael Neumann 
586457e252bfSMichael Neumann 	si_init_cg(rdev);
586557e252bfSMichael Neumann 
5866926deccbSFrançois Tigeot 	WREG32(RLC_RL_BASE, 0);
5867926deccbSFrançois Tigeot 	WREG32(RLC_RL_SIZE, 0);
5868926deccbSFrançois Tigeot 	WREG32(RLC_LB_CNTL, 0);
5869926deccbSFrançois Tigeot 	WREG32(RLC_LB_CNTR_MAX, 0xffffffff);
5870926deccbSFrançois Tigeot 	WREG32(RLC_LB_CNTR_INIT, 0);
587157e252bfSMichael Neumann 	WREG32(RLC_LB_INIT_CU_MASK, 0xffffffff);
5872926deccbSFrançois Tigeot 
5873926deccbSFrançois Tigeot 	WREG32(RLC_MC_CNTL, 0);
5874926deccbSFrançois Tigeot 	WREG32(RLC_UCODE_CNTL, 0);
5875926deccbSFrançois Tigeot 
5876cb754608SImre Vadász 	if (rdev->new_fw) {
5877cb754608SImre Vadász 		const struct rlc_firmware_header_v1_0 *hdr =
5878cb754608SImre Vadász 			(const struct rlc_firmware_header_v1_0 *)rdev->rlc_fw->data;
5879cb754608SImre Vadász 		u32 fw_size = le32_to_cpu(hdr->header.ucode_size_bytes) / 4;
5880cb754608SImre Vadász 		const __le32 *fw_data = (const __le32 *)
5881c59a5c48SFrançois Tigeot 			(rdev->rlc_fw->data + le32_to_cpu(hdr->header.ucode_array_offset_bytes));
5882cb754608SImre Vadász 
5883cb754608SImre Vadász 		radeon_ucode_print_rlc_hdr(&hdr->header);
5884cb754608SImre Vadász 
5885cb754608SImre Vadász 		for (i = 0; i < fw_size; i++) {
5886cb754608SImre Vadász 			WREG32(RLC_UCODE_ADDR, i);
5887cb754608SImre Vadász 			WREG32(RLC_UCODE_DATA, le32_to_cpup(fw_data++));
5888cb754608SImre Vadász 		}
5889cb754608SImre Vadász 	} else {
5890cb754608SImre Vadász 		const __be32 *fw_data =
5891cb754608SImre Vadász 			(const __be32 *)rdev->rlc_fw->data;
5892926deccbSFrançois Tigeot 		for (i = 0; i < SI_RLC_UCODE_SIZE; i++) {
5893926deccbSFrançois Tigeot 			WREG32(RLC_UCODE_ADDR, i);
5894926deccbSFrançois Tigeot 			WREG32(RLC_UCODE_DATA, be32_to_cpup(fw_data++));
5895926deccbSFrançois Tigeot 		}
5896cb754608SImre Vadász 	}
5897926deccbSFrançois Tigeot 	WREG32(RLC_UCODE_ADDR, 0);
5898926deccbSFrançois Tigeot 
589957e252bfSMichael Neumann 	si_enable_lbpw(rdev, si_lbpw_supported(rdev));
590057e252bfSMichael Neumann 
5901926deccbSFrançois Tigeot 	si_rlc_start(rdev);
5902926deccbSFrançois Tigeot 
5903926deccbSFrançois Tigeot 	return 0;
5904926deccbSFrançois Tigeot }
5905926deccbSFrançois Tigeot 
si_enable_interrupts(struct radeon_device * rdev)5906926deccbSFrançois Tigeot static void si_enable_interrupts(struct radeon_device *rdev)
5907926deccbSFrançois Tigeot {
5908926deccbSFrançois Tigeot 	u32 ih_cntl = RREG32(IH_CNTL);
5909926deccbSFrançois Tigeot 	u32 ih_rb_cntl = RREG32(IH_RB_CNTL);
5910926deccbSFrançois Tigeot 
5911926deccbSFrançois Tigeot 	ih_cntl |= ENABLE_INTR;
5912926deccbSFrançois Tigeot 	ih_rb_cntl |= IH_RB_ENABLE;
5913926deccbSFrançois Tigeot 	WREG32(IH_CNTL, ih_cntl);
5914926deccbSFrançois Tigeot 	WREG32(IH_RB_CNTL, ih_rb_cntl);
5915926deccbSFrançois Tigeot 	rdev->ih.enabled = true;
5916926deccbSFrançois Tigeot }
5917926deccbSFrançois Tigeot 
si_disable_interrupts(struct radeon_device * rdev)5918926deccbSFrançois Tigeot static void si_disable_interrupts(struct radeon_device *rdev)
5919926deccbSFrançois Tigeot {
5920926deccbSFrançois Tigeot 	u32 ih_rb_cntl = RREG32(IH_RB_CNTL);
5921926deccbSFrançois Tigeot 	u32 ih_cntl = RREG32(IH_CNTL);
5922926deccbSFrançois Tigeot 
5923926deccbSFrançois Tigeot 	ih_rb_cntl &= ~IH_RB_ENABLE;
5924926deccbSFrançois Tigeot 	ih_cntl &= ~ENABLE_INTR;
5925926deccbSFrançois Tigeot 	WREG32(IH_RB_CNTL, ih_rb_cntl);
5926926deccbSFrançois Tigeot 	WREG32(IH_CNTL, ih_cntl);
5927926deccbSFrançois Tigeot 	/* set rptr, wptr to 0 */
5928926deccbSFrançois Tigeot 	WREG32(IH_RB_RPTR, 0);
5929926deccbSFrançois Tigeot 	WREG32(IH_RB_WPTR, 0);
5930926deccbSFrançois Tigeot 	rdev->ih.enabled = false;
5931926deccbSFrançois Tigeot 	rdev->ih.rptr = 0;
5932926deccbSFrançois Tigeot }
5933926deccbSFrançois Tigeot 
si_disable_interrupt_state(struct radeon_device * rdev)5934926deccbSFrançois Tigeot static void si_disable_interrupt_state(struct radeon_device *rdev)
5935926deccbSFrançois Tigeot {
5936*3f2dd94aSFrançois Tigeot 	int i;
5937926deccbSFrançois Tigeot 	u32 tmp;
5938926deccbSFrançois Tigeot 
59394cd92098Szrj 	tmp = RREG32(CP_INT_CNTL_RING0) &
59404cd92098Szrj 		(CNTX_BUSY_INT_ENABLE | CNTX_EMPTY_INT_ENABLE);
59414cd92098Szrj 	WREG32(CP_INT_CNTL_RING0, tmp);
5942926deccbSFrançois Tigeot 	WREG32(CP_INT_CNTL_RING1, 0);
5943926deccbSFrançois Tigeot 	WREG32(CP_INT_CNTL_RING2, 0);
5944926deccbSFrançois Tigeot 	tmp = RREG32(DMA_CNTL + DMA0_REGISTER_OFFSET) & ~TRAP_ENABLE;
5945926deccbSFrançois Tigeot 	WREG32(DMA_CNTL + DMA0_REGISTER_OFFSET, tmp);
5946926deccbSFrançois Tigeot 	tmp = RREG32(DMA_CNTL + DMA1_REGISTER_OFFSET) & ~TRAP_ENABLE;
5947926deccbSFrançois Tigeot 	WREG32(DMA_CNTL + DMA1_REGISTER_OFFSET, tmp);
5948926deccbSFrançois Tigeot 	WREG32(GRBM_INT_CNTL, 0);
5949c59a5c48SFrançois Tigeot 	WREG32(SRBM_INT_CNTL, 0);
5950*3f2dd94aSFrançois Tigeot 	for (i = 0; i < rdev->num_crtc; i++)
5951*3f2dd94aSFrançois Tigeot 		WREG32(INT_MASK + crtc_offsets[i], 0);
5952*3f2dd94aSFrançois Tigeot 	for (i = 0; i < rdev->num_crtc; i++)
5953*3f2dd94aSFrançois Tigeot 		WREG32(GRPH_INT_CONTROL + crtc_offsets[i], 0);
5954926deccbSFrançois Tigeot 
5955f43cf1b1SMichael Neumann 	if (!ASIC_IS_NODCE(rdev)) {
5956c6f73aabSFrançois Tigeot 		WREG32(DAC_AUTODETECT_INT_CONTROL, 0);
5957926deccbSFrançois Tigeot 
5958*3f2dd94aSFrançois Tigeot 		for (i = 0; i < 6; i++)
5959*3f2dd94aSFrançois Tigeot 			WREG32_AND(DC_HPDx_INT_CONTROL(i),
5960*3f2dd94aSFrançois Tigeot 				   DC_HPDx_INT_POLARITY);
5961f43cf1b1SMichael Neumann 	}
5962926deccbSFrançois Tigeot }
5963926deccbSFrançois Tigeot 
si_irq_init(struct radeon_device * rdev)5964926deccbSFrançois Tigeot static int si_irq_init(struct radeon_device *rdev)
5965926deccbSFrançois Tigeot {
5966926deccbSFrançois Tigeot 	int ret = 0;
5967926deccbSFrançois Tigeot 	int rb_bufsz;
5968926deccbSFrançois Tigeot 	u32 interrupt_cntl, ih_cntl, ih_rb_cntl;
5969926deccbSFrançois Tigeot 
5970926deccbSFrançois Tigeot 	/* allocate ring */
5971926deccbSFrançois Tigeot 	ret = r600_ih_ring_alloc(rdev);
5972926deccbSFrançois Tigeot 	if (ret)
5973926deccbSFrançois Tigeot 		return ret;
5974926deccbSFrançois Tigeot 
5975926deccbSFrançois Tigeot 	/* disable irqs */
5976926deccbSFrançois Tigeot 	si_disable_interrupts(rdev);
5977926deccbSFrançois Tigeot 
5978926deccbSFrançois Tigeot 	/* init rlc */
5979926deccbSFrançois Tigeot 	ret = si_rlc_resume(rdev);
5980926deccbSFrançois Tigeot 	if (ret) {
5981926deccbSFrançois Tigeot 		r600_ih_ring_fini(rdev);
5982926deccbSFrançois Tigeot 		return ret;
5983926deccbSFrançois Tigeot 	}
5984926deccbSFrançois Tigeot 
5985926deccbSFrançois Tigeot 	/* setup interrupt control */
5986926deccbSFrançois Tigeot 	/* set dummy read address to ring address */
5987926deccbSFrançois Tigeot 	WREG32(INTERRUPT_CNTL2, rdev->ih.gpu_addr >> 8);
5988926deccbSFrançois Tigeot 	interrupt_cntl = RREG32(INTERRUPT_CNTL);
5989926deccbSFrançois Tigeot 	/* IH_DUMMY_RD_OVERRIDE=0 - dummy read disabled with msi, enabled without msi
5990926deccbSFrançois Tigeot 	 * IH_DUMMY_RD_OVERRIDE=1 - dummy read controlled by IH_DUMMY_RD_EN
5991926deccbSFrançois Tigeot 	 */
5992926deccbSFrançois Tigeot 	interrupt_cntl &= ~IH_DUMMY_RD_OVERRIDE;
5993926deccbSFrançois Tigeot 	/* IH_REQ_NONSNOOP_EN=1 if ring is in non-cacheable memory, e.g., vram */
5994926deccbSFrançois Tigeot 	interrupt_cntl &= ~IH_REQ_NONSNOOP_EN;
5995926deccbSFrançois Tigeot 	WREG32(INTERRUPT_CNTL, interrupt_cntl);
5996926deccbSFrançois Tigeot 
5997926deccbSFrançois Tigeot 	WREG32(IH_RB_BASE, rdev->ih.gpu_addr >> 8);
59984cd92098Szrj 	rb_bufsz = order_base_2(rdev->ih.ring_size / 4);
5999926deccbSFrançois Tigeot 
6000926deccbSFrançois Tigeot 	ih_rb_cntl = (IH_WPTR_OVERFLOW_ENABLE |
6001926deccbSFrançois Tigeot 		      IH_WPTR_OVERFLOW_CLEAR |
6002926deccbSFrançois Tigeot 		      (rb_bufsz << 1));
6003926deccbSFrançois Tigeot 
6004926deccbSFrançois Tigeot 	if (rdev->wb.enabled)
6005926deccbSFrançois Tigeot 		ih_rb_cntl |= IH_WPTR_WRITEBACK_ENABLE;
6006926deccbSFrançois Tigeot 
6007926deccbSFrançois Tigeot 	/* set the writeback address whether it's enabled or not */
6008926deccbSFrançois Tigeot 	WREG32(IH_RB_WPTR_ADDR_LO, (rdev->wb.gpu_addr + R600_WB_IH_WPTR_OFFSET) & 0xFFFFFFFC);
6009926deccbSFrançois Tigeot 	WREG32(IH_RB_WPTR_ADDR_HI, upper_32_bits(rdev->wb.gpu_addr + R600_WB_IH_WPTR_OFFSET) & 0xFF);
6010926deccbSFrançois Tigeot 
6011926deccbSFrançois Tigeot 	WREG32(IH_RB_CNTL, ih_rb_cntl);
6012926deccbSFrançois Tigeot 
6013926deccbSFrançois Tigeot 	/* set rptr, wptr to 0 */
6014926deccbSFrançois Tigeot 	WREG32(IH_RB_RPTR, 0);
6015926deccbSFrançois Tigeot 	WREG32(IH_RB_WPTR, 0);
6016926deccbSFrançois Tigeot 
6017926deccbSFrançois Tigeot 	/* Default settings for IH_CNTL (disabled at first) */
6018926deccbSFrançois Tigeot 	ih_cntl = MC_WRREQ_CREDIT(0x10) | MC_WR_CLEAN_CNT(0x10) | MC_VMID(0);
6019926deccbSFrançois Tigeot 	/* RPTR_REARM only works if msi's are enabled */
6020926deccbSFrançois Tigeot 	if (rdev->msi_enabled)
6021926deccbSFrançois Tigeot 		ih_cntl |= RPTR_REARM;
6022926deccbSFrançois Tigeot 	WREG32(IH_CNTL, ih_cntl);
6023926deccbSFrançois Tigeot 
6024926deccbSFrançois Tigeot 	/* force the active interrupt state to all disabled */
6025926deccbSFrançois Tigeot 	si_disable_interrupt_state(rdev);
6026926deccbSFrançois Tigeot 
6027c59a5c48SFrançois Tigeot 	pci_set_master(rdev->pdev);
6028926deccbSFrançois Tigeot 
6029926deccbSFrançois Tigeot 	/* enable irqs */
6030926deccbSFrançois Tigeot 	si_enable_interrupts(rdev);
6031926deccbSFrançois Tigeot 
6032926deccbSFrançois Tigeot 	return ret;
6033926deccbSFrançois Tigeot }
6034926deccbSFrançois Tigeot 
6035*3f2dd94aSFrançois Tigeot /* The order we write back each register here is important */
si_irq_set(struct radeon_device * rdev)6036926deccbSFrançois Tigeot int si_irq_set(struct radeon_device *rdev)
6037926deccbSFrançois Tigeot {
6038*3f2dd94aSFrançois Tigeot 	int i;
60394cd92098Szrj 	u32 cp_int_cntl;
6040926deccbSFrançois Tigeot 	u32 cp_int_cntl1 = 0, cp_int_cntl2 = 0;
6041926deccbSFrançois Tigeot 	u32 grbm_int_cntl = 0;
6042926deccbSFrançois Tigeot 	u32 dma_cntl, dma_cntl1;
604357e252bfSMichael Neumann 	u32 thermal_int = 0;
6044926deccbSFrançois Tigeot 
6045926deccbSFrançois Tigeot 	if (!rdev->irq.installed) {
6046c4ef309bSzrj 		WARN(1, "Can't enable IRQ/MSI because no handler is installed\n");
6047926deccbSFrançois Tigeot 		return -EINVAL;
6048926deccbSFrançois Tigeot 	}
6049926deccbSFrançois Tigeot 	/* don't enable anything if the ih is disabled */
6050926deccbSFrançois Tigeot 	if (!rdev->ih.enabled) {
6051926deccbSFrançois Tigeot 		si_disable_interrupts(rdev);
6052926deccbSFrançois Tigeot 		/* force the active interrupt state to all disabled */
6053926deccbSFrançois Tigeot 		si_disable_interrupt_state(rdev);
6054926deccbSFrançois Tigeot 		return 0;
6055926deccbSFrançois Tigeot 	}
6056926deccbSFrançois Tigeot 
60574cd92098Szrj 	cp_int_cntl = RREG32(CP_INT_CNTL_RING0) &
60584cd92098Szrj 		(CNTX_BUSY_INT_ENABLE | CNTX_EMPTY_INT_ENABLE);
60594cd92098Szrj 
6060926deccbSFrançois Tigeot 	dma_cntl = RREG32(DMA_CNTL + DMA0_REGISTER_OFFSET) & ~TRAP_ENABLE;
6061926deccbSFrançois Tigeot 	dma_cntl1 = RREG32(DMA_CNTL + DMA1_REGISTER_OFFSET) & ~TRAP_ENABLE;
6062926deccbSFrançois Tigeot 
606357e252bfSMichael Neumann 	thermal_int = RREG32(CG_THERMAL_INT) &
606457e252bfSMichael Neumann 		~(THERM_INT_MASK_HIGH | THERM_INT_MASK_LOW);
606557e252bfSMichael Neumann 
6066926deccbSFrançois Tigeot 	/* enable CP interrupts on all rings */
6067926deccbSFrançois Tigeot 	if (atomic_read(&rdev->irq.ring_int[RADEON_RING_TYPE_GFX_INDEX])) {
6068926deccbSFrançois Tigeot 		DRM_DEBUG("si_irq_set: sw int gfx\n");
6069926deccbSFrançois Tigeot 		cp_int_cntl |= TIME_STAMP_INT_ENABLE;
6070926deccbSFrançois Tigeot 	}
6071926deccbSFrançois Tigeot 	if (atomic_read(&rdev->irq.ring_int[CAYMAN_RING_TYPE_CP1_INDEX])) {
6072926deccbSFrançois Tigeot 		DRM_DEBUG("si_irq_set: sw int cp1\n");
6073926deccbSFrançois Tigeot 		cp_int_cntl1 |= TIME_STAMP_INT_ENABLE;
6074926deccbSFrançois Tigeot 	}
6075926deccbSFrançois Tigeot 	if (atomic_read(&rdev->irq.ring_int[CAYMAN_RING_TYPE_CP2_INDEX])) {
6076926deccbSFrançois Tigeot 		DRM_DEBUG("si_irq_set: sw int cp2\n");
6077926deccbSFrançois Tigeot 		cp_int_cntl2 |= TIME_STAMP_INT_ENABLE;
6078926deccbSFrançois Tigeot 	}
6079926deccbSFrançois Tigeot 	if (atomic_read(&rdev->irq.ring_int[R600_RING_TYPE_DMA_INDEX])) {
6080926deccbSFrançois Tigeot 		DRM_DEBUG("si_irq_set: sw int dma\n");
6081926deccbSFrançois Tigeot 		dma_cntl |= TRAP_ENABLE;
6082926deccbSFrançois Tigeot 	}
6083926deccbSFrançois Tigeot 
6084926deccbSFrançois Tigeot 	if (atomic_read(&rdev->irq.ring_int[CAYMAN_RING_TYPE_DMA1_INDEX])) {
6085926deccbSFrançois Tigeot 		DRM_DEBUG("si_irq_set: sw int dma1\n");
6086926deccbSFrançois Tigeot 		dma_cntl1 |= TRAP_ENABLE;
6087926deccbSFrançois Tigeot 	}
6088926deccbSFrançois Tigeot 
6089926deccbSFrançois Tigeot 	WREG32(CP_INT_CNTL_RING0, cp_int_cntl);
6090926deccbSFrançois Tigeot 	WREG32(CP_INT_CNTL_RING1, cp_int_cntl1);
6091926deccbSFrançois Tigeot 	WREG32(CP_INT_CNTL_RING2, cp_int_cntl2);
6092926deccbSFrançois Tigeot 
6093926deccbSFrançois Tigeot 	WREG32(DMA_CNTL + DMA0_REGISTER_OFFSET, dma_cntl);
6094926deccbSFrançois Tigeot 	WREG32(DMA_CNTL + DMA1_REGISTER_OFFSET, dma_cntl1);
6095926deccbSFrançois Tigeot 
6096926deccbSFrançois Tigeot 	WREG32(GRBM_INT_CNTL, grbm_int_cntl);
6097926deccbSFrançois Tigeot 
609857e252bfSMichael Neumann 	if (rdev->irq.dpm_thermal) {
609957e252bfSMichael Neumann 		DRM_DEBUG("dpm thermal\n");
610057e252bfSMichael Neumann 		thermal_int |= THERM_INT_MASK_HIGH | THERM_INT_MASK_LOW;
610157e252bfSMichael Neumann 	}
610257e252bfSMichael Neumann 
6103*3f2dd94aSFrançois Tigeot 	for (i = 0; i < rdev->num_crtc; i++) {
6104*3f2dd94aSFrançois Tigeot 		radeon_irq_kms_set_irq_n_enabled(
6105*3f2dd94aSFrançois Tigeot 		    rdev, INT_MASK + crtc_offsets[i], VBLANK_INT_MASK,
6106*3f2dd94aSFrançois Tigeot 		    rdev->irq.crtc_vblank_int[i] ||
6107*3f2dd94aSFrançois Tigeot 		    atomic_read(&rdev->irq.pflip[i]), "vblank", i);
6108926deccbSFrançois Tigeot 	}
6109926deccbSFrançois Tigeot 
6110*3f2dd94aSFrançois Tigeot 	for (i = 0; i < rdev->num_crtc; i++)
6111*3f2dd94aSFrançois Tigeot 		WREG32(GRPH_INT_CONTROL + crtc_offsets[i], GRPH_PFLIP_INT_MASK);
6112926deccbSFrançois Tigeot 
6113f43cf1b1SMichael Neumann 	if (!ASIC_IS_NODCE(rdev)) {
6114*3f2dd94aSFrançois Tigeot 		for (i = 0; i < 6; i++) {
6115*3f2dd94aSFrançois Tigeot 			radeon_irq_kms_set_irq_n_enabled(
6116*3f2dd94aSFrançois Tigeot 			    rdev, DC_HPDx_INT_CONTROL(i),
6117*3f2dd94aSFrançois Tigeot 			    DC_HPDx_INT_EN | DC_HPDx_RX_INT_EN,
6118*3f2dd94aSFrançois Tigeot 			    rdev->irq.hpd[i], "HPD", i);
6119*3f2dd94aSFrançois Tigeot 		}
6120f43cf1b1SMichael Neumann 	}
6121926deccbSFrançois Tigeot 
612257e252bfSMichael Neumann 	WREG32(CG_THERMAL_INT, thermal_int);
612357e252bfSMichael Neumann 
61247dcf36dcSFrançois Tigeot 	/* posting read */
61257dcf36dcSFrançois Tigeot 	RREG32(SRBM_STATUS);
61267dcf36dcSFrançois Tigeot 
6127926deccbSFrançois Tigeot 	return 0;
6128926deccbSFrançois Tigeot }
6129926deccbSFrançois Tigeot 
6130*3f2dd94aSFrançois Tigeot /* The order we write back each register here is important */
si_irq_ack(struct radeon_device * rdev)6131926deccbSFrançois Tigeot static inline void si_irq_ack(struct radeon_device *rdev)
6132926deccbSFrançois Tigeot {
6133*3f2dd94aSFrançois Tigeot 	int i, j;
6134*3f2dd94aSFrançois Tigeot 	u32 *disp_int = rdev->irq.stat_regs.evergreen.disp_int;
6135*3f2dd94aSFrançois Tigeot 	u32 *grph_int = rdev->irq.stat_regs.evergreen.grph_int;
6136926deccbSFrançois Tigeot 
6137f43cf1b1SMichael Neumann 	if (ASIC_IS_NODCE(rdev))
6138f43cf1b1SMichael Neumann 		return;
6139f43cf1b1SMichael Neumann 
6140*3f2dd94aSFrançois Tigeot 	for (i = 0; i < 6; i++) {
6141*3f2dd94aSFrançois Tigeot 		disp_int[i] = RREG32(si_disp_int_status[i]);
6142*3f2dd94aSFrançois Tigeot 		if (i < rdev->num_crtc)
6143*3f2dd94aSFrançois Tigeot 			grph_int[i] = RREG32(GRPH_INT_STATUS + crtc_offsets[i]);
6144926deccbSFrançois Tigeot 	}
6145926deccbSFrançois Tigeot 
6146*3f2dd94aSFrançois Tigeot 	/* We write back each interrupt register in pairs of two */
6147*3f2dd94aSFrançois Tigeot 	for (i = 0; i < rdev->num_crtc; i += 2) {
6148*3f2dd94aSFrançois Tigeot 		for (j = i; j < (i + 2); j++) {
6149*3f2dd94aSFrançois Tigeot 			if (grph_int[j] & GRPH_PFLIP_INT_OCCURRED)
6150*3f2dd94aSFrançois Tigeot 				WREG32(GRPH_INT_STATUS + crtc_offsets[j],
6151*3f2dd94aSFrançois Tigeot 				       GRPH_PFLIP_INT_CLEAR);
6152926deccbSFrançois Tigeot 		}
6153926deccbSFrançois Tigeot 
6154*3f2dd94aSFrançois Tigeot 		for (j = i; j < (i + 2); j++) {
6155*3f2dd94aSFrançois Tigeot 			if (disp_int[j] & LB_D1_VBLANK_INTERRUPT)
6156*3f2dd94aSFrançois Tigeot 				WREG32(VBLANK_STATUS + crtc_offsets[j],
6157*3f2dd94aSFrançois Tigeot 				       VBLANK_ACK);
6158*3f2dd94aSFrançois Tigeot 			if (disp_int[j] & LB_D1_VLINE_INTERRUPT)
6159*3f2dd94aSFrançois Tigeot 				WREG32(VLINE_STATUS + crtc_offsets[j],
6160*3f2dd94aSFrançois Tigeot 				       VLINE_ACK);
6161*3f2dd94aSFrançois Tigeot 		}
6162926deccbSFrançois Tigeot 	}
6163926deccbSFrançois Tigeot 
6164*3f2dd94aSFrançois Tigeot 	for (i = 0; i < 6; i++) {
6165*3f2dd94aSFrançois Tigeot 		if (disp_int[i] & DC_HPD1_INTERRUPT)
6166*3f2dd94aSFrançois Tigeot 			WREG32_OR(DC_HPDx_INT_CONTROL(i), DC_HPDx_INT_ACK);
6167926deccbSFrançois Tigeot 	}
6168c59a5c48SFrançois Tigeot 
6169*3f2dd94aSFrançois Tigeot 	for (i = 0; i < 6; i++) {
6170*3f2dd94aSFrançois Tigeot 		if (disp_int[i] & DC_HPD1_RX_INTERRUPT)
6171*3f2dd94aSFrançois Tigeot 			WREG32_OR(DC_HPDx_INT_CONTROL(i), DC_HPDx_RX_INT_ACK);
6172c59a5c48SFrançois Tigeot 	}
6173926deccbSFrançois Tigeot }
6174926deccbSFrançois Tigeot 
si_irq_disable(struct radeon_device * rdev)6175926deccbSFrançois Tigeot static void si_irq_disable(struct radeon_device *rdev)
6176926deccbSFrançois Tigeot {
6177926deccbSFrançois Tigeot 	si_disable_interrupts(rdev);
6178926deccbSFrançois Tigeot 	/* Wait and acknowledge irq */
6179c4ef309bSzrj 	mdelay(1);
6180926deccbSFrançois Tigeot 	si_irq_ack(rdev);
6181926deccbSFrançois Tigeot 	si_disable_interrupt_state(rdev);
6182926deccbSFrançois Tigeot }
6183926deccbSFrançois Tigeot 
si_irq_suspend(struct radeon_device * rdev)6184926deccbSFrançois Tigeot static void si_irq_suspend(struct radeon_device *rdev)
6185926deccbSFrançois Tigeot {
6186926deccbSFrançois Tigeot 	si_irq_disable(rdev);
6187926deccbSFrançois Tigeot 	si_rlc_stop(rdev);
6188926deccbSFrançois Tigeot }
6189926deccbSFrançois Tigeot 
si_irq_fini(struct radeon_device * rdev)6190926deccbSFrançois Tigeot static void si_irq_fini(struct radeon_device *rdev)
6191926deccbSFrançois Tigeot {
6192926deccbSFrançois Tigeot 	si_irq_suspend(rdev);
6193926deccbSFrançois Tigeot 	r600_ih_ring_fini(rdev);
6194926deccbSFrançois Tigeot }
6195926deccbSFrançois Tigeot 
si_get_ih_wptr(struct radeon_device * rdev)6196926deccbSFrançois Tigeot static inline u32 si_get_ih_wptr(struct radeon_device *rdev)
6197926deccbSFrançois Tigeot {
6198926deccbSFrançois Tigeot 	u32 wptr, tmp;
6199926deccbSFrançois Tigeot 
6200926deccbSFrançois Tigeot 	if (rdev->wb.enabled)
6201926deccbSFrançois Tigeot 		wptr = le32_to_cpu(rdev->wb.wb[R600_WB_IH_WPTR_OFFSET/4]);
6202926deccbSFrançois Tigeot 	else
6203926deccbSFrançois Tigeot 		wptr = RREG32(IH_RB_WPTR);
6204926deccbSFrançois Tigeot 
6205926deccbSFrançois Tigeot 	if (wptr & RB_OVERFLOW) {
6206c6f73aabSFrançois Tigeot 		wptr &= ~RB_OVERFLOW;
6207926deccbSFrançois Tigeot 		/* When a ring buffer overflow happen start parsing interrupt
6208926deccbSFrançois Tigeot 		 * from the last not overwritten vector (wptr + 16). Hopefully
6209926deccbSFrançois Tigeot 		 * this should allow us to catchup.
6210926deccbSFrançois Tigeot 		 */
6211c6f73aabSFrançois Tigeot 		dev_warn(rdev->dev, "IH ring buffer overflow (0x%08X, 0x%08X, 0x%08X)\n",
6212c6f73aabSFrançois Tigeot 			 wptr, rdev->ih.rptr, (wptr + 16) & rdev->ih.ptr_mask);
6213926deccbSFrançois Tigeot 		rdev->ih.rptr = (wptr + 16) & rdev->ih.ptr_mask;
6214926deccbSFrançois Tigeot 		tmp = RREG32(IH_RB_CNTL);
6215926deccbSFrançois Tigeot 		tmp |= IH_WPTR_OVERFLOW_CLEAR;
6216926deccbSFrançois Tigeot 		WREG32(IH_RB_CNTL, tmp);
6217926deccbSFrançois Tigeot 	}
6218926deccbSFrançois Tigeot 	return (wptr & rdev->ih.ptr_mask);
6219926deccbSFrançois Tigeot }
6220926deccbSFrançois Tigeot 
6221926deccbSFrançois Tigeot /*        SI IV Ring
6222926deccbSFrançois Tigeot  * Each IV ring entry is 128 bits:
6223926deccbSFrançois Tigeot  * [7:0]    - interrupt source id
6224926deccbSFrançois Tigeot  * [31:8]   - reserved
6225926deccbSFrançois Tigeot  * [59:32]  - interrupt source data
6226926deccbSFrançois Tigeot  * [63:60]  - reserved
6227926deccbSFrançois Tigeot  * [71:64]  - RINGID
6228926deccbSFrançois Tigeot  * [79:72]  - VMID
6229926deccbSFrançois Tigeot  * [127:80] - reserved
6230926deccbSFrançois Tigeot  */
si_irq_process(struct radeon_device * rdev)6231926deccbSFrançois Tigeot irqreturn_t si_irq_process(struct radeon_device *rdev)
6232926deccbSFrançois Tigeot {
6233*3f2dd94aSFrançois Tigeot 	u32 *disp_int = rdev->irq.stat_regs.evergreen.disp_int;
6234*3f2dd94aSFrançois Tigeot 	u32 crtc_idx, hpd_idx;
6235*3f2dd94aSFrançois Tigeot 	u32 mask;
6236926deccbSFrançois Tigeot 	u32 wptr;
6237926deccbSFrançois Tigeot 	u32 rptr;
6238926deccbSFrançois Tigeot 	u32 src_id, src_data, ring_id;
6239926deccbSFrançois Tigeot 	u32 ring_index;
6240926deccbSFrançois Tigeot 	bool queue_hotplug = false;
6241c59a5c48SFrançois Tigeot 	bool queue_dp = false;
624257e252bfSMichael Neumann 	bool queue_thermal = false;
624357e252bfSMichael Neumann 	u32 status, addr;
6244*3f2dd94aSFrançois Tigeot 	const char *event_name;
6245926deccbSFrançois Tigeot 
6246926deccbSFrançois Tigeot 	if (!rdev->ih.enabled || rdev->shutdown)
6247926deccbSFrançois Tigeot 		return IRQ_NONE;
6248926deccbSFrançois Tigeot 
6249926deccbSFrançois Tigeot 	wptr = si_get_ih_wptr(rdev);
6250926deccbSFrançois Tigeot 
6251926deccbSFrançois Tigeot restart_ih:
6252926deccbSFrançois Tigeot 	/* is somebody else already processing irqs? */
6253926deccbSFrançois Tigeot 	if (atomic_xchg(&rdev->ih.lock, 1))
6254926deccbSFrançois Tigeot 		return IRQ_NONE;
6255926deccbSFrançois Tigeot 
6256926deccbSFrançois Tigeot 	rptr = rdev->ih.rptr;
6257ee479021SImre Vadász 	DRM_DEBUG_VBLANK("si_irq_process start: rptr %d, wptr %d\n", rptr, wptr);
6258926deccbSFrançois Tigeot 
6259926deccbSFrançois Tigeot 	/* Order reading of wptr vs. reading of IH ring data */
6260c4ef309bSzrj 	rmb();
6261926deccbSFrançois Tigeot 
6262926deccbSFrançois Tigeot 	/* display interrupts */
6263926deccbSFrançois Tigeot 	si_irq_ack(rdev);
6264926deccbSFrançois Tigeot 
6265926deccbSFrançois Tigeot 	while (rptr != wptr) {
6266926deccbSFrançois Tigeot 		/* wptr/rptr are in bytes! */
6267926deccbSFrançois Tigeot 		ring_index = rptr / 4;
6268926deccbSFrançois Tigeot 		src_id =  le32_to_cpu(rdev->ih.ring[ring_index]) & 0xff;
6269926deccbSFrançois Tigeot 		src_data = le32_to_cpu(rdev->ih.ring[ring_index + 1]) & 0xfffffff;
6270926deccbSFrançois Tigeot 		ring_id = le32_to_cpu(rdev->ih.ring[ring_index + 2]) & 0xff;
6271926deccbSFrançois Tigeot 
6272926deccbSFrançois Tigeot 		switch (src_id) {
6273926deccbSFrançois Tigeot 		case 1: /* D1 vblank/vline */
6274926deccbSFrançois Tigeot 		case 2: /* D2 vblank/vline */
6275926deccbSFrançois Tigeot 		case 3: /* D3 vblank/vline */
6276926deccbSFrançois Tigeot 		case 4: /* D4 vblank/vline */
6277926deccbSFrançois Tigeot 		case 5: /* D5 vblank/vline */
6278926deccbSFrançois Tigeot 		case 6: /* D6 vblank/vline */
6279*3f2dd94aSFrançois Tigeot 			crtc_idx = src_id - 1;
6280c59a5c48SFrançois Tigeot 
6281*3f2dd94aSFrançois Tigeot 			if (src_data == 0) { /* vblank */
6282*3f2dd94aSFrançois Tigeot 				mask = LB_D1_VBLANK_INTERRUPT;
6283*3f2dd94aSFrançois Tigeot 				event_name = "vblank";
6284*3f2dd94aSFrançois Tigeot 
6285*3f2dd94aSFrançois Tigeot 				if (rdev->irq.crtc_vblank_int[crtc_idx]) {
6286*3f2dd94aSFrançois Tigeot 					drm_handle_vblank(rdev->ddev, crtc_idx);
6287926deccbSFrançois Tigeot 					rdev->pm.vblank_sync = true;
6288c4ef309bSzrj 					wake_up(&rdev->irq.vblank_queue);
6289926deccbSFrançois Tigeot 				}
6290*3f2dd94aSFrançois Tigeot 				if (atomic_read(&rdev->irq.pflip[crtc_idx])) {
6291*3f2dd94aSFrançois Tigeot 					radeon_crtc_handle_vblank(rdev,
6292*3f2dd94aSFrançois Tigeot 								  crtc_idx);
6293*3f2dd94aSFrançois Tigeot 				}
6294c59a5c48SFrançois Tigeot 
6295*3f2dd94aSFrançois Tigeot 			} else if (src_data == 1) { /* vline */
6296*3f2dd94aSFrançois Tigeot 				mask = LB_D1_VLINE_INTERRUPT;
6297*3f2dd94aSFrançois Tigeot 				event_name = "vline";
6298*3f2dd94aSFrançois Tigeot 			} else {
6299*3f2dd94aSFrançois Tigeot 				DRM_DEBUG("Unhandled interrupt: %d %d\n",
6300*3f2dd94aSFrançois Tigeot 					  src_id, src_data);
6301926deccbSFrançois Tigeot 				break;
6302926deccbSFrançois Tigeot 			}
6303*3f2dd94aSFrançois Tigeot 
6304*3f2dd94aSFrançois Tigeot 			if (!(disp_int[crtc_idx] & mask)) {
6305*3f2dd94aSFrançois Tigeot 				DRM_DEBUG("IH: D%d %s - IH event w/o asserted irq bit?\n",
6306*3f2dd94aSFrançois Tigeot 					  crtc_idx + 1, event_name);
6307*3f2dd94aSFrançois Tigeot 			}
6308*3f2dd94aSFrançois Tigeot 
6309*3f2dd94aSFrançois Tigeot 			disp_int[crtc_idx] &= ~mask;
6310*3f2dd94aSFrançois Tigeot 			DRM_DEBUG("IH: D%d %s\n", crtc_idx + 1, event_name);
6311*3f2dd94aSFrançois Tigeot 
6312926deccbSFrançois Tigeot 			break;
6313c6f73aabSFrançois Tigeot 		case 8: /* D1 page flip */
6314c6f73aabSFrançois Tigeot 		case 10: /* D2 page flip */
6315c6f73aabSFrançois Tigeot 		case 12: /* D3 page flip */
6316c6f73aabSFrançois Tigeot 		case 14: /* D4 page flip */
6317c6f73aabSFrançois Tigeot 		case 16: /* D5 page flip */
6318c6f73aabSFrançois Tigeot 		case 18: /* D6 page flip */
6319*3f2dd94aSFrançois Tigeot 			DRM_DEBUG("IH: D%d flip\n", ((src_id - 8) >> 1) + 1);
6320c6f73aabSFrançois Tigeot 			if (radeon_use_pflipirq > 0)
6321c6f73aabSFrançois Tigeot 				radeon_crtc_handle_flip(rdev, (src_id - 8) >> 1);
6322c6f73aabSFrançois Tigeot 			break;
6323926deccbSFrançois Tigeot 		case 42: /* HPD hotplug */
6324*3f2dd94aSFrançois Tigeot 			if (src_data <= 5) {
6325*3f2dd94aSFrançois Tigeot 				hpd_idx = src_data;
6326*3f2dd94aSFrançois Tigeot 				mask = DC_HPD1_INTERRUPT;
6327926deccbSFrançois Tigeot 				queue_hotplug = true;
6328*3f2dd94aSFrançois Tigeot 				event_name = "HPD";
6329c59a5c48SFrançois Tigeot 
6330*3f2dd94aSFrançois Tigeot 			} else if (src_data <= 11) {
6331*3f2dd94aSFrançois Tigeot 				hpd_idx = src_data - 6;
6332*3f2dd94aSFrançois Tigeot 				mask = DC_HPD1_RX_INTERRUPT;
6333c59a5c48SFrançois Tigeot 				queue_dp = true;
6334*3f2dd94aSFrançois Tigeot 				event_name = "HPD_RX";
6335c59a5c48SFrançois Tigeot 
6336*3f2dd94aSFrançois Tigeot 			} else {
6337*3f2dd94aSFrançois Tigeot 				DRM_DEBUG("Unhandled interrupt: %d %d\n",
6338*3f2dd94aSFrançois Tigeot 					  src_id, src_data);
6339926deccbSFrançois Tigeot 				break;
6340926deccbSFrançois Tigeot 			}
6341*3f2dd94aSFrançois Tigeot 
6342*3f2dd94aSFrançois Tigeot 			if (!(disp_int[hpd_idx] & mask))
6343*3f2dd94aSFrançois Tigeot 				DRM_DEBUG("IH: IH event w/o asserted irq bit?\n");
6344*3f2dd94aSFrançois Tigeot 
6345*3f2dd94aSFrançois Tigeot 			disp_int[hpd_idx] &= ~mask;
6346*3f2dd94aSFrançois Tigeot 			DRM_DEBUG("IH: %s%d\n", event_name, hpd_idx + 1);
6347926deccbSFrançois Tigeot 			break;
6348c59a5c48SFrançois Tigeot 		case 96:
6349c59a5c48SFrançois Tigeot 			DRM_ERROR("SRBM_READ_ERROR: 0x%x\n", RREG32(SRBM_READ_ERROR));
6350c59a5c48SFrançois Tigeot 			WREG32(SRBM_INT_ACK, 0x1);
6351c59a5c48SFrançois Tigeot 			break;
6352c6f73aabSFrançois Tigeot 		case 124: /* UVD */
6353c6f73aabSFrançois Tigeot 			DRM_DEBUG("IH: UVD int: 0x%08x\n", src_data);
6354c6f73aabSFrançois Tigeot 			radeon_fence_process(rdev, R600_RING_TYPE_UVD_INDEX);
6355c6f73aabSFrançois Tigeot 			break;
6356926deccbSFrançois Tigeot 		case 146:
6357926deccbSFrançois Tigeot 		case 147:
635857e252bfSMichael Neumann 			addr = RREG32(VM_CONTEXT1_PROTECTION_FAULT_ADDR);
635957e252bfSMichael Neumann 			status = RREG32(VM_CONTEXT1_PROTECTION_FAULT_STATUS);
6360c6f73aabSFrançois Tigeot 			/* reset addr and status */
6361c6f73aabSFrançois Tigeot 			WREG32_P(VM_CONTEXT1_CNTL2, 1, ~1);
6362c6f73aabSFrançois Tigeot 			if (addr == 0x0 && status == 0x0)
6363c6f73aabSFrançois Tigeot 				break;
6364926deccbSFrançois Tigeot 			dev_err(rdev->dev, "GPU fault detected: %d 0x%08x\n", src_id, src_data);
6365926deccbSFrançois Tigeot 			dev_err(rdev->dev, "  VM_CONTEXT1_PROTECTION_FAULT_ADDR   0x%08X\n",
636657e252bfSMichael Neumann 				addr);
6367926deccbSFrançois Tigeot 			dev_err(rdev->dev, "  VM_CONTEXT1_PROTECTION_FAULT_STATUS 0x%08X\n",
636857e252bfSMichael Neumann 				status);
636957e252bfSMichael Neumann 			si_vm_decode_fault(rdev, status, addr);
6370926deccbSFrançois Tigeot 			break;
6371926deccbSFrançois Tigeot 		case 176: /* RINGID0 CP_INT */
6372926deccbSFrançois Tigeot 			radeon_fence_process(rdev, RADEON_RING_TYPE_GFX_INDEX);
6373926deccbSFrançois Tigeot 			break;
6374926deccbSFrançois Tigeot 		case 177: /* RINGID1 CP_INT */
6375926deccbSFrançois Tigeot 			radeon_fence_process(rdev, CAYMAN_RING_TYPE_CP1_INDEX);
6376926deccbSFrançois Tigeot 			break;
6377926deccbSFrançois Tigeot 		case 178: /* RINGID2 CP_INT */
6378926deccbSFrançois Tigeot 			radeon_fence_process(rdev, CAYMAN_RING_TYPE_CP2_INDEX);
6379926deccbSFrançois Tigeot 			break;
6380926deccbSFrançois Tigeot 		case 181: /* CP EOP event */
6381926deccbSFrançois Tigeot 			DRM_DEBUG("IH: CP EOP\n");
6382926deccbSFrançois Tigeot 			switch (ring_id) {
6383926deccbSFrançois Tigeot 			case 0:
6384926deccbSFrançois Tigeot 				radeon_fence_process(rdev, RADEON_RING_TYPE_GFX_INDEX);
6385926deccbSFrançois Tigeot 				break;
6386926deccbSFrançois Tigeot 			case 1:
6387926deccbSFrançois Tigeot 				radeon_fence_process(rdev, CAYMAN_RING_TYPE_CP1_INDEX);
6388926deccbSFrançois Tigeot 				break;
6389926deccbSFrançois Tigeot 			case 2:
6390926deccbSFrançois Tigeot 				radeon_fence_process(rdev, CAYMAN_RING_TYPE_CP2_INDEX);
6391926deccbSFrançois Tigeot 				break;
6392926deccbSFrançois Tigeot 			}
6393926deccbSFrançois Tigeot 			break;
6394926deccbSFrançois Tigeot 		case 224: /* DMA trap event */
6395926deccbSFrançois Tigeot 			DRM_DEBUG("IH: DMA trap\n");
6396926deccbSFrançois Tigeot 			radeon_fence_process(rdev, R600_RING_TYPE_DMA_INDEX);
6397926deccbSFrançois Tigeot 			break;
639857e252bfSMichael Neumann 		case 230: /* thermal low to high */
639957e252bfSMichael Neumann 			DRM_DEBUG("IH: thermal low to high\n");
640057e252bfSMichael Neumann 			rdev->pm.dpm.thermal.high_to_low = false;
640157e252bfSMichael Neumann 			queue_thermal = true;
640257e252bfSMichael Neumann 			break;
640357e252bfSMichael Neumann 		case 231: /* thermal high to low */
640457e252bfSMichael Neumann 			DRM_DEBUG("IH: thermal high to low\n");
640557e252bfSMichael Neumann 			rdev->pm.dpm.thermal.high_to_low = true;
640657e252bfSMichael Neumann 			queue_thermal = true;
640757e252bfSMichael Neumann 			break;
6408926deccbSFrançois Tigeot 		case 233: /* GUI IDLE */
6409926deccbSFrançois Tigeot 			DRM_DEBUG("IH: GUI idle\n");
6410926deccbSFrançois Tigeot 			break;
6411926deccbSFrançois Tigeot 		case 244: /* DMA trap event */
6412926deccbSFrançois Tigeot 			DRM_DEBUG("IH: DMA1 trap\n");
6413926deccbSFrançois Tigeot 			radeon_fence_process(rdev, CAYMAN_RING_TYPE_DMA1_INDEX);
6414926deccbSFrançois Tigeot 			break;
6415926deccbSFrançois Tigeot 		default:
6416926deccbSFrançois Tigeot 			DRM_DEBUG("Unhandled interrupt: %d %d\n", src_id, src_data);
6417926deccbSFrançois Tigeot 			break;
6418926deccbSFrançois Tigeot 		}
6419926deccbSFrançois Tigeot 
6420926deccbSFrançois Tigeot 		/* wptr/rptr are in bytes! */
6421926deccbSFrançois Tigeot 		rptr += 16;
6422926deccbSFrançois Tigeot 		rptr &= rdev->ih.ptr_mask;
6423c6f73aabSFrançois Tigeot 		WREG32(IH_RB_RPTR, rptr);
6424926deccbSFrançois Tigeot 	}
6425c59a5c48SFrançois Tigeot 	if (queue_dp)
6426c59a5c48SFrançois Tigeot 		schedule_work(&rdev->dp_work);
6427926deccbSFrançois Tigeot 	if (queue_hotplug)
6428c59a5c48SFrançois Tigeot 		schedule_delayed_work(&rdev->hotplug_work, 0);
642957e252bfSMichael Neumann 	if (queue_thermal && rdev->pm.dpm_enabled)
64302c5cc6b9SFrançois Tigeot 		schedule_work(&rdev->pm.dpm.thermal.work);
6431926deccbSFrançois Tigeot 	rdev->ih.rptr = rptr;
6432926deccbSFrançois Tigeot 	atomic_set(&rdev->ih.lock, 0);
6433926deccbSFrançois Tigeot 
6434926deccbSFrançois Tigeot 	/* make sure wptr hasn't changed while processing */
6435926deccbSFrançois Tigeot 	wptr = si_get_ih_wptr(rdev);
6436926deccbSFrançois Tigeot 	if (wptr != rptr)
6437926deccbSFrançois Tigeot 		goto restart_ih;
6438926deccbSFrançois Tigeot 
6439926deccbSFrançois Tigeot 	return IRQ_HANDLED;
6440926deccbSFrançois Tigeot }
6441926deccbSFrançois Tigeot 
6442926deccbSFrançois Tigeot /*
6443926deccbSFrançois Tigeot  * startup/shutdown callbacks
6444926deccbSFrançois Tigeot  */
si_uvd_init(struct radeon_device * rdev)6445d78d3a22SFrançois Tigeot static void si_uvd_init(struct radeon_device *rdev)
6446d78d3a22SFrançois Tigeot {
6447d78d3a22SFrançois Tigeot 	int r;
6448d78d3a22SFrançois Tigeot 
6449d78d3a22SFrançois Tigeot 	if (!rdev->has_uvd)
6450d78d3a22SFrançois Tigeot 		return;
6451d78d3a22SFrançois Tigeot 
6452d78d3a22SFrançois Tigeot 	r = radeon_uvd_init(rdev);
6453d78d3a22SFrançois Tigeot 	if (r) {
6454d78d3a22SFrançois Tigeot 		dev_err(rdev->dev, "failed UVD (%d) init.\n", r);
6455d78d3a22SFrançois Tigeot 		/*
6456d78d3a22SFrançois Tigeot 		 * At this point rdev->uvd.vcpu_bo is NULL which trickles down
6457d78d3a22SFrançois Tigeot 		 * to early fails uvd_v2_2_resume() and thus nothing happens
6458d78d3a22SFrançois Tigeot 		 * there. So it is pointless to try to go through that code
6459d78d3a22SFrançois Tigeot 		 * hence why we disable uvd here.
6460d78d3a22SFrançois Tigeot 		 */
6461d78d3a22SFrançois Tigeot 		rdev->has_uvd = 0;
6462d78d3a22SFrançois Tigeot 		return;
6463d78d3a22SFrançois Tigeot 	}
6464d78d3a22SFrançois Tigeot 	rdev->ring[R600_RING_TYPE_UVD_INDEX].ring_obj = NULL;
6465d78d3a22SFrançois Tigeot 	r600_ring_init(rdev, &rdev->ring[R600_RING_TYPE_UVD_INDEX], 4096);
6466d78d3a22SFrançois Tigeot }
6467d78d3a22SFrançois Tigeot 
si_uvd_start(struct radeon_device * rdev)6468d78d3a22SFrançois Tigeot static void si_uvd_start(struct radeon_device *rdev)
6469d78d3a22SFrançois Tigeot {
6470d78d3a22SFrançois Tigeot 	int r;
6471d78d3a22SFrançois Tigeot 
6472d78d3a22SFrançois Tigeot 	if (!rdev->has_uvd)
6473d78d3a22SFrançois Tigeot 		return;
6474d78d3a22SFrançois Tigeot 
6475d78d3a22SFrançois Tigeot 	r = uvd_v2_2_resume(rdev);
6476d78d3a22SFrançois Tigeot 	if (r) {
6477d78d3a22SFrançois Tigeot 		dev_err(rdev->dev, "failed UVD resume (%d).\n", r);
6478d78d3a22SFrançois Tigeot 		goto error;
6479d78d3a22SFrançois Tigeot 	}
6480d78d3a22SFrançois Tigeot 	r = radeon_fence_driver_start_ring(rdev, R600_RING_TYPE_UVD_INDEX);
6481d78d3a22SFrançois Tigeot 	if (r) {
6482d78d3a22SFrançois Tigeot 		dev_err(rdev->dev, "failed initializing UVD fences (%d).\n", r);
6483d78d3a22SFrançois Tigeot 		goto error;
6484d78d3a22SFrançois Tigeot 	}
6485d78d3a22SFrançois Tigeot 	return;
6486d78d3a22SFrançois Tigeot 
6487d78d3a22SFrançois Tigeot error:
6488d78d3a22SFrançois Tigeot 	rdev->ring[R600_RING_TYPE_UVD_INDEX].ring_size = 0;
6489d78d3a22SFrançois Tigeot }
6490d78d3a22SFrançois Tigeot 
si_uvd_resume(struct radeon_device * rdev)6491d78d3a22SFrançois Tigeot static void si_uvd_resume(struct radeon_device *rdev)
6492d78d3a22SFrançois Tigeot {
6493d78d3a22SFrançois Tigeot 	struct radeon_ring *ring;
6494d78d3a22SFrançois Tigeot 	int r;
6495d78d3a22SFrançois Tigeot 
6496d78d3a22SFrançois Tigeot 	if (!rdev->has_uvd || !rdev->ring[R600_RING_TYPE_UVD_INDEX].ring_size)
6497d78d3a22SFrançois Tigeot 		return;
6498d78d3a22SFrançois Tigeot 
6499d78d3a22SFrançois Tigeot 	ring = &rdev->ring[R600_RING_TYPE_UVD_INDEX];
65001dedbd3bSFrançois Tigeot 	r = radeon_ring_init(rdev, ring, ring->ring_size, 0, PACKET0(UVD_NO_OP, 0));
6501d78d3a22SFrançois Tigeot 	if (r) {
6502d78d3a22SFrançois Tigeot 		dev_err(rdev->dev, "failed initializing UVD ring (%d).\n", r);
6503d78d3a22SFrançois Tigeot 		return;
6504d78d3a22SFrançois Tigeot 	}
6505d78d3a22SFrançois Tigeot 	r = uvd_v1_0_init(rdev);
6506d78d3a22SFrançois Tigeot 	if (r) {
6507d78d3a22SFrançois Tigeot 		dev_err(rdev->dev, "failed initializing UVD (%d).\n", r);
6508d78d3a22SFrançois Tigeot 		return;
6509d78d3a22SFrançois Tigeot 	}
6510d78d3a22SFrançois Tigeot }
6511d78d3a22SFrançois Tigeot 
si_vce_init(struct radeon_device * rdev)6512d78d3a22SFrançois Tigeot static void si_vce_init(struct radeon_device *rdev)
6513d78d3a22SFrançois Tigeot {
6514d78d3a22SFrançois Tigeot 	int r;
6515d78d3a22SFrançois Tigeot 
6516d78d3a22SFrançois Tigeot 	if (!rdev->has_vce)
6517d78d3a22SFrançois Tigeot 		return;
6518d78d3a22SFrançois Tigeot 
6519d78d3a22SFrançois Tigeot 	r = radeon_vce_init(rdev);
6520d78d3a22SFrançois Tigeot 	if (r) {
6521d78d3a22SFrançois Tigeot 		dev_err(rdev->dev, "failed VCE (%d) init.\n", r);
6522d78d3a22SFrançois Tigeot 		/*
6523d78d3a22SFrançois Tigeot 		 * At this point rdev->vce.vcpu_bo is NULL which trickles down
6524d78d3a22SFrançois Tigeot 		 * to early fails si_vce_start() and thus nothing happens
6525d78d3a22SFrançois Tigeot 		 * there. So it is pointless to try to go through that code
6526d78d3a22SFrançois Tigeot 		 * hence why we disable vce here.
6527d78d3a22SFrançois Tigeot 		 */
6528d78d3a22SFrançois Tigeot 		rdev->has_vce = 0;
6529d78d3a22SFrançois Tigeot 		return;
6530d78d3a22SFrançois Tigeot 	}
6531d78d3a22SFrançois Tigeot 	rdev->ring[TN_RING_TYPE_VCE1_INDEX].ring_obj = NULL;
6532d78d3a22SFrançois Tigeot 	r600_ring_init(rdev, &rdev->ring[TN_RING_TYPE_VCE1_INDEX], 4096);
6533d78d3a22SFrançois Tigeot 	rdev->ring[TN_RING_TYPE_VCE2_INDEX].ring_obj = NULL;
6534d78d3a22SFrançois Tigeot 	r600_ring_init(rdev, &rdev->ring[TN_RING_TYPE_VCE2_INDEX], 4096);
6535d78d3a22SFrançois Tigeot }
6536d78d3a22SFrançois Tigeot 
si_vce_start(struct radeon_device * rdev)6537d78d3a22SFrançois Tigeot static void si_vce_start(struct radeon_device *rdev)
6538d78d3a22SFrançois Tigeot {
6539d78d3a22SFrançois Tigeot 	int r;
6540d78d3a22SFrançois Tigeot 
6541d78d3a22SFrançois Tigeot 	if (!rdev->has_vce)
6542d78d3a22SFrançois Tigeot 		return;
6543d78d3a22SFrançois Tigeot 
6544d78d3a22SFrançois Tigeot 	r = radeon_vce_resume(rdev);
6545d78d3a22SFrançois Tigeot 	if (r) {
6546d78d3a22SFrançois Tigeot 		dev_err(rdev->dev, "failed VCE resume (%d).\n", r);
6547d78d3a22SFrançois Tigeot 		goto error;
6548d78d3a22SFrançois Tigeot 	}
6549d78d3a22SFrançois Tigeot 	r = vce_v1_0_resume(rdev);
6550d78d3a22SFrançois Tigeot 	if (r) {
6551d78d3a22SFrançois Tigeot 		dev_err(rdev->dev, "failed VCE resume (%d).\n", r);
6552d78d3a22SFrançois Tigeot 		goto error;
6553d78d3a22SFrançois Tigeot 	}
6554d78d3a22SFrançois Tigeot 	r = radeon_fence_driver_start_ring(rdev, TN_RING_TYPE_VCE1_INDEX);
6555d78d3a22SFrançois Tigeot 	if (r) {
6556d78d3a22SFrançois Tigeot 		dev_err(rdev->dev, "failed initializing VCE1 fences (%d).\n", r);
6557d78d3a22SFrançois Tigeot 		goto error;
6558d78d3a22SFrançois Tigeot 	}
6559d78d3a22SFrançois Tigeot 	r = radeon_fence_driver_start_ring(rdev, TN_RING_TYPE_VCE2_INDEX);
6560d78d3a22SFrançois Tigeot 	if (r) {
6561d78d3a22SFrançois Tigeot 		dev_err(rdev->dev, "failed initializing VCE2 fences (%d).\n", r);
6562d78d3a22SFrançois Tigeot 		goto error;
6563d78d3a22SFrançois Tigeot 	}
6564d78d3a22SFrançois Tigeot 	return;
6565d78d3a22SFrançois Tigeot 
6566d78d3a22SFrançois Tigeot error:
6567d78d3a22SFrançois Tigeot 	rdev->ring[TN_RING_TYPE_VCE1_INDEX].ring_size = 0;
6568d78d3a22SFrançois Tigeot 	rdev->ring[TN_RING_TYPE_VCE2_INDEX].ring_size = 0;
6569d78d3a22SFrançois Tigeot }
6570d78d3a22SFrançois Tigeot 
si_vce_resume(struct radeon_device * rdev)6571d78d3a22SFrançois Tigeot static void si_vce_resume(struct radeon_device *rdev)
6572d78d3a22SFrançois Tigeot {
6573d78d3a22SFrançois Tigeot 	struct radeon_ring *ring;
6574d78d3a22SFrançois Tigeot 	int r;
6575d78d3a22SFrançois Tigeot 
6576d78d3a22SFrançois Tigeot 	if (!rdev->has_vce || !rdev->ring[TN_RING_TYPE_VCE1_INDEX].ring_size)
6577d78d3a22SFrançois Tigeot 		return;
6578d78d3a22SFrançois Tigeot 
6579d78d3a22SFrançois Tigeot 	ring = &rdev->ring[TN_RING_TYPE_VCE1_INDEX];
6580d78d3a22SFrançois Tigeot 	r = radeon_ring_init(rdev, ring, ring->ring_size, 0, VCE_CMD_NO_OP);
6581d78d3a22SFrançois Tigeot 	if (r) {
6582d78d3a22SFrançois Tigeot 		dev_err(rdev->dev, "failed initializing VCE1 ring (%d).\n", r);
6583d78d3a22SFrançois Tigeot 		return;
6584d78d3a22SFrançois Tigeot 	}
6585d78d3a22SFrançois Tigeot 	ring = &rdev->ring[TN_RING_TYPE_VCE2_INDEX];
6586d78d3a22SFrançois Tigeot 	r = radeon_ring_init(rdev, ring, ring->ring_size, 0, VCE_CMD_NO_OP);
6587d78d3a22SFrançois Tigeot 	if (r) {
6588d78d3a22SFrançois Tigeot 		dev_err(rdev->dev, "failed initializing VCE1 ring (%d).\n", r);
6589d78d3a22SFrançois Tigeot 		return;
6590d78d3a22SFrançois Tigeot 	}
6591d78d3a22SFrançois Tigeot 	r = vce_v1_0_init(rdev);
6592d78d3a22SFrançois Tigeot 	if (r) {
6593d78d3a22SFrançois Tigeot 		dev_err(rdev->dev, "failed initializing VCE (%d).\n", r);
6594d78d3a22SFrançois Tigeot 		return;
6595d78d3a22SFrançois Tigeot 	}
6596d78d3a22SFrançois Tigeot }
6597d78d3a22SFrançois Tigeot 
si_startup(struct radeon_device * rdev)6598926deccbSFrançois Tigeot static int si_startup(struct radeon_device *rdev)
6599926deccbSFrançois Tigeot {
6600926deccbSFrançois Tigeot 	struct radeon_ring *ring;
6601926deccbSFrançois Tigeot 	int r;
6602926deccbSFrançois Tigeot 
660357e252bfSMichael Neumann 	/* enable pcie gen2/3 link */
660457e252bfSMichael Neumann 	si_pcie_gen3_enable(rdev);
660557e252bfSMichael Neumann 	/* enable aspm */
660657e252bfSMichael Neumann 	si_program_aspm(rdev);
660757e252bfSMichael Neumann 
66084cd92098Szrj 	/* scratch needs to be initialized before MC */
66094cd92098Szrj 	r = r600_vram_scratch_init(rdev);
66104cd92098Szrj 	if (r)
66114cd92098Szrj 		return r;
66124cd92098Szrj 
661357e252bfSMichael Neumann 	si_mc_program(rdev);
661457e252bfSMichael Neumann 
6615c6f73aabSFrançois Tigeot 	if (!rdev->pm.dpm_enabled) {
6616926deccbSFrançois Tigeot 		r = si_mc_load_microcode(rdev);
6617926deccbSFrançois Tigeot 		if (r) {
6618926deccbSFrançois Tigeot 			DRM_ERROR("Failed to load MC firmware!\n");
6619926deccbSFrançois Tigeot 			return r;
6620926deccbSFrançois Tigeot 		}
6621c6f73aabSFrançois Tigeot 	}
6622926deccbSFrançois Tigeot 
6623926deccbSFrançois Tigeot 	r = si_pcie_gart_enable(rdev);
6624926deccbSFrançois Tigeot 	if (r)
6625926deccbSFrançois Tigeot 		return r;
6626926deccbSFrançois Tigeot 	si_gpu_init(rdev);
6627926deccbSFrançois Tigeot 
6628926deccbSFrançois Tigeot 	/* allocate rlc buffers */
66294cd92098Szrj 	if (rdev->family == CHIP_VERDE) {
66304cd92098Szrj 		rdev->rlc.reg_list = verde_rlc_save_restore_register_list;
66314cd92098Szrj 		rdev->rlc.reg_list_size =
66324cd92098Szrj 			(u32)ARRAY_SIZE(verde_rlc_save_restore_register_list);
66334cd92098Szrj 	}
66344cd92098Szrj 	rdev->rlc.cs_data = si_cs_data;
66354cd92098Szrj 	r = sumo_rlc_init(rdev);
6636926deccbSFrançois Tigeot 	if (r) {
6637926deccbSFrançois Tigeot 		DRM_ERROR("Failed to init rlc BOs!\n");
6638926deccbSFrançois Tigeot 		return r;
6639926deccbSFrançois Tigeot 	}
6640926deccbSFrançois Tigeot 
6641926deccbSFrançois Tigeot 	/* allocate wb buffer */
6642926deccbSFrançois Tigeot 	r = radeon_wb_init(rdev);
6643926deccbSFrançois Tigeot 	if (r)
6644926deccbSFrançois Tigeot 		return r;
6645926deccbSFrançois Tigeot 
6646926deccbSFrançois Tigeot 	r = radeon_fence_driver_start_ring(rdev, RADEON_RING_TYPE_GFX_INDEX);
6647926deccbSFrançois Tigeot 	if (r) {
6648926deccbSFrançois Tigeot 		dev_err(rdev->dev, "failed initializing CP fences (%d).\n", r);
6649926deccbSFrançois Tigeot 		return r;
6650926deccbSFrançois Tigeot 	}
6651926deccbSFrançois Tigeot 
6652926deccbSFrançois Tigeot 	r = radeon_fence_driver_start_ring(rdev, CAYMAN_RING_TYPE_CP1_INDEX);
6653926deccbSFrançois Tigeot 	if (r) {
6654926deccbSFrançois Tigeot 		dev_err(rdev->dev, "failed initializing CP fences (%d).\n", r);
6655926deccbSFrançois Tigeot 		return r;
6656926deccbSFrançois Tigeot 	}
6657926deccbSFrançois Tigeot 
6658926deccbSFrançois Tigeot 	r = radeon_fence_driver_start_ring(rdev, CAYMAN_RING_TYPE_CP2_INDEX);
6659926deccbSFrançois Tigeot 	if (r) {
6660926deccbSFrançois Tigeot 		dev_err(rdev->dev, "failed initializing CP fences (%d).\n", r);
6661926deccbSFrançois Tigeot 		return r;
6662926deccbSFrançois Tigeot 	}
6663926deccbSFrançois Tigeot 
6664926deccbSFrançois Tigeot 	r = radeon_fence_driver_start_ring(rdev, R600_RING_TYPE_DMA_INDEX);
6665926deccbSFrançois Tigeot 	if (r) {
6666926deccbSFrançois Tigeot 		dev_err(rdev->dev, "failed initializing DMA fences (%d).\n", r);
6667926deccbSFrançois Tigeot 		return r;
6668926deccbSFrançois Tigeot 	}
6669926deccbSFrançois Tigeot 
6670926deccbSFrançois Tigeot 	r = radeon_fence_driver_start_ring(rdev, CAYMAN_RING_TYPE_DMA1_INDEX);
6671926deccbSFrançois Tigeot 	if (r) {
6672926deccbSFrançois Tigeot 		dev_err(rdev->dev, "failed initializing DMA fences (%d).\n", r);
6673926deccbSFrançois Tigeot 		return r;
6674926deccbSFrançois Tigeot 	}
6675926deccbSFrançois Tigeot 
6676d78d3a22SFrançois Tigeot 	si_uvd_start(rdev);
6677d78d3a22SFrançois Tigeot 	si_vce_start(rdev);
6678c59a5c48SFrançois Tigeot 
6679926deccbSFrançois Tigeot 	/* Enable IRQ */
6680f43cf1b1SMichael Neumann 	if (!rdev->irq.installed) {
6681f43cf1b1SMichael Neumann 		r = radeon_irq_kms_init(rdev);
6682f43cf1b1SMichael Neumann 		if (r)
6683f43cf1b1SMichael Neumann 			return r;
6684f43cf1b1SMichael Neumann 	}
6685f43cf1b1SMichael Neumann 
6686926deccbSFrançois Tigeot 	r = si_irq_init(rdev);
6687926deccbSFrançois Tigeot 	if (r) {
6688926deccbSFrançois Tigeot 		DRM_ERROR("radeon: IH init failed (%d).\n", r);
6689926deccbSFrançois Tigeot 		radeon_irq_kms_fini(rdev);
6690926deccbSFrançois Tigeot 		return r;
6691926deccbSFrançois Tigeot 	}
6692926deccbSFrançois Tigeot 	si_irq_set(rdev);
6693926deccbSFrançois Tigeot 
6694926deccbSFrançois Tigeot 	ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX];
6695926deccbSFrançois Tigeot 	r = radeon_ring_init(rdev, ring, ring->ring_size, RADEON_WB_CP_RPTR_OFFSET,
66964cd92098Szrj 			     RADEON_CP_PACKET2);
6697926deccbSFrançois Tigeot 	if (r)
6698926deccbSFrançois Tigeot 		return r;
6699926deccbSFrançois Tigeot 
6700926deccbSFrançois Tigeot 	ring = &rdev->ring[CAYMAN_RING_TYPE_CP1_INDEX];
6701926deccbSFrançois Tigeot 	r = radeon_ring_init(rdev, ring, ring->ring_size, RADEON_WB_CP1_RPTR_OFFSET,
67024cd92098Szrj 			     RADEON_CP_PACKET2);
6703926deccbSFrançois Tigeot 	if (r)
6704926deccbSFrançois Tigeot 		return r;
6705926deccbSFrançois Tigeot 
6706926deccbSFrançois Tigeot 	ring = &rdev->ring[CAYMAN_RING_TYPE_CP2_INDEX];
6707926deccbSFrançois Tigeot 	r = radeon_ring_init(rdev, ring, ring->ring_size, RADEON_WB_CP2_RPTR_OFFSET,
67084cd92098Szrj 			     RADEON_CP_PACKET2);
6709926deccbSFrançois Tigeot 	if (r)
6710926deccbSFrançois Tigeot 		return r;
6711926deccbSFrançois Tigeot 
6712926deccbSFrançois Tigeot 	ring = &rdev->ring[R600_RING_TYPE_DMA_INDEX];
6713926deccbSFrançois Tigeot 	r = radeon_ring_init(rdev, ring, ring->ring_size, R600_WB_DMA_RPTR_OFFSET,
67144cd92098Szrj 			     DMA_PACKET(DMA_PACKET_NOP, 0, 0, 0, 0));
6715926deccbSFrançois Tigeot 	if (r)
6716926deccbSFrançois Tigeot 		return r;
6717926deccbSFrançois Tigeot 
6718926deccbSFrançois Tigeot 	ring = &rdev->ring[CAYMAN_RING_TYPE_DMA1_INDEX];
6719926deccbSFrançois Tigeot 	r = radeon_ring_init(rdev, ring, ring->ring_size, CAYMAN_WB_DMA1_RPTR_OFFSET,
67204cd92098Szrj 			     DMA_PACKET(DMA_PACKET_NOP, 0, 0, 0, 0));
6721926deccbSFrançois Tigeot 	if (r)
6722926deccbSFrançois Tigeot 		return r;
6723926deccbSFrançois Tigeot 
6724926deccbSFrançois Tigeot 	r = si_cp_load_microcode(rdev);
6725926deccbSFrançois Tigeot 	if (r)
6726926deccbSFrançois Tigeot 		return r;
6727926deccbSFrançois Tigeot 	r = si_cp_resume(rdev);
6728926deccbSFrançois Tigeot 	if (r)
6729926deccbSFrançois Tigeot 		return r;
6730926deccbSFrançois Tigeot 
6731926deccbSFrançois Tigeot 	r = cayman_dma_resume(rdev);
6732926deccbSFrançois Tigeot 	if (r)
6733926deccbSFrançois Tigeot 		return r;
6734926deccbSFrançois Tigeot 
6735d78d3a22SFrançois Tigeot 	si_uvd_resume(rdev);
6736d78d3a22SFrançois Tigeot 	si_vce_resume(rdev);
6737c59a5c48SFrançois Tigeot 
6738926deccbSFrançois Tigeot 	r = radeon_ib_pool_init(rdev);
6739926deccbSFrançois Tigeot 	if (r) {
6740926deccbSFrançois Tigeot 		dev_err(rdev->dev, "IB initialization failed (%d).\n", r);
6741926deccbSFrançois Tigeot 		return r;
6742926deccbSFrançois Tigeot 	}
6743926deccbSFrançois Tigeot 
6744926deccbSFrançois Tigeot 	r = radeon_vm_manager_init(rdev);
6745926deccbSFrançois Tigeot 	if (r) {
6746926deccbSFrançois Tigeot 		dev_err(rdev->dev, "vm manager initialization failed (%d).\n", r);
6747926deccbSFrançois Tigeot 		return r;
6748926deccbSFrançois Tigeot 	}
6749926deccbSFrançois Tigeot 
6750c59a5c48SFrançois Tigeot 	r = radeon_audio_init(rdev);
67514cd92098Szrj 	if (r)
67524cd92098Szrj 		return r;
67534cd92098Szrj 
6754926deccbSFrançois Tigeot 	return 0;
6755926deccbSFrançois Tigeot }
6756926deccbSFrançois Tigeot 
si_resume(struct radeon_device * rdev)6757926deccbSFrançois Tigeot int si_resume(struct radeon_device *rdev)
6758926deccbSFrançois Tigeot {
6759926deccbSFrançois Tigeot 	int r;
6760926deccbSFrançois Tigeot 
6761926deccbSFrançois Tigeot 	/* Do not reset GPU before posting, on rv770 hw unlike on r500 hw,
6762926deccbSFrançois Tigeot 	 * posting will perform necessary task to bring back GPU into good
6763926deccbSFrançois Tigeot 	 * shape.
6764926deccbSFrançois Tigeot 	 */
6765926deccbSFrançois Tigeot 	/* post card */
6766926deccbSFrançois Tigeot 	atom_asic_init(rdev->mode_info.atom_context);
6767926deccbSFrançois Tigeot 
6768f43cf1b1SMichael Neumann 	/* init golden registers */
6769f43cf1b1SMichael Neumann 	si_init_golden_registers(rdev);
6770f43cf1b1SMichael Neumann 
6771c6f73aabSFrançois Tigeot 	if (rdev->pm.pm_method == PM_METHOD_DPM)
6772c6f73aabSFrançois Tigeot 		radeon_pm_resume(rdev);
6773c6f73aabSFrançois Tigeot 
6774926deccbSFrançois Tigeot 	rdev->accel_working = true;
6775926deccbSFrançois Tigeot 	r = si_startup(rdev);
6776926deccbSFrançois Tigeot 	if (r) {
6777926deccbSFrançois Tigeot 		DRM_ERROR("si startup failed on resume\n");
6778926deccbSFrançois Tigeot 		rdev->accel_working = false;
6779926deccbSFrançois Tigeot 		return r;
6780926deccbSFrançois Tigeot 	}
6781926deccbSFrançois Tigeot 
6782926deccbSFrançois Tigeot 	return r;
6783926deccbSFrançois Tigeot 
6784926deccbSFrançois Tigeot }
6785926deccbSFrançois Tigeot 
si_suspend(struct radeon_device * rdev)6786926deccbSFrançois Tigeot int si_suspend(struct radeon_device *rdev)
6787926deccbSFrançois Tigeot {
6788c6f73aabSFrançois Tigeot 	radeon_pm_suspend(rdev);
6789c59a5c48SFrançois Tigeot 	radeon_audio_fini(rdev);
6790b403bed8SMichael Neumann 	radeon_vm_manager_fini(rdev);
6791926deccbSFrançois Tigeot 	si_cp_enable(rdev, false);
6792926deccbSFrançois Tigeot 	cayman_dma_stop(rdev);
6793f43cf1b1SMichael Neumann 	if (rdev->has_uvd) {
67944cd92098Szrj 		uvd_v1_0_fini(rdev);
6795f43cf1b1SMichael Neumann 		radeon_uvd_suspend(rdev);
6796f43cf1b1SMichael Neumann 	}
6797d78d3a22SFrançois Tigeot 	if (rdev->has_vce)
6798d78d3a22SFrançois Tigeot 		radeon_vce_suspend(rdev);
67994cd92098Szrj 	si_fini_pg(rdev);
68004cd92098Szrj 	si_fini_cg(rdev);
6801926deccbSFrançois Tigeot 	si_irq_suspend(rdev);
6802926deccbSFrançois Tigeot 	radeon_wb_disable(rdev);
6803926deccbSFrançois Tigeot 	si_pcie_gart_disable(rdev);
6804926deccbSFrançois Tigeot 	return 0;
6805926deccbSFrançois Tigeot }
6806926deccbSFrançois Tigeot 
6807926deccbSFrançois Tigeot /* Plan is to move initialization in that function and use
6808926deccbSFrançois Tigeot  * helper function so that radeon_device_init pretty much
6809926deccbSFrançois Tigeot  * do nothing more than calling asic specific function. This
6810926deccbSFrançois Tigeot  * should also allow to remove a bunch of callback function
6811926deccbSFrançois Tigeot  * like vram_info.
6812926deccbSFrançois Tigeot  */
si_init(struct radeon_device * rdev)6813926deccbSFrançois Tigeot int si_init(struct radeon_device *rdev)
6814926deccbSFrançois Tigeot {
6815926deccbSFrançois Tigeot 	struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX];
6816926deccbSFrançois Tigeot 	int r;
6817926deccbSFrançois Tigeot 
6818926deccbSFrançois Tigeot 	/* Read BIOS */
6819926deccbSFrançois Tigeot 	if (!radeon_get_bios(rdev)) {
6820926deccbSFrançois Tigeot 		if (ASIC_IS_AVIVO(rdev))
6821926deccbSFrançois Tigeot 			return -EINVAL;
6822926deccbSFrançois Tigeot 	}
6823926deccbSFrançois Tigeot 	/* Must be an ATOMBIOS */
6824926deccbSFrançois Tigeot 	if (!rdev->is_atom_bios) {
6825926deccbSFrançois Tigeot 		dev_err(rdev->dev, "Expecting atombios for cayman GPU\n");
6826926deccbSFrançois Tigeot 		return -EINVAL;
6827926deccbSFrançois Tigeot 	}
6828926deccbSFrançois Tigeot 	r = radeon_atombios_init(rdev);
6829926deccbSFrançois Tigeot 	if (r)
6830926deccbSFrançois Tigeot 		return r;
6831926deccbSFrançois Tigeot 
6832926deccbSFrançois Tigeot 	/* Post card if necessary */
6833926deccbSFrançois Tigeot 	if (!radeon_card_posted(rdev)) {
6834926deccbSFrançois Tigeot 		if (!rdev->bios) {
6835926deccbSFrançois Tigeot 			dev_err(rdev->dev, "Card not posted and no BIOS - ignoring\n");
6836926deccbSFrançois Tigeot 			return -EINVAL;
6837926deccbSFrançois Tigeot 		}
6838926deccbSFrançois Tigeot 		DRM_INFO("GPU not posted. posting now...\n");
6839926deccbSFrançois Tigeot 		atom_asic_init(rdev->mode_info.atom_context);
6840926deccbSFrançois Tigeot 	}
6841f43cf1b1SMichael Neumann 	/* init golden registers */
6842f43cf1b1SMichael Neumann 	si_init_golden_registers(rdev);
6843926deccbSFrançois Tigeot 	/* Initialize scratch registers */
6844926deccbSFrançois Tigeot 	si_scratch_init(rdev);
6845926deccbSFrançois Tigeot 	/* Initialize surface registers */
6846926deccbSFrançois Tigeot 	radeon_surface_init(rdev);
6847926deccbSFrançois Tigeot 	/* Initialize clocks */
6848926deccbSFrançois Tigeot 	radeon_get_clock_info(rdev->ddev);
6849926deccbSFrançois Tigeot 
6850926deccbSFrançois Tigeot 	/* Fence driver */
6851926deccbSFrançois Tigeot 	r = radeon_fence_driver_init(rdev);
6852926deccbSFrançois Tigeot 	if (r)
6853926deccbSFrançois Tigeot 		return r;
6854926deccbSFrançois Tigeot 
6855926deccbSFrançois Tigeot 	/* initialize memory controller */
6856926deccbSFrançois Tigeot 	r = si_mc_init(rdev);
6857926deccbSFrançois Tigeot 	if (r)
6858926deccbSFrançois Tigeot 		return r;
6859926deccbSFrançois Tigeot 	/* Memory manager */
6860926deccbSFrançois Tigeot 	r = radeon_bo_init(rdev);
6861926deccbSFrançois Tigeot 	if (r)
6862926deccbSFrançois Tigeot 		return r;
6863926deccbSFrançois Tigeot 
6864c6f73aabSFrançois Tigeot 	if (!rdev->me_fw || !rdev->pfp_fw || !rdev->ce_fw ||
6865c6f73aabSFrançois Tigeot 	    !rdev->rlc_fw || !rdev->mc_fw) {
6866c6f73aabSFrançois Tigeot 		r = si_init_microcode(rdev);
6867c6f73aabSFrançois Tigeot 		if (r) {
6868c6f73aabSFrançois Tigeot 			DRM_ERROR("Failed to load firmware!\n");
6869c6f73aabSFrançois Tigeot 			return r;
6870c6f73aabSFrançois Tigeot 		}
6871c6f73aabSFrançois Tigeot 	}
6872c6f73aabSFrançois Tigeot 
6873c6f73aabSFrançois Tigeot 	/* Initialize power management */
6874c6f73aabSFrançois Tigeot 	radeon_pm_init(rdev);
6875c6f73aabSFrançois Tigeot 
6876926deccbSFrançois Tigeot 	ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX];
6877926deccbSFrançois Tigeot 	ring->ring_obj = NULL;
6878926deccbSFrançois Tigeot 	r600_ring_init(rdev, ring, 1024 * 1024);
6879926deccbSFrançois Tigeot 
6880926deccbSFrançois Tigeot 	ring = &rdev->ring[CAYMAN_RING_TYPE_CP1_INDEX];
6881926deccbSFrançois Tigeot 	ring->ring_obj = NULL;
6882926deccbSFrançois Tigeot 	r600_ring_init(rdev, ring, 1024 * 1024);
6883926deccbSFrançois Tigeot 
6884926deccbSFrançois Tigeot 	ring = &rdev->ring[CAYMAN_RING_TYPE_CP2_INDEX];
6885926deccbSFrançois Tigeot 	ring->ring_obj = NULL;
6886926deccbSFrançois Tigeot 	r600_ring_init(rdev, ring, 1024 * 1024);
6887926deccbSFrançois Tigeot 
6888926deccbSFrançois Tigeot 	ring = &rdev->ring[R600_RING_TYPE_DMA_INDEX];
6889926deccbSFrançois Tigeot 	ring->ring_obj = NULL;
6890926deccbSFrançois Tigeot 	r600_ring_init(rdev, ring, 64 * 1024);
6891926deccbSFrançois Tigeot 
6892926deccbSFrançois Tigeot 	ring = &rdev->ring[CAYMAN_RING_TYPE_DMA1_INDEX];
6893926deccbSFrançois Tigeot 	ring->ring_obj = NULL;
6894926deccbSFrançois Tigeot 	r600_ring_init(rdev, ring, 64 * 1024);
6895926deccbSFrançois Tigeot 
6896d78d3a22SFrançois Tigeot 	si_uvd_init(rdev);
6897d78d3a22SFrançois Tigeot 	si_vce_init(rdev);
6898c59a5c48SFrançois Tigeot 
6899926deccbSFrançois Tigeot 	rdev->ih.ring_obj = NULL;
6900926deccbSFrançois Tigeot 	r600_ih_ring_init(rdev, 64 * 1024);
6901926deccbSFrançois Tigeot 
6902926deccbSFrançois Tigeot 	r = r600_pcie_gart_init(rdev);
6903926deccbSFrançois Tigeot 	if (r)
6904926deccbSFrançois Tigeot 		return r;
6905926deccbSFrançois Tigeot 
6906e8de9e94SFrançois Tigeot #ifdef __DragonFly__
6907e8de9e94SFrançois Tigeot 	/*
6908e8de9e94SFrançois Tigeot 	   Some glx operations (xfce 4.14) hang on si hardware,
6909e8de9e94SFrançois Tigeot 	   tell userland acceleration is not working properly
6910e8de9e94SFrançois Tigeot 	*/
6911e8de9e94SFrançois Tigeot 	rdev->accel_working = false;
6912e6084b74SFrançois Tigeot 	DRM_ERROR("GPU acceleration disabled for now on DragonFly\n");
6913e8de9e94SFrançois Tigeot #else
6914926deccbSFrançois Tigeot 	rdev->accel_working = true;
6915e8de9e94SFrançois Tigeot #endif
6916926deccbSFrançois Tigeot 	r = si_startup(rdev);
6917926deccbSFrançois Tigeot 	if (r) {
6918926deccbSFrançois Tigeot 		dev_err(rdev->dev, "disabling GPU acceleration\n");
6919926deccbSFrançois Tigeot 		si_cp_fini(rdev);
6920926deccbSFrançois Tigeot 		cayman_dma_fini(rdev);
6921926deccbSFrançois Tigeot 		si_irq_fini(rdev);
69224cd92098Szrj 		sumo_rlc_fini(rdev);
6923926deccbSFrançois Tigeot 		radeon_wb_fini(rdev);
6924926deccbSFrançois Tigeot 		radeon_ib_pool_fini(rdev);
6925926deccbSFrançois Tigeot 		radeon_vm_manager_fini(rdev);
6926926deccbSFrançois Tigeot 		radeon_irq_kms_fini(rdev);
6927926deccbSFrançois Tigeot 		si_pcie_gart_fini(rdev);
6928926deccbSFrançois Tigeot 		rdev->accel_working = false;
6929926deccbSFrançois Tigeot 	}
6930926deccbSFrançois Tigeot 
6931926deccbSFrançois Tigeot 	/* Don't start up if the MC ucode is missing.
6932926deccbSFrançois Tigeot 	 * The default clocks and voltages before the MC ucode
6933926deccbSFrançois Tigeot 	 * is loaded are not suffient for advanced operations.
6934926deccbSFrançois Tigeot 	 */
6935926deccbSFrançois Tigeot 	if (!rdev->mc_fw) {
6936926deccbSFrançois Tigeot 		DRM_ERROR("radeon: MC ucode required for NI+.\n");
6937926deccbSFrançois Tigeot 		return -EINVAL;
6938926deccbSFrançois Tigeot 	}
6939926deccbSFrançois Tigeot 
6940926deccbSFrançois Tigeot 	return 0;
6941926deccbSFrançois Tigeot }
6942926deccbSFrançois Tigeot 
si_fini(struct radeon_device * rdev)6943926deccbSFrançois Tigeot void si_fini(struct radeon_device *rdev)
6944926deccbSFrançois Tigeot {
6945c6f73aabSFrançois Tigeot 	radeon_pm_fini(rdev);
6946926deccbSFrançois Tigeot 	si_cp_fini(rdev);
6947926deccbSFrançois Tigeot 	cayman_dma_fini(rdev);
694857e252bfSMichael Neumann 	si_fini_pg(rdev);
69494cd92098Szrj 	si_fini_cg(rdev);
69504cd92098Szrj 	si_irq_fini(rdev);
69514cd92098Szrj 	sumo_rlc_fini(rdev);
6952926deccbSFrançois Tigeot 	radeon_wb_fini(rdev);
6953926deccbSFrançois Tigeot 	radeon_vm_manager_fini(rdev);
6954926deccbSFrançois Tigeot 	radeon_ib_pool_fini(rdev);
6955926deccbSFrançois Tigeot 	radeon_irq_kms_fini(rdev);
695657e252bfSMichael Neumann 	if (rdev->has_uvd) {
69574cd92098Szrj 		uvd_v1_0_fini(rdev);
6958f43cf1b1SMichael Neumann 		radeon_uvd_fini(rdev);
695957e252bfSMichael Neumann 	}
6960d78d3a22SFrançois Tigeot 	if (rdev->has_vce)
6961d78d3a22SFrançois Tigeot 		radeon_vce_fini(rdev);
6962926deccbSFrançois Tigeot 	si_pcie_gart_fini(rdev);
6963926deccbSFrançois Tigeot 	r600_vram_scratch_fini(rdev);
6964926deccbSFrançois Tigeot 	radeon_gem_fini(rdev);
6965926deccbSFrançois Tigeot 	radeon_fence_driver_fini(rdev);
6966926deccbSFrançois Tigeot 	radeon_bo_fini(rdev);
6967926deccbSFrançois Tigeot 	radeon_atombios_fini(rdev);
6968c4ef309bSzrj 	kfree(rdev->bios);
6969926deccbSFrançois Tigeot 	rdev->bios = NULL;
6970926deccbSFrançois Tigeot }
6971926deccbSFrançois Tigeot 
6972926deccbSFrançois Tigeot /**
6973b403bed8SMichael Neumann  * si_get_gpu_clock_counter - return GPU clock counter snapshot
6974926deccbSFrançois Tigeot  *
6975926deccbSFrançois Tigeot  * @rdev: radeon_device pointer
6976926deccbSFrançois Tigeot  *
6977926deccbSFrançois Tigeot  * Fetches a GPU clock counter snapshot (SI).
6978926deccbSFrançois Tigeot  * Returns the 64 bit clock counter snapshot.
6979926deccbSFrançois Tigeot  */
si_get_gpu_clock_counter(struct radeon_device * rdev)6980b403bed8SMichael Neumann uint64_t si_get_gpu_clock_counter(struct radeon_device *rdev)
6981926deccbSFrançois Tigeot {
6982926deccbSFrançois Tigeot 	uint64_t clock;
6983926deccbSFrançois Tigeot 
6984fefad7a7SFrançois Tigeot 	mutex_lock(&rdev->gpu_clock_mutex);
6985926deccbSFrançois Tigeot 	WREG32(RLC_CAPTURE_GPU_CLOCK_COUNT, 1);
6986926deccbSFrançois Tigeot 	clock = (uint64_t)RREG32(RLC_GPU_CLOCK_COUNT_LSB) |
6987926deccbSFrançois Tigeot 		((uint64_t)RREG32(RLC_GPU_CLOCK_COUNT_MSB) << 32ULL);
6988fefad7a7SFrançois Tigeot 	mutex_unlock(&rdev->gpu_clock_mutex);
6989926deccbSFrançois Tigeot 	return clock;
6990926deccbSFrançois Tigeot }
6991f43cf1b1SMichael Neumann 
si_set_uvd_clocks(struct radeon_device * rdev,u32 vclk,u32 dclk)6992f43cf1b1SMichael Neumann int si_set_uvd_clocks(struct radeon_device *rdev, u32 vclk, u32 dclk)
6993f43cf1b1SMichael Neumann {
6994f43cf1b1SMichael Neumann 	unsigned fb_div = 0, vclk_div = 0, dclk_div = 0;
6995f43cf1b1SMichael Neumann 	int r;
6996f43cf1b1SMichael Neumann 
6997f43cf1b1SMichael Neumann 	/* bypass vclk and dclk with bclk */
6998f43cf1b1SMichael Neumann 	WREG32_P(CG_UPLL_FUNC_CNTL_2,
6999f43cf1b1SMichael Neumann 		VCLK_SRC_SEL(1) | DCLK_SRC_SEL(1),
7000f43cf1b1SMichael Neumann 		~(VCLK_SRC_SEL_MASK | DCLK_SRC_SEL_MASK));
7001f43cf1b1SMichael Neumann 
7002f43cf1b1SMichael Neumann 	/* put PLL in bypass mode */
7003f43cf1b1SMichael Neumann 	WREG32_P(CG_UPLL_FUNC_CNTL, UPLL_BYPASS_EN_MASK, ~UPLL_BYPASS_EN_MASK);
7004f43cf1b1SMichael Neumann 
7005f43cf1b1SMichael Neumann 	if (!vclk || !dclk) {
70067dcf36dcSFrançois Tigeot 		/* keep the Bypass mode */
7007f43cf1b1SMichael Neumann 		return 0;
7008f43cf1b1SMichael Neumann 	}
7009f43cf1b1SMichael Neumann 
7010f43cf1b1SMichael Neumann 	r = radeon_uvd_calc_upll_dividers(rdev, vclk, dclk, 125000, 250000,
7011f43cf1b1SMichael Neumann 					  16384, 0x03FFFFFF, 0, 128, 5,
7012f43cf1b1SMichael Neumann 					  &fb_div, &vclk_div, &dclk_div);
7013f43cf1b1SMichael Neumann 	if (r)
7014f43cf1b1SMichael Neumann 		return r;
7015f43cf1b1SMichael Neumann 
7016f43cf1b1SMichael Neumann 	/* set RESET_ANTI_MUX to 0 */
7017f43cf1b1SMichael Neumann 	WREG32_P(CG_UPLL_FUNC_CNTL_5, 0, ~RESET_ANTI_MUX_MASK);
7018f43cf1b1SMichael Neumann 
7019f43cf1b1SMichael Neumann 	/* set VCO_MODE to 1 */
7020f43cf1b1SMichael Neumann 	WREG32_P(CG_UPLL_FUNC_CNTL, UPLL_VCO_MODE_MASK, ~UPLL_VCO_MODE_MASK);
7021f43cf1b1SMichael Neumann 
70227dcf36dcSFrançois Tigeot 	/* disable sleep mode */
7023f43cf1b1SMichael Neumann 	WREG32_P(CG_UPLL_FUNC_CNTL, 0, ~UPLL_SLEEP_MASK);
7024f43cf1b1SMichael Neumann 
7025f43cf1b1SMichael Neumann 	/* deassert UPLL_RESET */
7026f43cf1b1SMichael Neumann 	WREG32_P(CG_UPLL_FUNC_CNTL, 0, ~UPLL_RESET_MASK);
7027f43cf1b1SMichael Neumann 
7028c4ef309bSzrj 	mdelay(1);
7029f43cf1b1SMichael Neumann 
7030f43cf1b1SMichael Neumann 	r = radeon_uvd_send_upll_ctlreq(rdev, CG_UPLL_FUNC_CNTL);
7031f43cf1b1SMichael Neumann 	if (r)
7032f43cf1b1SMichael Neumann 		return r;
7033f43cf1b1SMichael Neumann 
7034f43cf1b1SMichael Neumann 	/* assert UPLL_RESET again */
7035f43cf1b1SMichael Neumann 	WREG32_P(CG_UPLL_FUNC_CNTL, UPLL_RESET_MASK, ~UPLL_RESET_MASK);
7036f43cf1b1SMichael Neumann 
7037f43cf1b1SMichael Neumann 	/* disable spread spectrum. */
7038f43cf1b1SMichael Neumann 	WREG32_P(CG_UPLL_SPREAD_SPECTRUM, 0, ~SSEN_MASK);
7039f43cf1b1SMichael Neumann 
7040f43cf1b1SMichael Neumann 	/* set feedback divider */
7041f43cf1b1SMichael Neumann 	WREG32_P(CG_UPLL_FUNC_CNTL_3, UPLL_FB_DIV(fb_div), ~UPLL_FB_DIV_MASK);
7042f43cf1b1SMichael Neumann 
7043f43cf1b1SMichael Neumann 	/* set ref divider to 0 */
7044f43cf1b1SMichael Neumann 	WREG32_P(CG_UPLL_FUNC_CNTL, 0, ~UPLL_REF_DIV_MASK);
7045f43cf1b1SMichael Neumann 
7046f43cf1b1SMichael Neumann 	if (fb_div < 307200)
7047f43cf1b1SMichael Neumann 		WREG32_P(CG_UPLL_FUNC_CNTL_4, 0, ~UPLL_SPARE_ISPARE9);
7048f43cf1b1SMichael Neumann 	else
7049f43cf1b1SMichael Neumann 		WREG32_P(CG_UPLL_FUNC_CNTL_4, UPLL_SPARE_ISPARE9, ~UPLL_SPARE_ISPARE9);
7050f43cf1b1SMichael Neumann 
7051f43cf1b1SMichael Neumann 	/* set PDIV_A and PDIV_B */
7052f43cf1b1SMichael Neumann 	WREG32_P(CG_UPLL_FUNC_CNTL_2,
7053f43cf1b1SMichael Neumann 		UPLL_PDIV_A(vclk_div) | UPLL_PDIV_B(dclk_div),
7054f43cf1b1SMichael Neumann 		~(UPLL_PDIV_A_MASK | UPLL_PDIV_B_MASK));
7055f43cf1b1SMichael Neumann 
7056f43cf1b1SMichael Neumann 	/* give the PLL some time to settle */
7057c4ef309bSzrj 	mdelay(15);
7058f43cf1b1SMichael Neumann 
7059f43cf1b1SMichael Neumann 	/* deassert PLL_RESET */
7060f43cf1b1SMichael Neumann 	WREG32_P(CG_UPLL_FUNC_CNTL, 0, ~UPLL_RESET_MASK);
7061f43cf1b1SMichael Neumann 
7062c4ef309bSzrj 	mdelay(15);
7063f43cf1b1SMichael Neumann 
7064f43cf1b1SMichael Neumann 	/* switch from bypass mode to normal mode */
7065f43cf1b1SMichael Neumann 	WREG32_P(CG_UPLL_FUNC_CNTL, 0, ~UPLL_BYPASS_EN_MASK);
7066f43cf1b1SMichael Neumann 
7067f43cf1b1SMichael Neumann 	r = radeon_uvd_send_upll_ctlreq(rdev, CG_UPLL_FUNC_CNTL);
7068f43cf1b1SMichael Neumann 	if (r)
7069f43cf1b1SMichael Neumann 		return r;
7070f43cf1b1SMichael Neumann 
7071f43cf1b1SMichael Neumann 	/* switch VCLK and DCLK selection */
7072f43cf1b1SMichael Neumann 	WREG32_P(CG_UPLL_FUNC_CNTL_2,
7073f43cf1b1SMichael Neumann 		VCLK_SRC_SEL(2) | DCLK_SRC_SEL(2),
7074f43cf1b1SMichael Neumann 		~(VCLK_SRC_SEL_MASK | DCLK_SRC_SEL_MASK));
7075f43cf1b1SMichael Neumann 
7076c4ef309bSzrj 	mdelay(100);
7077f43cf1b1SMichael Neumann 
7078f43cf1b1SMichael Neumann 	return 0;
7079f43cf1b1SMichael Neumann }
708057e252bfSMichael Neumann 
si_pcie_gen3_enable(struct radeon_device * rdev)708157e252bfSMichael Neumann static void si_pcie_gen3_enable(struct radeon_device *rdev)
708257e252bfSMichael Neumann {
70834cd92098Szrj 	struct pci_dev *root = rdev->pdev->bus->self;
708457e252bfSMichael Neumann 	int bridge_pos, gpu_pos;
708557e252bfSMichael Neumann 	u32 speed_cntl, mask, current_data_rate;
708657e252bfSMichael Neumann 	int ret, i;
708757e252bfSMichael Neumann 	u16 tmp16;
708857e252bfSMichael Neumann 
7089c59a5c48SFrançois Tigeot #if 0
7090c59a5c48SFrançois Tigeot 	if (pci_is_root_bus(rdev->pdev->bus))
7091c59a5c48SFrançois Tigeot 		return;
7092c59a5c48SFrançois Tigeot #endif
7093c59a5c48SFrançois Tigeot 
709457e252bfSMichael Neumann 	if (radeon_pcie_gen2 == 0)
709557e252bfSMichael Neumann 		return;
709657e252bfSMichael Neumann 
709757e252bfSMichael Neumann 	if (rdev->flags & RADEON_IS_IGP)
709857e252bfSMichael Neumann 		return;
709957e252bfSMichael Neumann 
710057e252bfSMichael Neumann 	if (!(rdev->flags & RADEON_IS_PCIE))
710157e252bfSMichael Neumann 		return;
710257e252bfSMichael Neumann 
710357e252bfSMichael Neumann 	ret = drm_pcie_get_speed_cap_mask(rdev->ddev, &mask);
710457e252bfSMichael Neumann 	if (ret != 0)
710557e252bfSMichael Neumann 		return;
710657e252bfSMichael Neumann 
710757e252bfSMichael Neumann 	if (!(mask & (DRM_PCIE_SPEED_50 | DRM_PCIE_SPEED_80)))
710857e252bfSMichael Neumann 		return;
710957e252bfSMichael Neumann 
711057e252bfSMichael Neumann 	speed_cntl = RREG32_PCIE_PORT(PCIE_LC_SPEED_CNTL);
711157e252bfSMichael Neumann 	current_data_rate = (speed_cntl & LC_CURRENT_DATA_RATE_MASK) >>
711257e252bfSMichael Neumann 		LC_CURRENT_DATA_RATE_SHIFT;
711357e252bfSMichael Neumann 	if (mask & DRM_PCIE_SPEED_80) {
711457e252bfSMichael Neumann 		if (current_data_rate == 2) {
711557e252bfSMichael Neumann 			DRM_INFO("PCIE gen 3 link speeds already enabled\n");
711657e252bfSMichael Neumann 			return;
711757e252bfSMichael Neumann 		}
711857e252bfSMichael Neumann 		DRM_INFO("enabling PCIE gen 3 link speeds, disable with radeon.pcie_gen2=0\n");
711957e252bfSMichael Neumann 	} else if (mask & DRM_PCIE_SPEED_50) {
712057e252bfSMichael Neumann 		if (current_data_rate == 1) {
712157e252bfSMichael Neumann 			DRM_INFO("PCIE gen 2 link speeds already enabled\n");
712257e252bfSMichael Neumann 			return;
712357e252bfSMichael Neumann 		}
712457e252bfSMichael Neumann 		DRM_INFO("enabling PCIE gen 2 link speeds, disable with radeon.pcie_gen2=0\n");
712557e252bfSMichael Neumann 	}
712657e252bfSMichael Neumann 
7127c59a5c48SFrançois Tigeot 	bridge_pos = pci_pcie_cap(root);
712857e252bfSMichael Neumann 	if (!bridge_pos)
712957e252bfSMichael Neumann 		return;
713057e252bfSMichael Neumann 
7131c59a5c48SFrançois Tigeot 	gpu_pos = pci_pcie_cap(rdev->pdev);
713257e252bfSMichael Neumann 	if (!gpu_pos)
713357e252bfSMichael Neumann 		return;
713457e252bfSMichael Neumann 
713557e252bfSMichael Neumann 	if (mask & DRM_PCIE_SPEED_80) {
713657e252bfSMichael Neumann 		/* re-try equalization if gen3 is not already enabled */
713757e252bfSMichael Neumann 		if (current_data_rate != 2) {
713857e252bfSMichael Neumann 			u16 bridge_cfg, gpu_cfg;
713957e252bfSMichael Neumann 			u16 bridge_cfg2, gpu_cfg2;
714057e252bfSMichael Neumann 			u32 max_lw, current_lw, tmp;
714157e252bfSMichael Neumann 
7142c6f73aabSFrançois Tigeot 			pci_read_config_word(root, bridge_pos + PCI_EXP_LNKCTL, &bridge_cfg);
7143c6f73aabSFrançois Tigeot 			pci_read_config_word(rdev->pdev, gpu_pos + PCI_EXP_LNKCTL, &gpu_cfg);
714457e252bfSMichael Neumann 
714557e252bfSMichael Neumann 			tmp16 = bridge_cfg | PCI_EXP_LNKCTL_HAWD;
7146c6f73aabSFrançois Tigeot 			pci_write_config_word(root, bridge_pos + PCI_EXP_LNKCTL, tmp16);
714757e252bfSMichael Neumann 
714857e252bfSMichael Neumann 			tmp16 = gpu_cfg | PCI_EXP_LNKCTL_HAWD;
7149c6f73aabSFrançois Tigeot 			pci_write_config_word(rdev->pdev, gpu_pos + PCI_EXP_LNKCTL, tmp16);
715057e252bfSMichael Neumann 
715157e252bfSMichael Neumann 			tmp = RREG32_PCIE(PCIE_LC_STATUS1);
715257e252bfSMichael Neumann 			max_lw = (tmp & LC_DETECTED_LINK_WIDTH_MASK) >> LC_DETECTED_LINK_WIDTH_SHIFT;
715357e252bfSMichael Neumann 			current_lw = (tmp & LC_OPERATING_LINK_WIDTH_MASK) >> LC_OPERATING_LINK_WIDTH_SHIFT;
715457e252bfSMichael Neumann 
715557e252bfSMichael Neumann 			if (current_lw < max_lw) {
715657e252bfSMichael Neumann 				tmp = RREG32_PCIE_PORT(PCIE_LC_LINK_WIDTH_CNTL);
715757e252bfSMichael Neumann 				if (tmp & LC_RENEGOTIATION_SUPPORT) {
715857e252bfSMichael Neumann 					tmp &= ~(LC_LINK_WIDTH_MASK | LC_UPCONFIGURE_DIS);
715957e252bfSMichael Neumann 					tmp |= (max_lw << LC_LINK_WIDTH_SHIFT);
716057e252bfSMichael Neumann 					tmp |= LC_UPCONFIGURE_SUPPORT | LC_RENEGOTIATE_EN | LC_RECONFIG_NOW;
716157e252bfSMichael Neumann 					WREG32_PCIE_PORT(PCIE_LC_LINK_WIDTH_CNTL, tmp);
716257e252bfSMichael Neumann 				}
716357e252bfSMichael Neumann 			}
716457e252bfSMichael Neumann 
716557e252bfSMichael Neumann 			for (i = 0; i < 10; i++) {
716657e252bfSMichael Neumann 				/* check status */
7167c6f73aabSFrançois Tigeot 				pci_read_config_word(rdev->pdev, gpu_pos + PCI_EXP_DEVSTA, &tmp16);
716857e252bfSMichael Neumann 				if (tmp16 & PCI_EXP_DEVSTA_TRPND)
716957e252bfSMichael Neumann 					break;
717057e252bfSMichael Neumann 
7171c6f73aabSFrançois Tigeot 				pci_read_config_word(root, bridge_pos + PCI_EXP_LNKCTL, &bridge_cfg);
7172c6f73aabSFrançois Tigeot 				pci_read_config_word(rdev->pdev, gpu_pos + PCI_EXP_LNKCTL, &gpu_cfg);
717357e252bfSMichael Neumann 
7174c6f73aabSFrançois Tigeot 				pci_read_config_word(root, bridge_pos + PCI_EXP_LNKCTL2, &bridge_cfg2);
7175c6f73aabSFrançois Tigeot 				pci_read_config_word(rdev->pdev, gpu_pos + PCI_EXP_LNKCTL2, &gpu_cfg2);
717657e252bfSMichael Neumann 
717757e252bfSMichael Neumann 				tmp = RREG32_PCIE_PORT(PCIE_LC_CNTL4);
717857e252bfSMichael Neumann 				tmp |= LC_SET_QUIESCE;
717957e252bfSMichael Neumann 				WREG32_PCIE_PORT(PCIE_LC_CNTL4, tmp);
718057e252bfSMichael Neumann 
718157e252bfSMichael Neumann 				tmp = RREG32_PCIE_PORT(PCIE_LC_CNTL4);
718257e252bfSMichael Neumann 				tmp |= LC_REDO_EQ;
718357e252bfSMichael Neumann 				WREG32_PCIE_PORT(PCIE_LC_CNTL4, tmp);
718457e252bfSMichael Neumann 
7185c4ef309bSzrj 				mdelay(100);
718657e252bfSMichael Neumann 
718757e252bfSMichael Neumann 				/* linkctl */
7188c6f73aabSFrançois Tigeot 				pci_read_config_word(root, bridge_pos + PCI_EXP_LNKCTL, &tmp16);
718957e252bfSMichael Neumann 				tmp16 &= ~PCI_EXP_LNKCTL_HAWD;
719057e252bfSMichael Neumann 				tmp16 |= (bridge_cfg & PCI_EXP_LNKCTL_HAWD);
7191c6f73aabSFrançois Tigeot 				pci_write_config_word(root, bridge_pos + PCI_EXP_LNKCTL, tmp16);
719257e252bfSMichael Neumann 
7193c6f73aabSFrançois Tigeot 				pci_read_config_word(rdev->pdev, gpu_pos + PCI_EXP_LNKCTL, &tmp16);
719457e252bfSMichael Neumann 				tmp16 &= ~PCI_EXP_LNKCTL_HAWD;
719557e252bfSMichael Neumann 				tmp16 |= (gpu_cfg & PCI_EXP_LNKCTL_HAWD);
7196c6f73aabSFrançois Tigeot 				pci_write_config_word(rdev->pdev, gpu_pos + PCI_EXP_LNKCTL, tmp16);
719757e252bfSMichael Neumann 
719857e252bfSMichael Neumann 				/* linkctl2 */
7199c6f73aabSFrançois Tigeot 				pci_read_config_word(root, bridge_pos + PCI_EXP_LNKCTL2, &tmp16);
720057e252bfSMichael Neumann 				tmp16 &= ~((1 << 4) | (7 << 9));
720157e252bfSMichael Neumann 				tmp16 |= (bridge_cfg2 & ((1 << 4) | (7 << 9)));
7202c6f73aabSFrançois Tigeot 				pci_write_config_word(root, bridge_pos + PCI_EXP_LNKCTL2, tmp16);
720357e252bfSMichael Neumann 
7204c6f73aabSFrançois Tigeot 				pci_read_config_word(rdev->pdev, gpu_pos + PCI_EXP_LNKCTL2, &tmp16);
720557e252bfSMichael Neumann 				tmp16 &= ~((1 << 4) | (7 << 9));
720657e252bfSMichael Neumann 				tmp16 |= (gpu_cfg2 & ((1 << 4) | (7 << 9)));
7207c6f73aabSFrançois Tigeot 				pci_write_config_word(rdev->pdev, gpu_pos + PCI_EXP_LNKCTL2, tmp16);
720857e252bfSMichael Neumann 
720957e252bfSMichael Neumann 				tmp = RREG32_PCIE_PORT(PCIE_LC_CNTL4);
721057e252bfSMichael Neumann 				tmp &= ~LC_SET_QUIESCE;
721157e252bfSMichael Neumann 				WREG32_PCIE_PORT(PCIE_LC_CNTL4, tmp);
721257e252bfSMichael Neumann 			}
721357e252bfSMichael Neumann 		}
721457e252bfSMichael Neumann 	}
721557e252bfSMichael Neumann 
721657e252bfSMichael Neumann 	/* set the link speed */
721757e252bfSMichael Neumann 	speed_cntl |= LC_FORCE_EN_SW_SPEED_CHANGE | LC_FORCE_DIS_HW_SPEED_CHANGE;
721857e252bfSMichael Neumann 	speed_cntl &= ~LC_FORCE_DIS_SW_SPEED_CHANGE;
721957e252bfSMichael Neumann 	WREG32_PCIE_PORT(PCIE_LC_SPEED_CNTL, speed_cntl);
722057e252bfSMichael Neumann 
7221c6f73aabSFrançois Tigeot 	pci_read_config_word(rdev->pdev, gpu_pos + PCI_EXP_LNKCTL2, &tmp16);
722257e252bfSMichael Neumann 	tmp16 &= ~0xf;
722357e252bfSMichael Neumann 	if (mask & DRM_PCIE_SPEED_80)
722457e252bfSMichael Neumann 		tmp16 |= 3; /* gen3 */
722557e252bfSMichael Neumann 	else if (mask & DRM_PCIE_SPEED_50)
722657e252bfSMichael Neumann 		tmp16 |= 2; /* gen2 */
722757e252bfSMichael Neumann 	else
722857e252bfSMichael Neumann 		tmp16 |= 1; /* gen1 */
7229c6f73aabSFrançois Tigeot 	pci_write_config_word(rdev->pdev, gpu_pos + PCI_EXP_LNKCTL2, tmp16);
723057e252bfSMichael Neumann 
723157e252bfSMichael Neumann 	speed_cntl = RREG32_PCIE_PORT(PCIE_LC_SPEED_CNTL);
723257e252bfSMichael Neumann 	speed_cntl |= LC_INITIATE_LINK_SPEED_CHANGE;
723357e252bfSMichael Neumann 	WREG32_PCIE_PORT(PCIE_LC_SPEED_CNTL, speed_cntl);
723457e252bfSMichael Neumann 
723557e252bfSMichael Neumann 	for (i = 0; i < rdev->usec_timeout; i++) {
723657e252bfSMichael Neumann 		speed_cntl = RREG32_PCIE_PORT(PCIE_LC_SPEED_CNTL);
723757e252bfSMichael Neumann 		if ((speed_cntl & LC_INITIATE_LINK_SPEED_CHANGE) == 0)
723857e252bfSMichael Neumann 			break;
7239c4ef309bSzrj 		udelay(1);
724057e252bfSMichael Neumann 	}
724157e252bfSMichael Neumann }
724257e252bfSMichael Neumann 
si_program_aspm(struct radeon_device * rdev)724357e252bfSMichael Neumann static void si_program_aspm(struct radeon_device *rdev)
724457e252bfSMichael Neumann {
724557e252bfSMichael Neumann 	u32 data, orig;
724657e252bfSMichael Neumann 	bool disable_l0s = false, disable_l1 = false, disable_plloff_in_l1 = false;
7247c59a5c48SFrançois Tigeot #if 0
724857e252bfSMichael Neumann 	bool disable_clkreq = false;
7249c59a5c48SFrançois Tigeot #endif
725057e252bfSMichael Neumann 
725157e252bfSMichael Neumann 	if (radeon_aspm == 0)
725257e252bfSMichael Neumann 		return;
725357e252bfSMichael Neumann 
725457e252bfSMichael Neumann 	if (!(rdev->flags & RADEON_IS_PCIE))
725557e252bfSMichael Neumann 		return;
725657e252bfSMichael Neumann 
725757e252bfSMichael Neumann 	orig = data = RREG32_PCIE_PORT(PCIE_LC_N_FTS_CNTL);
725857e252bfSMichael Neumann 	data &= ~LC_XMIT_N_FTS_MASK;
725957e252bfSMichael Neumann 	data |= LC_XMIT_N_FTS(0x24) | LC_XMIT_N_FTS_OVERRIDE_EN;
726057e252bfSMichael Neumann 	if (orig != data)
726157e252bfSMichael Neumann 		WREG32_PCIE_PORT(PCIE_LC_N_FTS_CNTL, data);
726257e252bfSMichael Neumann 
726357e252bfSMichael Neumann 	orig = data = RREG32_PCIE_PORT(PCIE_LC_CNTL3);
726457e252bfSMichael Neumann 	data |= LC_GO_TO_RECOVERY;
726557e252bfSMichael Neumann 	if (orig != data)
726657e252bfSMichael Neumann 		WREG32_PCIE_PORT(PCIE_LC_CNTL3, data);
726757e252bfSMichael Neumann 
726857e252bfSMichael Neumann 	orig = data = RREG32_PCIE(PCIE_P_CNTL);
726957e252bfSMichael Neumann 	data |= P_IGNORE_EDB_ERR;
727057e252bfSMichael Neumann 	if (orig != data)
727157e252bfSMichael Neumann 		WREG32_PCIE(PCIE_P_CNTL, data);
727257e252bfSMichael Neumann 
727357e252bfSMichael Neumann 	orig = data = RREG32_PCIE_PORT(PCIE_LC_CNTL);
727457e252bfSMichael Neumann 	data &= ~(LC_L0S_INACTIVITY_MASK | LC_L1_INACTIVITY_MASK);
727557e252bfSMichael Neumann 	data |= LC_PMI_TO_L1_DIS;
727657e252bfSMichael Neumann 	if (!disable_l0s)
727757e252bfSMichael Neumann 		data |= LC_L0S_INACTIVITY(7);
727857e252bfSMichael Neumann 
727957e252bfSMichael Neumann 	if (!disable_l1) {
728057e252bfSMichael Neumann 		data |= LC_L1_INACTIVITY(7);
728157e252bfSMichael Neumann 		data &= ~LC_PMI_TO_L1_DIS;
728257e252bfSMichael Neumann 		if (orig != data)
728357e252bfSMichael Neumann 			WREG32_PCIE_PORT(PCIE_LC_CNTL, data);
728457e252bfSMichael Neumann 
728557e252bfSMichael Neumann 		if (!disable_plloff_in_l1) {
728657e252bfSMichael Neumann 			bool clk_req_support;
728757e252bfSMichael Neumann 
728857e252bfSMichael Neumann 			orig = data = RREG32_PIF_PHY0(PB0_PIF_PWRDOWN_0);
728957e252bfSMichael Neumann 			data &= ~(PLL_POWER_STATE_IN_OFF_0_MASK | PLL_POWER_STATE_IN_TXS2_0_MASK);
729057e252bfSMichael Neumann 			data |= PLL_POWER_STATE_IN_OFF_0(7) | PLL_POWER_STATE_IN_TXS2_0(7);
729157e252bfSMichael Neumann 			if (orig != data)
729257e252bfSMichael Neumann 				WREG32_PIF_PHY0(PB0_PIF_PWRDOWN_0, data);
729357e252bfSMichael Neumann 
729457e252bfSMichael Neumann 			orig = data = RREG32_PIF_PHY0(PB0_PIF_PWRDOWN_1);
729557e252bfSMichael Neumann 			data &= ~(PLL_POWER_STATE_IN_OFF_1_MASK | PLL_POWER_STATE_IN_TXS2_1_MASK);
729657e252bfSMichael Neumann 			data |= PLL_POWER_STATE_IN_OFF_1(7) | PLL_POWER_STATE_IN_TXS2_1(7);
729757e252bfSMichael Neumann 			if (orig != data)
729857e252bfSMichael Neumann 				WREG32_PIF_PHY0(PB0_PIF_PWRDOWN_1, data);
729957e252bfSMichael Neumann 
730057e252bfSMichael Neumann 			orig = data = RREG32_PIF_PHY1(PB1_PIF_PWRDOWN_0);
730157e252bfSMichael Neumann 			data &= ~(PLL_POWER_STATE_IN_OFF_0_MASK | PLL_POWER_STATE_IN_TXS2_0_MASK);
730257e252bfSMichael Neumann 			data |= PLL_POWER_STATE_IN_OFF_0(7) | PLL_POWER_STATE_IN_TXS2_0(7);
730357e252bfSMichael Neumann 			if (orig != data)
730457e252bfSMichael Neumann 				WREG32_PIF_PHY1(PB1_PIF_PWRDOWN_0, data);
730557e252bfSMichael Neumann 
730657e252bfSMichael Neumann 			orig = data = RREG32_PIF_PHY1(PB1_PIF_PWRDOWN_1);
730757e252bfSMichael Neumann 			data &= ~(PLL_POWER_STATE_IN_OFF_1_MASK | PLL_POWER_STATE_IN_TXS2_1_MASK);
730857e252bfSMichael Neumann 			data |= PLL_POWER_STATE_IN_OFF_1(7) | PLL_POWER_STATE_IN_TXS2_1(7);
730957e252bfSMichael Neumann 			if (orig != data)
731057e252bfSMichael Neumann 				WREG32_PIF_PHY1(PB1_PIF_PWRDOWN_1, data);
731157e252bfSMichael Neumann 
731257e252bfSMichael Neumann 			if ((rdev->family != CHIP_OLAND) && (rdev->family != CHIP_HAINAN)) {
731357e252bfSMichael Neumann 				orig = data = RREG32_PIF_PHY0(PB0_PIF_PWRDOWN_0);
731457e252bfSMichael Neumann 				data &= ~PLL_RAMP_UP_TIME_0_MASK;
731557e252bfSMichael Neumann 				if (orig != data)
731657e252bfSMichael Neumann 					WREG32_PIF_PHY0(PB0_PIF_PWRDOWN_0, data);
731757e252bfSMichael Neumann 
731857e252bfSMichael Neumann 				orig = data = RREG32_PIF_PHY0(PB0_PIF_PWRDOWN_1);
731957e252bfSMichael Neumann 				data &= ~PLL_RAMP_UP_TIME_1_MASK;
732057e252bfSMichael Neumann 				if (orig != data)
732157e252bfSMichael Neumann 					WREG32_PIF_PHY0(PB0_PIF_PWRDOWN_1, data);
732257e252bfSMichael Neumann 
732357e252bfSMichael Neumann 				orig = data = RREG32_PIF_PHY0(PB0_PIF_PWRDOWN_2);
732457e252bfSMichael Neumann 				data &= ~PLL_RAMP_UP_TIME_2_MASK;
732557e252bfSMichael Neumann 				if (orig != data)
732657e252bfSMichael Neumann 					WREG32_PIF_PHY0(PB0_PIF_PWRDOWN_2, data);
732757e252bfSMichael Neumann 
732857e252bfSMichael Neumann 				orig = data = RREG32_PIF_PHY0(PB0_PIF_PWRDOWN_3);
732957e252bfSMichael Neumann 				data &= ~PLL_RAMP_UP_TIME_3_MASK;
733057e252bfSMichael Neumann 				if (orig != data)
733157e252bfSMichael Neumann 					WREG32_PIF_PHY0(PB0_PIF_PWRDOWN_3, data);
733257e252bfSMichael Neumann 
733357e252bfSMichael Neumann 				orig = data = RREG32_PIF_PHY1(PB1_PIF_PWRDOWN_0);
733457e252bfSMichael Neumann 				data &= ~PLL_RAMP_UP_TIME_0_MASK;
733557e252bfSMichael Neumann 				if (orig != data)
733657e252bfSMichael Neumann 					WREG32_PIF_PHY1(PB1_PIF_PWRDOWN_0, data);
733757e252bfSMichael Neumann 
733857e252bfSMichael Neumann 				orig = data = RREG32_PIF_PHY1(PB1_PIF_PWRDOWN_1);
733957e252bfSMichael Neumann 				data &= ~PLL_RAMP_UP_TIME_1_MASK;
734057e252bfSMichael Neumann 				if (orig != data)
734157e252bfSMichael Neumann 					WREG32_PIF_PHY1(PB1_PIF_PWRDOWN_1, data);
734257e252bfSMichael Neumann 
734357e252bfSMichael Neumann 				orig = data = RREG32_PIF_PHY1(PB1_PIF_PWRDOWN_2);
734457e252bfSMichael Neumann 				data &= ~PLL_RAMP_UP_TIME_2_MASK;
734557e252bfSMichael Neumann 				if (orig != data)
734657e252bfSMichael Neumann 					WREG32_PIF_PHY1(PB1_PIF_PWRDOWN_2, data);
734757e252bfSMichael Neumann 
734857e252bfSMichael Neumann 				orig = data = RREG32_PIF_PHY1(PB1_PIF_PWRDOWN_3);
734957e252bfSMichael Neumann 				data &= ~PLL_RAMP_UP_TIME_3_MASK;
735057e252bfSMichael Neumann 				if (orig != data)
735157e252bfSMichael Neumann 					WREG32_PIF_PHY1(PB1_PIF_PWRDOWN_3, data);
735257e252bfSMichael Neumann 			}
735357e252bfSMichael Neumann 			orig = data = RREG32_PCIE_PORT(PCIE_LC_LINK_WIDTH_CNTL);
735457e252bfSMichael Neumann 			data &= ~LC_DYN_LANES_PWR_STATE_MASK;
735557e252bfSMichael Neumann 			data |= LC_DYN_LANES_PWR_STATE(3);
735657e252bfSMichael Neumann 			if (orig != data)
735757e252bfSMichael Neumann 				WREG32_PCIE_PORT(PCIE_LC_LINK_WIDTH_CNTL, data);
735857e252bfSMichael Neumann 
735957e252bfSMichael Neumann 			orig = data = RREG32_PIF_PHY0(PB0_PIF_CNTL);
736057e252bfSMichael Neumann 			data &= ~LS2_EXIT_TIME_MASK;
736157e252bfSMichael Neumann 			if ((rdev->family == CHIP_OLAND) || (rdev->family == CHIP_HAINAN))
736257e252bfSMichael Neumann 				data |= LS2_EXIT_TIME(5);
736357e252bfSMichael Neumann 			if (orig != data)
736457e252bfSMichael Neumann 				WREG32_PIF_PHY0(PB0_PIF_CNTL, data);
736557e252bfSMichael Neumann 
736657e252bfSMichael Neumann 			orig = data = RREG32_PIF_PHY1(PB1_PIF_CNTL);
736757e252bfSMichael Neumann 			data &= ~LS2_EXIT_TIME_MASK;
736857e252bfSMichael Neumann 			if ((rdev->family == CHIP_OLAND) || (rdev->family == CHIP_HAINAN))
736957e252bfSMichael Neumann 				data |= LS2_EXIT_TIME(5);
737057e252bfSMichael Neumann 			if (orig != data)
737157e252bfSMichael Neumann 				WREG32_PIF_PHY1(PB1_PIF_CNTL, data);
737257e252bfSMichael Neumann 
73734cd92098Szrj #ifdef zMN_TODO
7374c59a5c48SFrançois Tigeot 			if (!disable_clkreq &&
7375c59a5c48SFrançois Tigeot 			    !pci_is_root_bus(rdev->pdev->bus)) {
737657e252bfSMichael Neumann 				struct pci_dev *root = rdev->pdev->bus->self;
737757e252bfSMichael Neumann 				u32 lnkcap;
737857e252bfSMichael Neumann 
737957e252bfSMichael Neumann 				clk_req_support = false;
738057e252bfSMichael Neumann 				pcie_capability_read_dword(root, PCI_EXP_LNKCAP, &lnkcap);
738157e252bfSMichael Neumann 				if (lnkcap & PCI_EXP_LNKCAP_CLKPM)
738257e252bfSMichael Neumann 					clk_req_support = true;
738357e252bfSMichael Neumann 			} else {
738457e252bfSMichael Neumann 				clk_req_support = false;
738557e252bfSMichael Neumann 			}
7386c59a5c48SFrançois Tigeot #else
7387c59a5c48SFrançois Tigeot 			clk_req_support = false;
7388c59a5c48SFrançois Tigeot #endif
738957e252bfSMichael Neumann 
739057e252bfSMichael Neumann 			if (clk_req_support) {
739157e252bfSMichael Neumann 				orig = data = RREG32_PCIE_PORT(PCIE_LC_CNTL2);
739257e252bfSMichael Neumann 				data |= LC_ALLOW_PDWN_IN_L1 | LC_ALLOW_PDWN_IN_L23;
739357e252bfSMichael Neumann 				if (orig != data)
739457e252bfSMichael Neumann 					WREG32_PCIE_PORT(PCIE_LC_CNTL2, data);
739557e252bfSMichael Neumann 
739657e252bfSMichael Neumann 				orig = data = RREG32(THM_CLK_CNTL);
739757e252bfSMichael Neumann 				data &= ~(CMON_CLK_SEL_MASK | TMON_CLK_SEL_MASK);
739857e252bfSMichael Neumann 				data |= CMON_CLK_SEL(1) | TMON_CLK_SEL(1);
739957e252bfSMichael Neumann 				if (orig != data)
740057e252bfSMichael Neumann 					WREG32(THM_CLK_CNTL, data);
740157e252bfSMichael Neumann 
740257e252bfSMichael Neumann 				orig = data = RREG32(MISC_CLK_CNTL);
740357e252bfSMichael Neumann 				data &= ~(DEEP_SLEEP_CLK_SEL_MASK | ZCLK_SEL_MASK);
740457e252bfSMichael Neumann 				data |= DEEP_SLEEP_CLK_SEL(1) | ZCLK_SEL(1);
740557e252bfSMichael Neumann 				if (orig != data)
740657e252bfSMichael Neumann 					WREG32(MISC_CLK_CNTL, data);
740757e252bfSMichael Neumann 
740857e252bfSMichael Neumann 				orig = data = RREG32(CG_CLKPIN_CNTL);
740957e252bfSMichael Neumann 				data &= ~BCLK_AS_XCLK;
741057e252bfSMichael Neumann 				if (orig != data)
741157e252bfSMichael Neumann 					WREG32(CG_CLKPIN_CNTL, data);
741257e252bfSMichael Neumann 
741357e252bfSMichael Neumann 				orig = data = RREG32(CG_CLKPIN_CNTL_2);
741457e252bfSMichael Neumann 				data &= ~FORCE_BIF_REFCLK_EN;
741557e252bfSMichael Neumann 				if (orig != data)
741657e252bfSMichael Neumann 					WREG32(CG_CLKPIN_CNTL_2, data);
741757e252bfSMichael Neumann 
741857e252bfSMichael Neumann 				orig = data = RREG32(MPLL_BYPASSCLK_SEL);
741957e252bfSMichael Neumann 				data &= ~MPLL_CLKOUT_SEL_MASK;
742057e252bfSMichael Neumann 				data |= MPLL_CLKOUT_SEL(4);
742157e252bfSMichael Neumann 				if (orig != data)
742257e252bfSMichael Neumann 					WREG32(MPLL_BYPASSCLK_SEL, data);
742357e252bfSMichael Neumann 
742457e252bfSMichael Neumann 				orig = data = RREG32(SPLL_CNTL_MODE);
742557e252bfSMichael Neumann 				data &= ~SPLL_REFCLK_SEL_MASK;
742657e252bfSMichael Neumann 				if (orig != data)
742757e252bfSMichael Neumann 					WREG32(SPLL_CNTL_MODE, data);
742857e252bfSMichael Neumann 			}
742957e252bfSMichael Neumann 		}
743057e252bfSMichael Neumann 	} else {
743157e252bfSMichael Neumann 		if (orig != data)
743257e252bfSMichael Neumann 			WREG32_PCIE_PORT(PCIE_LC_CNTL, data);
743357e252bfSMichael Neumann 	}
743457e252bfSMichael Neumann 
743557e252bfSMichael Neumann 	orig = data = RREG32_PCIE(PCIE_CNTL2);
743657e252bfSMichael Neumann 	data |= SLV_MEM_LS_EN | MST_MEM_LS_EN | REPLAY_MEM_LS_EN;
743757e252bfSMichael Neumann 	if (orig != data)
743857e252bfSMichael Neumann 		WREG32_PCIE(PCIE_CNTL2, data);
743957e252bfSMichael Neumann 
744057e252bfSMichael Neumann 	if (!disable_l0s) {
744157e252bfSMichael Neumann 		data = RREG32_PCIE_PORT(PCIE_LC_N_FTS_CNTL);
744257e252bfSMichael Neumann 		if((data & LC_N_FTS_MASK) == LC_N_FTS_MASK) {
744357e252bfSMichael Neumann 			data = RREG32_PCIE(PCIE_LC_STATUS1);
744457e252bfSMichael Neumann 			if ((data & LC_REVERSE_XMIT) && (data & LC_REVERSE_RCVR)) {
744557e252bfSMichael Neumann 				orig = data = RREG32_PCIE_PORT(PCIE_LC_CNTL);
744657e252bfSMichael Neumann 				data &= ~LC_L0S_INACTIVITY_MASK;
744757e252bfSMichael Neumann 				if (orig != data)
744857e252bfSMichael Neumann 					WREG32_PCIE_PORT(PCIE_LC_CNTL, data);
744957e252bfSMichael Neumann 			}
745057e252bfSMichael Neumann 		}
745157e252bfSMichael Neumann 	}
745257e252bfSMichael Neumann }
7453c59a5c48SFrançois Tigeot 
si_vce_send_vcepll_ctlreq(struct radeon_device * rdev)7454c59a5c48SFrançois Tigeot static int si_vce_send_vcepll_ctlreq(struct radeon_device *rdev)
7455c59a5c48SFrançois Tigeot {
7456c59a5c48SFrançois Tigeot 	unsigned i;
7457c59a5c48SFrançois Tigeot 
7458c59a5c48SFrançois Tigeot 	/* make sure VCEPLL_CTLREQ is deasserted */
7459c59a5c48SFrançois Tigeot 	WREG32_SMC_P(CG_VCEPLL_FUNC_CNTL, 0, ~UPLL_CTLREQ_MASK);
7460c59a5c48SFrançois Tigeot 
7461c59a5c48SFrançois Tigeot 	mdelay(10);
7462c59a5c48SFrançois Tigeot 
7463c59a5c48SFrançois Tigeot 	/* assert UPLL_CTLREQ */
7464c59a5c48SFrançois Tigeot 	WREG32_SMC_P(CG_VCEPLL_FUNC_CNTL, UPLL_CTLREQ_MASK, ~UPLL_CTLREQ_MASK);
7465c59a5c48SFrançois Tigeot 
7466c59a5c48SFrançois Tigeot 	/* wait for CTLACK and CTLACK2 to get asserted */
7467c59a5c48SFrançois Tigeot 	for (i = 0; i < 100; ++i) {
7468c59a5c48SFrançois Tigeot 		uint32_t mask = UPLL_CTLACK_MASK | UPLL_CTLACK2_MASK;
7469c59a5c48SFrançois Tigeot 		if ((RREG32_SMC(CG_VCEPLL_FUNC_CNTL) & mask) == mask)
7470c59a5c48SFrançois Tigeot 			break;
7471c59a5c48SFrançois Tigeot 		mdelay(10);
7472c59a5c48SFrançois Tigeot 	}
7473c59a5c48SFrançois Tigeot 
7474c59a5c48SFrançois Tigeot 	/* deassert UPLL_CTLREQ */
7475c59a5c48SFrançois Tigeot 	WREG32_SMC_P(CG_VCEPLL_FUNC_CNTL, 0, ~UPLL_CTLREQ_MASK);
7476c59a5c48SFrançois Tigeot 
7477c59a5c48SFrançois Tigeot 	if (i == 100) {
7478c59a5c48SFrançois Tigeot 		DRM_ERROR("Timeout setting UVD clocks!\n");
7479c59a5c48SFrançois Tigeot 		return -ETIMEDOUT;
7480c59a5c48SFrançois Tigeot 	}
7481c59a5c48SFrançois Tigeot 
7482c59a5c48SFrançois Tigeot 	return 0;
7483c59a5c48SFrançois Tigeot }
7484c59a5c48SFrançois Tigeot 
si_set_vce_clocks(struct radeon_device * rdev,u32 evclk,u32 ecclk)7485c59a5c48SFrançois Tigeot int si_set_vce_clocks(struct radeon_device *rdev, u32 evclk, u32 ecclk)
7486c59a5c48SFrançois Tigeot {
7487c59a5c48SFrançois Tigeot 	unsigned fb_div = 0, evclk_div = 0, ecclk_div = 0;
7488c59a5c48SFrançois Tigeot 	int r;
7489c59a5c48SFrançois Tigeot 
7490c59a5c48SFrançois Tigeot 	/* bypass evclk and ecclk with bclk */
7491c59a5c48SFrançois Tigeot 	WREG32_SMC_P(CG_VCEPLL_FUNC_CNTL_2,
7492c59a5c48SFrançois Tigeot 		     EVCLK_SRC_SEL(1) | ECCLK_SRC_SEL(1),
7493c59a5c48SFrançois Tigeot 		     ~(EVCLK_SRC_SEL_MASK | ECCLK_SRC_SEL_MASK));
7494c59a5c48SFrançois Tigeot 
7495c59a5c48SFrançois Tigeot 	/* put PLL in bypass mode */
7496c59a5c48SFrançois Tigeot 	WREG32_SMC_P(CG_VCEPLL_FUNC_CNTL, VCEPLL_BYPASS_EN_MASK,
7497c59a5c48SFrançois Tigeot 		     ~VCEPLL_BYPASS_EN_MASK);
7498c59a5c48SFrançois Tigeot 
7499c59a5c48SFrançois Tigeot 	if (!evclk || !ecclk) {
7500c59a5c48SFrançois Tigeot 		/* keep the Bypass mode, put PLL to sleep */
7501c59a5c48SFrançois Tigeot 		WREG32_SMC_P(CG_VCEPLL_FUNC_CNTL, VCEPLL_SLEEP_MASK,
7502c59a5c48SFrançois Tigeot 			     ~VCEPLL_SLEEP_MASK);
7503c59a5c48SFrançois Tigeot 		return 0;
7504c59a5c48SFrançois Tigeot 	}
7505c59a5c48SFrançois Tigeot 
7506c59a5c48SFrançois Tigeot 	r = radeon_uvd_calc_upll_dividers(rdev, evclk, ecclk, 125000, 250000,
7507c59a5c48SFrançois Tigeot 					  16384, 0x03FFFFFF, 0, 128, 5,
7508c59a5c48SFrançois Tigeot 					  &fb_div, &evclk_div, &ecclk_div);
7509c59a5c48SFrançois Tigeot 	if (r)
7510c59a5c48SFrançois Tigeot 		return r;
7511c59a5c48SFrançois Tigeot 
7512c59a5c48SFrançois Tigeot 	/* set RESET_ANTI_MUX to 0 */
7513c59a5c48SFrançois Tigeot 	WREG32_SMC_P(CG_VCEPLL_FUNC_CNTL_5, 0, ~RESET_ANTI_MUX_MASK);
7514c59a5c48SFrançois Tigeot 
7515c59a5c48SFrançois Tigeot 	/* set VCO_MODE to 1 */
7516c59a5c48SFrançois Tigeot 	WREG32_SMC_P(CG_VCEPLL_FUNC_CNTL, VCEPLL_VCO_MODE_MASK,
7517c59a5c48SFrançois Tigeot 		     ~VCEPLL_VCO_MODE_MASK);
7518c59a5c48SFrançois Tigeot 
7519c59a5c48SFrançois Tigeot 	/* toggle VCEPLL_SLEEP to 1 then back to 0 */
7520c59a5c48SFrançois Tigeot 	WREG32_SMC_P(CG_VCEPLL_FUNC_CNTL, VCEPLL_SLEEP_MASK,
7521c59a5c48SFrançois Tigeot 		     ~VCEPLL_SLEEP_MASK);
7522c59a5c48SFrançois Tigeot 	WREG32_SMC_P(CG_VCEPLL_FUNC_CNTL, 0, ~VCEPLL_SLEEP_MASK);
7523c59a5c48SFrançois Tigeot 
7524c59a5c48SFrançois Tigeot 	/* deassert VCEPLL_RESET */
7525c59a5c48SFrançois Tigeot 	WREG32_SMC_P(CG_VCEPLL_FUNC_CNTL, 0, ~VCEPLL_RESET_MASK);
7526c59a5c48SFrançois Tigeot 
7527c59a5c48SFrançois Tigeot 	mdelay(1);
7528c59a5c48SFrançois Tigeot 
7529c59a5c48SFrançois Tigeot 	r = si_vce_send_vcepll_ctlreq(rdev);
7530c59a5c48SFrançois Tigeot 	if (r)
7531c59a5c48SFrançois Tigeot 		return r;
7532c59a5c48SFrançois Tigeot 
7533c59a5c48SFrançois Tigeot 	/* assert VCEPLL_RESET again */
7534c59a5c48SFrançois Tigeot 	WREG32_SMC_P(CG_VCEPLL_FUNC_CNTL, VCEPLL_RESET_MASK, ~VCEPLL_RESET_MASK);
7535c59a5c48SFrançois Tigeot 
7536c59a5c48SFrançois Tigeot 	/* disable spread spectrum. */
7537c59a5c48SFrançois Tigeot 	WREG32_SMC_P(CG_VCEPLL_SPREAD_SPECTRUM, 0, ~SSEN_MASK);
7538c59a5c48SFrançois Tigeot 
7539c59a5c48SFrançois Tigeot 	/* set feedback divider */
7540c59a5c48SFrançois Tigeot 	WREG32_SMC_P(CG_VCEPLL_FUNC_CNTL_3, VCEPLL_FB_DIV(fb_div), ~VCEPLL_FB_DIV_MASK);
7541c59a5c48SFrançois Tigeot 
7542c59a5c48SFrançois Tigeot 	/* set ref divider to 0 */
7543c59a5c48SFrançois Tigeot 	WREG32_SMC_P(CG_VCEPLL_FUNC_CNTL, 0, ~VCEPLL_REF_DIV_MASK);
7544c59a5c48SFrançois Tigeot 
7545c59a5c48SFrançois Tigeot 	/* set PDIV_A and PDIV_B */
7546c59a5c48SFrançois Tigeot 	WREG32_SMC_P(CG_VCEPLL_FUNC_CNTL_2,
7547c59a5c48SFrançois Tigeot 		     VCEPLL_PDIV_A(evclk_div) | VCEPLL_PDIV_B(ecclk_div),
7548c59a5c48SFrançois Tigeot 		     ~(VCEPLL_PDIV_A_MASK | VCEPLL_PDIV_B_MASK));
7549c59a5c48SFrançois Tigeot 
7550c59a5c48SFrançois Tigeot 	/* give the PLL some time to settle */
7551c59a5c48SFrançois Tigeot 	mdelay(15);
7552c59a5c48SFrançois Tigeot 
7553c59a5c48SFrançois Tigeot 	/* deassert PLL_RESET */
7554c59a5c48SFrançois Tigeot 	WREG32_SMC_P(CG_VCEPLL_FUNC_CNTL, 0, ~VCEPLL_RESET_MASK);
7555c59a5c48SFrançois Tigeot 
7556c59a5c48SFrançois Tigeot 	mdelay(15);
7557c59a5c48SFrançois Tigeot 
7558c59a5c48SFrançois Tigeot 	/* switch from bypass mode to normal mode */
7559c59a5c48SFrançois Tigeot 	WREG32_SMC_P(CG_VCEPLL_FUNC_CNTL, 0, ~VCEPLL_BYPASS_EN_MASK);
7560c59a5c48SFrançois Tigeot 
7561c59a5c48SFrançois Tigeot 	r = si_vce_send_vcepll_ctlreq(rdev);
7562c59a5c48SFrançois Tigeot 	if (r)
7563c59a5c48SFrançois Tigeot 		return r;
7564c59a5c48SFrançois Tigeot 
7565c59a5c48SFrançois Tigeot 	/* switch VCLK and DCLK selection */
7566c59a5c48SFrançois Tigeot 	WREG32_SMC_P(CG_VCEPLL_FUNC_CNTL_2,
7567c59a5c48SFrançois Tigeot 		     EVCLK_SRC_SEL(16) | ECCLK_SRC_SEL(16),
7568c59a5c48SFrançois Tigeot 		     ~(EVCLK_SRC_SEL_MASK | ECCLK_SRC_SEL_MASK));
7569c59a5c48SFrançois Tigeot 
7570c59a5c48SFrançois Tigeot 	mdelay(100);
7571c59a5c48SFrançois Tigeot 
7572c59a5c48SFrançois Tigeot 	return 0;
7573c59a5c48SFrançois Tigeot }
7574