17
#include <asm-generic/dma-mapping.h>
19
#include "etnaviv_compat.h"
20
#include "etnaviv_cmdbuf.h"
21
#include "etnaviv_gpu.h"
22
#include "etnaviv_mmu.h"
23
#include "etnaviv_drv.h"
24
#include "etnaviv_iommu.h"
26
#include <etnaviv_xml/state.xml.h>
27
#include <etnaviv_xml/state_hi.xml.h>
29
#define MMUv2_PTE_PRESENT BIT(0)
30
#define MMUv2_PTE_EXCEPTION BIT(1)
31
#define MMUv2_PTE_WRITEABLE BIT(2)
33
#define MMUv2_MTLB_MASK 0xffc00000
34
#define MMUv2_MTLB_SHIFT 22
35
#define MMUv2_STLB_MASK 0x003ff000
36
#define MMUv2_STLB_SHIFT 12
38
#define MMUv2_MAX_STLB_ENTRIES 1024
40
static int etnaviv_iommuv2_init(struct etnaviv_gpu *gpu) {
44
struct etnaviv_iommuv2_domain *etnaviv_domain = (void*) gpu->mmu.domain;
46
etnaviv_domain->bad_page_cpu = dma_alloc_coherent(etnaviv_domain->dev,
48
&etnaviv_domain->bad_page_dma,
50
if (!etnaviv_domain->bad_page_cpu) {
54
p = etnaviv_domain->bad_page_cpu;
55
for (i = 0; i < SZ_4K / 4; i++)
58
etnaviv_domain->mtlb_cpu = dma_alloc_coherent(etnaviv_domain->dev,
60
&etnaviv_domain->mtlb_dma,
62
if (!etnaviv_domain->mtlb_cpu) {
68
for (i = 0; i < MMUv2_MAX_STLB_ENTRIES; i++) {
69
etnaviv_domain->stlb_cpu[i] =
70
dma_alloc_coherent(etnaviv_domain->dev,
72
&etnaviv_domain->stlb_dma[i],
74
if (!etnaviv_domain->stlb_cpu[i]) {
78
p = etnaviv_domain->stlb_cpu[i];
79
for (j = 0; j < SZ_4K / 4; j++)
80
*p++ = MMUv2_PTE_EXCEPTION;
82
etnaviv_domain->mtlb_cpu[i] = etnaviv_domain->stlb_dma[i] |
89
if (etnaviv_domain->bad_page_cpu)
90
dma_free_coherent(etnaviv_domain->dev, SZ_4K,
91
etnaviv_domain->bad_page_cpu,
92
etnaviv_domain->bad_page_dma);
94
if (etnaviv_domain->mtlb_cpu)
95
dma_free_coherent(etnaviv_domain->dev, SZ_4K,
96
etnaviv_domain->mtlb_cpu,
97
etnaviv_domain->mtlb_dma);
99
for (i = 0; i < MMUv2_MAX_STLB_ENTRIES; i++) {
100
if (etnaviv_domain->stlb_cpu[i])
101
dma_free_coherent(etnaviv_domain->dev, SZ_4K,
102
etnaviv_domain->stlb_cpu[i],
103
etnaviv_domain->stlb_dma[i]);
109
void etnaviv_iommuv2_restore(struct etnaviv_gpu *gpu) {
110
struct etnaviv_iommuv2_domain *etnaviv_domain = (void *) gpu->mmu.domain;
114
if (gpu_read(gpu, VIVS_MMUv2_CONTROL) & VIVS_MMUv2_CONTROL_ENABLE)
117
prefetch = etnaviv_buffer_config_mmuv2(gpu,
118
(uint32_t)etnaviv_domain->mtlb_dma,
119
(uint32_t)etnaviv_domain->bad_page_dma);
120
etnaviv_gpu_start_fe(gpu, (uint32_t)etnaviv_cmdbuf_get_pa(gpu->buffer),
122
etnaviv_gpu_wait_idle(gpu, 100);
124
gpu_write(gpu, VIVS_MMUv2_CONTROL, VIVS_MMUv2_CONTROL_ENABLE);
127
int etnaviv_iommuv2_domain_init(struct etnaviv_gpu *gpu) {
128
gpu->mmu.start_addr = 0;
129
gpu->mmu.end_addr = 4096 - 1;
131
memset(gpu->mmu.domain, 0, sizeof(struct etnaviv_iommuv2_domain));
132
if (etnaviv_iommuv2_init(gpu)) {