drm/amdgpu: Add RREG64_PCIE_EXT/WREG64_PCIE_EXT functions
Add 64bits register access support on register whose address is greater than 32bits. Signed-off-by: Candice Li <candice.li@amd.com> Reviewed-by: Tao Zhou <tao.zhou1@amd.com> Reviewed-by: Hawking Zhang <Hawking.Zhang@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
parent
9b70a1d414
commit
a76b2870bd
|
@ -626,6 +626,9 @@ typedef void (*amdgpu_wreg_ext_t)(struct amdgpu_device*, uint64_t, uint32_t);
|
|||
typedef uint64_t (*amdgpu_rreg64_t)(struct amdgpu_device*, uint32_t);
|
||||
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);
|
||||
|
||||
|
@ -830,6 +833,8 @@ struct amdgpu_device {
|
|||
amdgpu_wreg_ext_t pcie_wreg_ext;
|
||||
amdgpu_rreg64_t pcie_rreg64;
|
||||
amdgpu_wreg64_t pcie_wreg64;
|
||||
amdgpu_rreg64_ext_t pcie_rreg64_ext;
|
||||
amdgpu_wreg64_ext_t pcie_wreg64_ext;
|
||||
/* protects concurrent UVD register access */
|
||||
spinlock_t uvd_ctx_idx_lock;
|
||||
amdgpu_rreg_t uvd_ctx_rreg;
|
||||
|
@ -1145,10 +1150,14 @@ u32 amdgpu_device_indirect_rreg(struct amdgpu_device *adev,
|
|||
u32 reg_addr);
|
||||
u64 amdgpu_device_indirect_rreg64(struct amdgpu_device *adev,
|
||||
u32 reg_addr);
|
||||
u64 amdgpu_device_indirect_rreg64_ext(struct amdgpu_device *adev,
|
||||
u64 reg_addr);
|
||||
void amdgpu_device_indirect_wreg(struct amdgpu_device *adev,
|
||||
u32 reg_addr, u32 reg_data);
|
||||
void amdgpu_device_indirect_wreg64(struct amdgpu_device *adev,
|
||||
u32 reg_addr, u64 reg_data);
|
||||
void amdgpu_device_indirect_wreg64_ext(struct amdgpu_device *adev,
|
||||
u64 reg_addr, u64 reg_data);
|
||||
u32 amdgpu_device_get_rev_id(struct amdgpu_device *adev);
|
||||
bool amdgpu_device_asic_has_dc_support(enum amd_asic_type asic_type);
|
||||
bool amdgpu_device_has_dc_support(struct amdgpu_device *adev);
|
||||
|
@ -1191,6 +1200,8 @@ int emu_soc_asic_init(struct amdgpu_device *adev);
|
|||
#define WREG32_PCIE_EXT(reg, v) adev->pcie_wreg_ext(adev, (reg), (v))
|
||||
#define RREG64_PCIE(reg) adev->pcie_rreg64(adev, (reg))
|
||||
#define WREG64_PCIE(reg, v) adev->pcie_wreg64(adev, (reg), (v))
|
||||
#define RREG64_PCIE_EXT(reg) adev->pcie_rreg64_ext(adev, (reg))
|
||||
#define WREG64_PCIE_EXT(reg, v) adev->pcie_wreg64_ext(adev, (reg), (v))
|
||||
#define RREG32_SMC(reg) adev->smc_rreg(adev, (reg))
|
||||
#define WREG32_SMC(reg, v) adev->smc_wreg(adev, (reg), (v))
|
||||
#define RREG32_UVD_CTX(reg) adev->uvd_ctx_rreg(adev, (reg))
|
||||
|
|
|
@ -639,6 +639,56 @@ u64 amdgpu_device_indirect_rreg64(struct amdgpu_device *adev,
|
|||
return r;
|
||||
}
|
||||
|
||||
u64 amdgpu_device_indirect_rreg64_ext(struct amdgpu_device *adev,
|
||||
u64 reg_addr)
|
||||
{
|
||||
unsigned long flags, pcie_index, pcie_data;
|
||||
unsigned long pcie_index_hi = 0;
|
||||
void __iomem *pcie_index_offset;
|
||||
void __iomem *pcie_index_hi_offset;
|
||||
void __iomem *pcie_data_offset;
|
||||
u64 r;
|
||||
|
||||
pcie_index = adev->nbio.funcs->get_pcie_index_offset(adev);
|
||||
pcie_data = adev->nbio.funcs->get_pcie_data_offset(adev);
|
||||
if ((reg_addr >> 32) && (adev->nbio.funcs->get_pcie_index_hi_offset))
|
||||
pcie_index_hi = adev->nbio.funcs->get_pcie_index_hi_offset(adev);
|
||||
|
||||
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;
|
||||
if (pcie_index_hi != 0)
|
||||
pcie_index_hi_offset = (void __iomem *)adev->rmmio +
|
||||
pcie_index_hi * 4;
|
||||
|
||||
/* read low 32 bits */
|
||||
writel(reg_addr, pcie_index_offset);
|
||||
readl(pcie_index_offset);
|
||||
if (pcie_index_hi != 0) {
|
||||
writel((reg_addr >> 32) & 0xff, pcie_index_hi_offset);
|
||||
readl(pcie_index_hi_offset);
|
||||
}
|
||||
r = readl(pcie_data_offset);
|
||||
/* read high 32 bits */
|
||||
writel(reg_addr + 4, pcie_index_offset);
|
||||
readl(pcie_index_offset);
|
||||
if (pcie_index_hi != 0) {
|
||||
writel((reg_addr >> 32) & 0xff, pcie_index_hi_offset);
|
||||
readl(pcie_index_hi_offset);
|
||||
}
|
||||
r |= ((u64)readl(pcie_data_offset) << 32);
|
||||
|
||||
/* clear the high bits */
|
||||
if (pcie_index_hi != 0) {
|
||||
writel(0, pcie_index_hi_offset);
|
||||
readl(pcie_index_hi_offset);
|
||||
}
|
||||
|
||||
spin_unlock_irqrestore(&adev->pcie_idx_lock, flags);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
/**
|
||||
* amdgpu_device_indirect_wreg - write an indirect register address
|
||||
*
|
||||
|
@ -743,6 +793,55 @@ void amdgpu_device_indirect_wreg64(struct amdgpu_device *adev,
|
|||
spin_unlock_irqrestore(&adev->pcie_idx_lock, flags);
|
||||
}
|
||||
|
||||
void amdgpu_device_indirect_wreg64_ext(struct amdgpu_device *adev,
|
||||
u64 reg_addr, u64 reg_data)
|
||||
{
|
||||
unsigned long flags, pcie_index, pcie_data;
|
||||
unsigned long pcie_index_hi = 0;
|
||||
void __iomem *pcie_index_offset;
|
||||
void __iomem *pcie_index_hi_offset;
|
||||
void __iomem *pcie_data_offset;
|
||||
|
||||
pcie_index = adev->nbio.funcs->get_pcie_index_offset(adev);
|
||||
pcie_data = adev->nbio.funcs->get_pcie_data_offset(adev);
|
||||
if ((reg_addr >> 32) && (adev->nbio.funcs->get_pcie_index_hi_offset))
|
||||
pcie_index_hi = adev->nbio.funcs->get_pcie_index_hi_offset(adev);
|
||||
|
||||
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;
|
||||
if (pcie_index_hi != 0)
|
||||
pcie_index_hi_offset = (void __iomem *)adev->rmmio +
|
||||
pcie_index_hi * 4;
|
||||
|
||||
/* write low 32 bits */
|
||||
writel(reg_addr, pcie_index_offset);
|
||||
readl(pcie_index_offset);
|
||||
if (pcie_index_hi != 0) {
|
||||
writel((reg_addr >> 32) & 0xff, pcie_index_hi_offset);
|
||||
readl(pcie_index_hi_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);
|
||||
if (pcie_index_hi != 0) {
|
||||
writel((reg_addr >> 32) & 0xff, pcie_index_hi_offset);
|
||||
readl(pcie_index_hi_offset);
|
||||
}
|
||||
writel((u32)(reg_data >> 32), pcie_data_offset);
|
||||
readl(pcie_data_offset);
|
||||
|
||||
/* clear the high bits */
|
||||
if (pcie_index_hi != 0) {
|
||||
writel(0, pcie_index_hi_offset);
|
||||
readl(pcie_index_hi_offset);
|
||||
}
|
||||
|
||||
spin_unlock_irqrestore(&adev->pcie_idx_lock, flags);
|
||||
}
|
||||
|
||||
/**
|
||||
* amdgpu_device_get_rev_id - query device rev_id
|
||||
*
|
||||
|
@ -820,6 +919,13 @@ static uint64_t amdgpu_invalid_rreg64(struct amdgpu_device *adev, uint32_t reg)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static uint64_t amdgpu_invalid_rreg64_ext(struct amdgpu_device *adev, uint64_t reg)
|
||||
{
|
||||
DRM_ERROR("Invalid callback to read register 0x%llX\n", reg);
|
||||
BUG();
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* amdgpu_invalid_wreg64 - dummy reg write function
|
||||
*
|
||||
|
@ -837,6 +943,13 @@ static void amdgpu_invalid_wreg64(struct amdgpu_device *adev, uint32_t reg, uint
|
|||
BUG();
|
||||
}
|
||||
|
||||
static void amdgpu_invalid_wreg64_ext(struct amdgpu_device *adev, uint64_t reg, uint64_t v)
|
||||
{
|
||||
DRM_ERROR("Invalid callback to write 64 bit register 0x%llX with 0x%08llX\n",
|
||||
reg, v);
|
||||
BUG();
|
||||
}
|
||||
|
||||
/**
|
||||
* amdgpu_block_invalid_rreg - dummy reg read function
|
||||
*
|
||||
|
@ -3569,6 +3682,8 @@ int amdgpu_device_init(struct amdgpu_device *adev,
|
|||
adev->pciep_wreg = &amdgpu_invalid_wreg;
|
||||
adev->pcie_rreg64 = &amdgpu_invalid_rreg64;
|
||||
adev->pcie_wreg64 = &amdgpu_invalid_wreg64;
|
||||
adev->pcie_rreg64_ext = &amdgpu_invalid_rreg64_ext;
|
||||
adev->pcie_wreg64_ext = &amdgpu_invalid_wreg64_ext;
|
||||
adev->uvd_ctx_rreg = &amdgpu_invalid_rreg;
|
||||
adev->uvd_ctx_wreg = &amdgpu_invalid_wreg;
|
||||
adev->didt_rreg = &amdgpu_invalid_rreg;
|
||||
|
|
|
@ -921,6 +921,8 @@ static int soc15_common_early_init(void *handle)
|
|||
adev->pcie_wreg_ext = &amdgpu_device_indirect_wreg_ext;
|
||||
adev->pcie_rreg64 = &amdgpu_device_indirect_rreg64;
|
||||
adev->pcie_wreg64 = &amdgpu_device_indirect_wreg64;
|
||||
adev->pcie_rreg64_ext = &amdgpu_device_indirect_rreg64_ext;
|
||||
adev->pcie_wreg64_ext = &amdgpu_device_indirect_wreg64_ext;
|
||||
adev->uvd_ctx_rreg = &soc15_uvd_ctx_rreg;
|
||||
adev->uvd_ctx_wreg = &soc15_uvd_ctx_wreg;
|
||||
adev->didt_rreg = &soc15_didt_rreg;
|
||||
|
|
Loading…
Reference in New Issue