From: Lijo Lazar Date: Mon, 8 Dec 2025 13:41:57 +0000 (+0530) Subject: drm/amdgpu: Add audio method to register block X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=72cc2e3011549d7b71e1d641c925ab6e9ff495d8;p=thirdparty%2Flinux.git drm/amdgpu: Add audio method to register block Move audio endpoint callbacks to register access block. Signed-off-by: Lijo Lazar Reviewed-by: Hawking Zhang Signed-off-by: Alex Deucher --- diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h index 5bd72261daae1..779bcec9bec73 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h @@ -914,10 +914,6 @@ struct amdgpu_device { amdgpu_wreg64_t pcie_wreg64; amdgpu_rreg64_ext_t pcie_rreg64_ext; amdgpu_wreg64_ext_t pcie_wreg64_ext; - /* protects concurrent ENDPOINT (audio) register access */ - spinlock_t audio_endpt_idx_lock; - amdgpu_block_rreg_t audio_endpt_rreg; - amdgpu_block_wreg_t audio_endpt_wreg; struct amdgpu_doorbell doorbell; /* clock/pll info */ @@ -1332,8 +1328,10 @@ int emu_soc_asic_init(struct amdgpu_device *adev); #define WREG32_GC_CAC(reg, v) amdgpu_reg_gc_cac_wr32(adev, (reg), (v)) #define RREG32_SE_CAC(reg) amdgpu_reg_se_cac_rd32(adev, (reg)) #define WREG32_SE_CAC(reg, v) amdgpu_reg_se_cac_wr32(adev, (reg), (v)) -#define RREG32_AUDIO_ENDPT(block, reg) adev->audio_endpt_rreg(adev, (block), (reg)) -#define WREG32_AUDIO_ENDPT(block, reg, v) adev->audio_endpt_wreg(adev, (block), (reg), (v)) +#define RREG32_AUDIO_ENDPT(block, reg) \ + amdgpu_reg_audio_endpt_rd32(adev, (block), (reg)) +#define WREG32_AUDIO_ENDPT(block, reg, v) \ + amdgpu_reg_audio_endpt_wr32(adev, (block), (reg), (v)) #define WREG32_P(reg, val, mask) \ do { \ uint32_t tmp_ = RREG32(reg); \ diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c index 3872b81cbcb51..be79a277f7e10 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c @@ -959,48 +959,6 @@ static void amdgpu_invalid_wreg64_ext(struct amdgpu_device *adev, uint64_t reg, BUG(); } -/** - * amdgpu_block_invalid_rreg - dummy reg read function - * - * @adev: amdgpu_device pointer - * @block: offset of instance - * @reg: offset of register - * - * Dummy register read function. Used for register blocks - * that certain asics don't have (all asics). - * Returns the value in the register. - */ -static uint32_t amdgpu_block_invalid_rreg(struct amdgpu_device *adev, - uint32_t block, uint32_t reg) -{ - dev_err(adev->dev, - "Invalid callback to read register 0x%04X in block 0x%04X\n", - reg, block); - BUG(); - return 0; -} - -/** - * amdgpu_block_invalid_wreg - dummy reg write function - * - * @adev: amdgpu_device pointer - * @block: offset of instance - * @reg: offset of register - * @v: value to write to the register - * - * Dummy register read function. Used for register blocks - * that certain asics don't have (all asics). - */ -static void amdgpu_block_invalid_wreg(struct amdgpu_device *adev, - uint32_t block, - uint32_t reg, uint32_t v) -{ - dev_err(adev->dev, - "Invalid block callback to write register 0x%04X in block 0x%04X with 0x%08X\n", - reg, block, v); - BUG(); -} - static uint32_t amdgpu_device_get_vbios_flags(struct amdgpu_device *adev) { if (hweight32(adev->aid_mask) && (adev->flags & AMD_IS_APU)) @@ -3842,8 +3800,6 @@ int amdgpu_device_init(struct amdgpu_device *adev, adev->pcie_wreg64 = &amdgpu_invalid_wreg64; adev->pcie_rreg64_ext = &amdgpu_invalid_rreg64_ext; adev->pcie_wreg64_ext = &amdgpu_invalid_wreg64_ext; - adev->audio_endpt_rreg = &amdgpu_block_invalid_rreg; - adev->audio_endpt_wreg = &amdgpu_block_invalid_wreg; dev_info( adev->dev, @@ -3889,7 +3845,6 @@ int amdgpu_device_init(struct amdgpu_device *adev, spin_lock_init(&adev->mmio_idx_lock); spin_lock_init(&adev->pcie_idx_lock); - spin_lock_init(&adev->audio_endpt_idx_lock); spin_lock_init(&adev->mm_stats.lock); spin_lock_init(&adev->virt.rlcg_reg_lock); spin_lock_init(&adev->wb.lock); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_reg_access.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_reg_access.c index d75ef23581a05..563b155b15c6e 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_reg_access.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_reg_access.c @@ -54,6 +54,10 @@ void amdgpu_reg_access_init(struct amdgpu_device *adev) spin_lock_init(&adev->reg.se_cac.lock); adev->reg.se_cac.rreg = NULL; adev->reg.se_cac.wreg = NULL; + + spin_lock_init(&adev->reg.audio_endpt.lock); + adev->reg.audio_endpt.rreg = NULL; + adev->reg.audio_endpt.wreg = NULL; } uint32_t amdgpu_reg_smc_rd32(struct amdgpu_device *adev, uint32_t reg) @@ -153,6 +157,28 @@ void amdgpu_reg_se_cac_wr32(struct amdgpu_device *adev, uint32_t reg, adev->reg.se_cac.wreg(adev, reg, v); } +uint32_t amdgpu_reg_audio_endpt_rd32(struct amdgpu_device *adev, uint32_t block, + uint32_t reg) +{ + if (!adev->reg.audio_endpt.rreg) { + dev_err_once(adev->dev, + "AUDIO_ENDPT register read not supported\n"); + return 0; + } + return adev->reg.audio_endpt.rreg(adev, block, reg); +} + +void amdgpu_reg_audio_endpt_wr32(struct amdgpu_device *adev, uint32_t block, + uint32_t reg, uint32_t v) +{ + if (!adev->reg.audio_endpt.wreg) { + dev_err_once(adev->dev, + "AUDIO_ENDPT register write not supported\n"); + return; + } + adev->reg.audio_endpt.wreg(adev, block, reg, v); +} + /* * register access helper functions. */ diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_reg_access.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_reg_access.h index 63929999cd76a..e19b7a5319063 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_reg_access.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_reg_access.h @@ -32,18 +32,30 @@ struct amdgpu_device; typedef uint32_t (*amdgpu_rreg_t)(struct amdgpu_device *, uint32_t); typedef void (*amdgpu_wreg_t)(struct amdgpu_device *, uint32_t, uint32_t); +typedef uint32_t (*amdgpu_block_rreg_t)(struct amdgpu_device *, uint32_t, + uint32_t); +typedef void (*amdgpu_block_wreg_t)(struct amdgpu_device *, uint32_t, uint32_t, + uint32_t); + struct amdgpu_reg_ind { spinlock_t lock; amdgpu_rreg_t rreg; amdgpu_wreg_t wreg; }; +struct amdgpu_reg_ind_blk { + spinlock_t lock; + amdgpu_block_rreg_t rreg; + amdgpu_block_wreg_t wreg; +}; + struct amdgpu_reg_access { struct amdgpu_reg_ind smc; struct amdgpu_reg_ind uvd_ctx; struct amdgpu_reg_ind didt; struct amdgpu_reg_ind gc_cac; struct amdgpu_reg_ind se_cac; + struct amdgpu_reg_ind_blk audio_endpt; }; void amdgpu_reg_access_init(struct amdgpu_device *adev); @@ -59,6 +71,10 @@ void amdgpu_reg_gc_cac_wr32(struct amdgpu_device *adev, uint32_t reg, uint32_t amdgpu_reg_se_cac_rd32(struct amdgpu_device *adev, uint32_t reg); void amdgpu_reg_se_cac_wr32(struct amdgpu_device *adev, uint32_t reg, uint32_t v); +uint32_t amdgpu_reg_audio_endpt_rd32(struct amdgpu_device *adev, uint32_t block, + uint32_t reg); +void amdgpu_reg_audio_endpt_wr32(struct amdgpu_device *adev, uint32_t block, + uint32_t reg, uint32_t v); typedef uint32_t (*amdgpu_rreg_ext_t)(struct amdgpu_device *, uint64_t); typedef void (*amdgpu_wreg_ext_t)(struct amdgpu_device *, uint64_t, uint32_t); @@ -69,11 +85,6 @@ typedef void (*amdgpu_wreg64_t)(struct amdgpu_device *, uint32_t, uint64_t); typedef uint64_t (*amdgpu_rreg64_ext_t)(struct amdgpu_device *, uint64_t); typedef void (*amdgpu_wreg64_ext_t)(struct amdgpu_device *, uint64_t, uint64_t); -typedef uint32_t (*amdgpu_block_rreg_t)(struct amdgpu_device *, uint32_t, - uint32_t); -typedef void (*amdgpu_block_wreg_t)(struct amdgpu_device *, uint32_t, uint32_t, - uint32_t); - uint32_t amdgpu_device_rreg(struct amdgpu_device *adev, uint32_t reg, uint32_t acc_flags); uint32_t amdgpu_device_xcc_rreg(struct amdgpu_device *adev, uint32_t reg, diff --git a/drivers/gpu/drm/amd/amdgpu/dce_v10_0.c b/drivers/gpu/drm/amd/amdgpu/dce_v10_0.c index a7ffe10eea1b4..f1052acea5ecc 100644 --- a/drivers/gpu/drm/amd/amdgpu/dce_v10_0.c +++ b/drivers/gpu/drm/amd/amdgpu/dce_v10_0.c @@ -175,10 +175,10 @@ static u32 dce_v10_0_audio_endpt_rreg(struct amdgpu_device *adev, unsigned long flags; u32 r; - spin_lock_irqsave(&adev->audio_endpt_idx_lock, flags); + spin_lock_irqsave(&adev->reg.audio_endpt.lock, flags); WREG32(mmAZALIA_F0_CODEC_ENDPOINT_INDEX + block_offset, reg); r = RREG32(mmAZALIA_F0_CODEC_ENDPOINT_DATA + block_offset); - spin_unlock_irqrestore(&adev->audio_endpt_idx_lock, flags); + spin_unlock_irqrestore(&adev->reg.audio_endpt.lock, flags); return r; } @@ -188,10 +188,10 @@ static void dce_v10_0_audio_endpt_wreg(struct amdgpu_device *adev, { unsigned long flags; - spin_lock_irqsave(&adev->audio_endpt_idx_lock, flags); + spin_lock_irqsave(&adev->reg.audio_endpt.lock, flags); WREG32(mmAZALIA_F0_CODEC_ENDPOINT_INDEX + block_offset, reg); WREG32(mmAZALIA_F0_CODEC_ENDPOINT_DATA + block_offset, v); - spin_unlock_irqrestore(&adev->audio_endpt_idx_lock, flags); + spin_unlock_irqrestore(&adev->reg.audio_endpt.lock, flags); } static u32 dce_v10_0_vblank_get_counter(struct amdgpu_device *adev, int crtc) @@ -2750,8 +2750,8 @@ static int dce_v10_0_early_init(struct amdgpu_ip_block *ip_block) { struct amdgpu_device *adev = ip_block->adev; - adev->audio_endpt_rreg = &dce_v10_0_audio_endpt_rreg; - adev->audio_endpt_wreg = &dce_v10_0_audio_endpt_wreg; + adev->reg.audio_endpt.rreg = &dce_v10_0_audio_endpt_rreg; + adev->reg.audio_endpt.wreg = &dce_v10_0_audio_endpt_wreg; dce_v10_0_set_display_funcs(adev); diff --git a/drivers/gpu/drm/amd/amdgpu/dce_v6_0.c b/drivers/gpu/drm/amd/amdgpu/dce_v6_0.c index a72e20db5363b..c153a6e1e22a9 100644 --- a/drivers/gpu/drm/amd/amdgpu/dce_v6_0.c +++ b/drivers/gpu/drm/amd/amdgpu/dce_v6_0.c @@ -138,10 +138,10 @@ static u32 dce_v6_0_audio_endpt_rreg(struct amdgpu_device *adev, unsigned long flags; u32 r; - spin_lock_irqsave(&adev->audio_endpt_idx_lock, flags); + spin_lock_irqsave(&adev->reg.audio_endpt.lock, flags); WREG32(mmAZALIA_F0_CODEC_ENDPOINT_INDEX + block_offset, reg); r = RREG32(mmAZALIA_F0_CODEC_ENDPOINT_DATA + block_offset); - spin_unlock_irqrestore(&adev->audio_endpt_idx_lock, flags); + spin_unlock_irqrestore(&adev->reg.audio_endpt.lock, flags); return r; } @@ -151,11 +151,11 @@ static void dce_v6_0_audio_endpt_wreg(struct amdgpu_device *adev, { unsigned long flags; - spin_lock_irqsave(&adev->audio_endpt_idx_lock, flags); + spin_lock_irqsave(&adev->reg.audio_endpt.lock, flags); WREG32(mmAZALIA_F0_CODEC_ENDPOINT_INDEX + block_offset, reg | AZALIA_F0_CODEC_ENDPOINT_INDEX__AZALIA_ENDPOINT_REG_WRITE_EN_MASK); WREG32(mmAZALIA_F0_CODEC_ENDPOINT_DATA + block_offset, v); - spin_unlock_irqrestore(&adev->audio_endpt_idx_lock, flags); + spin_unlock_irqrestore(&adev->reg.audio_endpt.lock, flags); } static u32 dce_v6_0_vblank_get_counter(struct amdgpu_device *adev, int crtc) @@ -2697,8 +2697,8 @@ static int dce_v6_0_early_init(struct amdgpu_ip_block *ip_block) { struct amdgpu_device *adev = ip_block->adev; - adev->audio_endpt_rreg = &dce_v6_0_audio_endpt_rreg; - adev->audio_endpt_wreg = &dce_v6_0_audio_endpt_wreg; + adev->reg.audio_endpt.rreg = &dce_v6_0_audio_endpt_rreg; + adev->reg.audio_endpt.wreg = &dce_v6_0_audio_endpt_wreg; dce_v6_0_set_display_funcs(adev); diff --git a/drivers/gpu/drm/amd/amdgpu/dce_v8_0.c b/drivers/gpu/drm/amd/amdgpu/dce_v8_0.c index 4221c7b7c5060..a85a9e32fde48 100644 --- a/drivers/gpu/drm/amd/amdgpu/dce_v8_0.c +++ b/drivers/gpu/drm/amd/amdgpu/dce_v8_0.c @@ -126,10 +126,10 @@ static u32 dce_v8_0_audio_endpt_rreg(struct amdgpu_device *adev, unsigned long flags; u32 r; - spin_lock_irqsave(&adev->audio_endpt_idx_lock, flags); + spin_lock_irqsave(&adev->reg.audio_endpt.lock, flags); WREG32(mmAZALIA_F0_CODEC_ENDPOINT_INDEX + block_offset, reg); r = RREG32(mmAZALIA_F0_CODEC_ENDPOINT_DATA + block_offset); - spin_unlock_irqrestore(&adev->audio_endpt_idx_lock, flags); + spin_unlock_irqrestore(&adev->reg.audio_endpt.lock, flags); return r; } @@ -139,10 +139,10 @@ static void dce_v8_0_audio_endpt_wreg(struct amdgpu_device *adev, { unsigned long flags; - spin_lock_irqsave(&adev->audio_endpt_idx_lock, flags); + spin_lock_irqsave(&adev->reg.audio_endpt.lock, flags); WREG32(mmAZALIA_F0_CODEC_ENDPOINT_INDEX + block_offset, reg); WREG32(mmAZALIA_F0_CODEC_ENDPOINT_DATA + block_offset, v); - spin_unlock_irqrestore(&adev->audio_endpt_idx_lock, flags); + spin_unlock_irqrestore(&adev->reg.audio_endpt.lock, flags); } static u32 dce_v8_0_vblank_get_counter(struct amdgpu_device *adev, int crtc) @@ -2655,8 +2655,8 @@ static int dce_v8_0_early_init(struct amdgpu_ip_block *ip_block) { struct amdgpu_device *adev = ip_block->adev; - adev->audio_endpt_rreg = &dce_v8_0_audio_endpt_rreg; - adev->audio_endpt_wreg = &dce_v8_0_audio_endpt_wreg; + adev->reg.audio_endpt.rreg = &dce_v8_0_audio_endpt_rreg; + adev->reg.audio_endpt.wreg = &dce_v8_0_audio_endpt_wreg; dce_v8_0_set_display_funcs(adev); diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c index 64aa5091fade9..92f5c0b4d511f 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -5968,8 +5968,8 @@ static int dm_early_init(struct amdgpu_ip_block *ip_block) adev->mode_info.funcs = &dm_display_funcs; /* - * Note: Do NOT change adev->audio_endpt_rreg and - * adev->audio_endpt_wreg because they are initialised in + * Note: Do NOT change adev->reg.audio_endpt.rreg and + * adev->reg.audio_endpt.wreg because they are initialised in * amdgpu_device_init() */ #if defined(CONFIG_DEBUG_KERNEL_DC)