Message ID | 20210205111757.585248-4-boris.brezillon@collabora.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | drm/panfrost: MMU fixes | expand |
On 05/02/2021 11:17, Boris Brezillon wrote: > Doing a hw-irq -> threaded-irq round-trip is counter-productive, stay > in the threaded irq handler as long as we can. > > v2: > * Rework the loop to avoid a goto > > Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com> Reviewed-by: Steven Price <steven.price@arm.com> > --- > drivers/gpu/drm/panfrost/panfrost_mmu.c | 26 +++++++++++++------------ > 1 file changed, 14 insertions(+), 12 deletions(-) > > diff --git a/drivers/gpu/drm/panfrost/panfrost_mmu.c b/drivers/gpu/drm/panfrost/panfrost_mmu.c > index 21e552d1ac71..0581186ebfb3 100644 > --- a/drivers/gpu/drm/panfrost/panfrost_mmu.c > +++ b/drivers/gpu/drm/panfrost/panfrost_mmu.c > @@ -578,22 +578,20 @@ static irqreturn_t panfrost_mmu_irq_handler_thread(int irq, void *data) > { > struct panfrost_device *pfdev = data; > u32 status = mmu_read(pfdev, MMU_INT_RAWSTAT); > - int i, ret; > + int ret; > > - for (i = 0; status; i++) { > - u32 mask = BIT(i) | BIT(i + 16); > + while (status) { > + u32 as = ffs(status | (status >> 16)) - 1; > + u32 mask = BIT(as) | BIT(as + 16); > u64 addr; > u32 fault_status; > u32 exception_type; > u32 access_type; > u32 source_id; > > - if (!(status & mask)) > - continue; > - > - fault_status = mmu_read(pfdev, AS_FAULTSTATUS(i)); > - addr = mmu_read(pfdev, AS_FAULTADDRESS_LO(i)); > - addr |= (u64)mmu_read(pfdev, AS_FAULTADDRESS_HI(i)) << 32; > + fault_status = mmu_read(pfdev, AS_FAULTSTATUS(as)); > + addr = mmu_read(pfdev, AS_FAULTADDRESS_LO(as)); > + addr |= (u64)mmu_read(pfdev, AS_FAULTADDRESS_HI(as)) << 32; > > /* decode the fault status */ > exception_type = fault_status & 0xFF; > @@ -604,8 +602,8 @@ static irqreturn_t panfrost_mmu_irq_handler_thread(int irq, void *data) > > /* Page fault only */ > ret = -1; > - if ((status & mask) == BIT(i) && (exception_type & 0xF8) == 0xC0) > - ret = panfrost_mmu_map_fault_addr(pfdev, i, addr); > + if ((status & mask) == BIT(as) && (exception_type & 0xF8) == 0xC0) > + ret = panfrost_mmu_map_fault_addr(pfdev, as, addr); > > if (ret) > /* terminal fault, print info about the fault */ > @@ -617,7 +615,7 @@ static irqreturn_t panfrost_mmu_irq_handler_thread(int irq, void *data) > "exception type 0x%X: %s\n" > "access type 0x%X: %s\n" > "source id 0x%X\n", > - i, addr, > + as, addr, > "TODO", > fault_status, > (fault_status & (1 << 10) ? "DECODER FAULT" : "SLAVE FAULT"), > @@ -626,6 +624,10 @@ static irqreturn_t panfrost_mmu_irq_handler_thread(int irq, void *data) > source_id); > > status &= ~mask; > + > + /* If we received new MMU interrupts, process them before returning. */ > + if (!status) > + status = mmu_read(pfdev, MMU_INT_RAWSTAT); > } > > mmu_write(pfdev, MMU_INT_MASK, ~0); >
On Fri, Feb 5, 2021 at 5:18 AM Boris Brezillon <boris.brezillon@collabora.com> wrote: > > Doing a hw-irq -> threaded-irq round-trip is counter-productive, stay > in the threaded irq handler as long as we can. > > v2: > * Rework the loop to avoid a goto > > Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com> > --- > drivers/gpu/drm/panfrost/panfrost_mmu.c | 26 +++++++++++++------------ > 1 file changed, 14 insertions(+), 12 deletions(-) Reviewed-by: Rob Herring <robh@kernel.org>
diff --git a/drivers/gpu/drm/panfrost/panfrost_mmu.c b/drivers/gpu/drm/panfrost/panfrost_mmu.c index 21e552d1ac71..0581186ebfb3 100644 --- a/drivers/gpu/drm/panfrost/panfrost_mmu.c +++ b/drivers/gpu/drm/panfrost/panfrost_mmu.c @@ -578,22 +578,20 @@ static irqreturn_t panfrost_mmu_irq_handler_thread(int irq, void *data) { struct panfrost_device *pfdev = data; u32 status = mmu_read(pfdev, MMU_INT_RAWSTAT); - int i, ret; + int ret; - for (i = 0; status; i++) { - u32 mask = BIT(i) | BIT(i + 16); + while (status) { + u32 as = ffs(status | (status >> 16)) - 1; + u32 mask = BIT(as) | BIT(as + 16); u64 addr; u32 fault_status; u32 exception_type; u32 access_type; u32 source_id; - if (!(status & mask)) - continue; - - fault_status = mmu_read(pfdev, AS_FAULTSTATUS(i)); - addr = mmu_read(pfdev, AS_FAULTADDRESS_LO(i)); - addr |= (u64)mmu_read(pfdev, AS_FAULTADDRESS_HI(i)) << 32; + fault_status = mmu_read(pfdev, AS_FAULTSTATUS(as)); + addr = mmu_read(pfdev, AS_FAULTADDRESS_LO(as)); + addr |= (u64)mmu_read(pfdev, AS_FAULTADDRESS_HI(as)) << 32; /* decode the fault status */ exception_type = fault_status & 0xFF; @@ -604,8 +602,8 @@ static irqreturn_t panfrost_mmu_irq_handler_thread(int irq, void *data) /* Page fault only */ ret = -1; - if ((status & mask) == BIT(i) && (exception_type & 0xF8) == 0xC0) - ret = panfrost_mmu_map_fault_addr(pfdev, i, addr); + if ((status & mask) == BIT(as) && (exception_type & 0xF8) == 0xC0) + ret = panfrost_mmu_map_fault_addr(pfdev, as, addr); if (ret) /* terminal fault, print info about the fault */ @@ -617,7 +615,7 @@ static irqreturn_t panfrost_mmu_irq_handler_thread(int irq, void *data) "exception type 0x%X: %s\n" "access type 0x%X: %s\n" "source id 0x%X\n", - i, addr, + as, addr, "TODO", fault_status, (fault_status & (1 << 10) ? "DECODER FAULT" : "SLAVE FAULT"), @@ -626,6 +624,10 @@ static irqreturn_t panfrost_mmu_irq_handler_thread(int irq, void *data) source_id); status &= ~mask; + + /* If we received new MMU interrupts, process them before returning. */ + if (!status) + status = mmu_read(pfdev, MMU_INT_RAWSTAT); } mmu_write(pfdev, MMU_INT_MASK, ~0);
Doing a hw-irq -> threaded-irq round-trip is counter-productive, stay in the threaded irq handler as long as we can. v2: * Rework the loop to avoid a goto Signed-off-by: Boris Brezillon <boris.brezillon@collabora.com> --- drivers/gpu/drm/panfrost/panfrost_mmu.c | 26 +++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-)