mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2024-12-28 11:18:45 +07:00
drm/amdgpu: add helper function for indirect reg access (v3)
Add helper function in order to remove RREG32/WREG32 in current pcie_rreg/wreg function for soc15 and onwards adapters. PCIE_INDEX/DATA pairs are used to access regsiters outside of mmio bar in the helper functions. The new helper functions help remove the recursion of amdgpu_mm_rreg/wreg from pcie_rreg/wreg and provide the oppotunity to centralize direct and indirect access in a single function. v2: Fixed typo and refine the comments v3: Remove unnecessary volatile local variable Signed-off-by: Hawking Zhang <Hawking.Zhang@amd.com> Reviewed-by: Alex Deucher <alexander.deucher@amd.com> Reviewed-by: Kevin Wang <kevin1.wang@amd.com> Reviewed-by: Christian König <christian.koenig@amd.com> Reviewed-by: Guchun Chen <guchun.chen@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
parent
f2fa07b39f
commit
1bba36834c
@ -1032,6 +1032,19 @@ uint8_t amdgpu_mm_rreg8(struct amdgpu_device *adev, uint32_t offset);
|
||||
u32 amdgpu_io_rreg(struct amdgpu_device *adev, u32 reg);
|
||||
void amdgpu_io_wreg(struct amdgpu_device *adev, u32 reg, u32 v);
|
||||
|
||||
u32 amdgpu_device_indirect_rreg(struct amdgpu_device *adev,
|
||||
u32 pcie_index, u32 pcie_data,
|
||||
u32 reg_addr);
|
||||
u64 amdgpu_device_indirect_rreg64(struct amdgpu_device *adev,
|
||||
u32 pcie_index, u32 pcie_data,
|
||||
u32 reg_addr);
|
||||
void amdgpu_device_indirect_wreg(struct amdgpu_device *adev,
|
||||
u32 pcie_index, u32 pcie_data,
|
||||
u32 reg_addr, u32 reg_data);
|
||||
void amdgpu_device_indirect_wreg64(struct amdgpu_device *adev,
|
||||
u32 pcie_index, u32 pcie_data,
|
||||
u32 reg_addr, u64 reg_data);
|
||||
|
||||
bool amdgpu_device_asic_has_dc_support(enum amd_asic_type asic_type);
|
||||
bool amdgpu_device_has_dc_support(struct amdgpu_device *adev);
|
||||
|
||||
|
@ -592,6 +592,135 @@ void amdgpu_mm_wdoorbell64(struct amdgpu_device *adev, u32 index, u64 v)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* amdgpu_device_indirect_rreg - read an indirect register
|
||||
*
|
||||
* @adev: amdgpu_device pointer
|
||||
* @pcie_index: mmio register offset
|
||||
* @pcie_data: mmio register offset
|
||||
*
|
||||
* Returns the value of indirect register @reg_addr
|
||||
*/
|
||||
u32 amdgpu_device_indirect_rreg(struct amdgpu_device *adev,
|
||||
u32 pcie_index, u32 pcie_data,
|
||||
u32 reg_addr)
|
||||
{
|
||||
unsigned long flags;
|
||||
u32 r;
|
||||
void __iomem *pcie_index_offset;
|
||||
void __iomem *pcie_data_offset;
|
||||
|
||||
spin_lock_irqsave(&adev->pcie_idx_lock, flags);
|
||||
pcie_index_offset = (void __iomem *)adev->rmmio + pcie_index * 4;
|
||||
pcie_data_offset = (void __iomem *)adev->rmmio + pcie_data * 4;
|
||||
|
||||
writel(reg_addr, pcie_index_offset);
|
||||
readl(pcie_index_offset);
|
||||
r = readl(pcie_data_offset);
|
||||
spin_unlock_irqrestore(&adev->pcie_idx_lock, flags);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
/**
|
||||
* amdgpu_device_indirect_rreg64 - read a 64bits indirect register
|
||||
*
|
||||
* @adev: amdgpu_device pointer
|
||||
* @pcie_index: mmio register offset
|
||||
* @pcie_data: mmio register offset
|
||||
*
|
||||
* Returns the value of indirect register @reg_addr
|
||||
*/
|
||||
u64 amdgpu_device_indirect_rreg64(struct amdgpu_device *adev,
|
||||
u32 pcie_index, u32 pcie_data,
|
||||
u32 reg_addr)
|
||||
{
|
||||
unsigned long flags;
|
||||
u64 r;
|
||||
void __iomem *pcie_index_offset;
|
||||
void __iomem *pcie_data_offset;
|
||||
|
||||
spin_lock_irqsave(&adev->pcie_idx_lock, flags);
|
||||
pcie_index_offset = (void __iomem *)adev->rmmio + pcie_index * 4;
|
||||
pcie_data_offset = (void __iomem *)adev->rmmio + pcie_data * 4;
|
||||
|
||||
/* read low 32 bits */
|
||||
writel(reg_addr, pcie_index_offset);
|
||||
readl(pcie_index_offset);
|
||||
r = readl(pcie_data_offset);
|
||||
/* read high 32 bits */
|
||||
writel(reg_addr + 4, pcie_index_offset);
|
||||
readl(pcie_index_offset);
|
||||
r |= ((u64)readl(pcie_data_offset) << 32);
|
||||
spin_unlock_irqrestore(&adev->pcie_idx_lock, flags);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
/**
|
||||
* amdgpu_device_indirect_wreg - write an indirect register address
|
||||
*
|
||||
* @adev: amdgpu_device pointer
|
||||
* @pcie_index: mmio register offset
|
||||
* @pcie_data: mmio register offset
|
||||
* @reg_addr: indirect register offset
|
||||
* @reg_data: indirect register data
|
||||
*
|
||||
*/
|
||||
void amdgpu_device_indirect_wreg(struct amdgpu_device *adev,
|
||||
u32 pcie_index, u32 pcie_data,
|
||||
u32 reg_addr, u32 reg_data)
|
||||
{
|
||||
unsigned long flags;
|
||||
void __iomem *pcie_index_offset;
|
||||
void __iomem *pcie_data_offset;
|
||||
|
||||
spin_lock_irqsave(&adev->pcie_idx_lock, flags);
|
||||
pcie_index_offset = (void __iomem *)adev->rmmio + pcie_index * 4;
|
||||
pcie_data_offset = (void __iomem *)adev->rmmio + pcie_data * 4;
|
||||
|
||||
writel(reg_addr, pcie_index_offset);
|
||||
readl(pcie_index_offset);
|
||||
writel(reg_data, pcie_data_offset);
|
||||
readl(pcie_data_offset);
|
||||
spin_unlock_irqrestore(&adev->pcie_idx_lock, flags);
|
||||
}
|
||||
|
||||
/**
|
||||
* amdgpu_device_indirect_wreg64 - write a 64bits indirect register address
|
||||
*
|
||||
* @adev: amdgpu_device pointer
|
||||
* @pcie_index: mmio register offset
|
||||
* @pcie_data: mmio register offset
|
||||
* @reg_addr: indirect register offset
|
||||
* @reg_data: indirect register data
|
||||
*
|
||||
*/
|
||||
void amdgpu_device_indirect_wreg64(struct amdgpu_device *adev,
|
||||
u32 pcie_index, u32 pcie_data,
|
||||
u32 reg_addr, u64 reg_data)
|
||||
{
|
||||
unsigned long flags;
|
||||
void __iomem *pcie_index_offset;
|
||||
void __iomem *pcie_data_offset;
|
||||
|
||||
spin_lock_irqsave(&adev->pcie_idx_lock, flags);
|
||||
pcie_index_offset = (void __iomem *)adev->rmmio + pcie_index * 4;
|
||||
pcie_data_offset = (void __iomem *)adev->rmmio + pcie_data * 4;
|
||||
|
||||
/* write low 32 bits */
|
||||
writel(reg_addr, pcie_index_offset);
|
||||
readl(pcie_index_offset);
|
||||
writel((u32)(reg_data & 0xffffffffULL), pcie_data_offset);
|
||||
readl(pcie_data_offset);
|
||||
/* write high 32 bits */
|
||||
writel(reg_addr + 4, pcie_index_offset);
|
||||
readl(pcie_index_offset);
|
||||
writel((u32)(reg_data >> 32), pcie_data_offset);
|
||||
readl(pcie_data_offset);
|
||||
spin_unlock_irqrestore(&adev->pcie_idx_lock, flags);
|
||||
}
|
||||
|
||||
/**
|
||||
* amdgpu_invalid_rreg - dummy reg read function
|
||||
*
|
||||
|
Loading…
Reference in New Issue
Block a user