xref: /linux/drivers/gpu/drm/amd/amdgpu/amdgpu_ip.c (revision 20905edb2461d8dac1c03f28f6ad06e957f3b45c)
1*20905edbSLikun Gao /*
2*20905edbSLikun Gao  * Copyright 2025 Advanced Micro Devices, Inc.
3*20905edbSLikun Gao  *
4*20905edbSLikun Gao  * Permission is hereby granted, free of charge, to any person obtaining a
5*20905edbSLikun Gao  * copy of this software and associated documentation files (the "Software"),
6*20905edbSLikun Gao  * to deal in the Software without restriction, including without limitation
7*20905edbSLikun Gao  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8*20905edbSLikun Gao  * and/or sell copies of the Software, and to permit persons to whom the
9*20905edbSLikun Gao  * Software is furnished to do so, subject to the following conditions:
10*20905edbSLikun Gao  *
11*20905edbSLikun Gao  * The above copyright notice and this permission notice shall be included in
12*20905edbSLikun Gao  * all copies or substantial portions of the Software.
13*20905edbSLikun Gao  *
14*20905edbSLikun Gao  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15*20905edbSLikun Gao  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16*20905edbSLikun Gao  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
17*20905edbSLikun Gao  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18*20905edbSLikun Gao  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19*20905edbSLikun Gao  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20*20905edbSLikun Gao  * OTHER DEALINGS IN THE SOFTWARE.
21*20905edbSLikun Gao  *
22*20905edbSLikun Gao  */
23*20905edbSLikun Gao 
24*20905edbSLikun Gao #include "amdgpu.h"
25*20905edbSLikun Gao #include "amdgpu_ip.h"
26*20905edbSLikun Gao 
27*20905edbSLikun Gao static int8_t amdgpu_logical_to_dev_inst(struct amdgpu_device *adev,
28*20905edbSLikun Gao 					 enum amd_hw_ip_block_type block,
29*20905edbSLikun Gao 					 int8_t inst)
30*20905edbSLikun Gao {
31*20905edbSLikun Gao 	int8_t dev_inst;
32*20905edbSLikun Gao 
33*20905edbSLikun Gao 	switch (block) {
34*20905edbSLikun Gao 	case GC_HWIP:
35*20905edbSLikun Gao 	case SDMA0_HWIP:
36*20905edbSLikun Gao 	/* Both JPEG and VCN as JPEG is only alias of VCN */
37*20905edbSLikun Gao 	case VCN_HWIP:
38*20905edbSLikun Gao 		dev_inst = adev->ip_map.dev_inst[block][inst];
39*20905edbSLikun Gao 		break;
40*20905edbSLikun Gao 	default:
41*20905edbSLikun Gao 		/* For rest of the IPs, no look up required.
42*20905edbSLikun Gao 		 * Assume 'logical instance == physical instance' for all configs. */
43*20905edbSLikun Gao 		dev_inst = inst;
44*20905edbSLikun Gao 		break;
45*20905edbSLikun Gao 	}
46*20905edbSLikun Gao 
47*20905edbSLikun Gao 	return dev_inst;
48*20905edbSLikun Gao }
49*20905edbSLikun Gao 
50*20905edbSLikun Gao static uint32_t amdgpu_logical_to_dev_mask(struct amdgpu_device *adev,
51*20905edbSLikun Gao 					   enum amd_hw_ip_block_type block,
52*20905edbSLikun Gao 					   uint32_t mask)
53*20905edbSLikun Gao {
54*20905edbSLikun Gao 	uint32_t dev_mask = 0;
55*20905edbSLikun Gao 	int8_t log_inst, dev_inst;
56*20905edbSLikun Gao 
57*20905edbSLikun Gao 	while (mask) {
58*20905edbSLikun Gao 		log_inst = ffs(mask) - 1;
59*20905edbSLikun Gao 		dev_inst = amdgpu_logical_to_dev_inst(adev, block, log_inst);
60*20905edbSLikun Gao 		dev_mask |= (1 << dev_inst);
61*20905edbSLikun Gao 		mask &= ~(1 << log_inst);
62*20905edbSLikun Gao 	}
63*20905edbSLikun Gao 
64*20905edbSLikun Gao 	return dev_mask;
65*20905edbSLikun Gao }
66*20905edbSLikun Gao 
67*20905edbSLikun Gao static void amdgpu_populate_ip_map(struct amdgpu_device *adev,
68*20905edbSLikun Gao 				   enum amd_hw_ip_block_type ip_block,
69*20905edbSLikun Gao 				   uint32_t inst_mask)
70*20905edbSLikun Gao {
71*20905edbSLikun Gao 	int l = 0, i;
72*20905edbSLikun Gao 
73*20905edbSLikun Gao 	while (inst_mask) {
74*20905edbSLikun Gao 		i = ffs(inst_mask) - 1;
75*20905edbSLikun Gao 		adev->ip_map.dev_inst[ip_block][l++] = i;
76*20905edbSLikun Gao 		inst_mask &= ~(1 << i);
77*20905edbSLikun Gao 	}
78*20905edbSLikun Gao 	for (; l < HWIP_MAX_INSTANCE; l++)
79*20905edbSLikun Gao 		adev->ip_map.dev_inst[ip_block][l] = -1;
80*20905edbSLikun Gao }
81*20905edbSLikun Gao 
82*20905edbSLikun Gao void amdgpu_ip_map_init(struct amdgpu_device *adev)
83*20905edbSLikun Gao {
84*20905edbSLikun Gao 	u32 ip_map[][2] = {
85*20905edbSLikun Gao 		{ GC_HWIP, adev->gfx.xcc_mask },
86*20905edbSLikun Gao 		{ SDMA0_HWIP, adev->sdma.sdma_mask },
87*20905edbSLikun Gao 		{ VCN_HWIP, adev->vcn.inst_mask },
88*20905edbSLikun Gao 	};
89*20905edbSLikun Gao 	int i;
90*20905edbSLikun Gao 
91*20905edbSLikun Gao 	for (i = 0; i < ARRAY_SIZE(ip_map); ++i)
92*20905edbSLikun Gao 		amdgpu_populate_ip_map(adev, ip_map[i][0], ip_map[i][1]);
93*20905edbSLikun Gao 
94*20905edbSLikun Gao 	adev->ip_map.logical_to_dev_inst = amdgpu_logical_to_dev_inst;
95*20905edbSLikun Gao 	adev->ip_map.logical_to_dev_mask = amdgpu_logical_to_dev_mask;
96*20905edbSLikun Gao }
97