Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0 OR MIT
0002 /* Copyright 2017-2019 Qiang Yu <yuq825@gmail.com> */
0003 
0004 #include <linux/interrupt.h>
0005 #include <linux/iopoll.h>
0006 #include <linux/device.h>
0007 
0008 #include "lima_device.h"
0009 #include "lima_mmu.h"
0010 #include "lima_vm.h"
0011 #include "lima_regs.h"
0012 
0013 #define mmu_write(reg, data) writel(data, ip->iomem + reg)
0014 #define mmu_read(reg) readl(ip->iomem + reg)
0015 
0016 #define lima_mmu_send_command(cmd, addr, val, cond)      \
0017 ({                               \
0018     int __ret;                       \
0019                                  \
0020     mmu_write(LIMA_MMU_COMMAND, cmd);            \
0021     __ret = readl_poll_timeout(ip->iomem + (addr), val,  \
0022                   cond, 0, 100);         \
0023     if (__ret)                       \
0024         dev_err(dev->dev,                \
0025             "mmu command %x timeout\n", cmd);    \
0026     __ret;                           \
0027 })
0028 
0029 static irqreturn_t lima_mmu_irq_handler(int irq, void *data)
0030 {
0031     struct lima_ip *ip = data;
0032     struct lima_device *dev = ip->dev;
0033     u32 status = mmu_read(LIMA_MMU_INT_STATUS);
0034     struct lima_sched_pipe *pipe;
0035 
0036     /* for shared irq case */
0037     if (!status)
0038         return IRQ_NONE;
0039 
0040     if (status & LIMA_MMU_INT_PAGE_FAULT) {
0041         u32 fault = mmu_read(LIMA_MMU_PAGE_FAULT_ADDR);
0042 
0043         dev_err(dev->dev, "mmu page fault at 0x%x from bus id %d of type %s on %s\n",
0044             fault, LIMA_MMU_STATUS_BUS_ID(status),
0045             status & LIMA_MMU_STATUS_PAGE_FAULT_IS_WRITE ? "write" : "read",
0046             lima_ip_name(ip));
0047     }
0048 
0049     if (status & LIMA_MMU_INT_READ_BUS_ERROR)
0050         dev_err(dev->dev, "mmu %s irq bus error\n", lima_ip_name(ip));
0051 
0052     /* mask all interrupts before resume */
0053     mmu_write(LIMA_MMU_INT_MASK, 0);
0054     mmu_write(LIMA_MMU_INT_CLEAR, status);
0055 
0056     pipe = dev->pipe + (ip->id == lima_ip_gpmmu ? lima_pipe_gp : lima_pipe_pp);
0057     lima_sched_pipe_mmu_error(pipe);
0058 
0059     return IRQ_HANDLED;
0060 }
0061 
0062 static int lima_mmu_hw_init(struct lima_ip *ip)
0063 {
0064     struct lima_device *dev = ip->dev;
0065     int err;
0066     u32 v;
0067 
0068     mmu_write(LIMA_MMU_COMMAND, LIMA_MMU_COMMAND_HARD_RESET);
0069     err = lima_mmu_send_command(LIMA_MMU_COMMAND_HARD_RESET,
0070                     LIMA_MMU_DTE_ADDR, v, v == 0);
0071     if (err)
0072         return err;
0073 
0074     mmu_write(LIMA_MMU_INT_MASK,
0075           LIMA_MMU_INT_PAGE_FAULT | LIMA_MMU_INT_READ_BUS_ERROR);
0076     mmu_write(LIMA_MMU_DTE_ADDR, dev->empty_vm->pd.dma);
0077     return lima_mmu_send_command(LIMA_MMU_COMMAND_ENABLE_PAGING,
0078                      LIMA_MMU_STATUS, v,
0079                      v & LIMA_MMU_STATUS_PAGING_ENABLED);
0080 }
0081 
0082 int lima_mmu_resume(struct lima_ip *ip)
0083 {
0084     if (ip->id == lima_ip_ppmmu_bcast)
0085         return 0;
0086 
0087     return lima_mmu_hw_init(ip);
0088 }
0089 
0090 void lima_mmu_suspend(struct lima_ip *ip)
0091 {
0092 
0093 }
0094 
0095 int lima_mmu_init(struct lima_ip *ip)
0096 {
0097     struct lima_device *dev = ip->dev;
0098     int err;
0099 
0100     if (ip->id == lima_ip_ppmmu_bcast)
0101         return 0;
0102 
0103     mmu_write(LIMA_MMU_DTE_ADDR, 0xCAFEBABE);
0104     if (mmu_read(LIMA_MMU_DTE_ADDR) != 0xCAFEB000) {
0105         dev_err(dev->dev, "mmu %s dte write test fail\n", lima_ip_name(ip));
0106         return -EIO;
0107     }
0108 
0109     err = devm_request_irq(dev->dev, ip->irq, lima_mmu_irq_handler,
0110                    IRQF_SHARED, lima_ip_name(ip), ip);
0111     if (err) {
0112         dev_err(dev->dev, "mmu %s fail to request irq\n", lima_ip_name(ip));
0113         return err;
0114     }
0115 
0116     return lima_mmu_hw_init(ip);
0117 }
0118 
0119 void lima_mmu_fini(struct lima_ip *ip)
0120 {
0121 
0122 }
0123 
0124 void lima_mmu_flush_tlb(struct lima_ip *ip)
0125 {
0126     mmu_write(LIMA_MMU_COMMAND, LIMA_MMU_COMMAND_ZAP_CACHE);
0127 }
0128 
0129 void lima_mmu_switch_vm(struct lima_ip *ip, struct lima_vm *vm)
0130 {
0131     struct lima_device *dev = ip->dev;
0132     u32 v;
0133 
0134     lima_mmu_send_command(LIMA_MMU_COMMAND_ENABLE_STALL,
0135                   LIMA_MMU_STATUS, v,
0136                   v & LIMA_MMU_STATUS_STALL_ACTIVE);
0137 
0138     mmu_write(LIMA_MMU_DTE_ADDR, vm->pd.dma);
0139 
0140     /* flush the TLB */
0141     mmu_write(LIMA_MMU_COMMAND, LIMA_MMU_COMMAND_ZAP_CACHE);
0142 
0143     lima_mmu_send_command(LIMA_MMU_COMMAND_DISABLE_STALL,
0144                   LIMA_MMU_STATUS, v,
0145                   !(v & LIMA_MMU_STATUS_STALL_ACTIVE));
0146 }
0147 
0148 void lima_mmu_page_fault_resume(struct lima_ip *ip)
0149 {
0150     struct lima_device *dev = ip->dev;
0151     u32 status = mmu_read(LIMA_MMU_STATUS);
0152     u32 v;
0153 
0154     if (status & LIMA_MMU_STATUS_PAGE_FAULT_ACTIVE) {
0155         dev_info(dev->dev, "mmu resume\n");
0156 
0157         mmu_write(LIMA_MMU_INT_MASK, 0);
0158         mmu_write(LIMA_MMU_DTE_ADDR, 0xCAFEBABE);
0159         lima_mmu_send_command(LIMA_MMU_COMMAND_HARD_RESET,
0160                       LIMA_MMU_DTE_ADDR, v, v == 0);
0161         mmu_write(LIMA_MMU_INT_MASK, LIMA_MMU_INT_PAGE_FAULT | LIMA_MMU_INT_READ_BUS_ERROR);
0162         mmu_write(LIMA_MMU_DTE_ADDR, dev->empty_vm->pd.dma);
0163         lima_mmu_send_command(LIMA_MMU_COMMAND_ENABLE_PAGING,
0164                       LIMA_MMU_STATUS, v,
0165                       v & LIMA_MMU_STATUS_PAGING_ENABLED);
0166     }
0167 }