143b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher/*
243b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher * Copyright 2011 Advanced Micro Devices, Inc.
343b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher *
443b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher * Permission is hereby granted, free of charge, to any person obtaining a
543b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher * copy of this software and associated documentation files (the "Software"),
643b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher * to deal in the Software without restriction, including without limitation
743b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher * the rights to use, copy, modify, merge, publish, distribute, sublicense,
843b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher * and/or sell copies of the Software, and to permit persons to whom the
943b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher * Software is furnished to do so, subject to the following conditions:
1043b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher *
1143b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher * The above copyright notice and this permission notice shall be included in
1243b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher * all copies or substantial portions of the Software.
1343b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher *
1443b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1543b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1643b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
1743b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
1843b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
1943b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
2043b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher * OTHER DEALINGS IN THE SOFTWARE.
2143b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher *
2243b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher * Authors: Alex Deucher
2343b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher */
240f0de06c809eac783ddb4ddfc52c9db43af94b4fAlex Deucher#include <linux/firmware.h>
250f0de06c809eac783ddb4ddfc52c9db43af94b4fAlex Deucher#include <linux/platform_device.h>
260f0de06c809eac783ddb4ddfc52c9db43af94b4fAlex Deucher#include <linux/slab.h>
270f0de06c809eac783ddb4ddfc52c9db43af94b4fAlex Deucher#include <linux/module.h>
2843b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher#include "drmP.h"
2943b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher#include "radeon.h"
3043b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher#include "radeon_asic.h"
3143b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher#include "radeon_drm.h"
3243b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher#include "sid.h"
3343b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher#include "atom.h"
3448c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher#include "si_blit_shaders.h"
3543b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher
360f0de06c809eac783ddb4ddfc52c9db43af94b4fAlex Deucher#define SI_PFP_UCODE_SIZE 2144
370f0de06c809eac783ddb4ddfc52c9db43af94b4fAlex Deucher#define SI_PM4_UCODE_SIZE 2144
380f0de06c809eac783ddb4ddfc52c9db43af94b4fAlex Deucher#define SI_CE_UCODE_SIZE 2144
390f0de06c809eac783ddb4ddfc52c9db43af94b4fAlex Deucher#define SI_RLC_UCODE_SIZE 2048
400f0de06c809eac783ddb4ddfc52c9db43af94b4fAlex Deucher#define SI_MC_UCODE_SIZE 7769
410f0de06c809eac783ddb4ddfc52c9db43af94b4fAlex Deucher
420f0de06c809eac783ddb4ddfc52c9db43af94b4fAlex DeucherMODULE_FIRMWARE("radeon/TAHITI_pfp.bin");
430f0de06c809eac783ddb4ddfc52c9db43af94b4fAlex DeucherMODULE_FIRMWARE("radeon/TAHITI_me.bin");
440f0de06c809eac783ddb4ddfc52c9db43af94b4fAlex DeucherMODULE_FIRMWARE("radeon/TAHITI_ce.bin");
450f0de06c809eac783ddb4ddfc52c9db43af94b4fAlex DeucherMODULE_FIRMWARE("radeon/TAHITI_mc.bin");
460f0de06c809eac783ddb4ddfc52c9db43af94b4fAlex DeucherMODULE_FIRMWARE("radeon/TAHITI_rlc.bin");
470f0de06c809eac783ddb4ddfc52c9db43af94b4fAlex DeucherMODULE_FIRMWARE("radeon/PITCAIRN_pfp.bin");
480f0de06c809eac783ddb4ddfc52c9db43af94b4fAlex DeucherMODULE_FIRMWARE("radeon/PITCAIRN_me.bin");
490f0de06c809eac783ddb4ddfc52c9db43af94b4fAlex DeucherMODULE_FIRMWARE("radeon/PITCAIRN_ce.bin");
500f0de06c809eac783ddb4ddfc52c9db43af94b4fAlex DeucherMODULE_FIRMWARE("radeon/PITCAIRN_mc.bin");
510f0de06c809eac783ddb4ddfc52c9db43af94b4fAlex DeucherMODULE_FIRMWARE("radeon/PITCAIRN_rlc.bin");
520f0de06c809eac783ddb4ddfc52c9db43af94b4fAlex DeucherMODULE_FIRMWARE("radeon/VERDE_pfp.bin");
530f0de06c809eac783ddb4ddfc52c9db43af94b4fAlex DeucherMODULE_FIRMWARE("radeon/VERDE_me.bin");
540f0de06c809eac783ddb4ddfc52c9db43af94b4fAlex DeucherMODULE_FIRMWARE("radeon/VERDE_ce.bin");
550f0de06c809eac783ddb4ddfc52c9db43af94b4fAlex DeucherMODULE_FIRMWARE("radeon/VERDE_mc.bin");
560f0de06c809eac783ddb4ddfc52c9db43af94b4fAlex DeucherMODULE_FIRMWARE("radeon/VERDE_rlc.bin");
570f0de06c809eac783ddb4ddfc52c9db43af94b4fAlex Deucher
5825a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucherextern int r600_ih_ring_alloc(struct radeon_device *rdev);
5925a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucherextern void r600_ih_ring_fini(struct radeon_device *rdev);
600a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucherextern void evergreen_fix_pci_max_read_req_size(struct radeon_device *rdev);
61c476dde2eda8c3e1af676fe3702b9fce98904cfbAlex Deucherextern void evergreen_mc_stop(struct radeon_device *rdev, struct evergreen_mc_save *save);
62c476dde2eda8c3e1af676fe3702b9fce98904cfbAlex Deucherextern void evergreen_mc_resume(struct radeon_device *rdev, struct evergreen_mc_save *save);
63ca7db22bc59ced2f180f37db8470140225d75860Alex Deucherextern u32 evergreen_get_number_of_dram_channels(struct radeon_device *rdev);
640a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher
651bd47d2e16573496efd2fd0ec36f57031d478f87Alex Deucher/* get temperature in millidegrees */
661bd47d2e16573496efd2fd0ec36f57031d478f87Alex Deucherint si_get_temp(struct radeon_device *rdev)
671bd47d2e16573496efd2fd0ec36f57031d478f87Alex Deucher{
681bd47d2e16573496efd2fd0ec36f57031d478f87Alex Deucher	u32 temp;
691bd47d2e16573496efd2fd0ec36f57031d478f87Alex Deucher	int actual_temp = 0;
701bd47d2e16573496efd2fd0ec36f57031d478f87Alex Deucher
711bd47d2e16573496efd2fd0ec36f57031d478f87Alex Deucher	temp = (RREG32(CG_MULT_THERMAL_STATUS) & CTF_TEMP_MASK) >>
721bd47d2e16573496efd2fd0ec36f57031d478f87Alex Deucher		CTF_TEMP_SHIFT;
731bd47d2e16573496efd2fd0ec36f57031d478f87Alex Deucher
741bd47d2e16573496efd2fd0ec36f57031d478f87Alex Deucher	if (temp & 0x200)
751bd47d2e16573496efd2fd0ec36f57031d478f87Alex Deucher		actual_temp = 255;
761bd47d2e16573496efd2fd0ec36f57031d478f87Alex Deucher	else
771bd47d2e16573496efd2fd0ec36f57031d478f87Alex Deucher		actual_temp = temp & 0x1ff;
781bd47d2e16573496efd2fd0ec36f57031d478f87Alex Deucher
791bd47d2e16573496efd2fd0ec36f57031d478f87Alex Deucher	actual_temp = (actual_temp * 1000);
801bd47d2e16573496efd2fd0ec36f57031d478f87Alex Deucher
811bd47d2e16573496efd2fd0ec36f57031d478f87Alex Deucher	return actual_temp;
821bd47d2e16573496efd2fd0ec36f57031d478f87Alex Deucher}
831bd47d2e16573496efd2fd0ec36f57031d478f87Alex Deucher
848b074dd64053d0bf93eed0638b74a8fec401577fAlex Deucher#define TAHITI_IO_MC_REGS_SIZE 36
858b074dd64053d0bf93eed0638b74a8fec401577fAlex Deucher
868b074dd64053d0bf93eed0638b74a8fec401577fAlex Deucherstatic const u32 tahiti_io_mc_regs[TAHITI_IO_MC_REGS_SIZE][2] = {
878b074dd64053d0bf93eed0638b74a8fec401577fAlex Deucher	{0x0000006f, 0x03044000},
888b074dd64053d0bf93eed0638b74a8fec401577fAlex Deucher	{0x00000070, 0x0480c018},
898b074dd64053d0bf93eed0638b74a8fec401577fAlex Deucher	{0x00000071, 0x00000040},
908b074dd64053d0bf93eed0638b74a8fec401577fAlex Deucher	{0x00000072, 0x01000000},
918b074dd64053d0bf93eed0638b74a8fec401577fAlex Deucher	{0x00000074, 0x000000ff},
928b074dd64053d0bf93eed0638b74a8fec401577fAlex Deucher	{0x00000075, 0x00143400},
938b074dd64053d0bf93eed0638b74a8fec401577fAlex Deucher	{0x00000076, 0x08ec0800},
948b074dd64053d0bf93eed0638b74a8fec401577fAlex Deucher	{0x00000077, 0x040000cc},
958b074dd64053d0bf93eed0638b74a8fec401577fAlex Deucher	{0x00000079, 0x00000000},
968b074dd64053d0bf93eed0638b74a8fec401577fAlex Deucher	{0x0000007a, 0x21000409},
978b074dd64053d0bf93eed0638b74a8fec401577fAlex Deucher	{0x0000007c, 0x00000000},
988b074dd64053d0bf93eed0638b74a8fec401577fAlex Deucher	{0x0000007d, 0xe8000000},
998b074dd64053d0bf93eed0638b74a8fec401577fAlex Deucher	{0x0000007e, 0x044408a8},
1008b074dd64053d0bf93eed0638b74a8fec401577fAlex Deucher	{0x0000007f, 0x00000003},
1018b074dd64053d0bf93eed0638b74a8fec401577fAlex Deucher	{0x00000080, 0x00000000},
1028b074dd64053d0bf93eed0638b74a8fec401577fAlex Deucher	{0x00000081, 0x01000000},
1038b074dd64053d0bf93eed0638b74a8fec401577fAlex Deucher	{0x00000082, 0x02000000},
1048b074dd64053d0bf93eed0638b74a8fec401577fAlex Deucher	{0x00000083, 0x00000000},
1058b074dd64053d0bf93eed0638b74a8fec401577fAlex Deucher	{0x00000084, 0xe3f3e4f4},
1068b074dd64053d0bf93eed0638b74a8fec401577fAlex Deucher	{0x00000085, 0x00052024},
1078b074dd64053d0bf93eed0638b74a8fec401577fAlex Deucher	{0x00000087, 0x00000000},
1088b074dd64053d0bf93eed0638b74a8fec401577fAlex Deucher	{0x00000088, 0x66036603},
1098b074dd64053d0bf93eed0638b74a8fec401577fAlex Deucher	{0x00000089, 0x01000000},
1108b074dd64053d0bf93eed0638b74a8fec401577fAlex Deucher	{0x0000008b, 0x1c0a0000},
1118b074dd64053d0bf93eed0638b74a8fec401577fAlex Deucher	{0x0000008c, 0xff010000},
1128b074dd64053d0bf93eed0638b74a8fec401577fAlex Deucher	{0x0000008e, 0xffffefff},
1138b074dd64053d0bf93eed0638b74a8fec401577fAlex Deucher	{0x0000008f, 0xfff3efff},
1148b074dd64053d0bf93eed0638b74a8fec401577fAlex Deucher	{0x00000090, 0xfff3efbf},
1158b074dd64053d0bf93eed0638b74a8fec401577fAlex Deucher	{0x00000094, 0x00101101},
1168b074dd64053d0bf93eed0638b74a8fec401577fAlex Deucher	{0x00000095, 0x00000fff},
1178b074dd64053d0bf93eed0638b74a8fec401577fAlex Deucher	{0x00000096, 0x00116fff},
1188b074dd64053d0bf93eed0638b74a8fec401577fAlex Deucher	{0x00000097, 0x60010000},
1198b074dd64053d0bf93eed0638b74a8fec401577fAlex Deucher	{0x00000098, 0x10010000},
1208b074dd64053d0bf93eed0638b74a8fec401577fAlex Deucher	{0x00000099, 0x00006000},
1218b074dd64053d0bf93eed0638b74a8fec401577fAlex Deucher	{0x0000009a, 0x00001000},
1228b074dd64053d0bf93eed0638b74a8fec401577fAlex Deucher	{0x0000009f, 0x00a77400}
1238b074dd64053d0bf93eed0638b74a8fec401577fAlex Deucher};
1248b074dd64053d0bf93eed0638b74a8fec401577fAlex Deucher
1258b074dd64053d0bf93eed0638b74a8fec401577fAlex Deucherstatic const u32 pitcairn_io_mc_regs[TAHITI_IO_MC_REGS_SIZE][2] = {
1268b074dd64053d0bf93eed0638b74a8fec401577fAlex Deucher	{0x0000006f, 0x03044000},
1278b074dd64053d0bf93eed0638b74a8fec401577fAlex Deucher	{0x00000070, 0x0480c018},
1288b074dd64053d0bf93eed0638b74a8fec401577fAlex Deucher	{0x00000071, 0x00000040},
1298b074dd64053d0bf93eed0638b74a8fec401577fAlex Deucher	{0x00000072, 0x01000000},
1308b074dd64053d0bf93eed0638b74a8fec401577fAlex Deucher	{0x00000074, 0x000000ff},
1318b074dd64053d0bf93eed0638b74a8fec401577fAlex Deucher	{0x00000075, 0x00143400},
1328b074dd64053d0bf93eed0638b74a8fec401577fAlex Deucher	{0x00000076, 0x08ec0800},
1338b074dd64053d0bf93eed0638b74a8fec401577fAlex Deucher	{0x00000077, 0x040000cc},
1348b074dd64053d0bf93eed0638b74a8fec401577fAlex Deucher	{0x00000079, 0x00000000},
1358b074dd64053d0bf93eed0638b74a8fec401577fAlex Deucher	{0x0000007a, 0x21000409},
1368b074dd64053d0bf93eed0638b74a8fec401577fAlex Deucher	{0x0000007c, 0x00000000},
1378b074dd64053d0bf93eed0638b74a8fec401577fAlex Deucher	{0x0000007d, 0xe8000000},
1388b074dd64053d0bf93eed0638b74a8fec401577fAlex Deucher	{0x0000007e, 0x044408a8},
1398b074dd64053d0bf93eed0638b74a8fec401577fAlex Deucher	{0x0000007f, 0x00000003},
1408b074dd64053d0bf93eed0638b74a8fec401577fAlex Deucher	{0x00000080, 0x00000000},
1418b074dd64053d0bf93eed0638b74a8fec401577fAlex Deucher	{0x00000081, 0x01000000},
1428b074dd64053d0bf93eed0638b74a8fec401577fAlex Deucher	{0x00000082, 0x02000000},
1438b074dd64053d0bf93eed0638b74a8fec401577fAlex Deucher	{0x00000083, 0x00000000},
1448b074dd64053d0bf93eed0638b74a8fec401577fAlex Deucher	{0x00000084, 0xe3f3e4f4},
1458b074dd64053d0bf93eed0638b74a8fec401577fAlex Deucher	{0x00000085, 0x00052024},
1468b074dd64053d0bf93eed0638b74a8fec401577fAlex Deucher	{0x00000087, 0x00000000},
1478b074dd64053d0bf93eed0638b74a8fec401577fAlex Deucher	{0x00000088, 0x66036603},
1488b074dd64053d0bf93eed0638b74a8fec401577fAlex Deucher	{0x00000089, 0x01000000},
1498b074dd64053d0bf93eed0638b74a8fec401577fAlex Deucher	{0x0000008b, 0x1c0a0000},
1508b074dd64053d0bf93eed0638b74a8fec401577fAlex Deucher	{0x0000008c, 0xff010000},
1518b074dd64053d0bf93eed0638b74a8fec401577fAlex Deucher	{0x0000008e, 0xffffefff},
1528b074dd64053d0bf93eed0638b74a8fec401577fAlex Deucher	{0x0000008f, 0xfff3efff},
1538b074dd64053d0bf93eed0638b74a8fec401577fAlex Deucher	{0x00000090, 0xfff3efbf},
1548b074dd64053d0bf93eed0638b74a8fec401577fAlex Deucher	{0x00000094, 0x00101101},
1558b074dd64053d0bf93eed0638b74a8fec401577fAlex Deucher	{0x00000095, 0x00000fff},
1568b074dd64053d0bf93eed0638b74a8fec401577fAlex Deucher	{0x00000096, 0x00116fff},
1578b074dd64053d0bf93eed0638b74a8fec401577fAlex Deucher	{0x00000097, 0x60010000},
1588b074dd64053d0bf93eed0638b74a8fec401577fAlex Deucher	{0x00000098, 0x10010000},
1598b074dd64053d0bf93eed0638b74a8fec401577fAlex Deucher	{0x00000099, 0x00006000},
1608b074dd64053d0bf93eed0638b74a8fec401577fAlex Deucher	{0x0000009a, 0x00001000},
1618b074dd64053d0bf93eed0638b74a8fec401577fAlex Deucher	{0x0000009f, 0x00a47400}
1628b074dd64053d0bf93eed0638b74a8fec401577fAlex Deucher};
1638b074dd64053d0bf93eed0638b74a8fec401577fAlex Deucher
1648b074dd64053d0bf93eed0638b74a8fec401577fAlex Deucherstatic const u32 verde_io_mc_regs[TAHITI_IO_MC_REGS_SIZE][2] = {
1658b074dd64053d0bf93eed0638b74a8fec401577fAlex Deucher	{0x0000006f, 0x03044000},
1668b074dd64053d0bf93eed0638b74a8fec401577fAlex Deucher	{0x00000070, 0x0480c018},
1678b074dd64053d0bf93eed0638b74a8fec401577fAlex Deucher	{0x00000071, 0x00000040},
1688b074dd64053d0bf93eed0638b74a8fec401577fAlex Deucher	{0x00000072, 0x01000000},
1698b074dd64053d0bf93eed0638b74a8fec401577fAlex Deucher	{0x00000074, 0x000000ff},
1708b074dd64053d0bf93eed0638b74a8fec401577fAlex Deucher	{0x00000075, 0x00143400},
1718b074dd64053d0bf93eed0638b74a8fec401577fAlex Deucher	{0x00000076, 0x08ec0800},
1728b074dd64053d0bf93eed0638b74a8fec401577fAlex Deucher	{0x00000077, 0x040000cc},
1738b074dd64053d0bf93eed0638b74a8fec401577fAlex Deucher	{0x00000079, 0x00000000},
1748b074dd64053d0bf93eed0638b74a8fec401577fAlex Deucher	{0x0000007a, 0x21000409},
1758b074dd64053d0bf93eed0638b74a8fec401577fAlex Deucher	{0x0000007c, 0x00000000},
1768b074dd64053d0bf93eed0638b74a8fec401577fAlex Deucher	{0x0000007d, 0xe8000000},
1778b074dd64053d0bf93eed0638b74a8fec401577fAlex Deucher	{0x0000007e, 0x044408a8},
1788b074dd64053d0bf93eed0638b74a8fec401577fAlex Deucher	{0x0000007f, 0x00000003},
1798b074dd64053d0bf93eed0638b74a8fec401577fAlex Deucher	{0x00000080, 0x00000000},
1808b074dd64053d0bf93eed0638b74a8fec401577fAlex Deucher	{0x00000081, 0x01000000},
1818b074dd64053d0bf93eed0638b74a8fec401577fAlex Deucher	{0x00000082, 0x02000000},
1828b074dd64053d0bf93eed0638b74a8fec401577fAlex Deucher	{0x00000083, 0x00000000},
1838b074dd64053d0bf93eed0638b74a8fec401577fAlex Deucher	{0x00000084, 0xe3f3e4f4},
1848b074dd64053d0bf93eed0638b74a8fec401577fAlex Deucher	{0x00000085, 0x00052024},
1858b074dd64053d0bf93eed0638b74a8fec401577fAlex Deucher	{0x00000087, 0x00000000},
1868b074dd64053d0bf93eed0638b74a8fec401577fAlex Deucher	{0x00000088, 0x66036603},
1878b074dd64053d0bf93eed0638b74a8fec401577fAlex Deucher	{0x00000089, 0x01000000},
1888b074dd64053d0bf93eed0638b74a8fec401577fAlex Deucher	{0x0000008b, 0x1c0a0000},
1898b074dd64053d0bf93eed0638b74a8fec401577fAlex Deucher	{0x0000008c, 0xff010000},
1908b074dd64053d0bf93eed0638b74a8fec401577fAlex Deucher	{0x0000008e, 0xffffefff},
1918b074dd64053d0bf93eed0638b74a8fec401577fAlex Deucher	{0x0000008f, 0xfff3efff},
1928b074dd64053d0bf93eed0638b74a8fec401577fAlex Deucher	{0x00000090, 0xfff3efbf},
1938b074dd64053d0bf93eed0638b74a8fec401577fAlex Deucher	{0x00000094, 0x00101101},
1948b074dd64053d0bf93eed0638b74a8fec401577fAlex Deucher	{0x00000095, 0x00000fff},
1958b074dd64053d0bf93eed0638b74a8fec401577fAlex Deucher	{0x00000096, 0x00116fff},
1968b074dd64053d0bf93eed0638b74a8fec401577fAlex Deucher	{0x00000097, 0x60010000},
1978b074dd64053d0bf93eed0638b74a8fec401577fAlex Deucher	{0x00000098, 0x10010000},
1988b074dd64053d0bf93eed0638b74a8fec401577fAlex Deucher	{0x00000099, 0x00006000},
1998b074dd64053d0bf93eed0638b74a8fec401577fAlex Deucher	{0x0000009a, 0x00001000},
2008b074dd64053d0bf93eed0638b74a8fec401577fAlex Deucher	{0x0000009f, 0x00a37400}
2018b074dd64053d0bf93eed0638b74a8fec401577fAlex Deucher};
2028b074dd64053d0bf93eed0638b74a8fec401577fAlex Deucher
2038b074dd64053d0bf93eed0638b74a8fec401577fAlex Deucher/* ucode loading */
2048b074dd64053d0bf93eed0638b74a8fec401577fAlex Deucherstatic int si_mc_load_microcode(struct radeon_device *rdev)
2058b074dd64053d0bf93eed0638b74a8fec401577fAlex Deucher{
2068b074dd64053d0bf93eed0638b74a8fec401577fAlex Deucher	const __be32 *fw_data;
2078b074dd64053d0bf93eed0638b74a8fec401577fAlex Deucher	u32 running, blackout = 0;
2088b074dd64053d0bf93eed0638b74a8fec401577fAlex Deucher	u32 *io_mc_regs;
2098b074dd64053d0bf93eed0638b74a8fec401577fAlex Deucher	int i, ucode_size, regs_size;
2108b074dd64053d0bf93eed0638b74a8fec401577fAlex Deucher
2118b074dd64053d0bf93eed0638b74a8fec401577fAlex Deucher	if (!rdev->mc_fw)
2128b074dd64053d0bf93eed0638b74a8fec401577fAlex Deucher		return -EINVAL;
2138b074dd64053d0bf93eed0638b74a8fec401577fAlex Deucher
2148b074dd64053d0bf93eed0638b74a8fec401577fAlex Deucher	switch (rdev->family) {
2158b074dd64053d0bf93eed0638b74a8fec401577fAlex Deucher	case CHIP_TAHITI:
2168b074dd64053d0bf93eed0638b74a8fec401577fAlex Deucher		io_mc_regs = (u32 *)&tahiti_io_mc_regs;
2178b074dd64053d0bf93eed0638b74a8fec401577fAlex Deucher		ucode_size = SI_MC_UCODE_SIZE;
2188b074dd64053d0bf93eed0638b74a8fec401577fAlex Deucher		regs_size = TAHITI_IO_MC_REGS_SIZE;
2198b074dd64053d0bf93eed0638b74a8fec401577fAlex Deucher		break;
2208b074dd64053d0bf93eed0638b74a8fec401577fAlex Deucher	case CHIP_PITCAIRN:
2218b074dd64053d0bf93eed0638b74a8fec401577fAlex Deucher		io_mc_regs = (u32 *)&pitcairn_io_mc_regs;
2228b074dd64053d0bf93eed0638b74a8fec401577fAlex Deucher		ucode_size = SI_MC_UCODE_SIZE;
2238b074dd64053d0bf93eed0638b74a8fec401577fAlex Deucher		regs_size = TAHITI_IO_MC_REGS_SIZE;
2248b074dd64053d0bf93eed0638b74a8fec401577fAlex Deucher		break;
2258b074dd64053d0bf93eed0638b74a8fec401577fAlex Deucher	case CHIP_VERDE:
2268b074dd64053d0bf93eed0638b74a8fec401577fAlex Deucher	default:
2278b074dd64053d0bf93eed0638b74a8fec401577fAlex Deucher		io_mc_regs = (u32 *)&verde_io_mc_regs;
2288b074dd64053d0bf93eed0638b74a8fec401577fAlex Deucher		ucode_size = SI_MC_UCODE_SIZE;
2298b074dd64053d0bf93eed0638b74a8fec401577fAlex Deucher		regs_size = TAHITI_IO_MC_REGS_SIZE;
2308b074dd64053d0bf93eed0638b74a8fec401577fAlex Deucher		break;
2318b074dd64053d0bf93eed0638b74a8fec401577fAlex Deucher	}
2328b074dd64053d0bf93eed0638b74a8fec401577fAlex Deucher
2338b074dd64053d0bf93eed0638b74a8fec401577fAlex Deucher	running = RREG32(MC_SEQ_SUP_CNTL) & RUN_MASK;
2348b074dd64053d0bf93eed0638b74a8fec401577fAlex Deucher
2358b074dd64053d0bf93eed0638b74a8fec401577fAlex Deucher	if (running == 0) {
2368b074dd64053d0bf93eed0638b74a8fec401577fAlex Deucher		if (running) {
2378b074dd64053d0bf93eed0638b74a8fec401577fAlex Deucher			blackout = RREG32(MC_SHARED_BLACKOUT_CNTL);
2388b074dd64053d0bf93eed0638b74a8fec401577fAlex Deucher			WREG32(MC_SHARED_BLACKOUT_CNTL, blackout | 1);
2398b074dd64053d0bf93eed0638b74a8fec401577fAlex Deucher		}
2408b074dd64053d0bf93eed0638b74a8fec401577fAlex Deucher
2418b074dd64053d0bf93eed0638b74a8fec401577fAlex Deucher		/* reset the engine and set to writable */
2428b074dd64053d0bf93eed0638b74a8fec401577fAlex Deucher		WREG32(MC_SEQ_SUP_CNTL, 0x00000008);
2438b074dd64053d0bf93eed0638b74a8fec401577fAlex Deucher		WREG32(MC_SEQ_SUP_CNTL, 0x00000010);
2448b074dd64053d0bf93eed0638b74a8fec401577fAlex Deucher
2458b074dd64053d0bf93eed0638b74a8fec401577fAlex Deucher		/* load mc io regs */
2468b074dd64053d0bf93eed0638b74a8fec401577fAlex Deucher		for (i = 0; i < regs_size; i++) {
2478b074dd64053d0bf93eed0638b74a8fec401577fAlex Deucher			WREG32(MC_SEQ_IO_DEBUG_INDEX, io_mc_regs[(i << 1)]);
2488b074dd64053d0bf93eed0638b74a8fec401577fAlex Deucher			WREG32(MC_SEQ_IO_DEBUG_DATA, io_mc_regs[(i << 1) + 1]);
2498b074dd64053d0bf93eed0638b74a8fec401577fAlex Deucher		}
2508b074dd64053d0bf93eed0638b74a8fec401577fAlex Deucher		/* load the MC ucode */
2518b074dd64053d0bf93eed0638b74a8fec401577fAlex Deucher		fw_data = (const __be32 *)rdev->mc_fw->data;
2528b074dd64053d0bf93eed0638b74a8fec401577fAlex Deucher		for (i = 0; i < ucode_size; i++)
2538b074dd64053d0bf93eed0638b74a8fec401577fAlex Deucher			WREG32(MC_SEQ_SUP_PGM, be32_to_cpup(fw_data++));
2548b074dd64053d0bf93eed0638b74a8fec401577fAlex Deucher
2558b074dd64053d0bf93eed0638b74a8fec401577fAlex Deucher		/* put the engine back into the active state */
2568b074dd64053d0bf93eed0638b74a8fec401577fAlex Deucher		WREG32(MC_SEQ_SUP_CNTL, 0x00000008);
2578b074dd64053d0bf93eed0638b74a8fec401577fAlex Deucher		WREG32(MC_SEQ_SUP_CNTL, 0x00000004);
2588b074dd64053d0bf93eed0638b74a8fec401577fAlex Deucher		WREG32(MC_SEQ_SUP_CNTL, 0x00000001);
2598b074dd64053d0bf93eed0638b74a8fec401577fAlex Deucher
2608b074dd64053d0bf93eed0638b74a8fec401577fAlex Deucher		/* wait for training to complete */
2618b074dd64053d0bf93eed0638b74a8fec401577fAlex Deucher		for (i = 0; i < rdev->usec_timeout; i++) {
2628b074dd64053d0bf93eed0638b74a8fec401577fAlex Deucher			if (RREG32(MC_SEQ_TRAIN_WAKEUP_CNTL) & TRAIN_DONE_D0)
2638b074dd64053d0bf93eed0638b74a8fec401577fAlex Deucher				break;
2648b074dd64053d0bf93eed0638b74a8fec401577fAlex Deucher			udelay(1);
2658b074dd64053d0bf93eed0638b74a8fec401577fAlex Deucher		}
2668b074dd64053d0bf93eed0638b74a8fec401577fAlex Deucher		for (i = 0; i < rdev->usec_timeout; i++) {
2678b074dd64053d0bf93eed0638b74a8fec401577fAlex Deucher			if (RREG32(MC_SEQ_TRAIN_WAKEUP_CNTL) & TRAIN_DONE_D1)
2688b074dd64053d0bf93eed0638b74a8fec401577fAlex Deucher				break;
2698b074dd64053d0bf93eed0638b74a8fec401577fAlex Deucher			udelay(1);
2708b074dd64053d0bf93eed0638b74a8fec401577fAlex Deucher		}
2718b074dd64053d0bf93eed0638b74a8fec401577fAlex Deucher
2728b074dd64053d0bf93eed0638b74a8fec401577fAlex Deucher		if (running)
2738b074dd64053d0bf93eed0638b74a8fec401577fAlex Deucher			WREG32(MC_SHARED_BLACKOUT_CNTL, blackout);
2748b074dd64053d0bf93eed0638b74a8fec401577fAlex Deucher	}
2758b074dd64053d0bf93eed0638b74a8fec401577fAlex Deucher
2768b074dd64053d0bf93eed0638b74a8fec401577fAlex Deucher	return 0;
2778b074dd64053d0bf93eed0638b74a8fec401577fAlex Deucher}
2788b074dd64053d0bf93eed0638b74a8fec401577fAlex Deucher
2790f0de06c809eac783ddb4ddfc52c9db43af94b4fAlex Deucherstatic int si_init_microcode(struct radeon_device *rdev)
2800f0de06c809eac783ddb4ddfc52c9db43af94b4fAlex Deucher{
2810f0de06c809eac783ddb4ddfc52c9db43af94b4fAlex Deucher	struct platform_device *pdev;
2820f0de06c809eac783ddb4ddfc52c9db43af94b4fAlex Deucher	const char *chip_name;
2830f0de06c809eac783ddb4ddfc52c9db43af94b4fAlex Deucher	const char *rlc_chip_name;
2840f0de06c809eac783ddb4ddfc52c9db43af94b4fAlex Deucher	size_t pfp_req_size, me_req_size, ce_req_size, rlc_req_size, mc_req_size;
2850f0de06c809eac783ddb4ddfc52c9db43af94b4fAlex Deucher	char fw_name[30];
2860f0de06c809eac783ddb4ddfc52c9db43af94b4fAlex Deucher	int err;
2870f0de06c809eac783ddb4ddfc52c9db43af94b4fAlex Deucher
2880f0de06c809eac783ddb4ddfc52c9db43af94b4fAlex Deucher	DRM_DEBUG("\n");
2890f0de06c809eac783ddb4ddfc52c9db43af94b4fAlex Deucher
2900f0de06c809eac783ddb4ddfc52c9db43af94b4fAlex Deucher	pdev = platform_device_register_simple("radeon_cp", 0, NULL, 0);
2910f0de06c809eac783ddb4ddfc52c9db43af94b4fAlex Deucher	err = IS_ERR(pdev);
2920f0de06c809eac783ddb4ddfc52c9db43af94b4fAlex Deucher	if (err) {
2930f0de06c809eac783ddb4ddfc52c9db43af94b4fAlex Deucher		printk(KERN_ERR "radeon_cp: Failed to register firmware\n");
2940f0de06c809eac783ddb4ddfc52c9db43af94b4fAlex Deucher		return -EINVAL;
2950f0de06c809eac783ddb4ddfc52c9db43af94b4fAlex Deucher	}
2960f0de06c809eac783ddb4ddfc52c9db43af94b4fAlex Deucher
2970f0de06c809eac783ddb4ddfc52c9db43af94b4fAlex Deucher	switch (rdev->family) {
2980f0de06c809eac783ddb4ddfc52c9db43af94b4fAlex Deucher	case CHIP_TAHITI:
2990f0de06c809eac783ddb4ddfc52c9db43af94b4fAlex Deucher		chip_name = "TAHITI";
3000f0de06c809eac783ddb4ddfc52c9db43af94b4fAlex Deucher		rlc_chip_name = "TAHITI";
3010f0de06c809eac783ddb4ddfc52c9db43af94b4fAlex Deucher		pfp_req_size = SI_PFP_UCODE_SIZE * 4;
3020f0de06c809eac783ddb4ddfc52c9db43af94b4fAlex Deucher		me_req_size = SI_PM4_UCODE_SIZE * 4;
3030f0de06c809eac783ddb4ddfc52c9db43af94b4fAlex Deucher		ce_req_size = SI_CE_UCODE_SIZE * 4;
3040f0de06c809eac783ddb4ddfc52c9db43af94b4fAlex Deucher		rlc_req_size = SI_RLC_UCODE_SIZE * 4;
3050f0de06c809eac783ddb4ddfc52c9db43af94b4fAlex Deucher		mc_req_size = SI_MC_UCODE_SIZE * 4;
3060f0de06c809eac783ddb4ddfc52c9db43af94b4fAlex Deucher		break;
3070f0de06c809eac783ddb4ddfc52c9db43af94b4fAlex Deucher	case CHIP_PITCAIRN:
3080f0de06c809eac783ddb4ddfc52c9db43af94b4fAlex Deucher		chip_name = "PITCAIRN";
3090f0de06c809eac783ddb4ddfc52c9db43af94b4fAlex Deucher		rlc_chip_name = "PITCAIRN";
3100f0de06c809eac783ddb4ddfc52c9db43af94b4fAlex Deucher		pfp_req_size = SI_PFP_UCODE_SIZE * 4;
3110f0de06c809eac783ddb4ddfc52c9db43af94b4fAlex Deucher		me_req_size = SI_PM4_UCODE_SIZE * 4;
3120f0de06c809eac783ddb4ddfc52c9db43af94b4fAlex Deucher		ce_req_size = SI_CE_UCODE_SIZE * 4;
3130f0de06c809eac783ddb4ddfc52c9db43af94b4fAlex Deucher		rlc_req_size = SI_RLC_UCODE_SIZE * 4;
3140f0de06c809eac783ddb4ddfc52c9db43af94b4fAlex Deucher		mc_req_size = SI_MC_UCODE_SIZE * 4;
3150f0de06c809eac783ddb4ddfc52c9db43af94b4fAlex Deucher		break;
3160f0de06c809eac783ddb4ddfc52c9db43af94b4fAlex Deucher	case CHIP_VERDE:
3170f0de06c809eac783ddb4ddfc52c9db43af94b4fAlex Deucher		chip_name = "VERDE";
3180f0de06c809eac783ddb4ddfc52c9db43af94b4fAlex Deucher		rlc_chip_name = "VERDE";
3190f0de06c809eac783ddb4ddfc52c9db43af94b4fAlex Deucher		pfp_req_size = SI_PFP_UCODE_SIZE * 4;
3200f0de06c809eac783ddb4ddfc52c9db43af94b4fAlex Deucher		me_req_size = SI_PM4_UCODE_SIZE * 4;
3210f0de06c809eac783ddb4ddfc52c9db43af94b4fAlex Deucher		ce_req_size = SI_CE_UCODE_SIZE * 4;
3220f0de06c809eac783ddb4ddfc52c9db43af94b4fAlex Deucher		rlc_req_size = SI_RLC_UCODE_SIZE * 4;
3230f0de06c809eac783ddb4ddfc52c9db43af94b4fAlex Deucher		mc_req_size = SI_MC_UCODE_SIZE * 4;
3240f0de06c809eac783ddb4ddfc52c9db43af94b4fAlex Deucher		break;
3250f0de06c809eac783ddb4ddfc52c9db43af94b4fAlex Deucher	default: BUG();
3260f0de06c809eac783ddb4ddfc52c9db43af94b4fAlex Deucher	}
3270f0de06c809eac783ddb4ddfc52c9db43af94b4fAlex Deucher
3280f0de06c809eac783ddb4ddfc52c9db43af94b4fAlex Deucher	DRM_INFO("Loading %s Microcode\n", chip_name);
3290f0de06c809eac783ddb4ddfc52c9db43af94b4fAlex Deucher
3300f0de06c809eac783ddb4ddfc52c9db43af94b4fAlex Deucher	snprintf(fw_name, sizeof(fw_name), "radeon/%s_pfp.bin", chip_name);
3310f0de06c809eac783ddb4ddfc52c9db43af94b4fAlex Deucher	err = request_firmware(&rdev->pfp_fw, fw_name, &pdev->dev);
3320f0de06c809eac783ddb4ddfc52c9db43af94b4fAlex Deucher	if (err)
3330f0de06c809eac783ddb4ddfc52c9db43af94b4fAlex Deucher		goto out;
3340f0de06c809eac783ddb4ddfc52c9db43af94b4fAlex Deucher	if (rdev->pfp_fw->size != pfp_req_size) {
3350f0de06c809eac783ddb4ddfc52c9db43af94b4fAlex Deucher		printk(KERN_ERR
3360f0de06c809eac783ddb4ddfc52c9db43af94b4fAlex Deucher		       "si_cp: Bogus length %zu in firmware \"%s\"\n",
3370f0de06c809eac783ddb4ddfc52c9db43af94b4fAlex Deucher		       rdev->pfp_fw->size, fw_name);
3380f0de06c809eac783ddb4ddfc52c9db43af94b4fAlex Deucher		err = -EINVAL;
3390f0de06c809eac783ddb4ddfc52c9db43af94b4fAlex Deucher		goto out;
3400f0de06c809eac783ddb4ddfc52c9db43af94b4fAlex Deucher	}
3410f0de06c809eac783ddb4ddfc52c9db43af94b4fAlex Deucher
3420f0de06c809eac783ddb4ddfc52c9db43af94b4fAlex Deucher	snprintf(fw_name, sizeof(fw_name), "radeon/%s_me.bin", chip_name);
3430f0de06c809eac783ddb4ddfc52c9db43af94b4fAlex Deucher	err = request_firmware(&rdev->me_fw, fw_name, &pdev->dev);
3440f0de06c809eac783ddb4ddfc52c9db43af94b4fAlex Deucher	if (err)
3450f0de06c809eac783ddb4ddfc52c9db43af94b4fAlex Deucher		goto out;
3460f0de06c809eac783ddb4ddfc52c9db43af94b4fAlex Deucher	if (rdev->me_fw->size != me_req_size) {
3470f0de06c809eac783ddb4ddfc52c9db43af94b4fAlex Deucher		printk(KERN_ERR
3480f0de06c809eac783ddb4ddfc52c9db43af94b4fAlex Deucher		       "si_cp: Bogus length %zu in firmware \"%s\"\n",
3490f0de06c809eac783ddb4ddfc52c9db43af94b4fAlex Deucher		       rdev->me_fw->size, fw_name);
3500f0de06c809eac783ddb4ddfc52c9db43af94b4fAlex Deucher		err = -EINVAL;
3510f0de06c809eac783ddb4ddfc52c9db43af94b4fAlex Deucher	}
3520f0de06c809eac783ddb4ddfc52c9db43af94b4fAlex Deucher
3530f0de06c809eac783ddb4ddfc52c9db43af94b4fAlex Deucher	snprintf(fw_name, sizeof(fw_name), "radeon/%s_ce.bin", chip_name);
3540f0de06c809eac783ddb4ddfc52c9db43af94b4fAlex Deucher	err = request_firmware(&rdev->ce_fw, fw_name, &pdev->dev);
3550f0de06c809eac783ddb4ddfc52c9db43af94b4fAlex Deucher	if (err)
3560f0de06c809eac783ddb4ddfc52c9db43af94b4fAlex Deucher		goto out;
3570f0de06c809eac783ddb4ddfc52c9db43af94b4fAlex Deucher	if (rdev->ce_fw->size != ce_req_size) {
3580f0de06c809eac783ddb4ddfc52c9db43af94b4fAlex Deucher		printk(KERN_ERR
3590f0de06c809eac783ddb4ddfc52c9db43af94b4fAlex Deucher		       "si_cp: Bogus length %zu in firmware \"%s\"\n",
3600f0de06c809eac783ddb4ddfc52c9db43af94b4fAlex Deucher		       rdev->ce_fw->size, fw_name);
3610f0de06c809eac783ddb4ddfc52c9db43af94b4fAlex Deucher		err = -EINVAL;
3620f0de06c809eac783ddb4ddfc52c9db43af94b4fAlex Deucher	}
3630f0de06c809eac783ddb4ddfc52c9db43af94b4fAlex Deucher
3640f0de06c809eac783ddb4ddfc52c9db43af94b4fAlex Deucher	snprintf(fw_name, sizeof(fw_name), "radeon/%s_rlc.bin", rlc_chip_name);
3650f0de06c809eac783ddb4ddfc52c9db43af94b4fAlex Deucher	err = request_firmware(&rdev->rlc_fw, fw_name, &pdev->dev);
3660f0de06c809eac783ddb4ddfc52c9db43af94b4fAlex Deucher	if (err)
3670f0de06c809eac783ddb4ddfc52c9db43af94b4fAlex Deucher		goto out;
3680f0de06c809eac783ddb4ddfc52c9db43af94b4fAlex Deucher	if (rdev->rlc_fw->size != rlc_req_size) {
3690f0de06c809eac783ddb4ddfc52c9db43af94b4fAlex Deucher		printk(KERN_ERR
3700f0de06c809eac783ddb4ddfc52c9db43af94b4fAlex Deucher		       "si_rlc: Bogus length %zu in firmware \"%s\"\n",
3710f0de06c809eac783ddb4ddfc52c9db43af94b4fAlex Deucher		       rdev->rlc_fw->size, fw_name);
3720f0de06c809eac783ddb4ddfc52c9db43af94b4fAlex Deucher		err = -EINVAL;
3730f0de06c809eac783ddb4ddfc52c9db43af94b4fAlex Deucher	}
3740f0de06c809eac783ddb4ddfc52c9db43af94b4fAlex Deucher
3750f0de06c809eac783ddb4ddfc52c9db43af94b4fAlex Deucher	snprintf(fw_name, sizeof(fw_name), "radeon/%s_mc.bin", chip_name);
3760f0de06c809eac783ddb4ddfc52c9db43af94b4fAlex Deucher	err = request_firmware(&rdev->mc_fw, fw_name, &pdev->dev);
3770f0de06c809eac783ddb4ddfc52c9db43af94b4fAlex Deucher	if (err)
3780f0de06c809eac783ddb4ddfc52c9db43af94b4fAlex Deucher		goto out;
3790f0de06c809eac783ddb4ddfc52c9db43af94b4fAlex Deucher	if (rdev->mc_fw->size != mc_req_size) {
3800f0de06c809eac783ddb4ddfc52c9db43af94b4fAlex Deucher		printk(KERN_ERR
3810f0de06c809eac783ddb4ddfc52c9db43af94b4fAlex Deucher		       "si_mc: Bogus length %zu in firmware \"%s\"\n",
3820f0de06c809eac783ddb4ddfc52c9db43af94b4fAlex Deucher		       rdev->mc_fw->size, fw_name);
3830f0de06c809eac783ddb4ddfc52c9db43af94b4fAlex Deucher		err = -EINVAL;
3840f0de06c809eac783ddb4ddfc52c9db43af94b4fAlex Deucher	}
3850f0de06c809eac783ddb4ddfc52c9db43af94b4fAlex Deucher
3860f0de06c809eac783ddb4ddfc52c9db43af94b4fAlex Deucherout:
3870f0de06c809eac783ddb4ddfc52c9db43af94b4fAlex Deucher	platform_device_unregister(pdev);
3880f0de06c809eac783ddb4ddfc52c9db43af94b4fAlex Deucher
3890f0de06c809eac783ddb4ddfc52c9db43af94b4fAlex Deucher	if (err) {
3900f0de06c809eac783ddb4ddfc52c9db43af94b4fAlex Deucher		if (err != -EINVAL)
3910f0de06c809eac783ddb4ddfc52c9db43af94b4fAlex Deucher			printk(KERN_ERR
3920f0de06c809eac783ddb4ddfc52c9db43af94b4fAlex Deucher			       "si_cp: Failed to load firmware \"%s\"\n",
3930f0de06c809eac783ddb4ddfc52c9db43af94b4fAlex Deucher			       fw_name);
3940f0de06c809eac783ddb4ddfc52c9db43af94b4fAlex Deucher		release_firmware(rdev->pfp_fw);
3950f0de06c809eac783ddb4ddfc52c9db43af94b4fAlex Deucher		rdev->pfp_fw = NULL;
3960f0de06c809eac783ddb4ddfc52c9db43af94b4fAlex Deucher		release_firmware(rdev->me_fw);
3970f0de06c809eac783ddb4ddfc52c9db43af94b4fAlex Deucher		rdev->me_fw = NULL;
3980f0de06c809eac783ddb4ddfc52c9db43af94b4fAlex Deucher		release_firmware(rdev->ce_fw);
3990f0de06c809eac783ddb4ddfc52c9db43af94b4fAlex Deucher		rdev->ce_fw = NULL;
4000f0de06c809eac783ddb4ddfc52c9db43af94b4fAlex Deucher		release_firmware(rdev->rlc_fw);
4010f0de06c809eac783ddb4ddfc52c9db43af94b4fAlex Deucher		rdev->rlc_fw = NULL;
4020f0de06c809eac783ddb4ddfc52c9db43af94b4fAlex Deucher		release_firmware(rdev->mc_fw);
4030f0de06c809eac783ddb4ddfc52c9db43af94b4fAlex Deucher		rdev->mc_fw = NULL;
4040f0de06c809eac783ddb4ddfc52c9db43af94b4fAlex Deucher	}
4050f0de06c809eac783ddb4ddfc52c9db43af94b4fAlex Deucher	return err;
4060f0de06c809eac783ddb4ddfc52c9db43af94b4fAlex Deucher}
4070f0de06c809eac783ddb4ddfc52c9db43af94b4fAlex Deucher
40843b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher/* watermark setup */
40943b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucherstatic u32 dce6_line_buffer_adjust(struct radeon_device *rdev,
41043b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher				   struct radeon_crtc *radeon_crtc,
41143b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher				   struct drm_display_mode *mode,
41243b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher				   struct drm_display_mode *other_mode)
41343b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher{
41443b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	u32 tmp;
41543b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	/*
41643b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	 * Line Buffer Setup
41743b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	 * There are 3 line buffers, each one shared by 2 display controllers.
41843b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	 * DC_LB_MEMORY_SPLIT controls how that line buffer is shared between
41943b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	 * the display controllers.  The paritioning is done via one of four
42043b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	 * preset allocations specified in bits 21:20:
42143b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	 *  0 - half lb
42243b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	 *  2 - whole lb, other crtc must be disabled
42343b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	 */
42443b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	/* this can get tricky if we have two large displays on a paired group
42543b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	 * of crtcs.  Ideally for multiple large displays we'd assign them to
42643b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	 * non-linked crtcs for maximum line buffer allocation.
42743b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	 */
42843b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	if (radeon_crtc->base.enabled && mode) {
42943b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher		if (other_mode)
43043b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher			tmp = 0; /* 1/2 */
43143b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher		else
43243b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher			tmp = 2; /* whole */
43343b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	} else
43443b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher		tmp = 0;
43543b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher
43643b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	WREG32(DC_LB_MEMORY_SPLIT + radeon_crtc->crtc_offset,
43743b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	       DC_LB_MEMORY_CONFIG(tmp));
43843b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher
43943b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	if (radeon_crtc->base.enabled && mode) {
44043b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher		switch (tmp) {
44143b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher		case 0:
44243b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher		default:
44343b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher			return 4096 * 2;
44443b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher		case 2:
44543b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher			return 8192 * 2;
44643b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher		}
44743b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	}
44843b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher
44943b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	/* controller not enabled, so no lb used */
45043b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	return 0;
45143b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher}
45243b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher
453ca7db22bc59ced2f180f37db8470140225d75860Alex Deucherstatic u32 si_get_number_of_dram_channels(struct radeon_device *rdev)
45443b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher{
45543b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	u32 tmp = RREG32(MC_SHARED_CHMAP);
45643b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher
45743b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	switch ((tmp & NOOFCHAN_MASK) >> NOOFCHAN_SHIFT) {
45843b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	case 0:
45943b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	default:
46043b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher		return 1;
46143b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	case 1:
46243b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher		return 2;
46343b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	case 2:
46443b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher		return 4;
46543b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	case 3:
46643b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher		return 8;
46743b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	case 4:
46843b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher		return 3;
46943b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	case 5:
47043b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher		return 6;
47143b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	case 6:
47243b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher		return 10;
47343b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	case 7:
47443b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher		return 12;
47543b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	case 8:
47643b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher		return 16;
47743b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	}
47843b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher}
47943b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher
48043b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucherstruct dce6_wm_params {
48143b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	u32 dram_channels; /* number of dram channels */
48243b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	u32 yclk;          /* bandwidth per dram data pin in kHz */
48343b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	u32 sclk;          /* engine clock in kHz */
48443b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	u32 disp_clk;      /* display clock in kHz */
48543b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	u32 src_width;     /* viewport width */
48643b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	u32 active_time;   /* active display time in ns */
48743b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	u32 blank_time;    /* blank time in ns */
48843b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	bool interlaced;    /* mode is interlaced */
48943b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	fixed20_12 vsc;    /* vertical scale ratio */
49043b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	u32 num_heads;     /* number of active crtcs */
49143b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	u32 bytes_per_pixel; /* bytes per pixel display + overlay */
49243b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	u32 lb_size;       /* line buffer allocated to pipe */
49343b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	u32 vtaps;         /* vertical scaler taps */
49443b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher};
49543b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher
49643b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucherstatic u32 dce6_dram_bandwidth(struct dce6_wm_params *wm)
49743b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher{
49843b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	/* Calculate raw DRAM Bandwidth */
49943b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	fixed20_12 dram_efficiency; /* 0.7 */
50043b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	fixed20_12 yclk, dram_channels, bandwidth;
50143b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	fixed20_12 a;
50243b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher
50343b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	a.full = dfixed_const(1000);
50443b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	yclk.full = dfixed_const(wm->yclk);
50543b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	yclk.full = dfixed_div(yclk, a);
50643b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	dram_channels.full = dfixed_const(wm->dram_channels * 4);
50743b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	a.full = dfixed_const(10);
50843b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	dram_efficiency.full = dfixed_const(7);
50943b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	dram_efficiency.full = dfixed_div(dram_efficiency, a);
51043b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	bandwidth.full = dfixed_mul(dram_channels, yclk);
51143b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	bandwidth.full = dfixed_mul(bandwidth, dram_efficiency);
51243b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher
51343b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	return dfixed_trunc(bandwidth);
51443b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher}
51543b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher
51643b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucherstatic u32 dce6_dram_bandwidth_for_display(struct dce6_wm_params *wm)
51743b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher{
51843b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	/* Calculate DRAM Bandwidth and the part allocated to display. */
51943b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	fixed20_12 disp_dram_allocation; /* 0.3 to 0.7 */
52043b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	fixed20_12 yclk, dram_channels, bandwidth;
52143b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	fixed20_12 a;
52243b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher
52343b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	a.full = dfixed_const(1000);
52443b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	yclk.full = dfixed_const(wm->yclk);
52543b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	yclk.full = dfixed_div(yclk, a);
52643b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	dram_channels.full = dfixed_const(wm->dram_channels * 4);
52743b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	a.full = dfixed_const(10);
52843b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	disp_dram_allocation.full = dfixed_const(3); /* XXX worse case value 0.3 */
52943b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	disp_dram_allocation.full = dfixed_div(disp_dram_allocation, a);
53043b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	bandwidth.full = dfixed_mul(dram_channels, yclk);
53143b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	bandwidth.full = dfixed_mul(bandwidth, disp_dram_allocation);
53243b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher
53343b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	return dfixed_trunc(bandwidth);
53443b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher}
53543b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher
53643b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucherstatic u32 dce6_data_return_bandwidth(struct dce6_wm_params *wm)
53743b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher{
53843b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	/* Calculate the display Data return Bandwidth */
53943b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	fixed20_12 return_efficiency; /* 0.8 */
54043b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	fixed20_12 sclk, bandwidth;
54143b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	fixed20_12 a;
54243b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher
54343b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	a.full = dfixed_const(1000);
54443b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	sclk.full = dfixed_const(wm->sclk);
54543b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	sclk.full = dfixed_div(sclk, a);
54643b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	a.full = dfixed_const(10);
54743b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	return_efficiency.full = dfixed_const(8);
54843b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	return_efficiency.full = dfixed_div(return_efficiency, a);
54943b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	a.full = dfixed_const(32);
55043b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	bandwidth.full = dfixed_mul(a, sclk);
55143b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	bandwidth.full = dfixed_mul(bandwidth, return_efficiency);
55243b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher
55343b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	return dfixed_trunc(bandwidth);
55443b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher}
55543b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher
55643b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucherstatic u32 dce6_get_dmif_bytes_per_request(struct dce6_wm_params *wm)
55743b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher{
55843b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	return 32;
55943b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher}
56043b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher
56143b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucherstatic u32 dce6_dmif_request_bandwidth(struct dce6_wm_params *wm)
56243b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher{
56343b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	/* Calculate the DMIF Request Bandwidth */
56443b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	fixed20_12 disp_clk_request_efficiency; /* 0.8 */
56543b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	fixed20_12 disp_clk, sclk, bandwidth;
56643b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	fixed20_12 a, b1, b2;
56743b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	u32 min_bandwidth;
56843b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher
56943b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	a.full = dfixed_const(1000);
57043b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	disp_clk.full = dfixed_const(wm->disp_clk);
57143b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	disp_clk.full = dfixed_div(disp_clk, a);
57243b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	a.full = dfixed_const(dce6_get_dmif_bytes_per_request(wm) / 2);
57343b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	b1.full = dfixed_mul(a, disp_clk);
57443b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher
57543b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	a.full = dfixed_const(1000);
57643b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	sclk.full = dfixed_const(wm->sclk);
57743b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	sclk.full = dfixed_div(sclk, a);
57843b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	a.full = dfixed_const(dce6_get_dmif_bytes_per_request(wm));
57943b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	b2.full = dfixed_mul(a, sclk);
58043b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher
58143b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	a.full = dfixed_const(10);
58243b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	disp_clk_request_efficiency.full = dfixed_const(8);
58343b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	disp_clk_request_efficiency.full = dfixed_div(disp_clk_request_efficiency, a);
58443b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher
58543b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	min_bandwidth = min(dfixed_trunc(b1), dfixed_trunc(b2));
58643b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher
58743b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	a.full = dfixed_const(min_bandwidth);
58843b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	bandwidth.full = dfixed_mul(a, disp_clk_request_efficiency);
58943b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher
59043b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	return dfixed_trunc(bandwidth);
59143b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher}
59243b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher
59343b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucherstatic u32 dce6_available_bandwidth(struct dce6_wm_params *wm)
59443b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher{
59543b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	/* Calculate the Available bandwidth. Display can use this temporarily but not in average. */
59643b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	u32 dram_bandwidth = dce6_dram_bandwidth(wm);
59743b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	u32 data_return_bandwidth = dce6_data_return_bandwidth(wm);
59843b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	u32 dmif_req_bandwidth = dce6_dmif_request_bandwidth(wm);
59943b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher
60043b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	return min(dram_bandwidth, min(data_return_bandwidth, dmif_req_bandwidth));
60143b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher}
60243b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher
60343b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucherstatic u32 dce6_average_bandwidth(struct dce6_wm_params *wm)
60443b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher{
60543b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	/* Calculate the display mode Average Bandwidth
60643b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	 * DisplayMode should contain the source and destination dimensions,
60743b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	 * timing, etc.
60843b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	 */
60943b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	fixed20_12 bpp;
61043b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	fixed20_12 line_time;
61143b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	fixed20_12 src_width;
61243b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	fixed20_12 bandwidth;
61343b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	fixed20_12 a;
61443b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher
61543b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	a.full = dfixed_const(1000);
61643b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	line_time.full = dfixed_const(wm->active_time + wm->blank_time);
61743b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	line_time.full = dfixed_div(line_time, a);
61843b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	bpp.full = dfixed_const(wm->bytes_per_pixel);
61943b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	src_width.full = dfixed_const(wm->src_width);
62043b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	bandwidth.full = dfixed_mul(src_width, bpp);
62143b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	bandwidth.full = dfixed_mul(bandwidth, wm->vsc);
62243b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	bandwidth.full = dfixed_div(bandwidth, line_time);
62343b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher
62443b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	return dfixed_trunc(bandwidth);
62543b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher}
62643b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher
62743b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucherstatic u32 dce6_latency_watermark(struct dce6_wm_params *wm)
62843b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher{
62943b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	/* First calcualte the latency in ns */
63043b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	u32 mc_latency = 2000; /* 2000 ns. */
63143b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	u32 available_bandwidth = dce6_available_bandwidth(wm);
63243b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	u32 worst_chunk_return_time = (512 * 8 * 1000) / available_bandwidth;
63343b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	u32 cursor_line_pair_return_time = (128 * 4 * 1000) / available_bandwidth;
63443b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	u32 dc_latency = 40000000 / wm->disp_clk; /* dc pipe latency */
63543b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	u32 other_heads_data_return_time = ((wm->num_heads + 1) * worst_chunk_return_time) +
63643b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher		(wm->num_heads * cursor_line_pair_return_time);
63743b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	u32 latency = mc_latency + other_heads_data_return_time + dc_latency;
63843b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	u32 max_src_lines_per_dst_line, lb_fill_bw, line_fill_time;
63943b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	u32 tmp, dmif_size = 12288;
64043b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	fixed20_12 a, b, c;
64143b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher
64243b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	if (wm->num_heads == 0)
64343b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher		return 0;
64443b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher
64543b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	a.full = dfixed_const(2);
64643b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	b.full = dfixed_const(1);
64743b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	if ((wm->vsc.full > a.full) ||
64843b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	    ((wm->vsc.full > b.full) && (wm->vtaps >= 3)) ||
64943b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	    (wm->vtaps >= 5) ||
65043b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	    ((wm->vsc.full >= a.full) && wm->interlaced))
65143b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher		max_src_lines_per_dst_line = 4;
65243b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	else
65343b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher		max_src_lines_per_dst_line = 2;
65443b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher
65543b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	a.full = dfixed_const(available_bandwidth);
65643b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	b.full = dfixed_const(wm->num_heads);
65743b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	a.full = dfixed_div(a, b);
65843b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher
65943b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	b.full = dfixed_const(mc_latency + 512);
66043b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	c.full = dfixed_const(wm->disp_clk);
66143b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	b.full = dfixed_div(b, c);
66243b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher
66343b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	c.full = dfixed_const(dmif_size);
66443b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	b.full = dfixed_div(c, b);
66543b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher
66643b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	tmp = min(dfixed_trunc(a), dfixed_trunc(b));
66743b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher
66843b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	b.full = dfixed_const(1000);
66943b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	c.full = dfixed_const(wm->disp_clk);
67043b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	b.full = dfixed_div(c, b);
67143b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	c.full = dfixed_const(wm->bytes_per_pixel);
67243b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	b.full = dfixed_mul(b, c);
67343b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher
67443b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	lb_fill_bw = min(tmp, dfixed_trunc(b));
67543b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher
67643b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	a.full = dfixed_const(max_src_lines_per_dst_line * wm->src_width * wm->bytes_per_pixel);
67743b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	b.full = dfixed_const(1000);
67843b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	c.full = dfixed_const(lb_fill_bw);
67943b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	b.full = dfixed_div(c, b);
68043b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	a.full = dfixed_div(a, b);
68143b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	line_fill_time = dfixed_trunc(a);
68243b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher
68343b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	if (line_fill_time < wm->active_time)
68443b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher		return latency;
68543b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	else
68643b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher		return latency + (line_fill_time - wm->active_time);
68743b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher
68843b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher}
68943b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher
69043b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucherstatic bool dce6_average_bandwidth_vs_dram_bandwidth_for_display(struct dce6_wm_params *wm)
69143b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher{
69243b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	if (dce6_average_bandwidth(wm) <=
69343b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	    (dce6_dram_bandwidth_for_display(wm) / wm->num_heads))
69443b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher		return true;
69543b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	else
69643b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher		return false;
69743b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher};
69843b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher
69943b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucherstatic bool dce6_average_bandwidth_vs_available_bandwidth(struct dce6_wm_params *wm)
70043b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher{
70143b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	if (dce6_average_bandwidth(wm) <=
70243b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	    (dce6_available_bandwidth(wm) / wm->num_heads))
70343b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher		return true;
70443b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	else
70543b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher		return false;
70643b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher};
70743b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher
70843b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucherstatic bool dce6_check_latency_hiding(struct dce6_wm_params *wm)
70943b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher{
71043b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	u32 lb_partitions = wm->lb_size / wm->src_width;
71143b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	u32 line_time = wm->active_time + wm->blank_time;
71243b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	u32 latency_tolerant_lines;
71343b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	u32 latency_hiding;
71443b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	fixed20_12 a;
71543b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher
71643b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	a.full = dfixed_const(1);
71743b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	if (wm->vsc.full > a.full)
71843b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher		latency_tolerant_lines = 1;
71943b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	else {
72043b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher		if (lb_partitions <= (wm->vtaps + 1))
72143b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher			latency_tolerant_lines = 1;
72243b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher		else
72343b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher			latency_tolerant_lines = 2;
72443b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	}
72543b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher
72643b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	latency_hiding = (latency_tolerant_lines * line_time + wm->blank_time);
72743b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher
72843b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	if (dce6_latency_watermark(wm) <= latency_hiding)
72943b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher		return true;
73043b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	else
73143b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher		return false;
73243b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher}
73343b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher
73443b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucherstatic void dce6_program_watermarks(struct radeon_device *rdev,
73543b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher					 struct radeon_crtc *radeon_crtc,
73643b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher					 u32 lb_size, u32 num_heads)
73743b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher{
73843b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	struct drm_display_mode *mode = &radeon_crtc->base.mode;
73943b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	struct dce6_wm_params wm;
74043b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	u32 pixel_period;
74143b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	u32 line_time = 0;
74243b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	u32 latency_watermark_a = 0, latency_watermark_b = 0;
74343b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	u32 priority_a_mark = 0, priority_b_mark = 0;
74443b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	u32 priority_a_cnt = PRIORITY_OFF;
74543b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	u32 priority_b_cnt = PRIORITY_OFF;
74643b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	u32 tmp, arb_control3;
74743b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	fixed20_12 a, b, c;
74843b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher
74943b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	if (radeon_crtc->base.enabled && num_heads && mode) {
75043b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher		pixel_period = 1000000 / (u32)mode->clock;
75143b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher		line_time = min((u32)mode->crtc_htotal * pixel_period, (u32)65535);
75243b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher		priority_a_cnt = 0;
75343b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher		priority_b_cnt = 0;
75443b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher
75543b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher		wm.yclk = rdev->pm.current_mclk * 10;
75643b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher		wm.sclk = rdev->pm.current_sclk * 10;
75743b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher		wm.disp_clk = mode->clock;
75843b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher		wm.src_width = mode->crtc_hdisplay;
75943b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher		wm.active_time = mode->crtc_hdisplay * pixel_period;
76043b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher		wm.blank_time = line_time - wm.active_time;
76143b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher		wm.interlaced = false;
76243b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher		if (mode->flags & DRM_MODE_FLAG_INTERLACE)
76343b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher			wm.interlaced = true;
76443b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher		wm.vsc = radeon_crtc->vsc;
76543b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher		wm.vtaps = 1;
76643b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher		if (radeon_crtc->rmx_type != RMX_OFF)
76743b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher			wm.vtaps = 2;
76843b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher		wm.bytes_per_pixel = 4; /* XXX: get this from fb config */
76943b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher		wm.lb_size = lb_size;
770ca7db22bc59ced2f180f37db8470140225d75860Alex Deucher		if (rdev->family == CHIP_ARUBA)
771ca7db22bc59ced2f180f37db8470140225d75860Alex Deucher			wm.dram_channels = evergreen_get_number_of_dram_channels(rdev);
772ca7db22bc59ced2f180f37db8470140225d75860Alex Deucher		else
773ca7db22bc59ced2f180f37db8470140225d75860Alex Deucher			wm.dram_channels = si_get_number_of_dram_channels(rdev);
77443b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher		wm.num_heads = num_heads;
77543b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher
77643b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher		/* set for high clocks */
77743b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher		latency_watermark_a = min(dce6_latency_watermark(&wm), (u32)65535);
77843b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher		/* set for low clocks */
77943b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher		/* wm.yclk = low clk; wm.sclk = low clk */
78043b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher		latency_watermark_b = min(dce6_latency_watermark(&wm), (u32)65535);
78143b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher
78243b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher		/* possibly force display priority to high */
78343b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher		/* should really do this at mode validation time... */
78443b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher		if (!dce6_average_bandwidth_vs_dram_bandwidth_for_display(&wm) ||
78543b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher		    !dce6_average_bandwidth_vs_available_bandwidth(&wm) ||
78643b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher		    !dce6_check_latency_hiding(&wm) ||
78743b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher		    (rdev->disp_priority == 2)) {
78843b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher			DRM_DEBUG_KMS("force priority to high\n");
78943b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher			priority_a_cnt |= PRIORITY_ALWAYS_ON;
79043b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher			priority_b_cnt |= PRIORITY_ALWAYS_ON;
79143b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher		}
79243b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher
79343b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher		a.full = dfixed_const(1000);
79443b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher		b.full = dfixed_const(mode->clock);
79543b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher		b.full = dfixed_div(b, a);
79643b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher		c.full = dfixed_const(latency_watermark_a);
79743b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher		c.full = dfixed_mul(c, b);
79843b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher		c.full = dfixed_mul(c, radeon_crtc->hsc);
79943b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher		c.full = dfixed_div(c, a);
80043b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher		a.full = dfixed_const(16);
80143b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher		c.full = dfixed_div(c, a);
80243b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher		priority_a_mark = dfixed_trunc(c);
80343b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher		priority_a_cnt |= priority_a_mark & PRIORITY_MARK_MASK;
80443b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher
80543b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher		a.full = dfixed_const(1000);
80643b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher		b.full = dfixed_const(mode->clock);
80743b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher		b.full = dfixed_div(b, a);
80843b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher		c.full = dfixed_const(latency_watermark_b);
80943b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher		c.full = dfixed_mul(c, b);
81043b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher		c.full = dfixed_mul(c, radeon_crtc->hsc);
81143b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher		c.full = dfixed_div(c, a);
81243b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher		a.full = dfixed_const(16);
81343b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher		c.full = dfixed_div(c, a);
81443b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher		priority_b_mark = dfixed_trunc(c);
81543b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher		priority_b_cnt |= priority_b_mark & PRIORITY_MARK_MASK;
81643b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	}
81743b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher
81843b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	/* select wm A */
81943b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	arb_control3 = RREG32(DPG_PIPE_ARBITRATION_CONTROL3 + radeon_crtc->crtc_offset);
82043b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	tmp = arb_control3;
82143b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	tmp &= ~LATENCY_WATERMARK_MASK(3);
82243b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	tmp |= LATENCY_WATERMARK_MASK(1);
82343b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	WREG32(DPG_PIPE_ARBITRATION_CONTROL3 + radeon_crtc->crtc_offset, tmp);
82443b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	WREG32(DPG_PIPE_LATENCY_CONTROL + radeon_crtc->crtc_offset,
82543b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	       (LATENCY_LOW_WATERMARK(latency_watermark_a) |
82643b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher		LATENCY_HIGH_WATERMARK(line_time)));
82743b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	/* select wm B */
82843b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	tmp = RREG32(DPG_PIPE_ARBITRATION_CONTROL3 + radeon_crtc->crtc_offset);
82943b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	tmp &= ~LATENCY_WATERMARK_MASK(3);
83043b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	tmp |= LATENCY_WATERMARK_MASK(2);
83143b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	WREG32(DPG_PIPE_ARBITRATION_CONTROL3 + radeon_crtc->crtc_offset, tmp);
83243b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	WREG32(DPG_PIPE_LATENCY_CONTROL + radeon_crtc->crtc_offset,
83343b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	       (LATENCY_LOW_WATERMARK(latency_watermark_b) |
83443b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher		LATENCY_HIGH_WATERMARK(line_time)));
83543b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	/* restore original selection */
83643b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	WREG32(DPG_PIPE_ARBITRATION_CONTROL3 + radeon_crtc->crtc_offset, arb_control3);
83743b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher
83843b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	/* write the priority marks */
83943b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	WREG32(PRIORITY_A_CNT + radeon_crtc->crtc_offset, priority_a_cnt);
84043b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	WREG32(PRIORITY_B_CNT + radeon_crtc->crtc_offset, priority_b_cnt);
84143b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher
84243b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher}
84343b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher
84443b3cd995f304c983393b7ed6563f09781bc41d0Alex Deuchervoid dce6_bandwidth_update(struct radeon_device *rdev)
84543b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher{
84643b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	struct drm_display_mode *mode0 = NULL;
84743b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	struct drm_display_mode *mode1 = NULL;
84843b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	u32 num_heads = 0, lb_size;
84943b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	int i;
85043b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher
85143b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	radeon_update_display_priority(rdev);
85243b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher
85343b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	for (i = 0; i < rdev->num_crtc; i++) {
85443b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher		if (rdev->mode_info.crtcs[i]->base.enabled)
85543b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher			num_heads++;
85643b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	}
85743b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	for (i = 0; i < rdev->num_crtc; i += 2) {
85843b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher		mode0 = &rdev->mode_info.crtcs[i]->base.mode;
85943b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher		mode1 = &rdev->mode_info.crtcs[i+1]->base.mode;
86043b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher		lb_size = dce6_line_buffer_adjust(rdev, rdev->mode_info.crtcs[i], mode0, mode1);
86143b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher		dce6_program_watermarks(rdev, rdev->mode_info.crtcs[i], lb_size, num_heads);
86243b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher		lb_size = dce6_line_buffer_adjust(rdev, rdev->mode_info.crtcs[i+1], mode1, mode0);
86343b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher		dce6_program_watermarks(rdev, rdev->mode_info.crtcs[i+1], lb_size, num_heads);
86443b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher	}
86543b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher}
86643b3cd995f304c983393b7ed6563f09781bc41d0Alex Deucher
8670a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher/*
8680a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher * Core functions
8690a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher */
8700a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucherstatic u32 si_get_tile_pipe_to_backend_map(struct radeon_device *rdev,
8710a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher					   u32 num_tile_pipes,
8720a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher					   u32 num_backends_per_asic,
8730a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher					   u32 *backend_disable_mask_per_asic,
8740a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher					   u32 num_shader_engines)
8750a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher{
8760a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	u32 backend_map = 0;
8770a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	u32 enabled_backends_mask = 0;
8780a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	u32 enabled_backends_count = 0;
8790a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	u32 num_backends_per_se;
8800a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	u32 cur_pipe;
8810a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	u32 swizzle_pipe[SI_MAX_PIPES];
8820a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	u32 cur_backend = 0;
8830a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	u32 i;
8840a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	bool force_no_swizzle;
8850a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher
8860a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	/* force legal values */
8870a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	if (num_tile_pipes < 1)
8880a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher		num_tile_pipes = 1;
8890a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	if (num_tile_pipes > rdev->config.si.max_tile_pipes)
8900a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher		num_tile_pipes = rdev->config.si.max_tile_pipes;
8910a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	if (num_shader_engines < 1)
8920a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher		num_shader_engines = 1;
8930a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	if (num_shader_engines > rdev->config.si.max_shader_engines)
8940a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher		num_shader_engines = rdev->config.si.max_shader_engines;
8950a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	if (num_backends_per_asic < num_shader_engines)
8960a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher		num_backends_per_asic = num_shader_engines;
8970a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	if (num_backends_per_asic > (rdev->config.si.max_backends_per_se * num_shader_engines))
8980a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher		num_backends_per_asic = rdev->config.si.max_backends_per_se * num_shader_engines;
8990a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher
9000a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	/* make sure we have the same number of backends per se */
9010a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	num_backends_per_asic = ALIGN(num_backends_per_asic, num_shader_engines);
9020a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	/* set up the number of backends per se */
9030a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	num_backends_per_se = num_backends_per_asic / num_shader_engines;
9040a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	if (num_backends_per_se > rdev->config.si.max_backends_per_se) {
9050a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher		num_backends_per_se = rdev->config.si.max_backends_per_se;
9060a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher		num_backends_per_asic = num_backends_per_se * num_shader_engines;
9070a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	}
9080a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher
9090a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	/* create enable mask and count for enabled backends */
9100a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	for (i = 0; i < SI_MAX_BACKENDS; ++i) {
9110a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher		if (((*backend_disable_mask_per_asic >> i) & 1) == 0) {
9120a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher			enabled_backends_mask |= (1 << i);
9130a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher			++enabled_backends_count;
9140a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher		}
9150a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher		if (enabled_backends_count == num_backends_per_asic)
9160a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher			break;
9170a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	}
9180a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher
9190a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	/* force the backends mask to match the current number of backends */
9200a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	if (enabled_backends_count != num_backends_per_asic) {
9210a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher		u32 this_backend_enabled;
9220a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher		u32 shader_engine;
9230a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher		u32 backend_per_se;
9240a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher
9250a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher		enabled_backends_mask = 0;
9260a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher		enabled_backends_count = 0;
9270a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher		*backend_disable_mask_per_asic = SI_MAX_BACKENDS_MASK;
9280a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher		for (i = 0; i < SI_MAX_BACKENDS; ++i) {
9290a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher			/* calc the current se */
9300a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher			shader_engine = i / rdev->config.si.max_backends_per_se;
9310a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher			/* calc the backend per se */
9320a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher			backend_per_se = i % rdev->config.si.max_backends_per_se;
9330a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher			/* default to not enabled */
9340a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher			this_backend_enabled = 0;
9350a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher			if ((shader_engine < num_shader_engines) &&
9360a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher			    (backend_per_se < num_backends_per_se))
9370a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher				this_backend_enabled = 1;
9380a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher			if (this_backend_enabled) {
9390a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher				enabled_backends_mask |= (1 << i);
9400a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher				*backend_disable_mask_per_asic &= ~(1 << i);
9410a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher				++enabled_backends_count;
9420a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher			}
9430a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher		}
9440a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	}
9450a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher
9460a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher
9470a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	memset((uint8_t *)&swizzle_pipe[0], 0, sizeof(u32) * SI_MAX_PIPES);
9480a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	switch (rdev->family) {
9490a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	case CHIP_TAHITI:
9500a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	case CHIP_PITCAIRN:
9510a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	case CHIP_VERDE:
9520a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher		force_no_swizzle = true;
9530a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher		break;
9540a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	default:
9550a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher		force_no_swizzle = false;
9560a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher		break;
9570a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	}
9580a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	if (force_no_swizzle) {
9590a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher		bool last_backend_enabled = false;
9600a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher
9610a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher		force_no_swizzle = false;
9620a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher		for (i = 0; i < SI_MAX_BACKENDS; ++i) {
9630a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher			if (((enabled_backends_mask >> i) & 1) == 1) {
9640a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher				if (last_backend_enabled)
9650a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher					force_no_swizzle = true;
9660a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher				last_backend_enabled = true;
9670a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher			} else
9680a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher				last_backend_enabled = false;
9690a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher		}
9700a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	}
9710a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher
9720a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	switch (num_tile_pipes) {
9730a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	case 1:
9740a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	case 3:
9750a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	case 5:
9760a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	case 7:
9770a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher		DRM_ERROR("odd number of pipes!\n");
9780a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher		break;
9790a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	case 2:
9800a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher		swizzle_pipe[0] = 0;
9810a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher		swizzle_pipe[1] = 1;
9820a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher		break;
9830a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	case 4:
9840a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher		if (force_no_swizzle) {
9850a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher			swizzle_pipe[0] = 0;
9860a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher			swizzle_pipe[1] = 1;
9870a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher			swizzle_pipe[2] = 2;
9880a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher			swizzle_pipe[3] = 3;
9890a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher		} else {
9900a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher			swizzle_pipe[0] = 0;
9910a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher			swizzle_pipe[1] = 2;
9920a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher			swizzle_pipe[2] = 1;
9930a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher			swizzle_pipe[3] = 3;
9940a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher		}
9950a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher		break;
9960a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	case 6:
9970a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher		if (force_no_swizzle) {
9980a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher			swizzle_pipe[0] = 0;
9990a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher			swizzle_pipe[1] = 1;
10000a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher			swizzle_pipe[2] = 2;
10010a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher			swizzle_pipe[3] = 3;
10020a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher			swizzle_pipe[4] = 4;
10030a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher			swizzle_pipe[5] = 5;
10040a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher		} else {
10050a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher			swizzle_pipe[0] = 0;
10060a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher			swizzle_pipe[1] = 2;
10070a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher			swizzle_pipe[2] = 4;
10080a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher			swizzle_pipe[3] = 1;
10090a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher			swizzle_pipe[4] = 3;
10100a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher			swizzle_pipe[5] = 5;
10110a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher		}
10120a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher		break;
10130a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	case 8:
10140a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher		if (force_no_swizzle) {
10150a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher			swizzle_pipe[0] = 0;
10160a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher			swizzle_pipe[1] = 1;
10170a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher			swizzle_pipe[2] = 2;
10180a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher			swizzle_pipe[3] = 3;
10190a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher			swizzle_pipe[4] = 4;
10200a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher			swizzle_pipe[5] = 5;
10210a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher			swizzle_pipe[6] = 6;
10220a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher			swizzle_pipe[7] = 7;
10230a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher		} else {
10240a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher			swizzle_pipe[0] = 0;
10250a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher			swizzle_pipe[1] = 2;
10260a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher			swizzle_pipe[2] = 4;
10270a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher			swizzle_pipe[3] = 6;
10280a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher			swizzle_pipe[4] = 1;
10290a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher			swizzle_pipe[5] = 3;
10300a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher			swizzle_pipe[6] = 5;
10310a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher			swizzle_pipe[7] = 7;
10320a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher		}
10330a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher		break;
10340a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	}
10350a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher
10360a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	for (cur_pipe = 0; cur_pipe < num_tile_pipes; ++cur_pipe) {
10370a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher		while (((1 << cur_backend) & enabled_backends_mask) == 0)
10380a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher			cur_backend = (cur_backend + 1) % SI_MAX_BACKENDS;
10390a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher
10400a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher		backend_map |= (((cur_backend & 0xf) << (swizzle_pipe[cur_pipe] * 4)));
10410a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher
10420a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher		cur_backend = (cur_backend + 1) % SI_MAX_BACKENDS;
10430a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	}
10440a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher
10450a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	return backend_map;
10460a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher}
10470a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher
10480a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucherstatic u32 si_get_disable_mask_per_asic(struct radeon_device *rdev,
10490a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher					u32 disable_mask_per_se,
10500a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher					u32 max_disable_mask_per_se,
10510a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher					u32 num_shader_engines)
10520a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher{
10530a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	u32 disable_field_width_per_se = r600_count_pipe_bits(disable_mask_per_se);
10540a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	u32 disable_mask_per_asic = disable_mask_per_se & max_disable_mask_per_se;
10550a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher
10560a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	if (num_shader_engines == 1)
10570a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher		return disable_mask_per_asic;
10580a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	else if (num_shader_engines == 2)
10590a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher		return disable_mask_per_asic | (disable_mask_per_asic << disable_field_width_per_se);
10600a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	else
10610a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher		return 0xffffffff;
10620a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher}
10630a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher
10640a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucherstatic void si_tiling_mode_table_init(struct radeon_device *rdev)
10650a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher{
10660a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	const u32 num_tile_mode_states = 32;
10670a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	u32 reg_offset, gb_tile_moden, split_equal_to_row_size;
10680a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher
10690a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	switch (rdev->config.si.mem_row_size_in_kb) {
10700a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	case 1:
10710a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher		split_equal_to_row_size = ADDR_SURF_TILE_SPLIT_1KB;
10720a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher		break;
10730a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	case 2:
10740a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	default:
10750a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher		split_equal_to_row_size = ADDR_SURF_TILE_SPLIT_2KB;
10760a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher		break;
10770a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	case 4:
10780a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher		split_equal_to_row_size = ADDR_SURF_TILE_SPLIT_4KB;
10790a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher		break;
10800a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	}
10810a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher
10820a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	if ((rdev->family == CHIP_TAHITI) ||
10830a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	    (rdev->family == CHIP_PITCAIRN)) {
10840a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher		for (reg_offset = 0; reg_offset < num_tile_mode_states; reg_offset++) {
10850a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher			switch (reg_offset) {
10860a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher			case 0:  /* non-AA compressed depth or any compressed stencil */
10870a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher				gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
10880a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 MICRO_TILE_MODE(ADDR_SURF_DEPTH_MICRO_TILING) |
10890a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) |
10900a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 TILE_SPLIT(ADDR_SURF_TILE_SPLIT_64B) |
10910a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 NUM_BANKS(ADDR_SURF_16_BANK) |
10920a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
10930a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) |
10940a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2));
10950a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher				break;
10960a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher			case 1:  /* 2xAA/4xAA compressed depth only */
10970a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher				gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
10980a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 MICRO_TILE_MODE(ADDR_SURF_DEPTH_MICRO_TILING) |
10990a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) |
11000a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 TILE_SPLIT(ADDR_SURF_TILE_SPLIT_128B) |
11010a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 NUM_BANKS(ADDR_SURF_16_BANK) |
11020a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
11030a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) |
11040a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2));
11050a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher				break;
11060a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher			case 2:  /* 8xAA compressed depth only */
11070a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher				gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
11080a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 MICRO_TILE_MODE(ADDR_SURF_DEPTH_MICRO_TILING) |
11090a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) |
11100a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 TILE_SPLIT(ADDR_SURF_TILE_SPLIT_256B) |
11110a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 NUM_BANKS(ADDR_SURF_16_BANK) |
11120a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
11130a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) |
11140a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2));
11150a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher				break;
11160a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher			case 3:  /* 2xAA/4xAA compressed depth with stencil (for depth buffer) */
11170a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher				gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
11180a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 MICRO_TILE_MODE(ADDR_SURF_DEPTH_MICRO_TILING) |
11190a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) |
11200a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 TILE_SPLIT(ADDR_SURF_TILE_SPLIT_128B) |
11210a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 NUM_BANKS(ADDR_SURF_16_BANK) |
11220a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
11230a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) |
11240a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2));
11250a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher				break;
11260a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher			case 4:  /* Maps w/ a dimension less than the 2D macro-tile dimensions (for mipmapped depth textures) */
11270a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher				gb_tile_moden = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) |
11280a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 MICRO_TILE_MODE(ADDR_SURF_DEPTH_MICRO_TILING) |
11290a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) |
11300a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 TILE_SPLIT(ADDR_SURF_TILE_SPLIT_64B) |
11310a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 NUM_BANKS(ADDR_SURF_16_BANK) |
11320a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
11330a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) |
11340a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2));
11350a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher				break;
11360a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher			case 5:  /* Uncompressed 16bpp depth - and stencil buffer allocated with it */
11370a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher				gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
11380a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 MICRO_TILE_MODE(ADDR_SURF_DEPTH_MICRO_TILING) |
11390a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) |
11400a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 TILE_SPLIT(split_equal_to_row_size) |
11410a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 NUM_BANKS(ADDR_SURF_16_BANK) |
11420a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
11430a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) |
11440a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2));
11450a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher				break;
11460a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher			case 6:  /* Uncompressed 32bpp depth - and stencil buffer allocated with it */
11470a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher				gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
11480a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 MICRO_TILE_MODE(ADDR_SURF_DEPTH_MICRO_TILING) |
11490a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) |
11500a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 TILE_SPLIT(split_equal_to_row_size) |
11510a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 NUM_BANKS(ADDR_SURF_16_BANK) |
11520a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
11530a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) |
11540a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1));
11550a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher				break;
11560a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher			case 7:  /* Uncompressed 8bpp stencil without depth (drivers typically do not use) */
11570a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher				gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
11580a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 MICRO_TILE_MODE(ADDR_SURF_DEPTH_MICRO_TILING) |
11590a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) |
11600a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 TILE_SPLIT(split_equal_to_row_size) |
11610a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 NUM_BANKS(ADDR_SURF_16_BANK) |
11620a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
11630a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) |
11640a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2));
11650a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher				break;
11660a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher			case 8:  /* 1D and 1D Array Surfaces */
11670a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher				gb_tile_moden = (ARRAY_MODE(ARRAY_LINEAR_ALIGNED) |
11680a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 MICRO_TILE_MODE(ADDR_SURF_DISPLAY_MICRO_TILING) |
11690a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) |
11700a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 TILE_SPLIT(ADDR_SURF_TILE_SPLIT_64B) |
11710a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 NUM_BANKS(ADDR_SURF_16_BANK) |
11720a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
11730a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) |
11740a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2));
11750a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher				break;
11760a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher			case 9:  /* Displayable maps. */
11770a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher				gb_tile_moden = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) |
11780a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 MICRO_TILE_MODE(ADDR_SURF_DISPLAY_MICRO_TILING) |
11790a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) |
11800a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 TILE_SPLIT(ADDR_SURF_TILE_SPLIT_64B) |
11810a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 NUM_BANKS(ADDR_SURF_16_BANK) |
11820a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
11830a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) |
11840a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2));
11850a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher				break;
11860a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher			case 10:  /* Display 8bpp. */
11870a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher				gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
11880a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 MICRO_TILE_MODE(ADDR_SURF_DISPLAY_MICRO_TILING) |
11890a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) |
11900a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 TILE_SPLIT(ADDR_SURF_TILE_SPLIT_256B) |
11910a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 NUM_BANKS(ADDR_SURF_16_BANK) |
11920a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
11930a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) |
11940a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2));
11950a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher				break;
11960a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher			case 11:  /* Display 16bpp. */
11970a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher				gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
11980a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 MICRO_TILE_MODE(ADDR_SURF_DISPLAY_MICRO_TILING) |
11990a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) |
12000a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 TILE_SPLIT(ADDR_SURF_TILE_SPLIT_256B) |
12010a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 NUM_BANKS(ADDR_SURF_16_BANK) |
12020a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
12030a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) |
12040a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2));
12050a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher				break;
12060a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher			case 12:  /* Display 32bpp. */
12070a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher				gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
12080a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 MICRO_TILE_MODE(ADDR_SURF_DISPLAY_MICRO_TILING) |
12090a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) |
12100a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 TILE_SPLIT(ADDR_SURF_TILE_SPLIT_512B) |
12110a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 NUM_BANKS(ADDR_SURF_16_BANK) |
12120a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
12130a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) |
12140a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1));
12150a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher				break;
12160a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher			case 13:  /* Thin. */
12170a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher				gb_tile_moden = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) |
12180a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) |
12190a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) |
12200a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 TILE_SPLIT(ADDR_SURF_TILE_SPLIT_64B) |
12210a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 NUM_BANKS(ADDR_SURF_16_BANK) |
12220a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
12230a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) |
12240a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2));
12250a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher				break;
12260a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher			case 14:  /* Thin 8 bpp. */
12270a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher				gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
12280a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) |
12290a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) |
12300a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 TILE_SPLIT(ADDR_SURF_TILE_SPLIT_256B) |
12310a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 NUM_BANKS(ADDR_SURF_16_BANK) |
12320a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
12330a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) |
12340a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1));
12350a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher				break;
12360a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher			case 15:  /* Thin 16 bpp. */
12370a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher				gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
12380a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) |
12390a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) |
12400a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 TILE_SPLIT(ADDR_SURF_TILE_SPLIT_256B) |
12410a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 NUM_BANKS(ADDR_SURF_16_BANK) |
12420a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
12430a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) |
12440a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1));
12450a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher				break;
12460a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher			case 16:  /* Thin 32 bpp. */
12470a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher				gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
12480a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) |
12490a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) |
12500a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 TILE_SPLIT(ADDR_SURF_TILE_SPLIT_512B) |
12510a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 NUM_BANKS(ADDR_SURF_16_BANK) |
12520a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
12530a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) |
12540a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1));
12550a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher				break;
12560a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher			case 17:  /* Thin 64 bpp. */
12570a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher				gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
12580a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) |
12590a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) |
12600a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 TILE_SPLIT(split_equal_to_row_size) |
12610a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 NUM_BANKS(ADDR_SURF_16_BANK) |
12620a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
12630a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) |
12640a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1));
12650a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher				break;
12660a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher			case 21:  /* 8 bpp PRT. */
12670a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher				gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
12680a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) |
12690a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) |
12700a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 TILE_SPLIT(ADDR_SURF_TILE_SPLIT_256B) |
12710a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 NUM_BANKS(ADDR_SURF_16_BANK) |
12720a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 BANK_WIDTH(ADDR_SURF_BANK_WIDTH_2) |
12730a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) |
12740a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2));
12750a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher				break;
12760a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher			case 22:  /* 16 bpp PRT */
12770a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher				gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
12780a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) |
12790a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) |
12800a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 TILE_SPLIT(ADDR_SURF_TILE_SPLIT_256B) |
12810a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 NUM_BANKS(ADDR_SURF_16_BANK) |
12820a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
12830a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) |
12840a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4));
12850a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher				break;
12860a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher			case 23:  /* 32 bpp PRT */
12870a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher				gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
12880a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) |
12890a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) |
12900a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 TILE_SPLIT(ADDR_SURF_TILE_SPLIT_256B) |
12910a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 NUM_BANKS(ADDR_SURF_16_BANK) |
12920a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
12930a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) |
12940a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2));
12950a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher				break;
12960a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher			case 24:  /* 64 bpp PRT */
12970a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher				gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
12980a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) |
12990a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) |
13000a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 TILE_SPLIT(ADDR_SURF_TILE_SPLIT_512B) |
13010a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 NUM_BANKS(ADDR_SURF_16_BANK) |
13020a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
13030a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) |
13040a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2));
13050a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher				break;
13060a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher			case 25:  /* 128 bpp PRT */
13070a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher				gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
13080a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) |
13090a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) |
13100a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 TILE_SPLIT(ADDR_SURF_TILE_SPLIT_1KB) |
13110a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 NUM_BANKS(ADDR_SURF_8_BANK) |
13120a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
13130a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) |
13140a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1));
13150a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher				break;
13160a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher			default:
13170a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher				gb_tile_moden = 0;
13180a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher				break;
13190a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher			}
13200a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher			WREG32(GB_TILE_MODE0 + (reg_offset * 4), gb_tile_moden);
13210a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher		}
13220a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	} else if (rdev->family == CHIP_VERDE) {
13230a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher		for (reg_offset = 0; reg_offset < num_tile_mode_states; reg_offset++) {
13240a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher			switch (reg_offset) {
13250a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher			case 0:  /* non-AA compressed depth or any compressed stencil */
13260a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher				gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
13270a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 MICRO_TILE_MODE(ADDR_SURF_DEPTH_MICRO_TILING) |
13280a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 PIPE_CONFIG(ADDR_SURF_P4_8x16) |
13290a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 TILE_SPLIT(ADDR_SURF_TILE_SPLIT_64B) |
13300a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 NUM_BANKS(ADDR_SURF_16_BANK) |
13310a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
13320a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) |
13330a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4));
13340a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher				break;
13350a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher			case 1:  /* 2xAA/4xAA compressed depth only */
13360a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher				gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
13370a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 MICRO_TILE_MODE(ADDR_SURF_DEPTH_MICRO_TILING) |
13380a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 PIPE_CONFIG(ADDR_SURF_P4_8x16) |
13390a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 TILE_SPLIT(ADDR_SURF_TILE_SPLIT_128B) |
13400a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 NUM_BANKS(ADDR_SURF_16_BANK) |
13410a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
13420a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) |
13430a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4));
13440a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher				break;
13450a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher			case 2:  /* 8xAA compressed depth only */
13460a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher				gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
13470a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 MICRO_TILE_MODE(ADDR_SURF_DEPTH_MICRO_TILING) |
13480a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 PIPE_CONFIG(ADDR_SURF_P4_8x16) |
13490a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 TILE_SPLIT(ADDR_SURF_TILE_SPLIT_256B) |
13500a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 NUM_BANKS(ADDR_SURF_16_BANK) |
13510a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
13520a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) |
13530a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4));
13540a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher				break;
13550a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher			case 3:  /* 2xAA/4xAA compressed depth with stencil (for depth buffer) */
13560a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher				gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
13570a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 MICRO_TILE_MODE(ADDR_SURF_DEPTH_MICRO_TILING) |
13580a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 PIPE_CONFIG(ADDR_SURF_P4_8x16) |
13590a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 TILE_SPLIT(ADDR_SURF_TILE_SPLIT_128B) |
13600a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 NUM_BANKS(ADDR_SURF_16_BANK) |
13610a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
13620a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) |
13630a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4));
13640a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher				break;
13650a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher			case 4:  /* Maps w/ a dimension less than the 2D macro-tile dimensions (for mipmapped depth textures) */
13660a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher				gb_tile_moden = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) |
13670a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 MICRO_TILE_MODE(ADDR_SURF_DEPTH_MICRO_TILING) |
13680a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 PIPE_CONFIG(ADDR_SURF_P4_8x16) |
13690a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 TILE_SPLIT(ADDR_SURF_TILE_SPLIT_64B) |
13700a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 NUM_BANKS(ADDR_SURF_16_BANK) |
13710a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
13720a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) |
13730a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2));
13740a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher				break;
13750a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher			case 5:  /* Uncompressed 16bpp depth - and stencil buffer allocated with it */
13760a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher				gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
13770a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 MICRO_TILE_MODE(ADDR_SURF_DEPTH_MICRO_TILING) |
13780a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 PIPE_CONFIG(ADDR_SURF_P4_8x16) |
13790a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 TILE_SPLIT(split_equal_to_row_size) |
13800a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 NUM_BANKS(ADDR_SURF_16_BANK) |
13810a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
13820a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) |
13830a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2));
13840a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher				break;
13850a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher			case 6:  /* Uncompressed 32bpp depth - and stencil buffer allocated with it */
13860a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher				gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
13870a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 MICRO_TILE_MODE(ADDR_SURF_DEPTH_MICRO_TILING) |
13880a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 PIPE_CONFIG(ADDR_SURF_P4_8x16) |
13890a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 TILE_SPLIT(split_equal_to_row_size) |
13900a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 NUM_BANKS(ADDR_SURF_16_BANK) |
13910a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
13920a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) |
13930a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2));
13940a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher				break;
13950a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher			case 7:  /* Uncompressed 8bpp stencil without depth (drivers typically do not use) */
13960a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher				gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
13970a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 MICRO_TILE_MODE(ADDR_SURF_DEPTH_MICRO_TILING) |
13980a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 PIPE_CONFIG(ADDR_SURF_P4_8x16) |
13990a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 TILE_SPLIT(split_equal_to_row_size) |
14000a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 NUM_BANKS(ADDR_SURF_16_BANK) |
14010a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
14020a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) |
14030a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4));
14040a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher				break;
14050a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher			case 8:  /* 1D and 1D Array Surfaces */
14060a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher				gb_tile_moden = (ARRAY_MODE(ARRAY_LINEAR_ALIGNED) |
14070a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 MICRO_TILE_MODE(ADDR_SURF_DISPLAY_MICRO_TILING) |
14080a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 PIPE_CONFIG(ADDR_SURF_P4_8x16) |
14090a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 TILE_SPLIT(ADDR_SURF_TILE_SPLIT_64B) |
14100a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 NUM_BANKS(ADDR_SURF_16_BANK) |
14110a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
14120a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) |
14130a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2));
14140a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher				break;
14150a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher			case 9:  /* Displayable maps. */
14160a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher				gb_tile_moden = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) |
14170a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 MICRO_TILE_MODE(ADDR_SURF_DISPLAY_MICRO_TILING) |
14180a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 PIPE_CONFIG(ADDR_SURF_P4_8x16) |
14190a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 TILE_SPLIT(ADDR_SURF_TILE_SPLIT_64B) |
14200a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 NUM_BANKS(ADDR_SURF_16_BANK) |
14210a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
14220a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) |
14230a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2));
14240a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher				break;
14250a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher			case 10:  /* Display 8bpp. */
14260a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher				gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
14270a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 MICRO_TILE_MODE(ADDR_SURF_DISPLAY_MICRO_TILING) |
14280a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 PIPE_CONFIG(ADDR_SURF_P4_8x16) |
14290a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 TILE_SPLIT(ADDR_SURF_TILE_SPLIT_256B) |
14300a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 NUM_BANKS(ADDR_SURF_16_BANK) |
14310a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
14320a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) |
14330a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4));
14340a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher				break;
14350a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher			case 11:  /* Display 16bpp. */
14360a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher				gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
14370a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 MICRO_TILE_MODE(ADDR_SURF_DISPLAY_MICRO_TILING) |
14380a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 PIPE_CONFIG(ADDR_SURF_P4_8x16) |
14390a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 TILE_SPLIT(ADDR_SURF_TILE_SPLIT_256B) |
14400a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 NUM_BANKS(ADDR_SURF_16_BANK) |
14410a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
14420a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) |
14430a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2));
14440a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher				break;
14450a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher			case 12:  /* Display 32bpp. */
14460a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher				gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
14470a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 MICRO_TILE_MODE(ADDR_SURF_DISPLAY_MICRO_TILING) |
14480a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 PIPE_CONFIG(ADDR_SURF_P4_8x16) |
14490a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 TILE_SPLIT(ADDR_SURF_TILE_SPLIT_512B) |
14500a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 NUM_BANKS(ADDR_SURF_16_BANK) |
14510a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
14520a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) |
14530a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2));
14540a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher				break;
14550a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher			case 13:  /* Thin. */
14560a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher				gb_tile_moden = (ARRAY_MODE(ARRAY_1D_TILED_THIN1) |
14570a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) |
14580a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 PIPE_CONFIG(ADDR_SURF_P4_8x16) |
14590a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 TILE_SPLIT(ADDR_SURF_TILE_SPLIT_64B) |
14600a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 NUM_BANKS(ADDR_SURF_16_BANK) |
14610a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
14620a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) |
14630a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2));
14640a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher				break;
14650a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher			case 14:  /* Thin 8 bpp. */
14660a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher				gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
14670a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) |
14680a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 PIPE_CONFIG(ADDR_SURF_P4_8x16) |
14690a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 TILE_SPLIT(ADDR_SURF_TILE_SPLIT_256B) |
14700a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 NUM_BANKS(ADDR_SURF_16_BANK) |
14710a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
14720a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) |
14730a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2));
14740a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher				break;
14750a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher			case 15:  /* Thin 16 bpp. */
14760a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher				gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
14770a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) |
14780a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 PIPE_CONFIG(ADDR_SURF_P4_8x16) |
14790a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 TILE_SPLIT(ADDR_SURF_TILE_SPLIT_256B) |
14800a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 NUM_BANKS(ADDR_SURF_16_BANK) |
14810a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
14820a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) |
14830a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2));
14840a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher				break;
14850a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher			case 16:  /* Thin 32 bpp. */
14860a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher				gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
14870a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) |
14880a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 PIPE_CONFIG(ADDR_SURF_P4_8x16) |
14890a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 TILE_SPLIT(ADDR_SURF_TILE_SPLIT_512B) |
14900a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 NUM_BANKS(ADDR_SURF_16_BANK) |
14910a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
14920a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) |
14930a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2));
14940a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher				break;
14950a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher			case 17:  /* Thin 64 bpp. */
14960a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher				gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
14970a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) |
14980a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 PIPE_CONFIG(ADDR_SURF_P4_8x16) |
14990a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 TILE_SPLIT(split_equal_to_row_size) |
15000a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 NUM_BANKS(ADDR_SURF_16_BANK) |
15010a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
15020a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) |
15030a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2));
15040a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher				break;
15050a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher			case 21:  /* 8 bpp PRT. */
15060a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher				gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
15070a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) |
15080a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) |
15090a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 TILE_SPLIT(ADDR_SURF_TILE_SPLIT_256B) |
15100a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 NUM_BANKS(ADDR_SURF_16_BANK) |
15110a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 BANK_WIDTH(ADDR_SURF_BANK_WIDTH_2) |
15120a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) |
15130a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2));
15140a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher				break;
15150a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher			case 22:  /* 16 bpp PRT */
15160a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher				gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
15170a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) |
15180a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) |
15190a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 TILE_SPLIT(ADDR_SURF_TILE_SPLIT_256B) |
15200a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 NUM_BANKS(ADDR_SURF_16_BANK) |
15210a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
15220a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_4) |
15230a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_4));
15240a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher				break;
15250a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher			case 23:  /* 32 bpp PRT */
15260a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher				gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
15270a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) |
15280a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) |
15290a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 TILE_SPLIT(ADDR_SURF_TILE_SPLIT_256B) |
15300a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 NUM_BANKS(ADDR_SURF_16_BANK) |
15310a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
15320a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_2) |
15330a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2));
15340a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher				break;
15350a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher			case 24:  /* 64 bpp PRT */
15360a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher				gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
15370a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) |
15380a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) |
15390a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 TILE_SPLIT(ADDR_SURF_TILE_SPLIT_512B) |
15400a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 NUM_BANKS(ADDR_SURF_16_BANK) |
15410a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
15420a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) |
15430a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_2));
15440a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher				break;
15450a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher			case 25:  /* 128 bpp PRT */
15460a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher				gb_tile_moden = (ARRAY_MODE(ARRAY_2D_TILED_THIN1) |
15470a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 MICRO_TILE_MODE(ADDR_SURF_THIN_MICRO_TILING) |
15480a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 PIPE_CONFIG(ADDR_SURF_P8_32x32_8x16) |
15490a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 TILE_SPLIT(ADDR_SURF_TILE_SPLIT_1KB) |
15500a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 NUM_BANKS(ADDR_SURF_8_BANK) |
15510a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 BANK_WIDTH(ADDR_SURF_BANK_WIDTH_1) |
15520a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 BANK_HEIGHT(ADDR_SURF_BANK_HEIGHT_1) |
15530a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						 MACRO_TILE_ASPECT(ADDR_SURF_MACRO_ASPECT_1));
15540a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher				break;
15550a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher			default:
15560a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher				gb_tile_moden = 0;
15570a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher				break;
15580a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher			}
15590a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher			WREG32(GB_TILE_MODE0 + (reg_offset * 4), gb_tile_moden);
15600a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher		}
15610a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	} else
15620a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher		DRM_ERROR("unknown asic: 0x%x\n", rdev->family);
15630a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher}
15640a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher
15650a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucherstatic void si_gpu_init(struct radeon_device *rdev)
15660a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher{
15670a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	u32 cc_rb_backend_disable = 0;
15680a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	u32 cc_gc_shader_array_config;
15690a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	u32 gb_addr_config = 0;
15700a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	u32 mc_shared_chmap, mc_arb_ramcfg;
15710a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	u32 gb_backend_map;
15720a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	u32 cgts_tcc_disable;
15730a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	u32 sx_debug_1;
15740a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	u32 gc_user_shader_array_config;
15750a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	u32 gc_user_rb_backend_disable;
15760a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	u32 cgts_user_tcc_disable;
15770a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	u32 hdp_host_path_cntl;
15780a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	u32 tmp;
15790a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	int i, j;
15800a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher
15810a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	switch (rdev->family) {
15820a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	case CHIP_TAHITI:
15830a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher		rdev->config.si.max_shader_engines = 2;
15840a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher		rdev->config.si.max_pipes_per_simd = 4;
15850a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher		rdev->config.si.max_tile_pipes = 12;
15860a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher		rdev->config.si.max_simds_per_se = 8;
15870a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher		rdev->config.si.max_backends_per_se = 4;
15880a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher		rdev->config.si.max_texture_channel_caches = 12;
15890a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher		rdev->config.si.max_gprs = 256;
15900a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher		rdev->config.si.max_gs_threads = 32;
15910a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher		rdev->config.si.max_hw_contexts = 8;
15920a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher
15930a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher		rdev->config.si.sc_prim_fifo_size_frontend = 0x20;
15940a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher		rdev->config.si.sc_prim_fifo_size_backend = 0x100;
15950a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher		rdev->config.si.sc_hiz_tile_fifo_size = 0x30;
15960a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher		rdev->config.si.sc_earlyz_tile_fifo_size = 0x130;
15970a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher		break;
15980a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	case CHIP_PITCAIRN:
15990a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher		rdev->config.si.max_shader_engines = 2;
16000a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher		rdev->config.si.max_pipes_per_simd = 4;
16010a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher		rdev->config.si.max_tile_pipes = 8;
16020a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher		rdev->config.si.max_simds_per_se = 5;
16030a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher		rdev->config.si.max_backends_per_se = 4;
16040a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher		rdev->config.si.max_texture_channel_caches = 8;
16050a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher		rdev->config.si.max_gprs = 256;
16060a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher		rdev->config.si.max_gs_threads = 32;
16070a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher		rdev->config.si.max_hw_contexts = 8;
16080a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher
16090a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher		rdev->config.si.sc_prim_fifo_size_frontend = 0x20;
16100a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher		rdev->config.si.sc_prim_fifo_size_backend = 0x100;
16110a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher		rdev->config.si.sc_hiz_tile_fifo_size = 0x30;
16120a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher		rdev->config.si.sc_earlyz_tile_fifo_size = 0x130;
16130a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher		break;
16140a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	case CHIP_VERDE:
16150a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	default:
16160a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher		rdev->config.si.max_shader_engines = 1;
16170a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher		rdev->config.si.max_pipes_per_simd = 4;
16180a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher		rdev->config.si.max_tile_pipes = 4;
16190a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher		rdev->config.si.max_simds_per_se = 2;
16200a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher		rdev->config.si.max_backends_per_se = 4;
16210a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher		rdev->config.si.max_texture_channel_caches = 4;
16220a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher		rdev->config.si.max_gprs = 256;
16230a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher		rdev->config.si.max_gs_threads = 32;
16240a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher		rdev->config.si.max_hw_contexts = 8;
16250a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher
16260a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher		rdev->config.si.sc_prim_fifo_size_frontend = 0x20;
16270a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher		rdev->config.si.sc_prim_fifo_size_backend = 0x40;
16280a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher		rdev->config.si.sc_hiz_tile_fifo_size = 0x30;
16290a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher		rdev->config.si.sc_earlyz_tile_fifo_size = 0x130;
16300a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher		break;
16310a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	}
16320a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher
16330a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	/* Initialize HDP */
16340a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	for (i = 0, j = 0; i < 32; i++, j += 0x18) {
16350a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher		WREG32((0x2c14 + j), 0x00000000);
16360a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher		WREG32((0x2c18 + j), 0x00000000);
16370a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher		WREG32((0x2c1c + j), 0x00000000);
16380a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher		WREG32((0x2c20 + j), 0x00000000);
16390a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher		WREG32((0x2c24 + j), 0x00000000);
16400a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	}
16410a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher
16420a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	WREG32(GRBM_CNTL, GRBM_READ_TIMEOUT(0xff));
16430a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher
16440a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	evergreen_fix_pci_max_read_req_size(rdev);
16450a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher
16460a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	WREG32(BIF_FB_EN, FB_READ_EN | FB_WRITE_EN);
16470a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher
16480a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	mc_shared_chmap = RREG32(MC_SHARED_CHMAP);
16490a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	mc_arb_ramcfg = RREG32(MC_ARB_RAMCFG);
16500a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher
16510a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	cc_rb_backend_disable = RREG32(CC_RB_BACKEND_DISABLE);
16520a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	cc_gc_shader_array_config = RREG32(CC_GC_SHADER_ARRAY_CONFIG);
16530a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	cgts_tcc_disable = 0xffff0000;
16540a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	for (i = 0; i < rdev->config.si.max_texture_channel_caches; i++)
16550a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher		cgts_tcc_disable &= ~(1 << (16 + i));
16560a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	gc_user_rb_backend_disable = RREG32(GC_USER_RB_BACKEND_DISABLE);
16570a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	gc_user_shader_array_config = RREG32(GC_USER_SHADER_ARRAY_CONFIG);
16580a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	cgts_user_tcc_disable = RREG32(CGTS_USER_TCC_DISABLE);
16590a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher
16600a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	rdev->config.si.num_shader_engines = rdev->config.si.max_shader_engines;
16610a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	rdev->config.si.num_tile_pipes = rdev->config.si.max_tile_pipes;
16620a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	tmp = ((~gc_user_rb_backend_disable) & BACKEND_DISABLE_MASK) >> BACKEND_DISABLE_SHIFT;
16630a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	rdev->config.si.num_backends_per_se = r600_count_pipe_bits(tmp);
16640a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	tmp = (gc_user_rb_backend_disable & BACKEND_DISABLE_MASK) >> BACKEND_DISABLE_SHIFT;
16650a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	rdev->config.si.backend_disable_mask_per_asic =
16660a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher		si_get_disable_mask_per_asic(rdev, tmp, SI_MAX_BACKENDS_PER_SE_MASK,
16670a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher					     rdev->config.si.num_shader_engines);
16680a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	rdev->config.si.backend_map =
16690a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher		si_get_tile_pipe_to_backend_map(rdev, rdev->config.si.num_tile_pipes,
16700a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						rdev->config.si.num_backends_per_se *
16710a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						rdev->config.si.num_shader_engines,
16720a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						&rdev->config.si.backend_disable_mask_per_asic,
16730a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						rdev->config.si.num_shader_engines);
16740a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	tmp = ((~cgts_user_tcc_disable) & TCC_DISABLE_MASK) >> TCC_DISABLE_SHIFT;
16750a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	rdev->config.si.num_texture_channel_caches = r600_count_pipe_bits(tmp);
16760a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	rdev->config.si.mem_max_burst_length_bytes = 256;
16770a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	tmp = (mc_arb_ramcfg & NOOFCOLS_MASK) >> NOOFCOLS_SHIFT;
16780a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	rdev->config.si.mem_row_size_in_kb = (4 * (1 << (8 + tmp))) / 1024;
16790a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	if (rdev->config.si.mem_row_size_in_kb > 4)
16800a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher		rdev->config.si.mem_row_size_in_kb = 4;
16810a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	/* XXX use MC settings? */
16820a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	rdev->config.si.shader_engine_tile_size = 32;
16830a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	rdev->config.si.num_gpus = 1;
16840a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	rdev->config.si.multi_gpu_tile_size = 64;
16850a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher
16860a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	gb_addr_config = 0;
16870a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	switch (rdev->config.si.num_tile_pipes) {
16880a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	case 1:
16890a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher		gb_addr_config |= NUM_PIPES(0);
16900a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher		break;
16910a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	case 2:
16920a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher		gb_addr_config |= NUM_PIPES(1);
16930a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher		break;
16940a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	case 4:
16950a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher		gb_addr_config |= NUM_PIPES(2);
16960a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher		break;
16970a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	case 8:
16980a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	default:
16990a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher		gb_addr_config |= NUM_PIPES(3);
17000a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher		break;
17010a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	}
17020a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher
17030a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	tmp = (rdev->config.si.mem_max_burst_length_bytes / 256) - 1;
17040a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	gb_addr_config |= PIPE_INTERLEAVE_SIZE(tmp);
17050a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	gb_addr_config |= NUM_SHADER_ENGINES(rdev->config.si.num_shader_engines - 1);
17060a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	tmp = (rdev->config.si.shader_engine_tile_size / 16) - 1;
17070a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	gb_addr_config |= SHADER_ENGINE_TILE_SIZE(tmp);
17080a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	switch (rdev->config.si.num_gpus) {
17090a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	case 1:
17100a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	default:
17110a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher		gb_addr_config |= NUM_GPUS(0);
17120a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher		break;
17130a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	case 2:
17140a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher		gb_addr_config |= NUM_GPUS(1);
17150a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher		break;
17160a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	case 4:
17170a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher		gb_addr_config |= NUM_GPUS(2);
17180a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher		break;
17190a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	}
17200a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	switch (rdev->config.si.multi_gpu_tile_size) {
17210a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	case 16:
17220a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher		gb_addr_config |= MULTI_GPU_TILE_SIZE(0);
17230a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher		break;
17240a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	case 32:
17250a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	default:
17260a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher		gb_addr_config |= MULTI_GPU_TILE_SIZE(1);
17270a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher		break;
17280a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	case 64:
17290a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher		gb_addr_config |= MULTI_GPU_TILE_SIZE(2);
17300a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher		break;
17310a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	case 128:
17320a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher		gb_addr_config |= MULTI_GPU_TILE_SIZE(3);
17330a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher		break;
17340a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	}
17350a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	switch (rdev->config.si.mem_row_size_in_kb) {
17360a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	case 1:
17370a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	default:
17380a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher		gb_addr_config |= ROW_SIZE(0);
17390a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher		break;
17400a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	case 2:
17410a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher		gb_addr_config |= ROW_SIZE(1);
17420a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher		break;
17430a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	case 4:
17440a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher		gb_addr_config |= ROW_SIZE(2);
17450a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher		break;
17460a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	}
17470a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher
17480a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	tmp = (gb_addr_config & NUM_PIPES_MASK) >> NUM_PIPES_SHIFT;
17490a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	rdev->config.si.num_tile_pipes = (1 << tmp);
17500a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	tmp = (gb_addr_config & PIPE_INTERLEAVE_SIZE_MASK) >> PIPE_INTERLEAVE_SIZE_SHIFT;
17510a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	rdev->config.si.mem_max_burst_length_bytes = (tmp + 1) * 256;
17520a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	tmp = (gb_addr_config & NUM_SHADER_ENGINES_MASK) >> NUM_SHADER_ENGINES_SHIFT;
17530a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	rdev->config.si.num_shader_engines = tmp + 1;
17540a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	tmp = (gb_addr_config & NUM_GPUS_MASK) >> NUM_GPUS_SHIFT;
17550a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	rdev->config.si.num_gpus = tmp + 1;
17560a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	tmp = (gb_addr_config & MULTI_GPU_TILE_SIZE_MASK) >> MULTI_GPU_TILE_SIZE_SHIFT;
17570a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	rdev->config.si.multi_gpu_tile_size = 1 << tmp;
17580a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	tmp = (gb_addr_config & ROW_SIZE_MASK) >> ROW_SIZE_SHIFT;
17590a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	rdev->config.si.mem_row_size_in_kb = 1 << tmp;
17600a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher
17610a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	gb_backend_map =
17620a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher		si_get_tile_pipe_to_backend_map(rdev, rdev->config.si.num_tile_pipes,
17630a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						rdev->config.si.num_backends_per_se *
17640a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						rdev->config.si.num_shader_engines,
17650a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						&rdev->config.si.backend_disable_mask_per_asic,
17660a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher						rdev->config.si.num_shader_engines);
17670a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher
17680a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	/* setup tiling info dword.  gb_addr_config is not adequate since it does
17690a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	 * not have bank info, so create a custom tiling dword.
17700a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	 * bits 3:0   num_pipes
17710a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	 * bits 7:4   num_banks
17720a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	 * bits 11:8  group_size
17730a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	 * bits 15:12 row_size
17740a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	 */
17750a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	rdev->config.si.tile_config = 0;
17760a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	switch (rdev->config.si.num_tile_pipes) {
17770a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	case 1:
17780a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher		rdev->config.si.tile_config |= (0 << 0);
17790a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher		break;
17800a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	case 2:
17810a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher		rdev->config.si.tile_config |= (1 << 0);
17820a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher		break;
17830a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	case 4:
17840a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher		rdev->config.si.tile_config |= (2 << 0);
17850a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher		break;
17860a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	case 8:
17870a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	default:
17880a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher		/* XXX what about 12? */
17890a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher		rdev->config.si.tile_config |= (3 << 0);
17900a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher		break;
17910a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	}
17920a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	rdev->config.si.tile_config |=
17930a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher		((mc_arb_ramcfg & NOOFBANK_MASK) >> NOOFBANK_SHIFT) << 4;
17940a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	rdev->config.si.tile_config |=
17950a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher		((gb_addr_config & PIPE_INTERLEAVE_SIZE_MASK) >> PIPE_INTERLEAVE_SIZE_SHIFT) << 8;
17960a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	rdev->config.si.tile_config |=
17970a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher		((gb_addr_config & ROW_SIZE_MASK) >> ROW_SIZE_SHIFT) << 12;
17980a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher
17990a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	rdev->config.si.backend_map = gb_backend_map;
18000a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	WREG32(GB_ADDR_CONFIG, gb_addr_config);
18010a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	WREG32(DMIF_ADDR_CONFIG, gb_addr_config);
18020a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	WREG32(HDP_ADDR_CONFIG, gb_addr_config);
18030a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher
18040a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	/* primary versions */
18050a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	WREG32(CC_RB_BACKEND_DISABLE, cc_rb_backend_disable);
18060a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	WREG32(CC_SYS_RB_BACKEND_DISABLE, cc_rb_backend_disable);
18070a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	WREG32(CC_GC_SHADER_ARRAY_CONFIG, cc_gc_shader_array_config);
18080a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher
18090a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	WREG32(CGTS_TCC_DISABLE, cgts_tcc_disable);
18100a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher
18110a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	/* user versions */
18120a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	WREG32(GC_USER_RB_BACKEND_DISABLE, cc_rb_backend_disable);
18130a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	WREG32(GC_USER_SYS_RB_BACKEND_DISABLE, cc_rb_backend_disable);
18140a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	WREG32(GC_USER_SHADER_ARRAY_CONFIG, cc_gc_shader_array_config);
18150a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher
18160a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	WREG32(CGTS_USER_TCC_DISABLE, cgts_tcc_disable);
18170a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher
18180a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	si_tiling_mode_table_init(rdev);
18190a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher
18200a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	/* set HW defaults for 3D engine */
18210a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	WREG32(CP_QUEUE_THRESHOLDS, (ROQ_IB1_START(0x16) |
18220a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher				     ROQ_IB2_START(0x2b)));
18230a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	WREG32(CP_MEQ_THRESHOLDS, MEQ1_START(0x30) | MEQ2_START(0x60));
18240a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher
18250a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	sx_debug_1 = RREG32(SX_DEBUG_1);
18260a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	WREG32(SX_DEBUG_1, sx_debug_1);
18270a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher
18280a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	WREG32(SPI_CONFIG_CNTL_1, VTX_DONE_DELAY(4));
18290a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher
18300a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	WREG32(PA_SC_FIFO_SIZE, (SC_FRONTEND_PRIM_FIFO_SIZE(rdev->config.si.sc_prim_fifo_size_frontend) |
18310a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher				 SC_BACKEND_PRIM_FIFO_SIZE(rdev->config.si.sc_prim_fifo_size_backend) |
18320a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher				 SC_HIZ_TILE_FIFO_SIZE(rdev->config.si.sc_hiz_tile_fifo_size) |
18330a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher				 SC_EARLYZ_TILE_FIFO_SIZE(rdev->config.si.sc_earlyz_tile_fifo_size)));
18340a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher
18350a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	WREG32(VGT_NUM_INSTANCES, 1);
18360a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher
18370a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	WREG32(CP_PERFMON_CNTL, 0);
18380a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher
18390a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	WREG32(SQ_CONFIG, 0);
18400a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher
18410a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	WREG32(PA_SC_FORCE_EOV_MAX_CNTS, (FORCE_EOV_MAX_CLK_CNT(4095) |
18420a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher					  FORCE_EOV_MAX_REZ_CNT(255)));
18430a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher
18440a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	WREG32(VGT_CACHE_INVALIDATION, CACHE_INVALIDATION(VC_AND_TC) |
18450a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	       AUTO_INVLD_EN(ES_AND_GS_AUTO));
18460a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher
18470a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	WREG32(VGT_GS_VERTEX_REUSE, 16);
18480a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	WREG32(PA_SC_LINE_STIPPLE_STATE, 0);
18490a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher
18500a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	WREG32(CB_PERFCOUNTER0_SELECT0, 0);
18510a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	WREG32(CB_PERFCOUNTER0_SELECT1, 0);
18520a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	WREG32(CB_PERFCOUNTER1_SELECT0, 0);
18530a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	WREG32(CB_PERFCOUNTER1_SELECT1, 0);
18540a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	WREG32(CB_PERFCOUNTER2_SELECT0, 0);
18550a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	WREG32(CB_PERFCOUNTER2_SELECT1, 0);
18560a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	WREG32(CB_PERFCOUNTER3_SELECT0, 0);
18570a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	WREG32(CB_PERFCOUNTER3_SELECT1, 0);
18580a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher
18590a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	tmp = RREG32(HDP_MISC_CNTL);
18600a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	tmp |= HDP_FLUSH_INVALIDATE_CACHE;
18610a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	WREG32(HDP_MISC_CNTL, tmp);
18620a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher
18630a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	hdp_host_path_cntl = RREG32(HDP_HOST_PATH_CNTL);
18640a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	WREG32(HDP_HOST_PATH_CNTL, hdp_host_path_cntl);
18650a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher
18660a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	WREG32(PA_CL_ENHANCE, CLIP_VTX_REORDER_ENA | NUM_CLIP_SEQ(3));
18670a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher
18680a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher	udelay(50);
18690a96d72be9ce6c5080f5b08a07f8e34b81b575baAlex Deucher}
1870c476dde2eda8c3e1af676fe3702b9fce98904cfbAlex Deucher
187148c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher/*
18722ece2e8b7d02040a59bc2f3a7f192c0521e2b867Alex Deucher * GPU scratch registers helpers function.
18732ece2e8b7d02040a59bc2f3a7f192c0521e2b867Alex Deucher */
18742ece2e8b7d02040a59bc2f3a7f192c0521e2b867Alex Deucherstatic void si_scratch_init(struct radeon_device *rdev)
18752ece2e8b7d02040a59bc2f3a7f192c0521e2b867Alex Deucher{
18762ece2e8b7d02040a59bc2f3a7f192c0521e2b867Alex Deucher	int i;
18772ece2e8b7d02040a59bc2f3a7f192c0521e2b867Alex Deucher
18782ece2e8b7d02040a59bc2f3a7f192c0521e2b867Alex Deucher	rdev->scratch.num_reg = 7;
18792ece2e8b7d02040a59bc2f3a7f192c0521e2b867Alex Deucher	rdev->scratch.reg_base = SCRATCH_REG0;
18802ece2e8b7d02040a59bc2f3a7f192c0521e2b867Alex Deucher	for (i = 0; i < rdev->scratch.num_reg; i++) {
18812ece2e8b7d02040a59bc2f3a7f192c0521e2b867Alex Deucher		rdev->scratch.free[i] = true;
18822ece2e8b7d02040a59bc2f3a7f192c0521e2b867Alex Deucher		rdev->scratch.reg[i] = rdev->scratch.reg_base + (i * 4);
18832ece2e8b7d02040a59bc2f3a7f192c0521e2b867Alex Deucher	}
18842ece2e8b7d02040a59bc2f3a7f192c0521e2b867Alex Deucher}
18852ece2e8b7d02040a59bc2f3a7f192c0521e2b867Alex Deucher
18862ece2e8b7d02040a59bc2f3a7f192c0521e2b867Alex Deuchervoid si_fence_ring_emit(struct radeon_device *rdev,
18872ece2e8b7d02040a59bc2f3a7f192c0521e2b867Alex Deucher			struct radeon_fence *fence)
18882ece2e8b7d02040a59bc2f3a7f192c0521e2b867Alex Deucher{
18892ece2e8b7d02040a59bc2f3a7f192c0521e2b867Alex Deucher	struct radeon_ring *ring = &rdev->ring[fence->ring];
18902ece2e8b7d02040a59bc2f3a7f192c0521e2b867Alex Deucher	u64 addr = rdev->fence_drv[fence->ring].gpu_addr;
18912ece2e8b7d02040a59bc2f3a7f192c0521e2b867Alex Deucher
18922ece2e8b7d02040a59bc2f3a7f192c0521e2b867Alex Deucher	/* flush read cache over gart */
18932ece2e8b7d02040a59bc2f3a7f192c0521e2b867Alex Deucher	radeon_ring_write(ring, PACKET3(PACKET3_SET_CONFIG_REG, 1));
18942ece2e8b7d02040a59bc2f3a7f192c0521e2b867Alex Deucher	radeon_ring_write(ring, (CP_COHER_CNTL2 - PACKET3_SET_CONFIG_REG_START) >> 2);
18952ece2e8b7d02040a59bc2f3a7f192c0521e2b867Alex Deucher	radeon_ring_write(ring, 0);
18962ece2e8b7d02040a59bc2f3a7f192c0521e2b867Alex Deucher	radeon_ring_write(ring, PACKET3(PACKET3_SURFACE_SYNC, 3));
18972ece2e8b7d02040a59bc2f3a7f192c0521e2b867Alex Deucher	radeon_ring_write(ring, PACKET3_TCL1_ACTION_ENA |
18982ece2e8b7d02040a59bc2f3a7f192c0521e2b867Alex Deucher			  PACKET3_TC_ACTION_ENA |
18992ece2e8b7d02040a59bc2f3a7f192c0521e2b867Alex Deucher			  PACKET3_SH_KCACHE_ACTION_ENA |
19002ece2e8b7d02040a59bc2f3a7f192c0521e2b867Alex Deucher			  PACKET3_SH_ICACHE_ACTION_ENA);
19012ece2e8b7d02040a59bc2f3a7f192c0521e2b867Alex Deucher	radeon_ring_write(ring, 0xFFFFFFFF);
19022ece2e8b7d02040a59bc2f3a7f192c0521e2b867Alex Deucher	radeon_ring_write(ring, 0);
19032ece2e8b7d02040a59bc2f3a7f192c0521e2b867Alex Deucher	radeon_ring_write(ring, 10); /* poll interval */
19042ece2e8b7d02040a59bc2f3a7f192c0521e2b867Alex Deucher	/* EVENT_WRITE_EOP - flush caches, send int */
19052ece2e8b7d02040a59bc2f3a7f192c0521e2b867Alex Deucher	radeon_ring_write(ring, PACKET3(PACKET3_EVENT_WRITE_EOP, 4));
19062ece2e8b7d02040a59bc2f3a7f192c0521e2b867Alex Deucher	radeon_ring_write(ring, EVENT_TYPE(CACHE_FLUSH_AND_INV_TS_EVENT) | EVENT_INDEX(5));
19072ece2e8b7d02040a59bc2f3a7f192c0521e2b867Alex Deucher	radeon_ring_write(ring, addr & 0xffffffff);
19082ece2e8b7d02040a59bc2f3a7f192c0521e2b867Alex Deucher	radeon_ring_write(ring, (upper_32_bits(addr) & 0xff) | DATA_SEL(1) | INT_SEL(2));
19092ece2e8b7d02040a59bc2f3a7f192c0521e2b867Alex Deucher	radeon_ring_write(ring, fence->seq);
19102ece2e8b7d02040a59bc2f3a7f192c0521e2b867Alex Deucher	radeon_ring_write(ring, 0);
19112ece2e8b7d02040a59bc2f3a7f192c0521e2b867Alex Deucher}
19122ece2e8b7d02040a59bc2f3a7f192c0521e2b867Alex Deucher
19132ece2e8b7d02040a59bc2f3a7f192c0521e2b867Alex Deucher/*
19142ece2e8b7d02040a59bc2f3a7f192c0521e2b867Alex Deucher * IB stuff
19152ece2e8b7d02040a59bc2f3a7f192c0521e2b867Alex Deucher */
19162ece2e8b7d02040a59bc2f3a7f192c0521e2b867Alex Deuchervoid si_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib)
19172ece2e8b7d02040a59bc2f3a7f192c0521e2b867Alex Deucher{
19182ece2e8b7d02040a59bc2f3a7f192c0521e2b867Alex Deucher	struct radeon_ring *ring = &rdev->ring[ib->fence->ring];
19192ece2e8b7d02040a59bc2f3a7f192c0521e2b867Alex Deucher	u32 header;
19202ece2e8b7d02040a59bc2f3a7f192c0521e2b867Alex Deucher
19212ece2e8b7d02040a59bc2f3a7f192c0521e2b867Alex Deucher	if (ib->is_const_ib)
19222ece2e8b7d02040a59bc2f3a7f192c0521e2b867Alex Deucher		header = PACKET3(PACKET3_INDIRECT_BUFFER_CONST, 2);
19232ece2e8b7d02040a59bc2f3a7f192c0521e2b867Alex Deucher	else
19242ece2e8b7d02040a59bc2f3a7f192c0521e2b867Alex Deucher		header = PACKET3(PACKET3_INDIRECT_BUFFER, 2);
19252ece2e8b7d02040a59bc2f3a7f192c0521e2b867Alex Deucher
19262ece2e8b7d02040a59bc2f3a7f192c0521e2b867Alex Deucher	radeon_ring_write(ring, header);
19272ece2e8b7d02040a59bc2f3a7f192c0521e2b867Alex Deucher	radeon_ring_write(ring,
19282ece2e8b7d02040a59bc2f3a7f192c0521e2b867Alex Deucher#ifdef __BIG_ENDIAN
19292ece2e8b7d02040a59bc2f3a7f192c0521e2b867Alex Deucher			  (2 << 0) |
19302ece2e8b7d02040a59bc2f3a7f192c0521e2b867Alex Deucher#endif
19312ece2e8b7d02040a59bc2f3a7f192c0521e2b867Alex Deucher			  (ib->gpu_addr & 0xFFFFFFFC));
19322ece2e8b7d02040a59bc2f3a7f192c0521e2b867Alex Deucher	radeon_ring_write(ring, upper_32_bits(ib->gpu_addr) & 0xFFFF);
19332ece2e8b7d02040a59bc2f3a7f192c0521e2b867Alex Deucher	radeon_ring_write(ring, ib->length_dw | (ib->vm_id << 24));
19342ece2e8b7d02040a59bc2f3a7f192c0521e2b867Alex Deucher
19352ece2e8b7d02040a59bc2f3a7f192c0521e2b867Alex Deucher	/* flush read cache over gart for this vmid */
19362ece2e8b7d02040a59bc2f3a7f192c0521e2b867Alex Deucher	radeon_ring_write(ring, PACKET3(PACKET3_SET_CONFIG_REG, 1));
19372ece2e8b7d02040a59bc2f3a7f192c0521e2b867Alex Deucher	radeon_ring_write(ring, (CP_COHER_CNTL2 - PACKET3_SET_CONFIG_REG_START) >> 2);
19382ece2e8b7d02040a59bc2f3a7f192c0521e2b867Alex Deucher	radeon_ring_write(ring, ib->vm_id);
19392ece2e8b7d02040a59bc2f3a7f192c0521e2b867Alex Deucher	radeon_ring_write(ring, PACKET3(PACKET3_SURFACE_SYNC, 3));
19402ece2e8b7d02040a59bc2f3a7f192c0521e2b867Alex Deucher	radeon_ring_write(ring, PACKET3_TCL1_ACTION_ENA |
19412ece2e8b7d02040a59bc2f3a7f192c0521e2b867Alex Deucher			  PACKET3_TC_ACTION_ENA |
19422ece2e8b7d02040a59bc2f3a7f192c0521e2b867Alex Deucher			  PACKET3_SH_KCACHE_ACTION_ENA |
19432ece2e8b7d02040a59bc2f3a7f192c0521e2b867Alex Deucher			  PACKET3_SH_ICACHE_ACTION_ENA);
19442ece2e8b7d02040a59bc2f3a7f192c0521e2b867Alex Deucher	radeon_ring_write(ring, 0xFFFFFFFF);
19452ece2e8b7d02040a59bc2f3a7f192c0521e2b867Alex Deucher	radeon_ring_write(ring, 0);
19462ece2e8b7d02040a59bc2f3a7f192c0521e2b867Alex Deucher	radeon_ring_write(ring, 10); /* poll interval */
19472ece2e8b7d02040a59bc2f3a7f192c0521e2b867Alex Deucher}
19482ece2e8b7d02040a59bc2f3a7f192c0521e2b867Alex Deucher
19492ece2e8b7d02040a59bc2f3a7f192c0521e2b867Alex Deucher/*
195048c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher * CP.
195148c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher */
195248c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucherstatic void si_cp_enable(struct radeon_device *rdev, bool enable)
195348c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher{
195448c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher	if (enable)
195548c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher		WREG32(CP_ME_CNTL, 0);
195648c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher	else {
195748c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher		radeon_ttm_set_active_vram_size(rdev, rdev->mc.visible_vram_size);
195848c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher		WREG32(CP_ME_CNTL, (CP_ME_HALT | CP_PFP_HALT | CP_CE_HALT));
195948c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher		WREG32(SCRATCH_UMSK, 0);
196048c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher	}
196148c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher	udelay(50);
196248c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher}
196348c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher
196448c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucherstatic int si_cp_load_microcode(struct radeon_device *rdev)
196548c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher{
196648c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher	const __be32 *fw_data;
196748c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher	int i;
196848c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher
196948c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher	if (!rdev->me_fw || !rdev->pfp_fw)
197048c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher		return -EINVAL;
197148c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher
197248c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher	si_cp_enable(rdev, false);
197348c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher
197448c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher	/* PFP */
197548c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher	fw_data = (const __be32 *)rdev->pfp_fw->data;
197648c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher	WREG32(CP_PFP_UCODE_ADDR, 0);
197748c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher	for (i = 0; i < SI_PFP_UCODE_SIZE; i++)
197848c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher		WREG32(CP_PFP_UCODE_DATA, be32_to_cpup(fw_data++));
197948c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher	WREG32(CP_PFP_UCODE_ADDR, 0);
198048c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher
198148c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher	/* CE */
198248c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher	fw_data = (const __be32 *)rdev->ce_fw->data;
198348c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher	WREG32(CP_CE_UCODE_ADDR, 0);
198448c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher	for (i = 0; i < SI_CE_UCODE_SIZE; i++)
198548c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher		WREG32(CP_CE_UCODE_DATA, be32_to_cpup(fw_data++));
198648c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher	WREG32(CP_CE_UCODE_ADDR, 0);
198748c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher
198848c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher	/* ME */
198948c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher	fw_data = (const __be32 *)rdev->me_fw->data;
199048c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher	WREG32(CP_ME_RAM_WADDR, 0);
199148c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher	for (i = 0; i < SI_PM4_UCODE_SIZE; i++)
199248c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher		WREG32(CP_ME_RAM_DATA, be32_to_cpup(fw_data++));
199348c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher	WREG32(CP_ME_RAM_WADDR, 0);
199448c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher
199548c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher	WREG32(CP_PFP_UCODE_ADDR, 0);
199648c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher	WREG32(CP_CE_UCODE_ADDR, 0);
199748c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher	WREG32(CP_ME_RAM_WADDR, 0);
199848c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher	WREG32(CP_ME_RAM_RADDR, 0);
199948c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher	return 0;
200048c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher}
200148c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher
200248c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucherstatic int si_cp_start(struct radeon_device *rdev)
200348c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher{
200448c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher	struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX];
200548c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher	int r, i;
200648c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher
200748c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher	r = radeon_ring_lock(rdev, ring, 7 + 4);
200848c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher	if (r) {
200948c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher		DRM_ERROR("radeon: cp failed to lock ring (%d).\n", r);
201048c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher		return r;
201148c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher	}
201248c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher	/* init the CP */
201348c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher	radeon_ring_write(ring, PACKET3(PACKET3_ME_INITIALIZE, 5));
201448c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher	radeon_ring_write(ring, 0x1);
201548c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher	radeon_ring_write(ring, 0x0);
201648c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher	radeon_ring_write(ring, rdev->config.si.max_hw_contexts - 1);
201748c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher	radeon_ring_write(ring, PACKET3_ME_INITIALIZE_DEVICE_ID(1));
201848c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher	radeon_ring_write(ring, 0);
201948c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher	radeon_ring_write(ring, 0);
202048c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher
202148c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher	/* init the CE partitions */
202248c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher	radeon_ring_write(ring, PACKET3(PACKET3_SET_BASE, 2));
202348c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher	radeon_ring_write(ring, PACKET3_BASE_INDEX(CE_PARTITION_BASE));
202448c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher	radeon_ring_write(ring, 0xc000);
202548c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher	radeon_ring_write(ring, 0xe000);
202648c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher	radeon_ring_unlock_commit(rdev, ring);
202748c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher
202848c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher	si_cp_enable(rdev, true);
202948c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher
203048c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher	r = radeon_ring_lock(rdev, ring, si_default_size + 10);
203148c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher	if (r) {
203248c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher		DRM_ERROR("radeon: cp failed to lock ring (%d).\n", r);
203348c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher		return r;
203448c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher	}
203548c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher
203648c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher	/* setup clear context state */
203748c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher	radeon_ring_write(ring, PACKET3(PACKET3_PREAMBLE_CNTL, 0));
203848c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher	radeon_ring_write(ring, PACKET3_PREAMBLE_BEGIN_CLEAR_STATE);
203948c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher
204048c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher	for (i = 0; i < si_default_size; i++)
204148c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher		radeon_ring_write(ring, si_default_state[i]);
204248c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher
204348c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher	radeon_ring_write(ring, PACKET3(PACKET3_PREAMBLE_CNTL, 0));
204448c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher	radeon_ring_write(ring, PACKET3_PREAMBLE_END_CLEAR_STATE);
204548c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher
204648c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher	/* set clear context state */
204748c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher	radeon_ring_write(ring, PACKET3(PACKET3_CLEAR_STATE, 0));
204848c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher	radeon_ring_write(ring, 0);
204948c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher
205048c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher	radeon_ring_write(ring, PACKET3(PACKET3_SET_CONTEXT_REG, 2));
205148c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher	radeon_ring_write(ring, 0x00000316);
205248c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher	radeon_ring_write(ring, 0x0000000e); /* VGT_VERTEX_REUSE_BLOCK_CNTL */
205348c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher	radeon_ring_write(ring, 0x00000010); /* VGT_OUT_DEALLOC_CNTL */
205448c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher
205548c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher	radeon_ring_unlock_commit(rdev, ring);
205648c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher
205748c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher	for (i = RADEON_RING_TYPE_GFX_INDEX; i <= CAYMAN_RING_TYPE_CP2_INDEX; ++i) {
205848c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher		ring = &rdev->ring[i];
205948c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher		r = radeon_ring_lock(rdev, ring, 2);
206048c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher
206148c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher		/* clear the compute context state */
206248c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher		radeon_ring_write(ring, PACKET3_COMPUTE(PACKET3_CLEAR_STATE, 0));
206348c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher		radeon_ring_write(ring, 0);
206448c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher
206548c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher		radeon_ring_unlock_commit(rdev, ring);
206648c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher	}
206748c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher
206848c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher	return 0;
206948c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher}
207048c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher
207148c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucherstatic void si_cp_fini(struct radeon_device *rdev)
207248c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher{
207348c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher	si_cp_enable(rdev, false);
207448c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher	radeon_ring_fini(rdev, &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]);
207548c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher	radeon_ring_fini(rdev, &rdev->ring[CAYMAN_RING_TYPE_CP1_INDEX]);
207648c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher	radeon_ring_fini(rdev, &rdev->ring[CAYMAN_RING_TYPE_CP2_INDEX]);
207748c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher}
207848c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher
207948c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucherstatic int si_cp_resume(struct radeon_device *rdev)
208048c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher{
208148c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher	struct radeon_ring *ring;
208248c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher	u32 tmp;
208348c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher	u32 rb_bufsz;
208448c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher	int r;
208548c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher
208648c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher	/* Reset cp; if cp is reset, then PA, SH, VGT also need to be reset */
208748c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher	WREG32(GRBM_SOFT_RESET, (SOFT_RESET_CP |
208848c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher				 SOFT_RESET_PA |
208948c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher				 SOFT_RESET_VGT |
209048c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher				 SOFT_RESET_SPI |
209148c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher				 SOFT_RESET_SX));
209248c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher	RREG32(GRBM_SOFT_RESET);
209348c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher	mdelay(15);
209448c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher	WREG32(GRBM_SOFT_RESET, 0);
209548c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher	RREG32(GRBM_SOFT_RESET);
209648c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher
209748c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher	WREG32(CP_SEM_WAIT_TIMER, 0x0);
209848c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher	WREG32(CP_SEM_INCOMPLETE_TIMER_CNTL, 0x0);
209948c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher
210048c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher	/* Set the write pointer delay */
210148c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher	WREG32(CP_RB_WPTR_DELAY, 0);
210248c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher
210348c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher	WREG32(CP_DEBUG, 0);
210448c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher	WREG32(SCRATCH_ADDR, ((rdev->wb.gpu_addr + RADEON_WB_SCRATCH_OFFSET) >> 8) & 0xFFFFFFFF);
210548c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher
210648c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher	/* ring 0 - compute and gfx */
210748c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher	/* Set ring buffer size */
210848c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher	ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX];
210948c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher	rb_bufsz = drm_order(ring->ring_size / 8);
211048c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher	tmp = (drm_order(RADEON_GPU_PAGE_SIZE/8) << 8) | rb_bufsz;
211148c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher#ifdef __BIG_ENDIAN
211248c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher	tmp |= BUF_SWAP_32BIT;
211348c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher#endif
211448c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher	WREG32(CP_RB0_CNTL, tmp);
211548c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher
211648c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher	/* Initialize the ring buffer's read and write pointers */
211748c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher	WREG32(CP_RB0_CNTL, tmp | RB_RPTR_WR_ENA);
211848c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher	ring->wptr = 0;
211948c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher	WREG32(CP_RB0_WPTR, ring->wptr);
212048c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher
212148c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher	/* set the wb address wether it's enabled or not */
212248c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher	WREG32(CP_RB0_RPTR_ADDR, (rdev->wb.gpu_addr + RADEON_WB_CP_RPTR_OFFSET) & 0xFFFFFFFC);
212348c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher	WREG32(CP_RB0_RPTR_ADDR_HI, upper_32_bits(rdev->wb.gpu_addr + RADEON_WB_CP_RPTR_OFFSET) & 0xFF);
212448c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher
212548c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher	if (rdev->wb.enabled)
212648c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher		WREG32(SCRATCH_UMSK, 0xff);
212748c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher	else {
212848c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher		tmp |= RB_NO_UPDATE;
212948c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher		WREG32(SCRATCH_UMSK, 0);
213048c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher	}
213148c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher
213248c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher	mdelay(1);
213348c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher	WREG32(CP_RB0_CNTL, tmp);
213448c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher
213548c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher	WREG32(CP_RB0_BASE, ring->gpu_addr >> 8);
213648c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher
213748c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher	ring->rptr = RREG32(CP_RB0_RPTR);
213848c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher
213948c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher	/* ring1  - compute only */
214048c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher	/* Set ring buffer size */
214148c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher	ring = &rdev->ring[CAYMAN_RING_TYPE_CP1_INDEX];
214248c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher	rb_bufsz = drm_order(ring->ring_size / 8);
214348c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher	tmp = (drm_order(RADEON_GPU_PAGE_SIZE/8) << 8) | rb_bufsz;
214448c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher#ifdef __BIG_ENDIAN
214548c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher	tmp |= BUF_SWAP_32BIT;
214648c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher#endif
214748c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher	WREG32(CP_RB1_CNTL, tmp);
214848c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher
214948c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher	/* Initialize the ring buffer's read and write pointers */
215048c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher	WREG32(CP_RB1_CNTL, tmp | RB_RPTR_WR_ENA);
215148c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher	ring->wptr = 0;
215248c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher	WREG32(CP_RB1_WPTR, ring->wptr);
215348c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher
215448c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher	/* set the wb address wether it's enabled or not */
215548c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher	WREG32(CP_RB1_RPTR_ADDR, (rdev->wb.gpu_addr + RADEON_WB_CP1_RPTR_OFFSET) & 0xFFFFFFFC);
215648c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher	WREG32(CP_RB1_RPTR_ADDR_HI, upper_32_bits(rdev->wb.gpu_addr + RADEON_WB_CP1_RPTR_OFFSET) & 0xFF);
215748c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher
215848c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher	mdelay(1);
215948c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher	WREG32(CP_RB1_CNTL, tmp);
216048c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher
216148c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher	WREG32(CP_RB1_BASE, ring->gpu_addr >> 8);
216248c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher
216348c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher	ring->rptr = RREG32(CP_RB1_RPTR);
216448c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher
216548c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher	/* ring2 - compute only */
216648c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher	/* Set ring buffer size */
216748c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher	ring = &rdev->ring[CAYMAN_RING_TYPE_CP2_INDEX];
216848c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher	rb_bufsz = drm_order(ring->ring_size / 8);
216948c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher	tmp = (drm_order(RADEON_GPU_PAGE_SIZE/8) << 8) | rb_bufsz;
217048c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher#ifdef __BIG_ENDIAN
217148c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher	tmp |= BUF_SWAP_32BIT;
217248c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher#endif
217348c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher	WREG32(CP_RB2_CNTL, tmp);
217448c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher
217548c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher	/* Initialize the ring buffer's read and write pointers */
217648c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher	WREG32(CP_RB2_CNTL, tmp | RB_RPTR_WR_ENA);
217748c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher	ring->wptr = 0;
217848c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher	WREG32(CP_RB2_WPTR, ring->wptr);
217948c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher
218048c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher	/* set the wb address wether it's enabled or not */
218148c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher	WREG32(CP_RB2_RPTR_ADDR, (rdev->wb.gpu_addr + RADEON_WB_CP2_RPTR_OFFSET) & 0xFFFFFFFC);
218248c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher	WREG32(CP_RB2_RPTR_ADDR_HI, upper_32_bits(rdev->wb.gpu_addr + RADEON_WB_CP2_RPTR_OFFSET) & 0xFF);
218348c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher
218448c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher	mdelay(1);
218548c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher	WREG32(CP_RB2_CNTL, tmp);
218648c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher
218748c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher	WREG32(CP_RB2_BASE, ring->gpu_addr >> 8);
218848c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher
218948c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher	ring->rptr = RREG32(CP_RB2_RPTR);
219048c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher
219148c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher	/* start the rings */
219248c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher	si_cp_start(rdev);
219348c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher	rdev->ring[RADEON_RING_TYPE_GFX_INDEX].ready = true;
219448c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher	rdev->ring[CAYMAN_RING_TYPE_CP1_INDEX].ready = true;
219548c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher	rdev->ring[CAYMAN_RING_TYPE_CP2_INDEX].ready = true;
219648c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher	r = radeon_ring_test(rdev, RADEON_RING_TYPE_GFX_INDEX, &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]);
219748c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher	if (r) {
219848c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher		rdev->ring[RADEON_RING_TYPE_GFX_INDEX].ready = false;
219948c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher		rdev->ring[CAYMAN_RING_TYPE_CP1_INDEX].ready = false;
220048c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher		rdev->ring[CAYMAN_RING_TYPE_CP2_INDEX].ready = false;
220148c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher		return r;
220248c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher	}
220348c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher	r = radeon_ring_test(rdev, CAYMAN_RING_TYPE_CP1_INDEX, &rdev->ring[CAYMAN_RING_TYPE_CP1_INDEX]);
220448c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher	if (r) {
220548c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher		rdev->ring[CAYMAN_RING_TYPE_CP1_INDEX].ready = false;
220648c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher	}
220748c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher	r = radeon_ring_test(rdev, CAYMAN_RING_TYPE_CP2_INDEX, &rdev->ring[CAYMAN_RING_TYPE_CP2_INDEX]);
220848c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher	if (r) {
220948c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher		rdev->ring[CAYMAN_RING_TYPE_CP2_INDEX].ready = false;
221048c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher	}
221148c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher
221248c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher	return 0;
221348c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher}
221448c0c902e2e6ca07b8c7ae1da48a7bb59eb88de9Alex Deucher
2215c476dde2eda8c3e1af676fe3702b9fce98904cfbAlex Deucherbool si_gpu_is_lockup(struct radeon_device *rdev, struct radeon_ring *ring)
2216c476dde2eda8c3e1af676fe3702b9fce98904cfbAlex Deucher{
2217c476dde2eda8c3e1af676fe3702b9fce98904cfbAlex Deucher	u32 srbm_status;
2218c476dde2eda8c3e1af676fe3702b9fce98904cfbAlex Deucher	u32 grbm_status, grbm_status2;
2219c476dde2eda8c3e1af676fe3702b9fce98904cfbAlex Deucher	u32 grbm_status_se0, grbm_status_se1;
2220c476dde2eda8c3e1af676fe3702b9fce98904cfbAlex Deucher	struct r100_gpu_lockup *lockup = &rdev->config.si.lockup;
2221c476dde2eda8c3e1af676fe3702b9fce98904cfbAlex Deucher	int r;
2222c476dde2eda8c3e1af676fe3702b9fce98904cfbAlex Deucher
2223c476dde2eda8c3e1af676fe3702b9fce98904cfbAlex Deucher	srbm_status = RREG32(SRBM_STATUS);
2224c476dde2eda8c3e1af676fe3702b9fce98904cfbAlex Deucher	grbm_status = RREG32(GRBM_STATUS);
2225c476dde2eda8c3e1af676fe3702b9fce98904cfbAlex Deucher	grbm_status2 = RREG32(GRBM_STATUS2);
2226c476dde2eda8c3e1af676fe3702b9fce98904cfbAlex Deucher	grbm_status_se0 = RREG32(GRBM_STATUS_SE0);
2227c476dde2eda8c3e1af676fe3702b9fce98904cfbAlex Deucher	grbm_status_se1 = RREG32(GRBM_STATUS_SE1);
2228c476dde2eda8c3e1af676fe3702b9fce98904cfbAlex Deucher	if (!(grbm_status & GUI_ACTIVE)) {
2229c476dde2eda8c3e1af676fe3702b9fce98904cfbAlex Deucher		r100_gpu_lockup_update(lockup, ring);
2230c476dde2eda8c3e1af676fe3702b9fce98904cfbAlex Deucher		return false;
2231c476dde2eda8c3e1af676fe3702b9fce98904cfbAlex Deucher	}
2232c476dde2eda8c3e1af676fe3702b9fce98904cfbAlex Deucher	/* force CP activities */
2233c476dde2eda8c3e1af676fe3702b9fce98904cfbAlex Deucher	r = radeon_ring_lock(rdev, ring, 2);
2234c476dde2eda8c3e1af676fe3702b9fce98904cfbAlex Deucher	if (!r) {
2235c476dde2eda8c3e1af676fe3702b9fce98904cfbAlex Deucher		/* PACKET2 NOP */
2236c476dde2eda8c3e1af676fe3702b9fce98904cfbAlex Deucher		radeon_ring_write(ring, 0x80000000);
2237c476dde2eda8c3e1af676fe3702b9fce98904cfbAlex Deucher		radeon_ring_write(ring, 0x80000000);
2238c476dde2eda8c3e1af676fe3702b9fce98904cfbAlex Deucher		radeon_ring_unlock_commit(rdev, ring);
2239c476dde2eda8c3e1af676fe3702b9fce98904cfbAlex Deucher	}
2240c476dde2eda8c3e1af676fe3702b9fce98904cfbAlex Deucher	/* XXX deal with CP0,1,2 */
2241c476dde2eda8c3e1af676fe3702b9fce98904cfbAlex Deucher	ring->rptr = RREG32(ring->rptr_reg);
2242c476dde2eda8c3e1af676fe3702b9fce98904cfbAlex Deucher	return r100_gpu_cp_is_lockup(rdev, lockup, ring);
2243c476dde2eda8c3e1af676fe3702b9fce98904cfbAlex Deucher}
2244c476dde2eda8c3e1af676fe3702b9fce98904cfbAlex Deucher
2245c476dde2eda8c3e1af676fe3702b9fce98904cfbAlex Deucherstatic int si_gpu_soft_reset(struct radeon_device *rdev)
2246c476dde2eda8c3e1af676fe3702b9fce98904cfbAlex Deucher{
2247c476dde2eda8c3e1af676fe3702b9fce98904cfbAlex Deucher	struct evergreen_mc_save save;
2248c476dde2eda8c3e1af676fe3702b9fce98904cfbAlex Deucher	u32 grbm_reset = 0;
2249c476dde2eda8c3e1af676fe3702b9fce98904cfbAlex Deucher
2250c476dde2eda8c3e1af676fe3702b9fce98904cfbAlex Deucher	if (!(RREG32(GRBM_STATUS) & GUI_ACTIVE))
2251c476dde2eda8c3e1af676fe3702b9fce98904cfbAlex Deucher		return 0;
2252c476dde2eda8c3e1af676fe3702b9fce98904cfbAlex Deucher
2253c476dde2eda8c3e1af676fe3702b9fce98904cfbAlex Deucher	dev_info(rdev->dev, "GPU softreset \n");
2254c476dde2eda8c3e1af676fe3702b9fce98904cfbAlex Deucher	dev_info(rdev->dev, "  GRBM_STATUS=0x%08X\n",
2255c476dde2eda8c3e1af676fe3702b9fce98904cfbAlex Deucher		RREG32(GRBM_STATUS));
2256c476dde2eda8c3e1af676fe3702b9fce98904cfbAlex Deucher	dev_info(rdev->dev, "  GRBM_STATUS2=0x%08X\n",
2257c476dde2eda8c3e1af676fe3702b9fce98904cfbAlex Deucher		RREG32(GRBM_STATUS2));
2258c476dde2eda8c3e1af676fe3702b9fce98904cfbAlex Deucher	dev_info(rdev->dev, "  GRBM_STATUS_SE0=0x%08X\n",
2259c476dde2eda8c3e1af676fe3702b9fce98904cfbAlex Deucher		RREG32(GRBM_STATUS_SE0));
2260c476dde2eda8c3e1af676fe3702b9fce98904cfbAlex Deucher	dev_info(rdev->dev, "  GRBM_STATUS_SE1=0x%08X\n",
2261c476dde2eda8c3e1af676fe3702b9fce98904cfbAlex Deucher		RREG32(GRBM_STATUS_SE1));
2262c476dde2eda8c3e1af676fe3702b9fce98904cfbAlex Deucher	dev_info(rdev->dev, "  SRBM_STATUS=0x%08X\n",
2263c476dde2eda8c3e1af676fe3702b9fce98904cfbAlex Deucher		RREG32(SRBM_STATUS));
2264c476dde2eda8c3e1af676fe3702b9fce98904cfbAlex Deucher	evergreen_mc_stop(rdev, &save);
2265c476dde2eda8c3e1af676fe3702b9fce98904cfbAlex Deucher	if (radeon_mc_wait_for_idle(rdev)) {
2266c476dde2eda8c3e1af676fe3702b9fce98904cfbAlex Deucher		dev_warn(rdev->dev, "Wait for MC idle timedout !\n");
2267c476dde2eda8c3e1af676fe3702b9fce98904cfbAlex Deucher	}
2268c476dde2eda8c3e1af676fe3702b9fce98904cfbAlex Deucher	/* Disable CP parsing/prefetching */
2269c476dde2eda8c3e1af676fe3702b9fce98904cfbAlex Deucher	WREG32(CP_ME_CNTL, CP_ME_HALT | CP_PFP_HALT | CP_CE_HALT);
2270c476dde2eda8c3e1af676fe3702b9fce98904cfbAlex Deucher
2271c476dde2eda8c3e1af676fe3702b9fce98904cfbAlex Deucher	/* reset all the gfx blocks */
2272c476dde2eda8c3e1af676fe3702b9fce98904cfbAlex Deucher	grbm_reset = (SOFT_RESET_CP |
2273c476dde2eda8c3e1af676fe3702b9fce98904cfbAlex Deucher		      SOFT_RESET_CB |
2274c476dde2eda8c3e1af676fe3702b9fce98904cfbAlex Deucher		      SOFT_RESET_DB |
2275c476dde2eda8c3e1af676fe3702b9fce98904cfbAlex Deucher		      SOFT_RESET_GDS |
2276c476dde2eda8c3e1af676fe3702b9fce98904cfbAlex Deucher		      SOFT_RESET_PA |
2277c476dde2eda8c3e1af676fe3702b9fce98904cfbAlex Deucher		      SOFT_RESET_SC |
2278c476dde2eda8c3e1af676fe3702b9fce98904cfbAlex Deucher		      SOFT_RESET_SPI |
2279c476dde2eda8c3e1af676fe3702b9fce98904cfbAlex Deucher		      SOFT_RESET_SX |
2280c476dde2eda8c3e1af676fe3702b9fce98904cfbAlex Deucher		      SOFT_RESET_TC |
2281c476dde2eda8c3e1af676fe3702b9fce98904cfbAlex Deucher		      SOFT_RESET_TA |
2282c476dde2eda8c3e1af676fe3702b9fce98904cfbAlex Deucher		      SOFT_RESET_VGT |
2283c476dde2eda8c3e1af676fe3702b9fce98904cfbAlex Deucher		      SOFT_RESET_IA);
2284c476dde2eda8c3e1af676fe3702b9fce98904cfbAlex Deucher
2285c476dde2eda8c3e1af676fe3702b9fce98904cfbAlex Deucher	dev_info(rdev->dev, "  GRBM_SOFT_RESET=0x%08X\n", grbm_reset);
2286c476dde2eda8c3e1af676fe3702b9fce98904cfbAlex Deucher	WREG32(GRBM_SOFT_RESET, grbm_reset);
2287c476dde2eda8c3e1af676fe3702b9fce98904cfbAlex Deucher	(void)RREG32(GRBM_SOFT_RESET);
2288c476dde2eda8c3e1af676fe3702b9fce98904cfbAlex Deucher	udelay(50);
2289c476dde2eda8c3e1af676fe3702b9fce98904cfbAlex Deucher	WREG32(GRBM_SOFT_RESET, 0);
2290c476dde2eda8c3e1af676fe3702b9fce98904cfbAlex Deucher	(void)RREG32(GRBM_SOFT_RESET);
2291c476dde2eda8c3e1af676fe3702b9fce98904cfbAlex Deucher	/* Wait a little for things to settle down */
2292c476dde2eda8c3e1af676fe3702b9fce98904cfbAlex Deucher	udelay(50);
2293c476dde2eda8c3e1af676fe3702b9fce98904cfbAlex Deucher	dev_info(rdev->dev, "  GRBM_STATUS=0x%08X\n",
2294c476dde2eda8c3e1af676fe3702b9fce98904cfbAlex Deucher		RREG32(GRBM_STATUS));
2295c476dde2eda8c3e1af676fe3702b9fce98904cfbAlex Deucher	dev_info(rdev->dev, "  GRBM_STATUS2=0x%08X\n",
2296c476dde2eda8c3e1af676fe3702b9fce98904cfbAlex Deucher		RREG32(GRBM_STATUS2));
2297c476dde2eda8c3e1af676fe3702b9fce98904cfbAlex Deucher	dev_info(rdev->dev, "  GRBM_STATUS_SE0=0x%08X\n",
2298c476dde2eda8c3e1af676fe3702b9fce98904cfbAlex Deucher		RREG32(GRBM_STATUS_SE0));
2299c476dde2eda8c3e1af676fe3702b9fce98904cfbAlex Deucher	dev_info(rdev->dev, "  GRBM_STATUS_SE1=0x%08X\n",
2300c476dde2eda8c3e1af676fe3702b9fce98904cfbAlex Deucher		RREG32(GRBM_STATUS_SE1));
2301c476dde2eda8c3e1af676fe3702b9fce98904cfbAlex Deucher	dev_info(rdev->dev, "  SRBM_STATUS=0x%08X\n",
2302c476dde2eda8c3e1af676fe3702b9fce98904cfbAlex Deucher		RREG32(SRBM_STATUS));
2303c476dde2eda8c3e1af676fe3702b9fce98904cfbAlex Deucher	evergreen_mc_resume(rdev, &save);
2304c476dde2eda8c3e1af676fe3702b9fce98904cfbAlex Deucher	return 0;
2305c476dde2eda8c3e1af676fe3702b9fce98904cfbAlex Deucher}
2306c476dde2eda8c3e1af676fe3702b9fce98904cfbAlex Deucher
2307c476dde2eda8c3e1af676fe3702b9fce98904cfbAlex Deucherint si_asic_reset(struct radeon_device *rdev)
2308c476dde2eda8c3e1af676fe3702b9fce98904cfbAlex Deucher{
2309c476dde2eda8c3e1af676fe3702b9fce98904cfbAlex Deucher	return si_gpu_soft_reset(rdev);
2310c476dde2eda8c3e1af676fe3702b9fce98904cfbAlex Deucher}
2311c476dde2eda8c3e1af676fe3702b9fce98904cfbAlex Deucher
2312d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher/* MC */
2313d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucherstatic void si_mc_program(struct radeon_device *rdev)
2314d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher{
2315d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher	struct evergreen_mc_save save;
2316d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher	u32 tmp;
2317d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher	int i, j;
2318d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher
2319d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher	/* Initialize HDP */
2320d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher	for (i = 0, j = 0; i < 32; i++, j += 0x18) {
2321d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher		WREG32((0x2c14 + j), 0x00000000);
2322d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher		WREG32((0x2c18 + j), 0x00000000);
2323d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher		WREG32((0x2c1c + j), 0x00000000);
2324d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher		WREG32((0x2c20 + j), 0x00000000);
2325d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher		WREG32((0x2c24 + j), 0x00000000);
2326d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher	}
2327d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher	WREG32(HDP_REG_COHERENCY_FLUSH_CNTL, 0);
2328d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher
2329d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher	evergreen_mc_stop(rdev, &save);
2330d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher	if (radeon_mc_wait_for_idle(rdev)) {
2331d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher		dev_warn(rdev->dev, "Wait for MC idle timedout !\n");
2332d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher	}
2333d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher	/* Lockout access through VGA aperture*/
2334d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher	WREG32(VGA_HDP_CONTROL, VGA_MEMORY_DISABLE);
2335d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher	/* Update configuration */
2336d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher	WREG32(MC_VM_SYSTEM_APERTURE_LOW_ADDR,
2337d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher	       rdev->mc.vram_start >> 12);
2338d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher	WREG32(MC_VM_SYSTEM_APERTURE_HIGH_ADDR,
2339d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher	       rdev->mc.vram_end >> 12);
2340d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher	WREG32(MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR,
2341d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher	       rdev->vram_scratch.gpu_addr >> 12);
2342d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher	tmp = ((rdev->mc.vram_end >> 24) & 0xFFFF) << 16;
2343d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher	tmp |= ((rdev->mc.vram_start >> 24) & 0xFFFF);
2344d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher	WREG32(MC_VM_FB_LOCATION, tmp);
2345d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher	/* XXX double check these! */
2346d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher	WREG32(HDP_NONSURFACE_BASE, (rdev->mc.vram_start >> 8));
2347d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher	WREG32(HDP_NONSURFACE_INFO, (2 << 7) | (1 << 30));
2348d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher	WREG32(HDP_NONSURFACE_SIZE, 0x3FFFFFFF);
2349d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher	WREG32(MC_VM_AGP_BASE, 0);
2350d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher	WREG32(MC_VM_AGP_TOP, 0x0FFFFFFF);
2351d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher	WREG32(MC_VM_AGP_BOT, 0x0FFFFFFF);
2352d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher	if (radeon_mc_wait_for_idle(rdev)) {
2353d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher		dev_warn(rdev->dev, "Wait for MC idle timedout !\n");
2354d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher	}
2355d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher	evergreen_mc_resume(rdev, &save);
2356d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher	/* we need to own VRAM, so turn off the VGA renderer here
2357d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher	 * to stop it overwriting our objects */
2358d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher	rv515_vga_render_disable(rdev);
2359d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher}
2360d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher
2361d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher/* SI MC address space is 40 bits */
2362d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucherstatic void si_vram_location(struct radeon_device *rdev,
2363d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher			     struct radeon_mc *mc, u64 base)
2364d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher{
2365d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher	mc->vram_start = base;
2366d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher	if (mc->mc_vram_size > (0xFFFFFFFFFFULL - base + 1)) {
2367d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher		dev_warn(rdev->dev, "limiting VRAM to PCI aperture size\n");
2368d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher		mc->real_vram_size = mc->aper_size;
2369d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher		mc->mc_vram_size = mc->aper_size;
2370d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher	}
2371d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher	mc->vram_end = mc->vram_start + mc->mc_vram_size - 1;
2372d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher	dev_info(rdev->dev, "VRAM: %lluM 0x%016llX - 0x%016llX (%lluM used)\n",
2373d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher			mc->mc_vram_size >> 20, mc->vram_start,
2374d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher			mc->vram_end, mc->real_vram_size >> 20);
2375d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher}
2376d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher
2377d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucherstatic void si_gtt_location(struct radeon_device *rdev, struct radeon_mc *mc)
2378d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher{
2379d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher	u64 size_af, size_bf;
2380d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher
2381d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher	size_af = ((0xFFFFFFFFFFULL - mc->vram_end) + mc->gtt_base_align) & ~mc->gtt_base_align;
2382d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher	size_bf = mc->vram_start & ~mc->gtt_base_align;
2383d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher	if (size_bf > size_af) {
2384d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher		if (mc->gtt_size > size_bf) {
2385d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher			dev_warn(rdev->dev, "limiting GTT\n");
2386d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher			mc->gtt_size = size_bf;
2387d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher		}
2388d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher		mc->gtt_start = (mc->vram_start & ~mc->gtt_base_align) - mc->gtt_size;
2389d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher	} else {
2390d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher		if (mc->gtt_size > size_af) {
2391d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher			dev_warn(rdev->dev, "limiting GTT\n");
2392d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher			mc->gtt_size = size_af;
2393d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher		}
2394d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher		mc->gtt_start = (mc->vram_end + 1 + mc->gtt_base_align) & ~mc->gtt_base_align;
2395d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher	}
2396d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher	mc->gtt_end = mc->gtt_start + mc->gtt_size - 1;
2397d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher	dev_info(rdev->dev, "GTT: %lluM 0x%016llX - 0x%016llX\n",
2398d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher			mc->gtt_size >> 20, mc->gtt_start, mc->gtt_end);
2399d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher}
2400d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher
2401d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucherstatic void si_vram_gtt_location(struct radeon_device *rdev,
2402d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher				 struct radeon_mc *mc)
2403d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher{
2404d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher	if (mc->mc_vram_size > 0xFFC0000000ULL) {
2405d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher		/* leave room for at least 1024M GTT */
2406d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher		dev_warn(rdev->dev, "limiting VRAM\n");
2407d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher		mc->real_vram_size = 0xFFC0000000ULL;
2408d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher		mc->mc_vram_size = 0xFFC0000000ULL;
2409d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher	}
2410d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher	si_vram_location(rdev, &rdev->mc, 0);
2411d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher	rdev->mc.gtt_base_align = 0;
2412d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher	si_gtt_location(rdev, mc);
2413d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher}
2414d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher
2415d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucherstatic int si_mc_init(struct radeon_device *rdev)
2416d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher{
2417d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher	u32 tmp;
2418d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher	int chansize, numchan;
2419d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher
2420d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher	/* Get VRAM informations */
2421d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher	rdev->mc.vram_is_ddr = true;
2422d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher	tmp = RREG32(MC_ARB_RAMCFG);
2423d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher	if (tmp & CHANSIZE_OVERRIDE) {
2424d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher		chansize = 16;
2425d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher	} else if (tmp & CHANSIZE_MASK) {
2426d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher		chansize = 64;
2427d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher	} else {
2428d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher		chansize = 32;
2429d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher	}
2430d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher	tmp = RREG32(MC_SHARED_CHMAP);
2431d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher	switch ((tmp & NOOFCHAN_MASK) >> NOOFCHAN_SHIFT) {
2432d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher	case 0:
2433d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher	default:
2434d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher		numchan = 1;
2435d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher		break;
2436d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher	case 1:
2437d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher		numchan = 2;
2438d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher		break;
2439d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher	case 2:
2440d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher		numchan = 4;
2441d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher		break;
2442d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher	case 3:
2443d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher		numchan = 8;
2444d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher		break;
2445d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher	case 4:
2446d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher		numchan = 3;
2447d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher		break;
2448d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher	case 5:
2449d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher		numchan = 6;
2450d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher		break;
2451d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher	case 6:
2452d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher		numchan = 10;
2453d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher		break;
2454d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher	case 7:
2455d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher		numchan = 12;
2456d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher		break;
2457d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher	case 8:
2458d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher		numchan = 16;
2459d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher		break;
2460d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher	}
2461d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher	rdev->mc.vram_width = numchan * chansize;
2462d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher	/* Could aper size report 0 ? */
2463d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher	rdev->mc.aper_base = pci_resource_start(rdev->pdev, 0);
2464d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher	rdev->mc.aper_size = pci_resource_len(rdev->pdev, 0);
2465d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher	/* size in MB on si */
2466d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher	rdev->mc.mc_vram_size = RREG32(CONFIG_MEMSIZE) * 1024 * 1024;
2467d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher	rdev->mc.real_vram_size = RREG32(CONFIG_MEMSIZE) * 1024 * 1024;
2468d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher	rdev->mc.visible_vram_size = rdev->mc.aper_size;
2469d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher	si_vram_gtt_location(rdev, &rdev->mc);
2470d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher	radeon_update_bandwidth_info(rdev);
2471d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher
2472d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher	return 0;
2473d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher}
2474d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher
2475d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher/*
2476d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher * GART
2477d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher */
2478d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deuchervoid si_pcie_gart_tlb_flush(struct radeon_device *rdev)
2479d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher{
2480d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher	/* flush hdp cache */
2481d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher	WREG32(HDP_MEM_COHERENCY_FLUSH_CNTL, 0x1);
2482d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher
2483d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher	/* bits 0-15 are the VM contexts0-15 */
2484d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher	WREG32(VM_INVALIDATE_REQUEST, 1);
2485d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher}
2486d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher
2487d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucherint si_pcie_gart_enable(struct radeon_device *rdev)
2488d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher{
2489d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher	int r, i;
2490d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher
2491d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher	if (rdev->gart.robj == NULL) {
2492d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher		dev_err(rdev->dev, "No VRAM object for PCIE GART.\n");
2493d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher		return -EINVAL;
2494d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher	}
2495d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher	r = radeon_gart_table_vram_pin(rdev);
2496d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher	if (r)
2497d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher		return r;
2498d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher	radeon_gart_restore(rdev);
2499d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher	/* Setup TLB control */
2500d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher	WREG32(MC_VM_MX_L1_TLB_CNTL,
2501d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher	       (0xA << 7) |
2502d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher	       ENABLE_L1_TLB |
2503d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher	       SYSTEM_ACCESS_MODE_NOT_IN_SYS |
2504d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher	       ENABLE_ADVANCED_DRIVER_MODEL |
2505d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher	       SYSTEM_APERTURE_UNMAPPED_ACCESS_PASS_THRU);
2506d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher	/* Setup L2 cache */
2507d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher	WREG32(VM_L2_CNTL, ENABLE_L2_CACHE |
2508d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher	       ENABLE_L2_PTE_CACHE_LRU_UPDATE_BY_WRITE |
2509d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher	       ENABLE_L2_PDE0_CACHE_LRU_UPDATE_BY_WRITE |
2510d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher	       EFFECTIVE_L2_QUEUE_SIZE(7) |
2511d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher	       CONTEXT1_IDENTITY_ACCESS_MODE(1));
2512d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher	WREG32(VM_L2_CNTL2, INVALIDATE_ALL_L1_TLBS | INVALIDATE_L2_CACHE);
2513d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher	WREG32(VM_L2_CNTL3, L2_CACHE_BIGK_ASSOCIATIVITY |
2514d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher	       L2_CACHE_BIGK_FRAGMENT_SIZE(0));
2515d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher	/* setup context0 */
2516d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher	WREG32(VM_CONTEXT0_PAGE_TABLE_START_ADDR, rdev->mc.gtt_start >> 12);
2517d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher	WREG32(VM_CONTEXT0_PAGE_TABLE_END_ADDR, rdev->mc.gtt_end >> 12);
2518d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher	WREG32(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR, rdev->gart.table_addr >> 12);
2519d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher	WREG32(VM_CONTEXT0_PROTECTION_FAULT_DEFAULT_ADDR,
2520d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher			(u32)(rdev->dummy_page.addr >> 12));
2521d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher	WREG32(VM_CONTEXT0_CNTL2, 0);
2522d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher	WREG32(VM_CONTEXT0_CNTL, (ENABLE_CONTEXT | PAGE_TABLE_DEPTH(0) |
2523d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher				  RANGE_PROTECTION_FAULT_ENABLE_DEFAULT));
2524d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher
2525d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher	WREG32(0x15D4, 0);
2526d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher	WREG32(0x15D8, 0);
2527d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher	WREG32(0x15DC, 0);
2528d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher
2529d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher	/* empty context1-15 */
2530a00d69ed0676b53e7e5c8d086d47a92f15b91e38Alex Deucher	/* FIXME start with 4G, once using 2 level pt switch to full
2531d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher	 * vm size space
2532d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher	 */
2533d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher	/* set vm size, must be a multiple of 4 */
2534d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher	WREG32(VM_CONTEXT1_PAGE_TABLE_START_ADDR, 0);
2535a00d69ed0676b53e7e5c8d086d47a92f15b91e38Alex Deucher	WREG32(VM_CONTEXT1_PAGE_TABLE_END_ADDR, rdev->vm_manager.max_pfn);
2536d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher	for (i = 1; i < 16; i++) {
2537d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher		if (i < 8)
2538d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher			WREG32(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR + (i << 2),
2539d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher			       rdev->gart.table_addr >> 12);
2540d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher		else
2541d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher			WREG32(VM_CONTEXT8_PAGE_TABLE_BASE_ADDR + ((i - 8) << 2),
2542d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher			       rdev->gart.table_addr >> 12);
2543d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher	}
2544d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher
2545d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher	/* enable context1-15 */
2546d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher	WREG32(VM_CONTEXT1_PROTECTION_FAULT_DEFAULT_ADDR,
2547d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher	       (u32)(rdev->dummy_page.addr >> 12));
2548d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher	WREG32(VM_CONTEXT1_CNTL2, 0);
2549d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher	WREG32(VM_CONTEXT1_CNTL, ENABLE_CONTEXT | PAGE_TABLE_DEPTH(0) |
2550d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher				RANGE_PROTECTION_FAULT_ENABLE_DEFAULT);
2551d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher
2552d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher	si_pcie_gart_tlb_flush(rdev);
2553d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher	DRM_INFO("PCIE GART of %uM enabled (table at 0x%016llX).\n",
2554d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher		 (unsigned)(rdev->mc.gtt_size >> 20),
2555d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher		 (unsigned long long)rdev->gart.table_addr);
2556d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher	rdev->gart.ready = true;
2557d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher	return 0;
2558d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher}
2559d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher
2560d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deuchervoid si_pcie_gart_disable(struct radeon_device *rdev)
2561d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher{
2562d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher	/* Disable all tables */
2563d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher	WREG32(VM_CONTEXT0_CNTL, 0);
2564d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher	WREG32(VM_CONTEXT1_CNTL, 0);
2565d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher	/* Setup TLB control */
2566d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher	WREG32(MC_VM_MX_L1_TLB_CNTL, SYSTEM_ACCESS_MODE_NOT_IN_SYS |
2567d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher	       SYSTEM_APERTURE_UNMAPPED_ACCESS_PASS_THRU);
2568d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher	/* Setup L2 cache */
2569d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher	WREG32(VM_L2_CNTL, ENABLE_L2_PTE_CACHE_LRU_UPDATE_BY_WRITE |
2570d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher	       ENABLE_L2_PDE0_CACHE_LRU_UPDATE_BY_WRITE |
2571d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher	       EFFECTIVE_L2_QUEUE_SIZE(7) |
2572d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher	       CONTEXT1_IDENTITY_ACCESS_MODE(1));
2573d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher	WREG32(VM_L2_CNTL2, 0);
2574d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher	WREG32(VM_L2_CNTL3, L2_CACHE_BIGK_ASSOCIATIVITY |
2575d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher	       L2_CACHE_BIGK_FRAGMENT_SIZE(0));
2576d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher	radeon_gart_table_vram_unpin(rdev);
2577d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher}
2578d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher
2579d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deuchervoid si_pcie_gart_fini(struct radeon_device *rdev)
2580d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher{
2581d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher	si_pcie_gart_disable(rdev);
2582d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher	radeon_gart_table_vram_free(rdev);
2583d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher	radeon_gart_fini(rdev);
2584d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher}
2585d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher
2586498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher/* vm parser */
2587498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucherstatic bool si_vm_reg_valid(u32 reg)
2588498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher{
2589498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher	/* context regs are fine */
2590498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher	if (reg >= 0x28000)
2591498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher		return true;
2592498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher
2593498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher	/* check config regs */
2594498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher	switch (reg) {
2595498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher	case GRBM_GFX_INDEX:
2596498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher	case VGT_VTX_VECT_EJECT_REG:
2597498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher	case VGT_CACHE_INVALIDATION:
2598498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher	case VGT_ESGS_RING_SIZE:
2599498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher	case VGT_GSVS_RING_SIZE:
2600498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher	case VGT_GS_VERTEX_REUSE:
2601498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher	case VGT_PRIMITIVE_TYPE:
2602498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher	case VGT_INDEX_TYPE:
2603498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher	case VGT_NUM_INDICES:
2604498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher	case VGT_NUM_INSTANCES:
2605498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher	case VGT_TF_RING_SIZE:
2606498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher	case VGT_HS_OFFCHIP_PARAM:
2607498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher	case VGT_TF_MEMORY_BASE:
2608498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher	case PA_CL_ENHANCE:
2609498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher	case PA_SU_LINE_STIPPLE_VALUE:
2610498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher	case PA_SC_LINE_STIPPLE_STATE:
2611498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher	case PA_SC_ENHANCE:
2612498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher	case SQC_CACHES:
2613498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher	case SPI_STATIC_THREAD_MGMT_1:
2614498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher	case SPI_STATIC_THREAD_MGMT_2:
2615498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher	case SPI_STATIC_THREAD_MGMT_3:
2616498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher	case SPI_PS_MAX_WAVE_ID:
2617498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher	case SPI_CONFIG_CNTL:
2618498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher	case SPI_CONFIG_CNTL_1:
2619498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher	case TA_CNTL_AUX:
2620498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher		return true;
2621498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher	default:
2622498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher		DRM_ERROR("Invalid register 0x%x in CS\n", reg);
2623498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher		return false;
2624498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher	}
2625498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher}
2626498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher
2627498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucherstatic int si_vm_packet3_ce_check(struct radeon_device *rdev,
2628498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher				  u32 *ib, struct radeon_cs_packet *pkt)
2629498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher{
2630498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher	switch (pkt->opcode) {
2631498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher	case PACKET3_NOP:
2632498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher	case PACKET3_SET_BASE:
2633498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher	case PACKET3_SET_CE_DE_COUNTERS:
2634498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher	case PACKET3_LOAD_CONST_RAM:
2635498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher	case PACKET3_WRITE_CONST_RAM:
2636498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher	case PACKET3_WRITE_CONST_RAM_OFFSET:
2637498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher	case PACKET3_DUMP_CONST_RAM:
2638498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher	case PACKET3_INCREMENT_CE_COUNTER:
2639498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher	case PACKET3_WAIT_ON_DE_COUNTER:
2640498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher	case PACKET3_CE_WRITE:
2641498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher		break;
2642498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher	default:
2643498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher		DRM_ERROR("Invalid CE packet3: 0x%x\n", pkt->opcode);
2644498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher		return -EINVAL;
2645498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher	}
2646498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher	return 0;
2647498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher}
2648498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher
2649498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucherstatic int si_vm_packet3_gfx_check(struct radeon_device *rdev,
2650498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher				   u32 *ib, struct radeon_cs_packet *pkt)
2651498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher{
2652498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher	u32 idx = pkt->idx + 1;
2653498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher	u32 idx_value = ib[idx];
2654498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher	u32 start_reg, end_reg, reg, i;
2655498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher
2656498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher	switch (pkt->opcode) {
2657498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher	case PACKET3_NOP:
2658498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher	case PACKET3_SET_BASE:
2659498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher	case PACKET3_CLEAR_STATE:
2660498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher	case PACKET3_INDEX_BUFFER_SIZE:
2661498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher	case PACKET3_DISPATCH_DIRECT:
2662498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher	case PACKET3_DISPATCH_INDIRECT:
2663498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher	case PACKET3_ALLOC_GDS:
2664498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher	case PACKET3_WRITE_GDS_RAM:
2665498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher	case PACKET3_ATOMIC_GDS:
2666498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher	case PACKET3_ATOMIC:
2667498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher	case PACKET3_OCCLUSION_QUERY:
2668498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher	case PACKET3_SET_PREDICATION:
2669498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher	case PACKET3_COND_EXEC:
2670498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher	case PACKET3_PRED_EXEC:
2671498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher	case PACKET3_DRAW_INDIRECT:
2672498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher	case PACKET3_DRAW_INDEX_INDIRECT:
2673498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher	case PACKET3_INDEX_BASE:
2674498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher	case PACKET3_DRAW_INDEX_2:
2675498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher	case PACKET3_CONTEXT_CONTROL:
2676498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher	case PACKET3_INDEX_TYPE:
2677498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher	case PACKET3_DRAW_INDIRECT_MULTI:
2678498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher	case PACKET3_DRAW_INDEX_AUTO:
2679498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher	case PACKET3_DRAW_INDEX_IMMD:
2680498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher	case PACKET3_NUM_INSTANCES:
2681498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher	case PACKET3_DRAW_INDEX_MULTI_AUTO:
2682498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher	case PACKET3_STRMOUT_BUFFER_UPDATE:
2683498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher	case PACKET3_DRAW_INDEX_OFFSET_2:
2684498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher	case PACKET3_DRAW_INDEX_MULTI_ELEMENT:
2685498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher	case PACKET3_DRAW_INDEX_INDIRECT_MULTI:
2686498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher	case PACKET3_MPEG_INDEX:
2687498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher	case PACKET3_WAIT_REG_MEM:
2688498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher	case PACKET3_MEM_WRITE:
2689498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher	case PACKET3_PFP_SYNC_ME:
2690498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher	case PACKET3_SURFACE_SYNC:
2691498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher	case PACKET3_EVENT_WRITE:
2692498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher	case PACKET3_EVENT_WRITE_EOP:
2693498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher	case PACKET3_EVENT_WRITE_EOS:
2694498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher	case PACKET3_SET_CONTEXT_REG:
2695498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher	case PACKET3_SET_CONTEXT_REG_INDIRECT:
2696498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher	case PACKET3_SET_SH_REG:
2697498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher	case PACKET3_SET_SH_REG_OFFSET:
2698498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher	case PACKET3_INCREMENT_DE_COUNTER:
2699498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher	case PACKET3_WAIT_ON_CE_COUNTER:
2700498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher	case PACKET3_WAIT_ON_AVAIL_BUFFER:
2701498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher	case PACKET3_ME_WRITE:
2702498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher		break;
2703498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher	case PACKET3_COPY_DATA:
2704498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher		if ((idx_value & 0xf00) == 0) {
2705498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher			reg = ib[idx + 3] * 4;
2706498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher			if (!si_vm_reg_valid(reg))
2707498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher				return -EINVAL;
2708498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher		}
2709498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher		break;
2710498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher	case PACKET3_WRITE_DATA:
2711498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher		if ((idx_value & 0xf00) == 0) {
2712498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher			start_reg = ib[idx + 1] * 4;
2713498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher			if (idx_value & 0x10000) {
2714498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher				if (!si_vm_reg_valid(start_reg))
2715498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher					return -EINVAL;
2716498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher			} else {
2717498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher				for (i = 0; i < (pkt->count - 2); i++) {
2718498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher					reg = start_reg + (4 * i);
2719498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher					if (!si_vm_reg_valid(reg))
2720498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher						return -EINVAL;
2721498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher				}
2722498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher			}
2723498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher		}
2724498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher		break;
2725498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher	case PACKET3_COND_WRITE:
2726498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher		if (idx_value & 0x100) {
2727498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher			reg = ib[idx + 5] * 4;
2728498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher			if (!si_vm_reg_valid(reg))
2729498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher				return -EINVAL;
2730498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher		}
2731498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher		break;
2732498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher	case PACKET3_COPY_DW:
2733498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher		if (idx_value & 0x2) {
2734498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher			reg = ib[idx + 3] * 4;
2735498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher			if (!si_vm_reg_valid(reg))
2736498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher				return -EINVAL;
2737498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher		}
2738498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher		break;
2739498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher	case PACKET3_SET_CONFIG_REG:
2740498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher		start_reg = (idx_value << 2) + PACKET3_SET_CONFIG_REG_START;
2741498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher		end_reg = 4 * pkt->count + start_reg - 4;
2742498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher		if ((start_reg < PACKET3_SET_CONFIG_REG_START) ||
2743498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher		    (start_reg >= PACKET3_SET_CONFIG_REG_END) ||
2744498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher		    (end_reg >= PACKET3_SET_CONFIG_REG_END)) {
2745498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher			DRM_ERROR("bad PACKET3_SET_CONFIG_REG\n");
2746498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher			return -EINVAL;
2747498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher		}
2748498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher		for (i = 0; i < pkt->count; i++) {
2749498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher			reg = start_reg + (4 * i);
2750498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher			if (!si_vm_reg_valid(reg))
2751498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher				return -EINVAL;
2752498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher		}
2753498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher		break;
2754498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher	default:
2755498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher		DRM_ERROR("Invalid GFX packet3: 0x%x\n", pkt->opcode);
2756498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher		return -EINVAL;
2757498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher	}
2758498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher	return 0;
2759498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher}
2760498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher
2761498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucherstatic int si_vm_packet3_compute_check(struct radeon_device *rdev,
2762498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher				       u32 *ib, struct radeon_cs_packet *pkt)
2763498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher{
2764498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher	u32 idx = pkt->idx + 1;
2765498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher	u32 idx_value = ib[idx];
2766498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher	u32 start_reg, reg, i;
2767498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher
2768498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher	switch (pkt->opcode) {
2769498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher	case PACKET3_NOP:
2770498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher	case PACKET3_SET_BASE:
2771498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher	case PACKET3_CLEAR_STATE:
2772498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher	case PACKET3_DISPATCH_DIRECT:
2773498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher	case PACKET3_DISPATCH_INDIRECT:
2774498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher	case PACKET3_ALLOC_GDS:
2775498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher	case PACKET3_WRITE_GDS_RAM:
2776498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher	case PACKET3_ATOMIC_GDS:
2777498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher	case PACKET3_ATOMIC:
2778498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher	case PACKET3_OCCLUSION_QUERY:
2779498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher	case PACKET3_SET_PREDICATION:
2780498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher	case PACKET3_COND_EXEC:
2781498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher	case PACKET3_PRED_EXEC:
2782498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher	case PACKET3_CONTEXT_CONTROL:
2783498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher	case PACKET3_STRMOUT_BUFFER_UPDATE:
2784498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher	case PACKET3_WAIT_REG_MEM:
2785498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher	case PACKET3_MEM_WRITE:
2786498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher	case PACKET3_PFP_SYNC_ME:
2787498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher	case PACKET3_SURFACE_SYNC:
2788498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher	case PACKET3_EVENT_WRITE:
2789498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher	case PACKET3_EVENT_WRITE_EOP:
2790498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher	case PACKET3_EVENT_WRITE_EOS:
2791498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher	case PACKET3_SET_CONTEXT_REG:
2792498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher	case PACKET3_SET_CONTEXT_REG_INDIRECT:
2793498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher	case PACKET3_SET_SH_REG:
2794498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher	case PACKET3_SET_SH_REG_OFFSET:
2795498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher	case PACKET3_INCREMENT_DE_COUNTER:
2796498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher	case PACKET3_WAIT_ON_CE_COUNTER:
2797498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher	case PACKET3_WAIT_ON_AVAIL_BUFFER:
2798498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher	case PACKET3_ME_WRITE:
2799498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher		break;
2800498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher	case PACKET3_COPY_DATA:
2801498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher		if ((idx_value & 0xf00) == 0) {
2802498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher			reg = ib[idx + 3] * 4;
2803498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher			if (!si_vm_reg_valid(reg))
2804498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher				return -EINVAL;
2805498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher		}
2806498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher		break;
2807498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher	case PACKET3_WRITE_DATA:
2808498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher		if ((idx_value & 0xf00) == 0) {
2809498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher			start_reg = ib[idx + 1] * 4;
2810498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher			if (idx_value & 0x10000) {
2811498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher				if (!si_vm_reg_valid(start_reg))
2812498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher					return -EINVAL;
2813498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher			} else {
2814498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher				for (i = 0; i < (pkt->count - 2); i++) {
2815498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher					reg = start_reg + (4 * i);
2816498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher					if (!si_vm_reg_valid(reg))
2817498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher						return -EINVAL;
2818498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher				}
2819498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher			}
2820498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher		}
2821498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher		break;
2822498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher	case PACKET3_COND_WRITE:
2823498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher		if (idx_value & 0x100) {
2824498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher			reg = ib[idx + 5] * 4;
2825498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher			if (!si_vm_reg_valid(reg))
2826498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher				return -EINVAL;
2827498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher		}
2828498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher		break;
2829498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher	case PACKET3_COPY_DW:
2830498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher		if (idx_value & 0x2) {
2831498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher			reg = ib[idx + 3] * 4;
2832498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher			if (!si_vm_reg_valid(reg))
2833498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher				return -EINVAL;
2834498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher		}
2835498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher		break;
2836498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher	default:
2837498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher		DRM_ERROR("Invalid Compute packet3: 0x%x\n", pkt->opcode);
2838498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher		return -EINVAL;
2839498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher	}
2840498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher	return 0;
2841498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher}
2842498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher
2843498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucherint si_ib_parse(struct radeon_device *rdev, struct radeon_ib *ib)
2844498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher{
2845498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher	int ret = 0;
2846498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher	u32 idx = 0;
2847498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher	struct radeon_cs_packet pkt;
2848498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher
2849498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher	do {
2850498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher		pkt.idx = idx;
2851498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher		pkt.type = CP_PACKET_GET_TYPE(ib->ptr[idx]);
2852498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher		pkt.count = CP_PACKET_GET_COUNT(ib->ptr[idx]);
2853498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher		pkt.one_reg_wr = 0;
2854498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher		switch (pkt.type) {
2855498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher		case PACKET_TYPE0:
2856498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher			dev_err(rdev->dev, "Packet0 not allowed!\n");
2857498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher			ret = -EINVAL;
2858498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher			break;
2859498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher		case PACKET_TYPE2:
2860498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher			idx += 1;
2861498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher			break;
2862498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher		case PACKET_TYPE3:
2863498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher			pkt.opcode = CP_PACKET3_GET_OPCODE(ib->ptr[idx]);
2864498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher			if (ib->is_const_ib)
2865498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher				ret = si_vm_packet3_ce_check(rdev, ib->ptr, &pkt);
2866498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher			else {
2867498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher				switch (ib->fence->ring) {
2868498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher				case RADEON_RING_TYPE_GFX_INDEX:
2869498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher					ret = si_vm_packet3_gfx_check(rdev, ib->ptr, &pkt);
2870498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher					break;
2871498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher				case CAYMAN_RING_TYPE_CP1_INDEX:
2872498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher				case CAYMAN_RING_TYPE_CP2_INDEX:
2873498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher					ret = si_vm_packet3_compute_check(rdev, ib->ptr, &pkt);
2874498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher					break;
2875498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher				default:
2876498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher					dev_err(rdev->dev, "Non-PM4 ring %d !\n", ib->fence->ring);
2877498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher					ret = -EINVAL;
2878498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher					break;
2879498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher				}
2880498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher			}
2881498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher			idx += pkt.count + 2;
2882498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher			break;
2883498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher		default:
2884498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher			dev_err(rdev->dev, "Unknown packet type %d !\n", pkt.type);
2885498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher			ret = -EINVAL;
2886498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher			break;
2887498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher		}
2888498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher		if (ret)
2889498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher			break;
2890498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher	} while (idx < ib->length_dw);
2891498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher
2892498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher	return ret;
2893498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher}
2894498dd8b35ae798c3a6c6c9da029db1806dc2cf93Alex Deucher
2895d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher/*
2896d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher * vm
2897d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher */
2898d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucherint si_vm_init(struct radeon_device *rdev)
2899d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher{
2900d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher	/* number of VMs */
2901d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher	rdev->vm_manager.nvm = 16;
2902d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher	/* base offset of vram pages */
2903d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher	rdev->vm_manager.vram_base_offset = 0;
2904d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher
2905d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher	return 0;
2906d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher}
2907d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher
2908d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deuchervoid si_vm_fini(struct radeon_device *rdev)
2909d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher{
2910d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher}
2911d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher
2912d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucherint si_vm_bind(struct radeon_device *rdev, struct radeon_vm *vm, int id)
2913d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher{
2914d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher	if (id < 8)
2915d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher		WREG32(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR + (id << 2), vm->pt_gpu_addr >> 12);
2916d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher	else
2917d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher		WREG32(VM_CONTEXT8_PAGE_TABLE_BASE_ADDR + ((id - 8) << 2),
2918d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher		       vm->pt_gpu_addr >> 12);
2919d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher	/* flush hdp cache */
2920d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher	WREG32(HDP_MEM_COHERENCY_FLUSH_CNTL, 0x1);
2921d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher	/* bits 0-15 are the VM contexts0-15 */
2922d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher	WREG32(VM_INVALIDATE_REQUEST, 1 << id);
2923d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher	return 0;
2924d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher}
2925d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher
2926d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deuchervoid si_vm_unbind(struct radeon_device *rdev, struct radeon_vm *vm)
2927d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher{
2928d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher	if (vm->id < 8)
2929d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher		WREG32(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR + (vm->id << 2), 0);
2930d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher	else
2931d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher		WREG32(VM_CONTEXT8_PAGE_TABLE_BASE_ADDR + ((vm->id - 8) << 2), 0);
2932d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher	/* flush hdp cache */
2933d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher	WREG32(HDP_MEM_COHERENCY_FLUSH_CNTL, 0x1);
2934d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher	/* bits 0-15 are the VM contexts0-15 */
2935d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher	WREG32(VM_INVALIDATE_REQUEST, 1 << vm->id);
2936d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher}
2937d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher
2938d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deuchervoid si_vm_tlb_flush(struct radeon_device *rdev, struct radeon_vm *vm)
2939d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher{
2940d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher	if (vm->id == -1)
2941d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher		return;
2942d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher
2943d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher	/* flush hdp cache */
2944d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher	WREG32(HDP_MEM_COHERENCY_FLUSH_CNTL, 0x1);
2945d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher	/* bits 0-15 are the VM contexts0-15 */
2946d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher	WREG32(VM_INVALIDATE_REQUEST, 1 << vm->id);
2947d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher}
2948d2800ee59ed28a5eaf3a4a8645feca040eacf7dfAlex Deucher
2949347e7592beb0abd56a11ec16ca8aba9f60681f13Alex Deucher/*
2950347e7592beb0abd56a11ec16ca8aba9f60681f13Alex Deucher * RLC
2951347e7592beb0abd56a11ec16ca8aba9f60681f13Alex Deucher */
2952c420c7454f9c13d2dc706516d13fb9329ccacd05Alex Deuchervoid si_rlc_fini(struct radeon_device *rdev)
2953347e7592beb0abd56a11ec16ca8aba9f60681f13Alex Deucher{
2954347e7592beb0abd56a11ec16ca8aba9f60681f13Alex Deucher	int r;
2955347e7592beb0abd56a11ec16ca8aba9f60681f13Alex Deucher
2956347e7592beb0abd56a11ec16ca8aba9f60681f13Alex Deucher	/* save restore block */
2957347e7592beb0abd56a11ec16ca8aba9f60681f13Alex Deucher	if (rdev->rlc.save_restore_obj) {
2958347e7592beb0abd56a11ec16ca8aba9f60681f13Alex Deucher		r = radeon_bo_reserve(rdev->rlc.save_restore_obj, false);
2959347e7592beb0abd56a11ec16ca8aba9f60681f13Alex Deucher		if (unlikely(r != 0))
2960347e7592beb0abd56a11ec16ca8aba9f60681f13Alex Deucher			dev_warn(rdev->dev, "(%d) reserve RLC sr bo failed\n", r);
2961347e7592beb0abd56a11ec16ca8aba9f60681f13Alex Deucher		radeon_bo_unpin(rdev->rlc.save_restore_obj);
2962347e7592beb0abd56a11ec16ca8aba9f60681f13Alex Deucher		radeon_bo_unreserve(rdev->rlc.save_restore_obj);
2963347e7592beb0abd56a11ec16ca8aba9f60681f13Alex Deucher
2964347e7592beb0abd56a11ec16ca8aba9f60681f13Alex Deucher		radeon_bo_unref(&rdev->rlc.save_restore_obj);
2965347e7592beb0abd56a11ec16ca8aba9f60681f13Alex Deucher		rdev->rlc.save_restore_obj = NULL;
2966347e7592beb0abd56a11ec16ca8aba9f60681f13Alex Deucher	}
2967347e7592beb0abd56a11ec16ca8aba9f60681f13Alex Deucher
2968347e7592beb0abd56a11ec16ca8aba9f60681f13Alex Deucher	/* clear state block */
2969347e7592beb0abd56a11ec16ca8aba9f60681f13Alex Deucher	if (rdev->rlc.clear_state_obj) {
2970347e7592beb0abd56a11ec16ca8aba9f60681f13Alex Deucher		r = radeon_bo_reserve(rdev->rlc.clear_state_obj, false);
2971347e7592beb0abd56a11ec16ca8aba9f60681f13Alex Deucher		if (unlikely(r != 0))
2972347e7592beb0abd56a11ec16ca8aba9f60681f13Alex Deucher			dev_warn(rdev->dev, "(%d) reserve RLC c bo failed\n", r);
2973347e7592beb0abd56a11ec16ca8aba9f60681f13Alex Deucher		radeon_bo_unpin(rdev->rlc.clear_state_obj);
2974347e7592beb0abd56a11ec16ca8aba9f60681f13Alex Deucher		radeon_bo_unreserve(rdev->rlc.clear_state_obj);
2975347e7592beb0abd56a11ec16ca8aba9f60681f13Alex Deucher
2976347e7592beb0abd56a11ec16ca8aba9f60681f13Alex Deucher		radeon_bo_unref(&rdev->rlc.clear_state_obj);
2977347e7592beb0abd56a11ec16ca8aba9f60681f13Alex Deucher		rdev->rlc.clear_state_obj = NULL;
2978347e7592beb0abd56a11ec16ca8aba9f60681f13Alex Deucher	}
2979347e7592beb0abd56a11ec16ca8aba9f60681f13Alex Deucher}
2980347e7592beb0abd56a11ec16ca8aba9f60681f13Alex Deucher
2981c420c7454f9c13d2dc706516d13fb9329ccacd05Alex Deucherint si_rlc_init(struct radeon_device *rdev)
2982347e7592beb0abd56a11ec16ca8aba9f60681f13Alex Deucher{
2983347e7592beb0abd56a11ec16ca8aba9f60681f13Alex Deucher	int r;
2984347e7592beb0abd56a11ec16ca8aba9f60681f13Alex Deucher
2985347e7592beb0abd56a11ec16ca8aba9f60681f13Alex Deucher	/* save restore block */
2986347e7592beb0abd56a11ec16ca8aba9f60681f13Alex Deucher	if (rdev->rlc.save_restore_obj == NULL) {
2987347e7592beb0abd56a11ec16ca8aba9f60681f13Alex Deucher		r = radeon_bo_create(rdev, RADEON_GPU_PAGE_SIZE, PAGE_SIZE, true,
2988347e7592beb0abd56a11ec16ca8aba9f60681f13Alex Deucher				RADEON_GEM_DOMAIN_VRAM, &rdev->rlc.save_restore_obj);
2989347e7592beb0abd56a11ec16ca8aba9f60681f13Alex Deucher		if (r) {
2990347e7592beb0abd56a11ec16ca8aba9f60681f13Alex Deucher			dev_warn(rdev->dev, "(%d) create RLC sr bo failed\n", r);
2991347e7592beb0abd56a11ec16ca8aba9f60681f13Alex Deucher			return r;
2992347e7592beb0abd56a11ec16ca8aba9f60681f13Alex Deucher		}
2993347e7592beb0abd56a11ec16ca8aba9f60681f13Alex Deucher	}
2994347e7592beb0abd56a11ec16ca8aba9f60681f13Alex Deucher
2995347e7592beb0abd56a11ec16ca8aba9f60681f13Alex Deucher	r = radeon_bo_reserve(rdev->rlc.save_restore_obj, false);
2996347e7592beb0abd56a11ec16ca8aba9f60681f13Alex Deucher	if (unlikely(r != 0)) {
2997347e7592beb0abd56a11ec16ca8aba9f60681f13Alex Deucher		si_rlc_fini(rdev);
2998347e7592beb0abd56a11ec16ca8aba9f60681f13Alex Deucher		return r;
2999347e7592beb0abd56a11ec16ca8aba9f60681f13Alex Deucher	}
3000347e7592beb0abd56a11ec16ca8aba9f60681f13Alex Deucher	r = radeon_bo_pin(rdev->rlc.save_restore_obj, RADEON_GEM_DOMAIN_VRAM,
3001347e7592beb0abd56a11ec16ca8aba9f60681f13Alex Deucher			  &rdev->rlc.save_restore_gpu_addr);
30025273db706f8b673902638fee7f907909ed6ae3f9Alex Deucher	radeon_bo_unreserve(rdev->rlc.save_restore_obj);
3003347e7592beb0abd56a11ec16ca8aba9f60681f13Alex Deucher	if (r) {
3004347e7592beb0abd56a11ec16ca8aba9f60681f13Alex Deucher		dev_warn(rdev->dev, "(%d) pin RLC sr bo failed\n", r);
3005347e7592beb0abd56a11ec16ca8aba9f60681f13Alex Deucher		si_rlc_fini(rdev);
3006347e7592beb0abd56a11ec16ca8aba9f60681f13Alex Deucher		return r;
3007347e7592beb0abd56a11ec16ca8aba9f60681f13Alex Deucher	}
3008347e7592beb0abd56a11ec16ca8aba9f60681f13Alex Deucher
3009347e7592beb0abd56a11ec16ca8aba9f60681f13Alex Deucher	/* clear state block */
3010347e7592beb0abd56a11ec16ca8aba9f60681f13Alex Deucher	if (rdev->rlc.clear_state_obj == NULL) {
3011347e7592beb0abd56a11ec16ca8aba9f60681f13Alex Deucher		r = radeon_bo_create(rdev, RADEON_GPU_PAGE_SIZE, PAGE_SIZE, true,
3012347e7592beb0abd56a11ec16ca8aba9f60681f13Alex Deucher				RADEON_GEM_DOMAIN_VRAM, &rdev->rlc.clear_state_obj);
3013347e7592beb0abd56a11ec16ca8aba9f60681f13Alex Deucher		if (r) {
3014347e7592beb0abd56a11ec16ca8aba9f60681f13Alex Deucher			dev_warn(rdev->dev, "(%d) create RLC c bo failed\n", r);
3015347e7592beb0abd56a11ec16ca8aba9f60681f13Alex Deucher			si_rlc_fini(rdev);
3016347e7592beb0abd56a11ec16ca8aba9f60681f13Alex Deucher			return r;
3017347e7592beb0abd56a11ec16ca8aba9f60681f13Alex Deucher		}
3018347e7592beb0abd56a11ec16ca8aba9f60681f13Alex Deucher	}
3019347e7592beb0abd56a11ec16ca8aba9f60681f13Alex Deucher	r = radeon_bo_reserve(rdev->rlc.clear_state_obj, false);
3020347e7592beb0abd56a11ec16ca8aba9f60681f13Alex Deucher	if (unlikely(r != 0)) {
3021347e7592beb0abd56a11ec16ca8aba9f60681f13Alex Deucher		si_rlc_fini(rdev);
3022347e7592beb0abd56a11ec16ca8aba9f60681f13Alex Deucher		return r;
3023347e7592beb0abd56a11ec16ca8aba9f60681f13Alex Deucher	}
3024347e7592beb0abd56a11ec16ca8aba9f60681f13Alex Deucher	r = radeon_bo_pin(rdev->rlc.clear_state_obj, RADEON_GEM_DOMAIN_VRAM,
3025347e7592beb0abd56a11ec16ca8aba9f60681f13Alex Deucher			  &rdev->rlc.clear_state_gpu_addr);
30265273db706f8b673902638fee7f907909ed6ae3f9Alex Deucher	radeon_bo_unreserve(rdev->rlc.clear_state_obj);
3027347e7592beb0abd56a11ec16ca8aba9f60681f13Alex Deucher	if (r) {
3028347e7592beb0abd56a11ec16ca8aba9f60681f13Alex Deucher		dev_warn(rdev->dev, "(%d) pin RLC c bo failed\n", r);
3029347e7592beb0abd56a11ec16ca8aba9f60681f13Alex Deucher		si_rlc_fini(rdev);
3030347e7592beb0abd56a11ec16ca8aba9f60681f13Alex Deucher		return r;
3031347e7592beb0abd56a11ec16ca8aba9f60681f13Alex Deucher	}
3032347e7592beb0abd56a11ec16ca8aba9f60681f13Alex Deucher
3033347e7592beb0abd56a11ec16ca8aba9f60681f13Alex Deucher	return 0;
3034347e7592beb0abd56a11ec16ca8aba9f60681f13Alex Deucher}
3035347e7592beb0abd56a11ec16ca8aba9f60681f13Alex Deucher
3036347e7592beb0abd56a11ec16ca8aba9f60681f13Alex Deucherstatic void si_rlc_stop(struct radeon_device *rdev)
3037347e7592beb0abd56a11ec16ca8aba9f60681f13Alex Deucher{
3038347e7592beb0abd56a11ec16ca8aba9f60681f13Alex Deucher	WREG32(RLC_CNTL, 0);
3039347e7592beb0abd56a11ec16ca8aba9f60681f13Alex Deucher}
3040347e7592beb0abd56a11ec16ca8aba9f60681f13Alex Deucher
3041347e7592beb0abd56a11ec16ca8aba9f60681f13Alex Deucherstatic void si_rlc_start(struct radeon_device *rdev)
3042347e7592beb0abd56a11ec16ca8aba9f60681f13Alex Deucher{
3043347e7592beb0abd56a11ec16ca8aba9f60681f13Alex Deucher	WREG32(RLC_CNTL, RLC_ENABLE);
3044347e7592beb0abd56a11ec16ca8aba9f60681f13Alex Deucher}
3045347e7592beb0abd56a11ec16ca8aba9f60681f13Alex Deucher
3046347e7592beb0abd56a11ec16ca8aba9f60681f13Alex Deucherstatic int si_rlc_resume(struct radeon_device *rdev)
3047347e7592beb0abd56a11ec16ca8aba9f60681f13Alex Deucher{
3048347e7592beb0abd56a11ec16ca8aba9f60681f13Alex Deucher	u32 i;
3049347e7592beb0abd56a11ec16ca8aba9f60681f13Alex Deucher	const __be32 *fw_data;
3050347e7592beb0abd56a11ec16ca8aba9f60681f13Alex Deucher
3051347e7592beb0abd56a11ec16ca8aba9f60681f13Alex Deucher	if (!rdev->rlc_fw)
3052347e7592beb0abd56a11ec16ca8aba9f60681f13Alex Deucher		return -EINVAL;
3053347e7592beb0abd56a11ec16ca8aba9f60681f13Alex Deucher
3054347e7592beb0abd56a11ec16ca8aba9f60681f13Alex Deucher	si_rlc_stop(rdev);
3055347e7592beb0abd56a11ec16ca8aba9f60681f13Alex Deucher
3056347e7592beb0abd56a11ec16ca8aba9f60681f13Alex Deucher	WREG32(RLC_RL_BASE, 0);
3057347e7592beb0abd56a11ec16ca8aba9f60681f13Alex Deucher	WREG32(RLC_RL_SIZE, 0);
3058347e7592beb0abd56a11ec16ca8aba9f60681f13Alex Deucher	WREG32(RLC_LB_CNTL, 0);
3059347e7592beb0abd56a11ec16ca8aba9f60681f13Alex Deucher	WREG32(RLC_LB_CNTR_MAX, 0xffffffff);
3060347e7592beb0abd56a11ec16ca8aba9f60681f13Alex Deucher	WREG32(RLC_LB_CNTR_INIT, 0);
3061347e7592beb0abd56a11ec16ca8aba9f60681f13Alex Deucher
3062347e7592beb0abd56a11ec16ca8aba9f60681f13Alex Deucher	WREG32(RLC_SAVE_AND_RESTORE_BASE, rdev->rlc.save_restore_gpu_addr >> 8);
3063347e7592beb0abd56a11ec16ca8aba9f60681f13Alex Deucher	WREG32(RLC_CLEAR_STATE_RESTORE_BASE, rdev->rlc.clear_state_gpu_addr >> 8);
3064347e7592beb0abd56a11ec16ca8aba9f60681f13Alex Deucher
3065347e7592beb0abd56a11ec16ca8aba9f60681f13Alex Deucher	WREG32(RLC_MC_CNTL, 0);
3066347e7592beb0abd56a11ec16ca8aba9f60681f13Alex Deucher	WREG32(RLC_UCODE_CNTL, 0);
3067347e7592beb0abd56a11ec16ca8aba9f60681f13Alex Deucher
3068347e7592beb0abd56a11ec16ca8aba9f60681f13Alex Deucher	fw_data = (const __be32 *)rdev->rlc_fw->data;
3069347e7592beb0abd56a11ec16ca8aba9f60681f13Alex Deucher	for (i = 0; i < SI_RLC_UCODE_SIZE; i++) {
3070347e7592beb0abd56a11ec16ca8aba9f60681f13Alex Deucher		WREG32(RLC_UCODE_ADDR, i);
3071347e7592beb0abd56a11ec16ca8aba9f60681f13Alex Deucher		WREG32(RLC_UCODE_DATA, be32_to_cpup(fw_data++));
3072347e7592beb0abd56a11ec16ca8aba9f60681f13Alex Deucher	}
3073347e7592beb0abd56a11ec16ca8aba9f60681f13Alex Deucher	WREG32(RLC_UCODE_ADDR, 0);
3074347e7592beb0abd56a11ec16ca8aba9f60681f13Alex Deucher
3075347e7592beb0abd56a11ec16ca8aba9f60681f13Alex Deucher	si_rlc_start(rdev);
3076347e7592beb0abd56a11ec16ca8aba9f60681f13Alex Deucher
3077347e7592beb0abd56a11ec16ca8aba9f60681f13Alex Deucher	return 0;
3078347e7592beb0abd56a11ec16ca8aba9f60681f13Alex Deucher}
3079347e7592beb0abd56a11ec16ca8aba9f60681f13Alex Deucher
308025a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucherstatic void si_enable_interrupts(struct radeon_device *rdev)
308125a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher{
308225a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	u32 ih_cntl = RREG32(IH_CNTL);
308325a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	u32 ih_rb_cntl = RREG32(IH_RB_CNTL);
308425a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher
308525a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	ih_cntl |= ENABLE_INTR;
308625a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	ih_rb_cntl |= IH_RB_ENABLE;
308725a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	WREG32(IH_CNTL, ih_cntl);
308825a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	WREG32(IH_RB_CNTL, ih_rb_cntl);
308925a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	rdev->ih.enabled = true;
309025a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher}
309125a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher
309225a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucherstatic void si_disable_interrupts(struct radeon_device *rdev)
309325a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher{
309425a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	u32 ih_rb_cntl = RREG32(IH_RB_CNTL);
309525a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	u32 ih_cntl = RREG32(IH_CNTL);
309625a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher
309725a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	ih_rb_cntl &= ~IH_RB_ENABLE;
309825a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	ih_cntl &= ~ENABLE_INTR;
309925a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	WREG32(IH_RB_CNTL, ih_rb_cntl);
310025a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	WREG32(IH_CNTL, ih_cntl);
310125a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	/* set rptr, wptr to 0 */
310225a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	WREG32(IH_RB_RPTR, 0);
310325a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	WREG32(IH_RB_WPTR, 0);
310425a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	rdev->ih.enabled = false;
310525a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	rdev->ih.wptr = 0;
310625a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	rdev->ih.rptr = 0;
310725a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher}
310825a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher
310925a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucherstatic void si_disable_interrupt_state(struct radeon_device *rdev)
311025a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher{
311125a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	u32 tmp;
311225a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher
311325a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	WREG32(CP_INT_CNTL_RING0, CNTX_BUSY_INT_ENABLE | CNTX_EMPTY_INT_ENABLE);
311425a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	WREG32(CP_INT_CNTL_RING1, 0);
311525a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	WREG32(CP_INT_CNTL_RING2, 0);
311625a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	WREG32(GRBM_INT_CNTL, 0);
311725a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	WREG32(INT_MASK + EVERGREEN_CRTC0_REGISTER_OFFSET, 0);
311825a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	WREG32(INT_MASK + EVERGREEN_CRTC1_REGISTER_OFFSET, 0);
311925a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	if (rdev->num_crtc >= 4) {
312025a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher		WREG32(INT_MASK + EVERGREEN_CRTC2_REGISTER_OFFSET, 0);
312125a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher		WREG32(INT_MASK + EVERGREEN_CRTC3_REGISTER_OFFSET, 0);
312225a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	}
312325a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	if (rdev->num_crtc >= 6) {
312425a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher		WREG32(INT_MASK + EVERGREEN_CRTC4_REGISTER_OFFSET, 0);
312525a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher		WREG32(INT_MASK + EVERGREEN_CRTC5_REGISTER_OFFSET, 0);
312625a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	}
312725a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher
312825a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC0_REGISTER_OFFSET, 0);
312925a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC1_REGISTER_OFFSET, 0);
313025a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	if (rdev->num_crtc >= 4) {
313125a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher		WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC2_REGISTER_OFFSET, 0);
313225a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher		WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC3_REGISTER_OFFSET, 0);
313325a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	}
313425a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	if (rdev->num_crtc >= 6) {
313525a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher		WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC4_REGISTER_OFFSET, 0);
313625a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher		WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC5_REGISTER_OFFSET, 0);
313725a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	}
313825a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher
313925a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	WREG32(DACA_AUTODETECT_INT_CONTROL, 0);
314025a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher
314125a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	tmp = RREG32(DC_HPD1_INT_CONTROL) & DC_HPDx_INT_POLARITY;
314225a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	WREG32(DC_HPD1_INT_CONTROL, tmp);
314325a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	tmp = RREG32(DC_HPD2_INT_CONTROL) & DC_HPDx_INT_POLARITY;
314425a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	WREG32(DC_HPD2_INT_CONTROL, tmp);
314525a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	tmp = RREG32(DC_HPD3_INT_CONTROL) & DC_HPDx_INT_POLARITY;
314625a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	WREG32(DC_HPD3_INT_CONTROL, tmp);
314725a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	tmp = RREG32(DC_HPD4_INT_CONTROL) & DC_HPDx_INT_POLARITY;
314825a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	WREG32(DC_HPD4_INT_CONTROL, tmp);
314925a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	tmp = RREG32(DC_HPD5_INT_CONTROL) & DC_HPDx_INT_POLARITY;
315025a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	WREG32(DC_HPD5_INT_CONTROL, tmp);
315125a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	tmp = RREG32(DC_HPD6_INT_CONTROL) & DC_HPDx_INT_POLARITY;
315225a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	WREG32(DC_HPD6_INT_CONTROL, tmp);
315325a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher
315425a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher}
315525a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher
315625a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucherstatic int si_irq_init(struct radeon_device *rdev)
315725a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher{
315825a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	int ret = 0;
315925a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	int rb_bufsz;
316025a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	u32 interrupt_cntl, ih_cntl, ih_rb_cntl;
316125a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher
316225a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	/* allocate ring */
316325a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	ret = r600_ih_ring_alloc(rdev);
316425a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	if (ret)
316525a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher		return ret;
316625a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher
316725a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	/* disable irqs */
316825a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	si_disable_interrupts(rdev);
316925a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher
317025a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	/* init rlc */
317125a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	ret = si_rlc_resume(rdev);
317225a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	if (ret) {
317325a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher		r600_ih_ring_fini(rdev);
317425a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher		return ret;
317525a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	}
317625a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher
317725a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	/* setup interrupt control */
317825a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	/* set dummy read address to ring address */
317925a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	WREG32(INTERRUPT_CNTL2, rdev->ih.gpu_addr >> 8);
318025a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	interrupt_cntl = RREG32(INTERRUPT_CNTL);
318125a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	/* IH_DUMMY_RD_OVERRIDE=0 - dummy read disabled with msi, enabled without msi
318225a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	 * IH_DUMMY_RD_OVERRIDE=1 - dummy read controlled by IH_DUMMY_RD_EN
318325a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	 */
318425a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	interrupt_cntl &= ~IH_DUMMY_RD_OVERRIDE;
318525a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	/* IH_REQ_NONSNOOP_EN=1 if ring is in non-cacheable memory, e.g., vram */
318625a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	interrupt_cntl &= ~IH_REQ_NONSNOOP_EN;
318725a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	WREG32(INTERRUPT_CNTL, interrupt_cntl);
318825a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher
318925a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	WREG32(IH_RB_BASE, rdev->ih.gpu_addr >> 8);
319025a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	rb_bufsz = drm_order(rdev->ih.ring_size / 4);
319125a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher
319225a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	ih_rb_cntl = (IH_WPTR_OVERFLOW_ENABLE |
319325a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher		      IH_WPTR_OVERFLOW_CLEAR |
319425a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher		      (rb_bufsz << 1));
319525a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher
319625a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	if (rdev->wb.enabled)
319725a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher		ih_rb_cntl |= IH_WPTR_WRITEBACK_ENABLE;
319825a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher
319925a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	/* set the writeback address whether it's enabled or not */
320025a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	WREG32(IH_RB_WPTR_ADDR_LO, (rdev->wb.gpu_addr + R600_WB_IH_WPTR_OFFSET) & 0xFFFFFFFC);
320125a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	WREG32(IH_RB_WPTR_ADDR_HI, upper_32_bits(rdev->wb.gpu_addr + R600_WB_IH_WPTR_OFFSET) & 0xFF);
320225a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher
320325a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	WREG32(IH_RB_CNTL, ih_rb_cntl);
320425a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher
320525a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	/* set rptr, wptr to 0 */
320625a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	WREG32(IH_RB_RPTR, 0);
320725a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	WREG32(IH_RB_WPTR, 0);
320825a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher
320925a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	/* Default settings for IH_CNTL (disabled at first) */
321025a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	ih_cntl = MC_WRREQ_CREDIT(0x10) | MC_WR_CLEAN_CNT(0x10) | MC_VMID(0);
321125a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	/* RPTR_REARM only works if msi's are enabled */
321225a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	if (rdev->msi_enabled)
321325a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher		ih_cntl |= RPTR_REARM;
321425a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	WREG32(IH_CNTL, ih_cntl);
321525a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher
321625a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	/* force the active interrupt state to all disabled */
321725a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	si_disable_interrupt_state(rdev);
321825a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher
321925a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	/* enable irqs */
322025a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	si_enable_interrupts(rdev);
322125a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher
322225a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	return ret;
322325a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher}
322425a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher
322525a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucherint si_irq_set(struct radeon_device *rdev)
322625a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher{
322725a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	u32 cp_int_cntl = CNTX_BUSY_INT_ENABLE | CNTX_EMPTY_INT_ENABLE;
322825a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	u32 cp_int_cntl1 = 0, cp_int_cntl2 = 0;
322925a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	u32 crtc1 = 0, crtc2 = 0, crtc3 = 0, crtc4 = 0, crtc5 = 0, crtc6 = 0;
323025a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	u32 hpd1, hpd2, hpd3, hpd4, hpd5, hpd6;
323125a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	u32 grbm_int_cntl = 0;
323225a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	u32 grph1 = 0, grph2 = 0, grph3 = 0, grph4 = 0, grph5 = 0, grph6 = 0;
323325a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher
323425a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	if (!rdev->irq.installed) {
323525a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher		WARN(1, "Can't enable IRQ/MSI because no handler is installed\n");
323625a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher		return -EINVAL;
323725a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	}
323825a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	/* don't enable anything if the ih is disabled */
323925a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	if (!rdev->ih.enabled) {
324025a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher		si_disable_interrupts(rdev);
324125a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher		/* force the active interrupt state to all disabled */
324225a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher		si_disable_interrupt_state(rdev);
324325a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher		return 0;
324425a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	}
324525a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher
324625a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	hpd1 = RREG32(DC_HPD1_INT_CONTROL) & ~DC_HPDx_INT_EN;
324725a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	hpd2 = RREG32(DC_HPD2_INT_CONTROL) & ~DC_HPDx_INT_EN;
324825a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	hpd3 = RREG32(DC_HPD3_INT_CONTROL) & ~DC_HPDx_INT_EN;
324925a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	hpd4 = RREG32(DC_HPD4_INT_CONTROL) & ~DC_HPDx_INT_EN;
325025a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	hpd5 = RREG32(DC_HPD5_INT_CONTROL) & ~DC_HPDx_INT_EN;
325125a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	hpd6 = RREG32(DC_HPD6_INT_CONTROL) & ~DC_HPDx_INT_EN;
325225a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher
325325a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	/* enable CP interrupts on all rings */
325425a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	if (rdev->irq.sw_int[RADEON_RING_TYPE_GFX_INDEX]) {
325525a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher		DRM_DEBUG("si_irq_set: sw int gfx\n");
325625a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher		cp_int_cntl |= TIME_STAMP_INT_ENABLE;
325725a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	}
325825a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	if (rdev->irq.sw_int[CAYMAN_RING_TYPE_CP1_INDEX]) {
325925a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher		DRM_DEBUG("si_irq_set: sw int cp1\n");
326025a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher		cp_int_cntl1 |= TIME_STAMP_INT_ENABLE;
326125a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	}
326225a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	if (rdev->irq.sw_int[CAYMAN_RING_TYPE_CP2_INDEX]) {
326325a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher		DRM_DEBUG("si_irq_set: sw int cp2\n");
326425a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher		cp_int_cntl2 |= TIME_STAMP_INT_ENABLE;
326525a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	}
326625a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	if (rdev->irq.crtc_vblank_int[0] ||
326725a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	    rdev->irq.pflip[0]) {
326825a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher		DRM_DEBUG("si_irq_set: vblank 0\n");
326925a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher		crtc1 |= VBLANK_INT_MASK;
327025a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	}
327125a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	if (rdev->irq.crtc_vblank_int[1] ||
327225a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	    rdev->irq.pflip[1]) {
327325a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher		DRM_DEBUG("si_irq_set: vblank 1\n");
327425a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher		crtc2 |= VBLANK_INT_MASK;
327525a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	}
327625a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	if (rdev->irq.crtc_vblank_int[2] ||
327725a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	    rdev->irq.pflip[2]) {
327825a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher		DRM_DEBUG("si_irq_set: vblank 2\n");
327925a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher		crtc3 |= VBLANK_INT_MASK;
328025a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	}
328125a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	if (rdev->irq.crtc_vblank_int[3] ||
328225a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	    rdev->irq.pflip[3]) {
328325a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher		DRM_DEBUG("si_irq_set: vblank 3\n");
328425a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher		crtc4 |= VBLANK_INT_MASK;
328525a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	}
328625a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	if (rdev->irq.crtc_vblank_int[4] ||
328725a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	    rdev->irq.pflip[4]) {
328825a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher		DRM_DEBUG("si_irq_set: vblank 4\n");
328925a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher		crtc5 |= VBLANK_INT_MASK;
329025a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	}
329125a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	if (rdev->irq.crtc_vblank_int[5] ||
329225a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	    rdev->irq.pflip[5]) {
329325a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher		DRM_DEBUG("si_irq_set: vblank 5\n");
329425a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher		crtc6 |= VBLANK_INT_MASK;
329525a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	}
329625a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	if (rdev->irq.hpd[0]) {
329725a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher		DRM_DEBUG("si_irq_set: hpd 1\n");
329825a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher		hpd1 |= DC_HPDx_INT_EN;
329925a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	}
330025a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	if (rdev->irq.hpd[1]) {
330125a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher		DRM_DEBUG("si_irq_set: hpd 2\n");
330225a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher		hpd2 |= DC_HPDx_INT_EN;
330325a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	}
330425a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	if (rdev->irq.hpd[2]) {
330525a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher		DRM_DEBUG("si_irq_set: hpd 3\n");
330625a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher		hpd3 |= DC_HPDx_INT_EN;
330725a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	}
330825a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	if (rdev->irq.hpd[3]) {
330925a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher		DRM_DEBUG("si_irq_set: hpd 4\n");
331025a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher		hpd4 |= DC_HPDx_INT_EN;
331125a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	}
331225a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	if (rdev->irq.hpd[4]) {
331325a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher		DRM_DEBUG("si_irq_set: hpd 5\n");
331425a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher		hpd5 |= DC_HPDx_INT_EN;
331525a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	}
331625a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	if (rdev->irq.hpd[5]) {
331725a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher		DRM_DEBUG("si_irq_set: hpd 6\n");
331825a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher		hpd6 |= DC_HPDx_INT_EN;
331925a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	}
332025a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	if (rdev->irq.gui_idle) {
332125a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher		DRM_DEBUG("gui idle\n");
332225a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher		grbm_int_cntl |= GUI_IDLE_INT_ENABLE;
332325a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	}
332425a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher
332525a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	WREG32(CP_INT_CNTL_RING0, cp_int_cntl);
332625a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	WREG32(CP_INT_CNTL_RING1, cp_int_cntl1);
332725a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	WREG32(CP_INT_CNTL_RING2, cp_int_cntl2);
332825a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher
332925a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	WREG32(GRBM_INT_CNTL, grbm_int_cntl);
333025a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher
333125a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	WREG32(INT_MASK + EVERGREEN_CRTC0_REGISTER_OFFSET, crtc1);
333225a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	WREG32(INT_MASK + EVERGREEN_CRTC1_REGISTER_OFFSET, crtc2);
333325a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	if (rdev->num_crtc >= 4) {
333425a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher		WREG32(INT_MASK + EVERGREEN_CRTC2_REGISTER_OFFSET, crtc3);
333525a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher		WREG32(INT_MASK + EVERGREEN_CRTC3_REGISTER_OFFSET, crtc4);
333625a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	}
333725a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	if (rdev->num_crtc >= 6) {
333825a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher		WREG32(INT_MASK + EVERGREEN_CRTC4_REGISTER_OFFSET, crtc5);
333925a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher		WREG32(INT_MASK + EVERGREEN_CRTC5_REGISTER_OFFSET, crtc6);
334025a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	}
334125a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher
334225a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC0_REGISTER_OFFSET, grph1);
334325a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC1_REGISTER_OFFSET, grph2);
334425a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	if (rdev->num_crtc >= 4) {
334525a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher		WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC2_REGISTER_OFFSET, grph3);
334625a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher		WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC3_REGISTER_OFFSET, grph4);
334725a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	}
334825a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	if (rdev->num_crtc >= 6) {
334925a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher		WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC4_REGISTER_OFFSET, grph5);
335025a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher		WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC5_REGISTER_OFFSET, grph6);
335125a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	}
335225a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher
335325a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	WREG32(DC_HPD1_INT_CONTROL, hpd1);
335425a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	WREG32(DC_HPD2_INT_CONTROL, hpd2);
335525a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	WREG32(DC_HPD3_INT_CONTROL, hpd3);
335625a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	WREG32(DC_HPD4_INT_CONTROL, hpd4);
335725a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	WREG32(DC_HPD5_INT_CONTROL, hpd5);
335825a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	WREG32(DC_HPD6_INT_CONTROL, hpd6);
335925a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher
336025a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	return 0;
336125a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher}
336225a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher
336325a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucherstatic inline void si_irq_ack(struct radeon_device *rdev)
336425a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher{
336525a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	u32 tmp;
336625a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher
336725a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	rdev->irq.stat_regs.evergreen.disp_int = RREG32(DISP_INTERRUPT_STATUS);
336825a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	rdev->irq.stat_regs.evergreen.disp_int_cont = RREG32(DISP_INTERRUPT_STATUS_CONTINUE);
336925a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	rdev->irq.stat_regs.evergreen.disp_int_cont2 = RREG32(DISP_INTERRUPT_STATUS_CONTINUE2);
337025a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	rdev->irq.stat_regs.evergreen.disp_int_cont3 = RREG32(DISP_INTERRUPT_STATUS_CONTINUE3);
337125a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	rdev->irq.stat_regs.evergreen.disp_int_cont4 = RREG32(DISP_INTERRUPT_STATUS_CONTINUE4);
337225a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	rdev->irq.stat_regs.evergreen.disp_int_cont5 = RREG32(DISP_INTERRUPT_STATUS_CONTINUE5);
337325a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	rdev->irq.stat_regs.evergreen.d1grph_int = RREG32(GRPH_INT_STATUS + EVERGREEN_CRTC0_REGISTER_OFFSET);
337425a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	rdev->irq.stat_regs.evergreen.d2grph_int = RREG32(GRPH_INT_STATUS + EVERGREEN_CRTC1_REGISTER_OFFSET);
337525a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	if (rdev->num_crtc >= 4) {
337625a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher		rdev->irq.stat_regs.evergreen.d3grph_int = RREG32(GRPH_INT_STATUS + EVERGREEN_CRTC2_REGISTER_OFFSET);
337725a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher		rdev->irq.stat_regs.evergreen.d4grph_int = RREG32(GRPH_INT_STATUS + EVERGREEN_CRTC3_REGISTER_OFFSET);
337825a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	}
337925a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	if (rdev->num_crtc >= 6) {
338025a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher		rdev->irq.stat_regs.evergreen.d5grph_int = RREG32(GRPH_INT_STATUS + EVERGREEN_CRTC4_REGISTER_OFFSET);
338125a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher		rdev->irq.stat_regs.evergreen.d6grph_int = RREG32(GRPH_INT_STATUS + EVERGREEN_CRTC5_REGISTER_OFFSET);
338225a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	}
338325a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher
338425a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	if (rdev->irq.stat_regs.evergreen.d1grph_int & GRPH_PFLIP_INT_OCCURRED)
338525a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher		WREG32(GRPH_INT_STATUS + EVERGREEN_CRTC0_REGISTER_OFFSET, GRPH_PFLIP_INT_CLEAR);
338625a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	if (rdev->irq.stat_regs.evergreen.d2grph_int & GRPH_PFLIP_INT_OCCURRED)
338725a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher		WREG32(GRPH_INT_STATUS + EVERGREEN_CRTC1_REGISTER_OFFSET, GRPH_PFLIP_INT_CLEAR);
338825a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	if (rdev->irq.stat_regs.evergreen.disp_int & LB_D1_VBLANK_INTERRUPT)
338925a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher		WREG32(VBLANK_STATUS + EVERGREEN_CRTC0_REGISTER_OFFSET, VBLANK_ACK);
339025a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	if (rdev->irq.stat_regs.evergreen.disp_int & LB_D1_VLINE_INTERRUPT)
339125a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher		WREG32(VLINE_STATUS + EVERGREEN_CRTC0_REGISTER_OFFSET, VLINE_ACK);
339225a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	if (rdev->irq.stat_regs.evergreen.disp_int_cont & LB_D2_VBLANK_INTERRUPT)
339325a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher		WREG32(VBLANK_STATUS + EVERGREEN_CRTC1_REGISTER_OFFSET, VBLANK_ACK);
339425a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	if (rdev->irq.stat_regs.evergreen.disp_int_cont & LB_D2_VLINE_INTERRUPT)
339525a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher		WREG32(VLINE_STATUS + EVERGREEN_CRTC1_REGISTER_OFFSET, VLINE_ACK);
339625a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher
339725a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	if (rdev->num_crtc >= 4) {
339825a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher		if (rdev->irq.stat_regs.evergreen.d3grph_int & GRPH_PFLIP_INT_OCCURRED)
339925a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher			WREG32(GRPH_INT_STATUS + EVERGREEN_CRTC2_REGISTER_OFFSET, GRPH_PFLIP_INT_CLEAR);
340025a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher		if (rdev->irq.stat_regs.evergreen.d4grph_int & GRPH_PFLIP_INT_OCCURRED)
340125a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher			WREG32(GRPH_INT_STATUS + EVERGREEN_CRTC3_REGISTER_OFFSET, GRPH_PFLIP_INT_CLEAR);
340225a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher		if (rdev->irq.stat_regs.evergreen.disp_int_cont2 & LB_D3_VBLANK_INTERRUPT)
340325a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher			WREG32(VBLANK_STATUS + EVERGREEN_CRTC2_REGISTER_OFFSET, VBLANK_ACK);
340425a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher		if (rdev->irq.stat_regs.evergreen.disp_int_cont2 & LB_D3_VLINE_INTERRUPT)
340525a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher			WREG32(VLINE_STATUS + EVERGREEN_CRTC2_REGISTER_OFFSET, VLINE_ACK);
340625a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher		if (rdev->irq.stat_regs.evergreen.disp_int_cont3 & LB_D4_VBLANK_INTERRUPT)
340725a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher			WREG32(VBLANK_STATUS + EVERGREEN_CRTC3_REGISTER_OFFSET, VBLANK_ACK);
340825a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher		if (rdev->irq.stat_regs.evergreen.disp_int_cont3 & LB_D4_VLINE_INTERRUPT)
340925a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher			WREG32(VLINE_STATUS + EVERGREEN_CRTC3_REGISTER_OFFSET, VLINE_ACK);
341025a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	}
341125a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher
341225a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	if (rdev->num_crtc >= 6) {
341325a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher		if (rdev->irq.stat_regs.evergreen.d5grph_int & GRPH_PFLIP_INT_OCCURRED)
341425a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher			WREG32(GRPH_INT_STATUS + EVERGREEN_CRTC4_REGISTER_OFFSET, GRPH_PFLIP_INT_CLEAR);
341525a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher		if (rdev->irq.stat_regs.evergreen.d6grph_int & GRPH_PFLIP_INT_OCCURRED)
341625a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher			WREG32(GRPH_INT_STATUS + EVERGREEN_CRTC5_REGISTER_OFFSET, GRPH_PFLIP_INT_CLEAR);
341725a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher		if (rdev->irq.stat_regs.evergreen.disp_int_cont4 & LB_D5_VBLANK_INTERRUPT)
341825a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher			WREG32(VBLANK_STATUS + EVERGREEN_CRTC4_REGISTER_OFFSET, VBLANK_ACK);
341925a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher		if (rdev->irq.stat_regs.evergreen.disp_int_cont4 & LB_D5_VLINE_INTERRUPT)
342025a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher			WREG32(VLINE_STATUS + EVERGREEN_CRTC4_REGISTER_OFFSET, VLINE_ACK);
342125a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher		if (rdev->irq.stat_regs.evergreen.disp_int_cont5 & LB_D6_VBLANK_INTERRUPT)
342225a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher			WREG32(VBLANK_STATUS + EVERGREEN_CRTC5_REGISTER_OFFSET, VBLANK_ACK);
342325a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher		if (rdev->irq.stat_regs.evergreen.disp_int_cont5 & LB_D6_VLINE_INTERRUPT)
342425a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher			WREG32(VLINE_STATUS + EVERGREEN_CRTC5_REGISTER_OFFSET, VLINE_ACK);
342525a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	}
342625a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher
342725a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	if (rdev->irq.stat_regs.evergreen.disp_int & DC_HPD1_INTERRUPT) {
342825a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher		tmp = RREG32(DC_HPD1_INT_CONTROL);
342925a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher		tmp |= DC_HPDx_INT_ACK;
343025a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher		WREG32(DC_HPD1_INT_CONTROL, tmp);
343125a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	}
343225a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	if (rdev->irq.stat_regs.evergreen.disp_int_cont & DC_HPD2_INTERRUPT) {
343325a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher		tmp = RREG32(DC_HPD2_INT_CONTROL);
343425a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher		tmp |= DC_HPDx_INT_ACK;
343525a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher		WREG32(DC_HPD2_INT_CONTROL, tmp);
343625a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	}
343725a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	if (rdev->irq.stat_regs.evergreen.disp_int_cont2 & DC_HPD3_INTERRUPT) {
343825a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher		tmp = RREG32(DC_HPD3_INT_CONTROL);
343925a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher		tmp |= DC_HPDx_INT_ACK;
344025a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher		WREG32(DC_HPD3_INT_CONTROL, tmp);
344125a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	}
344225a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	if (rdev->irq.stat_regs.evergreen.disp_int_cont3 & DC_HPD4_INTERRUPT) {
344325a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher		tmp = RREG32(DC_HPD4_INT_CONTROL);
344425a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher		tmp |= DC_HPDx_INT_ACK;
344525a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher		WREG32(DC_HPD4_INT_CONTROL, tmp);
344625a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	}
344725a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	if (rdev->irq.stat_regs.evergreen.disp_int_cont4 & DC_HPD5_INTERRUPT) {
344825a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher		tmp = RREG32(DC_HPD5_INT_CONTROL);
344925a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher		tmp |= DC_HPDx_INT_ACK;
345025a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher		WREG32(DC_HPD5_INT_CONTROL, tmp);
345125a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	}
345225a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	if (rdev->irq.stat_regs.evergreen.disp_int_cont5 & DC_HPD6_INTERRUPT) {
345325a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher		tmp = RREG32(DC_HPD5_INT_CONTROL);
345425a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher		tmp |= DC_HPDx_INT_ACK;
345525a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher		WREG32(DC_HPD6_INT_CONTROL, tmp);
345625a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	}
345725a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher}
345825a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher
345925a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucherstatic void si_irq_disable(struct radeon_device *rdev)
346025a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher{
346125a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	si_disable_interrupts(rdev);
346225a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	/* Wait and acknowledge irq */
346325a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	mdelay(1);
346425a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	si_irq_ack(rdev);
346525a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	si_disable_interrupt_state(rdev);
346625a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher}
346725a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher
346825a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucherstatic void si_irq_suspend(struct radeon_device *rdev)
346925a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher{
347025a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	si_irq_disable(rdev);
347125a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	si_rlc_stop(rdev);
347225a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher}
347325a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher
34749b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucherstatic void si_irq_fini(struct radeon_device *rdev)
34759b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher{
34769b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher	si_irq_suspend(rdev);
34779b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher	r600_ih_ring_fini(rdev);
34789b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher}
34799b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher
348025a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucherstatic inline u32 si_get_ih_wptr(struct radeon_device *rdev)
348125a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher{
348225a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	u32 wptr, tmp;
348325a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher
348425a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	if (rdev->wb.enabled)
348525a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher		wptr = le32_to_cpu(rdev->wb.wb[R600_WB_IH_WPTR_OFFSET/4]);
348625a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	else
348725a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher		wptr = RREG32(IH_RB_WPTR);
348825a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher
348925a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	if (wptr & RB_OVERFLOW) {
349025a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher		/* When a ring buffer overflow happen start parsing interrupt
349125a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher		 * from the last not overwritten vector (wptr + 16). Hopefully
349225a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher		 * this should allow us to catchup.
349325a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher		 */
349425a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher		dev_warn(rdev->dev, "IH ring buffer overflow (0x%08X, %d, %d)\n",
349525a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher			wptr, rdev->ih.rptr, (wptr + 16) + rdev->ih.ptr_mask);
349625a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher		rdev->ih.rptr = (wptr + 16) & rdev->ih.ptr_mask;
349725a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher		tmp = RREG32(IH_RB_CNTL);
349825a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher		tmp |= IH_WPTR_OVERFLOW_CLEAR;
349925a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher		WREG32(IH_RB_CNTL, tmp);
350025a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	}
350125a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	return (wptr & rdev->ih.ptr_mask);
350225a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher}
350325a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher
350425a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher/*        SI IV Ring
350525a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher * Each IV ring entry is 128 bits:
350625a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher * [7:0]    - interrupt source id
350725a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher * [31:8]   - reserved
350825a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher * [59:32]  - interrupt source data
350925a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher * [63:60]  - reserved
351025a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher * [71:64]  - RINGID
351125a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher * [79:72]  - VMID
351225a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher * [127:80] - reserved
351325a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher */
351425a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucherint si_irq_process(struct radeon_device *rdev)
351525a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher{
351625a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	u32 wptr;
351725a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	u32 rptr;
351825a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	u32 src_id, src_data, ring_id;
351925a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	u32 ring_index;
352025a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	unsigned long flags;
352125a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	bool queue_hotplug = false;
352225a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher
352325a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	if (!rdev->ih.enabled || rdev->shutdown)
352425a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher		return IRQ_NONE;
352525a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher
352625a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	wptr = si_get_ih_wptr(rdev);
352725a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	rptr = rdev->ih.rptr;
352825a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	DRM_DEBUG("si_irq_process start: rptr %d, wptr %d\n", rptr, wptr);
352925a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher
353025a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	spin_lock_irqsave(&rdev->ih.lock, flags);
353125a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	if (rptr == wptr) {
353225a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher		spin_unlock_irqrestore(&rdev->ih.lock, flags);
353325a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher		return IRQ_NONE;
353425a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	}
353525a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucherrestart_ih:
353625a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	/* Order reading of wptr vs. reading of IH ring data */
353725a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	rmb();
353825a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher
353925a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	/* display interrupts */
354025a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	si_irq_ack(rdev);
354125a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher
354225a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	rdev->ih.wptr = wptr;
354325a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	while (rptr != wptr) {
354425a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher		/* wptr/rptr are in bytes! */
354525a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher		ring_index = rptr / 4;
354625a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher		src_id =  le32_to_cpu(rdev->ih.ring[ring_index]) & 0xff;
354725a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher		src_data = le32_to_cpu(rdev->ih.ring[ring_index + 1]) & 0xfffffff;
354825a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher		ring_id = le32_to_cpu(rdev->ih.ring[ring_index + 2]) & 0xff;
354925a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher
355025a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher		switch (src_id) {
355125a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher		case 1: /* D1 vblank/vline */
355225a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher			switch (src_data) {
355325a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher			case 0: /* D1 vblank */
355425a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher				if (rdev->irq.stat_regs.evergreen.disp_int & LB_D1_VBLANK_INTERRUPT) {
355525a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher					if (rdev->irq.crtc_vblank_int[0]) {
355625a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher						drm_handle_vblank(rdev->ddev, 0);
355725a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher						rdev->pm.vblank_sync = true;
355825a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher						wake_up(&rdev->irq.vblank_queue);
355925a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher					}
356025a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher					if (rdev->irq.pflip[0])
356125a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher						radeon_crtc_handle_flip(rdev, 0);
356225a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher					rdev->irq.stat_regs.evergreen.disp_int &= ~LB_D1_VBLANK_INTERRUPT;
356325a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher					DRM_DEBUG("IH: D1 vblank\n");
356425a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher				}
356525a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher				break;
356625a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher			case 1: /* D1 vline */
356725a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher				if (rdev->irq.stat_regs.evergreen.disp_int & LB_D1_VLINE_INTERRUPT) {
356825a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher					rdev->irq.stat_regs.evergreen.disp_int &= ~LB_D1_VLINE_INTERRUPT;
356925a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher					DRM_DEBUG("IH: D1 vline\n");
357025a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher				}
357125a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher				break;
357225a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher			default:
357325a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher				DRM_DEBUG("Unhandled interrupt: %d %d\n", src_id, src_data);
357425a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher				break;
357525a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher			}
357625a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher			break;
357725a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher		case 2: /* D2 vblank/vline */
357825a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher			switch (src_data) {
357925a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher			case 0: /* D2 vblank */
358025a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher				if (rdev->irq.stat_regs.evergreen.disp_int_cont & LB_D2_VBLANK_INTERRUPT) {
358125a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher					if (rdev->irq.crtc_vblank_int[1]) {
358225a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher						drm_handle_vblank(rdev->ddev, 1);
358325a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher						rdev->pm.vblank_sync = true;
358425a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher						wake_up(&rdev->irq.vblank_queue);
358525a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher					}
358625a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher					if (rdev->irq.pflip[1])
358725a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher						radeon_crtc_handle_flip(rdev, 1);
358825a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher					rdev->irq.stat_regs.evergreen.disp_int_cont &= ~LB_D2_VBLANK_INTERRUPT;
358925a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher					DRM_DEBUG("IH: D2 vblank\n");
359025a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher				}
359125a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher				break;
359225a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher			case 1: /* D2 vline */
359325a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher				if (rdev->irq.stat_regs.evergreen.disp_int_cont & LB_D2_VLINE_INTERRUPT) {
359425a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher					rdev->irq.stat_regs.evergreen.disp_int_cont &= ~LB_D2_VLINE_INTERRUPT;
359525a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher					DRM_DEBUG("IH: D2 vline\n");
359625a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher				}
359725a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher				break;
359825a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher			default:
359925a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher				DRM_DEBUG("Unhandled interrupt: %d %d\n", src_id, src_data);
360025a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher				break;
360125a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher			}
360225a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher			break;
360325a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher		case 3: /* D3 vblank/vline */
360425a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher			switch (src_data) {
360525a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher			case 0: /* D3 vblank */
360625a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher				if (rdev->irq.stat_regs.evergreen.disp_int_cont2 & LB_D3_VBLANK_INTERRUPT) {
360725a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher					if (rdev->irq.crtc_vblank_int[2]) {
360825a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher						drm_handle_vblank(rdev->ddev, 2);
360925a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher						rdev->pm.vblank_sync = true;
361025a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher						wake_up(&rdev->irq.vblank_queue);
361125a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher					}
361225a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher					if (rdev->irq.pflip[2])
361325a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher						radeon_crtc_handle_flip(rdev, 2);
361425a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher					rdev->irq.stat_regs.evergreen.disp_int_cont2 &= ~LB_D3_VBLANK_INTERRUPT;
361525a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher					DRM_DEBUG("IH: D3 vblank\n");
361625a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher				}
361725a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher				break;
361825a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher			case 1: /* D3 vline */
361925a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher				if (rdev->irq.stat_regs.evergreen.disp_int_cont2 & LB_D3_VLINE_INTERRUPT) {
362025a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher					rdev->irq.stat_regs.evergreen.disp_int_cont2 &= ~LB_D3_VLINE_INTERRUPT;
362125a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher					DRM_DEBUG("IH: D3 vline\n");
362225a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher				}
362325a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher				break;
362425a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher			default:
362525a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher				DRM_DEBUG("Unhandled interrupt: %d %d\n", src_id, src_data);
362625a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher				break;
362725a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher			}
362825a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher			break;
362925a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher		case 4: /* D4 vblank/vline */
363025a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher			switch (src_data) {
363125a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher			case 0: /* D4 vblank */
363225a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher				if (rdev->irq.stat_regs.evergreen.disp_int_cont3 & LB_D4_VBLANK_INTERRUPT) {
363325a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher					if (rdev->irq.crtc_vblank_int[3]) {
363425a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher						drm_handle_vblank(rdev->ddev, 3);
363525a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher						rdev->pm.vblank_sync = true;
363625a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher						wake_up(&rdev->irq.vblank_queue);
363725a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher					}
363825a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher					if (rdev->irq.pflip[3])
363925a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher						radeon_crtc_handle_flip(rdev, 3);
364025a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher					rdev->irq.stat_regs.evergreen.disp_int_cont3 &= ~LB_D4_VBLANK_INTERRUPT;
364125a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher					DRM_DEBUG("IH: D4 vblank\n");
364225a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher				}
364325a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher				break;
364425a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher			case 1: /* D4 vline */
364525a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher				if (rdev->irq.stat_regs.evergreen.disp_int_cont3 & LB_D4_VLINE_INTERRUPT) {
364625a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher					rdev->irq.stat_regs.evergreen.disp_int_cont3 &= ~LB_D4_VLINE_INTERRUPT;
364725a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher					DRM_DEBUG("IH: D4 vline\n");
364825a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher				}
364925a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher				break;
365025a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher			default:
365125a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher				DRM_DEBUG("Unhandled interrupt: %d %d\n", src_id, src_data);
365225a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher				break;
365325a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher			}
365425a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher			break;
365525a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher		case 5: /* D5 vblank/vline */
365625a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher			switch (src_data) {
365725a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher			case 0: /* D5 vblank */
365825a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher				if (rdev->irq.stat_regs.evergreen.disp_int_cont4 & LB_D5_VBLANK_INTERRUPT) {
365925a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher					if (rdev->irq.crtc_vblank_int[4]) {
366025a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher						drm_handle_vblank(rdev->ddev, 4);
366125a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher						rdev->pm.vblank_sync = true;
366225a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher						wake_up(&rdev->irq.vblank_queue);
366325a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher					}
366425a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher					if (rdev->irq.pflip[4])
366525a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher						radeon_crtc_handle_flip(rdev, 4);
366625a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher					rdev->irq.stat_regs.evergreen.disp_int_cont4 &= ~LB_D5_VBLANK_INTERRUPT;
366725a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher					DRM_DEBUG("IH: D5 vblank\n");
366825a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher				}
366925a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher				break;
367025a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher			case 1: /* D5 vline */
367125a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher				if (rdev->irq.stat_regs.evergreen.disp_int_cont4 & LB_D5_VLINE_INTERRUPT) {
367225a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher					rdev->irq.stat_regs.evergreen.disp_int_cont4 &= ~LB_D5_VLINE_INTERRUPT;
367325a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher					DRM_DEBUG("IH: D5 vline\n");
367425a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher				}
367525a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher				break;
367625a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher			default:
367725a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher				DRM_DEBUG("Unhandled interrupt: %d %d\n", src_id, src_data);
367825a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher				break;
367925a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher			}
368025a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher			break;
368125a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher		case 6: /* D6 vblank/vline */
368225a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher			switch (src_data) {
368325a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher			case 0: /* D6 vblank */
368425a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher				if (rdev->irq.stat_regs.evergreen.disp_int_cont5 & LB_D6_VBLANK_INTERRUPT) {
368525a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher					if (rdev->irq.crtc_vblank_int[5]) {
368625a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher						drm_handle_vblank(rdev->ddev, 5);
368725a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher						rdev->pm.vblank_sync = true;
368825a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher						wake_up(&rdev->irq.vblank_queue);
368925a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher					}
369025a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher					if (rdev->irq.pflip[5])
369125a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher						radeon_crtc_handle_flip(rdev, 5);
369225a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher					rdev->irq.stat_regs.evergreen.disp_int_cont5 &= ~LB_D6_VBLANK_INTERRUPT;
369325a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher					DRM_DEBUG("IH: D6 vblank\n");
369425a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher				}
369525a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher				break;
369625a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher			case 1: /* D6 vline */
369725a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher				if (rdev->irq.stat_regs.evergreen.disp_int_cont5 & LB_D6_VLINE_INTERRUPT) {
369825a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher					rdev->irq.stat_regs.evergreen.disp_int_cont5 &= ~LB_D6_VLINE_INTERRUPT;
369925a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher					DRM_DEBUG("IH: D6 vline\n");
370025a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher				}
370125a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher				break;
370225a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher			default:
370325a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher				DRM_DEBUG("Unhandled interrupt: %d %d\n", src_id, src_data);
370425a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher				break;
370525a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher			}
370625a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher			break;
370725a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher		case 42: /* HPD hotplug */
370825a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher			switch (src_data) {
370925a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher			case 0:
371025a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher				if (rdev->irq.stat_regs.evergreen.disp_int & DC_HPD1_INTERRUPT) {
371125a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher					rdev->irq.stat_regs.evergreen.disp_int &= ~DC_HPD1_INTERRUPT;
371225a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher					queue_hotplug = true;
371325a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher					DRM_DEBUG("IH: HPD1\n");
371425a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher				}
371525a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher				break;
371625a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher			case 1:
371725a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher				if (rdev->irq.stat_regs.evergreen.disp_int_cont & DC_HPD2_INTERRUPT) {
371825a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher					rdev->irq.stat_regs.evergreen.disp_int_cont &= ~DC_HPD2_INTERRUPT;
371925a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher					queue_hotplug = true;
372025a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher					DRM_DEBUG("IH: HPD2\n");
372125a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher				}
372225a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher				break;
372325a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher			case 2:
372425a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher				if (rdev->irq.stat_regs.evergreen.disp_int_cont2 & DC_HPD3_INTERRUPT) {
372525a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher					rdev->irq.stat_regs.evergreen.disp_int_cont2 &= ~DC_HPD3_INTERRUPT;
372625a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher					queue_hotplug = true;
372725a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher					DRM_DEBUG("IH: HPD3\n");
372825a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher				}
372925a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher				break;
373025a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher			case 3:
373125a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher				if (rdev->irq.stat_regs.evergreen.disp_int_cont3 & DC_HPD4_INTERRUPT) {
373225a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher					rdev->irq.stat_regs.evergreen.disp_int_cont3 &= ~DC_HPD4_INTERRUPT;
373325a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher					queue_hotplug = true;
373425a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher					DRM_DEBUG("IH: HPD4\n");
373525a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher				}
373625a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher				break;
373725a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher			case 4:
373825a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher				if (rdev->irq.stat_regs.evergreen.disp_int_cont4 & DC_HPD5_INTERRUPT) {
373925a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher					rdev->irq.stat_regs.evergreen.disp_int_cont4 &= ~DC_HPD5_INTERRUPT;
374025a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher					queue_hotplug = true;
374125a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher					DRM_DEBUG("IH: HPD5\n");
374225a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher				}
374325a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher				break;
374425a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher			case 5:
374525a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher				if (rdev->irq.stat_regs.evergreen.disp_int_cont5 & DC_HPD6_INTERRUPT) {
374625a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher					rdev->irq.stat_regs.evergreen.disp_int_cont5 &= ~DC_HPD6_INTERRUPT;
374725a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher					queue_hotplug = true;
374825a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher					DRM_DEBUG("IH: HPD6\n");
374925a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher				}
375025a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher				break;
375125a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher			default:
375225a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher				DRM_DEBUG("Unhandled interrupt: %d %d\n", src_id, src_data);
375325a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher				break;
375425a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher			}
375525a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher			break;
375625a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher		case 176: /* RINGID0 CP_INT */
375725a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher			radeon_fence_process(rdev, RADEON_RING_TYPE_GFX_INDEX);
375825a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher			break;
375925a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher		case 177: /* RINGID1 CP_INT */
376025a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher			radeon_fence_process(rdev, CAYMAN_RING_TYPE_CP1_INDEX);
376125a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher			break;
376225a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher		case 178: /* RINGID2 CP_INT */
376325a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher			radeon_fence_process(rdev, CAYMAN_RING_TYPE_CP2_INDEX);
376425a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher			break;
376525a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher		case 181: /* CP EOP event */
376625a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher			DRM_DEBUG("IH: CP EOP\n");
376725a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher			switch (ring_id) {
376825a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher			case 0:
376925a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher				radeon_fence_process(rdev, RADEON_RING_TYPE_GFX_INDEX);
377025a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher				break;
377125a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher			case 1:
377225a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher				radeon_fence_process(rdev, CAYMAN_RING_TYPE_CP1_INDEX);
377325a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher				break;
377425a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher			case 2:
377525a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher				radeon_fence_process(rdev, CAYMAN_RING_TYPE_CP2_INDEX);
377625a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher				break;
377725a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher			}
377825a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher			break;
377925a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher		case 233: /* GUI IDLE */
378025a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher			DRM_DEBUG("IH: GUI idle\n");
378125a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher			rdev->pm.gui_idle = true;
378225a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher			wake_up(&rdev->irq.idle_queue);
378325a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher			break;
378425a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher		default:
378525a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher			DRM_DEBUG("Unhandled interrupt: %d %d\n", src_id, src_data);
378625a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher			break;
378725a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher		}
378825a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher
378925a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher		/* wptr/rptr are in bytes! */
379025a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher		rptr += 16;
379125a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher		rptr &= rdev->ih.ptr_mask;
379225a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	}
379325a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	/* make sure wptr hasn't changed while processing */
379425a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	wptr = si_get_ih_wptr(rdev);
379525a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	if (wptr != rdev->ih.wptr)
379625a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher		goto restart_ih;
379725a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	if (queue_hotplug)
379825a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher		schedule_work(&rdev->hotplug_work);
379925a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	rdev->ih.rptr = rptr;
380025a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	WREG32(IH_RB_RPTR, rdev->ih.rptr);
380125a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	spin_unlock_irqrestore(&rdev->ih.lock, flags);
380225a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher	return IRQ_HANDLED;
380325a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher}
380425a857fbe973bdcc7df0df2e0c8f9c6e1ab0e475Alex Deucher
38059b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher/*
38069b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher * startup/shutdown callbacks
38079b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher */
38089b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucherstatic int si_startup(struct radeon_device *rdev)
38099b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher{
38109b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher	struct radeon_ring *ring;
38119b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher	int r;
38129b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher
38139b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher	if (!rdev->me_fw || !rdev->pfp_fw || !rdev->ce_fw ||
38149b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher	    !rdev->rlc_fw || !rdev->mc_fw) {
38159b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher		r = si_init_microcode(rdev);
38169b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher		if (r) {
38179b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher			DRM_ERROR("Failed to load firmware!\n");
38189b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher			return r;
38199b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher		}
38209b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher	}
38219b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher
38229b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher	r = si_mc_load_microcode(rdev);
38239b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher	if (r) {
38249b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher		DRM_ERROR("Failed to load MC firmware!\n");
38259b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher		return r;
38269b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher	}
38279b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher
38289b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher	r = r600_vram_scratch_init(rdev);
38299b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher	if (r)
38309b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher		return r;
38319b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher
38329b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher	si_mc_program(rdev);
38339b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher	r = si_pcie_gart_enable(rdev);
38349b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher	if (r)
38359b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher		return r;
38369b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher	si_gpu_init(rdev);
38379b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher
38389b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher#if 0
38399b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher	r = evergreen_blit_init(rdev);
38409b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher	if (r) {
38419b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher		r600_blit_fini(rdev);
38429b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher		rdev->asic->copy = NULL;
38439b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher		dev_warn(rdev->dev, "failed blitter (%d) falling back to memcpy\n", r);
38449b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher	}
38459b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher#endif
38469b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher	/* allocate rlc buffers */
38479b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher	r = si_rlc_init(rdev);
38489b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher	if (r) {
38499b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher		DRM_ERROR("Failed to init rlc BOs!\n");
38509b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher		return r;
38519b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher	}
38529b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher
38539b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher	/* allocate wb buffer */
38549b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher	r = radeon_wb_init(rdev);
38559b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher	if (r)
38569b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher		return r;
38579b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher
38589b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher	r = radeon_fence_driver_start_ring(rdev, RADEON_RING_TYPE_GFX_INDEX);
38599b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher	if (r) {
38609b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher		dev_err(rdev->dev, "failed initializing CP fences (%d).\n", r);
38619b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher		return r;
38629b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher	}
38639b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher
38649b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher	r = radeon_fence_driver_start_ring(rdev, CAYMAN_RING_TYPE_CP1_INDEX);
38659b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher	if (r) {
38669b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher		dev_err(rdev->dev, "failed initializing CP fences (%d).\n", r);
38679b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher		return r;
38689b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher	}
38699b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher
38709b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher	r = radeon_fence_driver_start_ring(rdev, CAYMAN_RING_TYPE_CP2_INDEX);
38719b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher	if (r) {
38729b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher		dev_err(rdev->dev, "failed initializing CP fences (%d).\n", r);
38739b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher		return r;
38749b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher	}
38759b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher
38769b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher	/* Enable IRQ */
38779b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher	r = si_irq_init(rdev);
38789b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher	if (r) {
38799b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher		DRM_ERROR("radeon: IH init failed (%d).\n", r);
38809b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher		radeon_irq_kms_fini(rdev);
38819b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher		return r;
38829b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher	}
38839b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher	si_irq_set(rdev);
38849b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher
38859b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher	ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX];
38869b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher	r = radeon_ring_init(rdev, ring, ring->ring_size, RADEON_WB_CP_RPTR_OFFSET,
38879b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher			     CP_RB0_RPTR, CP_RB0_WPTR,
38889b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher			     0, 0xfffff, RADEON_CP_PACKET2);
38899b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher	if (r)
38909b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher		return r;
38919b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher
38929b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher	ring = &rdev->ring[CAYMAN_RING_TYPE_CP1_INDEX];
38939b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher	r = radeon_ring_init(rdev, ring, ring->ring_size, RADEON_WB_CP1_RPTR_OFFSET,
38949b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher			     CP_RB1_RPTR, CP_RB1_WPTR,
38959b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher			     0, 0xfffff, RADEON_CP_PACKET2);
38969b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher	if (r)
38979b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher		return r;
38989b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher
38999b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher	ring = &rdev->ring[CAYMAN_RING_TYPE_CP2_INDEX];
39009b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher	r = radeon_ring_init(rdev, ring, ring->ring_size, RADEON_WB_CP2_RPTR_OFFSET,
39019b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher			     CP_RB2_RPTR, CP_RB2_WPTR,
39029b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher			     0, 0xfffff, RADEON_CP_PACKET2);
39039b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher	if (r)
39049b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher		return r;
39059b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher
39069b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher	r = si_cp_load_microcode(rdev);
39079b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher	if (r)
39089b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher		return r;
39099b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher	r = si_cp_resume(rdev);
39109b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher	if (r)
39119b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher		return r;
39129b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher
39139b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher	r = radeon_ib_pool_start(rdev);
39149b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher	if (r)
39159b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher		return r;
39169b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher
39179b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher	r = radeon_ib_test(rdev, RADEON_RING_TYPE_GFX_INDEX, &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]);
39189b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher	if (r) {
39199b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher		DRM_ERROR("radeon: failed testing IB (%d) on CP ring 0\n", r);
39209b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher		rdev->accel_working = false;
39219b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher		return r;
39229b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher	}
39239b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher
39249b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher	r = radeon_ib_test(rdev, CAYMAN_RING_TYPE_CP1_INDEX, &rdev->ring[CAYMAN_RING_TYPE_CP1_INDEX]);
39259b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher	if (r) {
39269b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher		DRM_ERROR("radeon: failed testing IB (%d) on CP ring 1\n", r);
39279b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher		rdev->accel_working = false;
39289b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher		return r;
39299b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher	}
39309b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher
39319b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher	r = radeon_ib_test(rdev, CAYMAN_RING_TYPE_CP2_INDEX, &rdev->ring[CAYMAN_RING_TYPE_CP2_INDEX]);
39329b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher	if (r) {
39339b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher		DRM_ERROR("radeon: failed testing IB (%d) on CP ring 2\n", r);
39349b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher		rdev->accel_working = false;
39359b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher		return r;
39369b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher	}
39379b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher
39389b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher	r = radeon_vm_manager_start(rdev);
39399b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher	if (r)
39409b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher		return r;
39419b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher
39429b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher	return 0;
39439b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher}
39449b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher
39459b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucherint si_resume(struct radeon_device *rdev)
39469b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher{
39479b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher	int r;
39489b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher
39499b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher	/* Do not reset GPU before posting, on rv770 hw unlike on r500 hw,
39509b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher	 * posting will perform necessary task to bring back GPU into good
39519b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher	 * shape.
39529b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher	 */
39539b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher	/* post card */
39549b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher	atom_asic_init(rdev->mode_info.atom_context);
39559b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher
39569b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher	rdev->accel_working = true;
39579b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher	r = si_startup(rdev);
39589b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher	if (r) {
39599b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher		DRM_ERROR("si startup failed on resume\n");
39609b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher		rdev->accel_working = false;
39619b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher		return r;
39629b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher	}
39639b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher
39649b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher	return r;
39659b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher
39669b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher}
39679b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher
39689b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucherint si_suspend(struct radeon_device *rdev)
39699b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher{
39709b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher	/* FIXME: we should wait for ring to be empty */
39719b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher	radeon_ib_pool_suspend(rdev);
39729b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher	radeon_vm_manager_suspend(rdev);
39739b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher#if 0
39749b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher	r600_blit_suspend(rdev);
39759b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher#endif
39769b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher	si_cp_enable(rdev, false);
39779b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher	rdev->ring[RADEON_RING_TYPE_GFX_INDEX].ready = false;
39789b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher	rdev->ring[CAYMAN_RING_TYPE_CP1_INDEX].ready = false;
39799b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher	rdev->ring[CAYMAN_RING_TYPE_CP2_INDEX].ready = false;
39809b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher	si_irq_suspend(rdev);
39819b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher	radeon_wb_disable(rdev);
39829b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher	si_pcie_gart_disable(rdev);
39839b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher	return 0;
39849b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher}
39859b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher
39869b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher/* Plan is to move initialization in that function and use
39879b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher * helper function so that radeon_device_init pretty much
39889b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher * do nothing more than calling asic specific function. This
39899b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher * should also allow to remove a bunch of callback function
39909b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher * like vram_info.
39919b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher */
39929b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucherint si_init(struct radeon_device *rdev)
39939b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher{
39949b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher	struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX];
39959b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher	int r;
39969b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher
39979b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher	/* This don't do much */
39989b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher	r = radeon_gem_init(rdev);
39999b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher	if (r)
40009b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher		return r;
40019b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher	/* Read BIOS */
40029b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher	if (!radeon_get_bios(rdev)) {
40039b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher		if (ASIC_IS_AVIVO(rdev))
40049b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher			return -EINVAL;
40059b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher	}
40069b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher	/* Must be an ATOMBIOS */
40079b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher	if (!rdev->is_atom_bios) {
40089b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher		dev_err(rdev->dev, "Expecting atombios for cayman GPU\n");
40099b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher		return -EINVAL;
40109b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher	}
40119b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher	r = radeon_atombios_init(rdev);
40129b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher	if (r)
40139b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher		return r;
40149b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher
40159b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher	/* Post card if necessary */
40169b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher	if (!radeon_card_posted(rdev)) {
40179b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher		if (!rdev->bios) {
40189b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher			dev_err(rdev->dev, "Card not posted and no BIOS - ignoring\n");
40199b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher			return -EINVAL;
40209b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher		}
40219b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher		DRM_INFO("GPU not posted. posting now...\n");
40229b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher		atom_asic_init(rdev->mode_info.atom_context);
40239b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher	}
40249b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher	/* Initialize scratch registers */
40259b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher	si_scratch_init(rdev);
40269b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher	/* Initialize surface registers */
40279b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher	radeon_surface_init(rdev);
40289b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher	/* Initialize clocks */
40299b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher	radeon_get_clock_info(rdev->ddev);
40309b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher
40319b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher	/* Fence driver */
40329b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher	r = radeon_fence_driver_init(rdev);
40339b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher	if (r)
40349b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher		return r;
40359b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher
40369b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher	/* initialize memory controller */
40379b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher	r = si_mc_init(rdev);
40389b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher	if (r)
40399b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher		return r;
40409b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher	/* Memory manager */
40419b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher	r = radeon_bo_init(rdev);
40429b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher	if (r)
40439b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher		return r;
40449b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher
40459b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher	r = radeon_irq_kms_init(rdev);
40469b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher	if (r)
40479b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher		return r;
40489b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher
40499b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher	ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX];
40509b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher	ring->ring_obj = NULL;
40519b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher	r600_ring_init(rdev, ring, 1024 * 1024);
40529b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher
40539b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher	ring = &rdev->ring[CAYMAN_RING_TYPE_CP1_INDEX];
40549b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher	ring->ring_obj = NULL;
40559b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher	r600_ring_init(rdev, ring, 1024 * 1024);
40569b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher
40579b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher	ring = &rdev->ring[CAYMAN_RING_TYPE_CP2_INDEX];
40589b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher	ring->ring_obj = NULL;
40599b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher	r600_ring_init(rdev, ring, 1024 * 1024);
40609b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher
40619b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher	rdev->ih.ring_obj = NULL;
40629b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher	r600_ih_ring_init(rdev, 64 * 1024);
40639b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher
40649b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher	r = r600_pcie_gart_init(rdev);
40659b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher	if (r)
40669b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher		return r;
40679b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher
40689b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher	r = radeon_ib_pool_init(rdev);
40699b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher	rdev->accel_working = true;
40709b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher	if (r) {
40719b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher		dev_err(rdev->dev, "IB initialization failed (%d).\n", r);
40729b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher		rdev->accel_working = false;
40739b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher	}
40749b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher	r = radeon_vm_manager_init(rdev);
40759b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher	if (r) {
40769b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher		dev_err(rdev->dev, "vm manager initialization failed (%d).\n", r);
40779b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher	}
40789b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher
40799b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher	r = si_startup(rdev);
40809b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher	if (r) {
40819b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher		dev_err(rdev->dev, "disabling GPU acceleration\n");
40829b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher		si_cp_fini(rdev);
40839b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher		si_irq_fini(rdev);
40849b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher		si_rlc_fini(rdev);
40859b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher		radeon_wb_fini(rdev);
40869b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher		r100_ib_fini(rdev);
40879b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher		radeon_vm_manager_fini(rdev);
40889b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher		radeon_irq_kms_fini(rdev);
40899b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher		si_pcie_gart_fini(rdev);
40909b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher		rdev->accel_working = false;
40919b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher	}
40929b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher
40939b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher	/* Don't start up if the MC ucode is missing.
40949b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher	 * The default clocks and voltages before the MC ucode
40959b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher	 * is loaded are not suffient for advanced operations.
40969b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher	 */
40979b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher	if (!rdev->mc_fw) {
40989b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher		DRM_ERROR("radeon: MC ucode required for NI+.\n");
40999b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher		return -EINVAL;
41009b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher	}
41019b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher
41029b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher	return 0;
41039b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher}
41049b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher
41059b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deuchervoid si_fini(struct radeon_device *rdev)
41069b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher{
41079b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher#if 0
41089b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher	r600_blit_fini(rdev);
41099b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher#endif
41109b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher	si_cp_fini(rdev);
41119b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher	si_irq_fini(rdev);
41129b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher	si_rlc_fini(rdev);
41139b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher	radeon_wb_fini(rdev);
41149b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher	radeon_vm_manager_fini(rdev);
41159b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher	r100_ib_fini(rdev);
41169b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher	radeon_irq_kms_fini(rdev);
41179b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher	si_pcie_gart_fini(rdev);
41189b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher	r600_vram_scratch_fini(rdev);
41199b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher	radeon_gem_fini(rdev);
41209b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher	radeon_semaphore_driver_fini(rdev);
41219b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher	radeon_fence_driver_fini(rdev);
41229b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher	radeon_bo_fini(rdev);
41239b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher	radeon_atombios_fini(rdev);
41249b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher	kfree(rdev->bios);
41259b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher	rdev->bios = NULL;
41269b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher}
41279b136d514e3537a41e506f5306cd92d6d142f8bbAlex Deucher
4128