mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-08-23 16:36:56 -04:00
drm/amdgpu: Choose SOC15 RLC register read write functions at init time
Currently on every RLC register read the driver checks for three different conditions to decide which of the two register read/write functions to call. As these register operations are macros, which is required for register name expansion to work, the result is a significant explosion of generated (redundant) code which the compiler cannot optimise away. We however know that all of the three conditional are static and can therefore move the decision to driver init time. All that we need to do is define a new vfunc table for the SOC12 RLC read/write functions and just use them directly. Bloat-o-meter agrees the driver size savings are significant: add/remove: 11/35 grow/shrink: 82/1117 up/down: 53024/-450922 (-397898) ... Total: Before=10293928, After=9896030, chg -3.87% Signed-off-by: Tvrtko Ursulin <tvrtko.ursulin@igalia.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
committed by
Alex Deucher
parent
dbb0f5edcb
commit
6eadd448d7
@@ -3777,6 +3777,7 @@ int amdgpu_device_init(struct amdgpu_device *adev,
|
||||
|
||||
spin_lock_init(&adev->irq.lock);
|
||||
|
||||
amdgpu_early_init_rlc_reg_funcs(adev);
|
||||
amdgpu_device_init_apu_flags(adev);
|
||||
|
||||
r = amdgpu_device_check_arguments(adev);
|
||||
|
||||
@@ -583,3 +583,42 @@ int amdgpu_gfx_rlc_init_microcode(struct amdgpu_device *adev,
|
||||
amdgpu_gfx_rlc_init_microcode_v2_5(adev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct amdgpu_rlc_reg_funcs amdgpu_sriov_rlc_reg_funcs = {
|
||||
.rreg32 = amdgpu_sriov_rreg,
|
||||
.wreg32 = amdgpu_sriov_wreg,
|
||||
};
|
||||
|
||||
static u32
|
||||
amdgpu_rlc_rreg(struct amdgpu_device *adev, u32 reg, u32 acc_flags, u32 hwip,
|
||||
u32 xcc_id)
|
||||
{
|
||||
return amdgpu_device_rreg(adev, reg, 0);
|
||||
}
|
||||
|
||||
static void
|
||||
amdgpu_rlc_wreg(struct amdgpu_device *adev, u32 reg, u32 value, u32 acc_flags,
|
||||
u32 hwip, u32 xcc_id)
|
||||
{
|
||||
amdgpu_device_wreg(adev, reg, value, 0);
|
||||
}
|
||||
|
||||
static const struct amdgpu_rlc_reg_funcs amdgpu_rlc_reg_funcs = {
|
||||
.rreg32 = amdgpu_rlc_rreg,
|
||||
.wreg32 = amdgpu_rlc_wreg,
|
||||
};
|
||||
|
||||
void amdgpu_early_init_rlc_reg_funcs(struct amdgpu_device *adev)
|
||||
{
|
||||
adev->gfx.rlc.reg_funcs = &amdgpu_rlc_reg_funcs;
|
||||
}
|
||||
|
||||
void amdgpu_init_rlc_reg_funcs(struct amdgpu_device *adev)
|
||||
{
|
||||
if (amdgpu_sriov_vf(adev) &&
|
||||
adev->gfx.rlc.funcs &&
|
||||
adev->gfx.rlc.rlcg_reg_access_supported)
|
||||
adev->gfx.rlc.reg_funcs = &amdgpu_sriov_rlc_reg_funcs;
|
||||
else
|
||||
adev->gfx.rlc.reg_funcs = &amdgpu_rlc_reg_funcs;
|
||||
}
|
||||
|
||||
@@ -262,6 +262,11 @@ struct amdgpu_rlc_funcs {
|
||||
bool (*is_rlcg_access_range)(struct amdgpu_device *adev, uint32_t reg);
|
||||
};
|
||||
|
||||
struct amdgpu_rlc_reg_funcs {
|
||||
u32 (*rreg32)(struct amdgpu_device *adev, u32 reg, u32 acc_flags, u32 hwip, u32 xcc_id);
|
||||
void (*wreg32)(struct amdgpu_device *adev, u32 reg, u32 val, u32 acc_flags, u32 hwip, u32 xcc_id);
|
||||
};
|
||||
|
||||
struct amdgpu_rlcg_reg_access_ctrl {
|
||||
uint32_t scratch_reg0;
|
||||
uint32_t scratch_reg1;
|
||||
@@ -303,6 +308,7 @@ struct amdgpu_rlc {
|
||||
/* safe mode for updating CG/PG state */
|
||||
bool in_safe_mode[AMDGPU_MAX_RLC_INSTANCES];
|
||||
const struct amdgpu_rlc_funcs *funcs;
|
||||
const struct amdgpu_rlc_reg_funcs *reg_funcs;
|
||||
|
||||
/* for firmware data */
|
||||
u32 save_and_restore_offset;
|
||||
@@ -374,4 +380,8 @@ void amdgpu_gfx_rlc_fini(struct amdgpu_device *adev);
|
||||
int amdgpu_gfx_rlc_init_microcode(struct amdgpu_device *adev,
|
||||
uint16_t version_major,
|
||||
uint16_t version_minor);
|
||||
|
||||
void amdgpu_early_init_rlc_reg_funcs(struct amdgpu_device *adev);
|
||||
void amdgpu_init_rlc_reg_funcs(struct amdgpu_device *adev);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -7852,6 +7852,8 @@ static int gfx_v10_0_early_init(struct amdgpu_ip_block *ip_block)
|
||||
/* init rlcg reg access ctrl */
|
||||
gfx_v10_0_init_rlcg_reg_access_ctrl(adev);
|
||||
|
||||
amdgpu_init_rlc_reg_funcs(adev);
|
||||
|
||||
return gfx_v10_0_init_microcode(adev);
|
||||
}
|
||||
|
||||
|
||||
@@ -5411,6 +5411,8 @@ static int gfx_v11_0_early_init(struct amdgpu_ip_block *ip_block)
|
||||
|
||||
gfx_v11_0_init_rlcg_reg_access_ctrl(adev);
|
||||
|
||||
amdgpu_init_rlc_reg_funcs(adev);
|
||||
|
||||
return gfx_v11_0_init_microcode(adev);
|
||||
}
|
||||
|
||||
|
||||
@@ -3982,6 +3982,8 @@ static int gfx_v12_0_early_init(struct amdgpu_ip_block *ip_block)
|
||||
|
||||
gfx_v12_0_init_rlcg_reg_access_ctrl(adev);
|
||||
|
||||
amdgpu_init_rlc_reg_funcs(adev);
|
||||
|
||||
return gfx_v12_0_init_microcode(adev);
|
||||
}
|
||||
|
||||
|
||||
@@ -2997,6 +2997,8 @@ static int gfx_v12_1_early_init(struct amdgpu_ip_block *ip_block)
|
||||
|
||||
gfx_v12_1_init_rlcg_reg_access_ctrl(adev);
|
||||
|
||||
amdgpu_init_rlc_reg_funcs(adev);
|
||||
|
||||
return gfx_v12_1_init_microcode(adev);
|
||||
}
|
||||
|
||||
|
||||
@@ -4836,6 +4836,8 @@ static int gfx_v9_0_early_init(struct amdgpu_ip_block *ip_block)
|
||||
/* init rlcg reg access ctrl */
|
||||
gfx_v9_0_init_rlcg_reg_access_ctrl(adev);
|
||||
|
||||
amdgpu_init_rlc_reg_funcs(adev);
|
||||
|
||||
return gfx_v9_0_init_microcode(adev);
|
||||
}
|
||||
|
||||
|
||||
@@ -2623,6 +2623,8 @@ static int gfx_v9_4_3_early_init(struct amdgpu_ip_block *ip_block)
|
||||
/* init rlcg reg access ctrl */
|
||||
gfx_v9_4_3_init_rlcg_reg_access_ctrl(adev);
|
||||
|
||||
amdgpu_init_rlc_reg_funcs(adev);
|
||||
|
||||
return gfx_v9_4_3_init_microcode(adev);
|
||||
}
|
||||
|
||||
|
||||
@@ -38,14 +38,10 @@
|
||||
(adev->reg_offset[ip##_HWIP][inst][reg##_BASE_IDX] + (reg)+(offset))
|
||||
|
||||
#define __WREG32_SOC15_RLC__(reg, value, flag, hwip, inst) \
|
||||
((amdgpu_sriov_vf(adev) && adev->gfx.rlc.funcs && adev->gfx.rlc.rlcg_reg_access_supported) ? \
|
||||
amdgpu_sriov_wreg(adev, reg, value, flag, hwip, inst) : \
|
||||
WREG32(reg, value))
|
||||
adev->gfx.rlc.reg_funcs->wreg32(adev, reg, value, flag, hwip, inst)
|
||||
|
||||
#define __RREG32_SOC15_RLC__(reg, flag, hwip, inst) \
|
||||
((amdgpu_sriov_vf(adev) && adev->gfx.rlc.funcs && adev->gfx.rlc.rlcg_reg_access_supported) ? \
|
||||
amdgpu_sriov_rreg(adev, reg, flag, hwip, inst) : \
|
||||
RREG32(reg))
|
||||
adev->gfx.rlc.reg_funcs->rreg32(adev, reg, flag, hwip, inst)
|
||||
|
||||
#define WREG32_FIELD15(ip, idx, reg, field, val) \
|
||||
__WREG32_SOC15_RLC__(adev->reg_offset[ip##_HWIP][idx][mm##reg##_BASE_IDX] + mm##reg, \
|
||||
|
||||
Reference in New Issue
Block a user