* struct panthor_mmu - MMU related data
*/
struct panthor_mmu {
+ /** @iomem: CPU mapping of MMU_AS_CONTROL iomem region */
+ void __iomem *iomem;
+
/** @irq: The MMU irq. */
struct panthor_irq irq;
static int wait_ready(struct panthor_device *ptdev, u32 as_nr)
{
+ struct panthor_mmu *mmu = ptdev->mmu;
int ret;
u32 val;
/* Wait for the MMU status to indicate there is no active command, in
* case one is pending.
*/
- ret = gpu_read_relaxed_poll_timeout_atomic(ptdev->iomem, AS_STATUS(as_nr), val,
+ ret = gpu_read_relaxed_poll_timeout_atomic(mmu->iomem, AS_STATUS(as_nr), val,
!(val & AS_STATUS_AS_ACTIVE), 10, 100000);
if (ret) {
/* write AS_COMMAND when MMU is ready to accept another command */
status = wait_ready(ptdev, as_nr);
if (!status) {
- gpu_write(ptdev->iomem, AS_COMMAND(as_nr), cmd);
+ gpu_write(ptdev->mmu->iomem, AS_COMMAND(as_nr), cmd);
status = wait_ready(ptdev, as_nr);
}
static int panthor_mmu_as_enable(struct panthor_device *ptdev, u32 as_nr,
u64 transtab, u64 transcfg, u64 memattr)
{
+ struct panthor_mmu *mmu = ptdev->mmu;
+
panthor_mmu_irq_enable_events(&ptdev->mmu->irq,
panthor_mmu_as_fault_mask(ptdev, as_nr));
- gpu_write64(ptdev->iomem, AS_TRANSTAB(as_nr), transtab);
- gpu_write64(ptdev->iomem, AS_MEMATTR(as_nr), memattr);
- gpu_write64(ptdev->iomem, AS_TRANSCFG(as_nr), transcfg);
+ gpu_write64(mmu->iomem, AS_TRANSTAB(as_nr), transtab);
+ gpu_write64(mmu->iomem, AS_MEMATTR(as_nr), memattr);
+ gpu_write64(mmu->iomem, AS_TRANSCFG(as_nr), transcfg);
return as_send_cmd_and_wait(ptdev, as_nr, AS_COMMAND_UPDATE);
}
static int panthor_mmu_as_disable(struct panthor_device *ptdev, u32 as_nr,
bool recycle_slot)
{
+ struct panthor_mmu *mmu = ptdev->mmu;
struct panthor_vm *vm = ptdev->mmu->as.slots[as_nr].vm;
int ret;
if (recycle_slot)
return 0;
- gpu_write64(ptdev->iomem, AS_TRANSTAB(as_nr), 0);
- gpu_write64(ptdev->iomem, AS_MEMATTR(as_nr), 0);
- gpu_write64(ptdev->iomem, AS_TRANSCFG(as_nr), AS_TRANSCFG_ADRMODE_UNMAPPED);
+ gpu_write64(mmu->iomem, AS_TRANSTAB(as_nr), 0);
+ gpu_write64(mmu->iomem, AS_MEMATTR(as_nr), 0);
+ gpu_write64(mmu->iomem, AS_TRANSCFG(as_nr), AS_TRANSCFG_ADRMODE_UNMAPPED);
return as_send_cmd_and_wait(ptdev, as_nr, AS_COMMAND_UPDATE);
}
*/
fault_mask = panthor_mmu_as_fault_mask(ptdev, as);
if (ptdev->mmu->as.faulty_mask & fault_mask) {
- gpu_write(ptdev->iomem, MMU_INT_CLEAR, fault_mask);
+ gpu_write(ptdev->mmu->irq.iomem, INT_CLEAR, fault_mask);
ptdev->mmu->as.faulty_mask &= ~fault_mask;
}
mutex_lock(&ptdev->mmu->as.slots_lock);
if (vm->as.id >= 0 && size) {
/* Lock the region that needs to be updated */
- gpu_write64(ptdev->iomem, AS_LOCKADDR(vm->as.id),
+ gpu_write64(ptdev->mmu->iomem, AS_LOCKADDR(vm->as.id),
pack_region_range(ptdev, &start, &size));
/* If the lock succeeded, update the locked_region info. */
static void panthor_mmu_irq_handler(struct panthor_device *ptdev, u32 status)
{
+ struct panthor_mmu *mmu = ptdev->mmu;
bool has_unhandled_faults = false;
status = panthor_mmu_fault_mask(ptdev, status);
u32 access_type;
u32 source_id;
- fault_status = gpu_read(ptdev->iomem, AS_FAULTSTATUS(as));
- addr = gpu_read64(ptdev->iomem, AS_FAULTADDRESS(as));
+ fault_status = gpu_read(mmu->iomem, AS_FAULTSTATUS(as));
+ addr = gpu_read64(mmu->iomem, AS_FAULTADDRESS(as));
/* decode the fault status */
exception_type = fault_status & 0xFF;
* Note that COMPLETED irqs are never cleared, but this is fine
* because they are always masked.
*/
- gpu_write(ptdev->iomem, MMU_INT_CLEAR, mask);
+ gpu_write(mmu->irq.iomem, INT_CLEAR, mask);
if (ptdev->mmu->as.slots[as].vm)
ptdev->mmu->as.slots[as].vm->unhandled_fault = true;
if (ret)
return ret;
+ mmu->iomem = ptdev->iomem + MMU_AS_BASE;
ptdev->mmu = mmu;
irq = platform_get_irq_byname(to_platform_device(ptdev->base.dev), "mmu");