nv.c 34.8 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
/*
 * Copyright 2019 Advanced Micro Devices, Inc.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 * OTHER DEALINGS IN THE SOFTWARE.
 *
 */
#include <linux/firmware.h>
#include <linux/slab.h>
#include <linux/module.h>
26 27
#include <linux/pci.h>

28 29
#include <drm/amdgpu_drm.h>

30 31 32 33 34 35 36 37 38 39 40 41
#include "amdgpu.h"
#include "amdgpu_atombios.h"
#include "amdgpu_ih.h"
#include "amdgpu_uvd.h"
#include "amdgpu_vce.h"
#include "amdgpu_ucode.h"
#include "amdgpu_psp.h"
#include "atom.h"
#include "amd_pcie.h"

#include "gc/gc_10_1_0_offset.h"
#include "gc/gc_10_1_0_sh_mask.h"
42
#include "mp/mp_11_0_offset.h"
43 44 45 46 47 48

#include "soc15.h"
#include "soc15_common.h"
#include "gmc_v10_0.h"
#include "gfxhub_v2_0.h"
#include "mmhub_v2_0.h"
49
#include "nbio_v2_3.h"
50
#include "nbio_v7_2.h"
51
#include "hdp_v5_0.h"
52 53 54 55
#include "nv.h"
#include "navi10_ih.h"
#include "gfx_v10_0.h"
#include "sdma_v5_0.h"
56
#include "sdma_v5_2.h"
57
#include "vcn_v2_0.h"
58
#include "jpeg_v2_0.h"
59
#include "vcn_v3_0.h"
60
#include "jpeg_v3_0.h"
61
#include "amdgpu_vkms.h"
62
#include "mes_v10_1.h"
63
#include "mxgpu_nv.h"
64 65
#include "smuio_v11_0.h"
#include "smuio_v11_0_6.h"
66 67 68

static const struct amd_ip_funcs nv_common_ip_funcs;

69 70 71
/* Navi */
static const struct amdgpu_video_codec_info nv_video_codecs_encode_array[] =
{
72 73
	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4_AVC, 4096, 2304, 0)},
	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_HEVC, 4096, 2304, 0)},
74 75 76 77 78 79 80 81 82 83 84
};

static const struct amdgpu_video_codecs nv_video_codecs_encode =
{
	.codec_count = ARRAY_SIZE(nv_video_codecs_encode_array),
	.codec_array = nv_video_codecs_encode_array,
};

/* Navi1x */
static const struct amdgpu_video_codec_info nv_video_codecs_decode_array[] =
{
85 86 87 88
	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG2, 4096, 4096, 3)},
	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4, 4096, 4096, 5)},
	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4_AVC, 4096, 4096, 52)},
	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_VC1, 4096, 4096, 4)},
89 90 91
	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_HEVC, 8192, 4352, 186)},
	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_JPEG, 4096, 4096, 0)},
	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_VP9, 8192, 4352, 0)},
92 93 94 95 96 97 98 99 100
};

static const struct amdgpu_video_codecs nv_video_codecs_decode =
{
	.codec_count = ARRAY_SIZE(nv_video_codecs_decode_array),
	.codec_array = nv_video_codecs_decode_array,
};

/* Sienna Cichlid */
101
static const struct amdgpu_video_codec_info sc_video_codecs_decode_array_vcn0[] =
102
{
103 104 105 106
	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG2, 4096, 4096, 3)},
	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4, 4096, 4096, 5)},
	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4_AVC, 4096, 4096, 52)},
	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_VC1, 4096, 4096, 4)},
107 108 109 110
	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_HEVC, 8192, 4352, 186)},
	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_JPEG, 4096, 4096, 0)},
	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_VP9, 8192, 4352, 0)},
	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_AV1, 8192, 4352, 0)},
111 112
};

113
static const struct amdgpu_video_codec_info sc_video_codecs_decode_array_vcn1[] =
114
{
115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133
	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG2, 4096, 4096, 3)},
	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4, 4096, 4096, 5)},
	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4_AVC, 4096, 4096, 52)},
	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_VC1, 4096, 4096, 4)},
	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_HEVC, 8192, 4352, 186)},
	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_JPEG, 4096, 4096, 0)},
	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_VP9, 8192, 4352, 0)},
};

static const struct amdgpu_video_codecs sc_video_codecs_decode_vcn0 =
{
	.codec_count = ARRAY_SIZE(sc_video_codecs_decode_array_vcn0),
	.codec_array = sc_video_codecs_decode_array_vcn0,
};

static const struct amdgpu_video_codecs sc_video_codecs_decode_vcn1 =
{
	.codec_count = ARRAY_SIZE(sc_video_codecs_decode_array_vcn1),
	.codec_array = sc_video_codecs_decode_array_vcn1,
134 135
};

136 137 138
/* SRIOV Sienna Cichlid, not const since data is controlled by host */
static struct amdgpu_video_codec_info sriov_sc_video_codecs_encode_array[] =
{
139 140
	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4_AVC, 4096, 2304, 0)},
	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_HEVC, 4096, 2304, 0)},
141 142
};

143
static struct amdgpu_video_codec_info sriov_sc_video_codecs_decode_array_vcn0[] =
144
{
145 146 147 148
	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG2, 4096, 4096, 3)},
	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4, 4096, 4096, 5)},
	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4_AVC, 4096, 4096, 52)},
	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_VC1, 4096, 4096, 4)},
149 150 151 152
	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_HEVC, 8192, 4352, 186)},
	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_JPEG, 4096, 4096, 0)},
	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_VP9, 8192, 4352, 0)},
	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_AV1, 8192, 4352, 0)},
153 154
};

155 156 157 158 159 160 161 162 163 164 165
static struct amdgpu_video_codec_info sriov_sc_video_codecs_decode_array_vcn1[] =
{
	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG2, 4096, 4096, 3)},
	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4, 4096, 4096, 5)},
	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4_AVC, 4096, 4096, 52)},
	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_VC1, 4096, 4096, 4)},
	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_HEVC, 8192, 4352, 186)},
	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_JPEG, 4096, 4096, 0)},
	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_VP9, 8192, 4352, 0)},
};

166 167 168 169 170 171
static struct amdgpu_video_codecs sriov_sc_video_codecs_encode =
{
	.codec_count = ARRAY_SIZE(sriov_sc_video_codecs_encode_array),
	.codec_array = sriov_sc_video_codecs_encode_array,
};

172
static struct amdgpu_video_codecs sriov_sc_video_codecs_decode_vcn0 =
173
{
174 175 176 177 178 179 180 181
	.codec_count = ARRAY_SIZE(sriov_sc_video_codecs_decode_array_vcn0),
	.codec_array = sriov_sc_video_codecs_decode_array_vcn0,
};

static struct amdgpu_video_codecs sriov_sc_video_codecs_decode_vcn1 =
{
	.codec_count = ARRAY_SIZE(sriov_sc_video_codecs_decode_array_vcn1),
	.codec_array = sriov_sc_video_codecs_decode_array_vcn1,
182 183
};

184 185
/* Beige Goby*/
static const struct amdgpu_video_codec_info bg_video_codecs_decode_array[] = {
186
	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4_AVC, 4096, 4096, 52)},
187 188 189 190 191 192 193 194 195 196 197 198 199 200
	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_HEVC, 8192, 4352, 186)},
	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_VP9, 8192, 4352, 0)},
};

static const struct amdgpu_video_codecs bg_video_codecs_decode = {
	.codec_count = ARRAY_SIZE(bg_video_codecs_decode_array),
	.codec_array = bg_video_codecs_decode_array,
};

static const struct amdgpu_video_codecs bg_video_codecs_encode = {
	.codec_count = 0,
	.codec_array = NULL,
};

201 202
/* Yellow Carp*/
static const struct amdgpu_video_codec_info yc_video_codecs_decode_array[] = {
203
	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_MPEG4_AVC, 4096, 4096, 52)},
204 205 206
	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_HEVC, 8192, 4352, 186)},
	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_VP9, 8192, 4352, 0)},
	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_JPEG, 4096, 4096, 0)},
207
	{codec_info_build(AMDGPU_INFO_VIDEO_CAPS_CODEC_IDX_AV1, 8192, 4352, 0)},
208 209 210
};

static const struct amdgpu_video_codecs yc_video_codecs_decode = {
211 212
	.codec_count = ARRAY_SIZE(yc_video_codecs_decode_array),
	.codec_array = yc_video_codecs_decode_array,
213 214
};

215 216 217
static int nv_query_video_codecs(struct amdgpu_device *adev, bool encode,
				 const struct amdgpu_video_codecs **codecs)
{
218 219 220
	if (adev->vcn.num_vcn_inst == hweight8(adev->vcn.harvest_config))
		return -EINVAL;

221
	switch (adev->ip_versions[UVD_HWIP][0]) {
222
	case IP_VERSION(3, 0, 0):
223
	case IP_VERSION(3, 0, 64):
224
	case IP_VERSION(3, 0, 192):
225
		if (amdgpu_sriov_vf(adev)) {
226 227 228 229 230 231 232 233 234 235 236
			if (adev->vcn.harvest_config & AMDGPU_VCN_HARVEST_VCN0) {
				if (encode)
					*codecs = &sriov_sc_video_codecs_encode;
				else
					*codecs = &sriov_sc_video_codecs_decode_vcn1;
			} else {
				if (encode)
					*codecs = &sriov_sc_video_codecs_encode;
				else
					*codecs = &sriov_sc_video_codecs_decode_vcn0;
			}
237
		} else {
238 239 240 241 242 243 244 245 246 247 248
			if (adev->vcn.harvest_config & AMDGPU_VCN_HARVEST_VCN0) {
				if (encode)
					*codecs = &nv_video_codecs_encode;
				else
					*codecs = &sc_video_codecs_decode_vcn1;
			} else {
				if (encode)
					*codecs = &nv_video_codecs_encode;
				else
					*codecs = &sc_video_codecs_decode_vcn0;
			}
249 250
		}
		return 0;
251 252
	case IP_VERSION(3, 0, 16):
	case IP_VERSION(3, 0, 2):
253 254 255
		if (encode)
			*codecs = &nv_video_codecs_encode;
		else
256
			*codecs = &sc_video_codecs_decode_vcn0;
257
		return 0;
258
	case IP_VERSION(3, 1, 1):
259
	case IP_VERSION(3, 1, 2):
260 261 262 263 264
		if (encode)
			*codecs = &nv_video_codecs_encode;
		else
			*codecs = &yc_video_codecs_decode;
		return 0;
265
	case IP_VERSION(3, 0, 33):
266 267 268 269 270
		if (encode)
			*codecs = &bg_video_codecs_encode;
		else
			*codecs = &bg_video_codecs_decode;
		return 0;
271 272
	case IP_VERSION(2, 0, 0):
	case IP_VERSION(2, 0, 2):
273 274 275 276 277 278 279 280 281 282
		if (encode)
			*codecs = &nv_video_codecs_encode;
		else
			*codecs = &nv_video_codecs_decode;
		return 0;
	default:
		return -EINVAL;
	}
}

283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312
static u32 nv_didt_rreg(struct amdgpu_device *adev, u32 reg)
{
	unsigned long flags, address, data;
	u32 r;

	address = SOC15_REG_OFFSET(GC, 0, mmDIDT_IND_INDEX);
	data = SOC15_REG_OFFSET(GC, 0, mmDIDT_IND_DATA);

	spin_lock_irqsave(&adev->didt_idx_lock, flags);
	WREG32(address, (reg));
	r = RREG32(data);
	spin_unlock_irqrestore(&adev->didt_idx_lock, flags);
	return r;
}

static void nv_didt_wreg(struct amdgpu_device *adev, u32 reg, u32 v)
{
	unsigned long flags, address, data;

	address = SOC15_REG_OFFSET(GC, 0, mmDIDT_IND_INDEX);
	data = SOC15_REG_OFFSET(GC, 0, mmDIDT_IND_DATA);

	spin_lock_irqsave(&adev->didt_idx_lock, flags);
	WREG32(address, (reg));
	WREG32(data, (v));
	spin_unlock_irqrestore(&adev->didt_idx_lock, flags);
}

static u32 nv_get_config_memsize(struct amdgpu_device *adev)
{
313
	return adev->nbio.funcs->get_memsize(adev);
314 315 316 317
}

static u32 nv_get_xclk(struct amdgpu_device *adev)
{
318
	return adev->clock.spll.reference_freq;
319 320 321 322 323 324 325 326 327 328 329 330
}


void nv_grbm_select(struct amdgpu_device *adev,
		     u32 me, u32 pipe, u32 queue, u32 vmid)
{
	u32 grbm_gfx_cntl = 0;
	grbm_gfx_cntl = REG_SET_FIELD(grbm_gfx_cntl, GRBM_GFX_CNTL, PIPEID, pipe);
	grbm_gfx_cntl = REG_SET_FIELD(grbm_gfx_cntl, GRBM_GFX_CNTL, MEID, me);
	grbm_gfx_cntl = REG_SET_FIELD(grbm_gfx_cntl, GRBM_GFX_CNTL, VMID, vmid);
	grbm_gfx_cntl = REG_SET_FIELD(grbm_gfx_cntl, GRBM_GFX_CNTL, QUEUEID, queue);

331
	WREG32_SOC15(GC, 0, mmGRBM_GFX_CNTL, grbm_gfx_cntl);
332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360
}

static void nv_vga_set_state(struct amdgpu_device *adev, bool state)
{
	/* todo */
}

static bool nv_read_disabled_bios(struct amdgpu_device *adev)
{
	/* todo */
	return false;
}

static struct soc15_allowed_register_entry nv_allowed_read_registers[] = {
	{ SOC15_REG_ENTRY(GC, 0, mmGRBM_STATUS)},
	{ SOC15_REG_ENTRY(GC, 0, mmGRBM_STATUS2)},
	{ SOC15_REG_ENTRY(GC, 0, mmGRBM_STATUS_SE0)},
	{ SOC15_REG_ENTRY(GC, 0, mmGRBM_STATUS_SE1)},
	{ SOC15_REG_ENTRY(GC, 0, mmGRBM_STATUS_SE2)},
	{ SOC15_REG_ENTRY(GC, 0, mmGRBM_STATUS_SE3)},
	{ SOC15_REG_ENTRY(SDMA0, 0, mmSDMA0_STATUS_REG)},
	{ SOC15_REG_ENTRY(SDMA1, 0, mmSDMA1_STATUS_REG)},
	{ SOC15_REG_ENTRY(GC, 0, mmCP_STAT)},
	{ SOC15_REG_ENTRY(GC, 0, mmCP_STALLED_STAT1)},
	{ SOC15_REG_ENTRY(GC, 0, mmCP_STALLED_STAT2)},
	{ SOC15_REG_ENTRY(GC, 0, mmCP_STALLED_STAT3)},
	{ SOC15_REG_ENTRY(GC, 0, mmCP_CPF_BUSY_STAT)},
	{ SOC15_REG_ENTRY(GC, 0, mmCP_CPF_STALLED_STAT1)},
	{ SOC15_REG_ENTRY(GC, 0, mmCP_CPF_STATUS)},
361
	{ SOC15_REG_ENTRY(GC, 0, mmCP_CPC_BUSY_STAT)},
362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405
	{ SOC15_REG_ENTRY(GC, 0, mmCP_CPC_STALLED_STAT1)},
	{ SOC15_REG_ENTRY(GC, 0, mmCP_CPC_STATUS)},
	{ SOC15_REG_ENTRY(GC, 0, mmGB_ADDR_CONFIG)},
};

static uint32_t nv_read_indexed_register(struct amdgpu_device *adev, u32 se_num,
					 u32 sh_num, u32 reg_offset)
{
	uint32_t val;

	mutex_lock(&adev->grbm_idx_mutex);
	if (se_num != 0xffffffff || sh_num != 0xffffffff)
		amdgpu_gfx_select_se_sh(adev, se_num, sh_num, 0xffffffff);

	val = RREG32(reg_offset);

	if (se_num != 0xffffffff || sh_num != 0xffffffff)
		amdgpu_gfx_select_se_sh(adev, 0xffffffff, 0xffffffff, 0xffffffff);
	mutex_unlock(&adev->grbm_idx_mutex);
	return val;
}

static uint32_t nv_get_register_value(struct amdgpu_device *adev,
				      bool indexed, u32 se_num,
				      u32 sh_num, u32 reg_offset)
{
	if (indexed) {
		return nv_read_indexed_register(adev, se_num, sh_num, reg_offset);
	} else {
		if (reg_offset == SOC15_REG_OFFSET(GC, 0, mmGB_ADDR_CONFIG))
			return adev->gfx.config.gb_addr_config;
		return RREG32(reg_offset);
	}
}

static int nv_read_register(struct amdgpu_device *adev, u32 se_num,
			    u32 sh_num, u32 reg_offset, u32 *value)
{
	uint32_t i;
	struct soc15_allowed_register_entry  *en;

	*value = 0;
	for (i = 0; i < ARRAY_SIZE(nv_allowed_read_registers); i++) {
		en = &nv_allowed_read_registers[i];
406 407 408 409
		if (!adev->reg_offset[en->hwip][en->inst])
			continue;
		else if (reg_offset != (adev->reg_offset[en->hwip][en->inst][en->seg]
					+ en->reg_offset))
410 411 412 413 414 415 416 417 418 419
			continue;

		*value = nv_get_register_value(adev,
					       nv_allowed_read_registers[i].grbm_indexed,
					       se_num, sh_num, reg_offset);
		return 0;
	}
	return -EINVAL;
}

420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451
static int nv_asic_mode2_reset(struct amdgpu_device *adev)
{
	u32 i;
	int ret = 0;

	amdgpu_atombios_scratch_regs_engine_hung(adev, true);

	/* disable BM */
	pci_clear_master(adev->pdev);

	amdgpu_device_cache_pci_state(adev->pdev);

	ret = amdgpu_dpm_mode2_reset(adev);
	if (ret)
		dev_err(adev->dev, "GPU mode2 reset failed\n");

	amdgpu_device_load_pci_state(adev->pdev);

	/* wait for asic to come out of reset */
	for (i = 0; i < adev->usec_timeout; i++) {
		u32 memsize = adev->nbio.funcs->get_memsize(adev);

		if (memsize != 0xffffffff)
			break;
		udelay(1);
	}

	amdgpu_atombios_scratch_regs_engine_hung(adev, false);

	return ret;
}

452 453 454
static enum amd_reset_method
nv_asic_reset_method(struct amdgpu_device *adev)
{
455
	if (amdgpu_reset_method == AMD_RESET_METHOD_MODE1 ||
456
	    amdgpu_reset_method == AMD_RESET_METHOD_MODE2 ||
457 458
	    amdgpu_reset_method == AMD_RESET_METHOD_BACO ||
	    amdgpu_reset_method == AMD_RESET_METHOD_PCI)
459 460 461 462 463 464
		return amdgpu_reset_method;

	if (amdgpu_reset_method != -1)
		dev_warn(adev->dev, "Specified reset method:%d isn't supported, using AUTO instead.\n",
				  amdgpu_reset_method);

465
	switch (adev->ip_versions[MP1_HWIP][0]) {
466 467 468
	case IP_VERSION(11, 5, 0):
	case IP_VERSION(13, 0, 1):
	case IP_VERSION(13, 0, 3):
469
	case IP_VERSION(13, 0, 5):
470
	case IP_VERSION(13, 0, 8):
471
		return AMD_RESET_METHOD_MODE2;
472 473 474 475
	case IP_VERSION(11, 0, 7):
	case IP_VERSION(11, 0, 11):
	case IP_VERSION(11, 0, 12):
	case IP_VERSION(11, 0, 13):
476
		return AMD_RESET_METHOD_MODE1;
477
	default:
478
		if (amdgpu_dpm_is_baco_supported(adev))
479 480 481 482
			return AMD_RESET_METHOD_BACO;
		else
			return AMD_RESET_METHOD_MODE1;
	}
483 484
}

485 486
static int nv_asic_reset(struct amdgpu_device *adev)
{
487
	int ret = 0;
488

489
	switch (nv_asic_reset_method(adev)) {
490 491 492 493
	case AMD_RESET_METHOD_PCI:
		dev_info(adev->dev, "PCI reset\n");
		ret = amdgpu_device_pci_reset(adev);
		break;
494
	case AMD_RESET_METHOD_BACO:
495
		dev_info(adev->dev, "BACO reset\n");
496
		ret = amdgpu_dpm_baco_reset(adev);
497 498 499
		break;
	case AMD_RESET_METHOD_MODE2:
		dev_info(adev->dev, "MODE2 reset\n");
500
		ret = nv_asic_mode2_reset(adev);
501 502
		break;
	default:
503
		dev_info(adev->dev, "MODE1 reset\n");
504
		ret = amdgpu_device_mode1_reset(adev);
505
		break;
506
	}
507 508

	return ret;
509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539
}

static int nv_set_uvd_clocks(struct amdgpu_device *adev, u32 vclk, u32 dclk)
{
	/* todo */
	return 0;
}

static int nv_set_vce_clocks(struct amdgpu_device *adev, u32 evclk, u32 ecclk)
{
	/* todo */
	return 0;
}

static void nv_pcie_gen3_enable(struct amdgpu_device *adev)
{
	if (pci_is_root_bus(adev->pdev->bus))
		return;

	if (amdgpu_pcie_gen2 == 0)
		return;

	if (!(adev->pm.pcie_gen_mask & (CAIL_PCIE_LINK_SPEED_SUPPORT_GEN2 |
					CAIL_PCIE_LINK_SPEED_SUPPORT_GEN3)))
		return;

	/* todo */
}

static void nv_program_aspm(struct amdgpu_device *adev)
{
540
	if (!amdgpu_device_should_use_aspm(adev))
541 542
		return;

543
	if (!(adev->flags & AMD_IS_APU) &&
544 545 546
	    (adev->nbio.funcs->program_aspm))
		adev->nbio.funcs->program_aspm(adev);

547 548 549 550 551
}

static void nv_enable_doorbell_aperture(struct amdgpu_device *adev,
					bool enable)
{
552 553
	adev->nbio.funcs->enable_doorbell_aperture(adev, enable);
	adev->nbio.funcs->enable_doorbell_selfring_aperture(adev, enable);
554 555
}

556
const struct amdgpu_ip_block_version nv_common_ip_block =
557 558 559 560 561 562 563 564
{
	.type = AMD_IP_BLOCK_TYPE_COMMON,
	.major = 1,
	.minor = 0,
	.rev = 0,
	.funcs = &nv_common_ip_funcs,
};

565 566 567 568 569
void nv_set_virt_ops(struct amdgpu_device *adev)
{
	adev->virt.ops = &xgpu_nv_virt_ops;
}

570 571
static uint32_t nv_get_rev_id(struct amdgpu_device *adev)
{
572
	return adev->nbio.funcs->get_rev_id(adev);
573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592
}

static bool nv_need_full_reset(struct amdgpu_device *adev)
{
	return true;
}

static bool nv_need_reset_on_init(struct amdgpu_device *adev)
{
	u32 sol_reg;

	if (adev->flags & AMD_IS_APU)
		return false;

	/* Check sOS sign of life register to confirm sys driver and sOS
	 * are already been loaded.
	 */
	sol_reg = RREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_81);
	if (sol_reg)
		return true;
593

594 595 596
	return false;
}

597 598 599 600 601 602 603 604 605 606
static uint64_t nv_get_pcie_replay_count(struct amdgpu_device *adev)
{

	/* TODO
	 * dummy implement for pcie_replay_count sysfs interface
	 * */

	return 0;
}

607 608 609 610 611 612 613 614 615 616 617 618 619 620 621
static void nv_init_doorbell_index(struct amdgpu_device *adev)
{
	adev->doorbell_index.kiq = AMDGPU_NAVI10_DOORBELL_KIQ;
	adev->doorbell_index.mec_ring0 = AMDGPU_NAVI10_DOORBELL_MEC_RING0;
	adev->doorbell_index.mec_ring1 = AMDGPU_NAVI10_DOORBELL_MEC_RING1;
	adev->doorbell_index.mec_ring2 = AMDGPU_NAVI10_DOORBELL_MEC_RING2;
	adev->doorbell_index.mec_ring3 = AMDGPU_NAVI10_DOORBELL_MEC_RING3;
	adev->doorbell_index.mec_ring4 = AMDGPU_NAVI10_DOORBELL_MEC_RING4;
	adev->doorbell_index.mec_ring5 = AMDGPU_NAVI10_DOORBELL_MEC_RING5;
	adev->doorbell_index.mec_ring6 = AMDGPU_NAVI10_DOORBELL_MEC_RING6;
	adev->doorbell_index.mec_ring7 = AMDGPU_NAVI10_DOORBELL_MEC_RING7;
	adev->doorbell_index.userqueue_start = AMDGPU_NAVI10_DOORBELL_USERQUEUE_START;
	adev->doorbell_index.userqueue_end = AMDGPU_NAVI10_DOORBELL_USERQUEUE_END;
	adev->doorbell_index.gfx_ring0 = AMDGPU_NAVI10_DOORBELL_GFX_RING0;
	adev->doorbell_index.gfx_ring1 = AMDGPU_NAVI10_DOORBELL_GFX_RING1;
622 623 624 625
	adev->doorbell_index.gfx_userqueue_start =
		AMDGPU_NAVI10_DOORBELL_GFX_USERQUEUE_START;
	adev->doorbell_index.gfx_userqueue_end =
		AMDGPU_NAVI10_DOORBELL_GFX_USERQUEUE_END;
626 627
	adev->doorbell_index.mes_ring0 = AMDGPU_NAVI10_DOORBELL_MES_RING0;
	adev->doorbell_index.mes_ring1 = AMDGPU_NAVI10_DOORBELL_MES_RING1;
628 629
	adev->doorbell_index.sdma_engine[0] = AMDGPU_NAVI10_DOORBELL_sDMA_ENGINE0;
	adev->doorbell_index.sdma_engine[1] = AMDGPU_NAVI10_DOORBELL_sDMA_ENGINE1;
630 631
	adev->doorbell_index.sdma_engine[2] = AMDGPU_NAVI10_DOORBELL_sDMA_ENGINE2;
	adev->doorbell_index.sdma_engine[3] = AMDGPU_NAVI10_DOORBELL_sDMA_ENGINE3;
632 633 634 635 636 637 638 639 640 641 642 643
	adev->doorbell_index.ih = AMDGPU_NAVI10_DOORBELL_IH;
	adev->doorbell_index.vcn.vcn_ring0_1 = AMDGPU_NAVI10_DOORBELL64_VCN0_1;
	adev->doorbell_index.vcn.vcn_ring2_3 = AMDGPU_NAVI10_DOORBELL64_VCN2_3;
	adev->doorbell_index.vcn.vcn_ring4_5 = AMDGPU_NAVI10_DOORBELL64_VCN4_5;
	adev->doorbell_index.vcn.vcn_ring6_7 = AMDGPU_NAVI10_DOORBELL64_VCN6_7;
	adev->doorbell_index.first_non_cp = AMDGPU_NAVI10_DOORBELL64_FIRST_NON_CP;
	adev->doorbell_index.last_non_cp = AMDGPU_NAVI10_DOORBELL64_LAST_NON_CP;

	adev->doorbell_index.max_assignment = AMDGPU_NAVI10_DOORBELL_MAX_ASSIGNMENT << 1;
	adev->doorbell_index.sdma_doorbell_range = 20;
}

644 645 646 647
static void nv_pre_asic_init(struct amdgpu_device *adev)
{
}

648 649 650 651 652 653 654 655 656 657 658
static int nv_update_umd_stable_pstate(struct amdgpu_device *adev,
				       bool enter)
{
	if (enter)
		amdgpu_gfx_rlc_enter_safe_mode(adev);
	else
		amdgpu_gfx_rlc_exit_safe_mode(adev);

	if (adev->gfx.funcs->update_perfmon_mgcg)
		adev->gfx.funcs->update_perfmon_mgcg(adev, !enter);

659
	if (!(adev->flags & AMD_IS_APU) &&
660 661
	    (adev->nbio.funcs->enable_aspm) &&
	     amdgpu_device_should_use_aspm(adev))
662 663 664 665 666
		adev->nbio.funcs->enable_aspm(adev, !enter);

	return 0;
}

667 668 669
static const struct amdgpu_asic_funcs nv_asic_funcs =
{
	.read_disabled_bios = &nv_read_disabled_bios,
670
	.read_bios_from_rom = &amdgpu_soc15_read_bios_from_rom,
671 672
	.read_register = &nv_read_register,
	.reset = &nv_asic_reset,
673
	.reset_method = &nv_asic_reset_method,
674 675 676 677 678 679 680 681
	.set_vga_state = &nv_vga_set_state,
	.get_xclk = &nv_get_xclk,
	.set_uvd_clocks = &nv_set_uvd_clocks,
	.set_vce_clocks = &nv_set_vce_clocks,
	.get_config_memsize = &nv_get_config_memsize,
	.init_doorbell_index = &nv_init_doorbell_index,
	.need_full_reset = &nv_need_full_reset,
	.need_reset_on_init = &nv_need_reset_on_init,
682
	.get_pcie_replay_count = &nv_get_pcie_replay_count,
683
	.supports_baco = &amdgpu_dpm_is_baco_supported,
684
	.pre_asic_init = &nv_pre_asic_init,
685
	.update_umd_stable_pstate = &nv_update_umd_stable_pstate,
686
	.query_video_codecs = &nv_query_video_codecs,
687 688 689 690
};

static int nv_common_early_init(void *handle)
{
691
#define MMIO_REG_HOLE_OFFSET (0x80000 - PAGE_SIZE)
692 693
	struct amdgpu_device *adev = (struct amdgpu_device *)handle;

694 695 696 697
	if (!amdgpu_sriov_vf(adev)) {
		adev->rmmio_remap.reg_offset = MMIO_REG_HOLE_OFFSET;
		adev->rmmio_remap.bus_addr = adev->rmmio_base + MMIO_REG_HOLE_OFFSET;
	}
698 699
	adev->smc_rreg = NULL;
	adev->smc_wreg = NULL;
700 701 702 703
	adev->pcie_rreg = &amdgpu_device_indirect_rreg;
	adev->pcie_wreg = &amdgpu_device_indirect_wreg;
	adev->pcie_rreg64 = &amdgpu_device_indirect_rreg64;
	adev->pcie_wreg64 = &amdgpu_device_indirect_wreg64;
704 705
	adev->pciep_rreg = amdgpu_device_pcie_port_rreg;
	adev->pciep_wreg = amdgpu_device_pcie_port_wreg;
706 707 708 709 710 711 712 713 714 715 716 717

	/* TODO: will add them during VCN v2 implementation */
	adev->uvd_ctx_rreg = NULL;
	adev->uvd_ctx_wreg = NULL;

	adev->didt_rreg = &nv_didt_rreg;
	adev->didt_wreg = &nv_didt_wreg;

	adev->asic_funcs = &nv_asic_funcs;

	adev->rev_id = nv_get_rev_id(adev);
	adev->external_rev_id = 0xff;
718 719 720
	/* TODO: split the GC and PG flags based on the relevant IP version for which
	 * they are relevant.
	 */
721
	switch (adev->ip_versions[GC_HWIP][0]) {
722
	case IP_VERSION(10, 1, 10):
723 724 725 726 727 728 729 730 731 732 733 734
		adev->cg_flags = AMD_CG_SUPPORT_GFX_MGCG |
			AMD_CG_SUPPORT_GFX_CGCG |
			AMD_CG_SUPPORT_IH_CG |
			AMD_CG_SUPPORT_HDP_MGCG |
			AMD_CG_SUPPORT_HDP_LS |
			AMD_CG_SUPPORT_SDMA_MGCG |
			AMD_CG_SUPPORT_SDMA_LS |
			AMD_CG_SUPPORT_MC_MGCG |
			AMD_CG_SUPPORT_MC_LS |
			AMD_CG_SUPPORT_ATHUB_MGCG |
			AMD_CG_SUPPORT_ATHUB_LS |
			AMD_CG_SUPPORT_VCN_MGCG |
735
			AMD_CG_SUPPORT_JPEG_MGCG |
736 737
			AMD_CG_SUPPORT_BIF_MGCG |
			AMD_CG_SUPPORT_BIF_LS;
738
		adev->pg_flags = AMD_PG_SUPPORT_VCN |
739
			AMD_PG_SUPPORT_VCN_DPG |
740
			AMD_PG_SUPPORT_JPEG |
741
			AMD_PG_SUPPORT_ATHUB;
742 743
		adev->external_rev_id = adev->rev_id + 0x1;
		break;
744
	case IP_VERSION(10, 1, 1):
745 746 747 748 749 750 751 752 753 754 755 756
		adev->cg_flags = AMD_CG_SUPPORT_GFX_MGCG |
			AMD_CG_SUPPORT_GFX_CGCG |
			AMD_CG_SUPPORT_IH_CG |
			AMD_CG_SUPPORT_HDP_MGCG |
			AMD_CG_SUPPORT_HDP_LS |
			AMD_CG_SUPPORT_SDMA_MGCG |
			AMD_CG_SUPPORT_SDMA_LS |
			AMD_CG_SUPPORT_MC_MGCG |
			AMD_CG_SUPPORT_MC_LS |
			AMD_CG_SUPPORT_ATHUB_MGCG |
			AMD_CG_SUPPORT_ATHUB_LS |
			AMD_CG_SUPPORT_VCN_MGCG |
757
			AMD_CG_SUPPORT_JPEG_MGCG |
758 759
			AMD_CG_SUPPORT_BIF_MGCG |
			AMD_CG_SUPPORT_BIF_LS;
760
		adev->pg_flags = AMD_PG_SUPPORT_VCN |
761
			AMD_PG_SUPPORT_JPEG |
762
			AMD_PG_SUPPORT_VCN_DPG;
763
		adev->external_rev_id = adev->rev_id + 20;
764
		break;
765
	case IP_VERSION(10, 1, 2):
766 767 768 769
		adev->cg_flags = AMD_CG_SUPPORT_GFX_MGCG |
			AMD_CG_SUPPORT_GFX_MGLS |
			AMD_CG_SUPPORT_GFX_CGCG |
			AMD_CG_SUPPORT_GFX_CP_LS |
770
			AMD_CG_SUPPORT_GFX_RLC_LS |
771
			AMD_CG_SUPPORT_IH_CG |
772
			AMD_CG_SUPPORT_HDP_MGCG |
773 774
			AMD_CG_SUPPORT_HDP_LS |
			AMD_CG_SUPPORT_SDMA_MGCG |
775 776
			AMD_CG_SUPPORT_SDMA_LS |
			AMD_CG_SUPPORT_MC_MGCG |
777 778
			AMD_CG_SUPPORT_MC_LS |
			AMD_CG_SUPPORT_ATHUB_MGCG |
779
			AMD_CG_SUPPORT_ATHUB_LS |
780 781
			AMD_CG_SUPPORT_VCN_MGCG |
			AMD_CG_SUPPORT_JPEG_MGCG;
782
		adev->pg_flags = AMD_PG_SUPPORT_VCN |
783
			AMD_PG_SUPPORT_VCN_DPG |
784
			AMD_PG_SUPPORT_JPEG |
785
			AMD_PG_SUPPORT_ATHUB;
786 787 788 789 790 791
		/* guest vm gets 0xffffffff when reading RCC_DEV0_EPF0_STRAP0,
		 * as a consequence, the rev_id and external_rev_id are wrong.
		 * workaround it by hardcoding rev_id to 0 (default value).
		 */
		if (amdgpu_sriov_vf(adev))
			adev->rev_id = 0;
792 793
		adev->external_rev_id = adev->rev_id + 0xa;
		break;
794
	case IP_VERSION(10, 3, 0):
795 796
		adev->cg_flags = AMD_CG_SUPPORT_GFX_MGCG |
			AMD_CG_SUPPORT_GFX_CGCG |
Kenneth Feng's avatar
Kenneth Feng committed
797
			AMD_CG_SUPPORT_GFX_CGLS |
798
			AMD_CG_SUPPORT_GFX_3D_CGCG |
799
			AMD_CG_SUPPORT_MC_MGCG |
800
			AMD_CG_SUPPORT_VCN_MGCG |
801 802
			AMD_CG_SUPPORT_JPEG_MGCG |
			AMD_CG_SUPPORT_HDP_MGCG |
803
			AMD_CG_SUPPORT_HDP_LS |
804 805
			AMD_CG_SUPPORT_IH_CG |
			AMD_CG_SUPPORT_MC_LS;
806
		adev->pg_flags = AMD_PG_SUPPORT_VCN |
807
			AMD_PG_SUPPORT_VCN_DPG |
808
			AMD_PG_SUPPORT_JPEG |
809 810
			AMD_PG_SUPPORT_ATHUB |
			AMD_PG_SUPPORT_MMHUB;
811 812 813 814 815
		if (amdgpu_sriov_vf(adev)) {
			/* hypervisor control CG and PG enablement */
			adev->cg_flags = 0;
			adev->pg_flags = 0;
		}
816 817
		adev->external_rev_id = adev->rev_id + 0x28;
		break;
818
	case IP_VERSION(10, 3, 2):
819 820
		adev->cg_flags = AMD_CG_SUPPORT_GFX_MGCG |
			AMD_CG_SUPPORT_GFX_CGCG |
Kenneth Feng's avatar
Kenneth Feng committed
821
			AMD_CG_SUPPORT_GFX_CGLS |
822 823
			AMD_CG_SUPPORT_GFX_3D_CGCG |
			AMD_CG_SUPPORT_VCN_MGCG |
824 825
			AMD_CG_SUPPORT_JPEG_MGCG |
			AMD_CG_SUPPORT_MC_MGCG |
826 827
			AMD_CG_SUPPORT_MC_LS |
			AMD_CG_SUPPORT_HDP_MGCG |
828 829
			AMD_CG_SUPPORT_HDP_LS |
			AMD_CG_SUPPORT_IH_CG;
830
		adev->pg_flags = AMD_PG_SUPPORT_VCN |
831
			AMD_PG_SUPPORT_VCN_DPG |
832 833 834
			AMD_PG_SUPPORT_JPEG |
			AMD_PG_SUPPORT_ATHUB |
			AMD_PG_SUPPORT_MMHUB;
835 836
		adev->external_rev_id = adev->rev_id + 0x32;
		break;
837
	case IP_VERSION(10, 3, 1):
838 839 840 841 842
		adev->cg_flags = AMD_CG_SUPPORT_GFX_MGCG |
			AMD_CG_SUPPORT_GFX_MGLS |
			AMD_CG_SUPPORT_GFX_CP_LS |
			AMD_CG_SUPPORT_GFX_RLC_LS |
			AMD_CG_SUPPORT_GFX_CGCG |
843 844
			AMD_CG_SUPPORT_GFX_CGLS |
			AMD_CG_SUPPORT_GFX_3D_CGCG |
845
			AMD_CG_SUPPORT_GFX_3D_CGLS |
846 847
			AMD_CG_SUPPORT_MC_MGCG |
			AMD_CG_SUPPORT_MC_LS |
848
			AMD_CG_SUPPORT_GFX_FGCG |
849
			AMD_CG_SUPPORT_VCN_MGCG |
850
			AMD_CG_SUPPORT_SDMA_MGCG |
851
			AMD_CG_SUPPORT_SDMA_LS |
852 853 854 855 856
			AMD_CG_SUPPORT_JPEG_MGCG;
		adev->pg_flags = AMD_PG_SUPPORT_GFX_PG |
			AMD_PG_SUPPORT_VCN |
			AMD_PG_SUPPORT_VCN_DPG |
			AMD_PG_SUPPORT_JPEG;
857 858
		if (adev->apu_flags & AMD_APU_IS_VANGOGH)
			adev->external_rev_id = adev->rev_id + 0x01;
859
		break;
860
	case IP_VERSION(10, 3, 4):
861 862
		adev->cg_flags = AMD_CG_SUPPORT_GFX_MGCG |
			AMD_CG_SUPPORT_GFX_CGCG |
Kenneth Feng's avatar
Kenneth Feng committed
863
			AMD_CG_SUPPORT_GFX_CGLS |
864 865
			AMD_CG_SUPPORT_GFX_3D_CGCG |
			AMD_CG_SUPPORT_VCN_MGCG |
866 867
			AMD_CG_SUPPORT_JPEG_MGCG |
			AMD_CG_SUPPORT_MC_MGCG |
868 869
			AMD_CG_SUPPORT_MC_LS |
			AMD_CG_SUPPORT_HDP_MGCG |
870 871
			AMD_CG_SUPPORT_HDP_LS |
			AMD_CG_SUPPORT_IH_CG;
872
		adev->pg_flags = AMD_PG_SUPPORT_VCN |
873
			AMD_PG_SUPPORT_VCN_DPG |
874 875 876
			AMD_PG_SUPPORT_JPEG |
			AMD_PG_SUPPORT_ATHUB |
			AMD_PG_SUPPORT_MMHUB;
877 878
		adev->external_rev_id = adev->rev_id + 0x3c;
		break;
879
	case IP_VERSION(10, 3, 5):
880 881
		adev->cg_flags = AMD_CG_SUPPORT_GFX_MGCG |
			AMD_CG_SUPPORT_GFX_CGCG |
882
			AMD_CG_SUPPORT_GFX_CGLS |
883 884
			AMD_CG_SUPPORT_GFX_3D_CGCG |
			AMD_CG_SUPPORT_MC_MGCG |
885 886
			AMD_CG_SUPPORT_MC_LS |
			AMD_CG_SUPPORT_HDP_MGCG |
887
			AMD_CG_SUPPORT_HDP_LS |
888 889
			AMD_CG_SUPPORT_IH_CG |
			AMD_CG_SUPPORT_VCN_MGCG;
890
		adev->pg_flags = AMD_PG_SUPPORT_VCN |
891 892 893
			AMD_PG_SUPPORT_VCN_DPG |
			AMD_PG_SUPPORT_ATHUB |
			AMD_PG_SUPPORT_MMHUB;
894 895
		adev->external_rev_id = adev->rev_id + 0x46;
		break;
896
	case IP_VERSION(10, 3, 3):
897 898 899 900 901 902 903 904
		adev->cg_flags = AMD_CG_SUPPORT_GFX_MGCG |
			AMD_CG_SUPPORT_GFX_MGLS |
			AMD_CG_SUPPORT_GFX_CGCG |
			AMD_CG_SUPPORT_GFX_CGLS |
			AMD_CG_SUPPORT_GFX_3D_CGCG |
			AMD_CG_SUPPORT_GFX_3D_CGLS |
			AMD_CG_SUPPORT_GFX_RLC_LS |
			AMD_CG_SUPPORT_GFX_CP_LS |
905 906
			AMD_CG_SUPPORT_GFX_FGCG |
			AMD_CG_SUPPORT_MC_MGCG |
907
			AMD_CG_SUPPORT_MC_LS |
908 909
			AMD_CG_SUPPORT_SDMA_LS |
			AMD_CG_SUPPORT_HDP_MGCG |
910 911
			AMD_CG_SUPPORT_HDP_LS |
			AMD_CG_SUPPORT_ATHUB_MGCG |
912
			AMD_CG_SUPPORT_ATHUB_LS |
913 914 915
			AMD_CG_SUPPORT_IH_CG |
			AMD_CG_SUPPORT_VCN_MGCG |
			AMD_CG_SUPPORT_JPEG_MGCG;
916
		adev->pg_flags = AMD_PG_SUPPORT_GFX_PG |
917 918 919
			AMD_PG_SUPPORT_VCN |
			AMD_PG_SUPPORT_VCN_DPG |
			AMD_PG_SUPPORT_JPEG;
920
		if (adev->pdev->device == 0x1681)
921
			adev->external_rev_id = 0x20;
922 923
		else
			adev->external_rev_id = adev->rev_id + 0x01;
924
		break;
925
	case IP_VERSION(10, 1, 3):
926
	case IP_VERSION(10, 1, 4):
927 928 929 930
		adev->cg_flags = 0;
		adev->pg_flags = 0;
		adev->external_rev_id = adev->rev_id + 0x82;
		break;
931
	case IP_VERSION(10, 3, 6):
932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947
		adev->cg_flags = AMD_CG_SUPPORT_GFX_MGCG |
			AMD_CG_SUPPORT_GFX_MGLS |
			AMD_CG_SUPPORT_GFX_CGCG |
			AMD_CG_SUPPORT_GFX_CGLS |
			AMD_CG_SUPPORT_GFX_3D_CGCG |
			AMD_CG_SUPPORT_GFX_3D_CGLS |
			AMD_CG_SUPPORT_GFX_RLC_LS |
			AMD_CG_SUPPORT_GFX_CP_LS |
			AMD_CG_SUPPORT_GFX_FGCG |
			AMD_CG_SUPPORT_MC_MGCG |
			AMD_CG_SUPPORT_MC_LS |
			AMD_CG_SUPPORT_SDMA_LS |
			AMD_CG_SUPPORT_HDP_MGCG |
			AMD_CG_SUPPORT_HDP_LS |
			AMD_CG_SUPPORT_ATHUB_MGCG |
			AMD_CG_SUPPORT_ATHUB_LS |
948 949 950 951 952 953 954
			AMD_CG_SUPPORT_IH_CG |
			AMD_CG_SUPPORT_VCN_MGCG |
			AMD_CG_SUPPORT_JPEG_MGCG;
		adev->pg_flags = AMD_PG_SUPPORT_GFX_PG |
			AMD_PG_SUPPORT_VCN |
			AMD_PG_SUPPORT_VCN_DPG |
			AMD_PG_SUPPORT_JPEG;
955 956
		adev->external_rev_id = adev->rev_id + 0x01;
		break;
957
	case IP_VERSION(10, 3, 7):
958 959 960 961 962 963 964 965
		adev->cg_flags =  AMD_CG_SUPPORT_GFX_MGCG |
			AMD_CG_SUPPORT_GFX_MGLS |
			AMD_CG_SUPPORT_GFX_CGCG |
			AMD_CG_SUPPORT_GFX_CGLS |
			AMD_CG_SUPPORT_GFX_3D_CGCG |
			AMD_CG_SUPPORT_GFX_3D_CGLS |
			AMD_CG_SUPPORT_GFX_RLC_LS |
			AMD_CG_SUPPORT_GFX_CP_LS |
966 967 968 969 970 971 972 973 974 975 976
			AMD_CG_SUPPORT_GFX_FGCG |
			AMD_CG_SUPPORT_MC_MGCG |
			AMD_CG_SUPPORT_MC_LS |
			AMD_CG_SUPPORT_SDMA_LS |
			AMD_CG_SUPPORT_HDP_MGCG |
			AMD_CG_SUPPORT_HDP_LS |
			AMD_CG_SUPPORT_ATHUB_MGCG |
			AMD_CG_SUPPORT_ATHUB_LS |
			AMD_CG_SUPPORT_IH_CG |
			AMD_CG_SUPPORT_VCN_MGCG |
			AMD_CG_SUPPORT_JPEG_MGCG;
977 978
		adev->pg_flags = AMD_PG_SUPPORT_VCN |
			AMD_PG_SUPPORT_VCN_DPG |
979 980
			AMD_PG_SUPPORT_JPEG |
			AMD_PG_SUPPORT_GFX_PG;
981 982
		adev->external_rev_id = adev->rev_id + 0x01;
		break;
983 984 985 986 987
	default:
		/* FIXME: not supported yet */
		return -EINVAL;
	}

988 989 990 991 992
	if (adev->harvest_ip_mask & AMD_HARVEST_IP_VCN_MASK)
		adev->pg_flags &= ~(AMD_PG_SUPPORT_VCN |
				    AMD_PG_SUPPORT_VCN_DPG |
				    AMD_PG_SUPPORT_JPEG);

993 994 995 996 997
	if (amdgpu_sriov_vf(adev)) {
		amdgpu_virt_init_setting(adev);
		xgpu_nv_mailbox_set_irq_funcs(adev);
	}

998 999 1000 1001 1002
	return 0;
}

static int nv_common_late_init(void *handle)
{
1003 1004
	struct amdgpu_device *adev = (struct amdgpu_device *)handle;

1005
	if (amdgpu_sriov_vf(adev)) {
1006
		xgpu_nv_mailbox_get_irq(adev);
1007 1008 1009 1010 1011 1012 1013 1014 1015 1016
		if (adev->vcn.harvest_config & AMDGPU_VCN_HARVEST_VCN0) {
			amdgpu_virt_update_sriov_video_codec(adev,
							     sriov_sc_video_codecs_encode_array,
							     ARRAY_SIZE(sriov_sc_video_codecs_encode_array),
							     sriov_sc_video_codecs_decode_array_vcn1,
							     ARRAY_SIZE(sriov_sc_video_codecs_decode_array_vcn1));
		} else {
			amdgpu_virt_update_sriov_video_codec(adev,
							     sriov_sc_video_codecs_encode_array,
							     ARRAY_SIZE(sriov_sc_video_codecs_encode_array),
1017 1018
							     sriov_sc_video_codecs_decode_array_vcn0,
							     ARRAY_SIZE(sriov_sc_video_codecs_decode_array_vcn0));
1019
		}
1020
	}
1021

1022 1023 1024 1025 1026
	return 0;
}

static int nv_common_sw_init(void *handle)
{
1027 1028 1029 1030 1031
	struct amdgpu_device *adev = (struct amdgpu_device *)handle;

	if (amdgpu_sriov_vf(adev))
		xgpu_nv_mailbox_add_irq_id(adev);

1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043
	return 0;
}

static int nv_common_sw_fini(void *handle)
{
	return 0;
}

static int nv_common_hw_init(void *handle)
{
	struct amdgpu_device *adev = (struct amdgpu_device *)handle;

1044 1045 1046
	if (adev->nbio.funcs->apply_lc_spc_mode_wa)
		adev->nbio.funcs->apply_lc_spc_mode_wa(adev);

1047 1048 1049
	if (adev->nbio.funcs->apply_l1_link_width_reconfig_wa)
		adev->nbio.funcs->apply_l1_link_width_reconfig_wa(adev);

1050 1051 1052 1053 1054
	/* enable pcie gen2/3 link */
	nv_pcie_gen3_enable(adev);
	/* enable aspm */
	nv_program_aspm(adev);
	/* setup nbio registers */
1055
	adev->nbio.funcs->init_registers(adev);
1056 1057 1058 1059
	/* remap HDP registers to a hole in mmio space,
	 * for the purpose of expose those registers
	 * to process space
	 */
1060
	if (adev->nbio.funcs->remap_hdp_registers && !amdgpu_sriov_vf(adev))
1061
		adev->nbio.funcs->remap_hdp_registers(adev);
1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114
	/* enable the doorbell aperture */
	nv_enable_doorbell_aperture(adev, true);

	return 0;
}

static int nv_common_hw_fini(void *handle)
{
	struct amdgpu_device *adev = (struct amdgpu_device *)handle;

	/* disable the doorbell aperture */
	nv_enable_doorbell_aperture(adev, false);

	return 0;
}

static int nv_common_suspend(void *handle)
{
	struct amdgpu_device *adev = (struct amdgpu_device *)handle;

	return nv_common_hw_fini(adev);
}

static int nv_common_resume(void *handle)
{
	struct amdgpu_device *adev = (struct amdgpu_device *)handle;

	return nv_common_hw_init(adev);
}

static bool nv_common_is_idle(void *handle)
{
	return true;
}

static int nv_common_wait_for_idle(void *handle)
{
	return 0;
}

static int nv_common_soft_reset(void *handle)
{
	return 0;
}

static int nv_common_set_clockgating_state(void *handle,
					   enum amd_clockgating_state state)
{
	struct amdgpu_device *adev = (struct amdgpu_device *)handle;

	if (amdgpu_sriov_vf(adev))
		return 0;

1115
	switch (adev->ip_versions[NBIO_HWIP][0]) {
1116 1117 1118 1119 1120 1121 1122
	case IP_VERSION(2, 3, 0):
	case IP_VERSION(2, 3, 1):
	case IP_VERSION(2, 3, 2):
	case IP_VERSION(3, 3, 0):
	case IP_VERSION(3, 3, 1):
	case IP_VERSION(3, 3, 2):
	case IP_VERSION(3, 3, 3):
1123
		adev->nbio.funcs->update_medium_grain_clock_gating(adev,
1124
				state == AMD_CG_STATE_GATE);
1125
		adev->nbio.funcs->update_medium_grain_light_sleep(adev,
1126
				state == AMD_CG_STATE_GATE);
1127
		adev->hdp.funcs->update_clock_gating(adev,
1128
				state == AMD_CG_STATE_GATE);
1129 1130
		adev->smuio.funcs->update_rom_clock_gating(adev,
				state == AMD_CG_STATE_GATE);
1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144
		break;
	default:
		break;
	}
	return 0;
}

static int nv_common_set_powergating_state(void *handle,
					   enum amd_powergating_state state)
{
	/* TODO */
	return 0;
}

1145
static void nv_common_get_clockgating_state(void *handle, u64 *flags)
1146 1147 1148 1149 1150 1151
{
	struct amdgpu_device *adev = (struct amdgpu_device *)handle;

	if (amdgpu_sriov_vf(adev))
		*flags = 0;

1152
	adev->nbio.funcs->get_clockgating_state(adev, flags);
1153

1154
	adev->hdp.funcs->get_clock_gating_state(adev, flags);
1155

1156 1157
	adev->smuio.funcs->get_clock_gating_state(adev, flags);

1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177
	return;
}

static const struct amd_ip_funcs nv_common_ip_funcs = {
	.name = "nv_common",
	.early_init = nv_common_early_init,
	.late_init = nv_common_late_init,
	.sw_init = nv_common_sw_init,
	.sw_fini = nv_common_sw_fini,
	.hw_init = nv_common_hw_init,
	.hw_fini = nv_common_hw_fini,
	.suspend = nv_common_suspend,
	.resume = nv_common_resume,
	.is_idle = nv_common_is_idle,
	.wait_for_idle = nv_common_wait_for_idle,
	.soft_reset = nv_common_soft_reset,
	.set_clockgating_state = nv_common_set_clockgating_state,
	.set_powergating_state = nv_common_set_powergating_state,
	.get_clockgating_state = nv_common_get_clockgating_state,
};