mirror of
https://github.com/Fishwaldo/Star64_linux.git
synced 2025-06-28 17:41:50 +00:00
drm/amdgpu: simplify IH programming
Calculate all the addresses and pointers in amdgpu_ih.c Signed-off-by: Christian König <christian.koenig@amd.com> Reviewed-by: Alex Deucher <alexander.deucher@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
parent
8bb9eb480d
commit
d81f78b440
8 changed files with 73 additions and 85 deletions
|
@ -52,6 +52,8 @@ int amdgpu_ih_ring_init(struct amdgpu_device *adev, struct amdgpu_ih_ring *ih,
|
||||||
ih->use_bus_addr = use_bus_addr;
|
ih->use_bus_addr = use_bus_addr;
|
||||||
|
|
||||||
if (use_bus_addr) {
|
if (use_bus_addr) {
|
||||||
|
dma_addr_t dma_addr;
|
||||||
|
|
||||||
if (ih->ring)
|
if (ih->ring)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
@ -59,21 +61,26 @@ int amdgpu_ih_ring_init(struct amdgpu_device *adev, struct amdgpu_ih_ring *ih,
|
||||||
* add them to the end of the ring allocation.
|
* add them to the end of the ring allocation.
|
||||||
*/
|
*/
|
||||||
ih->ring = dma_alloc_coherent(adev->dev, ih->ring_size + 8,
|
ih->ring = dma_alloc_coherent(adev->dev, ih->ring_size + 8,
|
||||||
&ih->rb_dma_addr, GFP_KERNEL);
|
&dma_addr, GFP_KERNEL);
|
||||||
if (ih->ring == NULL)
|
if (ih->ring == NULL)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
memset((void *)ih->ring, 0, ih->ring_size + 8);
|
memset((void *)ih->ring, 0, ih->ring_size + 8);
|
||||||
ih->wptr_offs = (ih->ring_size / 4) + 0;
|
ih->gpu_addr = dma_addr;
|
||||||
ih->rptr_offs = (ih->ring_size / 4) + 1;
|
ih->wptr_addr = dma_addr + ih->ring_size;
|
||||||
|
ih->wptr_cpu = &ih->ring[ih->ring_size / 4];
|
||||||
|
ih->rptr_addr = dma_addr + ih->ring_size + 4;
|
||||||
|
ih->rptr_cpu = &ih->ring[(ih->ring_size / 4) + 1];
|
||||||
} else {
|
} else {
|
||||||
r = amdgpu_device_wb_get(adev, &ih->wptr_offs);
|
unsigned wptr_offs, rptr_offs;
|
||||||
|
|
||||||
|
r = amdgpu_device_wb_get(adev, &wptr_offs);
|
||||||
if (r)
|
if (r)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
r = amdgpu_device_wb_get(adev, &ih->rptr_offs);
|
r = amdgpu_device_wb_get(adev, &rptr_offs);
|
||||||
if (r) {
|
if (r) {
|
||||||
amdgpu_device_wb_free(adev, ih->wptr_offs);
|
amdgpu_device_wb_free(adev, wptr_offs);
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -82,10 +89,15 @@ int amdgpu_ih_ring_init(struct amdgpu_device *adev, struct amdgpu_ih_ring *ih,
|
||||||
&ih->ring_obj, &ih->gpu_addr,
|
&ih->ring_obj, &ih->gpu_addr,
|
||||||
(void **)&ih->ring);
|
(void **)&ih->ring);
|
||||||
if (r) {
|
if (r) {
|
||||||
amdgpu_device_wb_free(adev, ih->rptr_offs);
|
amdgpu_device_wb_free(adev, rptr_offs);
|
||||||
amdgpu_device_wb_free(adev, ih->wptr_offs);
|
amdgpu_device_wb_free(adev, wptr_offs);
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ih->wptr_addr = adev->wb.gpu_addr + wptr_offs * 4;
|
||||||
|
ih->wptr_cpu = &adev->wb.wb[wptr_offs];
|
||||||
|
ih->rptr_addr = adev->wb.gpu_addr + rptr_offs * 4;
|
||||||
|
ih->rptr_cpu = &adev->wb.wb[rptr_offs];
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -109,13 +121,13 @@ void amdgpu_ih_ring_fini(struct amdgpu_device *adev, struct amdgpu_ih_ring *ih)
|
||||||
* add them to the end of the ring allocation.
|
* add them to the end of the ring allocation.
|
||||||
*/
|
*/
|
||||||
dma_free_coherent(adev->dev, ih->ring_size + 8,
|
dma_free_coherent(adev->dev, ih->ring_size + 8,
|
||||||
(void *)ih->ring, ih->rb_dma_addr);
|
(void *)ih->ring, ih->gpu_addr);
|
||||||
ih->ring = NULL;
|
ih->ring = NULL;
|
||||||
} else {
|
} else {
|
||||||
amdgpu_bo_free_kernel(&ih->ring_obj, &ih->gpu_addr,
|
amdgpu_bo_free_kernel(&ih->ring_obj, &ih->gpu_addr,
|
||||||
(void **)&ih->ring);
|
(void **)&ih->ring);
|
||||||
amdgpu_device_wb_free(adev, ih->wptr_offs);
|
amdgpu_device_wb_free(adev, (ih->wptr_addr - ih->gpu_addr) / 4);
|
||||||
amdgpu_device_wb_free(adev, ih->rptr_offs);
|
amdgpu_device_wb_free(adev, (ih->rptr_addr - ih->gpu_addr) / 4);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -31,20 +31,25 @@ struct amdgpu_iv_entry;
|
||||||
* R6xx+ IH ring
|
* R6xx+ IH ring
|
||||||
*/
|
*/
|
||||||
struct amdgpu_ih_ring {
|
struct amdgpu_ih_ring {
|
||||||
struct amdgpu_bo *ring_obj;
|
|
||||||
volatile uint32_t *ring;
|
|
||||||
unsigned rptr;
|
|
||||||
unsigned ring_size;
|
unsigned ring_size;
|
||||||
uint64_t gpu_addr;
|
|
||||||
uint32_t ptr_mask;
|
uint32_t ptr_mask;
|
||||||
atomic_t lock;
|
|
||||||
bool enabled;
|
|
||||||
unsigned wptr_offs;
|
|
||||||
unsigned rptr_offs;
|
|
||||||
u32 doorbell_index;
|
u32 doorbell_index;
|
||||||
bool use_doorbell;
|
bool use_doorbell;
|
||||||
bool use_bus_addr;
|
bool use_bus_addr;
|
||||||
dma_addr_t rb_dma_addr; /* only used when use_bus_addr = true */
|
|
||||||
|
struct amdgpu_bo *ring_obj;
|
||||||
|
volatile uint32_t *ring;
|
||||||
|
uint64_t gpu_addr;
|
||||||
|
|
||||||
|
uint64_t wptr_addr;
|
||||||
|
volatile uint32_t *wptr_cpu;
|
||||||
|
|
||||||
|
uint64_t rptr_addr;
|
||||||
|
volatile uint32_t *rptr_cpu;
|
||||||
|
|
||||||
|
bool enabled;
|
||||||
|
unsigned rptr;
|
||||||
|
atomic_t lock;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* provided by the ih block */
|
/* provided by the ih block */
|
||||||
|
|
|
@ -103,9 +103,9 @@ static void cik_ih_disable_interrupts(struct amdgpu_device *adev)
|
||||||
*/
|
*/
|
||||||
static int cik_ih_irq_init(struct amdgpu_device *adev)
|
static int cik_ih_irq_init(struct amdgpu_device *adev)
|
||||||
{
|
{
|
||||||
|
struct amdgpu_ih_ring *ih = &adev->irq.ih;
|
||||||
int rb_bufsz;
|
int rb_bufsz;
|
||||||
u32 interrupt_cntl, ih_cntl, ih_rb_cntl;
|
u32 interrupt_cntl, ih_cntl, ih_rb_cntl;
|
||||||
u64 wptr_off;
|
|
||||||
|
|
||||||
/* disable irqs */
|
/* disable irqs */
|
||||||
cik_ih_disable_interrupts(adev);
|
cik_ih_disable_interrupts(adev);
|
||||||
|
@ -131,9 +131,8 @@ static int cik_ih_irq_init(struct amdgpu_device *adev)
|
||||||
ih_rb_cntl |= IH_RB_CNTL__WPTR_WRITEBACK_ENABLE_MASK;
|
ih_rb_cntl |= IH_RB_CNTL__WPTR_WRITEBACK_ENABLE_MASK;
|
||||||
|
|
||||||
/* set the writeback address whether it's enabled or not */
|
/* set the writeback address whether it's enabled or not */
|
||||||
wptr_off = adev->wb.gpu_addr + (adev->irq.ih.wptr_offs * 4);
|
WREG32(mmIH_RB_WPTR_ADDR_LO, lower_32_bits(ih->wptr_addr));
|
||||||
WREG32(mmIH_RB_WPTR_ADDR_LO, lower_32_bits(wptr_off));
|
WREG32(mmIH_RB_WPTR_ADDR_HI, upper_32_bits(ih->wptr_addr) & 0xFF);
|
||||||
WREG32(mmIH_RB_WPTR_ADDR_HI, upper_32_bits(wptr_off) & 0xFF);
|
|
||||||
|
|
||||||
WREG32(mmIH_RB_CNTL, ih_rb_cntl);
|
WREG32(mmIH_RB_CNTL, ih_rb_cntl);
|
||||||
|
|
||||||
|
@ -188,7 +187,7 @@ static u32 cik_ih_get_wptr(struct amdgpu_device *adev,
|
||||||
{
|
{
|
||||||
u32 wptr, tmp;
|
u32 wptr, tmp;
|
||||||
|
|
||||||
wptr = le32_to_cpu(adev->wb.wb[ih->wptr_offs]);
|
wptr = le32_to_cpu(*ih->wptr_cpu);
|
||||||
|
|
||||||
if (wptr & IH_RB_WPTR__RB_OVERFLOW_MASK) {
|
if (wptr & IH_RB_WPTR__RB_OVERFLOW_MASK) {
|
||||||
wptr &= ~IH_RB_WPTR__RB_OVERFLOW_MASK;
|
wptr &= ~IH_RB_WPTR__RB_OVERFLOW_MASK;
|
||||||
|
|
|
@ -103,9 +103,9 @@ static void cz_ih_disable_interrupts(struct amdgpu_device *adev)
|
||||||
*/
|
*/
|
||||||
static int cz_ih_irq_init(struct amdgpu_device *adev)
|
static int cz_ih_irq_init(struct amdgpu_device *adev)
|
||||||
{
|
{
|
||||||
int rb_bufsz;
|
struct amdgpu_ih_ring *ih = &adev->irq.ih;
|
||||||
u32 interrupt_cntl, ih_cntl, ih_rb_cntl;
|
u32 interrupt_cntl, ih_cntl, ih_rb_cntl;
|
||||||
u64 wptr_off;
|
int rb_bufsz;
|
||||||
|
|
||||||
/* disable irqs */
|
/* disable irqs */
|
||||||
cz_ih_disable_interrupts(adev);
|
cz_ih_disable_interrupts(adev);
|
||||||
|
@ -133,9 +133,8 @@ static int cz_ih_irq_init(struct amdgpu_device *adev)
|
||||||
ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL, WPTR_WRITEBACK_ENABLE, 1);
|
ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL, WPTR_WRITEBACK_ENABLE, 1);
|
||||||
|
|
||||||
/* set the writeback address whether it's enabled or not */
|
/* set the writeback address whether it's enabled or not */
|
||||||
wptr_off = adev->wb.gpu_addr + (adev->irq.ih.wptr_offs * 4);
|
WREG32(mmIH_RB_WPTR_ADDR_LO, lower_32_bits(ih->wptr_addr));
|
||||||
WREG32(mmIH_RB_WPTR_ADDR_LO, lower_32_bits(wptr_off));
|
WREG32(mmIH_RB_WPTR_ADDR_HI, upper_32_bits(ih->wptr_addr) & 0xFF);
|
||||||
WREG32(mmIH_RB_WPTR_ADDR_HI, upper_32_bits(wptr_off) & 0xFF);
|
|
||||||
|
|
||||||
WREG32(mmIH_RB_CNTL, ih_rb_cntl);
|
WREG32(mmIH_RB_CNTL, ih_rb_cntl);
|
||||||
|
|
||||||
|
@ -190,7 +189,7 @@ static u32 cz_ih_get_wptr(struct amdgpu_device *adev,
|
||||||
{
|
{
|
||||||
u32 wptr, tmp;
|
u32 wptr, tmp;
|
||||||
|
|
||||||
wptr = le32_to_cpu(adev->wb.wb[ih->wptr_offs]);
|
wptr = le32_to_cpu(*ih->wptr_cpu);
|
||||||
|
|
||||||
if (REG_GET_FIELD(wptr, IH_RB_WPTR, RB_OVERFLOW)) {
|
if (REG_GET_FIELD(wptr, IH_RB_WPTR, RB_OVERFLOW)) {
|
||||||
wptr = REG_SET_FIELD(wptr, IH_RB_WPTR, RB_OVERFLOW, 0);
|
wptr = REG_SET_FIELD(wptr, IH_RB_WPTR, RB_OVERFLOW, 0);
|
||||||
|
|
|
@ -103,9 +103,9 @@ static void iceland_ih_disable_interrupts(struct amdgpu_device *adev)
|
||||||
*/
|
*/
|
||||||
static int iceland_ih_irq_init(struct amdgpu_device *adev)
|
static int iceland_ih_irq_init(struct amdgpu_device *adev)
|
||||||
{
|
{
|
||||||
|
struct amdgpu_ih_ring *ih = &adev->irq.ih;
|
||||||
int rb_bufsz;
|
int rb_bufsz;
|
||||||
u32 interrupt_cntl, ih_cntl, ih_rb_cntl;
|
u32 interrupt_cntl, ih_cntl, ih_rb_cntl;
|
||||||
u64 wptr_off;
|
|
||||||
|
|
||||||
/* disable irqs */
|
/* disable irqs */
|
||||||
iceland_ih_disable_interrupts(adev);
|
iceland_ih_disable_interrupts(adev);
|
||||||
|
@ -133,9 +133,8 @@ static int iceland_ih_irq_init(struct amdgpu_device *adev)
|
||||||
ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL, WPTR_WRITEBACK_ENABLE, 1);
|
ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL, WPTR_WRITEBACK_ENABLE, 1);
|
||||||
|
|
||||||
/* set the writeback address whether it's enabled or not */
|
/* set the writeback address whether it's enabled or not */
|
||||||
wptr_off = adev->wb.gpu_addr + (adev->irq.ih.wptr_offs * 4);
|
WREG32(mmIH_RB_WPTR_ADDR_LO, lower_32_bits(ih->wptr_addr));
|
||||||
WREG32(mmIH_RB_WPTR_ADDR_LO, lower_32_bits(wptr_off));
|
WREG32(mmIH_RB_WPTR_ADDR_HI, upper_32_bits(ih->wptr_addr) & 0xFF);
|
||||||
WREG32(mmIH_RB_WPTR_ADDR_HI, upper_32_bits(wptr_off) & 0xFF);
|
|
||||||
|
|
||||||
WREG32(mmIH_RB_CNTL, ih_rb_cntl);
|
WREG32(mmIH_RB_CNTL, ih_rb_cntl);
|
||||||
|
|
||||||
|
@ -190,7 +189,7 @@ static u32 iceland_ih_get_wptr(struct amdgpu_device *adev,
|
||||||
{
|
{
|
||||||
u32 wptr, tmp;
|
u32 wptr, tmp;
|
||||||
|
|
||||||
wptr = le32_to_cpu(adev->wb.wb[ih->wptr_offs]);
|
wptr = le32_to_cpu(*ih->wptr_cpu);
|
||||||
|
|
||||||
if (REG_GET_FIELD(wptr, IH_RB_WPTR, RB_OVERFLOW)) {
|
if (REG_GET_FIELD(wptr, IH_RB_WPTR, RB_OVERFLOW)) {
|
||||||
wptr = REG_SET_FIELD(wptr, IH_RB_WPTR, RB_OVERFLOW, 0);
|
wptr = REG_SET_FIELD(wptr, IH_RB_WPTR, RB_OVERFLOW, 0);
|
||||||
|
|
|
@ -57,9 +57,9 @@ static void si_ih_disable_interrupts(struct amdgpu_device *adev)
|
||||||
|
|
||||||
static int si_ih_irq_init(struct amdgpu_device *adev)
|
static int si_ih_irq_init(struct amdgpu_device *adev)
|
||||||
{
|
{
|
||||||
|
struct amdgpu_ih_ring *ih = &adev->irq.ih;
|
||||||
int rb_bufsz;
|
int rb_bufsz;
|
||||||
u32 interrupt_cntl, ih_cntl, ih_rb_cntl;
|
u32 interrupt_cntl, ih_cntl, ih_rb_cntl;
|
||||||
u64 wptr_off;
|
|
||||||
|
|
||||||
si_ih_disable_interrupts(adev);
|
si_ih_disable_interrupts(adev);
|
||||||
WREG32(INTERRUPT_CNTL2, adev->irq.ih.gpu_addr >> 8);
|
WREG32(INTERRUPT_CNTL2, adev->irq.ih.gpu_addr >> 8);
|
||||||
|
@ -76,9 +76,8 @@ static int si_ih_irq_init(struct amdgpu_device *adev)
|
||||||
(rb_bufsz << 1) |
|
(rb_bufsz << 1) |
|
||||||
IH_WPTR_WRITEBACK_ENABLE;
|
IH_WPTR_WRITEBACK_ENABLE;
|
||||||
|
|
||||||
wptr_off = adev->wb.gpu_addr + (adev->irq.ih.wptr_offs * 4);
|
WREG32(IH_RB_WPTR_ADDR_LO, lower_32_bits(ih->wptr_addr));
|
||||||
WREG32(IH_RB_WPTR_ADDR_LO, lower_32_bits(wptr_off));
|
WREG32(IH_RB_WPTR_ADDR_HI, upper_32_bits(ih->wptr_addr) & 0xFF);
|
||||||
WREG32(IH_RB_WPTR_ADDR_HI, upper_32_bits(wptr_off) & 0xFF);
|
|
||||||
WREG32(IH_RB_CNTL, ih_rb_cntl);
|
WREG32(IH_RB_CNTL, ih_rb_cntl);
|
||||||
WREG32(IH_RB_RPTR, 0);
|
WREG32(IH_RB_RPTR, 0);
|
||||||
WREG32(IH_RB_WPTR, 0);
|
WREG32(IH_RB_WPTR, 0);
|
||||||
|
@ -105,7 +104,7 @@ static u32 si_ih_get_wptr(struct amdgpu_device *adev,
|
||||||
{
|
{
|
||||||
u32 wptr, tmp;
|
u32 wptr, tmp;
|
||||||
|
|
||||||
wptr = le32_to_cpu(adev->wb.wb[ih->wptr_offs]);
|
wptr = le32_to_cpu(*ih->wptr_cpu);
|
||||||
|
|
||||||
if (wptr & IH_RB_WPTR__RB_OVERFLOW_MASK) {
|
if (wptr & IH_RB_WPTR__RB_OVERFLOW_MASK) {
|
||||||
wptr &= ~IH_RB_WPTR__RB_OVERFLOW_MASK;
|
wptr &= ~IH_RB_WPTR__RB_OVERFLOW_MASK;
|
||||||
|
|
|
@ -99,9 +99,9 @@ static void tonga_ih_disable_interrupts(struct amdgpu_device *adev)
|
||||||
*/
|
*/
|
||||||
static int tonga_ih_irq_init(struct amdgpu_device *adev)
|
static int tonga_ih_irq_init(struct amdgpu_device *adev)
|
||||||
{
|
{
|
||||||
int rb_bufsz;
|
|
||||||
u32 interrupt_cntl, ih_rb_cntl, ih_doorbell_rtpr;
|
u32 interrupt_cntl, ih_rb_cntl, ih_doorbell_rtpr;
|
||||||
u64 wptr_off;
|
struct amdgpu_ih_ring *ih = &adev->irq.ih;
|
||||||
|
int rb_bufsz;
|
||||||
|
|
||||||
/* disable irqs */
|
/* disable irqs */
|
||||||
tonga_ih_disable_interrupts(adev);
|
tonga_ih_disable_interrupts(adev);
|
||||||
|
@ -118,10 +118,7 @@ static int tonga_ih_irq_init(struct amdgpu_device *adev)
|
||||||
WREG32(mmINTERRUPT_CNTL, interrupt_cntl);
|
WREG32(mmINTERRUPT_CNTL, interrupt_cntl);
|
||||||
|
|
||||||
/* Ring Buffer base. [39:8] of 40-bit address of the beginning of the ring buffer*/
|
/* Ring Buffer base. [39:8] of 40-bit address of the beginning of the ring buffer*/
|
||||||
if (adev->irq.ih.use_bus_addr)
|
WREG32(mmIH_RB_BASE, ih->gpu_addr >> 8);
|
||||||
WREG32(mmIH_RB_BASE, adev->irq.ih.rb_dma_addr >> 8);
|
|
||||||
else
|
|
||||||
WREG32(mmIH_RB_BASE, adev->irq.ih.gpu_addr >> 8);
|
|
||||||
|
|
||||||
rb_bufsz = order_base_2(adev->irq.ih.ring_size / 4);
|
rb_bufsz = order_base_2(adev->irq.ih.ring_size / 4);
|
||||||
ih_rb_cntl = REG_SET_FIELD(0, IH_RB_CNTL, WPTR_OVERFLOW_CLEAR, 1);
|
ih_rb_cntl = REG_SET_FIELD(0, IH_RB_CNTL, WPTR_OVERFLOW_CLEAR, 1);
|
||||||
|
@ -136,12 +133,8 @@ static int tonga_ih_irq_init(struct amdgpu_device *adev)
|
||||||
WREG32(mmIH_RB_CNTL, ih_rb_cntl);
|
WREG32(mmIH_RB_CNTL, ih_rb_cntl);
|
||||||
|
|
||||||
/* set the writeback address whether it's enabled or not */
|
/* set the writeback address whether it's enabled or not */
|
||||||
if (adev->irq.ih.use_bus_addr)
|
WREG32(mmIH_RB_WPTR_ADDR_LO, lower_32_bits(ih->wptr_addr));
|
||||||
wptr_off = adev->irq.ih.rb_dma_addr + (adev->irq.ih.wptr_offs * 4);
|
WREG32(mmIH_RB_WPTR_ADDR_HI, upper_32_bits(ih->wptr_addr) & 0xFF);
|
||||||
else
|
|
||||||
wptr_off = adev->wb.gpu_addr + (adev->irq.ih.wptr_offs * 4);
|
|
||||||
WREG32(mmIH_RB_WPTR_ADDR_LO, lower_32_bits(wptr_off));
|
|
||||||
WREG32(mmIH_RB_WPTR_ADDR_HI, upper_32_bits(wptr_off) & 0xFF);
|
|
||||||
|
|
||||||
/* set rptr, wptr to 0 */
|
/* set rptr, wptr to 0 */
|
||||||
WREG32(mmIH_RB_RPTR, 0);
|
WREG32(mmIH_RB_RPTR, 0);
|
||||||
|
@ -198,10 +191,7 @@ static u32 tonga_ih_get_wptr(struct amdgpu_device *adev,
|
||||||
{
|
{
|
||||||
u32 wptr, tmp;
|
u32 wptr, tmp;
|
||||||
|
|
||||||
if (adev->irq.ih.use_bus_addr)
|
wptr = le32_to_cpu(*ih->wptr_cpu);
|
||||||
wptr = le32_to_cpu(ih->ring[ih->wptr_offs]);
|
|
||||||
else
|
|
||||||
wptr = le32_to_cpu(adev->wb.wb[ih->wptr_offs]);
|
|
||||||
|
|
||||||
if (REG_GET_FIELD(wptr, IH_RB_WPTR, RB_OVERFLOW)) {
|
if (REG_GET_FIELD(wptr, IH_RB_WPTR, RB_OVERFLOW)) {
|
||||||
wptr = REG_SET_FIELD(wptr, IH_RB_WPTR, RB_OVERFLOW, 0);
|
wptr = REG_SET_FIELD(wptr, IH_RB_WPTR, RB_OVERFLOW, 0);
|
||||||
|
@ -263,10 +253,7 @@ static void tonga_ih_set_rptr(struct amdgpu_device *adev,
|
||||||
{
|
{
|
||||||
if (ih->use_doorbell) {
|
if (ih->use_doorbell) {
|
||||||
/* XXX check if swapping is necessary on BE */
|
/* XXX check if swapping is necessary on BE */
|
||||||
if (ih->use_bus_addr)
|
*ih->rptr_cpu = ih->rptr;
|
||||||
ih->ring[ih->rptr_offs] = ih->rptr;
|
|
||||||
else
|
|
||||||
adev->wb.wb[ih->rptr_offs] = ih->rptr;
|
|
||||||
WDOORBELL32(ih->doorbell_index, ih->rptr);
|
WDOORBELL32(ih->doorbell_index, ih->rptr);
|
||||||
} else {
|
} else {
|
||||||
WREG32(mmIH_RB_RPTR, ih->rptr);
|
WREG32(mmIH_RB_RPTR, ih->rptr);
|
||||||
|
|
|
@ -86,11 +86,11 @@ static void vega10_ih_disable_interrupts(struct amdgpu_device *adev)
|
||||||
*/
|
*/
|
||||||
static int vega10_ih_irq_init(struct amdgpu_device *adev)
|
static int vega10_ih_irq_init(struct amdgpu_device *adev)
|
||||||
{
|
{
|
||||||
|
struct amdgpu_ih_ring *ih = &adev->irq.ih;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
int rb_bufsz;
|
int rb_bufsz;
|
||||||
u32 ih_rb_cntl, ih_doorbell_rtpr;
|
u32 ih_rb_cntl, ih_doorbell_rtpr;
|
||||||
u32 tmp;
|
u32 tmp;
|
||||||
u64 wptr_off;
|
|
||||||
|
|
||||||
/* disable irqs */
|
/* disable irqs */
|
||||||
vega10_ih_disable_interrupts(adev);
|
vega10_ih_disable_interrupts(adev);
|
||||||
|
@ -99,15 +99,11 @@ static int vega10_ih_irq_init(struct amdgpu_device *adev)
|
||||||
|
|
||||||
ih_rb_cntl = RREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL);
|
ih_rb_cntl = RREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL);
|
||||||
/* Ring Buffer base. [39:8] of 40-bit address of the beginning of the ring buffer*/
|
/* Ring Buffer base. [39:8] of 40-bit address of the beginning of the ring buffer*/
|
||||||
if (adev->irq.ih.use_bus_addr) {
|
WREG32_SOC15(OSSSYS, 0, mmIH_RB_BASE, adev->irq.ih.gpu_addr >> 8);
|
||||||
WREG32_SOC15(OSSSYS, 0, mmIH_RB_BASE, adev->irq.ih.rb_dma_addr >> 8);
|
WREG32_SOC15(OSSSYS, 0, mmIH_RB_BASE_HI,
|
||||||
WREG32_SOC15(OSSSYS, 0, mmIH_RB_BASE_HI, ((u64)adev->irq.ih.rb_dma_addr >> 40) & 0xff);
|
(adev->irq.ih.gpu_addr >> 40) & 0xff);
|
||||||
ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL, MC_SPACE, 1);
|
ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL, MC_SPACE,
|
||||||
} else {
|
ih->use_bus_addr ? 1 : 4);
|
||||||
WREG32_SOC15(OSSSYS, 0, mmIH_RB_BASE, adev->irq.ih.gpu_addr >> 8);
|
|
||||||
WREG32_SOC15(OSSSYS, 0, mmIH_RB_BASE_HI, (adev->irq.ih.gpu_addr >> 40) & 0xff);
|
|
||||||
ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL, MC_SPACE, 4);
|
|
||||||
}
|
|
||||||
rb_bufsz = order_base_2(adev->irq.ih.ring_size / 4);
|
rb_bufsz = order_base_2(adev->irq.ih.ring_size / 4);
|
||||||
ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL, WPTR_OVERFLOW_CLEAR, 1);
|
ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL, WPTR_OVERFLOW_CLEAR, 1);
|
||||||
ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL, WPTR_OVERFLOW_ENABLE, 1);
|
ih_rb_cntl = REG_SET_FIELD(ih_rb_cntl, IH_RB_CNTL, WPTR_OVERFLOW_ENABLE, 1);
|
||||||
|
@ -124,12 +120,10 @@ static int vega10_ih_irq_init(struct amdgpu_device *adev)
|
||||||
WREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL, ih_rb_cntl);
|
WREG32_SOC15(OSSSYS, 0, mmIH_RB_CNTL, ih_rb_cntl);
|
||||||
|
|
||||||
/* set the writeback address whether it's enabled or not */
|
/* set the writeback address whether it's enabled or not */
|
||||||
if (adev->irq.ih.use_bus_addr)
|
WREG32_SOC15(OSSSYS, 0, mmIH_RB_WPTR_ADDR_LO,
|
||||||
wptr_off = adev->irq.ih.rb_dma_addr + (adev->irq.ih.wptr_offs * 4);
|
lower_32_bits(ih->wptr_addr));
|
||||||
else
|
WREG32_SOC15(OSSSYS, 0, mmIH_RB_WPTR_ADDR_HI,
|
||||||
wptr_off = adev->wb.gpu_addr + (adev->irq.ih.wptr_offs * 4);
|
upper_32_bits(ih->wptr_addr) & 0xFFFF);
|
||||||
WREG32_SOC15(OSSSYS, 0, mmIH_RB_WPTR_ADDR_LO, lower_32_bits(wptr_off));
|
|
||||||
WREG32_SOC15(OSSSYS, 0, mmIH_RB_WPTR_ADDR_HI, upper_32_bits(wptr_off) & 0xFFFF);
|
|
||||||
|
|
||||||
/* set rptr, wptr to 0 */
|
/* set rptr, wptr to 0 */
|
||||||
WREG32_SOC15(OSSSYS, 0, mmIH_RB_RPTR, 0);
|
WREG32_SOC15(OSSSYS, 0, mmIH_RB_RPTR, 0);
|
||||||
|
@ -196,10 +190,7 @@ static u32 vega10_ih_get_wptr(struct amdgpu_device *adev,
|
||||||
{
|
{
|
||||||
u32 wptr, tmp;
|
u32 wptr, tmp;
|
||||||
|
|
||||||
if (ih->use_bus_addr)
|
wptr = le32_to_cpu(*ih->wptr_cpu);
|
||||||
wptr = le32_to_cpu(ih->ring[ih->wptr_offs]);
|
|
||||||
else
|
|
||||||
wptr = le32_to_cpu(adev->wb.wb[ih->wptr_offs]);
|
|
||||||
|
|
||||||
if (REG_GET_FIELD(wptr, IH_RB_WPTR, RB_OVERFLOW)) {
|
if (REG_GET_FIELD(wptr, IH_RB_WPTR, RB_OVERFLOW)) {
|
||||||
wptr = REG_SET_FIELD(wptr, IH_RB_WPTR, RB_OVERFLOW, 0);
|
wptr = REG_SET_FIELD(wptr, IH_RB_WPTR, RB_OVERFLOW, 0);
|
||||||
|
@ -275,10 +266,7 @@ static void vega10_ih_set_rptr(struct amdgpu_device *adev,
|
||||||
{
|
{
|
||||||
if (ih->use_doorbell) {
|
if (ih->use_doorbell) {
|
||||||
/* XXX check if swapping is necessary on BE */
|
/* XXX check if swapping is necessary on BE */
|
||||||
if (ih->use_bus_addr)
|
*ih->rptr_cpu = ih->rptr;
|
||||||
ih->ring[ih->rptr_offs] = ih->rptr;
|
|
||||||
else
|
|
||||||
adev->wb.wb[ih->rptr_offs] = ih->rptr;
|
|
||||||
WDOORBELL32(ih->doorbell_index, ih->rptr);
|
WDOORBELL32(ih->doorbell_index, ih->rptr);
|
||||||
} else {
|
} else {
|
||||||
WREG32_SOC15(OSSSYS, 0, mmIH_RB_RPTR, ih->rptr);
|
WREG32_SOC15(OSSSYS, 0, mmIH_RB_RPTR, ih->rptr);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue