xref: /openbmc/linux/drivers/gpu/drm/radeon/evergreen.c (revision ecc23d0a422a3118fcf6e4f0a46e17a6c2047b02)
1bcc1c2a1SAlex Deucher /*
2bcc1c2a1SAlex Deucher  * Copyright 2010 Advanced Micro Devices, Inc.
3bcc1c2a1SAlex Deucher  *
4bcc1c2a1SAlex Deucher  * Permission is hereby granted, free of charge, to any person obtaining a
5bcc1c2a1SAlex Deucher  * copy of this software and associated documentation files (the "Software"),
6bcc1c2a1SAlex Deucher  * to deal in the Software without restriction, including without limitation
7bcc1c2a1SAlex Deucher  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8bcc1c2a1SAlex Deucher  * and/or sell copies of the Software, and to permit persons to whom the
9bcc1c2a1SAlex Deucher  * Software is furnished to do so, subject to the following conditions:
10bcc1c2a1SAlex Deucher  *
11bcc1c2a1SAlex Deucher  * The above copyright notice and this permission notice shall be included in
12bcc1c2a1SAlex Deucher  * all copies or substantial portions of the Software.
13bcc1c2a1SAlex Deucher  *
14bcc1c2a1SAlex Deucher  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15bcc1c2a1SAlex Deucher  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16bcc1c2a1SAlex Deucher  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
17bcc1c2a1SAlex Deucher  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18bcc1c2a1SAlex Deucher  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19bcc1c2a1SAlex Deucher  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20bcc1c2a1SAlex Deucher  * OTHER DEALINGS IN THE SOFTWARE.
21bcc1c2a1SAlex Deucher  *
22bcc1c2a1SAlex Deucher  * Authors: Alex Deucher
23bcc1c2a1SAlex Deucher  */
24c182615fSSam Ravnborg 
25bcc1c2a1SAlex Deucher #include <linux/firmware.h>
262ef79416SThomas Zimmermann #include <linux/pci.h>
275a0e3ad6STejun Heo #include <linux/slab.h>
28c182615fSSam Ravnborg 
29c182615fSSam Ravnborg #include <drm/drm_vblank.h>
30c182615fSSam Ravnborg #include <drm/radeon_drm.h>
31c841e552SZhenneng Li #include <drm/drm_fourcc.h>
32720cf96dSVille Syrjälä #include <drm/drm_framebuffer.h>
33c182615fSSam Ravnborg 
34c182615fSSam Ravnborg #include "atom.h"
35c182615fSSam Ravnborg #include "avivod.h"
36c580cfc9SLee Jones #include "cik.h"
37ef072392SLee Jones #include "ni.h"
38a9f9851fSLee Jones #include "rv770.h"
394fe1999eSLee Jones #include "evergreen.h"
40c182615fSSam Ravnborg #include "evergreen_blit_shaders.h"
41c182615fSSam Ravnborg #include "evergreen_reg.h"
42c182615fSSam Ravnborg #include "evergreend.h"
43bcc1c2a1SAlex Deucher #include "radeon.h"
44e6990375SDaniel Vetter #include "radeon_asic.h"
45bfc1f97dSSlava Grigorev #include "radeon_audio.h"
46138e4e16SAlex Deucher #include "radeon_ucode.h"
47f47a9d09SLee Jones #include "si.h"
48fe251e2fSAlex Deucher 
494cd096ddSLyude #define DC_HPDx_CONTROL(x)        (DC_HPD1_CONTROL     + (x * 0xc))
504cd096ddSLyude #define DC_HPDx_INT_CONTROL(x)    (DC_HPD1_INT_CONTROL + (x * 0xc))
514cd096ddSLyude #define DC_HPDx_INT_STATUS_REG(x) (DC_HPD1_INT_STATUS  + (x * 0xc))
524cd096ddSLyude 
539e5acbc2SDenys Vlasenko /*
549e5acbc2SDenys Vlasenko  * Indirect registers accessor
559e5acbc2SDenys Vlasenko  */
eg_cg_rreg(struct radeon_device * rdev,u32 reg)569e5acbc2SDenys Vlasenko u32 eg_cg_rreg(struct radeon_device *rdev, u32 reg)
579e5acbc2SDenys Vlasenko {
589e5acbc2SDenys Vlasenko 	unsigned long flags;
599e5acbc2SDenys Vlasenko 	u32 r;
609e5acbc2SDenys Vlasenko 
619e5acbc2SDenys Vlasenko 	spin_lock_irqsave(&rdev->cg_idx_lock, flags);
629e5acbc2SDenys Vlasenko 	WREG32(EVERGREEN_CG_IND_ADDR, ((reg) & 0xffff));
639e5acbc2SDenys Vlasenko 	r = RREG32(EVERGREEN_CG_IND_DATA);
649e5acbc2SDenys Vlasenko 	spin_unlock_irqrestore(&rdev->cg_idx_lock, flags);
659e5acbc2SDenys Vlasenko 	return r;
669e5acbc2SDenys Vlasenko }
679e5acbc2SDenys Vlasenko 
eg_cg_wreg(struct radeon_device * rdev,u32 reg,u32 v)689e5acbc2SDenys Vlasenko void eg_cg_wreg(struct radeon_device *rdev, u32 reg, u32 v)
699e5acbc2SDenys Vlasenko {
709e5acbc2SDenys Vlasenko 	unsigned long flags;
719e5acbc2SDenys Vlasenko 
729e5acbc2SDenys Vlasenko 	spin_lock_irqsave(&rdev->cg_idx_lock, flags);
739e5acbc2SDenys Vlasenko 	WREG32(EVERGREEN_CG_IND_ADDR, ((reg) & 0xffff));
749e5acbc2SDenys Vlasenko 	WREG32(EVERGREEN_CG_IND_DATA, (v));
759e5acbc2SDenys Vlasenko 	spin_unlock_irqrestore(&rdev->cg_idx_lock, flags);
769e5acbc2SDenys Vlasenko }
779e5acbc2SDenys Vlasenko 
eg_pif_phy0_rreg(struct radeon_device * rdev,u32 reg)789e5acbc2SDenys Vlasenko u32 eg_pif_phy0_rreg(struct radeon_device *rdev, u32 reg)
799e5acbc2SDenys Vlasenko {
809e5acbc2SDenys Vlasenko 	unsigned long flags;
819e5acbc2SDenys Vlasenko 	u32 r;
829e5acbc2SDenys Vlasenko 
839e5acbc2SDenys Vlasenko 	spin_lock_irqsave(&rdev->pif_idx_lock, flags);
849e5acbc2SDenys Vlasenko 	WREG32(EVERGREEN_PIF_PHY0_INDEX, ((reg) & 0xffff));
859e5acbc2SDenys Vlasenko 	r = RREG32(EVERGREEN_PIF_PHY0_DATA);
869e5acbc2SDenys Vlasenko 	spin_unlock_irqrestore(&rdev->pif_idx_lock, flags);
879e5acbc2SDenys Vlasenko 	return r;
889e5acbc2SDenys Vlasenko }
899e5acbc2SDenys Vlasenko 
eg_pif_phy0_wreg(struct radeon_device * rdev,u32 reg,u32 v)909e5acbc2SDenys Vlasenko void eg_pif_phy0_wreg(struct radeon_device *rdev, u32 reg, u32 v)
919e5acbc2SDenys Vlasenko {
929e5acbc2SDenys Vlasenko 	unsigned long flags;
939e5acbc2SDenys Vlasenko 
949e5acbc2SDenys Vlasenko 	spin_lock_irqsave(&rdev->pif_idx_lock, flags);
959e5acbc2SDenys Vlasenko 	WREG32(EVERGREEN_PIF_PHY0_INDEX, ((reg) & 0xffff));
969e5acbc2SDenys Vlasenko 	WREG32(EVERGREEN_PIF_PHY0_DATA, (v));
979e5acbc2SDenys Vlasenko 	spin_unlock_irqrestore(&rdev->pif_idx_lock, flags);
989e5acbc2SDenys Vlasenko }
999e5acbc2SDenys Vlasenko 
eg_pif_phy1_rreg(struct radeon_device * rdev,u32 reg)1009e5acbc2SDenys Vlasenko u32 eg_pif_phy1_rreg(struct radeon_device *rdev, u32 reg)
1019e5acbc2SDenys Vlasenko {
1029e5acbc2SDenys Vlasenko 	unsigned long flags;
1039e5acbc2SDenys Vlasenko 	u32 r;
1049e5acbc2SDenys Vlasenko 
1059e5acbc2SDenys Vlasenko 	spin_lock_irqsave(&rdev->pif_idx_lock, flags);
1069e5acbc2SDenys Vlasenko 	WREG32(EVERGREEN_PIF_PHY1_INDEX, ((reg) & 0xffff));
1079e5acbc2SDenys Vlasenko 	r = RREG32(EVERGREEN_PIF_PHY1_DATA);
1089e5acbc2SDenys Vlasenko 	spin_unlock_irqrestore(&rdev->pif_idx_lock, flags);
1099e5acbc2SDenys Vlasenko 	return r;
1109e5acbc2SDenys Vlasenko }
1119e5acbc2SDenys Vlasenko 
eg_pif_phy1_wreg(struct radeon_device * rdev,u32 reg,u32 v)1129e5acbc2SDenys Vlasenko void eg_pif_phy1_wreg(struct radeon_device *rdev, u32 reg, u32 v)
1139e5acbc2SDenys Vlasenko {
1149e5acbc2SDenys Vlasenko 	unsigned long flags;
1159e5acbc2SDenys Vlasenko 
1169e5acbc2SDenys Vlasenko 	spin_lock_irqsave(&rdev->pif_idx_lock, flags);
1179e5acbc2SDenys Vlasenko 	WREG32(EVERGREEN_PIF_PHY1_INDEX, ((reg) & 0xffff));
1189e5acbc2SDenys Vlasenko 	WREG32(EVERGREEN_PIF_PHY1_DATA, (v));
1199e5acbc2SDenys Vlasenko 	spin_unlock_irqrestore(&rdev->pif_idx_lock, flags);
1209e5acbc2SDenys Vlasenko }
1219e5acbc2SDenys Vlasenko 
1224a15903dSAlex Deucher static const u32 crtc_offsets[6] =
1234a15903dSAlex Deucher {
1244a15903dSAlex Deucher 	EVERGREEN_CRTC0_REGISTER_OFFSET,
1254a15903dSAlex Deucher 	EVERGREEN_CRTC1_REGISTER_OFFSET,
1264a15903dSAlex Deucher 	EVERGREEN_CRTC2_REGISTER_OFFSET,
1274a15903dSAlex Deucher 	EVERGREEN_CRTC3_REGISTER_OFFSET,
1284a15903dSAlex Deucher 	EVERGREEN_CRTC4_REGISTER_OFFSET,
1294a15903dSAlex Deucher 	EVERGREEN_CRTC5_REGISTER_OFFSET
1304a15903dSAlex Deucher };
1314a15903dSAlex Deucher 
1322948f5e6SAlex Deucher #include "clearstate_evergreen.h"
1332948f5e6SAlex Deucher 
1341fd11777SAlex Deucher static const u32 sumo_rlc_save_restore_register_list[] =
1352948f5e6SAlex Deucher {
1362948f5e6SAlex Deucher 	0x98fc,
1372948f5e6SAlex Deucher 	0x9830,
1382948f5e6SAlex Deucher 	0x9834,
1392948f5e6SAlex Deucher 	0x9838,
1402948f5e6SAlex Deucher 	0x9870,
1412948f5e6SAlex Deucher 	0x9874,
1422948f5e6SAlex Deucher 	0x8a14,
1432948f5e6SAlex Deucher 	0x8b24,
1442948f5e6SAlex Deucher 	0x8bcc,
1452948f5e6SAlex Deucher 	0x8b10,
1462948f5e6SAlex Deucher 	0x8d00,
1472948f5e6SAlex Deucher 	0x8d04,
1482948f5e6SAlex Deucher 	0x8c00,
1492948f5e6SAlex Deucher 	0x8c04,
1502948f5e6SAlex Deucher 	0x8c08,
1512948f5e6SAlex Deucher 	0x8c0c,
1522948f5e6SAlex Deucher 	0x8d8c,
1532948f5e6SAlex Deucher 	0x8c20,
1542948f5e6SAlex Deucher 	0x8c24,
1552948f5e6SAlex Deucher 	0x8c28,
1562948f5e6SAlex Deucher 	0x8c18,
1572948f5e6SAlex Deucher 	0x8c1c,
1582948f5e6SAlex Deucher 	0x8cf0,
1592948f5e6SAlex Deucher 	0x8e2c,
1602948f5e6SAlex Deucher 	0x8e38,
1612948f5e6SAlex Deucher 	0x8c30,
1622948f5e6SAlex Deucher 	0x9508,
1632948f5e6SAlex Deucher 	0x9688,
1642948f5e6SAlex Deucher 	0x9608,
1652948f5e6SAlex Deucher 	0x960c,
1662948f5e6SAlex Deucher 	0x9610,
1672948f5e6SAlex Deucher 	0x9614,
1682948f5e6SAlex Deucher 	0x88c4,
1692948f5e6SAlex Deucher 	0x88d4,
1702948f5e6SAlex Deucher 	0xa008,
1712948f5e6SAlex Deucher 	0x900c,
1722948f5e6SAlex Deucher 	0x9100,
1732948f5e6SAlex Deucher 	0x913c,
1742948f5e6SAlex Deucher 	0x98f8,
1752948f5e6SAlex Deucher 	0x98f4,
1762948f5e6SAlex Deucher 	0x9b7c,
1772948f5e6SAlex Deucher 	0x3f8c,
1782948f5e6SAlex Deucher 	0x8950,
1792948f5e6SAlex Deucher 	0x8954,
1802948f5e6SAlex Deucher 	0x8a18,
1812948f5e6SAlex Deucher 	0x8b28,
1822948f5e6SAlex Deucher 	0x9144,
1832948f5e6SAlex Deucher 	0x9148,
1842948f5e6SAlex Deucher 	0x914c,
1852948f5e6SAlex Deucher 	0x3f90,
1862948f5e6SAlex Deucher 	0x3f94,
1872948f5e6SAlex Deucher 	0x915c,
1882948f5e6SAlex Deucher 	0x9160,
1892948f5e6SAlex Deucher 	0x9178,
1902948f5e6SAlex Deucher 	0x917c,
1912948f5e6SAlex Deucher 	0x9180,
1922948f5e6SAlex Deucher 	0x918c,
1932948f5e6SAlex Deucher 	0x9190,
1942948f5e6SAlex Deucher 	0x9194,
1952948f5e6SAlex Deucher 	0x9198,
1962948f5e6SAlex Deucher 	0x919c,
1972948f5e6SAlex Deucher 	0x91a8,
1982948f5e6SAlex Deucher 	0x91ac,
1992948f5e6SAlex Deucher 	0x91b0,
2002948f5e6SAlex Deucher 	0x91b4,
2012948f5e6SAlex Deucher 	0x91b8,
2022948f5e6SAlex Deucher 	0x91c4,
2032948f5e6SAlex Deucher 	0x91c8,
2042948f5e6SAlex Deucher 	0x91cc,
2052948f5e6SAlex Deucher 	0x91d0,
2062948f5e6SAlex Deucher 	0x91d4,
2072948f5e6SAlex Deucher 	0x91e0,
2082948f5e6SAlex Deucher 	0x91e4,
2092948f5e6SAlex Deucher 	0x91ec,
2102948f5e6SAlex Deucher 	0x91f0,
2112948f5e6SAlex Deucher 	0x91f4,
2122948f5e6SAlex Deucher 	0x9200,
2132948f5e6SAlex Deucher 	0x9204,
2142948f5e6SAlex Deucher 	0x929c,
2152948f5e6SAlex Deucher 	0x9150,
2162948f5e6SAlex Deucher 	0x802c,
2172948f5e6SAlex Deucher };
2182948f5e6SAlex Deucher 
219bcc1c2a1SAlex Deucher static void evergreen_gpu_init(struct radeon_device *rdev);
220bcc1c2a1SAlex Deucher void evergreen_fini(struct radeon_device *rdev);
221b07759bfSIlija Hadzic void evergreen_pcie_gen2_enable(struct radeon_device *rdev);
222f52382d7SAlex Deucher void evergreen_program_aspm(struct radeon_device *rdev);
223bcc1c2a1SAlex Deucher 
224d4788db3SAlex Deucher static const u32 evergreen_golden_registers[] =
225d4788db3SAlex Deucher {
226d4788db3SAlex Deucher 	0x3f90, 0xffff0000, 0xff000000,
227d4788db3SAlex Deucher 	0x9148, 0xffff0000, 0xff000000,
228d4788db3SAlex Deucher 	0x3f94, 0xffff0000, 0xff000000,
229d4788db3SAlex Deucher 	0x914c, 0xffff0000, 0xff000000,
230d4788db3SAlex Deucher 	0x9b7c, 0xffffffff, 0x00000000,
231d4788db3SAlex Deucher 	0x8a14, 0xffffffff, 0x00000007,
232d4788db3SAlex Deucher 	0x8b10, 0xffffffff, 0x00000000,
233d4788db3SAlex Deucher 	0x960c, 0xffffffff, 0x54763210,
234d4788db3SAlex Deucher 	0x88c4, 0xffffffff, 0x000000c2,
235d4788db3SAlex Deucher 	0x88d4, 0xffffffff, 0x00000010,
236d4788db3SAlex Deucher 	0x8974, 0xffffffff, 0x00000000,
237d4788db3SAlex Deucher 	0xc78, 0x00000080, 0x00000080,
238d4788db3SAlex Deucher 	0x5eb4, 0xffffffff, 0x00000002,
239d4788db3SAlex Deucher 	0x5e78, 0xffffffff, 0x001000f0,
240d4788db3SAlex Deucher 	0x6104, 0x01000300, 0x00000000,
241d4788db3SAlex Deucher 	0x5bc0, 0x00300000, 0x00000000,
242d4788db3SAlex Deucher 	0x7030, 0xffffffff, 0x00000011,
243d4788db3SAlex Deucher 	0x7c30, 0xffffffff, 0x00000011,
244d4788db3SAlex Deucher 	0x10830, 0xffffffff, 0x00000011,
245d4788db3SAlex Deucher 	0x11430, 0xffffffff, 0x00000011,
246d4788db3SAlex Deucher 	0x12030, 0xffffffff, 0x00000011,
247d4788db3SAlex Deucher 	0x12c30, 0xffffffff, 0x00000011,
248d4788db3SAlex Deucher 	0xd02c, 0xffffffff, 0x08421000,
249d4788db3SAlex Deucher 	0x240c, 0xffffffff, 0x00000380,
250d4788db3SAlex Deucher 	0x8b24, 0xffffffff, 0x00ff0fff,
251d4788db3SAlex Deucher 	0x28a4c, 0x06000000, 0x06000000,
252d4788db3SAlex Deucher 	0x10c, 0x00000001, 0x00000001,
253d4788db3SAlex Deucher 	0x8d00, 0xffffffff, 0x100e4848,
254d4788db3SAlex Deucher 	0x8d04, 0xffffffff, 0x00164745,
255d4788db3SAlex Deucher 	0x8c00, 0xffffffff, 0xe4000003,
256d4788db3SAlex Deucher 	0x8c04, 0xffffffff, 0x40600060,
257d4788db3SAlex Deucher 	0x8c08, 0xffffffff, 0x001c001c,
258d4788db3SAlex Deucher 	0x8cf0, 0xffffffff, 0x08e00620,
259d4788db3SAlex Deucher 	0x8c20, 0xffffffff, 0x00800080,
260d4788db3SAlex Deucher 	0x8c24, 0xffffffff, 0x00800080,
261d4788db3SAlex Deucher 	0x8c18, 0xffffffff, 0x20202078,
262d4788db3SAlex Deucher 	0x8c1c, 0xffffffff, 0x00001010,
263d4788db3SAlex Deucher 	0x28350, 0xffffffff, 0x00000000,
264d4788db3SAlex Deucher 	0xa008, 0xffffffff, 0x00010000,
2656abafb78SAlex Deucher 	0x5c4, 0xffffffff, 0x00000001,
266d4788db3SAlex Deucher 	0x9508, 0xffffffff, 0x00000002,
267d4788db3SAlex Deucher 	0x913c, 0x0000000f, 0x0000000a
268d4788db3SAlex Deucher };
269d4788db3SAlex Deucher 
270d4788db3SAlex Deucher static const u32 evergreen_golden_registers2[] =
271d4788db3SAlex Deucher {
272d4788db3SAlex Deucher 	0x2f4c, 0xffffffff, 0x00000000,
273d4788db3SAlex Deucher 	0x54f4, 0xffffffff, 0x00000000,
274d4788db3SAlex Deucher 	0x54f0, 0xffffffff, 0x00000000,
275d4788db3SAlex Deucher 	0x5498, 0xffffffff, 0x00000000,
276d4788db3SAlex Deucher 	0x549c, 0xffffffff, 0x00000000,
277d4788db3SAlex Deucher 	0x5494, 0xffffffff, 0x00000000,
278d4788db3SAlex Deucher 	0x53cc, 0xffffffff, 0x00000000,
279d4788db3SAlex Deucher 	0x53c8, 0xffffffff, 0x00000000,
280d4788db3SAlex Deucher 	0x53c4, 0xffffffff, 0x00000000,
281d4788db3SAlex Deucher 	0x53c0, 0xffffffff, 0x00000000,
282d4788db3SAlex Deucher 	0x53bc, 0xffffffff, 0x00000000,
283d4788db3SAlex Deucher 	0x53b8, 0xffffffff, 0x00000000,
284d4788db3SAlex Deucher 	0x53b4, 0xffffffff, 0x00000000,
285d4788db3SAlex Deucher 	0x53b0, 0xffffffff, 0x00000000
286d4788db3SAlex Deucher };
287d4788db3SAlex Deucher 
288d4788db3SAlex Deucher static const u32 cypress_mgcg_init[] =
289d4788db3SAlex Deucher {
290d4788db3SAlex Deucher 	0x802c, 0xffffffff, 0xc0000000,
291d4788db3SAlex Deucher 	0x5448, 0xffffffff, 0x00000100,
292d4788db3SAlex Deucher 	0x55e4, 0xffffffff, 0x00000100,
293d4788db3SAlex Deucher 	0x160c, 0xffffffff, 0x00000100,
294d4788db3SAlex Deucher 	0x5644, 0xffffffff, 0x00000100,
295d4788db3SAlex Deucher 	0xc164, 0xffffffff, 0x00000100,
296d4788db3SAlex Deucher 	0x8a18, 0xffffffff, 0x00000100,
297d4788db3SAlex Deucher 	0x897c, 0xffffffff, 0x06000100,
298d4788db3SAlex Deucher 	0x8b28, 0xffffffff, 0x00000100,
299d4788db3SAlex Deucher 	0x9144, 0xffffffff, 0x00000100,
300d4788db3SAlex Deucher 	0x9a60, 0xffffffff, 0x00000100,
301d4788db3SAlex Deucher 	0x9868, 0xffffffff, 0x00000100,
302d4788db3SAlex Deucher 	0x8d58, 0xffffffff, 0x00000100,
303d4788db3SAlex Deucher 	0x9510, 0xffffffff, 0x00000100,
304d4788db3SAlex Deucher 	0x949c, 0xffffffff, 0x00000100,
305d4788db3SAlex Deucher 	0x9654, 0xffffffff, 0x00000100,
306d4788db3SAlex Deucher 	0x9030, 0xffffffff, 0x00000100,
307d4788db3SAlex Deucher 	0x9034, 0xffffffff, 0x00000100,
308d4788db3SAlex Deucher 	0x9038, 0xffffffff, 0x00000100,
309d4788db3SAlex Deucher 	0x903c, 0xffffffff, 0x00000100,
310d4788db3SAlex Deucher 	0x9040, 0xffffffff, 0x00000100,
311d4788db3SAlex Deucher 	0xa200, 0xffffffff, 0x00000100,
312d4788db3SAlex Deucher 	0xa204, 0xffffffff, 0x00000100,
313d4788db3SAlex Deucher 	0xa208, 0xffffffff, 0x00000100,
314d4788db3SAlex Deucher 	0xa20c, 0xffffffff, 0x00000100,
315d4788db3SAlex Deucher 	0x971c, 0xffffffff, 0x00000100,
316d4788db3SAlex Deucher 	0x977c, 0xffffffff, 0x00000100,
317d4788db3SAlex Deucher 	0x3f80, 0xffffffff, 0x00000100,
318d4788db3SAlex Deucher 	0xa210, 0xffffffff, 0x00000100,
319d4788db3SAlex Deucher 	0xa214, 0xffffffff, 0x00000100,
320d4788db3SAlex Deucher 	0x4d8, 0xffffffff, 0x00000100,
321d4788db3SAlex Deucher 	0x9784, 0xffffffff, 0x00000100,
322d4788db3SAlex Deucher 	0x9698, 0xffffffff, 0x00000100,
323d4788db3SAlex Deucher 	0x4d4, 0xffffffff, 0x00000200,
324d4788db3SAlex Deucher 	0x30cc, 0xffffffff, 0x00000100,
325d4788db3SAlex Deucher 	0xd0c0, 0xffffffff, 0xff000100,
326d4788db3SAlex Deucher 	0x802c, 0xffffffff, 0x40000000,
327d4788db3SAlex Deucher 	0x915c, 0xffffffff, 0x00010000,
328d4788db3SAlex Deucher 	0x9160, 0xffffffff, 0x00030002,
329d4788db3SAlex Deucher 	0x9178, 0xffffffff, 0x00070000,
330d4788db3SAlex Deucher 	0x917c, 0xffffffff, 0x00030002,
331d4788db3SAlex Deucher 	0x9180, 0xffffffff, 0x00050004,
332d4788db3SAlex Deucher 	0x918c, 0xffffffff, 0x00010006,
333d4788db3SAlex Deucher 	0x9190, 0xffffffff, 0x00090008,
334d4788db3SAlex Deucher 	0x9194, 0xffffffff, 0x00070000,
335d4788db3SAlex Deucher 	0x9198, 0xffffffff, 0x00030002,
336d4788db3SAlex Deucher 	0x919c, 0xffffffff, 0x00050004,
337d4788db3SAlex Deucher 	0x91a8, 0xffffffff, 0x00010006,
338d4788db3SAlex Deucher 	0x91ac, 0xffffffff, 0x00090008,
339d4788db3SAlex Deucher 	0x91b0, 0xffffffff, 0x00070000,
340d4788db3SAlex Deucher 	0x91b4, 0xffffffff, 0x00030002,
341d4788db3SAlex Deucher 	0x91b8, 0xffffffff, 0x00050004,
342d4788db3SAlex Deucher 	0x91c4, 0xffffffff, 0x00010006,
343d4788db3SAlex Deucher 	0x91c8, 0xffffffff, 0x00090008,
344d4788db3SAlex Deucher 	0x91cc, 0xffffffff, 0x00070000,
345d4788db3SAlex Deucher 	0x91d0, 0xffffffff, 0x00030002,
346d4788db3SAlex Deucher 	0x91d4, 0xffffffff, 0x00050004,
347d4788db3SAlex Deucher 	0x91e0, 0xffffffff, 0x00010006,
348d4788db3SAlex Deucher 	0x91e4, 0xffffffff, 0x00090008,
349d4788db3SAlex Deucher 	0x91e8, 0xffffffff, 0x00000000,
350d4788db3SAlex Deucher 	0x91ec, 0xffffffff, 0x00070000,
351d4788db3SAlex Deucher 	0x91f0, 0xffffffff, 0x00030002,
352d4788db3SAlex Deucher 	0x91f4, 0xffffffff, 0x00050004,
353d4788db3SAlex Deucher 	0x9200, 0xffffffff, 0x00010006,
354d4788db3SAlex Deucher 	0x9204, 0xffffffff, 0x00090008,
355d4788db3SAlex Deucher 	0x9208, 0xffffffff, 0x00070000,
356d4788db3SAlex Deucher 	0x920c, 0xffffffff, 0x00030002,
357d4788db3SAlex Deucher 	0x9210, 0xffffffff, 0x00050004,
358d4788db3SAlex Deucher 	0x921c, 0xffffffff, 0x00010006,
359d4788db3SAlex Deucher 	0x9220, 0xffffffff, 0x00090008,
360d4788db3SAlex Deucher 	0x9224, 0xffffffff, 0x00070000,
361d4788db3SAlex Deucher 	0x9228, 0xffffffff, 0x00030002,
362d4788db3SAlex Deucher 	0x922c, 0xffffffff, 0x00050004,
363d4788db3SAlex Deucher 	0x9238, 0xffffffff, 0x00010006,
364d4788db3SAlex Deucher 	0x923c, 0xffffffff, 0x00090008,
365d4788db3SAlex Deucher 	0x9240, 0xffffffff, 0x00070000,
366d4788db3SAlex Deucher 	0x9244, 0xffffffff, 0x00030002,
367d4788db3SAlex Deucher 	0x9248, 0xffffffff, 0x00050004,
368d4788db3SAlex Deucher 	0x9254, 0xffffffff, 0x00010006,
369d4788db3SAlex Deucher 	0x9258, 0xffffffff, 0x00090008,
370d4788db3SAlex Deucher 	0x925c, 0xffffffff, 0x00070000,
371d4788db3SAlex Deucher 	0x9260, 0xffffffff, 0x00030002,
372d4788db3SAlex Deucher 	0x9264, 0xffffffff, 0x00050004,
373d4788db3SAlex Deucher 	0x9270, 0xffffffff, 0x00010006,
374d4788db3SAlex Deucher 	0x9274, 0xffffffff, 0x00090008,
375d4788db3SAlex Deucher 	0x9278, 0xffffffff, 0x00070000,
376d4788db3SAlex Deucher 	0x927c, 0xffffffff, 0x00030002,
377d4788db3SAlex Deucher 	0x9280, 0xffffffff, 0x00050004,
378d4788db3SAlex Deucher 	0x928c, 0xffffffff, 0x00010006,
379d4788db3SAlex Deucher 	0x9290, 0xffffffff, 0x00090008,
380d4788db3SAlex Deucher 	0x9294, 0xffffffff, 0x00000000,
381d4788db3SAlex Deucher 	0x929c, 0xffffffff, 0x00000001,
382d4788db3SAlex Deucher 	0x802c, 0xffffffff, 0x40010000,
383d4788db3SAlex Deucher 	0x915c, 0xffffffff, 0x00010000,
384d4788db3SAlex Deucher 	0x9160, 0xffffffff, 0x00030002,
385d4788db3SAlex Deucher 	0x9178, 0xffffffff, 0x00070000,
386d4788db3SAlex Deucher 	0x917c, 0xffffffff, 0x00030002,
387d4788db3SAlex Deucher 	0x9180, 0xffffffff, 0x00050004,
388d4788db3SAlex Deucher 	0x918c, 0xffffffff, 0x00010006,
389d4788db3SAlex Deucher 	0x9190, 0xffffffff, 0x00090008,
390d4788db3SAlex Deucher 	0x9194, 0xffffffff, 0x00070000,
391d4788db3SAlex Deucher 	0x9198, 0xffffffff, 0x00030002,
392d4788db3SAlex Deucher 	0x919c, 0xffffffff, 0x00050004,
393d4788db3SAlex Deucher 	0x91a8, 0xffffffff, 0x00010006,
394d4788db3SAlex Deucher 	0x91ac, 0xffffffff, 0x00090008,
395d4788db3SAlex Deucher 	0x91b0, 0xffffffff, 0x00070000,
396d4788db3SAlex Deucher 	0x91b4, 0xffffffff, 0x00030002,
397d4788db3SAlex Deucher 	0x91b8, 0xffffffff, 0x00050004,
398d4788db3SAlex Deucher 	0x91c4, 0xffffffff, 0x00010006,
399d4788db3SAlex Deucher 	0x91c8, 0xffffffff, 0x00090008,
400d4788db3SAlex Deucher 	0x91cc, 0xffffffff, 0x00070000,
401d4788db3SAlex Deucher 	0x91d0, 0xffffffff, 0x00030002,
402d4788db3SAlex Deucher 	0x91d4, 0xffffffff, 0x00050004,
403d4788db3SAlex Deucher 	0x91e0, 0xffffffff, 0x00010006,
404d4788db3SAlex Deucher 	0x91e4, 0xffffffff, 0x00090008,
405d4788db3SAlex Deucher 	0x91e8, 0xffffffff, 0x00000000,
406d4788db3SAlex Deucher 	0x91ec, 0xffffffff, 0x00070000,
407d4788db3SAlex Deucher 	0x91f0, 0xffffffff, 0x00030002,
408d4788db3SAlex Deucher 	0x91f4, 0xffffffff, 0x00050004,
409d4788db3SAlex Deucher 	0x9200, 0xffffffff, 0x00010006,
410d4788db3SAlex Deucher 	0x9204, 0xffffffff, 0x00090008,
411d4788db3SAlex Deucher 	0x9208, 0xffffffff, 0x00070000,
412d4788db3SAlex Deucher 	0x920c, 0xffffffff, 0x00030002,
413d4788db3SAlex Deucher 	0x9210, 0xffffffff, 0x00050004,
414d4788db3SAlex Deucher 	0x921c, 0xffffffff, 0x00010006,
415d4788db3SAlex Deucher 	0x9220, 0xffffffff, 0x00090008,
416d4788db3SAlex Deucher 	0x9224, 0xffffffff, 0x00070000,
417d4788db3SAlex Deucher 	0x9228, 0xffffffff, 0x00030002,
418d4788db3SAlex Deucher 	0x922c, 0xffffffff, 0x00050004,
419d4788db3SAlex Deucher 	0x9238, 0xffffffff, 0x00010006,
420d4788db3SAlex Deucher 	0x923c, 0xffffffff, 0x00090008,
421d4788db3SAlex Deucher 	0x9240, 0xffffffff, 0x00070000,
422d4788db3SAlex Deucher 	0x9244, 0xffffffff, 0x00030002,
423d4788db3SAlex Deucher 	0x9248, 0xffffffff, 0x00050004,
424d4788db3SAlex Deucher 	0x9254, 0xffffffff, 0x00010006,
425d4788db3SAlex Deucher 	0x9258, 0xffffffff, 0x00090008,
426d4788db3SAlex Deucher 	0x925c, 0xffffffff, 0x00070000,
427d4788db3SAlex Deucher 	0x9260, 0xffffffff, 0x00030002,
428d4788db3SAlex Deucher 	0x9264, 0xffffffff, 0x00050004,
429d4788db3SAlex Deucher 	0x9270, 0xffffffff, 0x00010006,
430d4788db3SAlex Deucher 	0x9274, 0xffffffff, 0x00090008,
431d4788db3SAlex Deucher 	0x9278, 0xffffffff, 0x00070000,
432d4788db3SAlex Deucher 	0x927c, 0xffffffff, 0x00030002,
433d4788db3SAlex Deucher 	0x9280, 0xffffffff, 0x00050004,
434d4788db3SAlex Deucher 	0x928c, 0xffffffff, 0x00010006,
435d4788db3SAlex Deucher 	0x9290, 0xffffffff, 0x00090008,
436d4788db3SAlex Deucher 	0x9294, 0xffffffff, 0x00000000,
437d4788db3SAlex Deucher 	0x929c, 0xffffffff, 0x00000001,
438d4788db3SAlex Deucher 	0x802c, 0xffffffff, 0xc0000000
439d4788db3SAlex Deucher };
440d4788db3SAlex Deucher 
441d4788db3SAlex Deucher static const u32 redwood_mgcg_init[] =
442d4788db3SAlex Deucher {
443d4788db3SAlex Deucher 	0x802c, 0xffffffff, 0xc0000000,
444d4788db3SAlex Deucher 	0x5448, 0xffffffff, 0x00000100,
445d4788db3SAlex Deucher 	0x55e4, 0xffffffff, 0x00000100,
446d4788db3SAlex Deucher 	0x160c, 0xffffffff, 0x00000100,
447d4788db3SAlex Deucher 	0x5644, 0xffffffff, 0x00000100,
448d4788db3SAlex Deucher 	0xc164, 0xffffffff, 0x00000100,
449d4788db3SAlex Deucher 	0x8a18, 0xffffffff, 0x00000100,
450d4788db3SAlex Deucher 	0x897c, 0xffffffff, 0x06000100,
451d4788db3SAlex Deucher 	0x8b28, 0xffffffff, 0x00000100,
452d4788db3SAlex Deucher 	0x9144, 0xffffffff, 0x00000100,
453d4788db3SAlex Deucher 	0x9a60, 0xffffffff, 0x00000100,
454d4788db3SAlex Deucher 	0x9868, 0xffffffff, 0x00000100,
455d4788db3SAlex Deucher 	0x8d58, 0xffffffff, 0x00000100,
456d4788db3SAlex Deucher 	0x9510, 0xffffffff, 0x00000100,
457d4788db3SAlex Deucher 	0x949c, 0xffffffff, 0x00000100,
458d4788db3SAlex Deucher 	0x9654, 0xffffffff, 0x00000100,
459d4788db3SAlex Deucher 	0x9030, 0xffffffff, 0x00000100,
460d4788db3SAlex Deucher 	0x9034, 0xffffffff, 0x00000100,
461d4788db3SAlex Deucher 	0x9038, 0xffffffff, 0x00000100,
462d4788db3SAlex Deucher 	0x903c, 0xffffffff, 0x00000100,
463d4788db3SAlex Deucher 	0x9040, 0xffffffff, 0x00000100,
464d4788db3SAlex Deucher 	0xa200, 0xffffffff, 0x00000100,
465d4788db3SAlex Deucher 	0xa204, 0xffffffff, 0x00000100,
466d4788db3SAlex Deucher 	0xa208, 0xffffffff, 0x00000100,
467d4788db3SAlex Deucher 	0xa20c, 0xffffffff, 0x00000100,
468d4788db3SAlex Deucher 	0x971c, 0xffffffff, 0x00000100,
469d4788db3SAlex Deucher 	0x977c, 0xffffffff, 0x00000100,
470d4788db3SAlex Deucher 	0x3f80, 0xffffffff, 0x00000100,
471d4788db3SAlex Deucher 	0xa210, 0xffffffff, 0x00000100,
472d4788db3SAlex Deucher 	0xa214, 0xffffffff, 0x00000100,
473d4788db3SAlex Deucher 	0x4d8, 0xffffffff, 0x00000100,
474d4788db3SAlex Deucher 	0x9784, 0xffffffff, 0x00000100,
475d4788db3SAlex Deucher 	0x9698, 0xffffffff, 0x00000100,
476d4788db3SAlex Deucher 	0x4d4, 0xffffffff, 0x00000200,
477d4788db3SAlex Deucher 	0x30cc, 0xffffffff, 0x00000100,
478d4788db3SAlex Deucher 	0xd0c0, 0xffffffff, 0xff000100,
479d4788db3SAlex Deucher 	0x802c, 0xffffffff, 0x40000000,
480d4788db3SAlex Deucher 	0x915c, 0xffffffff, 0x00010000,
481d4788db3SAlex Deucher 	0x9160, 0xffffffff, 0x00030002,
482d4788db3SAlex Deucher 	0x9178, 0xffffffff, 0x00070000,
483d4788db3SAlex Deucher 	0x917c, 0xffffffff, 0x00030002,
484d4788db3SAlex Deucher 	0x9180, 0xffffffff, 0x00050004,
485d4788db3SAlex Deucher 	0x918c, 0xffffffff, 0x00010006,
486d4788db3SAlex Deucher 	0x9190, 0xffffffff, 0x00090008,
487d4788db3SAlex Deucher 	0x9194, 0xffffffff, 0x00070000,
488d4788db3SAlex Deucher 	0x9198, 0xffffffff, 0x00030002,
489d4788db3SAlex Deucher 	0x919c, 0xffffffff, 0x00050004,
490d4788db3SAlex Deucher 	0x91a8, 0xffffffff, 0x00010006,
491d4788db3SAlex Deucher 	0x91ac, 0xffffffff, 0x00090008,
492d4788db3SAlex Deucher 	0x91b0, 0xffffffff, 0x00070000,
493d4788db3SAlex Deucher 	0x91b4, 0xffffffff, 0x00030002,
494d4788db3SAlex Deucher 	0x91b8, 0xffffffff, 0x00050004,
495d4788db3SAlex Deucher 	0x91c4, 0xffffffff, 0x00010006,
496d4788db3SAlex Deucher 	0x91c8, 0xffffffff, 0x00090008,
497d4788db3SAlex Deucher 	0x91cc, 0xffffffff, 0x00070000,
498d4788db3SAlex Deucher 	0x91d0, 0xffffffff, 0x00030002,
499d4788db3SAlex Deucher 	0x91d4, 0xffffffff, 0x00050004,
500d4788db3SAlex Deucher 	0x91e0, 0xffffffff, 0x00010006,
501d4788db3SAlex Deucher 	0x91e4, 0xffffffff, 0x00090008,
502d4788db3SAlex Deucher 	0x91e8, 0xffffffff, 0x00000000,
503d4788db3SAlex Deucher 	0x91ec, 0xffffffff, 0x00070000,
504d4788db3SAlex Deucher 	0x91f0, 0xffffffff, 0x00030002,
505d4788db3SAlex Deucher 	0x91f4, 0xffffffff, 0x00050004,
506d4788db3SAlex Deucher 	0x9200, 0xffffffff, 0x00010006,
507d4788db3SAlex Deucher 	0x9204, 0xffffffff, 0x00090008,
508d4788db3SAlex Deucher 	0x9294, 0xffffffff, 0x00000000,
509d4788db3SAlex Deucher 	0x929c, 0xffffffff, 0x00000001,
510d4788db3SAlex Deucher 	0x802c, 0xffffffff, 0xc0000000
511d4788db3SAlex Deucher };
512d4788db3SAlex Deucher 
513d4788db3SAlex Deucher static const u32 cedar_golden_registers[] =
514d4788db3SAlex Deucher {
515d4788db3SAlex Deucher 	0x3f90, 0xffff0000, 0xff000000,
516d4788db3SAlex Deucher 	0x9148, 0xffff0000, 0xff000000,
517d4788db3SAlex Deucher 	0x3f94, 0xffff0000, 0xff000000,
518d4788db3SAlex Deucher 	0x914c, 0xffff0000, 0xff000000,
519d4788db3SAlex Deucher 	0x9b7c, 0xffffffff, 0x00000000,
520d4788db3SAlex Deucher 	0x8a14, 0xffffffff, 0x00000007,
521d4788db3SAlex Deucher 	0x8b10, 0xffffffff, 0x00000000,
522d4788db3SAlex Deucher 	0x960c, 0xffffffff, 0x54763210,
523d4788db3SAlex Deucher 	0x88c4, 0xffffffff, 0x000000c2,
524d4788db3SAlex Deucher 	0x88d4, 0xffffffff, 0x00000000,
525d4788db3SAlex Deucher 	0x8974, 0xffffffff, 0x00000000,
526d4788db3SAlex Deucher 	0xc78, 0x00000080, 0x00000080,
527d4788db3SAlex Deucher 	0x5eb4, 0xffffffff, 0x00000002,
528d4788db3SAlex Deucher 	0x5e78, 0xffffffff, 0x001000f0,
529d4788db3SAlex Deucher 	0x6104, 0x01000300, 0x00000000,
530d4788db3SAlex Deucher 	0x5bc0, 0x00300000, 0x00000000,
531d4788db3SAlex Deucher 	0x7030, 0xffffffff, 0x00000011,
532d4788db3SAlex Deucher 	0x7c30, 0xffffffff, 0x00000011,
533d4788db3SAlex Deucher 	0x10830, 0xffffffff, 0x00000011,
534d4788db3SAlex Deucher 	0x11430, 0xffffffff, 0x00000011,
535d4788db3SAlex Deucher 	0xd02c, 0xffffffff, 0x08421000,
536d4788db3SAlex Deucher 	0x240c, 0xffffffff, 0x00000380,
537d4788db3SAlex Deucher 	0x8b24, 0xffffffff, 0x00ff0fff,
538d4788db3SAlex Deucher 	0x28a4c, 0x06000000, 0x06000000,
539d4788db3SAlex Deucher 	0x10c, 0x00000001, 0x00000001,
540d4788db3SAlex Deucher 	0x8d00, 0xffffffff, 0x100e4848,
541d4788db3SAlex Deucher 	0x8d04, 0xffffffff, 0x00164745,
542d4788db3SAlex Deucher 	0x8c00, 0xffffffff, 0xe4000003,
543d4788db3SAlex Deucher 	0x8c04, 0xffffffff, 0x40600060,
544d4788db3SAlex Deucher 	0x8c08, 0xffffffff, 0x001c001c,
545d4788db3SAlex Deucher 	0x8cf0, 0xffffffff, 0x08e00410,
546d4788db3SAlex Deucher 	0x8c20, 0xffffffff, 0x00800080,
547d4788db3SAlex Deucher 	0x8c24, 0xffffffff, 0x00800080,
548d4788db3SAlex Deucher 	0x8c18, 0xffffffff, 0x20202078,
549d4788db3SAlex Deucher 	0x8c1c, 0xffffffff, 0x00001010,
550d4788db3SAlex Deucher 	0x28350, 0xffffffff, 0x00000000,
551d4788db3SAlex Deucher 	0xa008, 0xffffffff, 0x00010000,
5526abafb78SAlex Deucher 	0x5c4, 0xffffffff, 0x00000001,
553d4788db3SAlex Deucher 	0x9508, 0xffffffff, 0x00000002
554d4788db3SAlex Deucher };
555d4788db3SAlex Deucher 
556d4788db3SAlex Deucher static const u32 cedar_mgcg_init[] =
557d4788db3SAlex Deucher {
558d4788db3SAlex Deucher 	0x802c, 0xffffffff, 0xc0000000,
559d4788db3SAlex Deucher 	0x5448, 0xffffffff, 0x00000100,
560d4788db3SAlex Deucher 	0x55e4, 0xffffffff, 0x00000100,
561d4788db3SAlex Deucher 	0x160c, 0xffffffff, 0x00000100,
562d4788db3SAlex Deucher 	0x5644, 0xffffffff, 0x00000100,
563d4788db3SAlex Deucher 	0xc164, 0xffffffff, 0x00000100,
564d4788db3SAlex Deucher 	0x8a18, 0xffffffff, 0x00000100,
565d4788db3SAlex Deucher 	0x897c, 0xffffffff, 0x06000100,
566d4788db3SAlex Deucher 	0x8b28, 0xffffffff, 0x00000100,
567d4788db3SAlex Deucher 	0x9144, 0xffffffff, 0x00000100,
568d4788db3SAlex Deucher 	0x9a60, 0xffffffff, 0x00000100,
569d4788db3SAlex Deucher 	0x9868, 0xffffffff, 0x00000100,
570d4788db3SAlex Deucher 	0x8d58, 0xffffffff, 0x00000100,
571d4788db3SAlex Deucher 	0x9510, 0xffffffff, 0x00000100,
572d4788db3SAlex Deucher 	0x949c, 0xffffffff, 0x00000100,
573d4788db3SAlex Deucher 	0x9654, 0xffffffff, 0x00000100,
574d4788db3SAlex Deucher 	0x9030, 0xffffffff, 0x00000100,
575d4788db3SAlex Deucher 	0x9034, 0xffffffff, 0x00000100,
576d4788db3SAlex Deucher 	0x9038, 0xffffffff, 0x00000100,
577d4788db3SAlex Deucher 	0x903c, 0xffffffff, 0x00000100,
578d4788db3SAlex Deucher 	0x9040, 0xffffffff, 0x00000100,
579d4788db3SAlex Deucher 	0xa200, 0xffffffff, 0x00000100,
580d4788db3SAlex Deucher 	0xa204, 0xffffffff, 0x00000100,
581d4788db3SAlex Deucher 	0xa208, 0xffffffff, 0x00000100,
582d4788db3SAlex Deucher 	0xa20c, 0xffffffff, 0x00000100,
583d4788db3SAlex Deucher 	0x971c, 0xffffffff, 0x00000100,
584d4788db3SAlex Deucher 	0x977c, 0xffffffff, 0x00000100,
585d4788db3SAlex Deucher 	0x3f80, 0xffffffff, 0x00000100,
586d4788db3SAlex Deucher 	0xa210, 0xffffffff, 0x00000100,
587d4788db3SAlex Deucher 	0xa214, 0xffffffff, 0x00000100,
588d4788db3SAlex Deucher 	0x4d8, 0xffffffff, 0x00000100,
589d4788db3SAlex Deucher 	0x9784, 0xffffffff, 0x00000100,
590d4788db3SAlex Deucher 	0x9698, 0xffffffff, 0x00000100,
591d4788db3SAlex Deucher 	0x4d4, 0xffffffff, 0x00000200,
592d4788db3SAlex Deucher 	0x30cc, 0xffffffff, 0x00000100,
593d4788db3SAlex Deucher 	0xd0c0, 0xffffffff, 0xff000100,
594d4788db3SAlex Deucher 	0x802c, 0xffffffff, 0x40000000,
595d4788db3SAlex Deucher 	0x915c, 0xffffffff, 0x00010000,
596d4788db3SAlex Deucher 	0x9178, 0xffffffff, 0x00050000,
597d4788db3SAlex Deucher 	0x917c, 0xffffffff, 0x00030002,
598d4788db3SAlex Deucher 	0x918c, 0xffffffff, 0x00010004,
599d4788db3SAlex Deucher 	0x9190, 0xffffffff, 0x00070006,
600d4788db3SAlex Deucher 	0x9194, 0xffffffff, 0x00050000,
601d4788db3SAlex Deucher 	0x9198, 0xffffffff, 0x00030002,
602d4788db3SAlex Deucher 	0x91a8, 0xffffffff, 0x00010004,
603d4788db3SAlex Deucher 	0x91ac, 0xffffffff, 0x00070006,
604d4788db3SAlex Deucher 	0x91e8, 0xffffffff, 0x00000000,
605d4788db3SAlex Deucher 	0x9294, 0xffffffff, 0x00000000,
606d4788db3SAlex Deucher 	0x929c, 0xffffffff, 0x00000001,
607d4788db3SAlex Deucher 	0x802c, 0xffffffff, 0xc0000000
608d4788db3SAlex Deucher };
609d4788db3SAlex Deucher 
610d4788db3SAlex Deucher static const u32 juniper_mgcg_init[] =
611d4788db3SAlex Deucher {
612d4788db3SAlex Deucher 	0x802c, 0xffffffff, 0xc0000000,
613d4788db3SAlex Deucher 	0x5448, 0xffffffff, 0x00000100,
614d4788db3SAlex Deucher 	0x55e4, 0xffffffff, 0x00000100,
615d4788db3SAlex Deucher 	0x160c, 0xffffffff, 0x00000100,
616d4788db3SAlex Deucher 	0x5644, 0xffffffff, 0x00000100,
617d4788db3SAlex Deucher 	0xc164, 0xffffffff, 0x00000100,
618d4788db3SAlex Deucher 	0x8a18, 0xffffffff, 0x00000100,
619d4788db3SAlex Deucher 	0x897c, 0xffffffff, 0x06000100,
620d4788db3SAlex Deucher 	0x8b28, 0xffffffff, 0x00000100,
621d4788db3SAlex Deucher 	0x9144, 0xffffffff, 0x00000100,
622d4788db3SAlex Deucher 	0x9a60, 0xffffffff, 0x00000100,
623d4788db3SAlex Deucher 	0x9868, 0xffffffff, 0x00000100,
624d4788db3SAlex Deucher 	0x8d58, 0xffffffff, 0x00000100,
625d4788db3SAlex Deucher 	0x9510, 0xffffffff, 0x00000100,
626d4788db3SAlex Deucher 	0x949c, 0xffffffff, 0x00000100,
627d4788db3SAlex Deucher 	0x9654, 0xffffffff, 0x00000100,
628d4788db3SAlex Deucher 	0x9030, 0xffffffff, 0x00000100,
629d4788db3SAlex Deucher 	0x9034, 0xffffffff, 0x00000100,
630d4788db3SAlex Deucher 	0x9038, 0xffffffff, 0x00000100,
631d4788db3SAlex Deucher 	0x903c, 0xffffffff, 0x00000100,
632d4788db3SAlex Deucher 	0x9040, 0xffffffff, 0x00000100,
633d4788db3SAlex Deucher 	0xa200, 0xffffffff, 0x00000100,
634d4788db3SAlex Deucher 	0xa204, 0xffffffff, 0x00000100,
635d4788db3SAlex Deucher 	0xa208, 0xffffffff, 0x00000100,
636d4788db3SAlex Deucher 	0xa20c, 0xffffffff, 0x00000100,
637d4788db3SAlex Deucher 	0x971c, 0xffffffff, 0x00000100,
638d4788db3SAlex Deucher 	0xd0c0, 0xffffffff, 0xff000100,
639d4788db3SAlex Deucher 	0x802c, 0xffffffff, 0x40000000,
640d4788db3SAlex Deucher 	0x915c, 0xffffffff, 0x00010000,
641d4788db3SAlex Deucher 	0x9160, 0xffffffff, 0x00030002,
642d4788db3SAlex Deucher 	0x9178, 0xffffffff, 0x00070000,
643d4788db3SAlex Deucher 	0x917c, 0xffffffff, 0x00030002,
644d4788db3SAlex Deucher 	0x9180, 0xffffffff, 0x00050004,
645d4788db3SAlex Deucher 	0x918c, 0xffffffff, 0x00010006,
646d4788db3SAlex Deucher 	0x9190, 0xffffffff, 0x00090008,
647d4788db3SAlex Deucher 	0x9194, 0xffffffff, 0x00070000,
648d4788db3SAlex Deucher 	0x9198, 0xffffffff, 0x00030002,
649d4788db3SAlex Deucher 	0x919c, 0xffffffff, 0x00050004,
650d4788db3SAlex Deucher 	0x91a8, 0xffffffff, 0x00010006,
651d4788db3SAlex Deucher 	0x91ac, 0xffffffff, 0x00090008,
652d4788db3SAlex Deucher 	0x91b0, 0xffffffff, 0x00070000,
653d4788db3SAlex Deucher 	0x91b4, 0xffffffff, 0x00030002,
654d4788db3SAlex Deucher 	0x91b8, 0xffffffff, 0x00050004,
655d4788db3SAlex Deucher 	0x91c4, 0xffffffff, 0x00010006,
656d4788db3SAlex Deucher 	0x91c8, 0xffffffff, 0x00090008,
657d4788db3SAlex Deucher 	0x91cc, 0xffffffff, 0x00070000,
658d4788db3SAlex Deucher 	0x91d0, 0xffffffff, 0x00030002,
659d4788db3SAlex Deucher 	0x91d4, 0xffffffff, 0x00050004,
660d4788db3SAlex Deucher 	0x91e0, 0xffffffff, 0x00010006,
661d4788db3SAlex Deucher 	0x91e4, 0xffffffff, 0x00090008,
662d4788db3SAlex Deucher 	0x91e8, 0xffffffff, 0x00000000,
663d4788db3SAlex Deucher 	0x91ec, 0xffffffff, 0x00070000,
664d4788db3SAlex Deucher 	0x91f0, 0xffffffff, 0x00030002,
665d4788db3SAlex Deucher 	0x91f4, 0xffffffff, 0x00050004,
666d4788db3SAlex Deucher 	0x9200, 0xffffffff, 0x00010006,
667d4788db3SAlex Deucher 	0x9204, 0xffffffff, 0x00090008,
668d4788db3SAlex Deucher 	0x9208, 0xffffffff, 0x00070000,
669d4788db3SAlex Deucher 	0x920c, 0xffffffff, 0x00030002,
670d4788db3SAlex Deucher 	0x9210, 0xffffffff, 0x00050004,
671d4788db3SAlex Deucher 	0x921c, 0xffffffff, 0x00010006,
672d4788db3SAlex Deucher 	0x9220, 0xffffffff, 0x00090008,
673d4788db3SAlex Deucher 	0x9224, 0xffffffff, 0x00070000,
674d4788db3SAlex Deucher 	0x9228, 0xffffffff, 0x00030002,
675d4788db3SAlex Deucher 	0x922c, 0xffffffff, 0x00050004,
676d4788db3SAlex Deucher 	0x9238, 0xffffffff, 0x00010006,
677d4788db3SAlex Deucher 	0x923c, 0xffffffff, 0x00090008,
678d4788db3SAlex Deucher 	0x9240, 0xffffffff, 0x00070000,
679d4788db3SAlex Deucher 	0x9244, 0xffffffff, 0x00030002,
680d4788db3SAlex Deucher 	0x9248, 0xffffffff, 0x00050004,
681d4788db3SAlex Deucher 	0x9254, 0xffffffff, 0x00010006,
682d4788db3SAlex Deucher 	0x9258, 0xffffffff, 0x00090008,
683d4788db3SAlex Deucher 	0x925c, 0xffffffff, 0x00070000,
684d4788db3SAlex Deucher 	0x9260, 0xffffffff, 0x00030002,
685d4788db3SAlex Deucher 	0x9264, 0xffffffff, 0x00050004,
686d4788db3SAlex Deucher 	0x9270, 0xffffffff, 0x00010006,
687d4788db3SAlex Deucher 	0x9274, 0xffffffff, 0x00090008,
688d4788db3SAlex Deucher 	0x9278, 0xffffffff, 0x00070000,
689d4788db3SAlex Deucher 	0x927c, 0xffffffff, 0x00030002,
690d4788db3SAlex Deucher 	0x9280, 0xffffffff, 0x00050004,
691d4788db3SAlex Deucher 	0x928c, 0xffffffff, 0x00010006,
692d4788db3SAlex Deucher 	0x9290, 0xffffffff, 0x00090008,
693d4788db3SAlex Deucher 	0x9294, 0xffffffff, 0x00000000,
694d4788db3SAlex Deucher 	0x929c, 0xffffffff, 0x00000001,
695d4788db3SAlex Deucher 	0x802c, 0xffffffff, 0xc0000000,
696d4788db3SAlex Deucher 	0x977c, 0xffffffff, 0x00000100,
697d4788db3SAlex Deucher 	0x3f80, 0xffffffff, 0x00000100,
698d4788db3SAlex Deucher 	0xa210, 0xffffffff, 0x00000100,
699d4788db3SAlex Deucher 	0xa214, 0xffffffff, 0x00000100,
700d4788db3SAlex Deucher 	0x4d8, 0xffffffff, 0x00000100,
701d4788db3SAlex Deucher 	0x9784, 0xffffffff, 0x00000100,
702d4788db3SAlex Deucher 	0x9698, 0xffffffff, 0x00000100,
703d4788db3SAlex Deucher 	0x4d4, 0xffffffff, 0x00000200,
704d4788db3SAlex Deucher 	0x30cc, 0xffffffff, 0x00000100,
705d4788db3SAlex Deucher 	0x802c, 0xffffffff, 0xc0000000
706d4788db3SAlex Deucher };
707d4788db3SAlex Deucher 
708d4788db3SAlex Deucher static const u32 supersumo_golden_registers[] =
709d4788db3SAlex Deucher {
710d4788db3SAlex Deucher 	0x5eb4, 0xffffffff, 0x00000002,
7116abafb78SAlex Deucher 	0x5c4, 0xffffffff, 0x00000001,
712d4788db3SAlex Deucher 	0x7030, 0xffffffff, 0x00000011,
713d4788db3SAlex Deucher 	0x7c30, 0xffffffff, 0x00000011,
714d4788db3SAlex Deucher 	0x6104, 0x01000300, 0x00000000,
715d4788db3SAlex Deucher 	0x5bc0, 0x00300000, 0x00000000,
716d4788db3SAlex Deucher 	0x8c04, 0xffffffff, 0x40600060,
717d4788db3SAlex Deucher 	0x8c08, 0xffffffff, 0x001c001c,
718d4788db3SAlex Deucher 	0x8c20, 0xffffffff, 0x00800080,
719d4788db3SAlex Deucher 	0x8c24, 0xffffffff, 0x00800080,
720d4788db3SAlex Deucher 	0x8c18, 0xffffffff, 0x20202078,
721d4788db3SAlex Deucher 	0x8c1c, 0xffffffff, 0x00001010,
722d4788db3SAlex Deucher 	0x918c, 0xffffffff, 0x00010006,
723d4788db3SAlex Deucher 	0x91a8, 0xffffffff, 0x00010006,
724d4788db3SAlex Deucher 	0x91c4, 0xffffffff, 0x00010006,
725d4788db3SAlex Deucher 	0x91e0, 0xffffffff, 0x00010006,
726d4788db3SAlex Deucher 	0x9200, 0xffffffff, 0x00010006,
727d4788db3SAlex Deucher 	0x9150, 0xffffffff, 0x6e944040,
728d4788db3SAlex Deucher 	0x917c, 0xffffffff, 0x00030002,
729d4788db3SAlex Deucher 	0x9180, 0xffffffff, 0x00050004,
730d4788db3SAlex Deucher 	0x9198, 0xffffffff, 0x00030002,
731d4788db3SAlex Deucher 	0x919c, 0xffffffff, 0x00050004,
732d4788db3SAlex Deucher 	0x91b4, 0xffffffff, 0x00030002,
733d4788db3SAlex Deucher 	0x91b8, 0xffffffff, 0x00050004,
734d4788db3SAlex Deucher 	0x91d0, 0xffffffff, 0x00030002,
735d4788db3SAlex Deucher 	0x91d4, 0xffffffff, 0x00050004,
736d4788db3SAlex Deucher 	0x91f0, 0xffffffff, 0x00030002,
737d4788db3SAlex Deucher 	0x91f4, 0xffffffff, 0x00050004,
738d4788db3SAlex Deucher 	0x915c, 0xffffffff, 0x00010000,
739d4788db3SAlex Deucher 	0x9160, 0xffffffff, 0x00030002,
740d4788db3SAlex Deucher 	0x3f90, 0xffff0000, 0xff000000,
741d4788db3SAlex Deucher 	0x9178, 0xffffffff, 0x00070000,
742d4788db3SAlex Deucher 	0x9194, 0xffffffff, 0x00070000,
743d4788db3SAlex Deucher 	0x91b0, 0xffffffff, 0x00070000,
744d4788db3SAlex Deucher 	0x91cc, 0xffffffff, 0x00070000,
745d4788db3SAlex Deucher 	0x91ec, 0xffffffff, 0x00070000,
746d4788db3SAlex Deucher 	0x9148, 0xffff0000, 0xff000000,
747d4788db3SAlex Deucher 	0x9190, 0xffffffff, 0x00090008,
748d4788db3SAlex Deucher 	0x91ac, 0xffffffff, 0x00090008,
749d4788db3SAlex Deucher 	0x91c8, 0xffffffff, 0x00090008,
750d4788db3SAlex Deucher 	0x91e4, 0xffffffff, 0x00090008,
751d4788db3SAlex Deucher 	0x9204, 0xffffffff, 0x00090008,
752d4788db3SAlex Deucher 	0x3f94, 0xffff0000, 0xff000000,
753d4788db3SAlex Deucher 	0x914c, 0xffff0000, 0xff000000,
754d4788db3SAlex Deucher 	0x929c, 0xffffffff, 0x00000001,
755d4788db3SAlex Deucher 	0x8a18, 0xffffffff, 0x00000100,
756d4788db3SAlex Deucher 	0x8b28, 0xffffffff, 0x00000100,
757d4788db3SAlex Deucher 	0x9144, 0xffffffff, 0x00000100,
758d4788db3SAlex Deucher 	0x5644, 0xffffffff, 0x00000100,
759d4788db3SAlex Deucher 	0x9b7c, 0xffffffff, 0x00000000,
760d4788db3SAlex Deucher 	0x8030, 0xffffffff, 0x0000100a,
761d4788db3SAlex Deucher 	0x8a14, 0xffffffff, 0x00000007,
762d4788db3SAlex Deucher 	0x8b24, 0xffffffff, 0x00ff0fff,
763d4788db3SAlex Deucher 	0x8b10, 0xffffffff, 0x00000000,
764d4788db3SAlex Deucher 	0x28a4c, 0x06000000, 0x06000000,
765d4788db3SAlex Deucher 	0x4d8, 0xffffffff, 0x00000100,
766d4788db3SAlex Deucher 	0x913c, 0xffff000f, 0x0100000a,
767d4788db3SAlex Deucher 	0x960c, 0xffffffff, 0x54763210,
768d4788db3SAlex Deucher 	0x88c4, 0xffffffff, 0x000000c2,
769d4788db3SAlex Deucher 	0x88d4, 0xffffffff, 0x00000010,
770d4788db3SAlex Deucher 	0x8974, 0xffffffff, 0x00000000,
771d4788db3SAlex Deucher 	0xc78, 0x00000080, 0x00000080,
772d4788db3SAlex Deucher 	0x5e78, 0xffffffff, 0x001000f0,
773d4788db3SAlex Deucher 	0xd02c, 0xffffffff, 0x08421000,
774d4788db3SAlex Deucher 	0xa008, 0xffffffff, 0x00010000,
775d4788db3SAlex Deucher 	0x8d00, 0xffffffff, 0x100e4848,
776d4788db3SAlex Deucher 	0x8d04, 0xffffffff, 0x00164745,
777d4788db3SAlex Deucher 	0x8c00, 0xffffffff, 0xe4000003,
778d4788db3SAlex Deucher 	0x8cf0, 0x1fffffff, 0x08e00620,
779d4788db3SAlex Deucher 	0x28350, 0xffffffff, 0x00000000,
780d4788db3SAlex Deucher 	0x9508, 0xffffffff, 0x00000002
781d4788db3SAlex Deucher };
782d4788db3SAlex Deucher 
783d4788db3SAlex Deucher static const u32 sumo_golden_registers[] =
784d4788db3SAlex Deucher {
785d4788db3SAlex Deucher 	0x900c, 0x00ffffff, 0x0017071f,
786d4788db3SAlex Deucher 	0x8c18, 0xffffffff, 0x10101060,
787d4788db3SAlex Deucher 	0x8c1c, 0xffffffff, 0x00001010,
788d4788db3SAlex Deucher 	0x8c30, 0x0000000f, 0x00000005,
789d4788db3SAlex Deucher 	0x9688, 0x0000000f, 0x00000007
790d4788db3SAlex Deucher };
791d4788db3SAlex Deucher 
792d4788db3SAlex Deucher static const u32 wrestler_golden_registers[] =
793d4788db3SAlex Deucher {
794d4788db3SAlex Deucher 	0x5eb4, 0xffffffff, 0x00000002,
7956abafb78SAlex Deucher 	0x5c4, 0xffffffff, 0x00000001,
796d4788db3SAlex Deucher 	0x7030, 0xffffffff, 0x00000011,
797d4788db3SAlex Deucher 	0x7c30, 0xffffffff, 0x00000011,
798d4788db3SAlex Deucher 	0x6104, 0x01000300, 0x00000000,
799d4788db3SAlex Deucher 	0x5bc0, 0x00300000, 0x00000000,
800d4788db3SAlex Deucher 	0x918c, 0xffffffff, 0x00010006,
801d4788db3SAlex Deucher 	0x91a8, 0xffffffff, 0x00010006,
802d4788db3SAlex Deucher 	0x9150, 0xffffffff, 0x6e944040,
803d4788db3SAlex Deucher 	0x917c, 0xffffffff, 0x00030002,
804d4788db3SAlex Deucher 	0x9198, 0xffffffff, 0x00030002,
805d4788db3SAlex Deucher 	0x915c, 0xffffffff, 0x00010000,
806d4788db3SAlex Deucher 	0x3f90, 0xffff0000, 0xff000000,
807d4788db3SAlex Deucher 	0x9178, 0xffffffff, 0x00070000,
808d4788db3SAlex Deucher 	0x9194, 0xffffffff, 0x00070000,
809d4788db3SAlex Deucher 	0x9148, 0xffff0000, 0xff000000,
810d4788db3SAlex Deucher 	0x9190, 0xffffffff, 0x00090008,
811d4788db3SAlex Deucher 	0x91ac, 0xffffffff, 0x00090008,
812d4788db3SAlex Deucher 	0x3f94, 0xffff0000, 0xff000000,
813d4788db3SAlex Deucher 	0x914c, 0xffff0000, 0xff000000,
814d4788db3SAlex Deucher 	0x929c, 0xffffffff, 0x00000001,
815d4788db3SAlex Deucher 	0x8a18, 0xffffffff, 0x00000100,
816d4788db3SAlex Deucher 	0x8b28, 0xffffffff, 0x00000100,
817d4788db3SAlex Deucher 	0x9144, 0xffffffff, 0x00000100,
818d4788db3SAlex Deucher 	0x9b7c, 0xffffffff, 0x00000000,
819d4788db3SAlex Deucher 	0x8030, 0xffffffff, 0x0000100a,
820d4788db3SAlex Deucher 	0x8a14, 0xffffffff, 0x00000001,
821d4788db3SAlex Deucher 	0x8b24, 0xffffffff, 0x00ff0fff,
822d4788db3SAlex Deucher 	0x8b10, 0xffffffff, 0x00000000,
823d4788db3SAlex Deucher 	0x28a4c, 0x06000000, 0x06000000,
824d4788db3SAlex Deucher 	0x4d8, 0xffffffff, 0x00000100,
825d4788db3SAlex Deucher 	0x913c, 0xffff000f, 0x0100000a,
826d4788db3SAlex Deucher 	0x960c, 0xffffffff, 0x54763210,
827d4788db3SAlex Deucher 	0x88c4, 0xffffffff, 0x000000c2,
828d4788db3SAlex Deucher 	0x88d4, 0xffffffff, 0x00000010,
829d4788db3SAlex Deucher 	0x8974, 0xffffffff, 0x00000000,
830d4788db3SAlex Deucher 	0xc78, 0x00000080, 0x00000080,
831d4788db3SAlex Deucher 	0x5e78, 0xffffffff, 0x001000f0,
832d4788db3SAlex Deucher 	0xd02c, 0xffffffff, 0x08421000,
833d4788db3SAlex Deucher 	0xa008, 0xffffffff, 0x00010000,
834d4788db3SAlex Deucher 	0x8d00, 0xffffffff, 0x100e4848,
835d4788db3SAlex Deucher 	0x8d04, 0xffffffff, 0x00164745,
836d4788db3SAlex Deucher 	0x8c00, 0xffffffff, 0xe4000003,
837d4788db3SAlex Deucher 	0x8cf0, 0x1fffffff, 0x08e00410,
838d4788db3SAlex Deucher 	0x28350, 0xffffffff, 0x00000000,
839d4788db3SAlex Deucher 	0x9508, 0xffffffff, 0x00000002,
840d4788db3SAlex Deucher 	0x900c, 0xffffffff, 0x0017071f,
841d4788db3SAlex Deucher 	0x8c18, 0xffffffff, 0x10101060,
842d4788db3SAlex Deucher 	0x8c1c, 0xffffffff, 0x00001010
843d4788db3SAlex Deucher };
844d4788db3SAlex Deucher 
845d4788db3SAlex Deucher static const u32 barts_golden_registers[] =
846d4788db3SAlex Deucher {
847d4788db3SAlex Deucher 	0x5eb4, 0xffffffff, 0x00000002,
848d4788db3SAlex Deucher 	0x5e78, 0x8f311ff1, 0x001000f0,
849d4788db3SAlex Deucher 	0x3f90, 0xffff0000, 0xff000000,
850d4788db3SAlex Deucher 	0x9148, 0xffff0000, 0xff000000,
851d4788db3SAlex Deucher 	0x3f94, 0xffff0000, 0xff000000,
852d4788db3SAlex Deucher 	0x914c, 0xffff0000, 0xff000000,
853d4788db3SAlex Deucher 	0xc78, 0x00000080, 0x00000080,
854d4788db3SAlex Deucher 	0xbd4, 0x70073777, 0x00010001,
855d4788db3SAlex Deucher 	0xd02c, 0xbfffff1f, 0x08421000,
856d4788db3SAlex Deucher 	0xd0b8, 0x03773777, 0x02011003,
857d4788db3SAlex Deucher 	0x5bc0, 0x00200000, 0x50100000,
858d4788db3SAlex Deucher 	0x98f8, 0x33773777, 0x02011003,
859d4788db3SAlex Deucher 	0x98fc, 0xffffffff, 0x76543210,
860d4788db3SAlex Deucher 	0x7030, 0x31000311, 0x00000011,
861d4788db3SAlex Deucher 	0x2f48, 0x00000007, 0x02011003,
862d4788db3SAlex Deucher 	0x6b28, 0x00000010, 0x00000012,
863d4788db3SAlex Deucher 	0x7728, 0x00000010, 0x00000012,
864d4788db3SAlex Deucher 	0x10328, 0x00000010, 0x00000012,
865d4788db3SAlex Deucher 	0x10f28, 0x00000010, 0x00000012,
866d4788db3SAlex Deucher 	0x11b28, 0x00000010, 0x00000012,
867d4788db3SAlex Deucher 	0x12728, 0x00000010, 0x00000012,
868d4788db3SAlex Deucher 	0x240c, 0x000007ff, 0x00000380,
869d4788db3SAlex Deucher 	0x8a14, 0xf000001f, 0x00000007,
870d4788db3SAlex Deucher 	0x8b24, 0x3fff3fff, 0x00ff0fff,
871d4788db3SAlex Deucher 	0x8b10, 0x0000ff0f, 0x00000000,
872d4788db3SAlex Deucher 	0x28a4c, 0x07ffffff, 0x06000000,
873d4788db3SAlex Deucher 	0x10c, 0x00000001, 0x00010003,
874d4788db3SAlex Deucher 	0xa02c, 0xffffffff, 0x0000009b,
875d4788db3SAlex Deucher 	0x913c, 0x0000000f, 0x0100000a,
876d4788db3SAlex Deucher 	0x8d00, 0xffff7f7f, 0x100e4848,
877d4788db3SAlex Deucher 	0x8d04, 0x00ffffff, 0x00164745,
878d4788db3SAlex Deucher 	0x8c00, 0xfffc0003, 0xe4000003,
879d4788db3SAlex Deucher 	0x8c04, 0xf8ff00ff, 0x40600060,
880d4788db3SAlex Deucher 	0x8c08, 0x00ff00ff, 0x001c001c,
881d4788db3SAlex Deucher 	0x8cf0, 0x1fff1fff, 0x08e00620,
882d4788db3SAlex Deucher 	0x8c20, 0x0fff0fff, 0x00800080,
883d4788db3SAlex Deucher 	0x8c24, 0x0fff0fff, 0x00800080,
884d4788db3SAlex Deucher 	0x8c18, 0xffffffff, 0x20202078,
885d4788db3SAlex Deucher 	0x8c1c, 0x0000ffff, 0x00001010,
886d4788db3SAlex Deucher 	0x28350, 0x00000f01, 0x00000000,
887d4788db3SAlex Deucher 	0x9508, 0x3700001f, 0x00000002,
888d4788db3SAlex Deucher 	0x960c, 0xffffffff, 0x54763210,
889d4788db3SAlex Deucher 	0x88c4, 0x001f3ae3, 0x000000c2,
890d4788db3SAlex Deucher 	0x88d4, 0x0000001f, 0x00000010,
891d4788db3SAlex Deucher 	0x8974, 0xffffffff, 0x00000000
892d4788db3SAlex Deucher };
893d4788db3SAlex Deucher 
894d4788db3SAlex Deucher static const u32 turks_golden_registers[] =
895d4788db3SAlex Deucher {
896d4788db3SAlex Deucher 	0x5eb4, 0xffffffff, 0x00000002,
897d4788db3SAlex Deucher 	0x5e78, 0x8f311ff1, 0x001000f0,
898d4788db3SAlex Deucher 	0x8c8, 0x00003000, 0x00001070,
899d4788db3SAlex Deucher 	0x8cc, 0x000fffff, 0x00040035,
900d4788db3SAlex Deucher 	0x3f90, 0xffff0000, 0xfff00000,
901d4788db3SAlex Deucher 	0x9148, 0xffff0000, 0xfff00000,
902d4788db3SAlex Deucher 	0x3f94, 0xffff0000, 0xfff00000,
903d4788db3SAlex Deucher 	0x914c, 0xffff0000, 0xfff00000,
904d4788db3SAlex Deucher 	0xc78, 0x00000080, 0x00000080,
905d4788db3SAlex Deucher 	0xbd4, 0x00073007, 0x00010002,
906d4788db3SAlex Deucher 	0xd02c, 0xbfffff1f, 0x08421000,
907d4788db3SAlex Deucher 	0xd0b8, 0x03773777, 0x02010002,
908d4788db3SAlex Deucher 	0x5bc0, 0x00200000, 0x50100000,
909d4788db3SAlex Deucher 	0x98f8, 0x33773777, 0x00010002,
910d4788db3SAlex Deucher 	0x98fc, 0xffffffff, 0x33221100,
911d4788db3SAlex Deucher 	0x7030, 0x31000311, 0x00000011,
912d4788db3SAlex Deucher 	0x2f48, 0x33773777, 0x00010002,
913d4788db3SAlex Deucher 	0x6b28, 0x00000010, 0x00000012,
914d4788db3SAlex Deucher 	0x7728, 0x00000010, 0x00000012,
915d4788db3SAlex Deucher 	0x10328, 0x00000010, 0x00000012,
916d4788db3SAlex Deucher 	0x10f28, 0x00000010, 0x00000012,
917d4788db3SAlex Deucher 	0x11b28, 0x00000010, 0x00000012,
918d4788db3SAlex Deucher 	0x12728, 0x00000010, 0x00000012,
919d4788db3SAlex Deucher 	0x240c, 0x000007ff, 0x00000380,
920d4788db3SAlex Deucher 	0x8a14, 0xf000001f, 0x00000007,
921d4788db3SAlex Deucher 	0x8b24, 0x3fff3fff, 0x00ff0fff,
922d4788db3SAlex Deucher 	0x8b10, 0x0000ff0f, 0x00000000,
923d4788db3SAlex Deucher 	0x28a4c, 0x07ffffff, 0x06000000,
924d4788db3SAlex Deucher 	0x10c, 0x00000001, 0x00010003,
925d4788db3SAlex Deucher 	0xa02c, 0xffffffff, 0x0000009b,
926d4788db3SAlex Deucher 	0x913c, 0x0000000f, 0x0100000a,
927d4788db3SAlex Deucher 	0x8d00, 0xffff7f7f, 0x100e4848,
928d4788db3SAlex Deucher 	0x8d04, 0x00ffffff, 0x00164745,
929d4788db3SAlex Deucher 	0x8c00, 0xfffc0003, 0xe4000003,
930d4788db3SAlex Deucher 	0x8c04, 0xf8ff00ff, 0x40600060,
931d4788db3SAlex Deucher 	0x8c08, 0x00ff00ff, 0x001c001c,
932d4788db3SAlex Deucher 	0x8cf0, 0x1fff1fff, 0x08e00410,
933d4788db3SAlex Deucher 	0x8c20, 0x0fff0fff, 0x00800080,
934d4788db3SAlex Deucher 	0x8c24, 0x0fff0fff, 0x00800080,
935d4788db3SAlex Deucher 	0x8c18, 0xffffffff, 0x20202078,
936d4788db3SAlex Deucher 	0x8c1c, 0x0000ffff, 0x00001010,
937d4788db3SAlex Deucher 	0x28350, 0x00000f01, 0x00000000,
938d4788db3SAlex Deucher 	0x9508, 0x3700001f, 0x00000002,
939d4788db3SAlex Deucher 	0x960c, 0xffffffff, 0x54763210,
940d4788db3SAlex Deucher 	0x88c4, 0x001f3ae3, 0x000000c2,
941d4788db3SAlex Deucher 	0x88d4, 0x0000001f, 0x00000010,
942d4788db3SAlex Deucher 	0x8974, 0xffffffff, 0x00000000
943d4788db3SAlex Deucher };
944d4788db3SAlex Deucher 
945d4788db3SAlex Deucher static const u32 caicos_golden_registers[] =
946d4788db3SAlex Deucher {
947d4788db3SAlex Deucher 	0x5eb4, 0xffffffff, 0x00000002,
948d4788db3SAlex Deucher 	0x5e78, 0x8f311ff1, 0x001000f0,
949d4788db3SAlex Deucher 	0x8c8, 0x00003420, 0x00001450,
950d4788db3SAlex Deucher 	0x8cc, 0x000fffff, 0x00040035,
951d4788db3SAlex Deucher 	0x3f90, 0xffff0000, 0xfffc0000,
952d4788db3SAlex Deucher 	0x9148, 0xffff0000, 0xfffc0000,
953d4788db3SAlex Deucher 	0x3f94, 0xffff0000, 0xfffc0000,
954d4788db3SAlex Deucher 	0x914c, 0xffff0000, 0xfffc0000,
955d4788db3SAlex Deucher 	0xc78, 0x00000080, 0x00000080,
956d4788db3SAlex Deucher 	0xbd4, 0x00073007, 0x00010001,
957d4788db3SAlex Deucher 	0xd02c, 0xbfffff1f, 0x08421000,
958d4788db3SAlex Deucher 	0xd0b8, 0x03773777, 0x02010001,
959d4788db3SAlex Deucher 	0x5bc0, 0x00200000, 0x50100000,
960d4788db3SAlex Deucher 	0x98f8, 0x33773777, 0x02010001,
961d4788db3SAlex Deucher 	0x98fc, 0xffffffff, 0x33221100,
962d4788db3SAlex Deucher 	0x7030, 0x31000311, 0x00000011,
963d4788db3SAlex Deucher 	0x2f48, 0x33773777, 0x02010001,
964d4788db3SAlex Deucher 	0x6b28, 0x00000010, 0x00000012,
965d4788db3SAlex Deucher 	0x7728, 0x00000010, 0x00000012,
966d4788db3SAlex Deucher 	0x10328, 0x00000010, 0x00000012,
967d4788db3SAlex Deucher 	0x10f28, 0x00000010, 0x00000012,
968d4788db3SAlex Deucher 	0x11b28, 0x00000010, 0x00000012,
969d4788db3SAlex Deucher 	0x12728, 0x00000010, 0x00000012,
970d4788db3SAlex Deucher 	0x240c, 0x000007ff, 0x00000380,
971d4788db3SAlex Deucher 	0x8a14, 0xf000001f, 0x00000001,
972d4788db3SAlex Deucher 	0x8b24, 0x3fff3fff, 0x00ff0fff,
973d4788db3SAlex Deucher 	0x8b10, 0x0000ff0f, 0x00000000,
974d4788db3SAlex Deucher 	0x28a4c, 0x07ffffff, 0x06000000,
975d4788db3SAlex Deucher 	0x10c, 0x00000001, 0x00010003,
976d4788db3SAlex Deucher 	0xa02c, 0xffffffff, 0x0000009b,
977d4788db3SAlex Deucher 	0x913c, 0x0000000f, 0x0100000a,
978d4788db3SAlex Deucher 	0x8d00, 0xffff7f7f, 0x100e4848,
979d4788db3SAlex Deucher 	0x8d04, 0x00ffffff, 0x00164745,
980d4788db3SAlex Deucher 	0x8c00, 0xfffc0003, 0xe4000003,
981d4788db3SAlex Deucher 	0x8c04, 0xf8ff00ff, 0x40600060,
982d4788db3SAlex Deucher 	0x8c08, 0x00ff00ff, 0x001c001c,
983d4788db3SAlex Deucher 	0x8cf0, 0x1fff1fff, 0x08e00410,
984d4788db3SAlex Deucher 	0x8c20, 0x0fff0fff, 0x00800080,
985d4788db3SAlex Deucher 	0x8c24, 0x0fff0fff, 0x00800080,
986d4788db3SAlex Deucher 	0x8c18, 0xffffffff, 0x20202078,
987d4788db3SAlex Deucher 	0x8c1c, 0x0000ffff, 0x00001010,
988d4788db3SAlex Deucher 	0x28350, 0x00000f01, 0x00000000,
989d4788db3SAlex Deucher 	0x9508, 0x3700001f, 0x00000002,
990d4788db3SAlex Deucher 	0x960c, 0xffffffff, 0x54763210,
991d4788db3SAlex Deucher 	0x88c4, 0x001f3ae3, 0x000000c2,
992d4788db3SAlex Deucher 	0x88d4, 0x0000001f, 0x00000010,
993d4788db3SAlex Deucher 	0x8974, 0xffffffff, 0x00000000
994d4788db3SAlex Deucher };
995d4788db3SAlex Deucher 
evergreen_init_golden_registers(struct radeon_device * rdev)996d4788db3SAlex Deucher static void evergreen_init_golden_registers(struct radeon_device *rdev)
997d4788db3SAlex Deucher {
998d4788db3SAlex Deucher 	switch (rdev->family) {
999d4788db3SAlex Deucher 	case CHIP_CYPRESS:
1000d4788db3SAlex Deucher 	case CHIP_HEMLOCK:
1001d4788db3SAlex Deucher 		radeon_program_register_sequence(rdev,
1002d4788db3SAlex Deucher 						 evergreen_golden_registers,
1003d4788db3SAlex Deucher 						 (const u32)ARRAY_SIZE(evergreen_golden_registers));
1004d4788db3SAlex Deucher 		radeon_program_register_sequence(rdev,
1005d4788db3SAlex Deucher 						 evergreen_golden_registers2,
1006d4788db3SAlex Deucher 						 (const u32)ARRAY_SIZE(evergreen_golden_registers2));
1007d4788db3SAlex Deucher 		radeon_program_register_sequence(rdev,
1008d4788db3SAlex Deucher 						 cypress_mgcg_init,
1009d4788db3SAlex Deucher 						 (const u32)ARRAY_SIZE(cypress_mgcg_init));
1010d4788db3SAlex Deucher 		break;
1011d4788db3SAlex Deucher 	case CHIP_JUNIPER:
1012d4788db3SAlex Deucher 		radeon_program_register_sequence(rdev,
1013d4788db3SAlex Deucher 						 evergreen_golden_registers,
1014d4788db3SAlex Deucher 						 (const u32)ARRAY_SIZE(evergreen_golden_registers));
1015d4788db3SAlex Deucher 		radeon_program_register_sequence(rdev,
1016d4788db3SAlex Deucher 						 evergreen_golden_registers2,
1017d4788db3SAlex Deucher 						 (const u32)ARRAY_SIZE(evergreen_golden_registers2));
1018d4788db3SAlex Deucher 		radeon_program_register_sequence(rdev,
1019d4788db3SAlex Deucher 						 juniper_mgcg_init,
1020d4788db3SAlex Deucher 						 (const u32)ARRAY_SIZE(juniper_mgcg_init));
1021d4788db3SAlex Deucher 		break;
1022d4788db3SAlex Deucher 	case CHIP_REDWOOD:
1023d4788db3SAlex Deucher 		radeon_program_register_sequence(rdev,
1024d4788db3SAlex Deucher 						 evergreen_golden_registers,
1025d4788db3SAlex Deucher 						 (const u32)ARRAY_SIZE(evergreen_golden_registers));
1026d4788db3SAlex Deucher 		radeon_program_register_sequence(rdev,
1027d4788db3SAlex Deucher 						 evergreen_golden_registers2,
1028d4788db3SAlex Deucher 						 (const u32)ARRAY_SIZE(evergreen_golden_registers2));
1029d4788db3SAlex Deucher 		radeon_program_register_sequence(rdev,
1030d4788db3SAlex Deucher 						 redwood_mgcg_init,
1031d4788db3SAlex Deucher 						 (const u32)ARRAY_SIZE(redwood_mgcg_init));
1032d4788db3SAlex Deucher 		break;
1033d4788db3SAlex Deucher 	case CHIP_CEDAR:
1034d4788db3SAlex Deucher 		radeon_program_register_sequence(rdev,
1035d4788db3SAlex Deucher 						 cedar_golden_registers,
1036d4788db3SAlex Deucher 						 (const u32)ARRAY_SIZE(cedar_golden_registers));
1037d4788db3SAlex Deucher 		radeon_program_register_sequence(rdev,
1038d4788db3SAlex Deucher 						 evergreen_golden_registers2,
1039d4788db3SAlex Deucher 						 (const u32)ARRAY_SIZE(evergreen_golden_registers2));
1040d4788db3SAlex Deucher 		radeon_program_register_sequence(rdev,
1041d4788db3SAlex Deucher 						 cedar_mgcg_init,
1042d4788db3SAlex Deucher 						 (const u32)ARRAY_SIZE(cedar_mgcg_init));
1043d4788db3SAlex Deucher 		break;
1044d4788db3SAlex Deucher 	case CHIP_PALM:
1045d4788db3SAlex Deucher 		radeon_program_register_sequence(rdev,
1046d4788db3SAlex Deucher 						 wrestler_golden_registers,
1047d4788db3SAlex Deucher 						 (const u32)ARRAY_SIZE(wrestler_golden_registers));
1048d4788db3SAlex Deucher 		break;
1049d4788db3SAlex Deucher 	case CHIP_SUMO:
1050d4788db3SAlex Deucher 		radeon_program_register_sequence(rdev,
1051d4788db3SAlex Deucher 						 supersumo_golden_registers,
1052d4788db3SAlex Deucher 						 (const u32)ARRAY_SIZE(supersumo_golden_registers));
1053d4788db3SAlex Deucher 		break;
1054d4788db3SAlex Deucher 	case CHIP_SUMO2:
1055d4788db3SAlex Deucher 		radeon_program_register_sequence(rdev,
1056d4788db3SAlex Deucher 						 supersumo_golden_registers,
1057d4788db3SAlex Deucher 						 (const u32)ARRAY_SIZE(supersumo_golden_registers));
1058d4788db3SAlex Deucher 		radeon_program_register_sequence(rdev,
1059d4788db3SAlex Deucher 						 sumo_golden_registers,
1060d4788db3SAlex Deucher 						 (const u32)ARRAY_SIZE(sumo_golden_registers));
1061d4788db3SAlex Deucher 		break;
1062d4788db3SAlex Deucher 	case CHIP_BARTS:
1063d4788db3SAlex Deucher 		radeon_program_register_sequence(rdev,
1064d4788db3SAlex Deucher 						 barts_golden_registers,
1065d4788db3SAlex Deucher 						 (const u32)ARRAY_SIZE(barts_golden_registers));
1066d4788db3SAlex Deucher 		break;
1067d4788db3SAlex Deucher 	case CHIP_TURKS:
1068d4788db3SAlex Deucher 		radeon_program_register_sequence(rdev,
1069d4788db3SAlex Deucher 						 turks_golden_registers,
1070d4788db3SAlex Deucher 						 (const u32)ARRAY_SIZE(turks_golden_registers));
1071d4788db3SAlex Deucher 		break;
1072d4788db3SAlex Deucher 	case CHIP_CAICOS:
1073d4788db3SAlex Deucher 		radeon_program_register_sequence(rdev,
1074d4788db3SAlex Deucher 						 caicos_golden_registers,
1075d4788db3SAlex Deucher 						 (const u32)ARRAY_SIZE(caicos_golden_registers));
1076d4788db3SAlex Deucher 		break;
1077d4788db3SAlex Deucher 	default:
1078d4788db3SAlex Deucher 		break;
1079d4788db3SAlex Deucher 	}
1080d4788db3SAlex Deucher }
1081d4788db3SAlex Deucher 
1082ff609975SAlex Deucher /**
1083ff609975SAlex Deucher  * evergreen_get_allowed_info_register - fetch the register for the info ioctl
1084ff609975SAlex Deucher  *
1085ff609975SAlex Deucher  * @rdev: radeon_device pointer
1086ff609975SAlex Deucher  * @reg: register offset in bytes
1087ff609975SAlex Deucher  * @val: register value
1088ff609975SAlex Deucher  *
1089ff609975SAlex Deucher  * Returns 0 for success or -EINVAL for an invalid register
1090ff609975SAlex Deucher  *
1091ff609975SAlex Deucher  */
evergreen_get_allowed_info_register(struct radeon_device * rdev,u32 reg,u32 * val)1092ff609975SAlex Deucher int evergreen_get_allowed_info_register(struct radeon_device *rdev,
1093ff609975SAlex Deucher 					u32 reg, u32 *val)
1094ff609975SAlex Deucher {
1095ff609975SAlex Deucher 	switch (reg) {
1096ff609975SAlex Deucher 	case GRBM_STATUS:
1097ff609975SAlex Deucher 	case GRBM_STATUS_SE0:
1098ff609975SAlex Deucher 	case GRBM_STATUS_SE1:
1099ff609975SAlex Deucher 	case SRBM_STATUS:
1100ff609975SAlex Deucher 	case SRBM_STATUS2:
1101ff609975SAlex Deucher 	case DMA_STATUS_REG:
1102ff609975SAlex Deucher 	case UVD_STATUS:
1103ff609975SAlex Deucher 		*val = RREG32(reg);
1104ff609975SAlex Deucher 		return 0;
1105ff609975SAlex Deucher 	default:
1106ff609975SAlex Deucher 		return -EINVAL;
1107ff609975SAlex Deucher 	}
1108ff609975SAlex Deucher }
1109ff609975SAlex Deucher 
evergreen_tiling_fields(unsigned tiling_flags,unsigned * bankw,unsigned * bankh,unsigned * mtaspect,unsigned * tile_split)1110285484e2SJerome Glisse void evergreen_tiling_fields(unsigned tiling_flags, unsigned *bankw,
1111285484e2SJerome Glisse 			     unsigned *bankh, unsigned *mtaspect,
1112285484e2SJerome Glisse 			     unsigned *tile_split)
1113285484e2SJerome Glisse {
1114285484e2SJerome Glisse 	*bankw = (tiling_flags >> RADEON_TILING_EG_BANKW_SHIFT) & RADEON_TILING_EG_BANKW_MASK;
1115285484e2SJerome Glisse 	*bankh = (tiling_flags >> RADEON_TILING_EG_BANKH_SHIFT) & RADEON_TILING_EG_BANKH_MASK;
1116285484e2SJerome Glisse 	*mtaspect = (tiling_flags >> RADEON_TILING_EG_MACRO_TILE_ASPECT_SHIFT) & RADEON_TILING_EG_MACRO_TILE_ASPECT_MASK;
1117285484e2SJerome Glisse 	*tile_split = (tiling_flags >> RADEON_TILING_EG_TILE_SPLIT_SHIFT) & RADEON_TILING_EG_TILE_SPLIT_MASK;
1118285484e2SJerome Glisse 	switch (*bankw) {
1119285484e2SJerome Glisse 	default:
1120285484e2SJerome Glisse 	case 1: *bankw = EVERGREEN_ADDR_SURF_BANK_WIDTH_1; break;
1121285484e2SJerome Glisse 	case 2: *bankw = EVERGREEN_ADDR_SURF_BANK_WIDTH_2; break;
1122285484e2SJerome Glisse 	case 4: *bankw = EVERGREEN_ADDR_SURF_BANK_WIDTH_4; break;
1123285484e2SJerome Glisse 	case 8: *bankw = EVERGREEN_ADDR_SURF_BANK_WIDTH_8; break;
1124285484e2SJerome Glisse 	}
1125285484e2SJerome Glisse 	switch (*bankh) {
1126285484e2SJerome Glisse 	default:
1127285484e2SJerome Glisse 	case 1: *bankh = EVERGREEN_ADDR_SURF_BANK_HEIGHT_1; break;
1128285484e2SJerome Glisse 	case 2: *bankh = EVERGREEN_ADDR_SURF_BANK_HEIGHT_2; break;
1129285484e2SJerome Glisse 	case 4: *bankh = EVERGREEN_ADDR_SURF_BANK_HEIGHT_4; break;
1130285484e2SJerome Glisse 	case 8: *bankh = EVERGREEN_ADDR_SURF_BANK_HEIGHT_8; break;
1131285484e2SJerome Glisse 	}
1132285484e2SJerome Glisse 	switch (*mtaspect) {
1133285484e2SJerome Glisse 	default:
1134285484e2SJerome Glisse 	case 1: *mtaspect = EVERGREEN_ADDR_SURF_MACRO_TILE_ASPECT_1; break;
1135285484e2SJerome Glisse 	case 2: *mtaspect = EVERGREEN_ADDR_SURF_MACRO_TILE_ASPECT_2; break;
1136285484e2SJerome Glisse 	case 4: *mtaspect = EVERGREEN_ADDR_SURF_MACRO_TILE_ASPECT_4; break;
1137285484e2SJerome Glisse 	case 8: *mtaspect = EVERGREEN_ADDR_SURF_MACRO_TILE_ASPECT_8; break;
1138285484e2SJerome Glisse 	}
1139285484e2SJerome Glisse }
1140285484e2SJerome Glisse 
sumo_set_uvd_clock(struct radeon_device * rdev,u32 clock,u32 cntl_reg,u32 status_reg)114123d33ba3SAlex Deucher static int sumo_set_uvd_clock(struct radeon_device *rdev, u32 clock,
114223d33ba3SAlex Deucher 			      u32 cntl_reg, u32 status_reg)
114323d33ba3SAlex Deucher {
114423d33ba3SAlex Deucher 	int r, i;
114523d33ba3SAlex Deucher 	struct atom_clock_dividers dividers;
114623d33ba3SAlex Deucher 
114723d33ba3SAlex Deucher 	r = radeon_atom_get_clock_dividers(rdev, COMPUTE_ENGINE_PLL_PARAM,
114823d33ba3SAlex Deucher 					   clock, false, &dividers);
114923d33ba3SAlex Deucher 	if (r)
115023d33ba3SAlex Deucher 		return r;
115123d33ba3SAlex Deucher 
115223d33ba3SAlex Deucher 	WREG32_P(cntl_reg, dividers.post_div, ~(DCLK_DIR_CNTL_EN|DCLK_DIVIDER_MASK));
115323d33ba3SAlex Deucher 
115423d33ba3SAlex Deucher 	for (i = 0; i < 100; i++) {
115523d33ba3SAlex Deucher 		if (RREG32(status_reg) & DCLK_STATUS)
115623d33ba3SAlex Deucher 			break;
115723d33ba3SAlex Deucher 		mdelay(10);
115823d33ba3SAlex Deucher 	}
115923d33ba3SAlex Deucher 	if (i == 100)
116023d33ba3SAlex Deucher 		return -ETIMEDOUT;
116123d33ba3SAlex Deucher 
116223d33ba3SAlex Deucher 	return 0;
116323d33ba3SAlex Deucher }
116423d33ba3SAlex Deucher 
sumo_set_uvd_clocks(struct radeon_device * rdev,u32 vclk,u32 dclk)116523d33ba3SAlex Deucher int sumo_set_uvd_clocks(struct radeon_device *rdev, u32 vclk, u32 dclk)
116623d33ba3SAlex Deucher {
116723d33ba3SAlex Deucher 	int r = 0;
116823d33ba3SAlex Deucher 	u32 cg_scratch = RREG32(CG_SCRATCH1);
116923d33ba3SAlex Deucher 
117023d33ba3SAlex Deucher 	r = sumo_set_uvd_clock(rdev, vclk, CG_VCLK_CNTL, CG_VCLK_STATUS);
117123d33ba3SAlex Deucher 	if (r)
117223d33ba3SAlex Deucher 		goto done;
117323d33ba3SAlex Deucher 	cg_scratch &= 0xffff0000;
117423d33ba3SAlex Deucher 	cg_scratch |= vclk / 100; /* Mhz */
117523d33ba3SAlex Deucher 
117623d33ba3SAlex Deucher 	r = sumo_set_uvd_clock(rdev, dclk, CG_DCLK_CNTL, CG_DCLK_STATUS);
117723d33ba3SAlex Deucher 	if (r)
117823d33ba3SAlex Deucher 		goto done;
117923d33ba3SAlex Deucher 	cg_scratch &= 0x0000ffff;
118023d33ba3SAlex Deucher 	cg_scratch |= (dclk / 100) << 16; /* Mhz */
118123d33ba3SAlex Deucher 
118223d33ba3SAlex Deucher done:
118323d33ba3SAlex Deucher 	WREG32(CG_SCRATCH1, cg_scratch);
118423d33ba3SAlex Deucher 
118523d33ba3SAlex Deucher 	return r;
118623d33ba3SAlex Deucher }
118723d33ba3SAlex Deucher 
evergreen_set_uvd_clocks(struct radeon_device * rdev,u32 vclk,u32 dclk)1188a8b4925cSAlex Deucher int evergreen_set_uvd_clocks(struct radeon_device *rdev, u32 vclk, u32 dclk)
1189a8b4925cSAlex Deucher {
1190a8b4925cSAlex Deucher 	/* start off with something large */
1191facd112dSChristian König 	unsigned fb_div = 0, vclk_div = 0, dclk_div = 0;
1192a8b4925cSAlex Deucher 	int r;
1193a8b4925cSAlex Deucher 
11944ed10835SChristian König 	/* bypass vclk and dclk with bclk */
11954ed10835SChristian König 	WREG32_P(CG_UPLL_FUNC_CNTL_2,
11964ed10835SChristian König 		VCLK_SRC_SEL(1) | DCLK_SRC_SEL(1),
11974ed10835SChristian König 		~(VCLK_SRC_SEL_MASK | DCLK_SRC_SEL_MASK));
11984ed10835SChristian König 
11994ed10835SChristian König 	/* put PLL in bypass mode */
12004ed10835SChristian König 	WREG32_P(CG_UPLL_FUNC_CNTL, UPLL_BYPASS_EN_MASK, ~UPLL_BYPASS_EN_MASK);
12014ed10835SChristian König 
12024ed10835SChristian König 	if (!vclk || !dclk) {
12034ed10835SChristian König 		/* keep the Bypass mode, put PLL to sleep */
12044ed10835SChristian König 		WREG32_P(CG_UPLL_FUNC_CNTL, UPLL_SLEEP_MASK, ~UPLL_SLEEP_MASK);
12054ed10835SChristian König 		return 0;
12064ed10835SChristian König 	}
12074ed10835SChristian König 
1208facd112dSChristian König 	r = radeon_uvd_calc_upll_dividers(rdev, vclk, dclk, 125000, 250000,
1209facd112dSChristian König 					  16384, 0x03FFFFFF, 0, 128, 5,
1210facd112dSChristian König 					  &fb_div, &vclk_div, &dclk_div);
1211facd112dSChristian König 	if (r)
1212facd112dSChristian König 		return r;
1213a8b4925cSAlex Deucher 
1214a8b4925cSAlex Deucher 	/* set VCO_MODE to 1 */
1215a8b4925cSAlex Deucher 	WREG32_P(CG_UPLL_FUNC_CNTL, UPLL_VCO_MODE_MASK, ~UPLL_VCO_MODE_MASK);
1216a8b4925cSAlex Deucher 
1217a8b4925cSAlex Deucher 	/* toggle UPLL_SLEEP to 1 then back to 0 */
1218a8b4925cSAlex Deucher 	WREG32_P(CG_UPLL_FUNC_CNTL, UPLL_SLEEP_MASK, ~UPLL_SLEEP_MASK);
1219a8b4925cSAlex Deucher 	WREG32_P(CG_UPLL_FUNC_CNTL, 0, ~UPLL_SLEEP_MASK);
1220a8b4925cSAlex Deucher 
1221a8b4925cSAlex Deucher 	/* deassert UPLL_RESET */
1222a8b4925cSAlex Deucher 	WREG32_P(CG_UPLL_FUNC_CNTL, 0, ~UPLL_RESET_MASK);
1223a8b4925cSAlex Deucher 
1224a8b4925cSAlex Deucher 	mdelay(1);
1225a8b4925cSAlex Deucher 
1226facd112dSChristian König 	r = radeon_uvd_send_upll_ctlreq(rdev, CG_UPLL_FUNC_CNTL);
1227a8b4925cSAlex Deucher 	if (r)
1228a8b4925cSAlex Deucher 		return r;
1229a8b4925cSAlex Deucher 
1230a8b4925cSAlex Deucher 	/* assert UPLL_RESET again */
1231a8b4925cSAlex Deucher 	WREG32_P(CG_UPLL_FUNC_CNTL, UPLL_RESET_MASK, ~UPLL_RESET_MASK);
1232a8b4925cSAlex Deucher 
1233a8b4925cSAlex Deucher 	/* disable spread spectrum. */
1234a8b4925cSAlex Deucher 	WREG32_P(CG_UPLL_SPREAD_SPECTRUM, 0, ~SSEN_MASK);
1235a8b4925cSAlex Deucher 
1236a8b4925cSAlex Deucher 	/* set feedback divider */
1237facd112dSChristian König 	WREG32_P(CG_UPLL_FUNC_CNTL_3, UPLL_FB_DIV(fb_div), ~UPLL_FB_DIV_MASK);
1238a8b4925cSAlex Deucher 
1239a8b4925cSAlex Deucher 	/* set ref divider to 0 */
1240a8b4925cSAlex Deucher 	WREG32_P(CG_UPLL_FUNC_CNTL, 0, ~UPLL_REF_DIV_MASK);
1241a8b4925cSAlex Deucher 
1242facd112dSChristian König 	if (fb_div < 307200)
1243a8b4925cSAlex Deucher 		WREG32_P(CG_UPLL_FUNC_CNTL_4, 0, ~UPLL_SPARE_ISPARE9);
1244a8b4925cSAlex Deucher 	else
1245a8b4925cSAlex Deucher 		WREG32_P(CG_UPLL_FUNC_CNTL_4, UPLL_SPARE_ISPARE9, ~UPLL_SPARE_ISPARE9);
1246a8b4925cSAlex Deucher 
1247a8b4925cSAlex Deucher 	/* set PDIV_A and PDIV_B */
1248a8b4925cSAlex Deucher 	WREG32_P(CG_UPLL_FUNC_CNTL_2,
1249facd112dSChristian König 		UPLL_PDIV_A(vclk_div) | UPLL_PDIV_B(dclk_div),
1250a8b4925cSAlex Deucher 		~(UPLL_PDIV_A_MASK | UPLL_PDIV_B_MASK));
1251a8b4925cSAlex Deucher 
1252a8b4925cSAlex Deucher 	/* give the PLL some time to settle */
1253a8b4925cSAlex Deucher 	mdelay(15);
1254a8b4925cSAlex Deucher 
1255a8b4925cSAlex Deucher 	/* deassert PLL_RESET */
1256a8b4925cSAlex Deucher 	WREG32_P(CG_UPLL_FUNC_CNTL, 0, ~UPLL_RESET_MASK);
1257a8b4925cSAlex Deucher 
1258a8b4925cSAlex Deucher 	mdelay(15);
1259a8b4925cSAlex Deucher 
1260a8b4925cSAlex Deucher 	/* switch from bypass mode to normal mode */
1261a8b4925cSAlex Deucher 	WREG32_P(CG_UPLL_FUNC_CNTL, 0, ~UPLL_BYPASS_EN_MASK);
1262a8b4925cSAlex Deucher 
1263facd112dSChristian König 	r = radeon_uvd_send_upll_ctlreq(rdev, CG_UPLL_FUNC_CNTL);
1264a8b4925cSAlex Deucher 	if (r)
1265a8b4925cSAlex Deucher 		return r;
1266a8b4925cSAlex Deucher 
1267a8b4925cSAlex Deucher 	/* switch VCLK and DCLK selection */
1268a8b4925cSAlex Deucher 	WREG32_P(CG_UPLL_FUNC_CNTL_2,
1269a8b4925cSAlex Deucher 		VCLK_SRC_SEL(2) | DCLK_SRC_SEL(2),
1270a8b4925cSAlex Deucher 		~(VCLK_SRC_SEL_MASK | DCLK_SRC_SEL_MASK));
1271a8b4925cSAlex Deucher 
1272a8b4925cSAlex Deucher 	mdelay(100);
1273a8b4925cSAlex Deucher 
1274a8b4925cSAlex Deucher 	return 0;
1275a8b4925cSAlex Deucher }
1276a8b4925cSAlex Deucher 
evergreen_fix_pci_max_read_req_size(struct radeon_device * rdev)1277d054ac16SAlex Deucher void evergreen_fix_pci_max_read_req_size(struct radeon_device *rdev)
1278d054ac16SAlex Deucher {
1279c11592feSYijing Wang 	int readrq;
1280c11592feSYijing Wang 	u16 v;
1281d054ac16SAlex Deucher 
1282c11592feSYijing Wang 	readrq = pcie_get_readrq(rdev->pdev);
1283c11592feSYijing Wang 	v = ffs(readrq) - 8;
1284d054ac16SAlex Deucher 	/* if bios or OS sets MAX_READ_REQUEST_SIZE to an invalid value, fix it
1285d054ac16SAlex Deucher 	 * to avoid hangs or perfomance issues
1286d054ac16SAlex Deucher 	 */
1287c11592feSYijing Wang 	if ((v == 0) || (v == 6) || (v == 7))
1288c11592feSYijing Wang 		pcie_set_readrq(rdev->pdev, 512);
1289d054ac16SAlex Deucher }
1290d054ac16SAlex Deucher 
dce4_program_fmt(struct drm_encoder * encoder)1291134b480fSAlex Deucher void dce4_program_fmt(struct drm_encoder *encoder)
1292134b480fSAlex Deucher {
1293134b480fSAlex Deucher 	struct drm_device *dev = encoder->dev;
1294134b480fSAlex Deucher 	struct radeon_device *rdev = dev->dev_private;
1295134b480fSAlex Deucher 	struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
1296134b480fSAlex Deucher 	struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc);
1297134b480fSAlex Deucher 	struct drm_connector *connector = radeon_get_connector_for_encoder(encoder);
1298134b480fSAlex Deucher 	int bpc = 0;
1299134b480fSAlex Deucher 	u32 tmp = 0;
13006214bb74SAlex Deucher 	enum radeon_connector_dither dither = RADEON_FMT_DITHER_DISABLE;
1301134b480fSAlex Deucher 
13026214bb74SAlex Deucher 	if (connector) {
13036214bb74SAlex Deucher 		struct radeon_connector *radeon_connector = to_radeon_connector(connector);
1304134b480fSAlex Deucher 		bpc = radeon_get_monitor_bpc(connector);
13056214bb74SAlex Deucher 		dither = radeon_connector->dither;
13066214bb74SAlex Deucher 	}
1307134b480fSAlex Deucher 
1308134b480fSAlex Deucher 	/* LVDS/eDP FMT is set up by atom */
1309134b480fSAlex Deucher 	if (radeon_encoder->devices & ATOM_DEVICE_LCD_SUPPORT)
1310134b480fSAlex Deucher 		return;
1311134b480fSAlex Deucher 
1312134b480fSAlex Deucher 	/* not needed for analog */
1313134b480fSAlex Deucher 	if ((radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1) ||
1314134b480fSAlex Deucher 	    (radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2))
1315134b480fSAlex Deucher 		return;
1316134b480fSAlex Deucher 
1317134b480fSAlex Deucher 	if (bpc == 0)
1318134b480fSAlex Deucher 		return;
1319134b480fSAlex Deucher 
1320134b480fSAlex Deucher 	switch (bpc) {
1321134b480fSAlex Deucher 	case 6:
13226214bb74SAlex Deucher 		if (dither == RADEON_FMT_DITHER_ENABLE)
1323134b480fSAlex Deucher 			/* XXX sort out optimal dither settings */
1324134b480fSAlex Deucher 			tmp |= (FMT_FRAME_RANDOM_ENABLE | FMT_HIGHPASS_RANDOM_ENABLE |
1325134b480fSAlex Deucher 				FMT_SPATIAL_DITHER_EN);
1326134b480fSAlex Deucher 		else
1327134b480fSAlex Deucher 			tmp |= FMT_TRUNCATE_EN;
1328134b480fSAlex Deucher 		break;
1329134b480fSAlex Deucher 	case 8:
13306214bb74SAlex Deucher 		if (dither == RADEON_FMT_DITHER_ENABLE)
1331134b480fSAlex Deucher 			/* XXX sort out optimal dither settings */
1332134b480fSAlex Deucher 			tmp |= (FMT_FRAME_RANDOM_ENABLE | FMT_HIGHPASS_RANDOM_ENABLE |
1333134b480fSAlex Deucher 				FMT_RGB_RANDOM_ENABLE |
1334134b480fSAlex Deucher 				FMT_SPATIAL_DITHER_EN | FMT_SPATIAL_DITHER_DEPTH);
1335134b480fSAlex Deucher 		else
1336134b480fSAlex Deucher 			tmp |= (FMT_TRUNCATE_EN | FMT_TRUNCATE_DEPTH);
1337134b480fSAlex Deucher 		break;
1338134b480fSAlex Deucher 	case 10:
1339134b480fSAlex Deucher 	default:
1340134b480fSAlex Deucher 		/* not needed */
1341134b480fSAlex Deucher 		break;
1342134b480fSAlex Deucher 	}
1343134b480fSAlex Deucher 
1344134b480fSAlex Deucher 	WREG32(FMT_BIT_DEPTH_CONTROL + radeon_crtc->crtc_offset, tmp);
1345134b480fSAlex Deucher }
1346134b480fSAlex Deucher 
dce4_is_in_vblank(struct radeon_device * rdev,int crtc)134710257a6dSAlex Deucher static bool dce4_is_in_vblank(struct radeon_device *rdev, int crtc)
134810257a6dSAlex Deucher {
134910257a6dSAlex Deucher 	if (RREG32(EVERGREEN_CRTC_STATUS + crtc_offsets[crtc]) & EVERGREEN_CRTC_V_BLANK)
135010257a6dSAlex Deucher 		return true;
135110257a6dSAlex Deucher 	else
135210257a6dSAlex Deucher 		return false;
135310257a6dSAlex Deucher }
135410257a6dSAlex Deucher 
dce4_is_counter_moving(struct radeon_device * rdev,int crtc)135510257a6dSAlex Deucher static bool dce4_is_counter_moving(struct radeon_device *rdev, int crtc)
135610257a6dSAlex Deucher {
135710257a6dSAlex Deucher 	u32 pos1, pos2;
135810257a6dSAlex Deucher 
135910257a6dSAlex Deucher 	pos1 = RREG32(EVERGREEN_CRTC_STATUS_POSITION + crtc_offsets[crtc]);
136010257a6dSAlex Deucher 	pos2 = RREG32(EVERGREEN_CRTC_STATUS_POSITION + crtc_offsets[crtc]);
136110257a6dSAlex Deucher 
136210257a6dSAlex Deucher 	if (pos1 != pos2)
136310257a6dSAlex Deucher 		return true;
136410257a6dSAlex Deucher 	else
136510257a6dSAlex Deucher 		return false;
136610257a6dSAlex Deucher }
136710257a6dSAlex Deucher 
1368377edc8bSAlex Deucher /**
1369377edc8bSAlex Deucher  * dce4_wait_for_vblank - vblank wait asic callback.
1370377edc8bSAlex Deucher  *
1371377edc8bSAlex Deucher  * @rdev: radeon_device pointer
1372377edc8bSAlex Deucher  * @crtc: crtc to wait for vblank on
1373377edc8bSAlex Deucher  *
1374377edc8bSAlex Deucher  * Wait for vblank on the requested crtc (evergreen+).
1375377edc8bSAlex Deucher  */
dce4_wait_for_vblank(struct radeon_device * rdev,int crtc)13763ae19b75SAlex Deucher void dce4_wait_for_vblank(struct radeon_device *rdev, int crtc)
13773ae19b75SAlex Deucher {
137810257a6dSAlex Deucher 	unsigned i = 0;
13793ae19b75SAlex Deucher 
13804a15903dSAlex Deucher 	if (crtc >= rdev->num_crtc)
13814a15903dSAlex Deucher 		return;
13824a15903dSAlex Deucher 
138310257a6dSAlex Deucher 	if (!(RREG32(EVERGREEN_CRTC_CONTROL + crtc_offsets[crtc]) & EVERGREEN_CRTC_MASTER_EN))
138410257a6dSAlex Deucher 		return;
138510257a6dSAlex Deucher 
138610257a6dSAlex Deucher 	/* depending on when we hit vblank, we may be close to active; if so,
138710257a6dSAlex Deucher 	 * wait for another frame.
138810257a6dSAlex Deucher 	 */
138910257a6dSAlex Deucher 	while (dce4_is_in_vblank(rdev, crtc)) {
139010257a6dSAlex Deucher 		if (i++ % 100 == 0) {
139110257a6dSAlex Deucher 			if (!dce4_is_counter_moving(rdev, crtc))
13923ae19b75SAlex Deucher 				break;
13933ae19b75SAlex Deucher 		}
139410257a6dSAlex Deucher 	}
139510257a6dSAlex Deucher 
139610257a6dSAlex Deucher 	while (!dce4_is_in_vblank(rdev, crtc)) {
139710257a6dSAlex Deucher 		if (i++ % 100 == 0) {
139810257a6dSAlex Deucher 			if (!dce4_is_counter_moving(rdev, crtc))
13993ae19b75SAlex Deucher 				break;
14003ae19b75SAlex Deucher 		}
14013ae19b75SAlex Deucher 	}
14023ae19b75SAlex Deucher }
14033ae19b75SAlex Deucher 
1404377edc8bSAlex Deucher /**
1405377edc8bSAlex Deucher  * evergreen_page_flip - pageflip callback.
1406377edc8bSAlex Deucher  *
1407377edc8bSAlex Deucher  * @rdev: radeon_device pointer
1408377edc8bSAlex Deucher  * @crtc_id: crtc to cleanup pageflip on
1409377edc8bSAlex Deucher  * @crtc_base: new address of the crtc (GPU MC address)
1410901e860cSLee Jones  * @async: asynchronous flip
1411377edc8bSAlex Deucher  *
1412cbd3e249SAlex Deucher  * Triggers the actual pageflip by updating the primary
1413cbd3e249SAlex Deucher  * surface base address (evergreen+).
1414377edc8bSAlex Deucher  */
evergreen_page_flip(struct radeon_device * rdev,int crtc_id,u64 crtc_base,bool async)1415c63dd758SMichel Dänzer void evergreen_page_flip(struct radeon_device *rdev, int crtc_id, u64 crtc_base,
1416c63dd758SMichel Dänzer 			 bool async)
14176f34be50SAlex Deucher {
14186f34be50SAlex Deucher 	struct radeon_crtc *radeon_crtc = rdev->mode_info.crtcs[crtc_id];
1419c841e552SZhenneng Li 	struct drm_framebuffer *fb = radeon_crtc->base.primary->fb;
14206f34be50SAlex Deucher 
1421c841e552SZhenneng Li 	/* flip at hsync for async, default is vsync */
1422c63dd758SMichel Dänzer 	WREG32(EVERGREEN_GRPH_FLIP_CONTROL + radeon_crtc->crtc_offset,
1423c63dd758SMichel Dänzer 	       async ? EVERGREEN_GRPH_SURFACE_UPDATE_H_RETRACE_EN : 0);
1424c841e552SZhenneng Li 	/* update pitch */
1425c841e552SZhenneng Li 	WREG32(EVERGREEN_GRPH_PITCH + radeon_crtc->crtc_offset,
1426c841e552SZhenneng Li 	       fb->pitches[0] / fb->format->cpp[0]);
1427c841e552SZhenneng Li 	/* update the scanout addresses */
14286f34be50SAlex Deucher 	WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH + radeon_crtc->crtc_offset,
14296f34be50SAlex Deucher 	       upper_32_bits(crtc_base));
14306f34be50SAlex Deucher 	WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS + radeon_crtc->crtc_offset,
14316f34be50SAlex Deucher 	       (u32)crtc_base);
1432cbd3e249SAlex Deucher 	/* post the write */
1433cbd3e249SAlex Deucher 	RREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS + radeon_crtc->crtc_offset);
1434157fa14dSChristian König }
1435157fa14dSChristian König 
1436157fa14dSChristian König /**
1437157fa14dSChristian König  * evergreen_page_flip_pending - check if page flip is still pending
1438157fa14dSChristian König  *
1439157fa14dSChristian König  * @rdev: radeon_device pointer
1440157fa14dSChristian König  * @crtc_id: crtc to check
1441157fa14dSChristian König  *
1442157fa14dSChristian König  * Returns the current update pending status.
1443157fa14dSChristian König  */
evergreen_page_flip_pending(struct radeon_device * rdev,int crtc_id)1444157fa14dSChristian König bool evergreen_page_flip_pending(struct radeon_device *rdev, int crtc_id)
1445157fa14dSChristian König {
1446157fa14dSChristian König 	struct radeon_crtc *radeon_crtc = rdev->mode_info.crtcs[crtc_id];
14476f34be50SAlex Deucher 
14486f34be50SAlex Deucher 	/* Return current update_pending status: */
1449157fa14dSChristian König 	return !!(RREG32(EVERGREEN_GRPH_UPDATE + radeon_crtc->crtc_offset) &
1450157fa14dSChristian König 		EVERGREEN_GRPH_SURFACE_UPDATE_PENDING);
14516f34be50SAlex Deucher }
14526f34be50SAlex Deucher 
145321a8122aSAlex Deucher /* get temperature in millidegrees */
evergreen_get_temp(struct radeon_device * rdev)145420d391d7SAlex Deucher int evergreen_get_temp(struct radeon_device *rdev)
145521a8122aSAlex Deucher {
14561c88d74fSAlex Deucher 	u32 temp, toffset;
14571c88d74fSAlex Deucher 	int actual_temp = 0;
145867b3f823SAlex Deucher 
145967b3f823SAlex Deucher 	if (rdev->family == CHIP_JUNIPER) {
146067b3f823SAlex Deucher 		toffset = (RREG32(CG_THERMAL_CTRL) & TOFFSET_MASK) >>
146167b3f823SAlex Deucher 			TOFFSET_SHIFT;
146267b3f823SAlex Deucher 		temp = (RREG32(CG_TS0_STATUS) & TS0_ADC_DOUT_MASK) >>
146367b3f823SAlex Deucher 			TS0_ADC_DOUT_SHIFT;
146467b3f823SAlex Deucher 
146567b3f823SAlex Deucher 		if (toffset & 0x100)
146667b3f823SAlex Deucher 			actual_temp = temp / 2 - (0x200 - toffset);
146767b3f823SAlex Deucher 		else
146867b3f823SAlex Deucher 			actual_temp = temp / 2 + toffset;
146967b3f823SAlex Deucher 
147067b3f823SAlex Deucher 		actual_temp = actual_temp * 1000;
147167b3f823SAlex Deucher 
147267b3f823SAlex Deucher 	} else {
147367b3f823SAlex Deucher 		temp = (RREG32(CG_MULT_THERMAL_STATUS) & ASIC_T_MASK) >>
147421a8122aSAlex Deucher 			ASIC_T_SHIFT;
147521a8122aSAlex Deucher 
147620d391d7SAlex Deucher 		if (temp & 0x400)
147720d391d7SAlex Deucher 			actual_temp = -256;
147820d391d7SAlex Deucher 		else if (temp & 0x200)
147921a8122aSAlex Deucher 			actual_temp = 255;
148020d391d7SAlex Deucher 		else if (temp & 0x100) {
148120d391d7SAlex Deucher 			actual_temp = temp & 0x1ff;
148220d391d7SAlex Deucher 			actual_temp |= ~0x1ff;
148320d391d7SAlex Deucher 		} else
148420d391d7SAlex Deucher 			actual_temp = temp & 0xff;
148521a8122aSAlex Deucher 
148667b3f823SAlex Deucher 		actual_temp = (actual_temp * 1000) / 2;
148767b3f823SAlex Deucher 	}
148867b3f823SAlex Deucher 
148967b3f823SAlex Deucher 	return actual_temp;
149021a8122aSAlex Deucher }
149121a8122aSAlex Deucher 
sumo_get_temp(struct radeon_device * rdev)149220d391d7SAlex Deucher int sumo_get_temp(struct radeon_device *rdev)
1493e33df25fSAlex Deucher {
1494e33df25fSAlex Deucher 	u32 temp = RREG32(CG_THERMAL_STATUS) & 0xff;
149520d391d7SAlex Deucher 	int actual_temp = temp - 49;
1496e33df25fSAlex Deucher 
1497e33df25fSAlex Deucher 	return actual_temp * 1000;
1498e33df25fSAlex Deucher }
1499e33df25fSAlex Deucher 
1500377edc8bSAlex Deucher /**
1501377edc8bSAlex Deucher  * sumo_pm_init_profile - Initialize power profiles callback.
1502377edc8bSAlex Deucher  *
1503377edc8bSAlex Deucher  * @rdev: radeon_device pointer
1504377edc8bSAlex Deucher  *
1505377edc8bSAlex Deucher  * Initialize the power states used in profile mode
1506377edc8bSAlex Deucher  * (sumo, trinity, SI).
1507377edc8bSAlex Deucher  * Used for profile mode only.
1508377edc8bSAlex Deucher  */
sumo_pm_init_profile(struct radeon_device * rdev)1509a4c9e2eeSAlex Deucher void sumo_pm_init_profile(struct radeon_device *rdev)
1510a4c9e2eeSAlex Deucher {
1511a4c9e2eeSAlex Deucher 	int idx;
1512a4c9e2eeSAlex Deucher 
1513a4c9e2eeSAlex Deucher 	/* default */
1514a4c9e2eeSAlex Deucher 	rdev->pm.profiles[PM_PROFILE_DEFAULT_IDX].dpms_off_ps_idx = rdev->pm.default_power_state_index;
1515a4c9e2eeSAlex Deucher 	rdev->pm.profiles[PM_PROFILE_DEFAULT_IDX].dpms_on_ps_idx = rdev->pm.default_power_state_index;
1516a4c9e2eeSAlex Deucher 	rdev->pm.profiles[PM_PROFILE_DEFAULT_IDX].dpms_off_cm_idx = 0;
1517a4c9e2eeSAlex Deucher 	rdev->pm.profiles[PM_PROFILE_DEFAULT_IDX].dpms_on_cm_idx = 0;
1518a4c9e2eeSAlex Deucher 
1519a4c9e2eeSAlex Deucher 	/* low,mid sh/mh */
1520a4c9e2eeSAlex Deucher 	if (rdev->flags & RADEON_IS_MOBILITY)
1521a4c9e2eeSAlex Deucher 		idx = radeon_pm_get_type_index(rdev, POWER_STATE_TYPE_BATTERY, 0);
1522a4c9e2eeSAlex Deucher 	else
1523a4c9e2eeSAlex Deucher 		idx = radeon_pm_get_type_index(rdev, POWER_STATE_TYPE_PERFORMANCE, 0);
1524a4c9e2eeSAlex Deucher 
1525a4c9e2eeSAlex Deucher 	rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_off_ps_idx = idx;
1526a4c9e2eeSAlex Deucher 	rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_on_ps_idx = idx;
1527a4c9e2eeSAlex Deucher 	rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_off_cm_idx = 0;
1528a4c9e2eeSAlex Deucher 	rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_on_cm_idx = 0;
1529a4c9e2eeSAlex Deucher 
1530a4c9e2eeSAlex Deucher 	rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_off_ps_idx = idx;
1531a4c9e2eeSAlex Deucher 	rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_on_ps_idx = idx;
1532a4c9e2eeSAlex Deucher 	rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_off_cm_idx = 0;
1533a4c9e2eeSAlex Deucher 	rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_on_cm_idx = 0;
1534a4c9e2eeSAlex Deucher 
1535a4c9e2eeSAlex Deucher 	rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_off_ps_idx = idx;
1536a4c9e2eeSAlex Deucher 	rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_on_ps_idx = idx;
1537a4c9e2eeSAlex Deucher 	rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_off_cm_idx = 0;
1538a4c9e2eeSAlex Deucher 	rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_on_cm_idx = 0;
1539a4c9e2eeSAlex Deucher 
1540a4c9e2eeSAlex Deucher 	rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_off_ps_idx = idx;
1541a4c9e2eeSAlex Deucher 	rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_on_ps_idx = idx;
1542a4c9e2eeSAlex Deucher 	rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_off_cm_idx = 0;
1543a4c9e2eeSAlex Deucher 	rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_on_cm_idx = 0;
1544a4c9e2eeSAlex Deucher 
1545a4c9e2eeSAlex Deucher 	/* high sh/mh */
1546a4c9e2eeSAlex Deucher 	idx = radeon_pm_get_type_index(rdev, POWER_STATE_TYPE_PERFORMANCE, 0);
1547a4c9e2eeSAlex Deucher 	rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_off_ps_idx = idx;
1548a4c9e2eeSAlex Deucher 	rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_on_ps_idx = idx;
1549a4c9e2eeSAlex Deucher 	rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_off_cm_idx = 0;
1550a4c9e2eeSAlex Deucher 	rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_on_cm_idx =
1551a4c9e2eeSAlex Deucher 		rdev->pm.power_state[idx].num_clock_modes - 1;
1552a4c9e2eeSAlex Deucher 
1553a4c9e2eeSAlex Deucher 	rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_off_ps_idx = idx;
1554a4c9e2eeSAlex Deucher 	rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_on_ps_idx = idx;
1555a4c9e2eeSAlex Deucher 	rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_off_cm_idx = 0;
1556a4c9e2eeSAlex Deucher 	rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_on_cm_idx =
1557a4c9e2eeSAlex Deucher 		rdev->pm.power_state[idx].num_clock_modes - 1;
1558a4c9e2eeSAlex Deucher }
1559a4c9e2eeSAlex Deucher 
1560377edc8bSAlex Deucher /**
156127810fb2SAlex Deucher  * btc_pm_init_profile - Initialize power profiles callback.
156227810fb2SAlex Deucher  *
156327810fb2SAlex Deucher  * @rdev: radeon_device pointer
156427810fb2SAlex Deucher  *
156527810fb2SAlex Deucher  * Initialize the power states used in profile mode
156627810fb2SAlex Deucher  * (BTC, cayman).
156727810fb2SAlex Deucher  * Used for profile mode only.
156827810fb2SAlex Deucher  */
btc_pm_init_profile(struct radeon_device * rdev)156927810fb2SAlex Deucher void btc_pm_init_profile(struct radeon_device *rdev)
157027810fb2SAlex Deucher {
157127810fb2SAlex Deucher 	int idx;
157227810fb2SAlex Deucher 
157327810fb2SAlex Deucher 	/* default */
157427810fb2SAlex Deucher 	rdev->pm.profiles[PM_PROFILE_DEFAULT_IDX].dpms_off_ps_idx = rdev->pm.default_power_state_index;
157527810fb2SAlex Deucher 	rdev->pm.profiles[PM_PROFILE_DEFAULT_IDX].dpms_on_ps_idx = rdev->pm.default_power_state_index;
157627810fb2SAlex Deucher 	rdev->pm.profiles[PM_PROFILE_DEFAULT_IDX].dpms_off_cm_idx = 0;
157727810fb2SAlex Deucher 	rdev->pm.profiles[PM_PROFILE_DEFAULT_IDX].dpms_on_cm_idx = 2;
157827810fb2SAlex Deucher 	/* starting with BTC, there is one state that is used for both
157927810fb2SAlex Deucher 	 * MH and SH.  Difference is that we always use the high clock index for
158027810fb2SAlex Deucher 	 * mclk.
158127810fb2SAlex Deucher 	 */
158227810fb2SAlex Deucher 	if (rdev->flags & RADEON_IS_MOBILITY)
158327810fb2SAlex Deucher 		idx = radeon_pm_get_type_index(rdev, POWER_STATE_TYPE_BATTERY, 0);
158427810fb2SAlex Deucher 	else
158527810fb2SAlex Deucher 		idx = radeon_pm_get_type_index(rdev, POWER_STATE_TYPE_PERFORMANCE, 0);
158627810fb2SAlex Deucher 	/* low sh */
158727810fb2SAlex Deucher 	rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_off_ps_idx = idx;
158827810fb2SAlex Deucher 	rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_on_ps_idx = idx;
158927810fb2SAlex Deucher 	rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_off_cm_idx = 0;
159027810fb2SAlex Deucher 	rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_on_cm_idx = 0;
159127810fb2SAlex Deucher 	/* mid sh */
159227810fb2SAlex Deucher 	rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_off_ps_idx = idx;
159327810fb2SAlex Deucher 	rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_on_ps_idx = idx;
159427810fb2SAlex Deucher 	rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_off_cm_idx = 0;
159527810fb2SAlex Deucher 	rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_on_cm_idx = 1;
159627810fb2SAlex Deucher 	/* high sh */
159727810fb2SAlex Deucher 	rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_off_ps_idx = idx;
159827810fb2SAlex Deucher 	rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_on_ps_idx = idx;
159927810fb2SAlex Deucher 	rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_off_cm_idx = 0;
160027810fb2SAlex Deucher 	rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_on_cm_idx = 2;
160127810fb2SAlex Deucher 	/* low mh */
160227810fb2SAlex Deucher 	rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_off_ps_idx = idx;
160327810fb2SAlex Deucher 	rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_on_ps_idx = idx;
160427810fb2SAlex Deucher 	rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_off_cm_idx = 0;
160527810fb2SAlex Deucher 	rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_on_cm_idx = 0;
160627810fb2SAlex Deucher 	/* mid mh */
160727810fb2SAlex Deucher 	rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_off_ps_idx = idx;
160827810fb2SAlex Deucher 	rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_on_ps_idx = idx;
160927810fb2SAlex Deucher 	rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_off_cm_idx = 0;
161027810fb2SAlex Deucher 	rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_on_cm_idx = 1;
161127810fb2SAlex Deucher 	/* high mh */
161227810fb2SAlex Deucher 	rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_off_ps_idx = idx;
161327810fb2SAlex Deucher 	rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_on_ps_idx = idx;
161427810fb2SAlex Deucher 	rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_off_cm_idx = 0;
161527810fb2SAlex Deucher 	rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_on_cm_idx = 2;
161627810fb2SAlex Deucher }
161727810fb2SAlex Deucher 
161827810fb2SAlex Deucher /**
1619377edc8bSAlex Deucher  * evergreen_pm_misc - set additional pm hw parameters callback.
1620377edc8bSAlex Deucher  *
1621377edc8bSAlex Deucher  * @rdev: radeon_device pointer
1622377edc8bSAlex Deucher  *
1623377edc8bSAlex Deucher  * Set non-clock parameters associated with a power state
1624377edc8bSAlex Deucher  * (voltage, etc.) (evergreen+).
1625377edc8bSAlex Deucher  */
evergreen_pm_misc(struct radeon_device * rdev)162649e02b73SAlex Deucher void evergreen_pm_misc(struct radeon_device *rdev)
162749e02b73SAlex Deucher {
1628a081a9d6SRafał Miłecki 	int req_ps_idx = rdev->pm.requested_power_state_index;
1629a081a9d6SRafał Miłecki 	int req_cm_idx = rdev->pm.requested_clock_mode_index;
1630a081a9d6SRafał Miłecki 	struct radeon_power_state *ps = &rdev->pm.power_state[req_ps_idx];
1631a081a9d6SRafał Miłecki 	struct radeon_voltage *voltage = &ps->clock_info[req_cm_idx].voltage;
163249e02b73SAlex Deucher 
16332feea49aSAlex Deucher 	if (voltage->type == VOLTAGE_SW) {
1634c6cf7777SAlex Deucher 		/* 0xff0x are flags rather then an actual voltage */
1635c6cf7777SAlex Deucher 		if ((voltage->voltage & 0xff00) == 0xff00)
1636a377e187SAlex Deucher 			return;
16372feea49aSAlex Deucher 		if (voltage->voltage && (voltage->voltage != rdev->pm.current_vddc)) {
16388a83ec5eSAlex Deucher 			radeon_atom_set_voltage(rdev, voltage->voltage, SET_VOLTAGE_TYPE_ASIC_VDDC);
16394d60173fSAlex Deucher 			rdev->pm.current_vddc = voltage->voltage;
16402feea49aSAlex Deucher 			DRM_DEBUG("Setting: vddc: %d\n", voltage->voltage);
16412feea49aSAlex Deucher 		}
16427ae764b1SAlex Deucher 
16437ae764b1SAlex Deucher 		/* starting with BTC, there is one state that is used for both
16447ae764b1SAlex Deucher 		 * MH and SH.  Difference is that we always use the high clock index for
16457ae764b1SAlex Deucher 		 * mclk and vddci.
16467ae764b1SAlex Deucher 		 */
16477ae764b1SAlex Deucher 		if ((rdev->pm.pm_method == PM_METHOD_PROFILE) &&
16487ae764b1SAlex Deucher 		    (rdev->family >= CHIP_BARTS) &&
16497ae764b1SAlex Deucher 		    rdev->pm.active_crtc_count &&
16507ae764b1SAlex Deucher 		    ((rdev->pm.profile_index == PM_PROFILE_MID_MH_IDX) ||
16517ae764b1SAlex Deucher 		     (rdev->pm.profile_index == PM_PROFILE_LOW_MH_IDX)))
16527ae764b1SAlex Deucher 			voltage = &rdev->pm.power_state[req_ps_idx].
16537ae764b1SAlex Deucher 				clock_info[rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_on_cm_idx].voltage;
16547ae764b1SAlex Deucher 
1655c6cf7777SAlex Deucher 		/* 0xff0x are flags rather then an actual voltage */
1656c6cf7777SAlex Deucher 		if ((voltage->vddci & 0xff00) == 0xff00)
1657a377e187SAlex Deucher 			return;
16582feea49aSAlex Deucher 		if (voltage->vddci && (voltage->vddci != rdev->pm.current_vddci)) {
16592feea49aSAlex Deucher 			radeon_atom_set_voltage(rdev, voltage->vddci, SET_VOLTAGE_TYPE_ASIC_VDDCI);
16602feea49aSAlex Deucher 			rdev->pm.current_vddci = voltage->vddci;
16612feea49aSAlex Deucher 			DRM_DEBUG("Setting: vddci: %d\n", voltage->vddci);
16624d60173fSAlex Deucher 		}
16634d60173fSAlex Deucher 	}
166449e02b73SAlex Deucher }
166549e02b73SAlex Deucher 
1666377edc8bSAlex Deucher /**
1667377edc8bSAlex Deucher  * evergreen_pm_prepare - pre-power state change callback.
1668377edc8bSAlex Deucher  *
1669377edc8bSAlex Deucher  * @rdev: radeon_device pointer
1670377edc8bSAlex Deucher  *
1671377edc8bSAlex Deucher  * Prepare for a power state change (evergreen+).
1672377edc8bSAlex Deucher  */
evergreen_pm_prepare(struct radeon_device * rdev)167349e02b73SAlex Deucher void evergreen_pm_prepare(struct radeon_device *rdev)
167449e02b73SAlex Deucher {
1675*5e3a0f77SWu Hoi Pok 	struct drm_device *ddev = rdev_to_drm(rdev);
167649e02b73SAlex Deucher 	struct drm_crtc *crtc;
167749e02b73SAlex Deucher 	struct radeon_crtc *radeon_crtc;
167849e02b73SAlex Deucher 	u32 tmp;
167949e02b73SAlex Deucher 
168049e02b73SAlex Deucher 	/* disable any active CRTCs */
168149e02b73SAlex Deucher 	list_for_each_entry(crtc, &ddev->mode_config.crtc_list, head) {
168249e02b73SAlex Deucher 		radeon_crtc = to_radeon_crtc(crtc);
168349e02b73SAlex Deucher 		if (radeon_crtc->enabled) {
168449e02b73SAlex Deucher 			tmp = RREG32(EVERGREEN_CRTC_CONTROL + radeon_crtc->crtc_offset);
168549e02b73SAlex Deucher 			tmp |= EVERGREEN_CRTC_DISP_READ_REQUEST_DISABLE;
168649e02b73SAlex Deucher 			WREG32(EVERGREEN_CRTC_CONTROL + radeon_crtc->crtc_offset, tmp);
168749e02b73SAlex Deucher 		}
168849e02b73SAlex Deucher 	}
168949e02b73SAlex Deucher }
169049e02b73SAlex Deucher 
1691377edc8bSAlex Deucher /**
1692377edc8bSAlex Deucher  * evergreen_pm_finish - post-power state change callback.
1693377edc8bSAlex Deucher  *
1694377edc8bSAlex Deucher  * @rdev: radeon_device pointer
1695377edc8bSAlex Deucher  *
1696377edc8bSAlex Deucher  * Clean up after a power state change (evergreen+).
1697377edc8bSAlex Deucher  */
evergreen_pm_finish(struct radeon_device * rdev)169849e02b73SAlex Deucher void evergreen_pm_finish(struct radeon_device *rdev)
169949e02b73SAlex Deucher {
1700*5e3a0f77SWu Hoi Pok 	struct drm_device *ddev = rdev_to_drm(rdev);
170149e02b73SAlex Deucher 	struct drm_crtc *crtc;
170249e02b73SAlex Deucher 	struct radeon_crtc *radeon_crtc;
170349e02b73SAlex Deucher 	u32 tmp;
170449e02b73SAlex Deucher 
170549e02b73SAlex Deucher 	/* enable any active CRTCs */
170649e02b73SAlex Deucher 	list_for_each_entry(crtc, &ddev->mode_config.crtc_list, head) {
170749e02b73SAlex Deucher 		radeon_crtc = to_radeon_crtc(crtc);
170849e02b73SAlex Deucher 		if (radeon_crtc->enabled) {
170949e02b73SAlex Deucher 			tmp = RREG32(EVERGREEN_CRTC_CONTROL + radeon_crtc->crtc_offset);
171049e02b73SAlex Deucher 			tmp &= ~EVERGREEN_CRTC_DISP_READ_REQUEST_DISABLE;
171149e02b73SAlex Deucher 			WREG32(EVERGREEN_CRTC_CONTROL + radeon_crtc->crtc_offset, tmp);
171249e02b73SAlex Deucher 		}
171349e02b73SAlex Deucher 	}
171449e02b73SAlex Deucher }
171549e02b73SAlex Deucher 
1716377edc8bSAlex Deucher /**
1717377edc8bSAlex Deucher  * evergreen_hpd_sense - hpd sense callback.
1718377edc8bSAlex Deucher  *
1719377edc8bSAlex Deucher  * @rdev: radeon_device pointer
1720377edc8bSAlex Deucher  * @hpd: hpd (hotplug detect) pin
1721377edc8bSAlex Deucher  *
1722377edc8bSAlex Deucher  * Checks if a digital monitor is connected (evergreen+).
1723377edc8bSAlex Deucher  * Returns true if connected, false if not connected.
1724377edc8bSAlex Deucher  */
evergreen_hpd_sense(struct radeon_device * rdev,enum radeon_hpd_id hpd)1725bcc1c2a1SAlex Deucher bool evergreen_hpd_sense(struct radeon_device *rdev, enum radeon_hpd_id hpd)
1726bcc1c2a1SAlex Deucher {
17274cd096ddSLyude 	if (hpd == RADEON_HPD_NONE)
17284cd096ddSLyude 		return false;
17290ca2ab52SAlex Deucher 
17304cd096ddSLyude 	return !!(RREG32(DC_HPDx_INT_STATUS_REG(hpd)) & DC_HPDx_SENSE);
1731bcc1c2a1SAlex Deucher }
1732bcc1c2a1SAlex Deucher 
1733377edc8bSAlex Deucher /**
1734377edc8bSAlex Deucher  * evergreen_hpd_set_polarity - hpd set polarity callback.
1735377edc8bSAlex Deucher  *
1736377edc8bSAlex Deucher  * @rdev: radeon_device pointer
1737377edc8bSAlex Deucher  * @hpd: hpd (hotplug detect) pin
1738377edc8bSAlex Deucher  *
1739377edc8bSAlex Deucher  * Set the polarity of the hpd pin (evergreen+).
1740377edc8bSAlex Deucher  */
evergreen_hpd_set_polarity(struct radeon_device * rdev,enum radeon_hpd_id hpd)1741bcc1c2a1SAlex Deucher void evergreen_hpd_set_polarity(struct radeon_device *rdev,
1742bcc1c2a1SAlex Deucher 				enum radeon_hpd_id hpd)
1743bcc1c2a1SAlex Deucher {
17440ca2ab52SAlex Deucher 	bool connected = evergreen_hpd_sense(rdev, hpd);
17450ca2ab52SAlex Deucher 
17464cd096ddSLyude 	if (hpd == RADEON_HPD_NONE)
17474cd096ddSLyude 		return;
17484cd096ddSLyude 
17490ca2ab52SAlex Deucher 	if (connected)
17504cd096ddSLyude 		WREG32_AND(DC_HPDx_INT_CONTROL(hpd), ~DC_HPDx_INT_POLARITY);
17510ca2ab52SAlex Deucher 	else
17524cd096ddSLyude 		WREG32_OR(DC_HPDx_INT_CONTROL(hpd), DC_HPDx_INT_POLARITY);
1753bcc1c2a1SAlex Deucher }
1754bcc1c2a1SAlex Deucher 
1755377edc8bSAlex Deucher /**
1756377edc8bSAlex Deucher  * evergreen_hpd_init - hpd setup callback.
1757377edc8bSAlex Deucher  *
1758377edc8bSAlex Deucher  * @rdev: radeon_device pointer
1759377edc8bSAlex Deucher  *
1760377edc8bSAlex Deucher  * Setup the hpd pins used by the card (evergreen+).
1761377edc8bSAlex Deucher  * Enable the pin, set the polarity, and enable the hpd interrupts.
1762377edc8bSAlex Deucher  */
evergreen_hpd_init(struct radeon_device * rdev)1763bcc1c2a1SAlex Deucher void evergreen_hpd_init(struct radeon_device *rdev)
1764bcc1c2a1SAlex Deucher {
1765*5e3a0f77SWu Hoi Pok 	struct drm_device *dev = rdev_to_drm(rdev);
17660ca2ab52SAlex Deucher 	struct drm_connector *connector;
1767fb98257aSChristian Koenig 	unsigned enabled = 0;
17680ca2ab52SAlex Deucher 	u32 tmp = DC_HPDx_CONNECTION_TIMER(0x9c4) |
17690ca2ab52SAlex Deucher 		DC_HPDx_RX_INT_TIMER(0xfa) | DC_HPDx_EN;
17700ca2ab52SAlex Deucher 
17710ca2ab52SAlex Deucher 	list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
17724cd096ddSLyude 		enum radeon_hpd_id hpd =
17734cd096ddSLyude 			to_radeon_connector(connector)->hpd.hpd;
17742e97be73SAlex Deucher 
17752e97be73SAlex Deucher 		if (connector->connector_type == DRM_MODE_CONNECTOR_eDP ||
17762e97be73SAlex Deucher 		    connector->connector_type == DRM_MODE_CONNECTOR_LVDS) {
17772e97be73SAlex Deucher 			/* don't try to enable hpd on eDP or LVDS avoid breaking the
17782e97be73SAlex Deucher 			 * aux dp channel on imac and help (but not completely fix)
17792e97be73SAlex Deucher 			 * https://bugzilla.redhat.com/show_bug.cgi?id=726143
17802e97be73SAlex Deucher 			 * also avoid interrupt storms during dpms.
17812e97be73SAlex Deucher 			 */
17822e97be73SAlex Deucher 			continue;
17832e97be73SAlex Deucher 		}
17844cd096ddSLyude 
17854cd096ddSLyude 		if (hpd == RADEON_HPD_NONE)
17864cd096ddSLyude 			continue;
17874cd096ddSLyude 
17884cd096ddSLyude 		WREG32(DC_HPDx_CONTROL(hpd), tmp);
17894cd096ddSLyude 		enabled |= 1 << hpd;
17904cd096ddSLyude 
17914cd096ddSLyude 		radeon_hpd_set_polarity(rdev, hpd);
17920ca2ab52SAlex Deucher 	}
1793fb98257aSChristian Koenig 	radeon_irq_kms_enable_hpd(rdev, enabled);
1794bcc1c2a1SAlex Deucher }
1795bcc1c2a1SAlex Deucher 
1796377edc8bSAlex Deucher /**
1797377edc8bSAlex Deucher  * evergreen_hpd_fini - hpd tear down callback.
1798377edc8bSAlex Deucher  *
1799377edc8bSAlex Deucher  * @rdev: radeon_device pointer
1800377edc8bSAlex Deucher  *
1801377edc8bSAlex Deucher  * Tear down the hpd pins used by the card (evergreen+).
1802377edc8bSAlex Deucher  * Disable the hpd interrupts.
1803377edc8bSAlex Deucher  */
evergreen_hpd_fini(struct radeon_device * rdev)1804bcc1c2a1SAlex Deucher void evergreen_hpd_fini(struct radeon_device *rdev)
1805bcc1c2a1SAlex Deucher {
1806*5e3a0f77SWu Hoi Pok 	struct drm_device *dev = rdev_to_drm(rdev);
18070ca2ab52SAlex Deucher 	struct drm_connector *connector;
1808fb98257aSChristian Koenig 	unsigned disabled = 0;
18090ca2ab52SAlex Deucher 
18100ca2ab52SAlex Deucher 	list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
18114cd096ddSLyude 		enum radeon_hpd_id hpd =
18124cd096ddSLyude 			to_radeon_connector(connector)->hpd.hpd;
18134cd096ddSLyude 
18144cd096ddSLyude 		if (hpd == RADEON_HPD_NONE)
18154cd096ddSLyude 			continue;
18164cd096ddSLyude 
18174cd096ddSLyude 		WREG32(DC_HPDx_CONTROL(hpd), 0);
18184cd096ddSLyude 		disabled |= 1 << hpd;
18190ca2ab52SAlex Deucher 	}
1820fb98257aSChristian Koenig 	radeon_irq_kms_disable_hpd(rdev, disabled);
18210ca2ab52SAlex Deucher }
18220ca2ab52SAlex Deucher 
1823f9d9c362SAlex Deucher /* watermark setup */
1824f9d9c362SAlex Deucher 
evergreen_line_buffer_adjust(struct radeon_device * rdev,struct radeon_crtc * radeon_crtc,struct drm_display_mode * mode,struct drm_display_mode * other_mode)1825f9d9c362SAlex Deucher static u32 evergreen_line_buffer_adjust(struct radeon_device *rdev,
1826f9d9c362SAlex Deucher 					struct radeon_crtc *radeon_crtc,
1827f9d9c362SAlex Deucher 					struct drm_display_mode *mode,
1828f9d9c362SAlex Deucher 					struct drm_display_mode *other_mode)
1829f9d9c362SAlex Deucher {
18300b31e023SAlex Deucher 	u32 tmp, buffer_alloc, i;
18310b31e023SAlex Deucher 	u32 pipe_offset = radeon_crtc->crtc_id * 0x20;
1832f9d9c362SAlex Deucher 	/*
1833f9d9c362SAlex Deucher 	 * Line Buffer Setup
1834f9d9c362SAlex Deucher 	 * There are 3 line buffers, each one shared by 2 display controllers.
1835f9d9c362SAlex Deucher 	 * DC_LB_MEMORY_SPLIT controls how that line buffer is shared between
1836f9d9c362SAlex Deucher 	 * the display controllers.  The paritioning is done via one of four
1837f9d9c362SAlex Deucher 	 * preset allocations specified in bits 2:0:
1838f9d9c362SAlex Deucher 	 * first display controller
1839f9d9c362SAlex Deucher 	 *  0 - first half of lb (3840 * 2)
1840f9d9c362SAlex Deucher 	 *  1 - first 3/4 of lb (5760 * 2)
184112dfc843SAlex Deucher 	 *  2 - whole lb (7680 * 2), other crtc must be disabled
1842f9d9c362SAlex Deucher 	 *  3 - first 1/4 of lb (1920 * 2)
1843f9d9c362SAlex Deucher 	 * second display controller
1844f9d9c362SAlex Deucher 	 *  4 - second half of lb (3840 * 2)
1845f9d9c362SAlex Deucher 	 *  5 - second 3/4 of lb (5760 * 2)
184612dfc843SAlex Deucher 	 *  6 - whole lb (7680 * 2), other crtc must be disabled
1847f9d9c362SAlex Deucher 	 *  7 - last 1/4 of lb (1920 * 2)
1848f9d9c362SAlex Deucher 	 */
184912dfc843SAlex Deucher 	/* this can get tricky if we have two large displays on a paired group
185012dfc843SAlex Deucher 	 * of crtcs.  Ideally for multiple large displays we'd assign them to
185112dfc843SAlex Deucher 	 * non-linked crtcs for maximum line buffer allocation.
185212dfc843SAlex Deucher 	 */
185312dfc843SAlex Deucher 	if (radeon_crtc->base.enabled && mode) {
18540b31e023SAlex Deucher 		if (other_mode) {
185512dfc843SAlex Deucher 			tmp = 0; /* 1/2 */
18560b31e023SAlex Deucher 			buffer_alloc = 1;
18570b31e023SAlex Deucher 		} else {
1858f9d9c362SAlex Deucher 			tmp = 2; /* whole */
18590b31e023SAlex Deucher 			buffer_alloc = 2;
18600b31e023SAlex Deucher 		}
18610b31e023SAlex Deucher 	} else {
186212dfc843SAlex Deucher 		tmp = 0;
18630b31e023SAlex Deucher 		buffer_alloc = 0;
18640b31e023SAlex Deucher 	}
1865f9d9c362SAlex Deucher 
1866f9d9c362SAlex Deucher 	/* second controller of the pair uses second half of the lb */
1867f9d9c362SAlex Deucher 	if (radeon_crtc->crtc_id % 2)
1868f9d9c362SAlex Deucher 		tmp += 4;
1869f9d9c362SAlex Deucher 	WREG32(DC_LB_MEMORY_SPLIT + radeon_crtc->crtc_offset, tmp);
1870f9d9c362SAlex Deucher 
18710b31e023SAlex Deucher 	if (ASIC_IS_DCE41(rdev) || ASIC_IS_DCE5(rdev)) {
18720b31e023SAlex Deucher 		WREG32(PIPE0_DMIF_BUFFER_CONTROL + pipe_offset,
18730b31e023SAlex Deucher 		       DMIF_BUFFERS_ALLOCATED(buffer_alloc));
18740b31e023SAlex Deucher 		for (i = 0; i < rdev->usec_timeout; i++) {
18750b31e023SAlex Deucher 			if (RREG32(PIPE0_DMIF_BUFFER_CONTROL + pipe_offset) &
18760b31e023SAlex Deucher 			    DMIF_BUFFERS_ALLOCATED_COMPLETED)
18770b31e023SAlex Deucher 				break;
18780b31e023SAlex Deucher 			udelay(1);
18790b31e023SAlex Deucher 		}
18800b31e023SAlex Deucher 	}
18810b31e023SAlex Deucher 
188212dfc843SAlex Deucher 	if (radeon_crtc->base.enabled && mode) {
1883f9d9c362SAlex Deucher 		switch (tmp) {
1884f9d9c362SAlex Deucher 		case 0:
1885f9d9c362SAlex Deucher 		case 4:
1886f9d9c362SAlex Deucher 		default:
1887936b27ccSAlex Deucher 			if (ASIC_IS_DCE5(rdev))
1888936b27ccSAlex Deucher 				return 4096 * 2;
1889936b27ccSAlex Deucher 			else
1890f9d9c362SAlex Deucher 				return 3840 * 2;
1891f9d9c362SAlex Deucher 		case 1:
1892f9d9c362SAlex Deucher 		case 5:
1893936b27ccSAlex Deucher 			if (ASIC_IS_DCE5(rdev))
1894936b27ccSAlex Deucher 				return 6144 * 2;
1895936b27ccSAlex Deucher 			else
1896f9d9c362SAlex Deucher 				return 5760 * 2;
1897f9d9c362SAlex Deucher 		case 2:
1898f9d9c362SAlex Deucher 		case 6:
1899936b27ccSAlex Deucher 			if (ASIC_IS_DCE5(rdev))
1900936b27ccSAlex Deucher 				return 8192 * 2;
1901936b27ccSAlex Deucher 			else
1902f9d9c362SAlex Deucher 				return 7680 * 2;
1903f9d9c362SAlex Deucher 		case 3:
1904f9d9c362SAlex Deucher 		case 7:
1905936b27ccSAlex Deucher 			if (ASIC_IS_DCE5(rdev))
1906936b27ccSAlex Deucher 				return 2048 * 2;
1907936b27ccSAlex Deucher 			else
1908f9d9c362SAlex Deucher 				return 1920 * 2;
1909f9d9c362SAlex Deucher 		}
1910f9d9c362SAlex Deucher 	}
1911f9d9c362SAlex Deucher 
191212dfc843SAlex Deucher 	/* controller not enabled, so no lb used */
191312dfc843SAlex Deucher 	return 0;
191412dfc843SAlex Deucher }
191512dfc843SAlex Deucher 
evergreen_get_number_of_dram_channels(struct radeon_device * rdev)1916ca7db22bSAlex Deucher u32 evergreen_get_number_of_dram_channels(struct radeon_device *rdev)
1917f9d9c362SAlex Deucher {
1918f9d9c362SAlex Deucher 	u32 tmp = RREG32(MC_SHARED_CHMAP);
1919f9d9c362SAlex Deucher 
1920f9d9c362SAlex Deucher 	switch ((tmp & NOOFCHAN_MASK) >> NOOFCHAN_SHIFT) {
1921f9d9c362SAlex Deucher 	case 0:
1922f9d9c362SAlex Deucher 	default:
1923f9d9c362SAlex Deucher 		return 1;
1924f9d9c362SAlex Deucher 	case 1:
1925f9d9c362SAlex Deucher 		return 2;
1926f9d9c362SAlex Deucher 	case 2:
1927f9d9c362SAlex Deucher 		return 4;
1928f9d9c362SAlex Deucher 	case 3:
1929f9d9c362SAlex Deucher 		return 8;
1930f9d9c362SAlex Deucher 	}
1931f9d9c362SAlex Deucher }
1932f9d9c362SAlex Deucher 
1933f9d9c362SAlex Deucher struct evergreen_wm_params {
1934f9d9c362SAlex Deucher 	u32 dram_channels; /* number of dram channels */
1935f9d9c362SAlex Deucher 	u32 yclk;          /* bandwidth per dram data pin in kHz */
1936f9d9c362SAlex Deucher 	u32 sclk;          /* engine clock in kHz */
1937f9d9c362SAlex Deucher 	u32 disp_clk;      /* display clock in kHz */
1938f9d9c362SAlex Deucher 	u32 src_width;     /* viewport width */
1939f9d9c362SAlex Deucher 	u32 active_time;   /* active display time in ns */
1940f9d9c362SAlex Deucher 	u32 blank_time;    /* blank time in ns */
1941f9d9c362SAlex Deucher 	bool interlaced;    /* mode is interlaced */
1942f9d9c362SAlex Deucher 	fixed20_12 vsc;    /* vertical scale ratio */
1943f9d9c362SAlex Deucher 	u32 num_heads;     /* number of active crtcs */
1944f9d9c362SAlex Deucher 	u32 bytes_per_pixel; /* bytes per pixel display + overlay */
1945f9d9c362SAlex Deucher 	u32 lb_size;       /* line buffer allocated to pipe */
1946f9d9c362SAlex Deucher 	u32 vtaps;         /* vertical scaler taps */
1947f9d9c362SAlex Deucher };
1948f9d9c362SAlex Deucher 
evergreen_dram_bandwidth(struct evergreen_wm_params * wm)1949f9d9c362SAlex Deucher static u32 evergreen_dram_bandwidth(struct evergreen_wm_params *wm)
1950f9d9c362SAlex Deucher {
1951f9d9c362SAlex Deucher 	/* Calculate DRAM Bandwidth and the part allocated to display. */
1952f9d9c362SAlex Deucher 	fixed20_12 dram_efficiency; /* 0.7 */
1953f9d9c362SAlex Deucher 	fixed20_12 yclk, dram_channels, bandwidth;
1954f9d9c362SAlex Deucher 	fixed20_12 a;
1955f9d9c362SAlex Deucher 
1956f9d9c362SAlex Deucher 	a.full = dfixed_const(1000);
1957f9d9c362SAlex Deucher 	yclk.full = dfixed_const(wm->yclk);
1958f9d9c362SAlex Deucher 	yclk.full = dfixed_div(yclk, a);
1959f9d9c362SAlex Deucher 	dram_channels.full = dfixed_const(wm->dram_channels * 4);
1960f9d9c362SAlex Deucher 	a.full = dfixed_const(10);
1961f9d9c362SAlex Deucher 	dram_efficiency.full = dfixed_const(7);
1962f9d9c362SAlex Deucher 	dram_efficiency.full = dfixed_div(dram_efficiency, a);
1963f9d9c362SAlex Deucher 	bandwidth.full = dfixed_mul(dram_channels, yclk);
1964f9d9c362SAlex Deucher 	bandwidth.full = dfixed_mul(bandwidth, dram_efficiency);
1965f9d9c362SAlex Deucher 
1966f9d9c362SAlex Deucher 	return dfixed_trunc(bandwidth);
1967f9d9c362SAlex Deucher }
1968f9d9c362SAlex Deucher 
evergreen_dram_bandwidth_for_display(struct evergreen_wm_params * wm)1969f9d9c362SAlex Deucher static u32 evergreen_dram_bandwidth_for_display(struct evergreen_wm_params *wm)
1970f9d9c362SAlex Deucher {
1971f9d9c362SAlex Deucher 	/* Calculate DRAM Bandwidth and the part allocated to display. */
1972f9d9c362SAlex Deucher 	fixed20_12 disp_dram_allocation; /* 0.3 to 0.7 */
1973f9d9c362SAlex Deucher 	fixed20_12 yclk, dram_channels, bandwidth;
1974f9d9c362SAlex Deucher 	fixed20_12 a;
1975f9d9c362SAlex Deucher 
1976f9d9c362SAlex Deucher 	a.full = dfixed_const(1000);
1977f9d9c362SAlex Deucher 	yclk.full = dfixed_const(wm->yclk);
1978f9d9c362SAlex Deucher 	yclk.full = dfixed_div(yclk, a);
1979f9d9c362SAlex Deucher 	dram_channels.full = dfixed_const(wm->dram_channels * 4);
1980f9d9c362SAlex Deucher 	a.full = dfixed_const(10);
1981f9d9c362SAlex Deucher 	disp_dram_allocation.full = dfixed_const(3); /* XXX worse case value 0.3 */
1982f9d9c362SAlex Deucher 	disp_dram_allocation.full = dfixed_div(disp_dram_allocation, a);
1983f9d9c362SAlex Deucher 	bandwidth.full = dfixed_mul(dram_channels, yclk);
1984f9d9c362SAlex Deucher 	bandwidth.full = dfixed_mul(bandwidth, disp_dram_allocation);
1985f9d9c362SAlex Deucher 
1986f9d9c362SAlex Deucher 	return dfixed_trunc(bandwidth);
1987f9d9c362SAlex Deucher }
1988f9d9c362SAlex Deucher 
evergreen_data_return_bandwidth(struct evergreen_wm_params * wm)1989f9d9c362SAlex Deucher static u32 evergreen_data_return_bandwidth(struct evergreen_wm_params *wm)
1990f9d9c362SAlex Deucher {
1991f9d9c362SAlex Deucher 	/* Calculate the display Data return Bandwidth */
1992f9d9c362SAlex Deucher 	fixed20_12 return_efficiency; /* 0.8 */
1993f9d9c362SAlex Deucher 	fixed20_12 sclk, bandwidth;
1994f9d9c362SAlex Deucher 	fixed20_12 a;
1995f9d9c362SAlex Deucher 
1996f9d9c362SAlex Deucher 	a.full = dfixed_const(1000);
1997f9d9c362SAlex Deucher 	sclk.full = dfixed_const(wm->sclk);
1998f9d9c362SAlex Deucher 	sclk.full = dfixed_div(sclk, a);
1999f9d9c362SAlex Deucher 	a.full = dfixed_const(10);
2000f9d9c362SAlex Deucher 	return_efficiency.full = dfixed_const(8);
2001f9d9c362SAlex Deucher 	return_efficiency.full = dfixed_div(return_efficiency, a);
2002f9d9c362SAlex Deucher 	a.full = dfixed_const(32);
2003f9d9c362SAlex Deucher 	bandwidth.full = dfixed_mul(a, sclk);
2004f9d9c362SAlex Deucher 	bandwidth.full = dfixed_mul(bandwidth, return_efficiency);
2005f9d9c362SAlex Deucher 
2006f9d9c362SAlex Deucher 	return dfixed_trunc(bandwidth);
2007f9d9c362SAlex Deucher }
2008f9d9c362SAlex Deucher 
evergreen_dmif_request_bandwidth(struct evergreen_wm_params * wm)2009f9d9c362SAlex Deucher static u32 evergreen_dmif_request_bandwidth(struct evergreen_wm_params *wm)
2010f9d9c362SAlex Deucher {
2011f9d9c362SAlex Deucher 	/* Calculate the DMIF Request Bandwidth */
2012f9d9c362SAlex Deucher 	fixed20_12 disp_clk_request_efficiency; /* 0.8 */
2013f9d9c362SAlex Deucher 	fixed20_12 disp_clk, bandwidth;
2014f9d9c362SAlex Deucher 	fixed20_12 a;
2015f9d9c362SAlex Deucher 
2016f9d9c362SAlex Deucher 	a.full = dfixed_const(1000);
2017f9d9c362SAlex Deucher 	disp_clk.full = dfixed_const(wm->disp_clk);
2018f9d9c362SAlex Deucher 	disp_clk.full = dfixed_div(disp_clk, a);
2019f9d9c362SAlex Deucher 	a.full = dfixed_const(10);
2020f9d9c362SAlex Deucher 	disp_clk_request_efficiency.full = dfixed_const(8);
2021f9d9c362SAlex Deucher 	disp_clk_request_efficiency.full = dfixed_div(disp_clk_request_efficiency, a);
2022f9d9c362SAlex Deucher 	a.full = dfixed_const(32);
2023f9d9c362SAlex Deucher 	bandwidth.full = dfixed_mul(a, disp_clk);
2024f9d9c362SAlex Deucher 	bandwidth.full = dfixed_mul(bandwidth, disp_clk_request_efficiency);
2025f9d9c362SAlex Deucher 
2026f9d9c362SAlex Deucher 	return dfixed_trunc(bandwidth);
2027f9d9c362SAlex Deucher }
2028f9d9c362SAlex Deucher 
evergreen_available_bandwidth(struct evergreen_wm_params * wm)2029f9d9c362SAlex Deucher static u32 evergreen_available_bandwidth(struct evergreen_wm_params *wm)
2030f9d9c362SAlex Deucher {
2031f9d9c362SAlex Deucher 	/* Calculate the Available bandwidth. Display can use this temporarily but not in average. */
2032f9d9c362SAlex Deucher 	u32 dram_bandwidth = evergreen_dram_bandwidth(wm);
2033f9d9c362SAlex Deucher 	u32 data_return_bandwidth = evergreen_data_return_bandwidth(wm);
2034f9d9c362SAlex Deucher 	u32 dmif_req_bandwidth = evergreen_dmif_request_bandwidth(wm);
2035f9d9c362SAlex Deucher 
2036f9d9c362SAlex Deucher 	return min(dram_bandwidth, min(data_return_bandwidth, dmif_req_bandwidth));
2037f9d9c362SAlex Deucher }
2038f9d9c362SAlex Deucher 
evergreen_average_bandwidth(struct evergreen_wm_params * wm)2039f9d9c362SAlex Deucher static u32 evergreen_average_bandwidth(struct evergreen_wm_params *wm)
2040f9d9c362SAlex Deucher {
2041f9d9c362SAlex Deucher 	/* Calculate the display mode Average Bandwidth
2042f9d9c362SAlex Deucher 	 * DisplayMode should contain the source and destination dimensions,
2043f9d9c362SAlex Deucher 	 * timing, etc.
2044f9d9c362SAlex Deucher 	 */
2045f9d9c362SAlex Deucher 	fixed20_12 bpp;
2046f9d9c362SAlex Deucher 	fixed20_12 line_time;
2047f9d9c362SAlex Deucher 	fixed20_12 src_width;
2048f9d9c362SAlex Deucher 	fixed20_12 bandwidth;
2049f9d9c362SAlex Deucher 	fixed20_12 a;
2050f9d9c362SAlex Deucher 
2051f9d9c362SAlex Deucher 	a.full = dfixed_const(1000);
2052f9d9c362SAlex Deucher 	line_time.full = dfixed_const(wm->active_time + wm->blank_time);
2053f9d9c362SAlex Deucher 	line_time.full = dfixed_div(line_time, a);
2054f9d9c362SAlex Deucher 	bpp.full = dfixed_const(wm->bytes_per_pixel);
2055f9d9c362SAlex Deucher 	src_width.full = dfixed_const(wm->src_width);
2056f9d9c362SAlex Deucher 	bandwidth.full = dfixed_mul(src_width, bpp);
2057f9d9c362SAlex Deucher 	bandwidth.full = dfixed_mul(bandwidth, wm->vsc);
2058f9d9c362SAlex Deucher 	bandwidth.full = dfixed_div(bandwidth, line_time);
2059f9d9c362SAlex Deucher 
2060f9d9c362SAlex Deucher 	return dfixed_trunc(bandwidth);
2061f9d9c362SAlex Deucher }
2062f9d9c362SAlex Deucher 
evergreen_latency_watermark(struct evergreen_wm_params * wm)2063f9d9c362SAlex Deucher static u32 evergreen_latency_watermark(struct evergreen_wm_params *wm)
2064f9d9c362SAlex Deucher {
2065f9d9c362SAlex Deucher 	/* First calcualte the latency in ns */
2066f9d9c362SAlex Deucher 	u32 mc_latency = 2000; /* 2000 ns. */
2067f9d9c362SAlex Deucher 	u32 available_bandwidth = evergreen_available_bandwidth(wm);
2068f9d9c362SAlex Deucher 	u32 worst_chunk_return_time = (512 * 8 * 1000) / available_bandwidth;
2069f9d9c362SAlex Deucher 	u32 cursor_line_pair_return_time = (128 * 4 * 1000) / available_bandwidth;
2070f9d9c362SAlex Deucher 	u32 dc_latency = 40000000 / wm->disp_clk; /* dc pipe latency */
2071f9d9c362SAlex Deucher 	u32 other_heads_data_return_time = ((wm->num_heads + 1) * worst_chunk_return_time) +
2072f9d9c362SAlex Deucher 		(wm->num_heads * cursor_line_pair_return_time);
2073f9d9c362SAlex Deucher 	u32 latency = mc_latency + other_heads_data_return_time + dc_latency;
2074f9d9c362SAlex Deucher 	u32 max_src_lines_per_dst_line, lb_fill_bw, line_fill_time;
2075f9d9c362SAlex Deucher 	fixed20_12 a, b, c;
2076f9d9c362SAlex Deucher 
2077f9d9c362SAlex Deucher 	if (wm->num_heads == 0)
2078f9d9c362SAlex Deucher 		return 0;
2079f9d9c362SAlex Deucher 
2080f9d9c362SAlex Deucher 	a.full = dfixed_const(2);
2081f9d9c362SAlex Deucher 	b.full = dfixed_const(1);
2082f9d9c362SAlex Deucher 	if ((wm->vsc.full > a.full) ||
2083f9d9c362SAlex Deucher 	    ((wm->vsc.full > b.full) && (wm->vtaps >= 3)) ||
2084f9d9c362SAlex Deucher 	    (wm->vtaps >= 5) ||
2085f9d9c362SAlex Deucher 	    ((wm->vsc.full >= a.full) && wm->interlaced))
2086f9d9c362SAlex Deucher 		max_src_lines_per_dst_line = 4;
2087f9d9c362SAlex Deucher 	else
2088f9d9c362SAlex Deucher 		max_src_lines_per_dst_line = 2;
2089f9d9c362SAlex Deucher 
2090f9d9c362SAlex Deucher 	a.full = dfixed_const(available_bandwidth);
2091f9d9c362SAlex Deucher 	b.full = dfixed_const(wm->num_heads);
2092f9d9c362SAlex Deucher 	a.full = dfixed_div(a, b);
2093f9d9c362SAlex Deucher 
2094ae45bbc2SMario Kleiner 	lb_fill_bw = min(dfixed_trunc(a), wm->disp_clk * wm->bytes_per_pixel / 1000);
2095f9d9c362SAlex Deucher 
2096f9d9c362SAlex Deucher 	a.full = dfixed_const(max_src_lines_per_dst_line * wm->src_width * wm->bytes_per_pixel);
2097f9d9c362SAlex Deucher 	b.full = dfixed_const(1000);
2098f9d9c362SAlex Deucher 	c.full = dfixed_const(lb_fill_bw);
2099f9d9c362SAlex Deucher 	b.full = dfixed_div(c, b);
2100f9d9c362SAlex Deucher 	a.full = dfixed_div(a, b);
2101f9d9c362SAlex Deucher 	line_fill_time = dfixed_trunc(a);
2102f9d9c362SAlex Deucher 
2103f9d9c362SAlex Deucher 	if (line_fill_time < wm->active_time)
2104f9d9c362SAlex Deucher 		return latency;
2105f9d9c362SAlex Deucher 	else
2106f9d9c362SAlex Deucher 		return latency + (line_fill_time - wm->active_time);
2107f9d9c362SAlex Deucher 
2108f9d9c362SAlex Deucher }
2109f9d9c362SAlex Deucher 
evergreen_average_bandwidth_vs_dram_bandwidth_for_display(struct evergreen_wm_params * wm)2110f9d9c362SAlex Deucher static bool evergreen_average_bandwidth_vs_dram_bandwidth_for_display(struct evergreen_wm_params *wm)
2111f9d9c362SAlex Deucher {
2112f9d9c362SAlex Deucher 	if (evergreen_average_bandwidth(wm) <=
2113f9d9c362SAlex Deucher 	    (evergreen_dram_bandwidth_for_display(wm) / wm->num_heads))
2114f9d9c362SAlex Deucher 		return true;
2115f9d9c362SAlex Deucher 	else
2116f9d9c362SAlex Deucher 		return false;
2117f9d9c362SAlex Deucher };
2118f9d9c362SAlex Deucher 
evergreen_average_bandwidth_vs_available_bandwidth(struct evergreen_wm_params * wm)2119f9d9c362SAlex Deucher static bool evergreen_average_bandwidth_vs_available_bandwidth(struct evergreen_wm_params *wm)
2120f9d9c362SAlex Deucher {
2121f9d9c362SAlex Deucher 	if (evergreen_average_bandwidth(wm) <=
2122f9d9c362SAlex Deucher 	    (evergreen_available_bandwidth(wm) / wm->num_heads))
2123f9d9c362SAlex Deucher 		return true;
2124f9d9c362SAlex Deucher 	else
2125f9d9c362SAlex Deucher 		return false;
2126f9d9c362SAlex Deucher };
2127f9d9c362SAlex Deucher 
evergreen_check_latency_hiding(struct evergreen_wm_params * wm)2128f9d9c362SAlex Deucher static bool evergreen_check_latency_hiding(struct evergreen_wm_params *wm)
2129f9d9c362SAlex Deucher {
2130f9d9c362SAlex Deucher 	u32 lb_partitions = wm->lb_size / wm->src_width;
2131f9d9c362SAlex Deucher 	u32 line_time = wm->active_time + wm->blank_time;
2132f9d9c362SAlex Deucher 	u32 latency_tolerant_lines;
2133f9d9c362SAlex Deucher 	u32 latency_hiding;
2134f9d9c362SAlex Deucher 	fixed20_12 a;
2135f9d9c362SAlex Deucher 
2136f9d9c362SAlex Deucher 	a.full = dfixed_const(1);
2137f9d9c362SAlex Deucher 	if (wm->vsc.full > a.full)
2138f9d9c362SAlex Deucher 		latency_tolerant_lines = 1;
2139f9d9c362SAlex Deucher 	else {
2140f9d9c362SAlex Deucher 		if (lb_partitions <= (wm->vtaps + 1))
2141f9d9c362SAlex Deucher 			latency_tolerant_lines = 1;
2142f9d9c362SAlex Deucher 		else
2143f9d9c362SAlex Deucher 			latency_tolerant_lines = 2;
2144f9d9c362SAlex Deucher 	}
2145f9d9c362SAlex Deucher 
2146f9d9c362SAlex Deucher 	latency_hiding = (latency_tolerant_lines * line_time + wm->blank_time);
2147f9d9c362SAlex Deucher 
2148f9d9c362SAlex Deucher 	if (evergreen_latency_watermark(wm) <= latency_hiding)
2149f9d9c362SAlex Deucher 		return true;
2150f9d9c362SAlex Deucher 	else
2151f9d9c362SAlex Deucher 		return false;
2152f9d9c362SAlex Deucher }
2153f9d9c362SAlex Deucher 
evergreen_program_watermarks(struct radeon_device * rdev,struct radeon_crtc * radeon_crtc,u32 lb_size,u32 num_heads)2154f9d9c362SAlex Deucher static void evergreen_program_watermarks(struct radeon_device *rdev,
2155f9d9c362SAlex Deucher 					 struct radeon_crtc *radeon_crtc,
2156f9d9c362SAlex Deucher 					 u32 lb_size, u32 num_heads)
2157f9d9c362SAlex Deucher {
2158f9d9c362SAlex Deucher 	struct drm_display_mode *mode = &radeon_crtc->base.mode;
2159cf0cfdd7SAlex Deucher 	struct evergreen_wm_params wm_low, wm_high;
2160cf0cfdd7SAlex Deucher 	u32 dram_channels;
2161e6b9a6c8SMario Kleiner 	u32 active_time;
2162f9d9c362SAlex Deucher 	u32 line_time = 0;
2163f9d9c362SAlex Deucher 	u32 latency_watermark_a = 0, latency_watermark_b = 0;
2164f9d9c362SAlex Deucher 	u32 priority_a_mark = 0, priority_b_mark = 0;
2165f9d9c362SAlex Deucher 	u32 priority_a_cnt = PRIORITY_OFF;
2166f9d9c362SAlex Deucher 	u32 priority_b_cnt = PRIORITY_OFF;
2167f9d9c362SAlex Deucher 	u32 pipe_offset = radeon_crtc->crtc_id * 16;
2168f9d9c362SAlex Deucher 	u32 tmp, arb_control3;
2169f9d9c362SAlex Deucher 	fixed20_12 a, b, c;
2170f9d9c362SAlex Deucher 
2171f9d9c362SAlex Deucher 	if (radeon_crtc->base.enabled && num_heads && mode) {
217255f61a04SMario Kleiner 		active_time = (u32) div_u64((u64)mode->crtc_hdisplay * 1000000,
217355f61a04SMario Kleiner 					    (u32)mode->clock);
217455f61a04SMario Kleiner 		line_time = (u32) div_u64((u64)mode->crtc_htotal * 1000000,
217555f61a04SMario Kleiner 					  (u32)mode->clock);
217655f61a04SMario Kleiner 		line_time = min(line_time, (u32)65535);
2177f9d9c362SAlex Deucher 		priority_a_cnt = 0;
2178f9d9c362SAlex Deucher 		priority_b_cnt = 0;
2179cf0cfdd7SAlex Deucher 		dram_channels = evergreen_get_number_of_dram_channels(rdev);
2180f9d9c362SAlex Deucher 
2181cf0cfdd7SAlex Deucher 		/* watermark for high clocks */
2182cf0cfdd7SAlex Deucher 		if ((rdev->pm.pm_method == PM_METHOD_DPM) && rdev->pm.dpm_enabled) {
2183cf0cfdd7SAlex Deucher 			wm_high.yclk =
2184cf0cfdd7SAlex Deucher 				radeon_dpm_get_mclk(rdev, false) * 10;
2185cf0cfdd7SAlex Deucher 			wm_high.sclk =
2186cf0cfdd7SAlex Deucher 				radeon_dpm_get_sclk(rdev, false) * 10;
2187cf0cfdd7SAlex Deucher 		} else {
2188cf0cfdd7SAlex Deucher 			wm_high.yclk = rdev->pm.current_mclk * 10;
2189cf0cfdd7SAlex Deucher 			wm_high.sclk = rdev->pm.current_sclk * 10;
2190cf0cfdd7SAlex Deucher 		}
2191cf0cfdd7SAlex Deucher 
2192cf0cfdd7SAlex Deucher 		wm_high.disp_clk = mode->clock;
2193cf0cfdd7SAlex Deucher 		wm_high.src_width = mode->crtc_hdisplay;
2194e6b9a6c8SMario Kleiner 		wm_high.active_time = active_time;
2195cf0cfdd7SAlex Deucher 		wm_high.blank_time = line_time - wm_high.active_time;
2196cf0cfdd7SAlex Deucher 		wm_high.interlaced = false;
2197f9d9c362SAlex Deucher 		if (mode->flags & DRM_MODE_FLAG_INTERLACE)
2198cf0cfdd7SAlex Deucher 			wm_high.interlaced = true;
2199cf0cfdd7SAlex Deucher 		wm_high.vsc = radeon_crtc->vsc;
2200cf0cfdd7SAlex Deucher 		wm_high.vtaps = 1;
2201f9d9c362SAlex Deucher 		if (radeon_crtc->rmx_type != RMX_OFF)
2202cf0cfdd7SAlex Deucher 			wm_high.vtaps = 2;
2203cf0cfdd7SAlex Deucher 		wm_high.bytes_per_pixel = 4; /* XXX: get this from fb config */
2204cf0cfdd7SAlex Deucher 		wm_high.lb_size = lb_size;
2205cf0cfdd7SAlex Deucher 		wm_high.dram_channels = dram_channels;
2206cf0cfdd7SAlex Deucher 		wm_high.num_heads = num_heads;
2207cf0cfdd7SAlex Deucher 
2208cf0cfdd7SAlex Deucher 		/* watermark for low clocks */
2209cf0cfdd7SAlex Deucher 		if ((rdev->pm.pm_method == PM_METHOD_DPM) && rdev->pm.dpm_enabled) {
2210cf0cfdd7SAlex Deucher 			wm_low.yclk =
2211cf0cfdd7SAlex Deucher 				radeon_dpm_get_mclk(rdev, true) * 10;
2212cf0cfdd7SAlex Deucher 			wm_low.sclk =
2213cf0cfdd7SAlex Deucher 				radeon_dpm_get_sclk(rdev, true) * 10;
2214cf0cfdd7SAlex Deucher 		} else {
2215cf0cfdd7SAlex Deucher 			wm_low.yclk = rdev->pm.current_mclk * 10;
2216cf0cfdd7SAlex Deucher 			wm_low.sclk = rdev->pm.current_sclk * 10;
2217cf0cfdd7SAlex Deucher 		}
2218cf0cfdd7SAlex Deucher 
2219cf0cfdd7SAlex Deucher 		wm_low.disp_clk = mode->clock;
2220cf0cfdd7SAlex Deucher 		wm_low.src_width = mode->crtc_hdisplay;
2221e6b9a6c8SMario Kleiner 		wm_low.active_time = active_time;
2222cf0cfdd7SAlex Deucher 		wm_low.blank_time = line_time - wm_low.active_time;
2223cf0cfdd7SAlex Deucher 		wm_low.interlaced = false;
2224cf0cfdd7SAlex Deucher 		if (mode->flags & DRM_MODE_FLAG_INTERLACE)
2225cf0cfdd7SAlex Deucher 			wm_low.interlaced = true;
2226cf0cfdd7SAlex Deucher 		wm_low.vsc = radeon_crtc->vsc;
2227cf0cfdd7SAlex Deucher 		wm_low.vtaps = 1;
2228cf0cfdd7SAlex Deucher 		if (radeon_crtc->rmx_type != RMX_OFF)
2229cf0cfdd7SAlex Deucher 			wm_low.vtaps = 2;
2230cf0cfdd7SAlex Deucher 		wm_low.bytes_per_pixel = 4; /* XXX: get this from fb config */
2231cf0cfdd7SAlex Deucher 		wm_low.lb_size = lb_size;
2232cf0cfdd7SAlex Deucher 		wm_low.dram_channels = dram_channels;
2233cf0cfdd7SAlex Deucher 		wm_low.num_heads = num_heads;
2234f9d9c362SAlex Deucher 
2235f9d9c362SAlex Deucher 		/* set for high clocks */
2236cf0cfdd7SAlex Deucher 		latency_watermark_a = min(evergreen_latency_watermark(&wm_high), (u32)65535);
2237f9d9c362SAlex Deucher 		/* set for low clocks */
2238cf0cfdd7SAlex Deucher 		latency_watermark_b = min(evergreen_latency_watermark(&wm_low), (u32)65535);
2239f9d9c362SAlex Deucher 
2240f9d9c362SAlex Deucher 		/* possibly force display priority to high */
2241f9d9c362SAlex Deucher 		/* should really do this at mode validation time... */
2242cf0cfdd7SAlex Deucher 		if (!evergreen_average_bandwidth_vs_dram_bandwidth_for_display(&wm_high) ||
2243cf0cfdd7SAlex Deucher 		    !evergreen_average_bandwidth_vs_available_bandwidth(&wm_high) ||
2244cf0cfdd7SAlex Deucher 		    !evergreen_check_latency_hiding(&wm_high) ||
2245f9d9c362SAlex Deucher 		    (rdev->disp_priority == 2)) {
2246cf0cfdd7SAlex Deucher 			DRM_DEBUG_KMS("force priority a to high\n");
2247f9d9c362SAlex Deucher 			priority_a_cnt |= PRIORITY_ALWAYS_ON;
2248cf0cfdd7SAlex Deucher 		}
2249cf0cfdd7SAlex Deucher 		if (!evergreen_average_bandwidth_vs_dram_bandwidth_for_display(&wm_low) ||
2250cf0cfdd7SAlex Deucher 		    !evergreen_average_bandwidth_vs_available_bandwidth(&wm_low) ||
2251cf0cfdd7SAlex Deucher 		    !evergreen_check_latency_hiding(&wm_low) ||
2252cf0cfdd7SAlex Deucher 		    (rdev->disp_priority == 2)) {
2253cf0cfdd7SAlex Deucher 			DRM_DEBUG_KMS("force priority b to high\n");
2254f9d9c362SAlex Deucher 			priority_b_cnt |= PRIORITY_ALWAYS_ON;
2255f9d9c362SAlex Deucher 		}
2256f9d9c362SAlex Deucher 
2257f9d9c362SAlex Deucher 		a.full = dfixed_const(1000);
2258f9d9c362SAlex Deucher 		b.full = dfixed_const(mode->clock);
2259f9d9c362SAlex Deucher 		b.full = dfixed_div(b, a);
2260f9d9c362SAlex Deucher 		c.full = dfixed_const(latency_watermark_a);
2261f9d9c362SAlex Deucher 		c.full = dfixed_mul(c, b);
2262f9d9c362SAlex Deucher 		c.full = dfixed_mul(c, radeon_crtc->hsc);
2263f9d9c362SAlex Deucher 		c.full = dfixed_div(c, a);
2264f9d9c362SAlex Deucher 		a.full = dfixed_const(16);
2265f9d9c362SAlex Deucher 		c.full = dfixed_div(c, a);
2266f9d9c362SAlex Deucher 		priority_a_mark = dfixed_trunc(c);
2267f9d9c362SAlex Deucher 		priority_a_cnt |= priority_a_mark & PRIORITY_MARK_MASK;
2268f9d9c362SAlex Deucher 
2269f9d9c362SAlex Deucher 		a.full = dfixed_const(1000);
2270f9d9c362SAlex Deucher 		b.full = dfixed_const(mode->clock);
2271f9d9c362SAlex Deucher 		b.full = dfixed_div(b, a);
2272f9d9c362SAlex Deucher 		c.full = dfixed_const(latency_watermark_b);
2273f9d9c362SAlex Deucher 		c.full = dfixed_mul(c, b);
2274f9d9c362SAlex Deucher 		c.full = dfixed_mul(c, radeon_crtc->hsc);
2275f9d9c362SAlex Deucher 		c.full = dfixed_div(c, a);
2276f9d9c362SAlex Deucher 		a.full = dfixed_const(16);
2277f9d9c362SAlex Deucher 		c.full = dfixed_div(c, a);
2278f9d9c362SAlex Deucher 		priority_b_mark = dfixed_trunc(c);
2279f9d9c362SAlex Deucher 		priority_b_cnt |= priority_b_mark & PRIORITY_MARK_MASK;
22805b5561b3SMario Kleiner 
22815b5561b3SMario Kleiner 		/* Save number of lines the linebuffer leads before the scanout */
22825b5561b3SMario Kleiner 		radeon_crtc->lb_vblank_lead_lines = DIV_ROUND_UP(lb_size, mode->crtc_hdisplay);
2283f9d9c362SAlex Deucher 	}
2284f9d9c362SAlex Deucher 
2285f9d9c362SAlex Deucher 	/* select wm A */
2286f9d9c362SAlex Deucher 	arb_control3 = RREG32(PIPE0_ARBITRATION_CONTROL3 + pipe_offset);
2287f9d9c362SAlex Deucher 	tmp = arb_control3;
2288f9d9c362SAlex Deucher 	tmp &= ~LATENCY_WATERMARK_MASK(3);
2289f9d9c362SAlex Deucher 	tmp |= LATENCY_WATERMARK_MASK(1);
2290f9d9c362SAlex Deucher 	WREG32(PIPE0_ARBITRATION_CONTROL3 + pipe_offset, tmp);
2291f9d9c362SAlex Deucher 	WREG32(PIPE0_LATENCY_CONTROL + pipe_offset,
2292f9d9c362SAlex Deucher 	       (LATENCY_LOW_WATERMARK(latency_watermark_a) |
2293f9d9c362SAlex Deucher 		LATENCY_HIGH_WATERMARK(line_time)));
2294f9d9c362SAlex Deucher 	/* select wm B */
2295f9d9c362SAlex Deucher 	tmp = RREG32(PIPE0_ARBITRATION_CONTROL3 + pipe_offset);
2296f9d9c362SAlex Deucher 	tmp &= ~LATENCY_WATERMARK_MASK(3);
2297f9d9c362SAlex Deucher 	tmp |= LATENCY_WATERMARK_MASK(2);
2298f9d9c362SAlex Deucher 	WREG32(PIPE0_ARBITRATION_CONTROL3 + pipe_offset, tmp);
2299f9d9c362SAlex Deucher 	WREG32(PIPE0_LATENCY_CONTROL + pipe_offset,
2300f9d9c362SAlex Deucher 	       (LATENCY_LOW_WATERMARK(latency_watermark_b) |
2301f9d9c362SAlex Deucher 		LATENCY_HIGH_WATERMARK(line_time)));
2302f9d9c362SAlex Deucher 	/* restore original selection */
2303f9d9c362SAlex Deucher 	WREG32(PIPE0_ARBITRATION_CONTROL3 + pipe_offset, arb_control3);
2304f9d9c362SAlex Deucher 
2305f9d9c362SAlex Deucher 	/* write the priority marks */
2306f9d9c362SAlex Deucher 	WREG32(PRIORITY_A_CNT + radeon_crtc->crtc_offset, priority_a_cnt);
2307f9d9c362SAlex Deucher 	WREG32(PRIORITY_B_CNT + radeon_crtc->crtc_offset, priority_b_cnt);
2308f9d9c362SAlex Deucher 
23097178d2a6SAlex Deucher 	/* save values for DPM */
23107178d2a6SAlex Deucher 	radeon_crtc->line_time = line_time;
23117178d2a6SAlex Deucher 	radeon_crtc->wm_high = latency_watermark_a;
23127178d2a6SAlex Deucher 	radeon_crtc->wm_low = latency_watermark_b;
2313f9d9c362SAlex Deucher }
2314f9d9c362SAlex Deucher 
2315377edc8bSAlex Deucher /**
2316377edc8bSAlex Deucher  * evergreen_bandwidth_update - update display watermarks callback.
2317377edc8bSAlex Deucher  *
2318377edc8bSAlex Deucher  * @rdev: radeon_device pointer
2319377edc8bSAlex Deucher  *
2320377edc8bSAlex Deucher  * Update the display watermarks based on the requested mode(s)
2321377edc8bSAlex Deucher  * (evergreen+).
2322377edc8bSAlex Deucher  */
evergreen_bandwidth_update(struct radeon_device * rdev)23230ca2ab52SAlex Deucher void evergreen_bandwidth_update(struct radeon_device *rdev)
23240ca2ab52SAlex Deucher {
2325f9d9c362SAlex Deucher 	struct drm_display_mode *mode0 = NULL;
2326f9d9c362SAlex Deucher 	struct drm_display_mode *mode1 = NULL;
2327f9d9c362SAlex Deucher 	u32 num_heads = 0, lb_size;
2328f9d9c362SAlex Deucher 	int i;
2329f9d9c362SAlex Deucher 
23308efe82caSAlex Deucher 	if (!rdev->mode_info.mode_config_initialized)
23318efe82caSAlex Deucher 		return;
23328efe82caSAlex Deucher 
2333f9d9c362SAlex Deucher 	radeon_update_display_priority(rdev);
2334f9d9c362SAlex Deucher 
2335f9d9c362SAlex Deucher 	for (i = 0; i < rdev->num_crtc; i++) {
2336f9d9c362SAlex Deucher 		if (rdev->mode_info.crtcs[i]->base.enabled)
2337f9d9c362SAlex Deucher 			num_heads++;
2338f9d9c362SAlex Deucher 	}
2339f9d9c362SAlex Deucher 	for (i = 0; i < rdev->num_crtc; i += 2) {
2340f9d9c362SAlex Deucher 		mode0 = &rdev->mode_info.crtcs[i]->base.mode;
2341f9d9c362SAlex Deucher 		mode1 = &rdev->mode_info.crtcs[i+1]->base.mode;
2342f9d9c362SAlex Deucher 		lb_size = evergreen_line_buffer_adjust(rdev, rdev->mode_info.crtcs[i], mode0, mode1);
2343f9d9c362SAlex Deucher 		evergreen_program_watermarks(rdev, rdev->mode_info.crtcs[i], lb_size, num_heads);
2344f9d9c362SAlex Deucher 		lb_size = evergreen_line_buffer_adjust(rdev, rdev->mode_info.crtcs[i+1], mode1, mode0);
2345f9d9c362SAlex Deucher 		evergreen_program_watermarks(rdev, rdev->mode_info.crtcs[i+1], lb_size, num_heads);
2346f9d9c362SAlex Deucher 	}
2347bcc1c2a1SAlex Deucher }
2348bcc1c2a1SAlex Deucher 
2349377edc8bSAlex Deucher /**
2350377edc8bSAlex Deucher  * evergreen_mc_wait_for_idle - wait for MC idle callback.
2351377edc8bSAlex Deucher  *
2352377edc8bSAlex Deucher  * @rdev: radeon_device pointer
2353377edc8bSAlex Deucher  *
2354377edc8bSAlex Deucher  * Wait for the MC (memory controller) to be idle.
2355377edc8bSAlex Deucher  * (evergreen+).
2356377edc8bSAlex Deucher  * Returns 0 if the MC is idle, -1 if not.
2357377edc8bSAlex Deucher  */
evergreen_mc_wait_for_idle(struct radeon_device * rdev)2358b9952a8aSAlex Deucher int evergreen_mc_wait_for_idle(struct radeon_device *rdev)
2359bcc1c2a1SAlex Deucher {
2360bcc1c2a1SAlex Deucher 	unsigned i;
2361bcc1c2a1SAlex Deucher 	u32 tmp;
2362bcc1c2a1SAlex Deucher 
2363bcc1c2a1SAlex Deucher 	for (i = 0; i < rdev->usec_timeout; i++) {
2364bcc1c2a1SAlex Deucher 		/* read MC_STATUS */
2365bcc1c2a1SAlex Deucher 		tmp = RREG32(SRBM_STATUS) & 0x1F00;
2366bcc1c2a1SAlex Deucher 		if (!tmp)
2367bcc1c2a1SAlex Deucher 			return 0;
2368bcc1c2a1SAlex Deucher 		udelay(1);
2369bcc1c2a1SAlex Deucher 	}
2370bcc1c2a1SAlex Deucher 	return -1;
2371bcc1c2a1SAlex Deucher }
2372bcc1c2a1SAlex Deucher 
2373bcc1c2a1SAlex Deucher /*
2374bcc1c2a1SAlex Deucher  * GART
2375bcc1c2a1SAlex Deucher  */
evergreen_pcie_gart_tlb_flush(struct radeon_device * rdev)23760fcdb61eSAlex Deucher void evergreen_pcie_gart_tlb_flush(struct radeon_device *rdev)
23770fcdb61eSAlex Deucher {
23780fcdb61eSAlex Deucher 	unsigned i;
23790fcdb61eSAlex Deucher 	u32 tmp;
23800fcdb61eSAlex Deucher 
23816f2f48a9SAlex Deucher 	WREG32(HDP_MEM_COHERENCY_FLUSH_CNTL, 0x1);
23826f2f48a9SAlex Deucher 
23830fcdb61eSAlex Deucher 	WREG32(VM_CONTEXT0_REQUEST_RESPONSE, REQUEST_TYPE(1));
23840fcdb61eSAlex Deucher 	for (i = 0; i < rdev->usec_timeout; i++) {
23850fcdb61eSAlex Deucher 		/* read MC_STATUS */
23860fcdb61eSAlex Deucher 		tmp = RREG32(VM_CONTEXT0_REQUEST_RESPONSE);
23870fcdb61eSAlex Deucher 		tmp = (tmp & RESPONSE_TYPE_MASK) >> RESPONSE_TYPE_SHIFT;
23880fcdb61eSAlex Deucher 		if (tmp == 2) {
23897ca85295SJoe Perches 			pr_warn("[drm] r600 flush TLB failed\n");
23900fcdb61eSAlex Deucher 			return;
23910fcdb61eSAlex Deucher 		}
23920fcdb61eSAlex Deucher 		if (tmp) {
23930fcdb61eSAlex Deucher 			return;
23940fcdb61eSAlex Deucher 		}
23950fcdb61eSAlex Deucher 		udelay(1);
23960fcdb61eSAlex Deucher 	}
23970fcdb61eSAlex Deucher }
23980fcdb61eSAlex Deucher 
evergreen_pcie_gart_enable(struct radeon_device * rdev)23991109ca09SLauri Kasanen static int evergreen_pcie_gart_enable(struct radeon_device *rdev)
2400bcc1c2a1SAlex Deucher {
2401bcc1c2a1SAlex Deucher 	u32 tmp;
24020fcdb61eSAlex Deucher 	int r;
2403bcc1c2a1SAlex Deucher 
2404c9a1be96SJerome Glisse 	if (rdev->gart.robj == NULL) {
2405bcc1c2a1SAlex Deucher 		dev_err(rdev->dev, "No VRAM object for PCIE GART.\n");
2406bcc1c2a1SAlex Deucher 		return -EINVAL;
2407bcc1c2a1SAlex Deucher 	}
2408bcc1c2a1SAlex Deucher 	r = radeon_gart_table_vram_pin(rdev);
2409bcc1c2a1SAlex Deucher 	if (r)
2410bcc1c2a1SAlex Deucher 		return r;
2411bcc1c2a1SAlex Deucher 	/* Setup L2 cache */
2412bcc1c2a1SAlex Deucher 	WREG32(VM_L2_CNTL, ENABLE_L2_CACHE | ENABLE_L2_FRAGMENT_PROCESSING |
2413bcc1c2a1SAlex Deucher 				ENABLE_L2_PTE_CACHE_LRU_UPDATE_BY_WRITE |
2414bcc1c2a1SAlex Deucher 				EFFECTIVE_L2_QUEUE_SIZE(7));
2415bcc1c2a1SAlex Deucher 	WREG32(VM_L2_CNTL2, 0);
2416bcc1c2a1SAlex Deucher 	WREG32(VM_L2_CNTL3, BANK_SELECT(0) | CACHE_UPDATE_MODE(2));
2417bcc1c2a1SAlex Deucher 	/* Setup TLB control */
2418bcc1c2a1SAlex Deucher 	tmp = ENABLE_L1_TLB | ENABLE_L1_FRAGMENT_PROCESSING |
2419bcc1c2a1SAlex Deucher 		SYSTEM_ACCESS_MODE_NOT_IN_SYS |
2420bcc1c2a1SAlex Deucher 		SYSTEM_APERTURE_UNMAPPED_ACCESS_PASS_THRU |
2421bcc1c2a1SAlex Deucher 		EFFECTIVE_L1_TLB_SIZE(5) | EFFECTIVE_L1_QUEUE_SIZE(5);
24228aeb96f8SAlex Deucher 	if (rdev->flags & RADEON_IS_IGP) {
24238aeb96f8SAlex Deucher 		WREG32(FUS_MC_VM_MD_L1_TLB0_CNTL, tmp);
24248aeb96f8SAlex Deucher 		WREG32(FUS_MC_VM_MD_L1_TLB1_CNTL, tmp);
24258aeb96f8SAlex Deucher 		WREG32(FUS_MC_VM_MD_L1_TLB2_CNTL, tmp);
24268aeb96f8SAlex Deucher 	} else {
2427bcc1c2a1SAlex Deucher 		WREG32(MC_VM_MD_L1_TLB0_CNTL, tmp);
2428bcc1c2a1SAlex Deucher 		WREG32(MC_VM_MD_L1_TLB1_CNTL, tmp);
2429bcc1c2a1SAlex Deucher 		WREG32(MC_VM_MD_L1_TLB2_CNTL, tmp);
24300b8c30bcSAlex Deucher 		if ((rdev->family == CHIP_JUNIPER) ||
24310b8c30bcSAlex Deucher 		    (rdev->family == CHIP_CYPRESS) ||
24320b8c30bcSAlex Deucher 		    (rdev->family == CHIP_HEMLOCK) ||
24330b8c30bcSAlex Deucher 		    (rdev->family == CHIP_BARTS))
24340b8c30bcSAlex Deucher 			WREG32(MC_VM_MD_L1_TLB3_CNTL, tmp);
24358aeb96f8SAlex Deucher 	}
2436bcc1c2a1SAlex Deucher 	WREG32(MC_VM_MB_L1_TLB0_CNTL, tmp);
2437bcc1c2a1SAlex Deucher 	WREG32(MC_VM_MB_L1_TLB1_CNTL, tmp);
2438bcc1c2a1SAlex Deucher 	WREG32(MC_VM_MB_L1_TLB2_CNTL, tmp);
2439bcc1c2a1SAlex Deucher 	WREG32(MC_VM_MB_L1_TLB3_CNTL, tmp);
2440bcc1c2a1SAlex Deucher 	WREG32(VM_CONTEXT0_PAGE_TABLE_START_ADDR, rdev->mc.gtt_start >> 12);
24417c0411d2SChristian König 	WREG32(VM_CONTEXT0_PAGE_TABLE_END_ADDR, rdev->mc.gtt_end >> 12);
2442bcc1c2a1SAlex Deucher 	WREG32(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR, rdev->gart.table_addr >> 12);
2443bcc1c2a1SAlex Deucher 	WREG32(VM_CONTEXT0_CNTL, ENABLE_CONTEXT | PAGE_TABLE_DEPTH(0) |
2444bcc1c2a1SAlex Deucher 				RANGE_PROTECTION_FAULT_ENABLE_DEFAULT);
2445bcc1c2a1SAlex Deucher 	WREG32(VM_CONTEXT0_PROTECTION_FAULT_DEFAULT_ADDR,
2446bcc1c2a1SAlex Deucher 			(u32)(rdev->dummy_page.addr >> 12));
24470fcdb61eSAlex Deucher 	WREG32(VM_CONTEXT1_CNTL, 0);
2448bcc1c2a1SAlex Deucher 
24490fcdb61eSAlex Deucher 	evergreen_pcie_gart_tlb_flush(rdev);
2450fcf4de5aSTormod Volden 	DRM_INFO("PCIE GART of %uM enabled (table at 0x%016llX).\n",
2451fcf4de5aSTormod Volden 		 (unsigned)(rdev->mc.gtt_size >> 20),
2452fcf4de5aSTormod Volden 		 (unsigned long long)rdev->gart.table_addr);
2453bcc1c2a1SAlex Deucher 	rdev->gart.ready = true;
2454bcc1c2a1SAlex Deucher 	return 0;
2455bcc1c2a1SAlex Deucher }
2456bcc1c2a1SAlex Deucher 
evergreen_pcie_gart_disable(struct radeon_device * rdev)24571109ca09SLauri Kasanen static void evergreen_pcie_gart_disable(struct radeon_device *rdev)
2458bcc1c2a1SAlex Deucher {
2459bcc1c2a1SAlex Deucher 	u32 tmp;
2460bcc1c2a1SAlex Deucher 
2461bcc1c2a1SAlex Deucher 	/* Disable all tables */
24620fcdb61eSAlex Deucher 	WREG32(VM_CONTEXT0_CNTL, 0);
24630fcdb61eSAlex Deucher 	WREG32(VM_CONTEXT1_CNTL, 0);
2464bcc1c2a1SAlex Deucher 
2465bcc1c2a1SAlex Deucher 	/* Setup L2 cache */
2466bcc1c2a1SAlex Deucher 	WREG32(VM_L2_CNTL, ENABLE_L2_FRAGMENT_PROCESSING |
2467bcc1c2a1SAlex Deucher 				EFFECTIVE_L2_QUEUE_SIZE(7));
2468bcc1c2a1SAlex Deucher 	WREG32(VM_L2_CNTL2, 0);
2469bcc1c2a1SAlex Deucher 	WREG32(VM_L2_CNTL3, BANK_SELECT(0) | CACHE_UPDATE_MODE(2));
2470bcc1c2a1SAlex Deucher 	/* Setup TLB control */
2471bcc1c2a1SAlex Deucher 	tmp = EFFECTIVE_L1_TLB_SIZE(5) | EFFECTIVE_L1_QUEUE_SIZE(5);
2472bcc1c2a1SAlex Deucher 	WREG32(MC_VM_MD_L1_TLB0_CNTL, tmp);
2473bcc1c2a1SAlex Deucher 	WREG32(MC_VM_MD_L1_TLB1_CNTL, tmp);
2474bcc1c2a1SAlex Deucher 	WREG32(MC_VM_MD_L1_TLB2_CNTL, tmp);
2475bcc1c2a1SAlex Deucher 	WREG32(MC_VM_MB_L1_TLB0_CNTL, tmp);
2476bcc1c2a1SAlex Deucher 	WREG32(MC_VM_MB_L1_TLB1_CNTL, tmp);
2477bcc1c2a1SAlex Deucher 	WREG32(MC_VM_MB_L1_TLB2_CNTL, tmp);
2478bcc1c2a1SAlex Deucher 	WREG32(MC_VM_MB_L1_TLB3_CNTL, tmp);
2479c9a1be96SJerome Glisse 	radeon_gart_table_vram_unpin(rdev);
2480bcc1c2a1SAlex Deucher }
2481bcc1c2a1SAlex Deucher 
evergreen_pcie_gart_fini(struct radeon_device * rdev)24821109ca09SLauri Kasanen static void evergreen_pcie_gart_fini(struct radeon_device *rdev)
2483bcc1c2a1SAlex Deucher {
2484bcc1c2a1SAlex Deucher 	evergreen_pcie_gart_disable(rdev);
2485bcc1c2a1SAlex Deucher 	radeon_gart_table_vram_free(rdev);
2486bcc1c2a1SAlex Deucher 	radeon_gart_fini(rdev);
2487bcc1c2a1SAlex Deucher }
2488bcc1c2a1SAlex Deucher 
2489bcc1c2a1SAlex Deucher 
evergreen_agp_enable(struct radeon_device * rdev)24901109ca09SLauri Kasanen static void evergreen_agp_enable(struct radeon_device *rdev)
2491bcc1c2a1SAlex Deucher {
2492bcc1c2a1SAlex Deucher 	u32 tmp;
2493bcc1c2a1SAlex Deucher 
2494bcc1c2a1SAlex Deucher 	/* Setup L2 cache */
2495bcc1c2a1SAlex Deucher 	WREG32(VM_L2_CNTL, ENABLE_L2_CACHE | ENABLE_L2_FRAGMENT_PROCESSING |
2496bcc1c2a1SAlex Deucher 				ENABLE_L2_PTE_CACHE_LRU_UPDATE_BY_WRITE |
2497bcc1c2a1SAlex Deucher 				EFFECTIVE_L2_QUEUE_SIZE(7));
2498bcc1c2a1SAlex Deucher 	WREG32(VM_L2_CNTL2, 0);
2499bcc1c2a1SAlex Deucher 	WREG32(VM_L2_CNTL3, BANK_SELECT(0) | CACHE_UPDATE_MODE(2));
2500bcc1c2a1SAlex Deucher 	/* Setup TLB control */
2501bcc1c2a1SAlex Deucher 	tmp = ENABLE_L1_TLB | ENABLE_L1_FRAGMENT_PROCESSING |
2502bcc1c2a1SAlex Deucher 		SYSTEM_ACCESS_MODE_NOT_IN_SYS |
2503bcc1c2a1SAlex Deucher 		SYSTEM_APERTURE_UNMAPPED_ACCESS_PASS_THRU |
2504bcc1c2a1SAlex Deucher 		EFFECTIVE_L1_TLB_SIZE(5) | EFFECTIVE_L1_QUEUE_SIZE(5);
2505bcc1c2a1SAlex Deucher 	WREG32(MC_VM_MD_L1_TLB0_CNTL, tmp);
2506bcc1c2a1SAlex Deucher 	WREG32(MC_VM_MD_L1_TLB1_CNTL, tmp);
2507bcc1c2a1SAlex Deucher 	WREG32(MC_VM_MD_L1_TLB2_CNTL, tmp);
2508bcc1c2a1SAlex Deucher 	WREG32(MC_VM_MB_L1_TLB0_CNTL, tmp);
2509bcc1c2a1SAlex Deucher 	WREG32(MC_VM_MB_L1_TLB1_CNTL, tmp);
2510bcc1c2a1SAlex Deucher 	WREG32(MC_VM_MB_L1_TLB2_CNTL, tmp);
2511bcc1c2a1SAlex Deucher 	WREG32(MC_VM_MB_L1_TLB3_CNTL, tmp);
25120fcdb61eSAlex Deucher 	WREG32(VM_CONTEXT0_CNTL, 0);
25130fcdb61eSAlex Deucher 	WREG32(VM_CONTEXT1_CNTL, 0);
2514bcc1c2a1SAlex Deucher }
2515bcc1c2a1SAlex Deucher 
25165d5b7803SVitaly Prosyak static const unsigned ni_dig_offsets[] =
25175d5b7803SVitaly Prosyak {
25185d5b7803SVitaly Prosyak 	NI_DIG0_REGISTER_OFFSET,
25195d5b7803SVitaly Prosyak 	NI_DIG1_REGISTER_OFFSET,
25205d5b7803SVitaly Prosyak 	NI_DIG2_REGISTER_OFFSET,
25215d5b7803SVitaly Prosyak 	NI_DIG3_REGISTER_OFFSET,
25225d5b7803SVitaly Prosyak 	NI_DIG4_REGISTER_OFFSET,
25235d5b7803SVitaly Prosyak 	NI_DIG5_REGISTER_OFFSET
25245d5b7803SVitaly Prosyak };
25255d5b7803SVitaly Prosyak 
25265d5b7803SVitaly Prosyak static const unsigned ni_tx_offsets[] =
25275d5b7803SVitaly Prosyak {
25285d5b7803SVitaly Prosyak 	NI_DCIO_UNIPHY0_UNIPHY_TX_CONTROL1,
25295d5b7803SVitaly Prosyak 	NI_DCIO_UNIPHY1_UNIPHY_TX_CONTROL1,
25305d5b7803SVitaly Prosyak 	NI_DCIO_UNIPHY2_UNIPHY_TX_CONTROL1,
25315d5b7803SVitaly Prosyak 	NI_DCIO_UNIPHY3_UNIPHY_TX_CONTROL1,
25325d5b7803SVitaly Prosyak 	NI_DCIO_UNIPHY4_UNIPHY_TX_CONTROL1,
25335d5b7803SVitaly Prosyak 	NI_DCIO_UNIPHY5_UNIPHY_TX_CONTROL1
25345d5b7803SVitaly Prosyak };
25355d5b7803SVitaly Prosyak 
25365d5b7803SVitaly Prosyak static const unsigned evergreen_dp_offsets[] =
25375d5b7803SVitaly Prosyak {
25385d5b7803SVitaly Prosyak 	EVERGREEN_DP0_REGISTER_OFFSET,
25395d5b7803SVitaly Prosyak 	EVERGREEN_DP1_REGISTER_OFFSET,
25405d5b7803SVitaly Prosyak 	EVERGREEN_DP2_REGISTER_OFFSET,
25415d5b7803SVitaly Prosyak 	EVERGREEN_DP3_REGISTER_OFFSET,
25425d5b7803SVitaly Prosyak 	EVERGREEN_DP4_REGISTER_OFFSET,
25435d5b7803SVitaly Prosyak 	EVERGREEN_DP5_REGISTER_OFFSET
25445d5b7803SVitaly Prosyak };
25455d5b7803SVitaly Prosyak 
25464cd096ddSLyude static const unsigned evergreen_disp_int_status[] =
25474cd096ddSLyude {
25484cd096ddSLyude 	DISP_INTERRUPT_STATUS,
25494cd096ddSLyude 	DISP_INTERRUPT_STATUS_CONTINUE,
25504cd096ddSLyude 	DISP_INTERRUPT_STATUS_CONTINUE2,
25514cd096ddSLyude 	DISP_INTERRUPT_STATUS_CONTINUE3,
25524cd096ddSLyude 	DISP_INTERRUPT_STATUS_CONTINUE4,
25534cd096ddSLyude 	DISP_INTERRUPT_STATUS_CONTINUE5
25544cd096ddSLyude };
25555d5b7803SVitaly Prosyak 
25565d5b7803SVitaly Prosyak /*
25575d5b7803SVitaly Prosyak  * Assumption is that EVERGREEN_CRTC_MASTER_EN enable for requested crtc
25585d5b7803SVitaly Prosyak  * We go from crtc to connector and it is not relible  since it
25595d5b7803SVitaly Prosyak  * should be an opposite direction .If crtc is enable then
25605d5b7803SVitaly Prosyak  * find the dig_fe which selects this crtc and insure that it enable.
25615d5b7803SVitaly Prosyak  * if such dig_fe is found then find dig_be which selects found dig_be and
25625d5b7803SVitaly Prosyak  * insure that it enable and in DP_SST mode.
25635d5b7803SVitaly Prosyak  * if UNIPHY_PLL_CONTROL1.enable then we should disconnect timing
25645d5b7803SVitaly Prosyak  * from dp symbols clocks .
25655d5b7803SVitaly Prosyak  */
evergreen_is_dp_sst_stream_enabled(struct radeon_device * rdev,unsigned crtc_id,unsigned * ret_dig_fe)25665d5b7803SVitaly Prosyak static bool evergreen_is_dp_sst_stream_enabled(struct radeon_device *rdev,
25675d5b7803SVitaly Prosyak 					       unsigned crtc_id, unsigned *ret_dig_fe)
25685d5b7803SVitaly Prosyak {
25695d5b7803SVitaly Prosyak 	unsigned i;
25705d5b7803SVitaly Prosyak 	unsigned dig_fe;
25715d5b7803SVitaly Prosyak 	unsigned dig_be;
25725d5b7803SVitaly Prosyak 	unsigned dig_en_be;
25735d5b7803SVitaly Prosyak 	unsigned uniphy_pll;
25745d5b7803SVitaly Prosyak 	unsigned digs_fe_selected;
25755d5b7803SVitaly Prosyak 	unsigned dig_be_mode;
25765d5b7803SVitaly Prosyak 	unsigned dig_fe_mask;
25775d5b7803SVitaly Prosyak 	bool is_enabled = false;
25785d5b7803SVitaly Prosyak 	bool found_crtc = false;
25795d5b7803SVitaly Prosyak 
25805d5b7803SVitaly Prosyak 	/* loop through all running dig_fe to find selected crtc */
25815d5b7803SVitaly Prosyak 	for (i = 0; i < ARRAY_SIZE(ni_dig_offsets); i++) {
25825d5b7803SVitaly Prosyak 		dig_fe = RREG32(NI_DIG_FE_CNTL + ni_dig_offsets[i]);
25835d5b7803SVitaly Prosyak 		if (dig_fe & NI_DIG_FE_CNTL_SYMCLK_FE_ON &&
25845d5b7803SVitaly Prosyak 		    crtc_id == NI_DIG_FE_CNTL_SOURCE_SELECT(dig_fe)) {
25855d5b7803SVitaly Prosyak 			/* found running pipe */
25865d5b7803SVitaly Prosyak 			found_crtc = true;
25875d5b7803SVitaly Prosyak 			dig_fe_mask = 1 << i;
25885d5b7803SVitaly Prosyak 			dig_fe = i;
25895d5b7803SVitaly Prosyak 			break;
25905d5b7803SVitaly Prosyak 		}
25915d5b7803SVitaly Prosyak 	}
25925d5b7803SVitaly Prosyak 
25935d5b7803SVitaly Prosyak 	if (found_crtc) {
25945d5b7803SVitaly Prosyak 		/* loop through all running dig_be to find selected dig_fe */
25955d5b7803SVitaly Prosyak 		for (i = 0; i < ARRAY_SIZE(ni_dig_offsets); i++) {
25965d5b7803SVitaly Prosyak 			dig_be = RREG32(NI_DIG_BE_CNTL + ni_dig_offsets[i]);
25975d5b7803SVitaly Prosyak 			/* if dig_fe_selected by dig_be? */
25985d5b7803SVitaly Prosyak 			digs_fe_selected = NI_DIG_BE_CNTL_FE_SOURCE_SELECT(dig_be);
25995d5b7803SVitaly Prosyak 			dig_be_mode = NI_DIG_FE_CNTL_MODE(dig_be);
26005d5b7803SVitaly Prosyak 			if (dig_fe_mask &  digs_fe_selected &&
26015d5b7803SVitaly Prosyak 			    /* if dig_be in sst mode? */
26025d5b7803SVitaly Prosyak 			    dig_be_mode == NI_DIG_BE_DPSST) {
26035d5b7803SVitaly Prosyak 				dig_en_be = RREG32(NI_DIG_BE_EN_CNTL +
26045d5b7803SVitaly Prosyak 						   ni_dig_offsets[i]);
26055d5b7803SVitaly Prosyak 				uniphy_pll = RREG32(NI_DCIO_UNIPHY0_PLL_CONTROL1 +
26065d5b7803SVitaly Prosyak 						    ni_tx_offsets[i]);
26075d5b7803SVitaly Prosyak 				/* dig_be enable and tx is running */
26085d5b7803SVitaly Prosyak 				if (dig_en_be & NI_DIG_BE_EN_CNTL_ENABLE &&
26095d5b7803SVitaly Prosyak 				    dig_en_be & NI_DIG_BE_EN_CNTL_SYMBCLK_ON &&
26105d5b7803SVitaly Prosyak 				    uniphy_pll & NI_DCIO_UNIPHY0_PLL_CONTROL1_ENABLE) {
26115d5b7803SVitaly Prosyak 					is_enabled = true;
26125d5b7803SVitaly Prosyak 					*ret_dig_fe = dig_fe;
26135d5b7803SVitaly Prosyak 					break;
26145d5b7803SVitaly Prosyak 				}
26155d5b7803SVitaly Prosyak 			}
26165d5b7803SVitaly Prosyak 		}
26175d5b7803SVitaly Prosyak 	}
26185d5b7803SVitaly Prosyak 
26195d5b7803SVitaly Prosyak 	return is_enabled;
26205d5b7803SVitaly Prosyak }
26215d5b7803SVitaly Prosyak 
26225d5b7803SVitaly Prosyak /*
26235d5b7803SVitaly Prosyak  * Blank dig when in dp sst mode
26245d5b7803SVitaly Prosyak  * Dig ignores crtc timing
26255d5b7803SVitaly Prosyak  */
evergreen_blank_dp_output(struct radeon_device * rdev,unsigned dig_fe)26265d5b7803SVitaly Prosyak static void evergreen_blank_dp_output(struct radeon_device *rdev,
26275d5b7803SVitaly Prosyak 				      unsigned dig_fe)
26285d5b7803SVitaly Prosyak {
26295d5b7803SVitaly Prosyak 	unsigned stream_ctrl;
26305d5b7803SVitaly Prosyak 	unsigned fifo_ctrl;
26315d5b7803SVitaly Prosyak 	unsigned counter = 0;
26325d5b7803SVitaly Prosyak 
26335d5b7803SVitaly Prosyak 	if (dig_fe >= ARRAY_SIZE(evergreen_dp_offsets)) {
26345d5b7803SVitaly Prosyak 		DRM_ERROR("invalid dig_fe %d\n", dig_fe);
26355d5b7803SVitaly Prosyak 		return;
26365d5b7803SVitaly Prosyak 	}
26375d5b7803SVitaly Prosyak 
26385d5b7803SVitaly Prosyak 	stream_ctrl = RREG32(EVERGREEN_DP_VID_STREAM_CNTL +
26395d5b7803SVitaly Prosyak 			     evergreen_dp_offsets[dig_fe]);
26405d5b7803SVitaly Prosyak 	if (!(stream_ctrl & EVERGREEN_DP_VID_STREAM_CNTL_ENABLE)) {
26415d5b7803SVitaly Prosyak 		DRM_ERROR("dig %d , should be enable\n", dig_fe);
26425d5b7803SVitaly Prosyak 		return;
26435d5b7803SVitaly Prosyak 	}
26445d5b7803SVitaly Prosyak 
26455d5b7803SVitaly Prosyak 	stream_ctrl &=~EVERGREEN_DP_VID_STREAM_CNTL_ENABLE;
26465d5b7803SVitaly Prosyak 	WREG32(EVERGREEN_DP_VID_STREAM_CNTL +
26475d5b7803SVitaly Prosyak 	       evergreen_dp_offsets[dig_fe], stream_ctrl);
26485d5b7803SVitaly Prosyak 
26495d5b7803SVitaly Prosyak 	stream_ctrl = RREG32(EVERGREEN_DP_VID_STREAM_CNTL +
26505d5b7803SVitaly Prosyak 			     evergreen_dp_offsets[dig_fe]);
26515d5b7803SVitaly Prosyak 	while (counter < 32 && stream_ctrl & EVERGREEN_DP_VID_STREAM_STATUS) {
26525d5b7803SVitaly Prosyak 		msleep(1);
26535d5b7803SVitaly Prosyak 		counter++;
26545d5b7803SVitaly Prosyak 		stream_ctrl = RREG32(EVERGREEN_DP_VID_STREAM_CNTL +
26555d5b7803SVitaly Prosyak 				     evergreen_dp_offsets[dig_fe]);
26565d5b7803SVitaly Prosyak 	}
26575d5b7803SVitaly Prosyak 	if (counter >= 32 )
26585d5b7803SVitaly Prosyak 		DRM_ERROR("counter exceeds %d\n", counter);
26595d5b7803SVitaly Prosyak 
26605d5b7803SVitaly Prosyak 	fifo_ctrl = RREG32(EVERGREEN_DP_STEER_FIFO + evergreen_dp_offsets[dig_fe]);
26615d5b7803SVitaly Prosyak 	fifo_ctrl |= EVERGREEN_DP_STEER_FIFO_RESET;
26625d5b7803SVitaly Prosyak 	WREG32(EVERGREEN_DP_STEER_FIFO + evergreen_dp_offsets[dig_fe], fifo_ctrl);
26635d5b7803SVitaly Prosyak 
26645d5b7803SVitaly Prosyak }
26655d5b7803SVitaly Prosyak 
evergreen_mc_stop(struct radeon_device * rdev,struct evergreen_mc_save * save)2666b9952a8aSAlex Deucher void evergreen_mc_stop(struct radeon_device *rdev, struct evergreen_mc_save *save)
2667bcc1c2a1SAlex Deucher {
266862444b74SAlex Deucher 	u32 crtc_enabled, tmp, frame_count, blackout;
266962444b74SAlex Deucher 	int i, j;
26705d5b7803SVitaly Prosyak 	unsigned dig_fe;
267162444b74SAlex Deucher 
26725153550aSAlex Deucher 	if (!ASIC_IS_NODCE(rdev)) {
2673bcc1c2a1SAlex Deucher 		save->vga_render_control = RREG32(VGA_RENDER_CONTROL);
2674bcc1c2a1SAlex Deucher 		save->vga_hdp_control = RREG32(VGA_HDP_CONTROL);
2675bcc1c2a1SAlex Deucher 
267662444b74SAlex Deucher 		/* disable VGA render */
2677bcc1c2a1SAlex Deucher 		WREG32(VGA_RENDER_CONTROL, 0);
26785153550aSAlex Deucher 	}
267962444b74SAlex Deucher 	/* blank the display controllers */
268062444b74SAlex Deucher 	for (i = 0; i < rdev->num_crtc; i++) {
268162444b74SAlex Deucher 		crtc_enabled = RREG32(EVERGREEN_CRTC_CONTROL + crtc_offsets[i]) & EVERGREEN_CRTC_MASTER_EN;
268262444b74SAlex Deucher 		if (crtc_enabled) {
268362444b74SAlex Deucher 			save->crtc_enabled[i] = true;
268462444b74SAlex Deucher 			if (ASIC_IS_DCE6(rdev)) {
268562444b74SAlex Deucher 				tmp = RREG32(EVERGREEN_CRTC_BLANK_CONTROL + crtc_offsets[i]);
268662444b74SAlex Deucher 				if (!(tmp & EVERGREEN_CRTC_BLANK_DATA_EN)) {
268762444b74SAlex Deucher 					radeon_wait_for_vblank(rdev, i);
2688abf1457bSAlex Deucher 					WREG32(EVERGREEN_CRTC_UPDATE_LOCK + crtc_offsets[i], 1);
268962444b74SAlex Deucher 					tmp |= EVERGREEN_CRTC_BLANK_DATA_EN;
269062444b74SAlex Deucher 					WREG32(EVERGREEN_CRTC_BLANK_CONTROL + crtc_offsets[i], tmp);
2691f0d7bfb9SAlex Deucher 					WREG32(EVERGREEN_CRTC_UPDATE_LOCK + crtc_offsets[i], 0);
2692b7eff394SAlex Deucher 				}
269362444b74SAlex Deucher 			} else {
269462444b74SAlex Deucher 				tmp = RREG32(EVERGREEN_CRTC_CONTROL + crtc_offsets[i]);
269562444b74SAlex Deucher 				if (!(tmp & EVERGREEN_CRTC_DISP_READ_REQUEST_DISABLE)) {
269662444b74SAlex Deucher 					radeon_wait_for_vblank(rdev, i);
2697abf1457bSAlex Deucher 					WREG32(EVERGREEN_CRTC_UPDATE_LOCK + crtc_offsets[i], 1);
269862444b74SAlex Deucher 					tmp |= EVERGREEN_CRTC_DISP_READ_REQUEST_DISABLE;
269962444b74SAlex Deucher 					WREG32(EVERGREEN_CRTC_CONTROL + crtc_offsets[i], tmp);
2700abf1457bSAlex Deucher 					WREG32(EVERGREEN_CRTC_UPDATE_LOCK + crtc_offsets[i], 0);
270118007401SAlex Deucher 				}
2702b7eff394SAlex Deucher 			}
270362444b74SAlex Deucher 			/* wait for the next frame */
270462444b74SAlex Deucher 			frame_count = radeon_get_vblank_counter(rdev, i);
270562444b74SAlex Deucher 			for (j = 0; j < rdev->usec_timeout; j++) {
270662444b74SAlex Deucher 				if (radeon_get_vblank_counter(rdev, i) != frame_count)
270762444b74SAlex Deucher 					break;
270862444b74SAlex Deucher 				udelay(1);
270918007401SAlex Deucher 			}
27105d5b7803SVitaly Prosyak 			/*we should disable dig if it drives dp sst*/
27115d5b7803SVitaly Prosyak 			/*but we are in radeon_device_init and the topology is unknown*/
27125d5b7803SVitaly Prosyak 			/*and it is available after radeon_modeset_init*/
27135d5b7803SVitaly Prosyak 			/*the following method radeon_atom_encoder_dpms_dig*/
27145d5b7803SVitaly Prosyak 			/*does the job if we initialize it properly*/
27155d5b7803SVitaly Prosyak 			/*for now we do it this manually*/
27165d5b7803SVitaly Prosyak 			/**/
27175d5b7803SVitaly Prosyak 			if (ASIC_IS_DCE5(rdev) &&
27185d5b7803SVitaly Prosyak 			    evergreen_is_dp_sst_stream_enabled(rdev, i ,&dig_fe))
27195d5b7803SVitaly Prosyak 				evergreen_blank_dp_output(rdev, dig_fe);
27205d5b7803SVitaly Prosyak 			/*we could remove 6 lines below*/
2721abf1457bSAlex Deucher 			/* XXX this is a hack to avoid strange behavior with EFI on certain systems */
2722abf1457bSAlex Deucher 			WREG32(EVERGREEN_CRTC_UPDATE_LOCK + crtc_offsets[i], 1);
2723abf1457bSAlex Deucher 			tmp = RREG32(EVERGREEN_CRTC_CONTROL + crtc_offsets[i]);
2724abf1457bSAlex Deucher 			tmp &= ~EVERGREEN_CRTC_MASTER_EN;
2725abf1457bSAlex Deucher 			WREG32(EVERGREEN_CRTC_CONTROL + crtc_offsets[i], tmp);
2726abf1457bSAlex Deucher 			WREG32(EVERGREEN_CRTC_UPDATE_LOCK + crtc_offsets[i], 0);
2727abf1457bSAlex Deucher 			save->crtc_enabled[i] = false;
2728abf1457bSAlex Deucher 			/* ***** */
2729804cc4a0SAlex Deucher 		} else {
2730804cc4a0SAlex Deucher 			save->crtc_enabled[i] = false;
2731b7eff394SAlex Deucher 		}
273218007401SAlex Deucher 	}
2733bcc1c2a1SAlex Deucher 
273462444b74SAlex Deucher 	radeon_mc_wait_for_idle(rdev);
273562444b74SAlex Deucher 
273662444b74SAlex Deucher 	blackout = RREG32(MC_SHARED_BLACKOUT_CNTL);
273762444b74SAlex Deucher 	if ((blackout & BLACKOUT_MODE_MASK) != 1) {
273862444b74SAlex Deucher 		/* Block CPU access */
273962444b74SAlex Deucher 		WREG32(BIF_FB_EN, 0);
274062444b74SAlex Deucher 		/* blackout the MC */
274162444b74SAlex Deucher 		blackout &= ~BLACKOUT_MODE_MASK;
274262444b74SAlex Deucher 		WREG32(MC_SHARED_BLACKOUT_CNTL, blackout | 1);
2743bcc1c2a1SAlex Deucher 	}
2744ed39faddSAlex Deucher 	/* wait for the MC to settle */
2745ed39faddSAlex Deucher 	udelay(100);
2746968c0166SAlex Deucher 
2747968c0166SAlex Deucher 	/* lock double buffered regs */
2748968c0166SAlex Deucher 	for (i = 0; i < rdev->num_crtc; i++) {
2749968c0166SAlex Deucher 		if (save->crtc_enabled[i]) {
2750968c0166SAlex Deucher 			tmp = RREG32(EVERGREEN_GRPH_UPDATE + crtc_offsets[i]);
2751968c0166SAlex Deucher 			if (!(tmp & EVERGREEN_GRPH_UPDATE_LOCK)) {
2752968c0166SAlex Deucher 				tmp |= EVERGREEN_GRPH_UPDATE_LOCK;
2753968c0166SAlex Deucher 				WREG32(EVERGREEN_GRPH_UPDATE + crtc_offsets[i], tmp);
2754968c0166SAlex Deucher 			}
2755968c0166SAlex Deucher 			tmp = RREG32(EVERGREEN_MASTER_UPDATE_LOCK + crtc_offsets[i]);
2756968c0166SAlex Deucher 			if (!(tmp & 1)) {
2757968c0166SAlex Deucher 				tmp |= 1;
2758968c0166SAlex Deucher 				WREG32(EVERGREEN_MASTER_UPDATE_LOCK + crtc_offsets[i], tmp);
2759968c0166SAlex Deucher 			}
2760968c0166SAlex Deucher 		}
2761968c0166SAlex Deucher 	}
2762b7eff394SAlex Deucher }
2763bcc1c2a1SAlex Deucher 
evergreen_mc_resume(struct radeon_device * rdev,struct evergreen_mc_save * save)2764b9952a8aSAlex Deucher void evergreen_mc_resume(struct radeon_device *rdev, struct evergreen_mc_save *save)
2765bcc1c2a1SAlex Deucher {
276662444b74SAlex Deucher 	u32 tmp, frame_count;
276762444b74SAlex Deucher 	int i, j;
2768bcc1c2a1SAlex Deucher 
276962444b74SAlex Deucher 	/* update crtc base addresses */
277062444b74SAlex Deucher 	for (i = 0; i < rdev->num_crtc; i++) {
277162444b74SAlex Deucher 		WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH + crtc_offsets[i],
2772bcc1c2a1SAlex Deucher 		       upper_32_bits(rdev->mc.vram_start));
277362444b74SAlex Deucher 		WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS_HIGH + crtc_offsets[i],
2774bcc1c2a1SAlex Deucher 		       upper_32_bits(rdev->mc.vram_start));
277562444b74SAlex Deucher 		WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS + crtc_offsets[i],
2776bcc1c2a1SAlex Deucher 		       (u32)rdev->mc.vram_start);
277762444b74SAlex Deucher 		WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS + crtc_offsets[i],
2778bcc1c2a1SAlex Deucher 		       (u32)rdev->mc.vram_start);
2779b7eff394SAlex Deucher 	}
27805153550aSAlex Deucher 
27815153550aSAlex Deucher 	if (!ASIC_IS_NODCE(rdev)) {
2782bcc1c2a1SAlex Deucher 		WREG32(EVERGREEN_VGA_MEMORY_BASE_ADDRESS_HIGH, upper_32_bits(rdev->mc.vram_start));
2783bcc1c2a1SAlex Deucher 		WREG32(EVERGREEN_VGA_MEMORY_BASE_ADDRESS, (u32)rdev->mc.vram_start);
27845153550aSAlex Deucher 	}
278562444b74SAlex Deucher 
2786968c0166SAlex Deucher 	/* unlock regs and wait for update */
2787968c0166SAlex Deucher 	for (i = 0; i < rdev->num_crtc; i++) {
2788968c0166SAlex Deucher 		if (save->crtc_enabled[i]) {
2789968c0166SAlex Deucher 			tmp = RREG32(EVERGREEN_MASTER_UPDATE_MODE + crtc_offsets[i]);
27905dd20bbaSMichel Dänzer 			if ((tmp & 0x7) != 0) {
2791f53f81b2SMario Kleiner 				tmp &= ~0x7;
2792968c0166SAlex Deucher 				WREG32(EVERGREEN_MASTER_UPDATE_MODE + crtc_offsets[i], tmp);
2793968c0166SAlex Deucher 			}
2794968c0166SAlex Deucher 			tmp = RREG32(EVERGREEN_GRPH_UPDATE + crtc_offsets[i]);
2795968c0166SAlex Deucher 			if (tmp & EVERGREEN_GRPH_UPDATE_LOCK) {
2796968c0166SAlex Deucher 				tmp &= ~EVERGREEN_GRPH_UPDATE_LOCK;
2797968c0166SAlex Deucher 				WREG32(EVERGREEN_GRPH_UPDATE + crtc_offsets[i], tmp);
2798968c0166SAlex Deucher 			}
2799968c0166SAlex Deucher 			tmp = RREG32(EVERGREEN_MASTER_UPDATE_LOCK + crtc_offsets[i]);
2800968c0166SAlex Deucher 			if (tmp & 1) {
2801968c0166SAlex Deucher 				tmp &= ~1;
2802968c0166SAlex Deucher 				WREG32(EVERGREEN_MASTER_UPDATE_LOCK + crtc_offsets[i], tmp);
2803968c0166SAlex Deucher 			}
2804968c0166SAlex Deucher 			for (j = 0; j < rdev->usec_timeout; j++) {
2805968c0166SAlex Deucher 				tmp = RREG32(EVERGREEN_GRPH_UPDATE + crtc_offsets[i]);
2806968c0166SAlex Deucher 				if ((tmp & EVERGREEN_GRPH_SURFACE_UPDATE_PENDING) == 0)
2807968c0166SAlex Deucher 					break;
2808968c0166SAlex Deucher 				udelay(1);
2809968c0166SAlex Deucher 			}
2810968c0166SAlex Deucher 		}
2811968c0166SAlex Deucher 	}
2812968c0166SAlex Deucher 
281362444b74SAlex Deucher 	/* unblackout the MC */
281462444b74SAlex Deucher 	tmp = RREG32(MC_SHARED_BLACKOUT_CNTL);
281562444b74SAlex Deucher 	tmp &= ~BLACKOUT_MODE_MASK;
281662444b74SAlex Deucher 	WREG32(MC_SHARED_BLACKOUT_CNTL, tmp);
281762444b74SAlex Deucher 	/* allow CPU access */
281862444b74SAlex Deucher 	WREG32(BIF_FB_EN, FB_READ_EN | FB_WRITE_EN);
281962444b74SAlex Deucher 
282062444b74SAlex Deucher 	for (i = 0; i < rdev->num_crtc; i++) {
2821695ddeb4SAlex Deucher 		if (save->crtc_enabled[i]) {
282262444b74SAlex Deucher 			if (ASIC_IS_DCE6(rdev)) {
282362444b74SAlex Deucher 				tmp = RREG32(EVERGREEN_CRTC_BLANK_CONTROL + crtc_offsets[i]);
28243157c589SAlex Deucher 				tmp &= ~EVERGREEN_CRTC_BLANK_DATA_EN;
2825bb588820SChristopher Staite 				WREG32(EVERGREEN_CRTC_UPDATE_LOCK + crtc_offsets[i], 1);
282662444b74SAlex Deucher 				WREG32(EVERGREEN_CRTC_BLANK_CONTROL + crtc_offsets[i], tmp);
2827bb588820SChristopher Staite 				WREG32(EVERGREEN_CRTC_UPDATE_LOCK + crtc_offsets[i], 0);
282862444b74SAlex Deucher 			} else {
282962444b74SAlex Deucher 				tmp = RREG32(EVERGREEN_CRTC_CONTROL + crtc_offsets[i]);
283062444b74SAlex Deucher 				tmp &= ~EVERGREEN_CRTC_DISP_READ_REQUEST_DISABLE;
2831bb588820SChristopher Staite 				WREG32(EVERGREEN_CRTC_UPDATE_LOCK + crtc_offsets[i], 1);
283262444b74SAlex Deucher 				WREG32(EVERGREEN_CRTC_CONTROL + crtc_offsets[i], tmp);
2833bb588820SChristopher Staite 				WREG32(EVERGREEN_CRTC_UPDATE_LOCK + crtc_offsets[i], 0);
283462444b74SAlex Deucher 			}
283562444b74SAlex Deucher 			/* wait for the next frame */
283662444b74SAlex Deucher 			frame_count = radeon_get_vblank_counter(rdev, i);
283762444b74SAlex Deucher 			for (j = 0; j < rdev->usec_timeout; j++) {
283862444b74SAlex Deucher 				if (radeon_get_vblank_counter(rdev, i) != frame_count)
283962444b74SAlex Deucher 					break;
284062444b74SAlex Deucher 				udelay(1);
284162444b74SAlex Deucher 			}
284262444b74SAlex Deucher 		}
284362444b74SAlex Deucher 	}
28445153550aSAlex Deucher 	if (!ASIC_IS_NODCE(rdev)) {
284562444b74SAlex Deucher 		/* Unlock vga access */
2846bcc1c2a1SAlex Deucher 		WREG32(VGA_HDP_CONTROL, save->vga_hdp_control);
2847bcc1c2a1SAlex Deucher 		mdelay(1);
2848bcc1c2a1SAlex Deucher 		WREG32(VGA_RENDER_CONTROL, save->vga_render_control);
2849bcc1c2a1SAlex Deucher 	}
28505153550aSAlex Deucher }
2851bcc1c2a1SAlex Deucher 
evergreen_mc_program(struct radeon_device * rdev)2852755d819eSAlex Deucher void evergreen_mc_program(struct radeon_device *rdev)
2853bcc1c2a1SAlex Deucher {
2854bcc1c2a1SAlex Deucher 	struct evergreen_mc_save save;
2855bcc1c2a1SAlex Deucher 	u32 tmp;
2856bcc1c2a1SAlex Deucher 	int i, j;
2857bcc1c2a1SAlex Deucher 
2858bcc1c2a1SAlex Deucher 	/* Initialize HDP */
2859bcc1c2a1SAlex Deucher 	for (i = 0, j = 0; i < 32; i++, j += 0x18) {
2860bcc1c2a1SAlex Deucher 		WREG32((0x2c14 + j), 0x00000000);
2861bcc1c2a1SAlex Deucher 		WREG32((0x2c18 + j), 0x00000000);
2862bcc1c2a1SAlex Deucher 		WREG32((0x2c1c + j), 0x00000000);
2863bcc1c2a1SAlex Deucher 		WREG32((0x2c20 + j), 0x00000000);
2864bcc1c2a1SAlex Deucher 		WREG32((0x2c24 + j), 0x00000000);
2865bcc1c2a1SAlex Deucher 	}
2866bcc1c2a1SAlex Deucher 	WREG32(HDP_REG_COHERENCY_FLUSH_CNTL, 0);
2867bcc1c2a1SAlex Deucher 
2868bcc1c2a1SAlex Deucher 	evergreen_mc_stop(rdev, &save);
2869bcc1c2a1SAlex Deucher 	if (evergreen_mc_wait_for_idle(rdev)) {
2870bcc1c2a1SAlex Deucher 		dev_warn(rdev->dev, "Wait for MC idle timedout !\n");
2871bcc1c2a1SAlex Deucher 	}
2872bcc1c2a1SAlex Deucher 	/* Lockout access through VGA aperture*/
2873bcc1c2a1SAlex Deucher 	WREG32(VGA_HDP_CONTROL, VGA_MEMORY_DISABLE);
2874bcc1c2a1SAlex Deucher 	/* Update configuration */
2875bcc1c2a1SAlex Deucher 	if (rdev->flags & RADEON_IS_AGP) {
2876bcc1c2a1SAlex Deucher 		if (rdev->mc.vram_start < rdev->mc.gtt_start) {
2877bcc1c2a1SAlex Deucher 			/* VRAM before AGP */
2878bcc1c2a1SAlex Deucher 			WREG32(MC_VM_SYSTEM_APERTURE_LOW_ADDR,
2879bcc1c2a1SAlex Deucher 				rdev->mc.vram_start >> 12);
2880bcc1c2a1SAlex Deucher 			WREG32(MC_VM_SYSTEM_APERTURE_HIGH_ADDR,
2881bcc1c2a1SAlex Deucher 				rdev->mc.gtt_end >> 12);
2882bcc1c2a1SAlex Deucher 		} else {
2883bcc1c2a1SAlex Deucher 			/* VRAM after AGP */
2884bcc1c2a1SAlex Deucher 			WREG32(MC_VM_SYSTEM_APERTURE_LOW_ADDR,
2885bcc1c2a1SAlex Deucher 				rdev->mc.gtt_start >> 12);
2886bcc1c2a1SAlex Deucher 			WREG32(MC_VM_SYSTEM_APERTURE_HIGH_ADDR,
2887bcc1c2a1SAlex Deucher 				rdev->mc.vram_end >> 12);
2888bcc1c2a1SAlex Deucher 		}
2889bcc1c2a1SAlex Deucher 	} else {
2890bcc1c2a1SAlex Deucher 		WREG32(MC_VM_SYSTEM_APERTURE_LOW_ADDR,
2891bcc1c2a1SAlex Deucher 			rdev->mc.vram_start >> 12);
2892bcc1c2a1SAlex Deucher 		WREG32(MC_VM_SYSTEM_APERTURE_HIGH_ADDR,
2893bcc1c2a1SAlex Deucher 			rdev->mc.vram_end >> 12);
2894bcc1c2a1SAlex Deucher 	}
28953b9832f6SAlex Deucher 	WREG32(MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR, rdev->vram_scratch.gpu_addr >> 12);
289605b3ef69SAlex Deucher 	/* llano/ontario only */
289705b3ef69SAlex Deucher 	if ((rdev->family == CHIP_PALM) ||
289805b3ef69SAlex Deucher 	    (rdev->family == CHIP_SUMO) ||
289905b3ef69SAlex Deucher 	    (rdev->family == CHIP_SUMO2)) {
2900b4183e30SAlex Deucher 		tmp = RREG32(MC_FUS_VM_FB_OFFSET) & 0x000FFFFF;
2901b4183e30SAlex Deucher 		tmp |= ((rdev->mc.vram_end >> 20) & 0xF) << 24;
2902b4183e30SAlex Deucher 		tmp |= ((rdev->mc.vram_start >> 20) & 0xF) << 20;
2903b4183e30SAlex Deucher 		WREG32(MC_FUS_VM_FB_OFFSET, tmp);
2904b4183e30SAlex Deucher 	}
2905bcc1c2a1SAlex Deucher 	tmp = ((rdev->mc.vram_end >> 24) & 0xFFFF) << 16;
2906bcc1c2a1SAlex Deucher 	tmp |= ((rdev->mc.vram_start >> 24) & 0xFFFF);
2907bcc1c2a1SAlex Deucher 	WREG32(MC_VM_FB_LOCATION, tmp);
2908bcc1c2a1SAlex Deucher 	WREG32(HDP_NONSURFACE_BASE, (rdev->mc.vram_start >> 8));
2909c46cb4daSAlex Deucher 	WREG32(HDP_NONSURFACE_INFO, (2 << 7) | (1 << 30));
291046fcd2b3SJerome Glisse 	WREG32(HDP_NONSURFACE_SIZE, 0x3FFFFFFF);
2911bcc1c2a1SAlex Deucher 	if (rdev->flags & RADEON_IS_AGP) {
2912bcc1c2a1SAlex Deucher 		WREG32(MC_VM_AGP_TOP, rdev->mc.gtt_end >> 16);
2913bcc1c2a1SAlex Deucher 		WREG32(MC_VM_AGP_BOT, rdev->mc.gtt_start >> 16);
2914bcc1c2a1SAlex Deucher 		WREG32(MC_VM_AGP_BASE, rdev->mc.agp_base >> 22);
2915bcc1c2a1SAlex Deucher 	} else {
2916bcc1c2a1SAlex Deucher 		WREG32(MC_VM_AGP_BASE, 0);
2917bcc1c2a1SAlex Deucher 		WREG32(MC_VM_AGP_TOP, 0x0FFFFFFF);
2918bcc1c2a1SAlex Deucher 		WREG32(MC_VM_AGP_BOT, 0x0FFFFFFF);
2919bcc1c2a1SAlex Deucher 	}
2920bcc1c2a1SAlex Deucher 	if (evergreen_mc_wait_for_idle(rdev)) {
2921bcc1c2a1SAlex Deucher 		dev_warn(rdev->dev, "Wait for MC idle timedout !\n");
2922bcc1c2a1SAlex Deucher 	}
2923bcc1c2a1SAlex Deucher 	evergreen_mc_resume(rdev, &save);
2924bcc1c2a1SAlex Deucher 	/* we need to own VRAM, so turn off the VGA renderer here
2925bcc1c2a1SAlex Deucher 	 * to stop it overwriting our objects */
2926bcc1c2a1SAlex Deucher 	rv515_vga_render_disable(rdev);
2927bcc1c2a1SAlex Deucher }
2928bcc1c2a1SAlex Deucher 
2929bcc1c2a1SAlex Deucher /*
2930bcc1c2a1SAlex Deucher  * CP.
2931bcc1c2a1SAlex Deucher  */
evergreen_ring_ib_execute(struct radeon_device * rdev,struct radeon_ib * ib)293212920591SAlex Deucher void evergreen_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib)
293312920591SAlex Deucher {
2934876dc9f3SChristian König 	struct radeon_ring *ring = &rdev->ring[ib->ring];
293589d35807SAlex Deucher 	u32 next_rptr;
29367b1f2485SChristian König 
293712920591SAlex Deucher 	/* set to DX10/11 mode */
2938e32eb50dSChristian König 	radeon_ring_write(ring, PACKET3(PACKET3_MODE_CONTROL, 0));
2939e32eb50dSChristian König 	radeon_ring_write(ring, 1);
294045df6803SChristian König 
294145df6803SChristian König 	if (ring->rptr_save_reg) {
294289d35807SAlex Deucher 		next_rptr = ring->wptr + 3 + 4;
294345df6803SChristian König 		radeon_ring_write(ring, PACKET3(PACKET3_SET_CONFIG_REG, 1));
294445df6803SChristian König 		radeon_ring_write(ring, ((ring->rptr_save_reg -
294545df6803SChristian König 					  PACKET3_SET_CONFIG_REG_START) >> 2));
294645df6803SChristian König 		radeon_ring_write(ring, next_rptr);
294789d35807SAlex Deucher 	} else if (rdev->wb.enabled) {
294889d35807SAlex Deucher 		next_rptr = ring->wptr + 5 + 4;
294989d35807SAlex Deucher 		radeon_ring_write(ring, PACKET3(PACKET3_MEM_WRITE, 3));
295089d35807SAlex Deucher 		radeon_ring_write(ring, ring->next_rptr_gpu_addr & 0xfffffffc);
295189d35807SAlex Deucher 		radeon_ring_write(ring, (upper_32_bits(ring->next_rptr_gpu_addr) & 0xff) | (1 << 18));
295289d35807SAlex Deucher 		radeon_ring_write(ring, next_rptr);
295389d35807SAlex Deucher 		radeon_ring_write(ring, 0);
295445df6803SChristian König 	}
295545df6803SChristian König 
2956e32eb50dSChristian König 	radeon_ring_write(ring, PACKET3(PACKET3_INDIRECT_BUFFER, 2));
2957e32eb50dSChristian König 	radeon_ring_write(ring,
29580f234f5fSAlex Deucher #ifdef __BIG_ENDIAN
29590f234f5fSAlex Deucher 			  (2 << 0) |
29600f234f5fSAlex Deucher #endif
29610f234f5fSAlex Deucher 			  (ib->gpu_addr & 0xFFFFFFFC));
2962e32eb50dSChristian König 	radeon_ring_write(ring, upper_32_bits(ib->gpu_addr) & 0xFF);
2963e32eb50dSChristian König 	radeon_ring_write(ring, ib->length_dw);
296412920591SAlex Deucher }
296512920591SAlex Deucher 
2966bcc1c2a1SAlex Deucher 
evergreen_cp_load_microcode(struct radeon_device * rdev)2967bcc1c2a1SAlex Deucher static int evergreen_cp_load_microcode(struct radeon_device *rdev)
2968bcc1c2a1SAlex Deucher {
2969fe251e2fSAlex Deucher 	const __be32 *fw_data;
2970fe251e2fSAlex Deucher 	int i;
2971bcc1c2a1SAlex Deucher 
2972fe251e2fSAlex Deucher 	if (!rdev->me_fw || !rdev->pfp_fw)
2973fe251e2fSAlex Deucher 		return -EINVAL;
2974fe251e2fSAlex Deucher 
2975fe251e2fSAlex Deucher 	r700_cp_stop(rdev);
29760f234f5fSAlex Deucher 	WREG32(CP_RB_CNTL,
29770f234f5fSAlex Deucher #ifdef __BIG_ENDIAN
29780f234f5fSAlex Deucher 	       BUF_SWAP_32BIT |
29790f234f5fSAlex Deucher #endif
29800f234f5fSAlex Deucher 	       RB_NO_UPDATE | RB_BLKSZ(15) | RB_BUFSZ(3));
2981fe251e2fSAlex Deucher 
2982fe251e2fSAlex Deucher 	fw_data = (const __be32 *)rdev->pfp_fw->data;
2983fe251e2fSAlex Deucher 	WREG32(CP_PFP_UCODE_ADDR, 0);
2984fe251e2fSAlex Deucher 	for (i = 0; i < EVERGREEN_PFP_UCODE_SIZE; i++)
2985fe251e2fSAlex Deucher 		WREG32(CP_PFP_UCODE_DATA, be32_to_cpup(fw_data++));
2986fe251e2fSAlex Deucher 	WREG32(CP_PFP_UCODE_ADDR, 0);
2987fe251e2fSAlex Deucher 
2988fe251e2fSAlex Deucher 	fw_data = (const __be32 *)rdev->me_fw->data;
2989fe251e2fSAlex Deucher 	WREG32(CP_ME_RAM_WADDR, 0);
2990fe251e2fSAlex Deucher 	for (i = 0; i < EVERGREEN_PM4_UCODE_SIZE; i++)
2991fe251e2fSAlex Deucher 		WREG32(CP_ME_RAM_DATA, be32_to_cpup(fw_data++));
2992fe251e2fSAlex Deucher 
2993fe251e2fSAlex Deucher 	WREG32(CP_PFP_UCODE_ADDR, 0);
2994fe251e2fSAlex Deucher 	WREG32(CP_ME_RAM_WADDR, 0);
2995fe251e2fSAlex Deucher 	WREG32(CP_ME_RAM_RADDR, 0);
2996bcc1c2a1SAlex Deucher 	return 0;
2997bcc1c2a1SAlex Deucher }
2998bcc1c2a1SAlex Deucher 
evergreen_cp_start(struct radeon_device * rdev)29997e7b41d2SAlex Deucher static int evergreen_cp_start(struct radeon_device *rdev)
30007e7b41d2SAlex Deucher {
3001e32eb50dSChristian König 	struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX];
30022281a378SAlex Deucher 	int r, i;
30037e7b41d2SAlex Deucher 	uint32_t cp_me;
30047e7b41d2SAlex Deucher 
3005e32eb50dSChristian König 	r = radeon_ring_lock(rdev, ring, 7);
30067e7b41d2SAlex Deucher 	if (r) {
30077e7b41d2SAlex Deucher 		DRM_ERROR("radeon: cp failed to lock ring (%d).\n", r);
30087e7b41d2SAlex Deucher 		return r;
30097e7b41d2SAlex Deucher 	}
3010e32eb50dSChristian König 	radeon_ring_write(ring, PACKET3(PACKET3_ME_INITIALIZE, 5));
3011e32eb50dSChristian König 	radeon_ring_write(ring, 0x1);
3012e32eb50dSChristian König 	radeon_ring_write(ring, 0x0);
3013e32eb50dSChristian König 	radeon_ring_write(ring, rdev->config.evergreen.max_hw_contexts - 1);
3014e32eb50dSChristian König 	radeon_ring_write(ring, PACKET3_ME_INITIALIZE_DEVICE_ID(1));
3015e32eb50dSChristian König 	radeon_ring_write(ring, 0);
3016e32eb50dSChristian König 	radeon_ring_write(ring, 0);
30171538a9e0SMichel Dänzer 	radeon_ring_unlock_commit(rdev, ring, false);
30187e7b41d2SAlex Deucher 
30197e7b41d2SAlex Deucher 	cp_me = 0xff;
30207e7b41d2SAlex Deucher 	WREG32(CP_ME_CNTL, cp_me);
30217e7b41d2SAlex Deucher 
3022e32eb50dSChristian König 	r = radeon_ring_lock(rdev, ring, evergreen_default_size + 19);
30237e7b41d2SAlex Deucher 	if (r) {
30247e7b41d2SAlex Deucher 		DRM_ERROR("radeon: cp failed to lock ring (%d).\n", r);
30257e7b41d2SAlex Deucher 		return r;
30267e7b41d2SAlex Deucher 	}
30272281a378SAlex Deucher 
30282281a378SAlex Deucher 	/* setup clear context state */
3029e32eb50dSChristian König 	radeon_ring_write(ring, PACKET3(PACKET3_PREAMBLE_CNTL, 0));
3030e32eb50dSChristian König 	radeon_ring_write(ring, PACKET3_PREAMBLE_BEGIN_CLEAR_STATE);
30312281a378SAlex Deucher 
30322281a378SAlex Deucher 	for (i = 0; i < evergreen_default_size; i++)
3033e32eb50dSChristian König 		radeon_ring_write(ring, evergreen_default_state[i]);
30342281a378SAlex Deucher 
3035e32eb50dSChristian König 	radeon_ring_write(ring, PACKET3(PACKET3_PREAMBLE_CNTL, 0));
3036e32eb50dSChristian König 	radeon_ring_write(ring, PACKET3_PREAMBLE_END_CLEAR_STATE);
30372281a378SAlex Deucher 
30382281a378SAlex Deucher 	/* set clear context state */
3039e32eb50dSChristian König 	radeon_ring_write(ring, PACKET3(PACKET3_CLEAR_STATE, 0));
3040e32eb50dSChristian König 	radeon_ring_write(ring, 0);
30412281a378SAlex Deucher 
30422281a378SAlex Deucher 	/* SQ_VTX_BASE_VTX_LOC */
3043e32eb50dSChristian König 	radeon_ring_write(ring, 0xc0026f00);
3044e32eb50dSChristian König 	radeon_ring_write(ring, 0x00000000);
3045e32eb50dSChristian König 	radeon_ring_write(ring, 0x00000000);
3046e32eb50dSChristian König 	radeon_ring_write(ring, 0x00000000);
30472281a378SAlex Deucher 
30482281a378SAlex Deucher 	/* Clear consts */
3049e32eb50dSChristian König 	radeon_ring_write(ring, 0xc0036f00);
3050e32eb50dSChristian König 	radeon_ring_write(ring, 0x00000bc4);
3051e32eb50dSChristian König 	radeon_ring_write(ring, 0xffffffff);
3052e32eb50dSChristian König 	radeon_ring_write(ring, 0xffffffff);
3053e32eb50dSChristian König 	radeon_ring_write(ring, 0xffffffff);
30542281a378SAlex Deucher 
3055e32eb50dSChristian König 	radeon_ring_write(ring, 0xc0026900);
3056e32eb50dSChristian König 	radeon_ring_write(ring, 0x00000316);
3057e32eb50dSChristian König 	radeon_ring_write(ring, 0x0000000e); /* VGT_VERTEX_REUSE_BLOCK_CNTL */
3058e32eb50dSChristian König 	radeon_ring_write(ring, 0x00000010); /*  */
305918ff84daSAlex Deucher 
30601538a9e0SMichel Dänzer 	radeon_ring_unlock_commit(rdev, ring, false);
30617e7b41d2SAlex Deucher 
30627e7b41d2SAlex Deucher 	return 0;
30637e7b41d2SAlex Deucher }
30647e7b41d2SAlex Deucher 
evergreen_cp_resume(struct radeon_device * rdev)30651109ca09SLauri Kasanen static int evergreen_cp_resume(struct radeon_device *rdev)
3066fe251e2fSAlex Deucher {
3067e32eb50dSChristian König 	struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX];
3068fe251e2fSAlex Deucher 	u32 tmp;
3069fe251e2fSAlex Deucher 	u32 rb_bufsz;
3070fe251e2fSAlex Deucher 	int r;
3071fe251e2fSAlex Deucher 
3072fe251e2fSAlex Deucher 	/* Reset cp; if cp is reset, then PA, SH, VGT also need to be reset */
3073fe251e2fSAlex Deucher 	WREG32(GRBM_SOFT_RESET, (SOFT_RESET_CP |
3074fe251e2fSAlex Deucher 				 SOFT_RESET_PA |
3075fe251e2fSAlex Deucher 				 SOFT_RESET_SH |
3076fe251e2fSAlex Deucher 				 SOFT_RESET_VGT |
3077a49a50daSJerome Glisse 				 SOFT_RESET_SPI |
3078fe251e2fSAlex Deucher 				 SOFT_RESET_SX));
3079fe251e2fSAlex Deucher 	RREG32(GRBM_SOFT_RESET);
3080fe251e2fSAlex Deucher 	mdelay(15);
3081fe251e2fSAlex Deucher 	WREG32(GRBM_SOFT_RESET, 0);
3082fe251e2fSAlex Deucher 	RREG32(GRBM_SOFT_RESET);
3083fe251e2fSAlex Deucher 
3084fe251e2fSAlex Deucher 	/* Set ring buffer size */
3085b72a8925SDaniel Vetter 	rb_bufsz = order_base_2(ring->ring_size / 8);
3086b72a8925SDaniel Vetter 	tmp = (order_base_2(RADEON_GPU_PAGE_SIZE/8) << 8) | rb_bufsz;
3087fe251e2fSAlex Deucher #ifdef __BIG_ENDIAN
3088fe251e2fSAlex Deucher 	tmp |= BUF_SWAP_32BIT;
308932fcdbf4SAlex Deucher #endif
3090fe251e2fSAlex Deucher 	WREG32(CP_RB_CNTL, tmp);
309115d3332fSChristian König 	WREG32(CP_SEM_WAIT_TIMER, 0x0);
309211ef3f1fSAlex Deucher 	WREG32(CP_SEM_INCOMPLETE_TIMER_CNTL, 0x0);
3093fe251e2fSAlex Deucher 
3094fe251e2fSAlex Deucher 	/* Set the write pointer delay */
3095fe251e2fSAlex Deucher 	WREG32(CP_RB_WPTR_DELAY, 0);
3096fe251e2fSAlex Deucher 
3097fe251e2fSAlex Deucher 	/* Initialize the ring buffer's read and write pointers */
3098fe251e2fSAlex Deucher 	WREG32(CP_RB_CNTL, tmp | RB_RPTR_WR_ENA);
3099fe251e2fSAlex Deucher 	WREG32(CP_RB_RPTR_WR, 0);
3100e32eb50dSChristian König 	ring->wptr = 0;
3101e32eb50dSChristian König 	WREG32(CP_RB_WPTR, ring->wptr);
3102724c80e1SAlex Deucher 
310348fc7f7eSAdam Buchbinder 	/* set the wb address whether it's enabled or not */
31040f234f5fSAlex Deucher 	WREG32(CP_RB_RPTR_ADDR,
31050f234f5fSAlex Deucher 	       ((rdev->wb.gpu_addr + RADEON_WB_CP_RPTR_OFFSET) & 0xFFFFFFFC));
3106724c80e1SAlex Deucher 	WREG32(CP_RB_RPTR_ADDR_HI, upper_32_bits(rdev->wb.gpu_addr + RADEON_WB_CP_RPTR_OFFSET) & 0xFF);
3107724c80e1SAlex Deucher 	WREG32(SCRATCH_ADDR, ((rdev->wb.gpu_addr + RADEON_WB_SCRATCH_OFFSET) >> 8) & 0xFFFFFFFF);
3108724c80e1SAlex Deucher 
3109724c80e1SAlex Deucher 	if (rdev->wb.enabled)
3110724c80e1SAlex Deucher 		WREG32(SCRATCH_UMSK, 0xff);
3111724c80e1SAlex Deucher 	else {
3112724c80e1SAlex Deucher 		tmp |= RB_NO_UPDATE;
3113724c80e1SAlex Deucher 		WREG32(SCRATCH_UMSK, 0);
3114724c80e1SAlex Deucher 	}
3115724c80e1SAlex Deucher 
3116fe251e2fSAlex Deucher 	mdelay(1);
3117fe251e2fSAlex Deucher 	WREG32(CP_RB_CNTL, tmp);
3118fe251e2fSAlex Deucher 
3119e32eb50dSChristian König 	WREG32(CP_RB_BASE, ring->gpu_addr >> 8);
3120fe251e2fSAlex Deucher 	WREG32(CP_DEBUG, (1 << 27) | (1 << 28));
3121fe251e2fSAlex Deucher 
31227e7b41d2SAlex Deucher 	evergreen_cp_start(rdev);
3123e32eb50dSChristian König 	ring->ready = true;
3124f712812eSAlex Deucher 	r = radeon_ring_test(rdev, RADEON_RING_TYPE_GFX_INDEX, ring);
3125fe251e2fSAlex Deucher 	if (r) {
3126e32eb50dSChristian König 		ring->ready = false;
3127fe251e2fSAlex Deucher 		return r;
3128fe251e2fSAlex Deucher 	}
3129fe251e2fSAlex Deucher 	return 0;
3130fe251e2fSAlex Deucher }
3131bcc1c2a1SAlex Deucher 
3132bcc1c2a1SAlex Deucher /*
3133bcc1c2a1SAlex Deucher  * Core functions
3134bcc1c2a1SAlex Deucher  */
evergreen_gpu_init(struct radeon_device * rdev)3135bcc1c2a1SAlex Deucher static void evergreen_gpu_init(struct radeon_device *rdev)
3136bcc1c2a1SAlex Deucher {
3137416a2bd2SAlex Deucher 	u32 gb_addr_config;
3138ca648e38SLee Jones 	u32 mc_arb_ramcfg;
313932fcdbf4SAlex Deucher 	u32 sx_debug_1;
314032fcdbf4SAlex Deucher 	u32 smx_dc_ctl0;
314132fcdbf4SAlex Deucher 	u32 sq_config;
314232fcdbf4SAlex Deucher 	u32 sq_lds_resource_mgmt;
314332fcdbf4SAlex Deucher 	u32 sq_gpr_resource_mgmt_1;
314432fcdbf4SAlex Deucher 	u32 sq_gpr_resource_mgmt_2;
314532fcdbf4SAlex Deucher 	u32 sq_gpr_resource_mgmt_3;
314632fcdbf4SAlex Deucher 	u32 sq_thread_resource_mgmt;
314732fcdbf4SAlex Deucher 	u32 sq_thread_resource_mgmt_2;
314832fcdbf4SAlex Deucher 	u32 sq_stack_resource_mgmt_1;
314932fcdbf4SAlex Deucher 	u32 sq_stack_resource_mgmt_2;
315032fcdbf4SAlex Deucher 	u32 sq_stack_resource_mgmt_3;
315132fcdbf4SAlex Deucher 	u32 vgt_cache_invalidation;
3152f25a5c63SAlex Deucher 	u32 hdp_host_path_cntl, tmp;
3153416a2bd2SAlex Deucher 	u32 disabled_rb_mask;
3154072c44bfSDan Carpenter 	int i, j, ps_thread_count;
315532fcdbf4SAlex Deucher 
315632fcdbf4SAlex Deucher 	switch (rdev->family) {
315732fcdbf4SAlex Deucher 	case CHIP_CYPRESS:
315832fcdbf4SAlex Deucher 	case CHIP_HEMLOCK:
315932fcdbf4SAlex Deucher 		rdev->config.evergreen.num_ses = 2;
316032fcdbf4SAlex Deucher 		rdev->config.evergreen.max_pipes = 4;
316132fcdbf4SAlex Deucher 		rdev->config.evergreen.max_tile_pipes = 8;
316232fcdbf4SAlex Deucher 		rdev->config.evergreen.max_simds = 10;
316332fcdbf4SAlex Deucher 		rdev->config.evergreen.max_backends = 4 * rdev->config.evergreen.num_ses;
316432fcdbf4SAlex Deucher 		rdev->config.evergreen.max_gprs = 256;
316532fcdbf4SAlex Deucher 		rdev->config.evergreen.max_threads = 248;
316632fcdbf4SAlex Deucher 		rdev->config.evergreen.max_gs_threads = 32;
316732fcdbf4SAlex Deucher 		rdev->config.evergreen.max_stack_entries = 512;
316832fcdbf4SAlex Deucher 		rdev->config.evergreen.sx_num_of_sets = 4;
316932fcdbf4SAlex Deucher 		rdev->config.evergreen.sx_max_export_size = 256;
317032fcdbf4SAlex Deucher 		rdev->config.evergreen.sx_max_export_pos_size = 64;
317132fcdbf4SAlex Deucher 		rdev->config.evergreen.sx_max_export_smx_size = 192;
317232fcdbf4SAlex Deucher 		rdev->config.evergreen.max_hw_contexts = 8;
317332fcdbf4SAlex Deucher 		rdev->config.evergreen.sq_num_cf_insts = 2;
317432fcdbf4SAlex Deucher 
317532fcdbf4SAlex Deucher 		rdev->config.evergreen.sc_prim_fifo_size = 0x100;
317632fcdbf4SAlex Deucher 		rdev->config.evergreen.sc_hiz_tile_fifo_size = 0x30;
317732fcdbf4SAlex Deucher 		rdev->config.evergreen.sc_earlyz_tile_fifo_size = 0x130;
3178416a2bd2SAlex Deucher 		gb_addr_config = CYPRESS_GB_ADDR_CONFIG_GOLDEN;
317932fcdbf4SAlex Deucher 		break;
318032fcdbf4SAlex Deucher 	case CHIP_JUNIPER:
318132fcdbf4SAlex Deucher 		rdev->config.evergreen.num_ses = 1;
318232fcdbf4SAlex Deucher 		rdev->config.evergreen.max_pipes = 4;
318332fcdbf4SAlex Deucher 		rdev->config.evergreen.max_tile_pipes = 4;
318432fcdbf4SAlex Deucher 		rdev->config.evergreen.max_simds = 10;
318532fcdbf4SAlex Deucher 		rdev->config.evergreen.max_backends = 4 * rdev->config.evergreen.num_ses;
318632fcdbf4SAlex Deucher 		rdev->config.evergreen.max_gprs = 256;
318732fcdbf4SAlex Deucher 		rdev->config.evergreen.max_threads = 248;
318832fcdbf4SAlex Deucher 		rdev->config.evergreen.max_gs_threads = 32;
318932fcdbf4SAlex Deucher 		rdev->config.evergreen.max_stack_entries = 512;
319032fcdbf4SAlex Deucher 		rdev->config.evergreen.sx_num_of_sets = 4;
319132fcdbf4SAlex Deucher 		rdev->config.evergreen.sx_max_export_size = 256;
319232fcdbf4SAlex Deucher 		rdev->config.evergreen.sx_max_export_pos_size = 64;
319332fcdbf4SAlex Deucher 		rdev->config.evergreen.sx_max_export_smx_size = 192;
319432fcdbf4SAlex Deucher 		rdev->config.evergreen.max_hw_contexts = 8;
319532fcdbf4SAlex Deucher 		rdev->config.evergreen.sq_num_cf_insts = 2;
319632fcdbf4SAlex Deucher 
319732fcdbf4SAlex Deucher 		rdev->config.evergreen.sc_prim_fifo_size = 0x100;
319832fcdbf4SAlex Deucher 		rdev->config.evergreen.sc_hiz_tile_fifo_size = 0x30;
319932fcdbf4SAlex Deucher 		rdev->config.evergreen.sc_earlyz_tile_fifo_size = 0x130;
3200416a2bd2SAlex Deucher 		gb_addr_config = JUNIPER_GB_ADDR_CONFIG_GOLDEN;
320132fcdbf4SAlex Deucher 		break;
320232fcdbf4SAlex Deucher 	case CHIP_REDWOOD:
320332fcdbf4SAlex Deucher 		rdev->config.evergreen.num_ses = 1;
320432fcdbf4SAlex Deucher 		rdev->config.evergreen.max_pipes = 4;
320532fcdbf4SAlex Deucher 		rdev->config.evergreen.max_tile_pipes = 4;
320632fcdbf4SAlex Deucher 		rdev->config.evergreen.max_simds = 5;
320732fcdbf4SAlex Deucher 		rdev->config.evergreen.max_backends = 2 * rdev->config.evergreen.num_ses;
320832fcdbf4SAlex Deucher 		rdev->config.evergreen.max_gprs = 256;
320932fcdbf4SAlex Deucher 		rdev->config.evergreen.max_threads = 248;
321032fcdbf4SAlex Deucher 		rdev->config.evergreen.max_gs_threads = 32;
321132fcdbf4SAlex Deucher 		rdev->config.evergreen.max_stack_entries = 256;
321232fcdbf4SAlex Deucher 		rdev->config.evergreen.sx_num_of_sets = 4;
321332fcdbf4SAlex Deucher 		rdev->config.evergreen.sx_max_export_size = 256;
321432fcdbf4SAlex Deucher 		rdev->config.evergreen.sx_max_export_pos_size = 64;
321532fcdbf4SAlex Deucher 		rdev->config.evergreen.sx_max_export_smx_size = 192;
321632fcdbf4SAlex Deucher 		rdev->config.evergreen.max_hw_contexts = 8;
321732fcdbf4SAlex Deucher 		rdev->config.evergreen.sq_num_cf_insts = 2;
321832fcdbf4SAlex Deucher 
321932fcdbf4SAlex Deucher 		rdev->config.evergreen.sc_prim_fifo_size = 0x100;
322032fcdbf4SAlex Deucher 		rdev->config.evergreen.sc_hiz_tile_fifo_size = 0x30;
322132fcdbf4SAlex Deucher 		rdev->config.evergreen.sc_earlyz_tile_fifo_size = 0x130;
3222416a2bd2SAlex Deucher 		gb_addr_config = REDWOOD_GB_ADDR_CONFIG_GOLDEN;
322332fcdbf4SAlex Deucher 		break;
322432fcdbf4SAlex Deucher 	case CHIP_CEDAR:
322532fcdbf4SAlex Deucher 	default:
322632fcdbf4SAlex Deucher 		rdev->config.evergreen.num_ses = 1;
322732fcdbf4SAlex Deucher 		rdev->config.evergreen.max_pipes = 2;
322832fcdbf4SAlex Deucher 		rdev->config.evergreen.max_tile_pipes = 2;
322932fcdbf4SAlex Deucher 		rdev->config.evergreen.max_simds = 2;
323032fcdbf4SAlex Deucher 		rdev->config.evergreen.max_backends = 1 * rdev->config.evergreen.num_ses;
323132fcdbf4SAlex Deucher 		rdev->config.evergreen.max_gprs = 256;
323232fcdbf4SAlex Deucher 		rdev->config.evergreen.max_threads = 192;
323332fcdbf4SAlex Deucher 		rdev->config.evergreen.max_gs_threads = 16;
323432fcdbf4SAlex Deucher 		rdev->config.evergreen.max_stack_entries = 256;
323532fcdbf4SAlex Deucher 		rdev->config.evergreen.sx_num_of_sets = 4;
323632fcdbf4SAlex Deucher 		rdev->config.evergreen.sx_max_export_size = 128;
323732fcdbf4SAlex Deucher 		rdev->config.evergreen.sx_max_export_pos_size = 32;
323832fcdbf4SAlex Deucher 		rdev->config.evergreen.sx_max_export_smx_size = 96;
323932fcdbf4SAlex Deucher 		rdev->config.evergreen.max_hw_contexts = 4;
324032fcdbf4SAlex Deucher 		rdev->config.evergreen.sq_num_cf_insts = 1;
324132fcdbf4SAlex Deucher 
324232fcdbf4SAlex Deucher 		rdev->config.evergreen.sc_prim_fifo_size = 0x40;
324332fcdbf4SAlex Deucher 		rdev->config.evergreen.sc_hiz_tile_fifo_size = 0x30;
324432fcdbf4SAlex Deucher 		rdev->config.evergreen.sc_earlyz_tile_fifo_size = 0x130;
3245416a2bd2SAlex Deucher 		gb_addr_config = CEDAR_GB_ADDR_CONFIG_GOLDEN;
324632fcdbf4SAlex Deucher 		break;
3247d5e455e4SAlex Deucher 	case CHIP_PALM:
3248d5e455e4SAlex Deucher 		rdev->config.evergreen.num_ses = 1;
3249d5e455e4SAlex Deucher 		rdev->config.evergreen.max_pipes = 2;
3250d5e455e4SAlex Deucher 		rdev->config.evergreen.max_tile_pipes = 2;
3251d5e455e4SAlex Deucher 		rdev->config.evergreen.max_simds = 2;
3252d5e455e4SAlex Deucher 		rdev->config.evergreen.max_backends = 1 * rdev->config.evergreen.num_ses;
3253d5e455e4SAlex Deucher 		rdev->config.evergreen.max_gprs = 256;
3254d5e455e4SAlex Deucher 		rdev->config.evergreen.max_threads = 192;
3255d5e455e4SAlex Deucher 		rdev->config.evergreen.max_gs_threads = 16;
3256d5e455e4SAlex Deucher 		rdev->config.evergreen.max_stack_entries = 256;
3257d5e455e4SAlex Deucher 		rdev->config.evergreen.sx_num_of_sets = 4;
3258d5e455e4SAlex Deucher 		rdev->config.evergreen.sx_max_export_size = 128;
3259d5e455e4SAlex Deucher 		rdev->config.evergreen.sx_max_export_pos_size = 32;
3260d5e455e4SAlex Deucher 		rdev->config.evergreen.sx_max_export_smx_size = 96;
3261d5e455e4SAlex Deucher 		rdev->config.evergreen.max_hw_contexts = 4;
3262d5e455e4SAlex Deucher 		rdev->config.evergreen.sq_num_cf_insts = 1;
3263d5e455e4SAlex Deucher 
3264d5e455e4SAlex Deucher 		rdev->config.evergreen.sc_prim_fifo_size = 0x40;
3265d5e455e4SAlex Deucher 		rdev->config.evergreen.sc_hiz_tile_fifo_size = 0x30;
3266d5e455e4SAlex Deucher 		rdev->config.evergreen.sc_earlyz_tile_fifo_size = 0x130;
3267416a2bd2SAlex Deucher 		gb_addr_config = CEDAR_GB_ADDR_CONFIG_GOLDEN;
3268d5e455e4SAlex Deucher 		break;
3269d5c5a72fSAlex Deucher 	case CHIP_SUMO:
3270d5c5a72fSAlex Deucher 		rdev->config.evergreen.num_ses = 1;
3271d5c5a72fSAlex Deucher 		rdev->config.evergreen.max_pipes = 4;
3272bd25f078SJerome Glisse 		rdev->config.evergreen.max_tile_pipes = 4;
3273d5c5a72fSAlex Deucher 		if (rdev->pdev->device == 0x9648)
3274d5c5a72fSAlex Deucher 			rdev->config.evergreen.max_simds = 3;
3275d5c5a72fSAlex Deucher 		else if ((rdev->pdev->device == 0x9647) ||
3276d5c5a72fSAlex Deucher 			 (rdev->pdev->device == 0x964a))
3277d5c5a72fSAlex Deucher 			rdev->config.evergreen.max_simds = 4;
3278d5c5a72fSAlex Deucher 		else
3279d5c5a72fSAlex Deucher 			rdev->config.evergreen.max_simds = 5;
3280d5c5a72fSAlex Deucher 		rdev->config.evergreen.max_backends = 2 * rdev->config.evergreen.num_ses;
3281d5c5a72fSAlex Deucher 		rdev->config.evergreen.max_gprs = 256;
3282d5c5a72fSAlex Deucher 		rdev->config.evergreen.max_threads = 248;
3283d5c5a72fSAlex Deucher 		rdev->config.evergreen.max_gs_threads = 32;
3284d5c5a72fSAlex Deucher 		rdev->config.evergreen.max_stack_entries = 256;
3285d5c5a72fSAlex Deucher 		rdev->config.evergreen.sx_num_of_sets = 4;
3286d5c5a72fSAlex Deucher 		rdev->config.evergreen.sx_max_export_size = 256;
3287d5c5a72fSAlex Deucher 		rdev->config.evergreen.sx_max_export_pos_size = 64;
3288d5c5a72fSAlex Deucher 		rdev->config.evergreen.sx_max_export_smx_size = 192;
3289d5c5a72fSAlex Deucher 		rdev->config.evergreen.max_hw_contexts = 8;
3290d5c5a72fSAlex Deucher 		rdev->config.evergreen.sq_num_cf_insts = 2;
3291d5c5a72fSAlex Deucher 
3292d5c5a72fSAlex Deucher 		rdev->config.evergreen.sc_prim_fifo_size = 0x40;
3293d5c5a72fSAlex Deucher 		rdev->config.evergreen.sc_hiz_tile_fifo_size = 0x30;
3294d5c5a72fSAlex Deucher 		rdev->config.evergreen.sc_earlyz_tile_fifo_size = 0x130;
3295bd25f078SJerome Glisse 		gb_addr_config = SUMO_GB_ADDR_CONFIG_GOLDEN;
3296d5c5a72fSAlex Deucher 		break;
3297d5c5a72fSAlex Deucher 	case CHIP_SUMO2:
3298d5c5a72fSAlex Deucher 		rdev->config.evergreen.num_ses = 1;
3299d5c5a72fSAlex Deucher 		rdev->config.evergreen.max_pipes = 4;
3300d5c5a72fSAlex Deucher 		rdev->config.evergreen.max_tile_pipes = 4;
3301d5c5a72fSAlex Deucher 		rdev->config.evergreen.max_simds = 2;
3302d5c5a72fSAlex Deucher 		rdev->config.evergreen.max_backends = 1 * rdev->config.evergreen.num_ses;
3303d5c5a72fSAlex Deucher 		rdev->config.evergreen.max_gprs = 256;
3304d5c5a72fSAlex Deucher 		rdev->config.evergreen.max_threads = 248;
3305d5c5a72fSAlex Deucher 		rdev->config.evergreen.max_gs_threads = 32;
3306d5c5a72fSAlex Deucher 		rdev->config.evergreen.max_stack_entries = 512;
3307d5c5a72fSAlex Deucher 		rdev->config.evergreen.sx_num_of_sets = 4;
3308d5c5a72fSAlex Deucher 		rdev->config.evergreen.sx_max_export_size = 256;
3309d5c5a72fSAlex Deucher 		rdev->config.evergreen.sx_max_export_pos_size = 64;
3310d5c5a72fSAlex Deucher 		rdev->config.evergreen.sx_max_export_smx_size = 192;
331150b8f5aeSwojciech kapuscinski 		rdev->config.evergreen.max_hw_contexts = 4;
3312d5c5a72fSAlex Deucher 		rdev->config.evergreen.sq_num_cf_insts = 2;
3313d5c5a72fSAlex Deucher 
3314d5c5a72fSAlex Deucher 		rdev->config.evergreen.sc_prim_fifo_size = 0x40;
3315d5c5a72fSAlex Deucher 		rdev->config.evergreen.sc_hiz_tile_fifo_size = 0x30;
3316d5c5a72fSAlex Deucher 		rdev->config.evergreen.sc_earlyz_tile_fifo_size = 0x130;
3317bd25f078SJerome Glisse 		gb_addr_config = SUMO2_GB_ADDR_CONFIG_GOLDEN;
3318d5c5a72fSAlex Deucher 		break;
3319adb68fa2SAlex Deucher 	case CHIP_BARTS:
3320adb68fa2SAlex Deucher 		rdev->config.evergreen.num_ses = 2;
3321adb68fa2SAlex Deucher 		rdev->config.evergreen.max_pipes = 4;
3322adb68fa2SAlex Deucher 		rdev->config.evergreen.max_tile_pipes = 8;
3323adb68fa2SAlex Deucher 		rdev->config.evergreen.max_simds = 7;
3324adb68fa2SAlex Deucher 		rdev->config.evergreen.max_backends = 4 * rdev->config.evergreen.num_ses;
3325adb68fa2SAlex Deucher 		rdev->config.evergreen.max_gprs = 256;
3326adb68fa2SAlex Deucher 		rdev->config.evergreen.max_threads = 248;
3327adb68fa2SAlex Deucher 		rdev->config.evergreen.max_gs_threads = 32;
3328adb68fa2SAlex Deucher 		rdev->config.evergreen.max_stack_entries = 512;
3329adb68fa2SAlex Deucher 		rdev->config.evergreen.sx_num_of_sets = 4;
3330adb68fa2SAlex Deucher 		rdev->config.evergreen.sx_max_export_size = 256;
3331adb68fa2SAlex Deucher 		rdev->config.evergreen.sx_max_export_pos_size = 64;
3332adb68fa2SAlex Deucher 		rdev->config.evergreen.sx_max_export_smx_size = 192;
3333adb68fa2SAlex Deucher 		rdev->config.evergreen.max_hw_contexts = 8;
3334adb68fa2SAlex Deucher 		rdev->config.evergreen.sq_num_cf_insts = 2;
3335adb68fa2SAlex Deucher 
3336adb68fa2SAlex Deucher 		rdev->config.evergreen.sc_prim_fifo_size = 0x100;
3337adb68fa2SAlex Deucher 		rdev->config.evergreen.sc_hiz_tile_fifo_size = 0x30;
3338adb68fa2SAlex Deucher 		rdev->config.evergreen.sc_earlyz_tile_fifo_size = 0x130;
3339416a2bd2SAlex Deucher 		gb_addr_config = BARTS_GB_ADDR_CONFIG_GOLDEN;
3340adb68fa2SAlex Deucher 		break;
3341adb68fa2SAlex Deucher 	case CHIP_TURKS:
3342adb68fa2SAlex Deucher 		rdev->config.evergreen.num_ses = 1;
3343adb68fa2SAlex Deucher 		rdev->config.evergreen.max_pipes = 4;
3344adb68fa2SAlex Deucher 		rdev->config.evergreen.max_tile_pipes = 4;
3345adb68fa2SAlex Deucher 		rdev->config.evergreen.max_simds = 6;
3346adb68fa2SAlex Deucher 		rdev->config.evergreen.max_backends = 2 * rdev->config.evergreen.num_ses;
3347adb68fa2SAlex Deucher 		rdev->config.evergreen.max_gprs = 256;
3348adb68fa2SAlex Deucher 		rdev->config.evergreen.max_threads = 248;
3349adb68fa2SAlex Deucher 		rdev->config.evergreen.max_gs_threads = 32;
3350adb68fa2SAlex Deucher 		rdev->config.evergreen.max_stack_entries = 256;
3351adb68fa2SAlex Deucher 		rdev->config.evergreen.sx_num_of_sets = 4;
3352adb68fa2SAlex Deucher 		rdev->config.evergreen.sx_max_export_size = 256;
3353adb68fa2SAlex Deucher 		rdev->config.evergreen.sx_max_export_pos_size = 64;
3354adb68fa2SAlex Deucher 		rdev->config.evergreen.sx_max_export_smx_size = 192;
3355adb68fa2SAlex Deucher 		rdev->config.evergreen.max_hw_contexts = 8;
3356adb68fa2SAlex Deucher 		rdev->config.evergreen.sq_num_cf_insts = 2;
3357adb68fa2SAlex Deucher 
3358adb68fa2SAlex Deucher 		rdev->config.evergreen.sc_prim_fifo_size = 0x100;
3359adb68fa2SAlex Deucher 		rdev->config.evergreen.sc_hiz_tile_fifo_size = 0x30;
3360adb68fa2SAlex Deucher 		rdev->config.evergreen.sc_earlyz_tile_fifo_size = 0x130;
3361416a2bd2SAlex Deucher 		gb_addr_config = TURKS_GB_ADDR_CONFIG_GOLDEN;
3362adb68fa2SAlex Deucher 		break;
3363adb68fa2SAlex Deucher 	case CHIP_CAICOS:
3364adb68fa2SAlex Deucher 		rdev->config.evergreen.num_ses = 1;
3365bd25f078SJerome Glisse 		rdev->config.evergreen.max_pipes = 2;
3366adb68fa2SAlex Deucher 		rdev->config.evergreen.max_tile_pipes = 2;
3367adb68fa2SAlex Deucher 		rdev->config.evergreen.max_simds = 2;
3368adb68fa2SAlex Deucher 		rdev->config.evergreen.max_backends = 1 * rdev->config.evergreen.num_ses;
3369adb68fa2SAlex Deucher 		rdev->config.evergreen.max_gprs = 256;
3370adb68fa2SAlex Deucher 		rdev->config.evergreen.max_threads = 192;
3371adb68fa2SAlex Deucher 		rdev->config.evergreen.max_gs_threads = 16;
3372adb68fa2SAlex Deucher 		rdev->config.evergreen.max_stack_entries = 256;
3373adb68fa2SAlex Deucher 		rdev->config.evergreen.sx_num_of_sets = 4;
3374adb68fa2SAlex Deucher 		rdev->config.evergreen.sx_max_export_size = 128;
3375adb68fa2SAlex Deucher 		rdev->config.evergreen.sx_max_export_pos_size = 32;
3376adb68fa2SAlex Deucher 		rdev->config.evergreen.sx_max_export_smx_size = 96;
3377adb68fa2SAlex Deucher 		rdev->config.evergreen.max_hw_contexts = 4;
3378adb68fa2SAlex Deucher 		rdev->config.evergreen.sq_num_cf_insts = 1;
3379adb68fa2SAlex Deucher 
3380adb68fa2SAlex Deucher 		rdev->config.evergreen.sc_prim_fifo_size = 0x40;
3381adb68fa2SAlex Deucher 		rdev->config.evergreen.sc_hiz_tile_fifo_size = 0x30;
3382adb68fa2SAlex Deucher 		rdev->config.evergreen.sc_earlyz_tile_fifo_size = 0x130;
3383416a2bd2SAlex Deucher 		gb_addr_config = CAICOS_GB_ADDR_CONFIG_GOLDEN;
3384adb68fa2SAlex Deucher 		break;
338532fcdbf4SAlex Deucher 	}
338632fcdbf4SAlex Deucher 
338732fcdbf4SAlex Deucher 	/* Initialize HDP */
338832fcdbf4SAlex Deucher 	for (i = 0, j = 0; i < 32; i++, j += 0x18) {
338932fcdbf4SAlex Deucher 		WREG32((0x2c14 + j), 0x00000000);
339032fcdbf4SAlex Deucher 		WREG32((0x2c18 + j), 0x00000000);
339132fcdbf4SAlex Deucher 		WREG32((0x2c1c + j), 0x00000000);
339232fcdbf4SAlex Deucher 		WREG32((0x2c20 + j), 0x00000000);
339332fcdbf4SAlex Deucher 		WREG32((0x2c24 + j), 0x00000000);
339432fcdbf4SAlex Deucher 	}
339532fcdbf4SAlex Deucher 
339632fcdbf4SAlex Deucher 	WREG32(GRBM_CNTL, GRBM_READ_TIMEOUT(0xff));
3397acc1522aSChristian König 	WREG32(SRBM_INT_CNTL, 0x1);
3398acc1522aSChristian König 	WREG32(SRBM_INT_ACK, 0x1);
339932fcdbf4SAlex Deucher 
3400d054ac16SAlex Deucher 	evergreen_fix_pci_max_read_req_size(rdev);
3401d054ac16SAlex Deucher 
3402ca648e38SLee Jones 	RREG32(MC_SHARED_CHMAP);
340305b3ef69SAlex Deucher 	if ((rdev->family == CHIP_PALM) ||
340405b3ef69SAlex Deucher 	    (rdev->family == CHIP_SUMO) ||
340505b3ef69SAlex Deucher 	    (rdev->family == CHIP_SUMO2))
3406d9282fcaSAlex Deucher 		mc_arb_ramcfg = RREG32(FUS_MC_ARB_RAMCFG);
3407d9282fcaSAlex Deucher 	else
340832fcdbf4SAlex Deucher 		mc_arb_ramcfg = RREG32(MC_ARB_RAMCFG);
340932fcdbf4SAlex Deucher 
34101aa52bd3SAlex Deucher 	/* setup tiling info dword.  gb_addr_config is not adequate since it does
34111aa52bd3SAlex Deucher 	 * not have bank info, so create a custom tiling dword.
34121aa52bd3SAlex Deucher 	 * bits 3:0   num_pipes
34131aa52bd3SAlex Deucher 	 * bits 7:4   num_banks
34141aa52bd3SAlex Deucher 	 * bits 11:8  group_size
34151aa52bd3SAlex Deucher 	 * bits 15:12 row_size
34161aa52bd3SAlex Deucher 	 */
34171aa52bd3SAlex Deucher 	rdev->config.evergreen.tile_config = 0;
34181aa52bd3SAlex Deucher 	switch (rdev->config.evergreen.max_tile_pipes) {
34191aa52bd3SAlex Deucher 	case 1:
34201aa52bd3SAlex Deucher 	default:
34211aa52bd3SAlex Deucher 		rdev->config.evergreen.tile_config |= (0 << 0);
34221aa52bd3SAlex Deucher 		break;
34231aa52bd3SAlex Deucher 	case 2:
34241aa52bd3SAlex Deucher 		rdev->config.evergreen.tile_config |= (1 << 0);
34251aa52bd3SAlex Deucher 		break;
34261aa52bd3SAlex Deucher 	case 4:
34271aa52bd3SAlex Deucher 		rdev->config.evergreen.tile_config |= (2 << 0);
34281aa52bd3SAlex Deucher 		break;
34291aa52bd3SAlex Deucher 	case 8:
34301aa52bd3SAlex Deucher 		rdev->config.evergreen.tile_config |= (3 << 0);
34311aa52bd3SAlex Deucher 		break;
34321aa52bd3SAlex Deucher 	}
3433d698a34dSAlex Deucher 	/* num banks is 8 on all fusion asics. 0 = 4, 1 = 8, 2 = 16 */
34345bfa4879SAlex Deucher 	if (rdev->flags & RADEON_IS_IGP)
3435d698a34dSAlex Deucher 		rdev->config.evergreen.tile_config |= 1 << 4;
343629d65406SAlex Deucher 	else {
3437c8d15edcSAlex Deucher 		switch ((mc_arb_ramcfg & NOOFBANK_MASK) >> NOOFBANK_SHIFT) {
3438c8d15edcSAlex Deucher 		case 0: /* four banks */
343929d65406SAlex Deucher 			rdev->config.evergreen.tile_config |= 0 << 4;
3440c8d15edcSAlex Deucher 			break;
3441c8d15edcSAlex Deucher 		case 1: /* eight banks */
3442c8d15edcSAlex Deucher 			rdev->config.evergreen.tile_config |= 1 << 4;
3443c8d15edcSAlex Deucher 			break;
3444c8d15edcSAlex Deucher 		case 2: /* sixteen banks */
3445c8d15edcSAlex Deucher 		default:
3446c8d15edcSAlex Deucher 			rdev->config.evergreen.tile_config |= 2 << 4;
3447c8d15edcSAlex Deucher 			break;
3448c8d15edcSAlex Deucher 		}
344929d65406SAlex Deucher 	}
3450416a2bd2SAlex Deucher 	rdev->config.evergreen.tile_config |= 0 << 8;
34511aa52bd3SAlex Deucher 	rdev->config.evergreen.tile_config |=
34521aa52bd3SAlex Deucher 		((gb_addr_config & 0x30000000) >> 28) << 12;
34531aa52bd3SAlex Deucher 
3454416a2bd2SAlex Deucher 	if ((rdev->family >= CHIP_CEDAR) && (rdev->family <= CHIP_HEMLOCK)) {
3455416a2bd2SAlex Deucher 		u32 efuse_straps_4;
3456416a2bd2SAlex Deucher 		u32 efuse_straps_3;
3457416a2bd2SAlex Deucher 
3458ff82bbc4SAlex Deucher 		efuse_straps_4 = RREG32_RCU(0x204);
3459ff82bbc4SAlex Deucher 		efuse_straps_3 = RREG32_RCU(0x203);
3460416a2bd2SAlex Deucher 		tmp = (((efuse_straps_4 & 0xf) << 4) |
3461416a2bd2SAlex Deucher 		      ((efuse_straps_3 & 0xf0000000) >> 28));
3462416a2bd2SAlex Deucher 	} else {
3463416a2bd2SAlex Deucher 		tmp = 0;
3464416a2bd2SAlex Deucher 		for (i = (rdev->config.evergreen.num_ses - 1); i >= 0; i--) {
3465416a2bd2SAlex Deucher 			u32 rb_disable_bitmap;
3466416a2bd2SAlex Deucher 
3467416a2bd2SAlex Deucher 			WREG32(GRBM_GFX_INDEX, INSTANCE_BROADCAST_WRITES | SE_INDEX(i));
3468416a2bd2SAlex Deucher 			WREG32(RLC_GFX_INDEX, INSTANCE_BROADCAST_WRITES | SE_INDEX(i));
3469416a2bd2SAlex Deucher 			rb_disable_bitmap = (RREG32(CC_RB_BACKEND_DISABLE) & 0x00ff0000) >> 16;
3470416a2bd2SAlex Deucher 			tmp <<= 4;
3471416a2bd2SAlex Deucher 			tmp |= rb_disable_bitmap;
3472416a2bd2SAlex Deucher 		}
3473416a2bd2SAlex Deucher 	}
3474416a2bd2SAlex Deucher 	/* enabled rb are just the one not disabled :) */
3475416a2bd2SAlex Deucher 	disabled_rb_mask = tmp;
3476cedb655aSAlex Deucher 	tmp = 0;
3477cedb655aSAlex Deucher 	for (i = 0; i < rdev->config.evergreen.max_backends; i++)
3478cedb655aSAlex Deucher 		tmp |= (1 << i);
3479cedb655aSAlex Deucher 	/* if all the backends are disabled, fix it up here */
3480cedb655aSAlex Deucher 	if ((disabled_rb_mask & tmp) == tmp) {
3481cedb655aSAlex Deucher 		for (i = 0; i < rdev->config.evergreen.max_backends; i++)
3482cedb655aSAlex Deucher 			disabled_rb_mask &= ~(1 << i);
3483cedb655aSAlex Deucher 	}
3484416a2bd2SAlex Deucher 
348565fcf668SAlex Deucher 	for (i = 0; i < rdev->config.evergreen.num_ses; i++) {
348665fcf668SAlex Deucher 		u32 simd_disable_bitmap;
348765fcf668SAlex Deucher 
348865fcf668SAlex Deucher 		WREG32(GRBM_GFX_INDEX, INSTANCE_BROADCAST_WRITES | SE_INDEX(i));
348965fcf668SAlex Deucher 		WREG32(RLC_GFX_INDEX, INSTANCE_BROADCAST_WRITES | SE_INDEX(i));
349065fcf668SAlex Deucher 		simd_disable_bitmap = (RREG32(CC_GC_SHADER_PIPE_CONFIG) & 0xffff0000) >> 16;
349165fcf668SAlex Deucher 		simd_disable_bitmap |= 0xffffffff << rdev->config.evergreen.max_simds;
349265fcf668SAlex Deucher 		tmp <<= 16;
349365fcf668SAlex Deucher 		tmp |= simd_disable_bitmap;
349465fcf668SAlex Deucher 	}
349565fcf668SAlex Deucher 	rdev->config.evergreen.active_simds = hweight32(~tmp);
349665fcf668SAlex Deucher 
3497416a2bd2SAlex Deucher 	WREG32(GRBM_GFX_INDEX, INSTANCE_BROADCAST_WRITES | SE_BROADCAST_WRITES);
3498416a2bd2SAlex Deucher 	WREG32(RLC_GFX_INDEX, INSTANCE_BROADCAST_WRITES | SE_BROADCAST_WRITES);
3499416a2bd2SAlex Deucher 
350032fcdbf4SAlex Deucher 	WREG32(GB_ADDR_CONFIG, gb_addr_config);
350132fcdbf4SAlex Deucher 	WREG32(DMIF_ADDR_CONFIG, gb_addr_config);
350232fcdbf4SAlex Deucher 	WREG32(HDP_ADDR_CONFIG, gb_addr_config);
3503233d1ad5SAlex Deucher 	WREG32(DMA_TILING_CONFIG, gb_addr_config);
35049a21059dSChristian König 	WREG32(UVD_UDEC_ADDR_CONFIG, gb_addr_config);
35059a21059dSChristian König 	WREG32(UVD_UDEC_DB_ADDR_CONFIG, gb_addr_config);
35069a21059dSChristian König 	WREG32(UVD_UDEC_DBW_ADDR_CONFIG, gb_addr_config);
350732fcdbf4SAlex Deucher 
3508f7eb9730SAlex Deucher 	if ((rdev->config.evergreen.max_backends == 1) &&
3509f7eb9730SAlex Deucher 	    (rdev->flags & RADEON_IS_IGP)) {
3510f7eb9730SAlex Deucher 		if ((disabled_rb_mask & 3) == 1) {
3511f7eb9730SAlex Deucher 			/* RB0 disabled, RB1 enabled */
3512f7eb9730SAlex Deucher 			tmp = 0x11111111;
3513f7eb9730SAlex Deucher 		} else {
3514f7eb9730SAlex Deucher 			/* RB1 disabled, RB0 enabled */
3515f7eb9730SAlex Deucher 			tmp = 0x00000000;
3516f7eb9730SAlex Deucher 		}
3517f7eb9730SAlex Deucher 	} else {
3518416a2bd2SAlex Deucher 		tmp = gb_addr_config & NUM_PIPES_MASK;
3519416a2bd2SAlex Deucher 		tmp = r6xx_remap_render_backend(rdev, tmp, rdev->config.evergreen.max_backends,
3520416a2bd2SAlex Deucher 						EVERGREEN_MAX_BACKENDS, disabled_rb_mask);
3521f7eb9730SAlex Deucher 	}
35228159e509SDave Airlie 	rdev->config.evergreen.backend_map = tmp;
3523416a2bd2SAlex Deucher 	WREG32(GB_BACKEND_MAP, tmp);
352432fcdbf4SAlex Deucher 
352532fcdbf4SAlex Deucher 	WREG32(CGTS_SYS_TCC_DISABLE, 0);
352632fcdbf4SAlex Deucher 	WREG32(CGTS_TCC_DISABLE, 0);
352732fcdbf4SAlex Deucher 	WREG32(CGTS_USER_SYS_TCC_DISABLE, 0);
352832fcdbf4SAlex Deucher 	WREG32(CGTS_USER_TCC_DISABLE, 0);
352932fcdbf4SAlex Deucher 
353032fcdbf4SAlex Deucher 	/* set HW defaults for 3D engine */
353132fcdbf4SAlex Deucher 	WREG32(CP_QUEUE_THRESHOLDS, (ROQ_IB1_START(0x16) |
353232fcdbf4SAlex Deucher 				     ROQ_IB2_START(0x2b)));
353332fcdbf4SAlex Deucher 
353432fcdbf4SAlex Deucher 	WREG32(CP_MEQ_THRESHOLDS, STQ_SPLIT(0x30));
353532fcdbf4SAlex Deucher 
353632fcdbf4SAlex Deucher 	WREG32(TA_CNTL_AUX, (DISABLE_CUBE_ANISO |
353732fcdbf4SAlex Deucher 			     SYNC_GRADIENT |
353832fcdbf4SAlex Deucher 			     SYNC_WALKER |
353932fcdbf4SAlex Deucher 			     SYNC_ALIGNER));
354032fcdbf4SAlex Deucher 
354132fcdbf4SAlex Deucher 	sx_debug_1 = RREG32(SX_DEBUG_1);
354232fcdbf4SAlex Deucher 	sx_debug_1 |= ENABLE_NEW_SMX_ADDRESS;
354332fcdbf4SAlex Deucher 	WREG32(SX_DEBUG_1, sx_debug_1);
354432fcdbf4SAlex Deucher 
354532fcdbf4SAlex Deucher 
354632fcdbf4SAlex Deucher 	smx_dc_ctl0 = RREG32(SMX_DC_CTL0);
354732fcdbf4SAlex Deucher 	smx_dc_ctl0 &= ~NUMBER_OF_SETS(0x1ff);
354832fcdbf4SAlex Deucher 	smx_dc_ctl0 |= NUMBER_OF_SETS(rdev->config.evergreen.sx_num_of_sets);
354932fcdbf4SAlex Deucher 	WREG32(SMX_DC_CTL0, smx_dc_ctl0);
355032fcdbf4SAlex Deucher 
3551b866d133SAlex Deucher 	if (rdev->family <= CHIP_SUMO2)
3552b866d133SAlex Deucher 		WREG32(SMX_SAR_CTL0, 0x00010000);
3553b866d133SAlex Deucher 
355432fcdbf4SAlex Deucher 	WREG32(SX_EXPORT_BUFFER_SIZES, (COLOR_BUFFER_SIZE((rdev->config.evergreen.sx_max_export_size / 4) - 1) |
355532fcdbf4SAlex Deucher 					POSITION_BUFFER_SIZE((rdev->config.evergreen.sx_max_export_pos_size / 4) - 1) |
355632fcdbf4SAlex Deucher 					SMX_BUFFER_SIZE((rdev->config.evergreen.sx_max_export_smx_size / 4) - 1)));
355732fcdbf4SAlex Deucher 
355832fcdbf4SAlex Deucher 	WREG32(PA_SC_FIFO_SIZE, (SC_PRIM_FIFO_SIZE(rdev->config.evergreen.sc_prim_fifo_size) |
355932fcdbf4SAlex Deucher 				 SC_HIZ_TILE_FIFO_SIZE(rdev->config.evergreen.sc_hiz_tile_fifo_size) |
356032fcdbf4SAlex Deucher 				 SC_EARLYZ_TILE_FIFO_SIZE(rdev->config.evergreen.sc_earlyz_tile_fifo_size)));
356132fcdbf4SAlex Deucher 
356232fcdbf4SAlex Deucher 	WREG32(VGT_NUM_INSTANCES, 1);
356332fcdbf4SAlex Deucher 	WREG32(SPI_CONFIG_CNTL, 0);
356432fcdbf4SAlex Deucher 	WREG32(SPI_CONFIG_CNTL_1, VTX_DONE_DELAY(4));
356532fcdbf4SAlex Deucher 	WREG32(CP_PERFMON_CNTL, 0);
356632fcdbf4SAlex Deucher 
356732fcdbf4SAlex Deucher 	WREG32(SQ_MS_FIFO_SIZES, (CACHE_FIFO_SIZE(16 * rdev->config.evergreen.sq_num_cf_insts) |
356832fcdbf4SAlex Deucher 				  FETCH_FIFO_HIWATER(0x4) |
356932fcdbf4SAlex Deucher 				  DONE_FIFO_HIWATER(0xe0) |
357032fcdbf4SAlex Deucher 				  ALU_UPDATE_FIFO_HIWATER(0x8)));
357132fcdbf4SAlex Deucher 
357232fcdbf4SAlex Deucher 	sq_config = RREG32(SQ_CONFIG);
357332fcdbf4SAlex Deucher 	sq_config &= ~(PS_PRIO(3) |
357432fcdbf4SAlex Deucher 		       VS_PRIO(3) |
357532fcdbf4SAlex Deucher 		       GS_PRIO(3) |
357632fcdbf4SAlex Deucher 		       ES_PRIO(3));
357732fcdbf4SAlex Deucher 	sq_config |= (VC_ENABLE |
357832fcdbf4SAlex Deucher 		      EXPORT_SRC_C |
357932fcdbf4SAlex Deucher 		      PS_PRIO(0) |
358032fcdbf4SAlex Deucher 		      VS_PRIO(1) |
358132fcdbf4SAlex Deucher 		      GS_PRIO(2) |
358232fcdbf4SAlex Deucher 		      ES_PRIO(3));
358332fcdbf4SAlex Deucher 
3584d5e455e4SAlex Deucher 	switch (rdev->family) {
3585d5e455e4SAlex Deucher 	case CHIP_CEDAR:
3586d5e455e4SAlex Deucher 	case CHIP_PALM:
3587d5c5a72fSAlex Deucher 	case CHIP_SUMO:
3588d5c5a72fSAlex Deucher 	case CHIP_SUMO2:
3589adb68fa2SAlex Deucher 	case CHIP_CAICOS:
359032fcdbf4SAlex Deucher 		/* no vertex cache */
359132fcdbf4SAlex Deucher 		sq_config &= ~VC_ENABLE;
3592d5e455e4SAlex Deucher 		break;
3593d5e455e4SAlex Deucher 	default:
3594d5e455e4SAlex Deucher 		break;
3595d5e455e4SAlex Deucher 	}
359632fcdbf4SAlex Deucher 
359732fcdbf4SAlex Deucher 	sq_lds_resource_mgmt = RREG32(SQ_LDS_RESOURCE_MGMT);
359832fcdbf4SAlex Deucher 
359932fcdbf4SAlex Deucher 	sq_gpr_resource_mgmt_1 = NUM_PS_GPRS((rdev->config.evergreen.max_gprs - (4 * 2))* 12 / 32);
360032fcdbf4SAlex Deucher 	sq_gpr_resource_mgmt_1 |= NUM_VS_GPRS((rdev->config.evergreen.max_gprs - (4 * 2)) * 6 / 32);
360132fcdbf4SAlex Deucher 	sq_gpr_resource_mgmt_1 |= NUM_CLAUSE_TEMP_GPRS(4);
360232fcdbf4SAlex Deucher 	sq_gpr_resource_mgmt_2 = NUM_GS_GPRS((rdev->config.evergreen.max_gprs - (4 * 2)) * 4 / 32);
360332fcdbf4SAlex Deucher 	sq_gpr_resource_mgmt_2 |= NUM_ES_GPRS((rdev->config.evergreen.max_gprs - (4 * 2)) * 4 / 32);
360432fcdbf4SAlex Deucher 	sq_gpr_resource_mgmt_3 = NUM_HS_GPRS((rdev->config.evergreen.max_gprs - (4 * 2)) * 3 / 32);
360532fcdbf4SAlex Deucher 	sq_gpr_resource_mgmt_3 |= NUM_LS_GPRS((rdev->config.evergreen.max_gprs - (4 * 2)) * 3 / 32);
360632fcdbf4SAlex Deucher 
3607d5e455e4SAlex Deucher 	switch (rdev->family) {
3608d5e455e4SAlex Deucher 	case CHIP_CEDAR:
3609d5e455e4SAlex Deucher 	case CHIP_PALM:
3610d5c5a72fSAlex Deucher 	case CHIP_SUMO:
3611d5c5a72fSAlex Deucher 	case CHIP_SUMO2:
361232fcdbf4SAlex Deucher 		ps_thread_count = 96;
3613d5e455e4SAlex Deucher 		break;
3614d5e455e4SAlex Deucher 	default:
361532fcdbf4SAlex Deucher 		ps_thread_count = 128;
3616d5e455e4SAlex Deucher 		break;
3617d5e455e4SAlex Deucher 	}
361832fcdbf4SAlex Deucher 
361932fcdbf4SAlex Deucher 	sq_thread_resource_mgmt = NUM_PS_THREADS(ps_thread_count);
3620f96b35cdSAlex Deucher 	sq_thread_resource_mgmt |= NUM_VS_THREADS((((rdev->config.evergreen.max_threads - ps_thread_count) / 6) / 8) * 8);
3621f96b35cdSAlex Deucher 	sq_thread_resource_mgmt |= NUM_GS_THREADS((((rdev->config.evergreen.max_threads - ps_thread_count) / 6) / 8) * 8);
3622f96b35cdSAlex Deucher 	sq_thread_resource_mgmt |= NUM_ES_THREADS((((rdev->config.evergreen.max_threads - ps_thread_count) / 6) / 8) * 8);
3623f96b35cdSAlex Deucher 	sq_thread_resource_mgmt_2 = NUM_HS_THREADS((((rdev->config.evergreen.max_threads - ps_thread_count) / 6) / 8) * 8);
3624f96b35cdSAlex Deucher 	sq_thread_resource_mgmt_2 |= NUM_LS_THREADS((((rdev->config.evergreen.max_threads - ps_thread_count) / 6) / 8) * 8);
362532fcdbf4SAlex Deucher 
362632fcdbf4SAlex Deucher 	sq_stack_resource_mgmt_1 = NUM_PS_STACK_ENTRIES((rdev->config.evergreen.max_stack_entries * 1) / 6);
362732fcdbf4SAlex Deucher 	sq_stack_resource_mgmt_1 |= NUM_VS_STACK_ENTRIES((rdev->config.evergreen.max_stack_entries * 1) / 6);
362832fcdbf4SAlex Deucher 	sq_stack_resource_mgmt_2 = NUM_GS_STACK_ENTRIES((rdev->config.evergreen.max_stack_entries * 1) / 6);
362932fcdbf4SAlex Deucher 	sq_stack_resource_mgmt_2 |= NUM_ES_STACK_ENTRIES((rdev->config.evergreen.max_stack_entries * 1) / 6);
363032fcdbf4SAlex Deucher 	sq_stack_resource_mgmt_3 = NUM_HS_STACK_ENTRIES((rdev->config.evergreen.max_stack_entries * 1) / 6);
363132fcdbf4SAlex Deucher 	sq_stack_resource_mgmt_3 |= NUM_LS_STACK_ENTRIES((rdev->config.evergreen.max_stack_entries * 1) / 6);
363232fcdbf4SAlex Deucher 
363332fcdbf4SAlex Deucher 	WREG32(SQ_CONFIG, sq_config);
363432fcdbf4SAlex Deucher 	WREG32(SQ_GPR_RESOURCE_MGMT_1, sq_gpr_resource_mgmt_1);
363532fcdbf4SAlex Deucher 	WREG32(SQ_GPR_RESOURCE_MGMT_2, sq_gpr_resource_mgmt_2);
363632fcdbf4SAlex Deucher 	WREG32(SQ_GPR_RESOURCE_MGMT_3, sq_gpr_resource_mgmt_3);
363732fcdbf4SAlex Deucher 	WREG32(SQ_THREAD_RESOURCE_MGMT, sq_thread_resource_mgmt);
363832fcdbf4SAlex Deucher 	WREG32(SQ_THREAD_RESOURCE_MGMT_2, sq_thread_resource_mgmt_2);
363932fcdbf4SAlex Deucher 	WREG32(SQ_STACK_RESOURCE_MGMT_1, sq_stack_resource_mgmt_1);
364032fcdbf4SAlex Deucher 	WREG32(SQ_STACK_RESOURCE_MGMT_2, sq_stack_resource_mgmt_2);
364132fcdbf4SAlex Deucher 	WREG32(SQ_STACK_RESOURCE_MGMT_3, sq_stack_resource_mgmt_3);
364232fcdbf4SAlex Deucher 	WREG32(SQ_DYN_GPR_CNTL_PS_FLUSH_REQ, 0);
364332fcdbf4SAlex Deucher 	WREG32(SQ_LDS_RESOURCE_MGMT, sq_lds_resource_mgmt);
364432fcdbf4SAlex Deucher 
364532fcdbf4SAlex Deucher 	WREG32(PA_SC_FORCE_EOV_MAX_CNTS, (FORCE_EOV_MAX_CLK_CNT(4095) |
364632fcdbf4SAlex Deucher 					  FORCE_EOV_MAX_REZ_CNT(255)));
364732fcdbf4SAlex Deucher 
3648d5e455e4SAlex Deucher 	switch (rdev->family) {
3649d5e455e4SAlex Deucher 	case CHIP_CEDAR:
3650d5e455e4SAlex Deucher 	case CHIP_PALM:
3651d5c5a72fSAlex Deucher 	case CHIP_SUMO:
3652d5c5a72fSAlex Deucher 	case CHIP_SUMO2:
3653adb68fa2SAlex Deucher 	case CHIP_CAICOS:
365432fcdbf4SAlex Deucher 		vgt_cache_invalidation = CACHE_INVALIDATION(TC_ONLY);
3655d5e455e4SAlex Deucher 		break;
3656d5e455e4SAlex Deucher 	default:
365732fcdbf4SAlex Deucher 		vgt_cache_invalidation = CACHE_INVALIDATION(VC_AND_TC);
3658d5e455e4SAlex Deucher 		break;
3659d5e455e4SAlex Deucher 	}
366032fcdbf4SAlex Deucher 	vgt_cache_invalidation |= AUTO_INVLD_EN(ES_AND_GS_AUTO);
366132fcdbf4SAlex Deucher 	WREG32(VGT_CACHE_INVALIDATION, vgt_cache_invalidation);
366232fcdbf4SAlex Deucher 
366332fcdbf4SAlex Deucher 	WREG32(VGT_GS_VERTEX_REUSE, 16);
366412920591SAlex Deucher 	WREG32(PA_SU_LINE_STIPPLE_VALUE, 0);
366532fcdbf4SAlex Deucher 	WREG32(PA_SC_LINE_STIPPLE_STATE, 0);
366632fcdbf4SAlex Deucher 
366760a4a3e0SAlex Deucher 	WREG32(VGT_VERTEX_REUSE_BLOCK_CNTL, 14);
366860a4a3e0SAlex Deucher 	WREG32(VGT_OUT_DEALLOC_CNTL, 16);
366960a4a3e0SAlex Deucher 
367032fcdbf4SAlex Deucher 	WREG32(CB_PERF_CTR0_SEL_0, 0);
367132fcdbf4SAlex Deucher 	WREG32(CB_PERF_CTR0_SEL_1, 0);
367232fcdbf4SAlex Deucher 	WREG32(CB_PERF_CTR1_SEL_0, 0);
367332fcdbf4SAlex Deucher 	WREG32(CB_PERF_CTR1_SEL_1, 0);
367432fcdbf4SAlex Deucher 	WREG32(CB_PERF_CTR2_SEL_0, 0);
367532fcdbf4SAlex Deucher 	WREG32(CB_PERF_CTR2_SEL_1, 0);
367632fcdbf4SAlex Deucher 	WREG32(CB_PERF_CTR3_SEL_0, 0);
367732fcdbf4SAlex Deucher 	WREG32(CB_PERF_CTR3_SEL_1, 0);
367832fcdbf4SAlex Deucher 
367960a4a3e0SAlex Deucher 	/* clear render buffer base addresses */
368060a4a3e0SAlex Deucher 	WREG32(CB_COLOR0_BASE, 0);
368160a4a3e0SAlex Deucher 	WREG32(CB_COLOR1_BASE, 0);
368260a4a3e0SAlex Deucher 	WREG32(CB_COLOR2_BASE, 0);
368360a4a3e0SAlex Deucher 	WREG32(CB_COLOR3_BASE, 0);
368460a4a3e0SAlex Deucher 	WREG32(CB_COLOR4_BASE, 0);
368560a4a3e0SAlex Deucher 	WREG32(CB_COLOR5_BASE, 0);
368660a4a3e0SAlex Deucher 	WREG32(CB_COLOR6_BASE, 0);
368760a4a3e0SAlex Deucher 	WREG32(CB_COLOR7_BASE, 0);
368860a4a3e0SAlex Deucher 	WREG32(CB_COLOR8_BASE, 0);
368960a4a3e0SAlex Deucher 	WREG32(CB_COLOR9_BASE, 0);
369060a4a3e0SAlex Deucher 	WREG32(CB_COLOR10_BASE, 0);
369160a4a3e0SAlex Deucher 	WREG32(CB_COLOR11_BASE, 0);
369260a4a3e0SAlex Deucher 
369360a4a3e0SAlex Deucher 	/* set the shader const cache sizes to 0 */
369460a4a3e0SAlex Deucher 	for (i = SQ_ALU_CONST_BUFFER_SIZE_PS_0; i < 0x28200; i += 4)
369560a4a3e0SAlex Deucher 		WREG32(i, 0);
369660a4a3e0SAlex Deucher 	for (i = SQ_ALU_CONST_BUFFER_SIZE_HS_0; i < 0x29000; i += 4)
369760a4a3e0SAlex Deucher 		WREG32(i, 0);
369860a4a3e0SAlex Deucher 
3699f25a5c63SAlex Deucher 	tmp = RREG32(HDP_MISC_CNTL);
3700f25a5c63SAlex Deucher 	tmp |= HDP_FLUSH_INVALIDATE_CACHE;
3701f25a5c63SAlex Deucher 	WREG32(HDP_MISC_CNTL, tmp);
3702f25a5c63SAlex Deucher 
370332fcdbf4SAlex Deucher 	hdp_host_path_cntl = RREG32(HDP_HOST_PATH_CNTL);
370432fcdbf4SAlex Deucher 	WREG32(HDP_HOST_PATH_CNTL, hdp_host_path_cntl);
370532fcdbf4SAlex Deucher 
370632fcdbf4SAlex Deucher 	WREG32(PA_CL_ENHANCE, CLIP_VTX_REORDER_ENA | NUM_CLIP_SEQ(3));
370732fcdbf4SAlex Deucher 
370832fcdbf4SAlex Deucher 	udelay(50);
370932fcdbf4SAlex Deucher 
3710bcc1c2a1SAlex Deucher }
3711bcc1c2a1SAlex Deucher 
evergreen_mc_init(struct radeon_device * rdev)3712bcc1c2a1SAlex Deucher int evergreen_mc_init(struct radeon_device *rdev)
3713bcc1c2a1SAlex Deucher {
3714bcc1c2a1SAlex Deucher 	u32 tmp;
3715bcc1c2a1SAlex Deucher 	int chansize, numchan;
3716bcc1c2a1SAlex Deucher 
3717bcc1c2a1SAlex Deucher 	/* Get VRAM informations */
3718bcc1c2a1SAlex Deucher 	rdev->mc.vram_is_ddr = true;
371905b3ef69SAlex Deucher 	if ((rdev->family == CHIP_PALM) ||
372005b3ef69SAlex Deucher 	    (rdev->family == CHIP_SUMO) ||
372105b3ef69SAlex Deucher 	    (rdev->family == CHIP_SUMO2))
37228208441bSAlex Deucher 		tmp = RREG32(FUS_MC_ARB_RAMCFG);
37238208441bSAlex Deucher 	else
3724bcc1c2a1SAlex Deucher 		tmp = RREG32(MC_ARB_RAMCFG);
3725bcc1c2a1SAlex Deucher 	if (tmp & CHANSIZE_OVERRIDE) {
3726bcc1c2a1SAlex Deucher 		chansize = 16;
3727bcc1c2a1SAlex Deucher 	} else if (tmp & CHANSIZE_MASK) {
3728bcc1c2a1SAlex Deucher 		chansize = 64;
3729bcc1c2a1SAlex Deucher 	} else {
3730bcc1c2a1SAlex Deucher 		chansize = 32;
3731bcc1c2a1SAlex Deucher 	}
3732bcc1c2a1SAlex Deucher 	tmp = RREG32(MC_SHARED_CHMAP);
3733bcc1c2a1SAlex Deucher 	switch ((tmp & NOOFCHAN_MASK) >> NOOFCHAN_SHIFT) {
3734bcc1c2a1SAlex Deucher 	case 0:
3735bcc1c2a1SAlex Deucher 	default:
3736bcc1c2a1SAlex Deucher 		numchan = 1;
3737bcc1c2a1SAlex Deucher 		break;
3738bcc1c2a1SAlex Deucher 	case 1:
3739bcc1c2a1SAlex Deucher 		numchan = 2;
3740bcc1c2a1SAlex Deucher 		break;
3741bcc1c2a1SAlex Deucher 	case 2:
3742bcc1c2a1SAlex Deucher 		numchan = 4;
3743bcc1c2a1SAlex Deucher 		break;
3744bcc1c2a1SAlex Deucher 	case 3:
3745bcc1c2a1SAlex Deucher 		numchan = 8;
3746bcc1c2a1SAlex Deucher 		break;
3747bcc1c2a1SAlex Deucher 	}
3748bcc1c2a1SAlex Deucher 	rdev->mc.vram_width = numchan * chansize;
3749bcc1c2a1SAlex Deucher 	/* Could aper size report 0 ? */
375001d73a69SJordan Crouse 	rdev->mc.aper_base = pci_resource_start(rdev->pdev, 0);
375101d73a69SJordan Crouse 	rdev->mc.aper_size = pci_resource_len(rdev->pdev, 0);
3752bcc1c2a1SAlex Deucher 	/* Setup GPU memory space */
375305b3ef69SAlex Deucher 	if ((rdev->family == CHIP_PALM) ||
375405b3ef69SAlex Deucher 	    (rdev->family == CHIP_SUMO) ||
375505b3ef69SAlex Deucher 	    (rdev->family == CHIP_SUMO2)) {
37566eb18f8bSAlex Deucher 		/* size in bytes on fusion */
37576eb18f8bSAlex Deucher 		rdev->mc.mc_vram_size = RREG32(CONFIG_MEMSIZE);
37586eb18f8bSAlex Deucher 		rdev->mc.real_vram_size = RREG32(CONFIG_MEMSIZE);
37596eb18f8bSAlex Deucher 	} else {
376005b3ef69SAlex Deucher 		/* size in MB on evergreen/cayman/tn */
3761fc986034SNiels Ole Salscheider 		rdev->mc.mc_vram_size = RREG32(CONFIG_MEMSIZE) * 1024ULL * 1024ULL;
3762fc986034SNiels Ole Salscheider 		rdev->mc.real_vram_size = RREG32(CONFIG_MEMSIZE) * 1024ULL * 1024ULL;
37636eb18f8bSAlex Deucher 	}
376451e5fcd3SJerome Glisse 	rdev->mc.visible_vram_size = rdev->mc.aper_size;
37650ef0c1f7SAlex Deucher 	r700_vram_gtt_location(rdev, &rdev->mc);
3766f47299c5SAlex Deucher 	radeon_update_bandwidth_info(rdev);
3767f47299c5SAlex Deucher 
3768bcc1c2a1SAlex Deucher 	return 0;
3769bcc1c2a1SAlex Deucher }
3770d594e46aSJerome Glisse 
evergreen_print_gpu_status_regs(struct radeon_device * rdev)3771187e3593SAlex Deucher void evergreen_print_gpu_status_regs(struct radeon_device *rdev)
3772747943eaSAlex Deucher {
3773747943eaSAlex Deucher 	dev_info(rdev->dev, "  GRBM_STATUS               = 0x%08X\n",
3774747943eaSAlex Deucher 		RREG32(GRBM_STATUS));
3775747943eaSAlex Deucher 	dev_info(rdev->dev, "  GRBM_STATUS_SE0           = 0x%08X\n",
3776747943eaSAlex Deucher 		RREG32(GRBM_STATUS_SE0));
3777747943eaSAlex Deucher 	dev_info(rdev->dev, "  GRBM_STATUS_SE1           = 0x%08X\n",
3778747943eaSAlex Deucher 		RREG32(GRBM_STATUS_SE1));
3779747943eaSAlex Deucher 	dev_info(rdev->dev, "  SRBM_STATUS               = 0x%08X\n",
3780747943eaSAlex Deucher 		RREG32(SRBM_STATUS));
3781a65a4369SAlex Deucher 	dev_info(rdev->dev, "  SRBM_STATUS2              = 0x%08X\n",
3782a65a4369SAlex Deucher 		RREG32(SRBM_STATUS2));
3783440a7cd8SJerome Glisse 	dev_info(rdev->dev, "  R_008674_CP_STALLED_STAT1 = 0x%08X\n",
3784440a7cd8SJerome Glisse 		RREG32(CP_STALLED_STAT1));
3785440a7cd8SJerome Glisse 	dev_info(rdev->dev, "  R_008678_CP_STALLED_STAT2 = 0x%08X\n",
3786440a7cd8SJerome Glisse 		RREG32(CP_STALLED_STAT2));
3787440a7cd8SJerome Glisse 	dev_info(rdev->dev, "  R_00867C_CP_BUSY_STAT     = 0x%08X\n",
3788440a7cd8SJerome Glisse 		RREG32(CP_BUSY_STAT));
3789440a7cd8SJerome Glisse 	dev_info(rdev->dev, "  R_008680_CP_STAT          = 0x%08X\n",
3790440a7cd8SJerome Glisse 		RREG32(CP_STAT));
37910ecebb9eSAlex Deucher 	dev_info(rdev->dev, "  R_00D034_DMA_STATUS_REG   = 0x%08X\n",
37920ecebb9eSAlex Deucher 		RREG32(DMA_STATUS_REG));
3793168757eaSAlex Deucher 	if (rdev->family >= CHIP_CAYMAN) {
3794168757eaSAlex Deucher 		dev_info(rdev->dev, "  R_00D834_DMA_STATUS_REG   = 0x%08X\n",
3795168757eaSAlex Deucher 			 RREG32(DMA_STATUS_REG + 0x800));
3796168757eaSAlex Deucher 	}
37970ecebb9eSAlex Deucher }
37980ecebb9eSAlex Deucher 
evergreen_is_display_hung(struct radeon_device * rdev)3799168757eaSAlex Deucher bool evergreen_is_display_hung(struct radeon_device *rdev)
3800a65a4369SAlex Deucher {
3801a65a4369SAlex Deucher 	u32 crtc_hung = 0;
3802a65a4369SAlex Deucher 	u32 crtc_status[6];
3803a65a4369SAlex Deucher 	u32 i, j, tmp;
3804a65a4369SAlex Deucher 
3805a65a4369SAlex Deucher 	for (i = 0; i < rdev->num_crtc; i++) {
3806a65a4369SAlex Deucher 		if (RREG32(EVERGREEN_CRTC_CONTROL + crtc_offsets[i]) & EVERGREEN_CRTC_MASTER_EN) {
3807a65a4369SAlex Deucher 			crtc_status[i] = RREG32(EVERGREEN_CRTC_STATUS_HV_COUNT + crtc_offsets[i]);
3808a65a4369SAlex Deucher 			crtc_hung |= (1 << i);
3809a65a4369SAlex Deucher 		}
3810a65a4369SAlex Deucher 	}
3811a65a4369SAlex Deucher 
3812a65a4369SAlex Deucher 	for (j = 0; j < 10; j++) {
3813a65a4369SAlex Deucher 		for (i = 0; i < rdev->num_crtc; i++) {
3814a65a4369SAlex Deucher 			if (crtc_hung & (1 << i)) {
3815a65a4369SAlex Deucher 				tmp = RREG32(EVERGREEN_CRTC_STATUS_HV_COUNT + crtc_offsets[i]);
3816a65a4369SAlex Deucher 				if (tmp != crtc_status[i])
3817a65a4369SAlex Deucher 					crtc_hung &= ~(1 << i);
3818a65a4369SAlex Deucher 			}
3819a65a4369SAlex Deucher 		}
3820a65a4369SAlex Deucher 		if (crtc_hung == 0)
3821a65a4369SAlex Deucher 			return false;
3822a65a4369SAlex Deucher 		udelay(100);
3823a65a4369SAlex Deucher 	}
3824a65a4369SAlex Deucher 
3825a65a4369SAlex Deucher 	return true;
3826a65a4369SAlex Deucher }
3827a65a4369SAlex Deucher 
evergreen_gpu_check_soft_reset(struct radeon_device * rdev)38282483b4eaSChristian König u32 evergreen_gpu_check_soft_reset(struct radeon_device *rdev)
3829a65a4369SAlex Deucher {
3830a65a4369SAlex Deucher 	u32 reset_mask = 0;
3831a65a4369SAlex Deucher 	u32 tmp;
3832a65a4369SAlex Deucher 
3833a65a4369SAlex Deucher 	/* GRBM_STATUS */
3834a65a4369SAlex Deucher 	tmp = RREG32(GRBM_STATUS);
3835a65a4369SAlex Deucher 	if (tmp & (PA_BUSY | SC_BUSY |
3836a65a4369SAlex Deucher 		   SH_BUSY | SX_BUSY |
3837a65a4369SAlex Deucher 		   TA_BUSY | VGT_BUSY |
3838a65a4369SAlex Deucher 		   DB_BUSY | CB_BUSY |
3839a65a4369SAlex Deucher 		   SPI_BUSY | VGT_BUSY_NO_DMA))
3840a65a4369SAlex Deucher 		reset_mask |= RADEON_RESET_GFX;
3841a65a4369SAlex Deucher 
3842a65a4369SAlex Deucher 	if (tmp & (CF_RQ_PENDING | PF_RQ_PENDING |
3843a65a4369SAlex Deucher 		   CP_BUSY | CP_COHERENCY_BUSY))
3844a65a4369SAlex Deucher 		reset_mask |= RADEON_RESET_CP;
3845a65a4369SAlex Deucher 
3846a65a4369SAlex Deucher 	if (tmp & GRBM_EE_BUSY)
3847a65a4369SAlex Deucher 		reset_mask |= RADEON_RESET_GRBM | RADEON_RESET_GFX | RADEON_RESET_CP;
3848a65a4369SAlex Deucher 
3849a65a4369SAlex Deucher 	/* DMA_STATUS_REG */
3850a65a4369SAlex Deucher 	tmp = RREG32(DMA_STATUS_REG);
3851a65a4369SAlex Deucher 	if (!(tmp & DMA_IDLE))
3852a65a4369SAlex Deucher 		reset_mask |= RADEON_RESET_DMA;
3853a65a4369SAlex Deucher 
3854a65a4369SAlex Deucher 	/* SRBM_STATUS2 */
3855a65a4369SAlex Deucher 	tmp = RREG32(SRBM_STATUS2);
3856a65a4369SAlex Deucher 	if (tmp & DMA_BUSY)
3857a65a4369SAlex Deucher 		reset_mask |= RADEON_RESET_DMA;
3858a65a4369SAlex Deucher 
3859a65a4369SAlex Deucher 	/* SRBM_STATUS */
3860a65a4369SAlex Deucher 	tmp = RREG32(SRBM_STATUS);
3861a65a4369SAlex Deucher 	if (tmp & (RLC_RQ_PENDING | RLC_BUSY))
3862a65a4369SAlex Deucher 		reset_mask |= RADEON_RESET_RLC;
3863a65a4369SAlex Deucher 
3864a65a4369SAlex Deucher 	if (tmp & IH_BUSY)
3865a65a4369SAlex Deucher 		reset_mask |= RADEON_RESET_IH;
3866a65a4369SAlex Deucher 
3867a65a4369SAlex Deucher 	if (tmp & SEM_BUSY)
3868a65a4369SAlex Deucher 		reset_mask |= RADEON_RESET_SEM;
3869a65a4369SAlex Deucher 
3870a65a4369SAlex Deucher 	if (tmp & GRBM_RQ_PENDING)
3871a65a4369SAlex Deucher 		reset_mask |= RADEON_RESET_GRBM;
3872a65a4369SAlex Deucher 
3873a65a4369SAlex Deucher 	if (tmp & VMC_BUSY)
3874a65a4369SAlex Deucher 		reset_mask |= RADEON_RESET_VMC;
3875a65a4369SAlex Deucher 
3876a65a4369SAlex Deucher 	if (tmp & (MCB_BUSY | MCB_NON_DISPLAY_BUSY |
3877a65a4369SAlex Deucher 		   MCC_BUSY | MCD_BUSY))
3878a65a4369SAlex Deucher 		reset_mask |= RADEON_RESET_MC;
3879a65a4369SAlex Deucher 
3880a65a4369SAlex Deucher 	if (evergreen_is_display_hung(rdev))
3881a65a4369SAlex Deucher 		reset_mask |= RADEON_RESET_DISPLAY;
3882a65a4369SAlex Deucher 
3883a65a4369SAlex Deucher 	/* VM_L2_STATUS */
3884a65a4369SAlex Deucher 	tmp = RREG32(VM_L2_STATUS);
3885a65a4369SAlex Deucher 	if (tmp & L2_BUSY)
3886a65a4369SAlex Deucher 		reset_mask |= RADEON_RESET_VMC;
3887a65a4369SAlex Deucher 
3888d808fc88SAlex Deucher 	/* Skip MC reset as it's mostly likely not hung, just busy */
3889d808fc88SAlex Deucher 	if (reset_mask & RADEON_RESET_MC) {
3890d808fc88SAlex Deucher 		DRM_DEBUG("MC busy: 0x%08X, clearing.\n", reset_mask);
3891d808fc88SAlex Deucher 		reset_mask &= ~RADEON_RESET_MC;
3892d808fc88SAlex Deucher 	}
3893d808fc88SAlex Deucher 
3894a65a4369SAlex Deucher 	return reset_mask;
3895a65a4369SAlex Deucher }
3896a65a4369SAlex Deucher 
evergreen_gpu_soft_reset(struct radeon_device * rdev,u32 reset_mask)3897a65a4369SAlex Deucher static void evergreen_gpu_soft_reset(struct radeon_device *rdev, u32 reset_mask)
38980ecebb9eSAlex Deucher {
38990ecebb9eSAlex Deucher 	struct evergreen_mc_save save;
3900b7630473SAlex Deucher 	u32 grbm_soft_reset = 0, srbm_soft_reset = 0;
3901b7630473SAlex Deucher 	u32 tmp;
390219fc42edSAlex Deucher 
39030ecebb9eSAlex Deucher 	if (reset_mask == 0)
3904a65a4369SAlex Deucher 		return;
39050ecebb9eSAlex Deucher 
39060ecebb9eSAlex Deucher 	dev_info(rdev->dev, "GPU softreset: 0x%08X\n", reset_mask);
39070ecebb9eSAlex Deucher 
3908b7630473SAlex Deucher 	evergreen_print_gpu_status_regs(rdev);
3909b7630473SAlex Deucher 
3910b7630473SAlex Deucher 	/* Disable CP parsing/prefetching */
3911b7630473SAlex Deucher 	WREG32(CP_ME_CNTL, CP_ME_HALT | CP_PFP_HALT);
3912b7630473SAlex Deucher 
3913b7630473SAlex Deucher 	if (reset_mask & RADEON_RESET_DMA) {
3914b7630473SAlex Deucher 		/* Disable DMA */
3915b7630473SAlex Deucher 		tmp = RREG32(DMA_RB_CNTL);
3916b7630473SAlex Deucher 		tmp &= ~DMA_RB_ENABLE;
3917b7630473SAlex Deucher 		WREG32(DMA_RB_CNTL, tmp);
3918b7630473SAlex Deucher 	}
3919b7630473SAlex Deucher 
3920b21b6e7aSAlex Deucher 	udelay(50);
3921b21b6e7aSAlex Deucher 
3922b21b6e7aSAlex Deucher 	evergreen_mc_stop(rdev, &save);
3923b21b6e7aSAlex Deucher 	if (evergreen_mc_wait_for_idle(rdev)) {
3924b21b6e7aSAlex Deucher 		dev_warn(rdev->dev, "Wait for MC idle timedout !\n");
3925b21b6e7aSAlex Deucher 	}
3926b21b6e7aSAlex Deucher 
3927b7630473SAlex Deucher 	if (reset_mask & (RADEON_RESET_GFX | RADEON_RESET_COMPUTE)) {
3928b7630473SAlex Deucher 		grbm_soft_reset |= SOFT_RESET_DB |
3929b7630473SAlex Deucher 			SOFT_RESET_CB |
3930b7630473SAlex Deucher 			SOFT_RESET_PA |
3931b7630473SAlex Deucher 			SOFT_RESET_SC |
3932b7630473SAlex Deucher 			SOFT_RESET_SPI |
3933b7630473SAlex Deucher 			SOFT_RESET_SX |
3934b7630473SAlex Deucher 			SOFT_RESET_SH |
3935b7630473SAlex Deucher 			SOFT_RESET_TC |
3936b7630473SAlex Deucher 			SOFT_RESET_TA |
3937b7630473SAlex Deucher 			SOFT_RESET_VC |
3938b7630473SAlex Deucher 			SOFT_RESET_VGT;
3939b7630473SAlex Deucher 	}
3940b7630473SAlex Deucher 
3941b7630473SAlex Deucher 	if (reset_mask & RADEON_RESET_CP) {
3942b7630473SAlex Deucher 		grbm_soft_reset |= SOFT_RESET_CP |
3943b7630473SAlex Deucher 			SOFT_RESET_VGT;
3944b7630473SAlex Deucher 
3945b7630473SAlex Deucher 		srbm_soft_reset |= SOFT_RESET_GRBM;
3946b7630473SAlex Deucher 	}
39470ecebb9eSAlex Deucher 
39480ecebb9eSAlex Deucher 	if (reset_mask & RADEON_RESET_DMA)
3949b7630473SAlex Deucher 		srbm_soft_reset |= SOFT_RESET_DMA;
3950b7630473SAlex Deucher 
3951a65a4369SAlex Deucher 	if (reset_mask & RADEON_RESET_DISPLAY)
3952a65a4369SAlex Deucher 		srbm_soft_reset |= SOFT_RESET_DC;
3953a65a4369SAlex Deucher 
3954a65a4369SAlex Deucher 	if (reset_mask & RADEON_RESET_RLC)
3955a65a4369SAlex Deucher 		srbm_soft_reset |= SOFT_RESET_RLC;
3956a65a4369SAlex Deucher 
3957a65a4369SAlex Deucher 	if (reset_mask & RADEON_RESET_SEM)
3958a65a4369SAlex Deucher 		srbm_soft_reset |= SOFT_RESET_SEM;
3959a65a4369SAlex Deucher 
3960a65a4369SAlex Deucher 	if (reset_mask & RADEON_RESET_IH)
3961a65a4369SAlex Deucher 		srbm_soft_reset |= SOFT_RESET_IH;
3962a65a4369SAlex Deucher 
3963a65a4369SAlex Deucher 	if (reset_mask & RADEON_RESET_GRBM)
3964a65a4369SAlex Deucher 		srbm_soft_reset |= SOFT_RESET_GRBM;
3965a65a4369SAlex Deucher 
3966a65a4369SAlex Deucher 	if (reset_mask & RADEON_RESET_VMC)
3967a65a4369SAlex Deucher 		srbm_soft_reset |= SOFT_RESET_VMC;
3968a65a4369SAlex Deucher 
396924178ec4SAlex Deucher 	if (!(rdev->flags & RADEON_IS_IGP)) {
3970a65a4369SAlex Deucher 		if (reset_mask & RADEON_RESET_MC)
3971a65a4369SAlex Deucher 			srbm_soft_reset |= SOFT_RESET_MC;
397224178ec4SAlex Deucher 	}
3973a65a4369SAlex Deucher 
3974b7630473SAlex Deucher 	if (grbm_soft_reset) {
3975b7630473SAlex Deucher 		tmp = RREG32(GRBM_SOFT_RESET);
3976b7630473SAlex Deucher 		tmp |= grbm_soft_reset;
3977b7630473SAlex Deucher 		dev_info(rdev->dev, "GRBM_SOFT_RESET=0x%08X\n", tmp);
3978b7630473SAlex Deucher 		WREG32(GRBM_SOFT_RESET, tmp);
3979b7630473SAlex Deucher 		tmp = RREG32(GRBM_SOFT_RESET);
3980b7630473SAlex Deucher 
3981b7630473SAlex Deucher 		udelay(50);
3982b7630473SAlex Deucher 
3983b7630473SAlex Deucher 		tmp &= ~grbm_soft_reset;
3984b7630473SAlex Deucher 		WREG32(GRBM_SOFT_RESET, tmp);
3985b7630473SAlex Deucher 		tmp = RREG32(GRBM_SOFT_RESET);
3986b7630473SAlex Deucher 	}
3987b7630473SAlex Deucher 
3988b7630473SAlex Deucher 	if (srbm_soft_reset) {
3989b7630473SAlex Deucher 		tmp = RREG32(SRBM_SOFT_RESET);
3990b7630473SAlex Deucher 		tmp |= srbm_soft_reset;
3991b7630473SAlex Deucher 		dev_info(rdev->dev, "SRBM_SOFT_RESET=0x%08X\n", tmp);
3992b7630473SAlex Deucher 		WREG32(SRBM_SOFT_RESET, tmp);
3993b7630473SAlex Deucher 		tmp = RREG32(SRBM_SOFT_RESET);
3994b7630473SAlex Deucher 
3995b7630473SAlex Deucher 		udelay(50);
3996b7630473SAlex Deucher 
3997b7630473SAlex Deucher 		tmp &= ~srbm_soft_reset;
3998b7630473SAlex Deucher 		WREG32(SRBM_SOFT_RESET, tmp);
3999b7630473SAlex Deucher 		tmp = RREG32(SRBM_SOFT_RESET);
4000b7630473SAlex Deucher 	}
40010ecebb9eSAlex Deucher 
40020ecebb9eSAlex Deucher 	/* Wait a little for things to settle down */
40030ecebb9eSAlex Deucher 	udelay(50);
40040ecebb9eSAlex Deucher 
4005747943eaSAlex Deucher 	evergreen_mc_resume(rdev, &save);
4006b7630473SAlex Deucher 	udelay(50);
4007410a3418SAlex Deucher 
4008b7630473SAlex Deucher 	evergreen_print_gpu_status_regs(rdev);
4009747943eaSAlex Deucher }
4010747943eaSAlex Deucher 
evergreen_gpu_pci_config_reset(struct radeon_device * rdev)4011b5470b03SAlex Deucher void evergreen_gpu_pci_config_reset(struct radeon_device *rdev)
4012b5470b03SAlex Deucher {
4013b5470b03SAlex Deucher 	struct evergreen_mc_save save;
4014b5470b03SAlex Deucher 	u32 tmp, i;
4015b5470b03SAlex Deucher 
4016b5470b03SAlex Deucher 	dev_info(rdev->dev, "GPU pci config reset\n");
4017b5470b03SAlex Deucher 
4018b5470b03SAlex Deucher 	/* disable dpm? */
4019b5470b03SAlex Deucher 
4020b5470b03SAlex Deucher 	/* Disable CP parsing/prefetching */
4021b5470b03SAlex Deucher 	WREG32(CP_ME_CNTL, CP_ME_HALT | CP_PFP_HALT);
4022b5470b03SAlex Deucher 	udelay(50);
4023b5470b03SAlex Deucher 	/* Disable DMA */
4024b5470b03SAlex Deucher 	tmp = RREG32(DMA_RB_CNTL);
4025b5470b03SAlex Deucher 	tmp &= ~DMA_RB_ENABLE;
4026b5470b03SAlex Deucher 	WREG32(DMA_RB_CNTL, tmp);
4027b5470b03SAlex Deucher 	/* XXX other engines? */
4028b5470b03SAlex Deucher 
4029b5470b03SAlex Deucher 	/* halt the rlc */
4030b5470b03SAlex Deucher 	r600_rlc_stop(rdev);
4031b5470b03SAlex Deucher 
4032b5470b03SAlex Deucher 	udelay(50);
4033b5470b03SAlex Deucher 
4034b5470b03SAlex Deucher 	/* set mclk/sclk to bypass */
4035b5470b03SAlex Deucher 	rv770_set_clk_bypass_mode(rdev);
4036b5470b03SAlex Deucher 	/* disable BM */
4037b5470b03SAlex Deucher 	pci_clear_master(rdev->pdev);
4038b5470b03SAlex Deucher 	/* disable mem access */
4039b5470b03SAlex Deucher 	evergreen_mc_stop(rdev, &save);
4040b5470b03SAlex Deucher 	if (evergreen_mc_wait_for_idle(rdev)) {
4041b5470b03SAlex Deucher 		dev_warn(rdev->dev, "Wait for MC idle timed out !\n");
4042b5470b03SAlex Deucher 	}
4043b5470b03SAlex Deucher 	/* reset */
4044b5470b03SAlex Deucher 	radeon_pci_config_reset(rdev);
4045b5470b03SAlex Deucher 	/* wait for asic to come out of reset */
4046b5470b03SAlex Deucher 	for (i = 0; i < rdev->usec_timeout; i++) {
4047b5470b03SAlex Deucher 		if (RREG32(CONFIG_MEMSIZE) != 0xffffffff)
4048b5470b03SAlex Deucher 			break;
4049b5470b03SAlex Deucher 		udelay(1);
4050b5470b03SAlex Deucher 	}
4051b5470b03SAlex Deucher }
4052b5470b03SAlex Deucher 
evergreen_asic_reset(struct radeon_device * rdev,bool hard)405371fe2899SJérome Glisse int evergreen_asic_reset(struct radeon_device *rdev, bool hard)
4054bcc1c2a1SAlex Deucher {
4055a65a4369SAlex Deucher 	u32 reset_mask;
4056a65a4369SAlex Deucher 
405771fe2899SJérome Glisse 	if (hard) {
405871fe2899SJérome Glisse 		evergreen_gpu_pci_config_reset(rdev);
405971fe2899SJérome Glisse 		return 0;
406071fe2899SJérome Glisse 	}
406171fe2899SJérome Glisse 
4062a65a4369SAlex Deucher 	reset_mask = evergreen_gpu_check_soft_reset(rdev);
4063a65a4369SAlex Deucher 
4064a65a4369SAlex Deucher 	if (reset_mask)
4065a65a4369SAlex Deucher 		r600_set_bios_scratch_engine_hung(rdev, true);
4066a65a4369SAlex Deucher 
4067b5470b03SAlex Deucher 	/* try soft reset */
4068a65a4369SAlex Deucher 	evergreen_gpu_soft_reset(rdev, reset_mask);
4069a65a4369SAlex Deucher 
4070a65a4369SAlex Deucher 	reset_mask = evergreen_gpu_check_soft_reset(rdev);
4071a65a4369SAlex Deucher 
4072b5470b03SAlex Deucher 	/* try pci config reset */
4073b5470b03SAlex Deucher 	if (reset_mask && radeon_hard_reset)
4074b5470b03SAlex Deucher 		evergreen_gpu_pci_config_reset(rdev);
4075b5470b03SAlex Deucher 
4076b5470b03SAlex Deucher 	reset_mask = evergreen_gpu_check_soft_reset(rdev);
4077b5470b03SAlex Deucher 
4078a65a4369SAlex Deucher 	if (!reset_mask)
4079a65a4369SAlex Deucher 		r600_set_bios_scratch_engine_hung(rdev, false);
4080a65a4369SAlex Deucher 
4081a65a4369SAlex Deucher 	return 0;
4082bcc1c2a1SAlex Deucher }
4083bcc1c2a1SAlex Deucher 
4084123bc183SAlex Deucher /**
4085123bc183SAlex Deucher  * evergreen_gfx_is_lockup - Check if the GFX engine is locked up
4086123bc183SAlex Deucher  *
4087123bc183SAlex Deucher  * @rdev: radeon_device pointer
4088123bc183SAlex Deucher  * @ring: radeon_ring structure holding ring information
4089123bc183SAlex Deucher  *
4090123bc183SAlex Deucher  * Check if the GFX engine is locked up.
4091123bc183SAlex Deucher  * Returns true if the engine appears to be locked up, false if not.
4092123bc183SAlex Deucher  */
evergreen_gfx_is_lockup(struct radeon_device * rdev,struct radeon_ring * ring)4093123bc183SAlex Deucher bool evergreen_gfx_is_lockup(struct radeon_device *rdev, struct radeon_ring *ring)
4094123bc183SAlex Deucher {
4095123bc183SAlex Deucher 	u32 reset_mask = evergreen_gpu_check_soft_reset(rdev);
4096123bc183SAlex Deucher 
4097123bc183SAlex Deucher 	if (!(reset_mask & (RADEON_RESET_GFX |
4098123bc183SAlex Deucher 			    RADEON_RESET_COMPUTE |
4099123bc183SAlex Deucher 			    RADEON_RESET_CP))) {
4100ff212f25SChristian König 		radeon_ring_lockup_update(rdev, ring);
4101123bc183SAlex Deucher 		return false;
4102123bc183SAlex Deucher 	}
4103123bc183SAlex Deucher 	return radeon_ring_test_lockup(rdev, ring);
4104123bc183SAlex Deucher }
4105123bc183SAlex Deucher 
41062948f5e6SAlex Deucher /*
41072948f5e6SAlex Deucher  * RLC
41082948f5e6SAlex Deucher  */
41092948f5e6SAlex Deucher #define RLC_SAVE_RESTORE_LIST_END_MARKER    0x00000000
41102948f5e6SAlex Deucher #define RLC_CLEAR_STATE_END_MARKER          0x00000001
41112948f5e6SAlex Deucher 
sumo_rlc_fini(struct radeon_device * rdev)41122948f5e6SAlex Deucher void sumo_rlc_fini(struct radeon_device *rdev)
41132948f5e6SAlex Deucher {
41142948f5e6SAlex Deucher 	int r;
41152948f5e6SAlex Deucher 
41162948f5e6SAlex Deucher 	/* save restore block */
41172948f5e6SAlex Deucher 	if (rdev->rlc.save_restore_obj) {
41182948f5e6SAlex Deucher 		r = radeon_bo_reserve(rdev->rlc.save_restore_obj, false);
41192948f5e6SAlex Deucher 		if (unlikely(r != 0))
41202948f5e6SAlex Deucher 			dev_warn(rdev->dev, "(%d) reserve RLC sr bo failed\n", r);
41212948f5e6SAlex Deucher 		radeon_bo_unpin(rdev->rlc.save_restore_obj);
41222948f5e6SAlex Deucher 		radeon_bo_unreserve(rdev->rlc.save_restore_obj);
41232948f5e6SAlex Deucher 
41242948f5e6SAlex Deucher 		radeon_bo_unref(&rdev->rlc.save_restore_obj);
41252948f5e6SAlex Deucher 		rdev->rlc.save_restore_obj = NULL;
41262948f5e6SAlex Deucher 	}
41272948f5e6SAlex Deucher 
41282948f5e6SAlex Deucher 	/* clear state block */
41292948f5e6SAlex Deucher 	if (rdev->rlc.clear_state_obj) {
41302948f5e6SAlex Deucher 		r = radeon_bo_reserve(rdev->rlc.clear_state_obj, false);
41312948f5e6SAlex Deucher 		if (unlikely(r != 0))
41322948f5e6SAlex Deucher 			dev_warn(rdev->dev, "(%d) reserve RLC c bo failed\n", r);
41332948f5e6SAlex Deucher 		radeon_bo_unpin(rdev->rlc.clear_state_obj);
41342948f5e6SAlex Deucher 		radeon_bo_unreserve(rdev->rlc.clear_state_obj);
41352948f5e6SAlex Deucher 
41362948f5e6SAlex Deucher 		radeon_bo_unref(&rdev->rlc.clear_state_obj);
41372948f5e6SAlex Deucher 		rdev->rlc.clear_state_obj = NULL;
41382948f5e6SAlex Deucher 	}
413922c775ceSAlex Deucher 
414022c775ceSAlex Deucher 	/* clear state block */
414122c775ceSAlex Deucher 	if (rdev->rlc.cp_table_obj) {
414222c775ceSAlex Deucher 		r = radeon_bo_reserve(rdev->rlc.cp_table_obj, false);
414322c775ceSAlex Deucher 		if (unlikely(r != 0))
414422c775ceSAlex Deucher 			dev_warn(rdev->dev, "(%d) reserve RLC cp table bo failed\n", r);
414522c775ceSAlex Deucher 		radeon_bo_unpin(rdev->rlc.cp_table_obj);
414622c775ceSAlex Deucher 		radeon_bo_unreserve(rdev->rlc.cp_table_obj);
414722c775ceSAlex Deucher 
414822c775ceSAlex Deucher 		radeon_bo_unref(&rdev->rlc.cp_table_obj);
414922c775ceSAlex Deucher 		rdev->rlc.cp_table_obj = NULL;
41502948f5e6SAlex Deucher 	}
415122c775ceSAlex Deucher }
415222c775ceSAlex Deucher 
415322c775ceSAlex Deucher #define CP_ME_TABLE_SIZE    96
41542948f5e6SAlex Deucher 
sumo_rlc_init(struct radeon_device * rdev)41552948f5e6SAlex Deucher int sumo_rlc_init(struct radeon_device *rdev)
41562948f5e6SAlex Deucher {
41571fd11777SAlex Deucher 	const u32 *src_ptr;
41582948f5e6SAlex Deucher 	volatile u32 *dst_ptr;
41592948f5e6SAlex Deucher 	u32 dws, data, i, j, k, reg_num;
416059a82d0eSAlex Deucher 	u32 reg_list_num, reg_list_hdr_blk_index, reg_list_blk_index = 0;
41612948f5e6SAlex Deucher 	u64 reg_list_mc_addr;
41621fd11777SAlex Deucher 	const struct cs_section_def *cs_data;
41632948f5e6SAlex Deucher 	int r;
41642948f5e6SAlex Deucher 
41652948f5e6SAlex Deucher 	src_ptr = rdev->rlc.reg_list;
41662948f5e6SAlex Deucher 	dws = rdev->rlc.reg_list_size;
4167a0f38609SAlex Deucher 	if (rdev->family >= CHIP_BONAIRE) {
4168a0f38609SAlex Deucher 		dws += (5 * 16) + 48 + 48 + 64;
4169a0f38609SAlex Deucher 	}
41702948f5e6SAlex Deucher 	cs_data = rdev->rlc.cs_data;
41712948f5e6SAlex Deucher 
417210b7ca7eSAlex Deucher 	if (src_ptr) {
41732948f5e6SAlex Deucher 		/* save restore block */
41742948f5e6SAlex Deucher 		if (rdev->rlc.save_restore_obj == NULL) {
41752948f5e6SAlex Deucher 			r = radeon_bo_create(rdev, dws * 4, PAGE_SIZE, true,
417602376d82SMichel Dänzer 					     RADEON_GEM_DOMAIN_VRAM, 0, NULL,
4177831b6966SMaarten Lankhorst 					     NULL, &rdev->rlc.save_restore_obj);
41782948f5e6SAlex Deucher 			if (r) {
41792948f5e6SAlex Deucher 				dev_warn(rdev->dev, "(%d) create RLC sr bo failed\n", r);
41802948f5e6SAlex Deucher 				return r;
41812948f5e6SAlex Deucher 			}
41822948f5e6SAlex Deucher 		}
41832948f5e6SAlex Deucher 
41842948f5e6SAlex Deucher 		r = radeon_bo_reserve(rdev->rlc.save_restore_obj, false);
41852948f5e6SAlex Deucher 		if (unlikely(r != 0)) {
41862948f5e6SAlex Deucher 			sumo_rlc_fini(rdev);
41872948f5e6SAlex Deucher 			return r;
41882948f5e6SAlex Deucher 		}
41892948f5e6SAlex Deucher 		r = radeon_bo_pin(rdev->rlc.save_restore_obj, RADEON_GEM_DOMAIN_VRAM,
41902948f5e6SAlex Deucher 				  &rdev->rlc.save_restore_gpu_addr);
41912948f5e6SAlex Deucher 		if (r) {
41922948f5e6SAlex Deucher 			radeon_bo_unreserve(rdev->rlc.save_restore_obj);
41932948f5e6SAlex Deucher 			dev_warn(rdev->dev, "(%d) pin RLC sr bo failed\n", r);
41942948f5e6SAlex Deucher 			sumo_rlc_fini(rdev);
41952948f5e6SAlex Deucher 			return r;
41962948f5e6SAlex Deucher 		}
419710b7ca7eSAlex Deucher 
41982948f5e6SAlex Deucher 		r = radeon_bo_kmap(rdev->rlc.save_restore_obj, (void **)&rdev->rlc.sr_ptr);
41992948f5e6SAlex Deucher 		if (r) {
42002948f5e6SAlex Deucher 			dev_warn(rdev->dev, "(%d) map RLC sr bo failed\n", r);
42012948f5e6SAlex Deucher 			sumo_rlc_fini(rdev);
42022948f5e6SAlex Deucher 			return r;
42032948f5e6SAlex Deucher 		}
42042948f5e6SAlex Deucher 		/* write the sr buffer */
42052948f5e6SAlex Deucher 		dst_ptr = rdev->rlc.sr_ptr;
42061fd11777SAlex Deucher 		if (rdev->family >= CHIP_TAHITI) {
42071fd11777SAlex Deucher 			/* SI */
420859a82d0eSAlex Deucher 			for (i = 0; i < rdev->rlc.reg_list_size; i++)
42096ba81e53SAlex Deucher 				dst_ptr[i] = cpu_to_le32(src_ptr[i]);
42101fd11777SAlex Deucher 		} else {
42111fd11777SAlex Deucher 			/* ON/LN/TN */
42122948f5e6SAlex Deucher 			/* format:
42132948f5e6SAlex Deucher 			 * dw0: (reg2 << 16) | reg1
42142948f5e6SAlex Deucher 			 * dw1: reg1 save space
42152948f5e6SAlex Deucher 			 * dw2: reg2 save space
42162948f5e6SAlex Deucher 			 */
42172948f5e6SAlex Deucher 			for (i = 0; i < dws; i++) {
42182948f5e6SAlex Deucher 				data = src_ptr[i] >> 2;
42192948f5e6SAlex Deucher 				i++;
42202948f5e6SAlex Deucher 				if (i < dws)
42212948f5e6SAlex Deucher 					data |= (src_ptr[i] >> 2) << 16;
42222948f5e6SAlex Deucher 				j = (((i - 1) * 3) / 2);
42236ba81e53SAlex Deucher 				dst_ptr[j] = cpu_to_le32(data);
42242948f5e6SAlex Deucher 			}
42252948f5e6SAlex Deucher 			j = ((i * 3) / 2);
42266ba81e53SAlex Deucher 			dst_ptr[j] = cpu_to_le32(RLC_SAVE_RESTORE_LIST_END_MARKER);
42271fd11777SAlex Deucher 		}
42282948f5e6SAlex Deucher 		radeon_bo_kunmap(rdev->rlc.save_restore_obj);
42292948f5e6SAlex Deucher 		radeon_bo_unreserve(rdev->rlc.save_restore_obj);
423010b7ca7eSAlex Deucher 	}
42312948f5e6SAlex Deucher 
423210b7ca7eSAlex Deucher 	if (cs_data) {
42332948f5e6SAlex Deucher 		/* clear state block */
4234a0f38609SAlex Deucher 		if (rdev->family >= CHIP_BONAIRE) {
4235a0f38609SAlex Deucher 			rdev->rlc.clear_state_size = dws = cik_get_csb_size(rdev);
4236a0f38609SAlex Deucher 		} else if (rdev->family >= CHIP_TAHITI) {
423759a82d0eSAlex Deucher 			rdev->rlc.clear_state_size = si_get_csb_size(rdev);
423859a82d0eSAlex Deucher 			dws = rdev->rlc.clear_state_size + (256 / 4);
423959a82d0eSAlex Deucher 		} else {
42402948f5e6SAlex Deucher 			reg_list_num = 0;
42412948f5e6SAlex Deucher 			dws = 0;
42422948f5e6SAlex Deucher 			for (i = 0; cs_data[i].section != NULL; i++) {
42432948f5e6SAlex Deucher 				for (j = 0; cs_data[i].section[j].extent != NULL; j++) {
42442948f5e6SAlex Deucher 					reg_list_num++;
42452948f5e6SAlex Deucher 					dws += cs_data[i].section[j].reg_count;
42462948f5e6SAlex Deucher 				}
42472948f5e6SAlex Deucher 			}
42482948f5e6SAlex Deucher 			reg_list_blk_index = (3 * reg_list_num + 2);
42492948f5e6SAlex Deucher 			dws += reg_list_blk_index;
425022c775ceSAlex Deucher 			rdev->rlc.clear_state_size = dws;
425159a82d0eSAlex Deucher 		}
42522948f5e6SAlex Deucher 
42532948f5e6SAlex Deucher 		if (rdev->rlc.clear_state_obj == NULL) {
42542948f5e6SAlex Deucher 			r = radeon_bo_create(rdev, dws * 4, PAGE_SIZE, true,
425502376d82SMichel Dänzer 					     RADEON_GEM_DOMAIN_VRAM, 0, NULL,
4256831b6966SMaarten Lankhorst 					     NULL, &rdev->rlc.clear_state_obj);
42572948f5e6SAlex Deucher 			if (r) {
42582948f5e6SAlex Deucher 				dev_warn(rdev->dev, "(%d) create RLC c bo failed\n", r);
42592948f5e6SAlex Deucher 				sumo_rlc_fini(rdev);
42602948f5e6SAlex Deucher 				return r;
42612948f5e6SAlex Deucher 			}
42622948f5e6SAlex Deucher 		}
42632948f5e6SAlex Deucher 		r = radeon_bo_reserve(rdev->rlc.clear_state_obj, false);
42642948f5e6SAlex Deucher 		if (unlikely(r != 0)) {
42652948f5e6SAlex Deucher 			sumo_rlc_fini(rdev);
42662948f5e6SAlex Deucher 			return r;
42672948f5e6SAlex Deucher 		}
42682948f5e6SAlex Deucher 		r = radeon_bo_pin(rdev->rlc.clear_state_obj, RADEON_GEM_DOMAIN_VRAM,
42692948f5e6SAlex Deucher 				  &rdev->rlc.clear_state_gpu_addr);
42702948f5e6SAlex Deucher 		if (r) {
42712948f5e6SAlex Deucher 			radeon_bo_unreserve(rdev->rlc.clear_state_obj);
42722948f5e6SAlex Deucher 			dev_warn(rdev->dev, "(%d) pin RLC c bo failed\n", r);
42732948f5e6SAlex Deucher 			sumo_rlc_fini(rdev);
42742948f5e6SAlex Deucher 			return r;
42752948f5e6SAlex Deucher 		}
427610b7ca7eSAlex Deucher 
42772948f5e6SAlex Deucher 		r = radeon_bo_kmap(rdev->rlc.clear_state_obj, (void **)&rdev->rlc.cs_ptr);
42782948f5e6SAlex Deucher 		if (r) {
42792948f5e6SAlex Deucher 			dev_warn(rdev->dev, "(%d) map RLC c bo failed\n", r);
42802948f5e6SAlex Deucher 			sumo_rlc_fini(rdev);
42812948f5e6SAlex Deucher 			return r;
42822948f5e6SAlex Deucher 		}
42832948f5e6SAlex Deucher 		/* set up the cs buffer */
42842948f5e6SAlex Deucher 		dst_ptr = rdev->rlc.cs_ptr;
4285a0f38609SAlex Deucher 		if (rdev->family >= CHIP_BONAIRE) {
4286a0f38609SAlex Deucher 			cik_get_csb_buffer(rdev, dst_ptr);
4287a0f38609SAlex Deucher 		} else if (rdev->family >= CHIP_TAHITI) {
428859a82d0eSAlex Deucher 			reg_list_mc_addr = rdev->rlc.clear_state_gpu_addr + 256;
42896ba81e53SAlex Deucher 			dst_ptr[0] = cpu_to_le32(upper_32_bits(reg_list_mc_addr));
42906ba81e53SAlex Deucher 			dst_ptr[1] = cpu_to_le32(lower_32_bits(reg_list_mc_addr));
42916ba81e53SAlex Deucher 			dst_ptr[2] = cpu_to_le32(rdev->rlc.clear_state_size);
429259a82d0eSAlex Deucher 			si_get_csb_buffer(rdev, &dst_ptr[(256/4)]);
429359a82d0eSAlex Deucher 		} else {
42942948f5e6SAlex Deucher 			reg_list_hdr_blk_index = 0;
42952948f5e6SAlex Deucher 			reg_list_mc_addr = rdev->rlc.clear_state_gpu_addr + (reg_list_blk_index * 4);
42962948f5e6SAlex Deucher 			data = upper_32_bits(reg_list_mc_addr);
42976ba81e53SAlex Deucher 			dst_ptr[reg_list_hdr_blk_index] = cpu_to_le32(data);
42982948f5e6SAlex Deucher 			reg_list_hdr_blk_index++;
42992948f5e6SAlex Deucher 			for (i = 0; cs_data[i].section != NULL; i++) {
43002948f5e6SAlex Deucher 				for (j = 0; cs_data[i].section[j].extent != NULL; j++) {
43012948f5e6SAlex Deucher 					reg_num = cs_data[i].section[j].reg_count;
43022948f5e6SAlex Deucher 					data = reg_list_mc_addr & 0xffffffff;
43036ba81e53SAlex Deucher 					dst_ptr[reg_list_hdr_blk_index] = cpu_to_le32(data);
43042948f5e6SAlex Deucher 					reg_list_hdr_blk_index++;
43052948f5e6SAlex Deucher 
43062948f5e6SAlex Deucher 					data = (cs_data[i].section[j].reg_index * 4) & 0xffffffff;
43076ba81e53SAlex Deucher 					dst_ptr[reg_list_hdr_blk_index] = cpu_to_le32(data);
43082948f5e6SAlex Deucher 					reg_list_hdr_blk_index++;
43092948f5e6SAlex Deucher 
43102948f5e6SAlex Deucher 					data = 0x08000000 | (reg_num * 4);
43116ba81e53SAlex Deucher 					dst_ptr[reg_list_hdr_blk_index] = cpu_to_le32(data);
43122948f5e6SAlex Deucher 					reg_list_hdr_blk_index++;
43132948f5e6SAlex Deucher 
43142948f5e6SAlex Deucher 					for (k = 0; k < reg_num; k++) {
43152948f5e6SAlex Deucher 						data = cs_data[i].section[j].extent[k];
43166ba81e53SAlex Deucher 						dst_ptr[reg_list_blk_index + k] = cpu_to_le32(data);
43172948f5e6SAlex Deucher 					}
43182948f5e6SAlex Deucher 					reg_list_mc_addr += reg_num * 4;
43192948f5e6SAlex Deucher 					reg_list_blk_index += reg_num;
43202948f5e6SAlex Deucher 				}
43212948f5e6SAlex Deucher 			}
43226ba81e53SAlex Deucher 			dst_ptr[reg_list_hdr_blk_index] = cpu_to_le32(RLC_CLEAR_STATE_END_MARKER);
432359a82d0eSAlex Deucher 		}
43242948f5e6SAlex Deucher 		radeon_bo_kunmap(rdev->rlc.clear_state_obj);
43252948f5e6SAlex Deucher 		radeon_bo_unreserve(rdev->rlc.clear_state_obj);
432610b7ca7eSAlex Deucher 	}
43272948f5e6SAlex Deucher 
432822c775ceSAlex Deucher 	if (rdev->rlc.cp_table_size) {
432922c775ceSAlex Deucher 		if (rdev->rlc.cp_table_obj == NULL) {
433002376d82SMichel Dänzer 			r = radeon_bo_create(rdev, rdev->rlc.cp_table_size,
433102376d82SMichel Dänzer 					     PAGE_SIZE, true,
433202376d82SMichel Dänzer 					     RADEON_GEM_DOMAIN_VRAM, 0, NULL,
4333831b6966SMaarten Lankhorst 					     NULL, &rdev->rlc.cp_table_obj);
433422c775ceSAlex Deucher 			if (r) {
433522c775ceSAlex Deucher 				dev_warn(rdev->dev, "(%d) create RLC cp table bo failed\n", r);
433622c775ceSAlex Deucher 				sumo_rlc_fini(rdev);
433722c775ceSAlex Deucher 				return r;
433822c775ceSAlex Deucher 			}
433922c775ceSAlex Deucher 		}
434022c775ceSAlex Deucher 
434122c775ceSAlex Deucher 		r = radeon_bo_reserve(rdev->rlc.cp_table_obj, false);
434222c775ceSAlex Deucher 		if (unlikely(r != 0)) {
434322c775ceSAlex Deucher 			dev_warn(rdev->dev, "(%d) reserve RLC cp table bo failed\n", r);
434422c775ceSAlex Deucher 			sumo_rlc_fini(rdev);
434522c775ceSAlex Deucher 			return r;
434622c775ceSAlex Deucher 		}
434722c775ceSAlex Deucher 		r = radeon_bo_pin(rdev->rlc.cp_table_obj, RADEON_GEM_DOMAIN_VRAM,
434822c775ceSAlex Deucher 				  &rdev->rlc.cp_table_gpu_addr);
434922c775ceSAlex Deucher 		if (r) {
435022c775ceSAlex Deucher 			radeon_bo_unreserve(rdev->rlc.cp_table_obj);
435122c775ceSAlex Deucher 			dev_warn(rdev->dev, "(%d) pin RLC cp_table bo failed\n", r);
435222c775ceSAlex Deucher 			sumo_rlc_fini(rdev);
435322c775ceSAlex Deucher 			return r;
435422c775ceSAlex Deucher 		}
435522c775ceSAlex Deucher 		r = radeon_bo_kmap(rdev->rlc.cp_table_obj, (void **)&rdev->rlc.cp_table_ptr);
435622c775ceSAlex Deucher 		if (r) {
435722c775ceSAlex Deucher 			dev_warn(rdev->dev, "(%d) map RLC cp table bo failed\n", r);
435822c775ceSAlex Deucher 			sumo_rlc_fini(rdev);
435922c775ceSAlex Deucher 			return r;
436022c775ceSAlex Deucher 		}
436122c775ceSAlex Deucher 
436222c775ceSAlex Deucher 		cik_init_cp_pg_table(rdev);
436322c775ceSAlex Deucher 
436422c775ceSAlex Deucher 		radeon_bo_kunmap(rdev->rlc.cp_table_obj);
436522c775ceSAlex Deucher 		radeon_bo_unreserve(rdev->rlc.cp_table_obj);
436622c775ceSAlex Deucher 
436722c775ceSAlex Deucher 	}
43682948f5e6SAlex Deucher 
43692948f5e6SAlex Deucher 	return 0;
43702948f5e6SAlex Deucher }
43712948f5e6SAlex Deucher 
evergreen_rlc_start(struct radeon_device * rdev)43722948f5e6SAlex Deucher static void evergreen_rlc_start(struct radeon_device *rdev)
43732948f5e6SAlex Deucher {
43748ba10463SAlex Deucher 	u32 mask = RLC_ENABLE;
43758ba10463SAlex Deucher 
43768ba10463SAlex Deucher 	if (rdev->flags & RADEON_IS_IGP) {
43778ba10463SAlex Deucher 		mask |= GFX_POWER_GATING_ENABLE | GFX_POWER_GATING_SRC;
43788ba10463SAlex Deucher 	}
43798ba10463SAlex Deucher 
43808ba10463SAlex Deucher 	WREG32(RLC_CNTL, mask);
43812948f5e6SAlex Deucher }
43822948f5e6SAlex Deucher 
evergreen_rlc_resume(struct radeon_device * rdev)43832948f5e6SAlex Deucher int evergreen_rlc_resume(struct radeon_device *rdev)
43842948f5e6SAlex Deucher {
43852948f5e6SAlex Deucher 	u32 i;
43862948f5e6SAlex Deucher 	const __be32 *fw_data;
43872948f5e6SAlex Deucher 
43882948f5e6SAlex Deucher 	if (!rdev->rlc_fw)
43892948f5e6SAlex Deucher 		return -EINVAL;
43902948f5e6SAlex Deucher 
43912948f5e6SAlex Deucher 	r600_rlc_stop(rdev);
43922948f5e6SAlex Deucher 
43932948f5e6SAlex Deucher 	WREG32(RLC_HB_CNTL, 0);
43942948f5e6SAlex Deucher 
43952948f5e6SAlex Deucher 	if (rdev->flags & RADEON_IS_IGP) {
43968ba10463SAlex Deucher 		if (rdev->family == CHIP_ARUBA) {
43978ba10463SAlex Deucher 			u32 always_on_bitmap =
43988ba10463SAlex Deucher 				3 | (3 << (16 * rdev->config.cayman.max_shader_engines));
43998ba10463SAlex Deucher 			/* find out the number of active simds */
44008ba10463SAlex Deucher 			u32 tmp = (RREG32(CC_GC_SHADER_PIPE_CONFIG) & 0xffff0000) >> 16;
44018ba10463SAlex Deucher 			tmp |= 0xffffffff << rdev->config.cayman.max_simds_per_se;
44028ba10463SAlex Deucher 			tmp = hweight32(~tmp);
44038ba10463SAlex Deucher 			if (tmp == rdev->config.cayman.max_simds_per_se) {
44048ba10463SAlex Deucher 				WREG32(TN_RLC_LB_ALWAYS_ACTIVE_SIMD_MASK, always_on_bitmap);
44058ba10463SAlex Deucher 				WREG32(TN_RLC_LB_PARAMS, 0x00601004);
44068ba10463SAlex Deucher 				WREG32(TN_RLC_LB_INIT_SIMD_MASK, 0xffffffff);
44078ba10463SAlex Deucher 				WREG32(TN_RLC_LB_CNTR_INIT, 0x00000000);
44088ba10463SAlex Deucher 				WREG32(TN_RLC_LB_CNTR_MAX, 0x00002000);
44098ba10463SAlex Deucher 			}
44108ba10463SAlex Deucher 		} else {
44118ba10463SAlex Deucher 			WREG32(RLC_HB_WPTR_LSB_ADDR, 0);
44128ba10463SAlex Deucher 			WREG32(RLC_HB_WPTR_MSB_ADDR, 0);
44138ba10463SAlex Deucher 		}
44142948f5e6SAlex Deucher 		WREG32(TN_RLC_SAVE_AND_RESTORE_BASE, rdev->rlc.save_restore_gpu_addr >> 8);
44152948f5e6SAlex Deucher 		WREG32(TN_RLC_CLEAR_STATE_RESTORE_BASE, rdev->rlc.clear_state_gpu_addr >> 8);
44162948f5e6SAlex Deucher 	} else {
44172948f5e6SAlex Deucher 		WREG32(RLC_HB_BASE, 0);
44182948f5e6SAlex Deucher 		WREG32(RLC_HB_RPTR, 0);
44192948f5e6SAlex Deucher 		WREG32(RLC_HB_WPTR, 0);
44202948f5e6SAlex Deucher 		WREG32(RLC_HB_WPTR_LSB_ADDR, 0);
44212948f5e6SAlex Deucher 		WREG32(RLC_HB_WPTR_MSB_ADDR, 0);
44228ba10463SAlex Deucher 	}
44232948f5e6SAlex Deucher 	WREG32(RLC_MC_CNTL, 0);
44242948f5e6SAlex Deucher 	WREG32(RLC_UCODE_CNTL, 0);
44252948f5e6SAlex Deucher 
44262948f5e6SAlex Deucher 	fw_data = (const __be32 *)rdev->rlc_fw->data;
44272948f5e6SAlex Deucher 	if (rdev->family >= CHIP_ARUBA) {
44282948f5e6SAlex Deucher 		for (i = 0; i < ARUBA_RLC_UCODE_SIZE; i++) {
44292948f5e6SAlex Deucher 			WREG32(RLC_UCODE_ADDR, i);
44302948f5e6SAlex Deucher 			WREG32(RLC_UCODE_DATA, be32_to_cpup(fw_data++));
44312948f5e6SAlex Deucher 		}
44322948f5e6SAlex Deucher 	} else if (rdev->family >= CHIP_CAYMAN) {
44332948f5e6SAlex Deucher 		for (i = 0; i < CAYMAN_RLC_UCODE_SIZE; i++) {
44342948f5e6SAlex Deucher 			WREG32(RLC_UCODE_ADDR, i);
44352948f5e6SAlex Deucher 			WREG32(RLC_UCODE_DATA, be32_to_cpup(fw_data++));
44362948f5e6SAlex Deucher 		}
44372948f5e6SAlex Deucher 	} else {
44382948f5e6SAlex Deucher 		for (i = 0; i < EVERGREEN_RLC_UCODE_SIZE; i++) {
44392948f5e6SAlex Deucher 			WREG32(RLC_UCODE_ADDR, i);
44402948f5e6SAlex Deucher 			WREG32(RLC_UCODE_DATA, be32_to_cpup(fw_data++));
44412948f5e6SAlex Deucher 		}
44422948f5e6SAlex Deucher 	}
44432948f5e6SAlex Deucher 	WREG32(RLC_UCODE_ADDR, 0);
44442948f5e6SAlex Deucher 
44452948f5e6SAlex Deucher 	evergreen_rlc_start(rdev);
44462948f5e6SAlex Deucher 
44472948f5e6SAlex Deucher 	return 0;
44482948f5e6SAlex Deucher }
44492948f5e6SAlex Deucher 
445045f9a39bSAlex Deucher /* Interrupts */
445145f9a39bSAlex Deucher 
evergreen_get_vblank_counter(struct radeon_device * rdev,int crtc)445245f9a39bSAlex Deucher u32 evergreen_get_vblank_counter(struct radeon_device *rdev, int crtc)
445345f9a39bSAlex Deucher {
445446437057SAlex Deucher 	if (crtc >= rdev->num_crtc)
4455bcc1c2a1SAlex Deucher 		return 0;
445646437057SAlex Deucher 	else
445746437057SAlex Deucher 		return RREG32(CRTC_STATUS_FRAME_COUNT + crtc_offsets[crtc]);
445845f9a39bSAlex Deucher }
445945f9a39bSAlex Deucher 
evergreen_disable_interrupt_state(struct radeon_device * rdev)446045f9a39bSAlex Deucher void evergreen_disable_interrupt_state(struct radeon_device *rdev)
446145f9a39bSAlex Deucher {
44624cd096ddSLyude 	int i;
446345f9a39bSAlex Deucher 	u32 tmp;
446445f9a39bSAlex Deucher 
44651b37078bSAlex Deucher 	if (rdev->family >= CHIP_CAYMAN) {
44661b37078bSAlex Deucher 		cayman_cp_int_cntl_setup(rdev, 0,
44671b37078bSAlex Deucher 					 CNTX_BUSY_INT_ENABLE | CNTX_EMPTY_INT_ENABLE);
44681b37078bSAlex Deucher 		cayman_cp_int_cntl_setup(rdev, 1, 0);
44691b37078bSAlex Deucher 		cayman_cp_int_cntl_setup(rdev, 2, 0);
4470f60cbd11SAlex Deucher 		tmp = RREG32(CAYMAN_DMA1_CNTL) & ~TRAP_ENABLE;
4471f60cbd11SAlex Deucher 		WREG32(CAYMAN_DMA1_CNTL, tmp);
44721b37078bSAlex Deucher 	} else
44733555e53bSAlex Deucher 		WREG32(CP_INT_CNTL, CNTX_BUSY_INT_ENABLE | CNTX_EMPTY_INT_ENABLE);
4474233d1ad5SAlex Deucher 	tmp = RREG32(DMA_CNTL) & ~TRAP_ENABLE;
4475233d1ad5SAlex Deucher 	WREG32(DMA_CNTL, tmp);
447645f9a39bSAlex Deucher 	WREG32(GRBM_INT_CNTL, 0);
4477acc1522aSChristian König 	WREG32(SRBM_INT_CNTL, 0);
44784cd096ddSLyude 	for (i = 0; i < rdev->num_crtc; i++)
44794cd096ddSLyude 		WREG32(INT_MASK + crtc_offsets[i], 0);
448098990faeSLyude 	for (i = 0; i < rdev->num_crtc; i++)
448198990faeSLyude 		WREG32(GRPH_INT_CONTROL + crtc_offsets[i], 0);
448245f9a39bSAlex Deucher 
4483e9a321c6SAlex Deucher 	/* only one DAC on DCE5 */
4484e9a321c6SAlex Deucher 	if (!ASIC_IS_DCE5(rdev))
448545f9a39bSAlex Deucher 		WREG32(DACA_AUTODETECT_INT_CONTROL, 0);
448645f9a39bSAlex Deucher 	WREG32(DACB_AUTODETECT_INT_CONTROL, 0);
448745f9a39bSAlex Deucher 
44884cd096ddSLyude 	for (i = 0; i < 6; i++)
44894cd096ddSLyude 		WREG32_AND(DC_HPDx_INT_CONTROL(i), DC_HPDx_INT_POLARITY);
449045f9a39bSAlex Deucher }
449145f9a39bSAlex Deucher 
44924cd096ddSLyude /* Note that the order we write back regs here is important */
evergreen_irq_set(struct radeon_device * rdev)449345f9a39bSAlex Deucher int evergreen_irq_set(struct radeon_device *rdev)
449445f9a39bSAlex Deucher {
44954cd096ddSLyude 	int i;
449645f9a39bSAlex Deucher 	u32 cp_int_cntl = CNTX_BUSY_INT_ENABLE | CNTX_EMPTY_INT_ENABLE;
44971b37078bSAlex Deucher 	u32 cp_int_cntl1 = 0, cp_int_cntl2 = 0;
44982031f77cSAlex Deucher 	u32 grbm_int_cntl = 0;
4499f60cbd11SAlex Deucher 	u32 dma_cntl, dma_cntl1 = 0;
4500dc50ba7fSAlex Deucher 	u32 thermal_int = 0;
450145f9a39bSAlex Deucher 
450245f9a39bSAlex Deucher 	if (!rdev->irq.installed) {
4503fce7d61bSJoe Perches 		WARN(1, "Can't enable IRQ/MSI because no handler is installed\n");
450445f9a39bSAlex Deucher 		return -EINVAL;
450545f9a39bSAlex Deucher 	}
450645f9a39bSAlex Deucher 	/* don't enable anything if the ih is disabled */
450745f9a39bSAlex Deucher 	if (!rdev->ih.enabled) {
450845f9a39bSAlex Deucher 		r600_disable_interrupts(rdev);
450945f9a39bSAlex Deucher 		/* force the active interrupt state to all disabled */
451045f9a39bSAlex Deucher 		evergreen_disable_interrupt_state(rdev);
451145f9a39bSAlex Deucher 		return 0;
451245f9a39bSAlex Deucher 	}
451345f9a39bSAlex Deucher 
4514d70229f7SAlex Deucher 	if (rdev->family == CHIP_ARUBA)
4515d70229f7SAlex Deucher 		thermal_int = RREG32(TN_CG_THERMAL_INT_CTRL) &
4516d70229f7SAlex Deucher 			~(THERM_INT_MASK_HIGH | THERM_INT_MASK_LOW);
4517d70229f7SAlex Deucher 	else
4518dc50ba7fSAlex Deucher 		thermal_int = RREG32(CG_THERMAL_INT) &
4519dc50ba7fSAlex Deucher 			~(THERM_INT_MASK_HIGH | THERM_INT_MASK_LOW);
452045f9a39bSAlex Deucher 
4521233d1ad5SAlex Deucher 	dma_cntl = RREG32(DMA_CNTL) & ~TRAP_ENABLE;
4522233d1ad5SAlex Deucher 
45231b37078bSAlex Deucher 	if (rdev->family >= CHIP_CAYMAN) {
45241b37078bSAlex Deucher 		/* enable CP interrupts on all rings */
4525736fc37fSChristian Koenig 		if (atomic_read(&rdev->irq.ring_int[RADEON_RING_TYPE_GFX_INDEX])) {
45261b37078bSAlex Deucher 			DRM_DEBUG("evergreen_irq_set: sw int gfx\n");
45271b37078bSAlex Deucher 			cp_int_cntl |= TIME_STAMP_INT_ENABLE;
45281b37078bSAlex Deucher 		}
4529736fc37fSChristian Koenig 		if (atomic_read(&rdev->irq.ring_int[CAYMAN_RING_TYPE_CP1_INDEX])) {
45301b37078bSAlex Deucher 			DRM_DEBUG("evergreen_irq_set: sw int cp1\n");
45311b37078bSAlex Deucher 			cp_int_cntl1 |= TIME_STAMP_INT_ENABLE;
45321b37078bSAlex Deucher 		}
4533736fc37fSChristian Koenig 		if (atomic_read(&rdev->irq.ring_int[CAYMAN_RING_TYPE_CP2_INDEX])) {
45341b37078bSAlex Deucher 			DRM_DEBUG("evergreen_irq_set: sw int cp2\n");
45351b37078bSAlex Deucher 			cp_int_cntl2 |= TIME_STAMP_INT_ENABLE;
45361b37078bSAlex Deucher 		}
45371b37078bSAlex Deucher 	} else {
4538736fc37fSChristian Koenig 		if (atomic_read(&rdev->irq.ring_int[RADEON_RING_TYPE_GFX_INDEX])) {
45391b37078bSAlex Deucher 			DRM_DEBUG("evergreen_irq_set: sw int gfx\n");
454045f9a39bSAlex Deucher 			cp_int_cntl |= RB_INT_ENABLE;
4541d0f8a854SAlex Deucher 			cp_int_cntl |= TIME_STAMP_INT_ENABLE;
454245f9a39bSAlex Deucher 		}
45431b37078bSAlex Deucher 	}
45441b37078bSAlex Deucher 
4545233d1ad5SAlex Deucher 	if (atomic_read(&rdev->irq.ring_int[R600_RING_TYPE_DMA_INDEX])) {
4546233d1ad5SAlex Deucher 		DRM_DEBUG("r600_irq_set: sw int dma\n");
4547233d1ad5SAlex Deucher 		dma_cntl |= TRAP_ENABLE;
4548233d1ad5SAlex Deucher 	}
4549233d1ad5SAlex Deucher 
4550f60cbd11SAlex Deucher 	if (rdev->family >= CHIP_CAYMAN) {
4551f60cbd11SAlex Deucher 		dma_cntl1 = RREG32(CAYMAN_DMA1_CNTL) & ~TRAP_ENABLE;
4552f60cbd11SAlex Deucher 		if (atomic_read(&rdev->irq.ring_int[CAYMAN_RING_TYPE_DMA1_INDEX])) {
4553f60cbd11SAlex Deucher 			DRM_DEBUG("r600_irq_set: sw int dma1\n");
4554f60cbd11SAlex Deucher 			dma_cntl1 |= TRAP_ENABLE;
4555f60cbd11SAlex Deucher 		}
4556f60cbd11SAlex Deucher 	}
4557f60cbd11SAlex Deucher 
4558dc50ba7fSAlex Deucher 	if (rdev->irq.dpm_thermal) {
4559dc50ba7fSAlex Deucher 		DRM_DEBUG("dpm thermal\n");
4560dc50ba7fSAlex Deucher 		thermal_int |= THERM_INT_MASK_HIGH | THERM_INT_MASK_LOW;
4561dc50ba7fSAlex Deucher 	}
4562dc50ba7fSAlex Deucher 
45631b37078bSAlex Deucher 	if (rdev->family >= CHIP_CAYMAN) {
45641b37078bSAlex Deucher 		cayman_cp_int_cntl_setup(rdev, 0, cp_int_cntl);
45651b37078bSAlex Deucher 		cayman_cp_int_cntl_setup(rdev, 1, cp_int_cntl1);
45661b37078bSAlex Deucher 		cayman_cp_int_cntl_setup(rdev, 2, cp_int_cntl2);
45671b37078bSAlex Deucher 	} else
456845f9a39bSAlex Deucher 		WREG32(CP_INT_CNTL, cp_int_cntl);
4569233d1ad5SAlex Deucher 
4570233d1ad5SAlex Deucher 	WREG32(DMA_CNTL, dma_cntl);
4571233d1ad5SAlex Deucher 
4572f60cbd11SAlex Deucher 	if (rdev->family >= CHIP_CAYMAN)
4573f60cbd11SAlex Deucher 		WREG32(CAYMAN_DMA1_CNTL, dma_cntl1);
4574f60cbd11SAlex Deucher 
45752031f77cSAlex Deucher 	WREG32(GRBM_INT_CNTL, grbm_int_cntl);
457645f9a39bSAlex Deucher 
45774cd096ddSLyude 	for (i = 0; i < rdev->num_crtc; i++) {
45784cd096ddSLyude 		radeon_irq_kms_set_irq_n_enabled(
45794cd096ddSLyude 		    rdev, INT_MASK + crtc_offsets[i],
45804cd096ddSLyude 		    VBLANK_INT_MASK,
45814cd096ddSLyude 		    rdev->irq.crtc_vblank_int[i] ||
45824cd096ddSLyude 		    atomic_read(&rdev->irq.pflip[i]), "vblank", i);
458318007401SAlex Deucher 	}
458445f9a39bSAlex Deucher 
458598990faeSLyude 	for (i = 0; i < rdev->num_crtc; i++)
458698990faeSLyude 		WREG32(GRPH_INT_CONTROL + crtc_offsets[i], GRPH_PFLIP_INT_MASK);
45876f34be50SAlex Deucher 
45884cd096ddSLyude 	for (i = 0; i < 6; i++) {
45894cd096ddSLyude 		radeon_irq_kms_set_irq_n_enabled(
45904cd096ddSLyude 		    rdev, DC_HPDx_INT_CONTROL(i),
45914cd096ddSLyude 		    DC_HPDx_INT_EN | DC_HPDx_RX_INT_EN,
45924cd096ddSLyude 		    rdev->irq.hpd[i], "HPD", i);
45934cd096ddSLyude 	}
45944cd096ddSLyude 
4595d70229f7SAlex Deucher 	if (rdev->family == CHIP_ARUBA)
4596d70229f7SAlex Deucher 		WREG32(TN_CG_THERMAL_INT_CTRL, thermal_int);
4597d70229f7SAlex Deucher 	else
4598dc50ba7fSAlex Deucher 		WREG32(CG_THERMAL_INT, thermal_int);
459945f9a39bSAlex Deucher 
46005cc4e5fcSLyude 	for (i = 0; i < 6; i++) {
46015cc4e5fcSLyude 		radeon_irq_kms_set_irq_n_enabled(
46025cc4e5fcSLyude 		    rdev, AFMT_AUDIO_PACKET_CONTROL + crtc_offsets[i],
46035cc4e5fcSLyude 		    AFMT_AZ_FORMAT_WTRIG_MASK,
46045cc4e5fcSLyude 		    rdev->irq.afmt[i], "HDMI", i);
46055cc4e5fcSLyude 	}
4606f122c610SAlex Deucher 
4607c320bb5fSAlex Deucher 	/* posting read */
4608c320bb5fSAlex Deucher 	RREG32(SRBM_STATUS);
4609c320bb5fSAlex Deucher 
461045f9a39bSAlex Deucher 	return 0;
461145f9a39bSAlex Deucher }
461245f9a39bSAlex Deucher 
46134cd096ddSLyude /* Note that the order we write back regs here is important */
evergreen_irq_ack(struct radeon_device * rdev)4614cbdd4501SAndi Kleen static void evergreen_irq_ack(struct radeon_device *rdev)
461545f9a39bSAlex Deucher {
461698990faeSLyude 	int i, j;
461798990faeSLyude 	u32 *grph_int = rdev->irq.stat_regs.evergreen.grph_int;
46184cd096ddSLyude 	u32 *disp_int = rdev->irq.stat_regs.evergreen.disp_int;
46195cc4e5fcSLyude 	u32 *afmt_status = rdev->irq.stat_regs.evergreen.afmt_status;
462045f9a39bSAlex Deucher 
46215cc4e5fcSLyude 	for (i = 0; i < 6; i++) {
46224cd096ddSLyude 		disp_int[i] = RREG32(evergreen_disp_int_status[i]);
46235cc4e5fcSLyude 		afmt_status[i] = RREG32(AFMT_STATUS + crtc_offsets[i]);
462498990faeSLyude 		if (i < rdev->num_crtc)
462598990faeSLyude 			grph_int[i] = RREG32(GRPH_INT_STATUS + crtc_offsets[i]);
46265cc4e5fcSLyude 	}
46274cd096ddSLyude 
462898990faeSLyude 	/* We write back each interrupt register in pairs of two */
462998990faeSLyude 	for (i = 0; i < rdev->num_crtc; i += 2) {
463098990faeSLyude 		for (j = i; j < (i + 2); j++) {
463198990faeSLyude 			if (grph_int[j] & GRPH_PFLIP_INT_OCCURRED)
463298990faeSLyude 				WREG32(GRPH_INT_STATUS + crtc_offsets[j],
463398990faeSLyude 				       GRPH_PFLIP_INT_CLEAR);
4634b7eff394SAlex Deucher 		}
463545f9a39bSAlex Deucher 
463698990faeSLyude 		for (j = i; j < (i + 2); j++) {
463798990faeSLyude 			if (disp_int[j] & LB_D1_VBLANK_INTERRUPT)
463898990faeSLyude 				WREG32(VBLANK_STATUS + crtc_offsets[j],
463998990faeSLyude 				       VBLANK_ACK);
464098990faeSLyude 			if (disp_int[j] & LB_D1_VLINE_INTERRUPT)
464198990faeSLyude 				WREG32(VLINE_STATUS + crtc_offsets[j],
464298990faeSLyude 				       VLINE_ACK);
4643b7eff394SAlex Deucher 		}
4644b7eff394SAlex Deucher 	}
464545f9a39bSAlex Deucher 
46464cd096ddSLyude 	for (i = 0; i < 6; i++) {
46474cd096ddSLyude 		if (disp_int[i] & DC_HPD1_INTERRUPT)
46484cd096ddSLyude 			WREG32_OR(DC_HPDx_INT_CONTROL(i), DC_HPDx_INT_ACK);
464945f9a39bSAlex Deucher 	}
46502bc67b4dSDave Airlie 
46514cd096ddSLyude 	for (i = 0; i < 6; i++) {
46524cd096ddSLyude 		if (disp_int[i] & DC_HPD1_RX_INTERRUPT)
46534cd096ddSLyude 			WREG32_OR(DC_HPDx_INT_CONTROL(i), DC_HPDx_RX_INT_ACK);
46542bc67b4dSDave Airlie 	}
46552bc67b4dSDave Airlie 
46565cc4e5fcSLyude 	for (i = 0; i < 6; i++) {
46575cc4e5fcSLyude 		if (afmt_status[i] & AFMT_AZ_FORMAT_WTRIG)
46585cc4e5fcSLyude 			WREG32_OR(AFMT_AUDIO_PACKET_CONTROL + crtc_offsets[i],
46595cc4e5fcSLyude 				  AFMT_AZ_FORMAT_WTRIG_ACK);
4660f122c610SAlex Deucher 	}
466145f9a39bSAlex Deucher }
466245f9a39bSAlex Deucher 
evergreen_irq_disable(struct radeon_device * rdev)46631109ca09SLauri Kasanen static void evergreen_irq_disable(struct radeon_device *rdev)
466445f9a39bSAlex Deucher {
466545f9a39bSAlex Deucher 	r600_disable_interrupts(rdev);
466645f9a39bSAlex Deucher 	/* Wait and acknowledge irq */
466745f9a39bSAlex Deucher 	mdelay(1);
46686f34be50SAlex Deucher 	evergreen_irq_ack(rdev);
466945f9a39bSAlex Deucher 	evergreen_disable_interrupt_state(rdev);
467045f9a39bSAlex Deucher }
467145f9a39bSAlex Deucher 
evergreen_irq_suspend(struct radeon_device * rdev)4672755d819eSAlex Deucher void evergreen_irq_suspend(struct radeon_device *rdev)
467345f9a39bSAlex Deucher {
467445f9a39bSAlex Deucher 	evergreen_irq_disable(rdev);
467545f9a39bSAlex Deucher 	r600_rlc_stop(rdev);
467645f9a39bSAlex Deucher }
467745f9a39bSAlex Deucher 
evergreen_get_ih_wptr(struct radeon_device * rdev)4678cbdd4501SAndi Kleen static u32 evergreen_get_ih_wptr(struct radeon_device *rdev)
467945f9a39bSAlex Deucher {
468045f9a39bSAlex Deucher 	u32 wptr, tmp;
468145f9a39bSAlex Deucher 
4682724c80e1SAlex Deucher 	if (rdev->wb.enabled)
4683204ae24dSCédric Cano 		wptr = le32_to_cpu(rdev->wb.wb[R600_WB_IH_WPTR_OFFSET/4]);
4684724c80e1SAlex Deucher 	else
468545f9a39bSAlex Deucher 		wptr = RREG32(IH_RB_WPTR);
468645f9a39bSAlex Deucher 
468745f9a39bSAlex Deucher 	if (wptr & RB_OVERFLOW) {
468811bab0aeSMichel Dänzer 		wptr &= ~RB_OVERFLOW;
468945f9a39bSAlex Deucher 		/* When a ring buffer overflow happen start parsing interrupt
469045f9a39bSAlex Deucher 		 * from the last not overwritten vector (wptr + 16). Hopefully
469145f9a39bSAlex Deucher 		 * this should allow us to catchup.
469245f9a39bSAlex Deucher 		 */
46936cc2fda2SMichel Dänzer 		dev_warn(rdev->dev, "IH ring buffer overflow (0x%08X, 0x%08X, 0x%08X)\n",
46946cc2fda2SMichel Dänzer 			 wptr, rdev->ih.rptr, (wptr + 16) & rdev->ih.ptr_mask);
469545f9a39bSAlex Deucher 		rdev->ih.rptr = (wptr + 16) & rdev->ih.ptr_mask;
469645f9a39bSAlex Deucher 		tmp = RREG32(IH_RB_CNTL);
469745f9a39bSAlex Deucher 		tmp |= IH_WPTR_OVERFLOW_CLEAR;
469845f9a39bSAlex Deucher 		WREG32(IH_RB_CNTL, tmp);
469945f9a39bSAlex Deucher 	}
470045f9a39bSAlex Deucher 	return (wptr & rdev->ih.ptr_mask);
470145f9a39bSAlex Deucher }
470245f9a39bSAlex Deucher 
evergreen_irq_process(struct radeon_device * rdev)470345f9a39bSAlex Deucher int evergreen_irq_process(struct radeon_device *rdev)
470445f9a39bSAlex Deucher {
47054cd096ddSLyude 	u32 *disp_int = rdev->irq.stat_regs.evergreen.disp_int;
47065cc4e5fcSLyude 	u32 *afmt_status = rdev->irq.stat_regs.evergreen.afmt_status;
47075cc4e5fcSLyude 	u32 crtc_idx, hpd_idx, afmt_idx;
47084cd096ddSLyude 	u32 mask;
4709682f1a54SDave Airlie 	u32 wptr;
4710682f1a54SDave Airlie 	u32 rptr;
471145f9a39bSAlex Deucher 	u32 src_id, src_data;
471245f9a39bSAlex Deucher 	u32 ring_index;
471345f9a39bSAlex Deucher 	bool queue_hotplug = false;
4714f122c610SAlex Deucher 	bool queue_hdmi = false;
47152bc67b4dSDave Airlie 	bool queue_dp = false;
4716dc50ba7fSAlex Deucher 	bool queue_thermal = false;
471754e2e49cSAlex Deucher 	u32 status, addr;
47184cd096ddSLyude 	const char *event_name;
471945f9a39bSAlex Deucher 
4720682f1a54SDave Airlie 	if (!rdev->ih.enabled || rdev->shutdown)
472145f9a39bSAlex Deucher 		return IRQ_NONE;
472245f9a39bSAlex Deucher 
4723682f1a54SDave Airlie 	wptr = evergreen_get_ih_wptr(rdev);
4724c20dc369SChristian Koenig 
4725c20dc369SChristian Koenig restart_ih:
4726c20dc369SChristian Koenig 	/* is somebody else already processing irqs? */
4727c20dc369SChristian Koenig 	if (atomic_xchg(&rdev->ih.lock, 1))
4728c20dc369SChristian Koenig 		return IRQ_NONE;
4729c20dc369SChristian Koenig 
4730682f1a54SDave Airlie 	rptr = rdev->ih.rptr;
473107f18f0bSMario Kleiner 	DRM_DEBUG("evergreen_irq_process start: rptr %d, wptr %d\n", rptr, wptr);
473245f9a39bSAlex Deucher 
4733964f6645SBenjamin Herrenschmidt 	/* Order reading of wptr vs. reading of IH ring data */
4734964f6645SBenjamin Herrenschmidt 	rmb();
4735964f6645SBenjamin Herrenschmidt 
473645f9a39bSAlex Deucher 	/* display interrupts */
47376f34be50SAlex Deucher 	evergreen_irq_ack(rdev);
473845f9a39bSAlex Deucher 
473945f9a39bSAlex Deucher 	while (rptr != wptr) {
474045f9a39bSAlex Deucher 		/* wptr/rptr are in bytes! */
474145f9a39bSAlex Deucher 		ring_index = rptr / 4;
47420f234f5fSAlex Deucher 		src_id =  le32_to_cpu(rdev->ih.ring[ring_index]) & 0xff;
47430f234f5fSAlex Deucher 		src_data = le32_to_cpu(rdev->ih.ring[ring_index + 1]) & 0xfffffff;
474445f9a39bSAlex Deucher 
474545f9a39bSAlex Deucher 		switch (src_id) {
474645f9a39bSAlex Deucher 		case 1: /* D1 vblank/vline */
474745f9a39bSAlex Deucher 		case 2: /* D2 vblank/vline */
474845f9a39bSAlex Deucher 		case 3: /* D3 vblank/vline */
474945f9a39bSAlex Deucher 		case 4: /* D4 vblank/vline */
475045f9a39bSAlex Deucher 		case 5: /* D5 vblank/vline */
475145f9a39bSAlex Deucher 		case 6: /* D6 vblank/vline */
47524cd096ddSLyude 			crtc_idx = src_id - 1;
475307f18f0bSMario Kleiner 
47544cd096ddSLyude 			if (src_data == 0) { /* vblank */
47554cd096ddSLyude 				mask = LB_D1_VBLANK_INTERRUPT;
47564cd096ddSLyude 				event_name = "vblank";
47574cd096ddSLyude 
47584cd096ddSLyude 				if (rdev->irq.crtc_vblank_int[crtc_idx]) {
4759*5e3a0f77SWu Hoi Pok 					drm_handle_vblank(rdev_to_drm(rdev), crtc_idx);
4760f5d8e0ebSAlex Deucher 					rdev->pm.vblank_sync = true;
476145f9a39bSAlex Deucher 					wake_up(&rdev->irq.vblank_queue);
47626f34be50SAlex Deucher 				}
47634cd096ddSLyude 				if (atomic_read(&rdev->irq.pflip[crtc_idx])) {
47644cd096ddSLyude 					radeon_crtc_handle_vblank(rdev,
47654cd096ddSLyude 								  crtc_idx);
47664cd096ddSLyude 				}
476707f18f0bSMario Kleiner 
47684cd096ddSLyude 			} else if (src_data == 1) { /* vline */
47694cd096ddSLyude 				mask = LB_D1_VLINE_INTERRUPT;
47704cd096ddSLyude 				event_name = "vline";
47714cd096ddSLyude 			} else {
47724cd096ddSLyude 				DRM_DEBUG("Unhandled interrupt: %d %d\n",
47734cd096ddSLyude 					  src_id, src_data);
477445f9a39bSAlex Deucher 				break;
477545f9a39bSAlex Deucher 			}
47764cd096ddSLyude 
47774cd096ddSLyude 			if (!(disp_int[crtc_idx] & mask)) {
47784cd096ddSLyude 				DRM_DEBUG("IH: D%d %s - IH event w/o asserted irq bit?\n",
47794cd096ddSLyude 					  crtc_idx + 1, event_name);
47804cd096ddSLyude 			}
47814cd096ddSLyude 
47824cd096ddSLyude 			disp_int[crtc_idx] &= ~mask;
47834cd096ddSLyude 			DRM_DEBUG("IH: D%d %s\n", crtc_idx + 1, event_name);
47844cd096ddSLyude 
478545f9a39bSAlex Deucher 			break;
4786f5d636d2SChristian König 		case 8: /* D1 page flip */
4787f5d636d2SChristian König 		case 10: /* D2 page flip */
4788f5d636d2SChristian König 		case 12: /* D3 page flip */
4789f5d636d2SChristian König 		case 14: /* D4 page flip */
4790f5d636d2SChristian König 		case 16: /* D5 page flip */
4791f5d636d2SChristian König 		case 18: /* D6 page flip */
4792f5d636d2SChristian König 			DRM_DEBUG("IH: D%d flip\n", ((src_id - 8) >> 1) + 1);
479339dc5454SMario Kleiner 			if (radeon_use_pflipirq > 0)
4794f5d636d2SChristian König 				radeon_crtc_handle_flip(rdev, (src_id - 8) >> 1);
4795f5d636d2SChristian König 			break;
479645f9a39bSAlex Deucher 		case 42: /* HPD hotplug */
47974cd096ddSLyude 			if (src_data <= 5) {
47984cd096ddSLyude 				hpd_idx = src_data;
47994cd096ddSLyude 				mask = DC_HPD1_INTERRUPT;
480045f9a39bSAlex Deucher 				queue_hotplug = true;
48014cd096ddSLyude 				event_name = "HPD";
480207f18f0bSMario Kleiner 
48034cd096ddSLyude 			} else if (src_data <= 11) {
48044cd096ddSLyude 				hpd_idx = src_data - 6;
48054cd096ddSLyude 				mask = DC_HPD1_RX_INTERRUPT;
48062bc67b4dSDave Airlie 				queue_dp = true;
48074cd096ddSLyude 				event_name = "HPD_RX";
480807f18f0bSMario Kleiner 
48094cd096ddSLyude 			} else {
48104cd096ddSLyude 				DRM_DEBUG("Unhandled interrupt: %d %d\n",
48114cd096ddSLyude 					  src_id, src_data);
481245f9a39bSAlex Deucher 				break;
481345f9a39bSAlex Deucher 			}
48144cd096ddSLyude 
48154cd096ddSLyude 			if (!(disp_int[hpd_idx] & mask))
48164cd096ddSLyude 				DRM_DEBUG("IH: IH event w/o asserted irq bit?\n");
48174cd096ddSLyude 
48184cd096ddSLyude 			disp_int[hpd_idx] &= ~mask;
48194cd096ddSLyude 			DRM_DEBUG("IH: %s%d\n", event_name, hpd_idx + 1);
48204cd096ddSLyude 
482145f9a39bSAlex Deucher 			break;
4822f122c610SAlex Deucher 		case 44: /* hdmi */
48235cc4e5fcSLyude 			afmt_idx = src_data;
48245cc4e5fcSLyude 			if (afmt_idx > 5) {
48255cc4e5fcSLyude 				DRM_ERROR("Unhandled interrupt: %d %d\n",
48265cc4e5fcSLyude 					  src_id, src_data);
4827f122c610SAlex Deucher 				break;
4828f122c610SAlex Deucher 			}
482919534a7aSKonstantin Meskhidze 
483019534a7aSKonstantin Meskhidze 			if (!(afmt_status[afmt_idx] & AFMT_AZ_FORMAT_WTRIG))
483119534a7aSKonstantin Meskhidze 				DRM_DEBUG("IH: IH event w/o asserted irq bit?\n");
483219534a7aSKonstantin Meskhidze 
48335cc4e5fcSLyude 			afmt_status[afmt_idx] &= ~AFMT_AZ_FORMAT_WTRIG;
48345cc4e5fcSLyude 			queue_hdmi = true;
48355cc4e5fcSLyude 			DRM_DEBUG("IH: HDMI%d\n", afmt_idx + 1);
48365cc4e5fcSLyude 			break;
4837acc1522aSChristian König 		case 96:
4838acc1522aSChristian König 			DRM_ERROR("SRBM_READ_ERROR: 0x%x\n", RREG32(SRBM_READ_ERROR));
4839acc1522aSChristian König 			WREG32(SRBM_INT_ACK, 0x1);
4840acc1522aSChristian König 			break;
4841f2ba57b5SChristian König 		case 124: /* UVD */
4842f2ba57b5SChristian König 			DRM_DEBUG("IH: UVD int: 0x%08x\n", src_data);
4843f2ba57b5SChristian König 			radeon_fence_process(rdev, R600_RING_TYPE_UVD_INDEX);
4844f122c610SAlex Deucher 			break;
4845ae133a11SChristian König 		case 146:
4846ae133a11SChristian König 		case 147:
484754e2e49cSAlex Deucher 			addr = RREG32(VM_CONTEXT1_PROTECTION_FAULT_ADDR);
484854e2e49cSAlex Deucher 			status = RREG32(VM_CONTEXT1_PROTECTION_FAULT_STATUS);
48499b7d786bSChristian König 			/* reset addr and status */
48509b7d786bSChristian König 			WREG32_P(VM_CONTEXT1_CNTL2, 1, ~1);
48519b7d786bSChristian König 			if (addr == 0x0 && status == 0x0)
48529b7d786bSChristian König 				break;
4853ae133a11SChristian König 			dev_err(rdev->dev, "GPU fault detected: %d 0x%08x\n", src_id, src_data);
4854ae133a11SChristian König 			dev_err(rdev->dev, "  VM_CONTEXT1_PROTECTION_FAULT_ADDR   0x%08X\n",
485554e2e49cSAlex Deucher 				addr);
4856ae133a11SChristian König 			dev_err(rdev->dev, "  VM_CONTEXT1_PROTECTION_FAULT_STATUS 0x%08X\n",
485754e2e49cSAlex Deucher 				status);
485854e2e49cSAlex Deucher 			cayman_vm_decode_fault(rdev, status, addr);
4859ae133a11SChristian König 			break;
486045f9a39bSAlex Deucher 		case 176: /* CP_INT in ring buffer */
486145f9a39bSAlex Deucher 		case 177: /* CP_INT in IB1 */
486245f9a39bSAlex Deucher 		case 178: /* CP_INT in IB2 */
486345f9a39bSAlex Deucher 			DRM_DEBUG("IH: CP int: 0x%08x\n", src_data);
48647465280cSAlex Deucher 			radeon_fence_process(rdev, RADEON_RING_TYPE_GFX_INDEX);
486545f9a39bSAlex Deucher 			break;
486645f9a39bSAlex Deucher 		case 181: /* CP EOP event */
486745f9a39bSAlex Deucher 			DRM_DEBUG("IH: CP EOP\n");
48681b37078bSAlex Deucher 			if (rdev->family >= CHIP_CAYMAN) {
48691b37078bSAlex Deucher 				switch (src_data) {
48701b37078bSAlex Deucher 				case 0:
48711b37078bSAlex Deucher 					radeon_fence_process(rdev, RADEON_RING_TYPE_GFX_INDEX);
48721b37078bSAlex Deucher 					break;
48731b37078bSAlex Deucher 				case 1:
48741b37078bSAlex Deucher 					radeon_fence_process(rdev, CAYMAN_RING_TYPE_CP1_INDEX);
48751b37078bSAlex Deucher 					break;
48761b37078bSAlex Deucher 				case 2:
48771b37078bSAlex Deucher 					radeon_fence_process(rdev, CAYMAN_RING_TYPE_CP2_INDEX);
48781b37078bSAlex Deucher 					break;
48791b37078bSAlex Deucher 				}
48801b37078bSAlex Deucher 			} else
48817465280cSAlex Deucher 				radeon_fence_process(rdev, RADEON_RING_TYPE_GFX_INDEX);
488245f9a39bSAlex Deucher 			break;
4883233d1ad5SAlex Deucher 		case 224: /* DMA trap event */
4884233d1ad5SAlex Deucher 			DRM_DEBUG("IH: DMA trap\n");
4885233d1ad5SAlex Deucher 			radeon_fence_process(rdev, R600_RING_TYPE_DMA_INDEX);
4886233d1ad5SAlex Deucher 			break;
4887dc50ba7fSAlex Deucher 		case 230: /* thermal low to high */
4888dc50ba7fSAlex Deucher 			DRM_DEBUG("IH: thermal low to high\n");
4889dc50ba7fSAlex Deucher 			rdev->pm.dpm.thermal.high_to_low = false;
4890dc50ba7fSAlex Deucher 			queue_thermal = true;
4891dc50ba7fSAlex Deucher 			break;
4892dc50ba7fSAlex Deucher 		case 231: /* thermal high to low */
4893dc50ba7fSAlex Deucher 			DRM_DEBUG("IH: thermal high to low\n");
4894dc50ba7fSAlex Deucher 			rdev->pm.dpm.thermal.high_to_low = true;
4895dc50ba7fSAlex Deucher 			queue_thermal = true;
4896dc50ba7fSAlex Deucher 			break;
48972031f77cSAlex Deucher 		case 233: /* GUI IDLE */
4898303c805cSIlija Hadzic 			DRM_DEBUG("IH: GUI idle\n");
48992031f77cSAlex Deucher 			break;
4900f60cbd11SAlex Deucher 		case 244: /* DMA trap event */
4901f60cbd11SAlex Deucher 			if (rdev->family >= CHIP_CAYMAN) {
4902f60cbd11SAlex Deucher 				DRM_DEBUG("IH: DMA1 trap\n");
4903f60cbd11SAlex Deucher 				radeon_fence_process(rdev, CAYMAN_RING_TYPE_DMA1_INDEX);
4904f60cbd11SAlex Deucher 			}
4905f60cbd11SAlex Deucher 			break;
490645f9a39bSAlex Deucher 		default:
490745f9a39bSAlex Deucher 			DRM_DEBUG("Unhandled interrupt: %d %d\n", src_id, src_data);
490845f9a39bSAlex Deucher 			break;
490945f9a39bSAlex Deucher 		}
491045f9a39bSAlex Deucher 
491145f9a39bSAlex Deucher 		/* wptr/rptr are in bytes! */
491245f9a39bSAlex Deucher 		rptr += 16;
491345f9a39bSAlex Deucher 		rptr &= rdev->ih.ptr_mask;
4914f55e03b9SMichel Dänzer 		WREG32(IH_RB_RPTR, rptr);
491545f9a39bSAlex Deucher 	}
49162bc67b4dSDave Airlie 	if (queue_dp)
49172bc67b4dSDave Airlie 		schedule_work(&rdev->dp_work);
491845f9a39bSAlex Deucher 	if (queue_hotplug)
4919cb5d4166SLyude 		schedule_delayed_work(&rdev->hotplug_work, 0);
4920f122c610SAlex Deucher 	if (queue_hdmi)
4921f122c610SAlex Deucher 		schedule_work(&rdev->audio_work);
4922dc50ba7fSAlex Deucher 	if (queue_thermal && rdev->pm.dpm_enabled)
4923dc50ba7fSAlex Deucher 		schedule_work(&rdev->pm.dpm.thermal.work);
492445f9a39bSAlex Deucher 	rdev->ih.rptr = rptr;
4925c20dc369SChristian Koenig 	atomic_set(&rdev->ih.lock, 0);
4926c20dc369SChristian Koenig 
4927c20dc369SChristian Koenig 	/* make sure wptr hasn't changed while processing */
4928c20dc369SChristian Koenig 	wptr = evergreen_get_ih_wptr(rdev);
4929c20dc369SChristian Koenig 	if (wptr != rptr)
4930c20dc369SChristian Koenig 		goto restart_ih;
4931c20dc369SChristian Koenig 
493245f9a39bSAlex Deucher 	return IRQ_HANDLED;
493345f9a39bSAlex Deucher }
4934bcc1c2a1SAlex Deucher 
evergreen_uvd_init(struct radeon_device * rdev)4935d78d6f39SJérome Glisse static void evergreen_uvd_init(struct radeon_device *rdev)
4936d78d6f39SJérome Glisse {
4937d78d6f39SJérome Glisse 	int r;
4938d78d6f39SJérome Glisse 
4939d78d6f39SJérome Glisse 	if (!rdev->has_uvd)
4940d78d6f39SJérome Glisse 		return;
4941d78d6f39SJérome Glisse 
4942d78d6f39SJérome Glisse 	r = radeon_uvd_init(rdev);
4943d78d6f39SJérome Glisse 	if (r) {
4944d78d6f39SJérome Glisse 		dev_err(rdev->dev, "failed UVD (%d) init.\n", r);
4945d78d6f39SJérome Glisse 		/*
4946d78d6f39SJérome Glisse 		 * At this point rdev->uvd.vcpu_bo is NULL which trickles down
4947d78d6f39SJérome Glisse 		 * to early fails uvd_v2_2_resume() and thus nothing happens
4948d78d6f39SJérome Glisse 		 * there. So it is pointless to try to go through that code
4949d78d6f39SJérome Glisse 		 * hence why we disable uvd here.
4950d78d6f39SJérome Glisse 		 */
4951f30abb96Szhengbin 		rdev->has_uvd = false;
4952d78d6f39SJérome Glisse 		return;
4953d78d6f39SJérome Glisse 	}
4954d78d6f39SJérome Glisse 	rdev->ring[R600_RING_TYPE_UVD_INDEX].ring_obj = NULL;
4955d78d6f39SJérome Glisse 	r600_ring_init(rdev, &rdev->ring[R600_RING_TYPE_UVD_INDEX], 4096);
4956d78d6f39SJérome Glisse }
4957d78d6f39SJérome Glisse 
evergreen_uvd_start(struct radeon_device * rdev)4958d78d6f39SJérome Glisse static void evergreen_uvd_start(struct radeon_device *rdev)
4959d78d6f39SJérome Glisse {
4960d78d6f39SJérome Glisse 	int r;
4961d78d6f39SJérome Glisse 
4962d78d6f39SJérome Glisse 	if (!rdev->has_uvd)
4963d78d6f39SJérome Glisse 		return;
4964d78d6f39SJérome Glisse 
4965d78d6f39SJérome Glisse 	r = uvd_v2_2_resume(rdev);
4966d78d6f39SJérome Glisse 	if (r) {
4967d78d6f39SJérome Glisse 		dev_err(rdev->dev, "failed UVD resume (%d).\n", r);
4968d78d6f39SJérome Glisse 		goto error;
4969d78d6f39SJérome Glisse 	}
4970d78d6f39SJérome Glisse 	r = radeon_fence_driver_start_ring(rdev, R600_RING_TYPE_UVD_INDEX);
4971d78d6f39SJérome Glisse 	if (r) {
4972d78d6f39SJérome Glisse 		dev_err(rdev->dev, "failed initializing UVD fences (%d).\n", r);
4973d78d6f39SJérome Glisse 		goto error;
4974d78d6f39SJérome Glisse 	}
4975d78d6f39SJérome Glisse 	return;
4976d78d6f39SJérome Glisse 
4977d78d6f39SJérome Glisse error:
4978d78d6f39SJérome Glisse 	rdev->ring[R600_RING_TYPE_UVD_INDEX].ring_size = 0;
4979d78d6f39SJérome Glisse }
4980d78d6f39SJérome Glisse 
evergreen_uvd_resume(struct radeon_device * rdev)4981d78d6f39SJérome Glisse static void evergreen_uvd_resume(struct radeon_device *rdev)
4982d78d6f39SJérome Glisse {
4983d78d6f39SJérome Glisse 	struct radeon_ring *ring;
4984d78d6f39SJérome Glisse 	int r;
4985d78d6f39SJérome Glisse 
4986d78d6f39SJérome Glisse 	if (!rdev->has_uvd || !rdev->ring[R600_RING_TYPE_UVD_INDEX].ring_size)
4987d78d6f39SJérome Glisse 		return;
4988d78d6f39SJérome Glisse 
4989d78d6f39SJérome Glisse 	ring = &rdev->ring[R600_RING_TYPE_UVD_INDEX];
499070a033d2SAlex Deucher 	r = radeon_ring_init(rdev, ring, ring->ring_size, 0, PACKET0(UVD_NO_OP, 0));
4991d78d6f39SJérome Glisse 	if (r) {
4992d78d6f39SJérome Glisse 		dev_err(rdev->dev, "failed initializing UVD ring (%d).\n", r);
4993d78d6f39SJérome Glisse 		return;
4994d78d6f39SJérome Glisse 	}
4995d78d6f39SJérome Glisse 	r = uvd_v1_0_init(rdev);
4996d78d6f39SJérome Glisse 	if (r) {
4997d78d6f39SJérome Glisse 		dev_err(rdev->dev, "failed initializing UVD (%d).\n", r);
4998d78d6f39SJérome Glisse 		return;
4999d78d6f39SJérome Glisse 	}
5000d78d6f39SJérome Glisse }
5001d78d6f39SJérome Glisse 
evergreen_startup(struct radeon_device * rdev)5002bcc1c2a1SAlex Deucher static int evergreen_startup(struct radeon_device *rdev)
5003bcc1c2a1SAlex Deucher {
5004f2ba57b5SChristian König 	struct radeon_ring *ring;
5005bcc1c2a1SAlex Deucher 	int r;
5006bcc1c2a1SAlex Deucher 
50079e46a48dSAlex Deucher 	/* enable pcie gen2 link */
50089e46a48dSAlex Deucher 	evergreen_pcie_gen2_enable(rdev);
5009f52382d7SAlex Deucher 	/* enable aspm */
5010f52382d7SAlex Deucher 	evergreen_program_aspm(rdev);
50119e46a48dSAlex Deucher 
5012e5903d39SAlex Deucher 	/* scratch needs to be initialized before MC */
5013e5903d39SAlex Deucher 	r = r600_vram_scratch_init(rdev);
5014e5903d39SAlex Deucher 	if (r)
5015e5903d39SAlex Deucher 		return r;
5016e5903d39SAlex Deucher 
50176fab3febSAlex Deucher 	evergreen_mc_program(rdev);
50186fab3febSAlex Deucher 
50196c7bcceaSAlex Deucher 	if (ASIC_IS_DCE5(rdev) && !rdev->pm.dpm_enabled) {
5020755d819eSAlex Deucher 		r = ni_mc_load_microcode(rdev);
50210af62b01SAlex Deucher 		if (r) {
50220af62b01SAlex Deucher 			DRM_ERROR("Failed to load MC firmware!\n");
50230af62b01SAlex Deucher 			return r;
50240af62b01SAlex Deucher 		}
50250af62b01SAlex Deucher 	}
5026fe251e2fSAlex Deucher 
5027bcc1c2a1SAlex Deucher 	if (rdev->flags & RADEON_IS_AGP) {
50280fcdb61eSAlex Deucher 		evergreen_agp_enable(rdev);
5029bcc1c2a1SAlex Deucher 	} else {
5030bcc1c2a1SAlex Deucher 		r = evergreen_pcie_gart_enable(rdev);
5031bcc1c2a1SAlex Deucher 		if (r)
5032bcc1c2a1SAlex Deucher 			return r;
5033bcc1c2a1SAlex Deucher 	}
5034bcc1c2a1SAlex Deucher 	evergreen_gpu_init(rdev);
5035bcc1c2a1SAlex Deucher 
50362948f5e6SAlex Deucher 	/* allocate rlc buffers */
50372948f5e6SAlex Deucher 	if (rdev->flags & RADEON_IS_IGP) {
50382948f5e6SAlex Deucher 		rdev->rlc.reg_list = sumo_rlc_save_restore_register_list;
50391fd11777SAlex Deucher 		rdev->rlc.reg_list_size =
50401fd11777SAlex Deucher 			(u32)ARRAY_SIZE(sumo_rlc_save_restore_register_list);
50412948f5e6SAlex Deucher 		rdev->rlc.cs_data = evergreen_cs_data;
50422948f5e6SAlex Deucher 		r = sumo_rlc_init(rdev);
50432948f5e6SAlex Deucher 		if (r) {
50442948f5e6SAlex Deucher 			DRM_ERROR("Failed to init rlc BOs!\n");
50452948f5e6SAlex Deucher 			return r;
50462948f5e6SAlex Deucher 		}
50472948f5e6SAlex Deucher 	}
50482948f5e6SAlex Deucher 
5049724c80e1SAlex Deucher 	/* allocate wb buffer */
5050724c80e1SAlex Deucher 	r = radeon_wb_init(rdev);
5051724c80e1SAlex Deucher 	if (r)
5052724c80e1SAlex Deucher 		return r;
5053724c80e1SAlex Deucher 
505430eb77f4SJerome Glisse 	r = radeon_fence_driver_start_ring(rdev, RADEON_RING_TYPE_GFX_INDEX);
505530eb77f4SJerome Glisse 	if (r) {
505630eb77f4SJerome Glisse 		dev_err(rdev->dev, "failed initializing CP fences (%d).\n", r);
505730eb77f4SJerome Glisse 		return r;
505830eb77f4SJerome Glisse 	}
505930eb77f4SJerome Glisse 
5060233d1ad5SAlex Deucher 	r = radeon_fence_driver_start_ring(rdev, R600_RING_TYPE_DMA_INDEX);
5061233d1ad5SAlex Deucher 	if (r) {
5062233d1ad5SAlex Deucher 		dev_err(rdev->dev, "failed initializing DMA fences (%d).\n", r);
5063233d1ad5SAlex Deucher 		return r;
5064233d1ad5SAlex Deucher 	}
5065233d1ad5SAlex Deucher 
5066d78d6f39SJérome Glisse 	evergreen_uvd_start(rdev);
5067f2ba57b5SChristian König 
5068bcc1c2a1SAlex Deucher 	/* Enable IRQ */
5069e49f3959SAdis Hamzić 	if (!rdev->irq.installed) {
5070e49f3959SAdis Hamzić 		r = radeon_irq_kms_init(rdev);
5071e49f3959SAdis Hamzić 		if (r)
5072e49f3959SAdis Hamzić 			return r;
5073e49f3959SAdis Hamzić 	}
5074e49f3959SAdis Hamzić 
5075bcc1c2a1SAlex Deucher 	r = r600_irq_init(rdev);
5076bcc1c2a1SAlex Deucher 	if (r) {
5077bcc1c2a1SAlex Deucher 		DRM_ERROR("radeon: IH init failed (%d).\n", r);
5078bcc1c2a1SAlex Deucher 		radeon_irq_kms_fini(rdev);
5079bcc1c2a1SAlex Deucher 		return r;
5080bcc1c2a1SAlex Deucher 	}
508145f9a39bSAlex Deucher 	evergreen_irq_set(rdev);
5082bcc1c2a1SAlex Deucher 
5083f2ba57b5SChristian König 	ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX];
5084e32eb50dSChristian König 	r = radeon_ring_init(rdev, ring, ring->ring_size, RADEON_WB_CP_RPTR_OFFSET,
50852e1e6dadSChristian König 			     RADEON_CP_PACKET2);
5086bcc1c2a1SAlex Deucher 	if (r)
5087bcc1c2a1SAlex Deucher 		return r;
5088233d1ad5SAlex Deucher 
5089233d1ad5SAlex Deucher 	ring = &rdev->ring[R600_RING_TYPE_DMA_INDEX];
5090233d1ad5SAlex Deucher 	r = radeon_ring_init(rdev, ring, ring->ring_size, R600_WB_DMA_RPTR_OFFSET,
50912e1e6dadSChristian König 			     DMA_PACKET(DMA_PACKET_NOP, 0, 0));
5092233d1ad5SAlex Deucher 	if (r)
5093233d1ad5SAlex Deucher 		return r;
5094233d1ad5SAlex Deucher 
5095bcc1c2a1SAlex Deucher 	r = evergreen_cp_load_microcode(rdev);
5096bcc1c2a1SAlex Deucher 	if (r)
5097bcc1c2a1SAlex Deucher 		return r;
5098fe251e2fSAlex Deucher 	r = evergreen_cp_resume(rdev);
5099bcc1c2a1SAlex Deucher 	if (r)
5100bcc1c2a1SAlex Deucher 		return r;
5101233d1ad5SAlex Deucher 	r = r600_dma_resume(rdev);
5102233d1ad5SAlex Deucher 	if (r)
5103233d1ad5SAlex Deucher 		return r;
5104fe251e2fSAlex Deucher 
5105d78d6f39SJérome Glisse 	evergreen_uvd_resume(rdev);
5106f2ba57b5SChristian König 
51072898c348SChristian König 	r = radeon_ib_pool_init(rdev);
51082898c348SChristian König 	if (r) {
51092898c348SChristian König 		dev_err(rdev->dev, "IB initialization failed (%d).\n", r);
5110b15ba512SJerome Glisse 		return r;
51112898c348SChristian König 	}
5112b15ba512SJerome Glisse 
5113bfc1f97dSSlava Grigorev 	r = radeon_audio_init(rdev);
511469d2ae57SRafał Miłecki 	if (r) {
511569d2ae57SRafał Miłecki 		DRM_ERROR("radeon: audio init failed\n");
5116b15ba512SJerome Glisse 		return r;
5117b15ba512SJerome Glisse 	}
5118b15ba512SJerome Glisse 
5119bcc1c2a1SAlex Deucher 	return 0;
5120bcc1c2a1SAlex Deucher }
5121bcc1c2a1SAlex Deucher 
evergreen_resume(struct radeon_device * rdev)5122bcc1c2a1SAlex Deucher int evergreen_resume(struct radeon_device *rdev)
5123bcc1c2a1SAlex Deucher {
5124bcc1c2a1SAlex Deucher 	int r;
5125bcc1c2a1SAlex Deucher 
512686f5c9edSAlex Deucher 	/* reset the asic, the gfx blocks are often in a bad state
512786f5c9edSAlex Deucher 	 * after the driver is unloaded or after a resume
512886f5c9edSAlex Deucher 	 */
512986f5c9edSAlex Deucher 	if (radeon_asic_reset(rdev))
513086f5c9edSAlex Deucher 		dev_warn(rdev->dev, "GPU reset failed !\n");
5131bcc1c2a1SAlex Deucher 	/* Do not reset GPU before posting, on rv770 hw unlike on r500 hw,
5132bcc1c2a1SAlex Deucher 	 * posting will perform necessary task to bring back GPU into good
5133bcc1c2a1SAlex Deucher 	 * shape.
5134bcc1c2a1SAlex Deucher 	 */
5135bcc1c2a1SAlex Deucher 	/* post card */
5136bcc1c2a1SAlex Deucher 	atom_asic_init(rdev->mode_info.atom_context);
5137bcc1c2a1SAlex Deucher 
5138d4788db3SAlex Deucher 	/* init golden registers */
5139d4788db3SAlex Deucher 	evergreen_init_golden_registers(rdev);
5140d4788db3SAlex Deucher 
5141bc6a6295SAlex Deucher 	if (rdev->pm.pm_method == PM_METHOD_DPM)
51426c7bcceaSAlex Deucher 		radeon_pm_resume(rdev);
51436c7bcceaSAlex Deucher 
5144b15ba512SJerome Glisse 	rdev->accel_working = true;
5145bcc1c2a1SAlex Deucher 	r = evergreen_startup(rdev);
5146bcc1c2a1SAlex Deucher 	if (r) {
5147755d819eSAlex Deucher 		DRM_ERROR("evergreen startup failed on resume\n");
51486b7746e8SJerome Glisse 		rdev->accel_working = false;
5149bcc1c2a1SAlex Deucher 		return r;
5150bcc1c2a1SAlex Deucher 	}
5151fe251e2fSAlex Deucher 
5152bcc1c2a1SAlex Deucher 	return r;
5153bcc1c2a1SAlex Deucher 
5154bcc1c2a1SAlex Deucher }
5155bcc1c2a1SAlex Deucher 
evergreen_suspend(struct radeon_device * rdev)5156bcc1c2a1SAlex Deucher int evergreen_suspend(struct radeon_device *rdev)
5157bcc1c2a1SAlex Deucher {
51586c7bcceaSAlex Deucher 	radeon_pm_suspend(rdev);
51597991d665SSlava Grigorev 	radeon_audio_fini(rdev);
5160d78d6f39SJérome Glisse 	if (rdev->has_uvd) {
5161f2ba57b5SChristian König 		radeon_uvd_suspend(rdev);
5162dfd6879bSQiang Ma 		uvd_v1_0_fini(rdev);
5163d78d6f39SJérome Glisse 	}
5164bcc1c2a1SAlex Deucher 	r700_cp_stop(rdev);
5165233d1ad5SAlex Deucher 	r600_dma_stop(rdev);
516645f9a39bSAlex Deucher 	evergreen_irq_suspend(rdev);
5167724c80e1SAlex Deucher 	radeon_wb_disable(rdev);
5168bcc1c2a1SAlex Deucher 	evergreen_pcie_gart_disable(rdev);
5169d7ccd8fcSAlex Deucher 
5170d7ccd8fcSAlex Deucher 	return 0;
5171d7ccd8fcSAlex Deucher }
5172d7ccd8fcSAlex Deucher 
5173bcc1c2a1SAlex Deucher /* Plan is to move initialization in that function and use
5174bcc1c2a1SAlex Deucher  * helper function so that radeon_device_init pretty much
5175bcc1c2a1SAlex Deucher  * do nothing more than calling asic specific function. This
5176bcc1c2a1SAlex Deucher  * should also allow to remove a bunch of callback function
5177bcc1c2a1SAlex Deucher  * like vram_info.
5178bcc1c2a1SAlex Deucher  */
evergreen_init(struct radeon_device * rdev)5179bcc1c2a1SAlex Deucher int evergreen_init(struct radeon_device *rdev)
5180bcc1c2a1SAlex Deucher {
5181bcc1c2a1SAlex Deucher 	int r;
5182bcc1c2a1SAlex Deucher 
5183bcc1c2a1SAlex Deucher 	/* Read BIOS */
5184bcc1c2a1SAlex Deucher 	if (!radeon_get_bios(rdev)) {
5185bcc1c2a1SAlex Deucher 		if (ASIC_IS_AVIVO(rdev))
5186bcc1c2a1SAlex Deucher 			return -EINVAL;
5187bcc1c2a1SAlex Deucher 	}
5188bcc1c2a1SAlex Deucher 	/* Must be an ATOMBIOS */
5189bcc1c2a1SAlex Deucher 	if (!rdev->is_atom_bios) {
5190755d819eSAlex Deucher 		dev_err(rdev->dev, "Expecting atombios for evergreen GPU\n");
5191bcc1c2a1SAlex Deucher 		return -EINVAL;
5192bcc1c2a1SAlex Deucher 	}
5193bcc1c2a1SAlex Deucher 	r = radeon_atombios_init(rdev);
5194bcc1c2a1SAlex Deucher 	if (r)
5195bcc1c2a1SAlex Deucher 		return r;
519686f5c9edSAlex Deucher 	/* reset the asic, the gfx blocks are often in a bad state
519786f5c9edSAlex Deucher 	 * after the driver is unloaded or after a resume
519886f5c9edSAlex Deucher 	 */
519986f5c9edSAlex Deucher 	if (radeon_asic_reset(rdev))
520086f5c9edSAlex Deucher 		dev_warn(rdev->dev, "GPU reset failed !\n");
5201bcc1c2a1SAlex Deucher 	/* Post card if necessary */
5202fd909c37SAlex Deucher 	if (!radeon_card_posted(rdev)) {
5203bcc1c2a1SAlex Deucher 		if (!rdev->bios) {
5204bcc1c2a1SAlex Deucher 			dev_err(rdev->dev, "Card not posted and no BIOS - ignoring\n");
5205bcc1c2a1SAlex Deucher 			return -EINVAL;
5206bcc1c2a1SAlex Deucher 		}
5207bcc1c2a1SAlex Deucher 		DRM_INFO("GPU not posted. posting now...\n");
5208bcc1c2a1SAlex Deucher 		atom_asic_init(rdev->mode_info.atom_context);
5209bcc1c2a1SAlex Deucher 	}
5210d4788db3SAlex Deucher 	/* init golden registers */
5211d4788db3SAlex Deucher 	evergreen_init_golden_registers(rdev);
5212bcc1c2a1SAlex Deucher 	/* Initialize scratch registers */
5213bcc1c2a1SAlex Deucher 	r600_scratch_init(rdev);
5214bcc1c2a1SAlex Deucher 	/* Initialize surface registers */
5215bcc1c2a1SAlex Deucher 	radeon_surface_init(rdev);
5216bcc1c2a1SAlex Deucher 	/* Initialize clocks */
5217*5e3a0f77SWu Hoi Pok 	radeon_get_clock_info(rdev_to_drm(rdev));
5218bcc1c2a1SAlex Deucher 	/* Fence driver */
5219519424d7SBernard Zhao 	radeon_fence_driver_init(rdev);
5220d594e46aSJerome Glisse 	/* initialize AGP */
5221d594e46aSJerome Glisse 	if (rdev->flags & RADEON_IS_AGP) {
5222d594e46aSJerome Glisse 		r = radeon_agp_init(rdev);
5223d594e46aSJerome Glisse 		if (r)
5224d594e46aSJerome Glisse 			radeon_agp_disable(rdev);
5225d594e46aSJerome Glisse 	}
5226d594e46aSJerome Glisse 	/* initialize memory controller */
5227bcc1c2a1SAlex Deucher 	r = evergreen_mc_init(rdev);
5228bcc1c2a1SAlex Deucher 	if (r)
5229bcc1c2a1SAlex Deucher 		return r;
5230bcc1c2a1SAlex Deucher 	/* Memory manager */
5231bcc1c2a1SAlex Deucher 	r = radeon_bo_init(rdev);
5232bcc1c2a1SAlex Deucher 	if (r)
5233bcc1c2a1SAlex Deucher 		return r;
523445f9a39bSAlex Deucher 
523501ac8794SAlex Deucher 	if (ASIC_IS_DCE5(rdev)) {
523601ac8794SAlex Deucher 		if (!rdev->me_fw || !rdev->pfp_fw || !rdev->rlc_fw || !rdev->mc_fw) {
523701ac8794SAlex Deucher 			r = ni_init_microcode(rdev);
523801ac8794SAlex Deucher 			if (r) {
523901ac8794SAlex Deucher 				DRM_ERROR("Failed to load firmware!\n");
524001ac8794SAlex Deucher 				return r;
524101ac8794SAlex Deucher 			}
524201ac8794SAlex Deucher 		}
524301ac8794SAlex Deucher 	} else {
524401ac8794SAlex Deucher 		if (!rdev->me_fw || !rdev->pfp_fw || !rdev->rlc_fw) {
524501ac8794SAlex Deucher 			r = r600_init_microcode(rdev);
524601ac8794SAlex Deucher 			if (r) {
524701ac8794SAlex Deucher 				DRM_ERROR("Failed to load firmware!\n");
524801ac8794SAlex Deucher 				return r;
524901ac8794SAlex Deucher 			}
525001ac8794SAlex Deucher 		}
525101ac8794SAlex Deucher 	}
525201ac8794SAlex Deucher 
52536c7bcceaSAlex Deucher 	/* Initialize power management */
52546c7bcceaSAlex Deucher 	radeon_pm_init(rdev);
52556c7bcceaSAlex Deucher 
5256e32eb50dSChristian König 	rdev->ring[RADEON_RING_TYPE_GFX_INDEX].ring_obj = NULL;
5257e32eb50dSChristian König 	r600_ring_init(rdev, &rdev->ring[RADEON_RING_TYPE_GFX_INDEX], 1024 * 1024);
5258bcc1c2a1SAlex Deucher 
5259233d1ad5SAlex Deucher 	rdev->ring[R600_RING_TYPE_DMA_INDEX].ring_obj = NULL;
5260233d1ad5SAlex Deucher 	r600_ring_init(rdev, &rdev->ring[R600_RING_TYPE_DMA_INDEX], 64 * 1024);
5261233d1ad5SAlex Deucher 
5262d78d6f39SJérome Glisse 	evergreen_uvd_init(rdev);
5263f2ba57b5SChristian König 
5264bcc1c2a1SAlex Deucher 	rdev->ih.ring_obj = NULL;
5265bcc1c2a1SAlex Deucher 	r600_ih_ring_init(rdev, 64 * 1024);
5266bcc1c2a1SAlex Deucher 
5267bcc1c2a1SAlex Deucher 	r = r600_pcie_gart_init(rdev);
5268bcc1c2a1SAlex Deucher 	if (r)
5269bcc1c2a1SAlex Deucher 		return r;
52700fcdb61eSAlex Deucher 
5271148a03bcSAlex Deucher 	rdev->accel_working = true;
5272bcc1c2a1SAlex Deucher 	r = evergreen_startup(rdev);
5273bcc1c2a1SAlex Deucher 	if (r) {
5274fe251e2fSAlex Deucher 		dev_err(rdev->dev, "disabling GPU acceleration\n");
5275fe251e2fSAlex Deucher 		r700_cp_fini(rdev);
5276233d1ad5SAlex Deucher 		r600_dma_fini(rdev);
5277fe251e2fSAlex Deucher 		r600_irq_fini(rdev);
52782948f5e6SAlex Deucher 		if (rdev->flags & RADEON_IS_IGP)
52792948f5e6SAlex Deucher 			sumo_rlc_fini(rdev);
5280724c80e1SAlex Deucher 		radeon_wb_fini(rdev);
52812898c348SChristian König 		radeon_ib_pool_fini(rdev);
5282fe251e2fSAlex Deucher 		radeon_irq_kms_fini(rdev);
52830fcdb61eSAlex Deucher 		evergreen_pcie_gart_fini(rdev);
5284bcc1c2a1SAlex Deucher 		rdev->accel_working = false;
5285bcc1c2a1SAlex Deucher 	}
528677e00f2eSAlex Deucher 
528777e00f2eSAlex Deucher 	/* Don't start up if the MC ucode is missing on BTC parts.
528877e00f2eSAlex Deucher 	 * The default clocks and voltages before the MC ucode
528977e00f2eSAlex Deucher 	 * is loaded are not suffient for advanced operations.
529077e00f2eSAlex Deucher 	 */
529177e00f2eSAlex Deucher 	if (ASIC_IS_DCE5(rdev)) {
529277e00f2eSAlex Deucher 		if (!rdev->mc_fw && !(rdev->flags & RADEON_IS_IGP)) {
529377e00f2eSAlex Deucher 			DRM_ERROR("radeon: MC ucode required for NI+.\n");
529477e00f2eSAlex Deucher 			return -EINVAL;
529577e00f2eSAlex Deucher 		}
529677e00f2eSAlex Deucher 	}
529777e00f2eSAlex Deucher 
5298bcc1c2a1SAlex Deucher 	return 0;
5299bcc1c2a1SAlex Deucher }
5300bcc1c2a1SAlex Deucher 
evergreen_fini(struct radeon_device * rdev)5301bcc1c2a1SAlex Deucher void evergreen_fini(struct radeon_device *rdev)
5302bcc1c2a1SAlex Deucher {
53036c7bcceaSAlex Deucher 	radeon_pm_fini(rdev);
53047991d665SSlava Grigorev 	radeon_audio_fini(rdev);
530545f9a39bSAlex Deucher 	r700_cp_fini(rdev);
5306233d1ad5SAlex Deucher 	r600_dma_fini(rdev);
5307bcc1c2a1SAlex Deucher 	r600_irq_fini(rdev);
53082948f5e6SAlex Deucher 	if (rdev->flags & RADEON_IS_IGP)
53092948f5e6SAlex Deucher 		sumo_rlc_fini(rdev);
5310724c80e1SAlex Deucher 	radeon_wb_fini(rdev);
53112898c348SChristian König 	radeon_ib_pool_fini(rdev);
5312bcc1c2a1SAlex Deucher 	radeon_irq_kms_fini(rdev);
5313e409b128SChristian König 	uvd_v1_0_fini(rdev);
5314f2ba57b5SChristian König 	radeon_uvd_fini(rdev);
5315d9654413SJerome Glisse 	evergreen_pcie_gart_fini(rdev);
531616cdf04dSAlex Deucher 	r600_vram_scratch_fini(rdev);
5317bcc1c2a1SAlex Deucher 	radeon_gem_fini(rdev);
5318bcc1c2a1SAlex Deucher 	radeon_fence_driver_fini(rdev);
5319bcc1c2a1SAlex Deucher 	radeon_agp_fini(rdev);
5320bcc1c2a1SAlex Deucher 	radeon_bo_fini(rdev);
5321bcc1c2a1SAlex Deucher 	radeon_atombios_fini(rdev);
5322bcc1c2a1SAlex Deucher 	kfree(rdev->bios);
5323bcc1c2a1SAlex Deucher 	rdev->bios = NULL;
5324bcc1c2a1SAlex Deucher }
53259e46a48dSAlex Deucher 
evergreen_pcie_gen2_enable(struct radeon_device * rdev)5326b07759bfSIlija Hadzic void evergreen_pcie_gen2_enable(struct radeon_device *rdev)
53279e46a48dSAlex Deucher {
53287e0e4196SKleber Sacilotto de Souza 	u32 link_width_cntl, speed_cntl;
53299e46a48dSAlex Deucher 
5330d42dd579SAlex Deucher 	if (radeon_pcie_gen2 == 0)
5331d42dd579SAlex Deucher 		return;
5332d42dd579SAlex Deucher 
53339e46a48dSAlex Deucher 	if (rdev->flags & RADEON_IS_IGP)
53349e46a48dSAlex Deucher 		return;
53359e46a48dSAlex Deucher 
53369e46a48dSAlex Deucher 	if (!(rdev->flags & RADEON_IS_PCIE))
53379e46a48dSAlex Deucher 		return;
53389e46a48dSAlex Deucher 
53399e46a48dSAlex Deucher 	/* x2 cards have a special sequence */
53409e46a48dSAlex Deucher 	if (ASIC_IS_X2(rdev))
53419e46a48dSAlex Deucher 		return;
53429e46a48dSAlex Deucher 
53437e0e4196SKleber Sacilotto de Souza 	if ((rdev->pdev->bus->max_bus_speed != PCIE_SPEED_5_0GT) &&
53447e0e4196SKleber Sacilotto de Souza 		(rdev->pdev->bus->max_bus_speed != PCIE_SPEED_8_0GT))
5345197bbb3dSDave Airlie 		return;
5346197bbb3dSDave Airlie 
5347492d2b61SAlex Deucher 	speed_cntl = RREG32_PCIE_PORT(PCIE_LC_SPEED_CNTL);
53483691feeaSAlex Deucher 	if (speed_cntl & LC_CURRENT_DATA_RATE) {
53493691feeaSAlex Deucher 		DRM_INFO("PCIE gen 2 link speeds already enabled\n");
53503691feeaSAlex Deucher 		return;
53513691feeaSAlex Deucher 	}
53523691feeaSAlex Deucher 
5353197bbb3dSDave Airlie 	DRM_INFO("enabling PCIE gen 2 link speeds, disable with radeon.pcie_gen2=0\n");
5354197bbb3dSDave Airlie 
53559e46a48dSAlex Deucher 	if ((speed_cntl & LC_OTHER_SIDE_EVER_SENT_GEN2) ||
53569e46a48dSAlex Deucher 	    (speed_cntl & LC_OTHER_SIDE_SUPPORTS_GEN2)) {
53579e46a48dSAlex Deucher 
5358492d2b61SAlex Deucher 		link_width_cntl = RREG32_PCIE_PORT(PCIE_LC_LINK_WIDTH_CNTL);
53599e46a48dSAlex Deucher 		link_width_cntl &= ~LC_UPCONFIGURE_DIS;
5360492d2b61SAlex Deucher 		WREG32_PCIE_PORT(PCIE_LC_LINK_WIDTH_CNTL, link_width_cntl);
53619e46a48dSAlex Deucher 
5362492d2b61SAlex Deucher 		speed_cntl = RREG32_PCIE_PORT(PCIE_LC_SPEED_CNTL);
53639e46a48dSAlex Deucher 		speed_cntl &= ~LC_TARGET_LINK_SPEED_OVERRIDE_EN;
5364492d2b61SAlex Deucher 		WREG32_PCIE_PORT(PCIE_LC_SPEED_CNTL, speed_cntl);
53659e46a48dSAlex Deucher 
5366492d2b61SAlex Deucher 		speed_cntl = RREG32_PCIE_PORT(PCIE_LC_SPEED_CNTL);
53679e46a48dSAlex Deucher 		speed_cntl |= LC_CLR_FAILED_SPD_CHANGE_CNT;
5368492d2b61SAlex Deucher 		WREG32_PCIE_PORT(PCIE_LC_SPEED_CNTL, speed_cntl);
53699e46a48dSAlex Deucher 
5370492d2b61SAlex Deucher 		speed_cntl = RREG32_PCIE_PORT(PCIE_LC_SPEED_CNTL);
53719e46a48dSAlex Deucher 		speed_cntl &= ~LC_CLR_FAILED_SPD_CHANGE_CNT;
5372492d2b61SAlex Deucher 		WREG32_PCIE_PORT(PCIE_LC_SPEED_CNTL, speed_cntl);
53739e46a48dSAlex Deucher 
5374492d2b61SAlex Deucher 		speed_cntl = RREG32_PCIE_PORT(PCIE_LC_SPEED_CNTL);
53759e46a48dSAlex Deucher 		speed_cntl |= LC_GEN2_EN_STRAP;
5376492d2b61SAlex Deucher 		WREG32_PCIE_PORT(PCIE_LC_SPEED_CNTL, speed_cntl);
53779e46a48dSAlex Deucher 
53789e46a48dSAlex Deucher 	} else {
5379492d2b61SAlex Deucher 		link_width_cntl = RREG32_PCIE_PORT(PCIE_LC_LINK_WIDTH_CNTL);
53809e46a48dSAlex Deucher 		/* XXX: only disable it if gen1 bridge vendor == 0x111d or 0x1106 */
53819e46a48dSAlex Deucher 		if (1)
53829e46a48dSAlex Deucher 			link_width_cntl |= LC_UPCONFIGURE_DIS;
53839e46a48dSAlex Deucher 		else
53849e46a48dSAlex Deucher 			link_width_cntl &= ~LC_UPCONFIGURE_DIS;
5385492d2b61SAlex Deucher 		WREG32_PCIE_PORT(PCIE_LC_LINK_WIDTH_CNTL, link_width_cntl);
53869e46a48dSAlex Deucher 	}
53879e46a48dSAlex Deucher }
5388f52382d7SAlex Deucher 
evergreen_program_aspm(struct radeon_device * rdev)5389f52382d7SAlex Deucher void evergreen_program_aspm(struct radeon_device *rdev)
5390f52382d7SAlex Deucher {
5391f52382d7SAlex Deucher 	u32 data, orig;
5392f52382d7SAlex Deucher 	u32 pcie_lc_cntl, pcie_lc_cntl_old;
5393f52382d7SAlex Deucher 	bool disable_l0s, disable_l1 = false, disable_plloff_in_l1 = false;
5394f52382d7SAlex Deucher 	/* fusion_platform = true
5395f52382d7SAlex Deucher 	 * if the system is a fusion system
5396f52382d7SAlex Deucher 	 * (APU or DGPU in a fusion system).
5397f52382d7SAlex Deucher 	 * todo: check if the system is a fusion platform.
5398f52382d7SAlex Deucher 	 */
5399f52382d7SAlex Deucher 	bool fusion_platform = false;
5400f52382d7SAlex Deucher 
54011294d4a3SAlex Deucher 	if (radeon_aspm == 0)
54021294d4a3SAlex Deucher 		return;
54031294d4a3SAlex Deucher 
5404f52382d7SAlex Deucher 	if (!(rdev->flags & RADEON_IS_PCIE))
5405f52382d7SAlex Deucher 		return;
5406f52382d7SAlex Deucher 
5407f52382d7SAlex Deucher 	switch (rdev->family) {
5408f52382d7SAlex Deucher 	case CHIP_CYPRESS:
5409f52382d7SAlex Deucher 	case CHIP_HEMLOCK:
5410f52382d7SAlex Deucher 	case CHIP_JUNIPER:
5411f52382d7SAlex Deucher 	case CHIP_REDWOOD:
5412f52382d7SAlex Deucher 	case CHIP_CEDAR:
5413f52382d7SAlex Deucher 	case CHIP_SUMO:
5414f52382d7SAlex Deucher 	case CHIP_SUMO2:
5415f52382d7SAlex Deucher 	case CHIP_PALM:
5416f52382d7SAlex Deucher 	case CHIP_ARUBA:
5417f52382d7SAlex Deucher 		disable_l0s = true;
5418f52382d7SAlex Deucher 		break;
5419f52382d7SAlex Deucher 	default:
5420f52382d7SAlex Deucher 		disable_l0s = false;
5421f52382d7SAlex Deucher 		break;
5422f52382d7SAlex Deucher 	}
5423f52382d7SAlex Deucher 
5424f52382d7SAlex Deucher 	if (rdev->flags & RADEON_IS_IGP)
5425f52382d7SAlex Deucher 		fusion_platform = true; /* XXX also dGPUs in a fusion system */
5426f52382d7SAlex Deucher 
5427f52382d7SAlex Deucher 	data = orig = RREG32_PIF_PHY0(PB0_PIF_PAIRING);
5428f52382d7SAlex Deucher 	if (fusion_platform)
5429f52382d7SAlex Deucher 		data &= ~MULTI_PIF;
5430f52382d7SAlex Deucher 	else
5431f52382d7SAlex Deucher 		data |= MULTI_PIF;
5432f52382d7SAlex Deucher 	if (data != orig)
5433f52382d7SAlex Deucher 		WREG32_PIF_PHY0(PB0_PIF_PAIRING, data);
5434f52382d7SAlex Deucher 
5435f52382d7SAlex Deucher 	data = orig = RREG32_PIF_PHY1(PB1_PIF_PAIRING);
5436f52382d7SAlex Deucher 	if (fusion_platform)
5437f52382d7SAlex Deucher 		data &= ~MULTI_PIF;
5438f52382d7SAlex Deucher 	else
5439f52382d7SAlex Deucher 		data |= MULTI_PIF;
5440f52382d7SAlex Deucher 	if (data != orig)
5441f52382d7SAlex Deucher 		WREG32_PIF_PHY1(PB1_PIF_PAIRING, data);
5442f52382d7SAlex Deucher 
5443f52382d7SAlex Deucher 	pcie_lc_cntl = pcie_lc_cntl_old = RREG32_PCIE_PORT(PCIE_LC_CNTL);
5444f52382d7SAlex Deucher 	pcie_lc_cntl &= ~(LC_L0S_INACTIVITY_MASK | LC_L1_INACTIVITY_MASK);
5445f52382d7SAlex Deucher 	if (!disable_l0s) {
5446f52382d7SAlex Deucher 		if (rdev->family >= CHIP_BARTS)
5447f52382d7SAlex Deucher 			pcie_lc_cntl |= LC_L0S_INACTIVITY(7);
5448f52382d7SAlex Deucher 		else
5449f52382d7SAlex Deucher 			pcie_lc_cntl |= LC_L0S_INACTIVITY(3);
5450f52382d7SAlex Deucher 	}
5451f52382d7SAlex Deucher 
5452f52382d7SAlex Deucher 	if (!disable_l1) {
5453f52382d7SAlex Deucher 		if (rdev->family >= CHIP_BARTS)
5454f52382d7SAlex Deucher 			pcie_lc_cntl |= LC_L1_INACTIVITY(7);
5455f52382d7SAlex Deucher 		else
5456f52382d7SAlex Deucher 			pcie_lc_cntl |= LC_L1_INACTIVITY(8);
5457f52382d7SAlex Deucher 
5458f52382d7SAlex Deucher 		if (!disable_plloff_in_l1) {
5459f52382d7SAlex Deucher 			data = orig = RREG32_PIF_PHY0(PB0_PIF_PWRDOWN_0);
5460f52382d7SAlex Deucher 			data &= ~(PLL_POWER_STATE_IN_OFF_0_MASK | PLL_POWER_STATE_IN_TXS2_0_MASK);
5461f52382d7SAlex Deucher 			data |= PLL_POWER_STATE_IN_OFF_0(7) | PLL_POWER_STATE_IN_TXS2_0(7);
5462f52382d7SAlex Deucher 			if (data != orig)
5463f52382d7SAlex Deucher 				WREG32_PIF_PHY0(PB0_PIF_PWRDOWN_0, data);
5464f52382d7SAlex Deucher 
5465f52382d7SAlex Deucher 			data = orig = RREG32_PIF_PHY0(PB0_PIF_PWRDOWN_1);
5466f52382d7SAlex Deucher 			data &= ~(PLL_POWER_STATE_IN_OFF_1_MASK | PLL_POWER_STATE_IN_TXS2_1_MASK);
5467f52382d7SAlex Deucher 			data |= PLL_POWER_STATE_IN_OFF_1(7) | PLL_POWER_STATE_IN_TXS2_1(7);
5468f52382d7SAlex Deucher 			if (data != orig)
5469f52382d7SAlex Deucher 				WREG32_PIF_PHY0(PB0_PIF_PWRDOWN_1, data);
5470f52382d7SAlex Deucher 
5471f52382d7SAlex Deucher 			data = orig = RREG32_PIF_PHY1(PB1_PIF_PWRDOWN_0);
5472f52382d7SAlex Deucher 			data &= ~(PLL_POWER_STATE_IN_OFF_0_MASK | PLL_POWER_STATE_IN_TXS2_0_MASK);
5473f52382d7SAlex Deucher 			data |= PLL_POWER_STATE_IN_OFF_0(7) | PLL_POWER_STATE_IN_TXS2_0(7);
5474f52382d7SAlex Deucher 			if (data != orig)
5475f52382d7SAlex Deucher 				WREG32_PIF_PHY1(PB1_PIF_PWRDOWN_0, data);
5476f52382d7SAlex Deucher 
5477f52382d7SAlex Deucher 			data = orig = RREG32_PIF_PHY1(PB1_PIF_PWRDOWN_1);
5478f52382d7SAlex Deucher 			data &= ~(PLL_POWER_STATE_IN_OFF_1_MASK | PLL_POWER_STATE_IN_TXS2_1_MASK);
5479f52382d7SAlex Deucher 			data |= PLL_POWER_STATE_IN_OFF_1(7) | PLL_POWER_STATE_IN_TXS2_1(7);
5480f52382d7SAlex Deucher 			if (data != orig)
5481f52382d7SAlex Deucher 				WREG32_PIF_PHY1(PB1_PIF_PWRDOWN_1, data);
5482f52382d7SAlex Deucher 
5483f52382d7SAlex Deucher 			if (rdev->family >= CHIP_BARTS) {
5484f52382d7SAlex Deucher 				data = orig = RREG32_PIF_PHY0(PB0_PIF_PWRDOWN_0);
5485f52382d7SAlex Deucher 				data &= ~PLL_RAMP_UP_TIME_0_MASK;
5486f52382d7SAlex Deucher 				data |= PLL_RAMP_UP_TIME_0(4);
5487f52382d7SAlex Deucher 				if (data != orig)
5488f52382d7SAlex Deucher 					WREG32_PIF_PHY0(PB0_PIF_PWRDOWN_0, data);
5489f52382d7SAlex Deucher 
5490f52382d7SAlex Deucher 				data = orig = RREG32_PIF_PHY0(PB0_PIF_PWRDOWN_1);
5491f52382d7SAlex Deucher 				data &= ~PLL_RAMP_UP_TIME_1_MASK;
5492f52382d7SAlex Deucher 				data |= PLL_RAMP_UP_TIME_1(4);
5493f52382d7SAlex Deucher 				if (data != orig)
5494f52382d7SAlex Deucher 					WREG32_PIF_PHY0(PB0_PIF_PWRDOWN_1, data);
5495f52382d7SAlex Deucher 
5496f52382d7SAlex Deucher 				data = orig = RREG32_PIF_PHY1(PB1_PIF_PWRDOWN_0);
5497f52382d7SAlex Deucher 				data &= ~PLL_RAMP_UP_TIME_0_MASK;
5498f52382d7SAlex Deucher 				data |= PLL_RAMP_UP_TIME_0(4);
5499f52382d7SAlex Deucher 				if (data != orig)
5500f52382d7SAlex Deucher 					WREG32_PIF_PHY1(PB1_PIF_PWRDOWN_0, data);
5501f52382d7SAlex Deucher 
5502f52382d7SAlex Deucher 				data = orig = RREG32_PIF_PHY1(PB1_PIF_PWRDOWN_1);
5503f52382d7SAlex Deucher 				data &= ~PLL_RAMP_UP_TIME_1_MASK;
5504f52382d7SAlex Deucher 				data |= PLL_RAMP_UP_TIME_1(4);
5505f52382d7SAlex Deucher 				if (data != orig)
5506f52382d7SAlex Deucher 					WREG32_PIF_PHY1(PB1_PIF_PWRDOWN_1, data);
5507f52382d7SAlex Deucher 			}
5508f52382d7SAlex Deucher 
5509f52382d7SAlex Deucher 			data = orig = RREG32_PCIE_PORT(PCIE_LC_LINK_WIDTH_CNTL);
5510f52382d7SAlex Deucher 			data &= ~LC_DYN_LANES_PWR_STATE_MASK;
5511f52382d7SAlex Deucher 			data |= LC_DYN_LANES_PWR_STATE(3);
5512f52382d7SAlex Deucher 			if (data != orig)
5513f52382d7SAlex Deucher 				WREG32_PCIE_PORT(PCIE_LC_LINK_WIDTH_CNTL, data);
5514f52382d7SAlex Deucher 
5515f52382d7SAlex Deucher 			if (rdev->family >= CHIP_BARTS) {
5516f52382d7SAlex Deucher 				data = orig = RREG32_PIF_PHY0(PB0_PIF_CNTL);
5517f52382d7SAlex Deucher 				data &= ~LS2_EXIT_TIME_MASK;
5518f52382d7SAlex Deucher 				data |= LS2_EXIT_TIME(1);
5519f52382d7SAlex Deucher 				if (data != orig)
5520f52382d7SAlex Deucher 					WREG32_PIF_PHY0(PB0_PIF_CNTL, data);
5521f52382d7SAlex Deucher 
5522f52382d7SAlex Deucher 				data = orig = RREG32_PIF_PHY1(PB1_PIF_CNTL);
5523f52382d7SAlex Deucher 				data &= ~LS2_EXIT_TIME_MASK;
5524f52382d7SAlex Deucher 				data |= LS2_EXIT_TIME(1);
5525f52382d7SAlex Deucher 				if (data != orig)
5526f52382d7SAlex Deucher 					WREG32_PIF_PHY1(PB1_PIF_CNTL, data);
5527f52382d7SAlex Deucher 			}
5528f52382d7SAlex Deucher 		}
5529f52382d7SAlex Deucher 	}
5530f52382d7SAlex Deucher 
5531f52382d7SAlex Deucher 	/* evergreen parts only */
5532f52382d7SAlex Deucher 	if (rdev->family < CHIP_BARTS)
5533f52382d7SAlex Deucher 		pcie_lc_cntl |= LC_PMI_TO_L1_DIS;
5534f52382d7SAlex Deucher 
5535f52382d7SAlex Deucher 	if (pcie_lc_cntl != pcie_lc_cntl_old)
5536f52382d7SAlex Deucher 		WREG32_PCIE_PORT(PCIE_LC_CNTL, pcie_lc_cntl);
5537f52382d7SAlex Deucher }
5538