1 // SPDX-License-Identifier: GPL-2.0 OR MIT
2 /* Copyright 2017-2019 Qiang Yu <yuq825@gmail.com> */
4 #include <linux/interrupt.h>
5 #include <linux/iopoll.h>
6 #include <linux/device.h>
8 #include "lima_device.h"
11 #include "lima_regs.h"
13 #define mmu_write(reg, data) writel(data, ip->iomem + reg)
14 #define mmu_read(reg) readl(ip->iomem + reg)
16 #define lima_mmu_send_command(cmd, addr, val, cond) \
20 mmu_write(LIMA_MMU_COMMAND, cmd); \
21 __ret = readl_poll_timeout(ip->iomem + (addr), val, \
25 "mmu command %x timeout\n", cmd); \
29 static irqreturn_t
lima_mmu_irq_handler(int irq
, void *data
)
31 struct lima_ip
*ip
= data
;
32 struct lima_device
*dev
= ip
->dev
;
33 u32 status
= mmu_read(LIMA_MMU_INT_STATUS
);
34 struct lima_sched_pipe
*pipe
;
36 /* for shared irq case */
40 if (status
& LIMA_MMU_INT_PAGE_FAULT
) {
41 u32 fault
= mmu_read(LIMA_MMU_PAGE_FAULT_ADDR
);
43 dev_err(dev
->dev
, "mmu page fault at 0x%x from bus id %d of type %s on %s\n",
44 fault
, LIMA_MMU_STATUS_BUS_ID(status
),
45 status
& LIMA_MMU_STATUS_PAGE_FAULT_IS_WRITE
? "write" : "read",
49 if (status
& LIMA_MMU_INT_READ_BUS_ERROR
)
50 dev_err(dev
->dev
, "mmu %s irq bus error\n", lima_ip_name(ip
));
52 /* mask all interrupts before resume */
53 mmu_write(LIMA_MMU_INT_MASK
, 0);
54 mmu_write(LIMA_MMU_INT_CLEAR
, status
);
56 pipe
= dev
->pipe
+ (ip
->id
== lima_ip_gpmmu
? lima_pipe_gp
: lima_pipe_pp
);
57 lima_sched_pipe_mmu_error(pipe
);
62 int lima_mmu_init(struct lima_ip
*ip
)
64 struct lima_device
*dev
= ip
->dev
;
68 if (ip
->id
== lima_ip_ppmmu_bcast
)
71 mmu_write(LIMA_MMU_DTE_ADDR
, 0xCAFEBABE);
72 if (mmu_read(LIMA_MMU_DTE_ADDR
) != 0xCAFEB000) {
73 dev_err(dev
->dev
, "mmu %s dte write test fail\n", lima_ip_name(ip
));
77 mmu_write(LIMA_MMU_COMMAND
, LIMA_MMU_COMMAND_HARD_RESET
);
78 err
= lima_mmu_send_command(LIMA_MMU_COMMAND_HARD_RESET
,
79 LIMA_MMU_DTE_ADDR
, v
, v
== 0);
83 err
= devm_request_irq(dev
->dev
, ip
->irq
, lima_mmu_irq_handler
,
84 IRQF_SHARED
, lima_ip_name(ip
), ip
);
86 dev_err(dev
->dev
, "mmu %s fail to request irq\n", lima_ip_name(ip
));
90 mmu_write(LIMA_MMU_INT_MASK
, LIMA_MMU_INT_PAGE_FAULT
| LIMA_MMU_INT_READ_BUS_ERROR
);
91 mmu_write(LIMA_MMU_DTE_ADDR
, dev
->empty_vm
->pd
.dma
);
92 return lima_mmu_send_command(LIMA_MMU_COMMAND_ENABLE_PAGING
,
94 v
& LIMA_MMU_STATUS_PAGING_ENABLED
);
97 void lima_mmu_fini(struct lima_ip
*ip
)
102 void lima_mmu_switch_vm(struct lima_ip
*ip
, struct lima_vm
*vm
)
104 struct lima_device
*dev
= ip
->dev
;
107 lima_mmu_send_command(LIMA_MMU_COMMAND_ENABLE_STALL
,
109 v
& LIMA_MMU_STATUS_STALL_ACTIVE
);
112 mmu_write(LIMA_MMU_DTE_ADDR
, vm
->pd
.dma
);
115 mmu_write(LIMA_MMU_COMMAND
, LIMA_MMU_COMMAND_ZAP_CACHE
);
117 lima_mmu_send_command(LIMA_MMU_COMMAND_DISABLE_STALL
,
119 !(v
& LIMA_MMU_STATUS_STALL_ACTIVE
));
122 void lima_mmu_page_fault_resume(struct lima_ip
*ip
)
124 struct lima_device
*dev
= ip
->dev
;
125 u32 status
= mmu_read(LIMA_MMU_STATUS
);
128 if (status
& LIMA_MMU_STATUS_PAGE_FAULT_ACTIVE
) {
129 dev_info(dev
->dev
, "mmu resume\n");
131 mmu_write(LIMA_MMU_INT_MASK
, 0);
132 mmu_write(LIMA_MMU_DTE_ADDR
, 0xCAFEBABE);
133 lima_mmu_send_command(LIMA_MMU_COMMAND_HARD_RESET
,
134 LIMA_MMU_DTE_ADDR
, v
, v
== 0);
135 mmu_write(LIMA_MMU_INT_MASK
, LIMA_MMU_INT_PAGE_FAULT
| LIMA_MMU_INT_READ_BUS_ERROR
);
136 mmu_write(LIMA_MMU_DTE_ADDR
, dev
->empty_vm
->pd
.dma
);
137 lima_mmu_send_command(LIMA_MMU_COMMAND_ENABLE_PAGING
,
139 v
& LIMA_MMU_STATUS_PAGING_ENABLED
);