blob: 1338d0d4b00839367d0d65d829b81f6b1a1dd7fc [file] [log] [blame]
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001/* Copyright (c) 2002,2007-2011, Code Aurora Forum. All rights reserved.
2 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and
5 * only version 2 as published by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 */
13#ifndef __KGSL_MMU_H
14#define __KGSL_MMU_H
15
Shubhraprakash Das767fdda2011-08-15 15:49:45 -060016#define KGSL_MMU_ALIGN_SHIFT 13
17#define KGSL_MMU_ALIGN_MASK (~((1 << KGSL_MMU_ALIGN_SHIFT) - 1))
18
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070019/* Identifier for the global page table */
20/* Per process page tables will probably pass in the thread group
21 as an identifier */
22
23#define KGSL_MMU_GLOBAL_PT 0
24
Shubhraprakash Das767fdda2011-08-15 15:49:45 -060025struct kgsl_device;
26
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070027#define GSL_PT_SUPER_PTE 8
28#define GSL_PT_PAGE_WV 0x00000001
29#define GSL_PT_PAGE_RV 0x00000002
30#define GSL_PT_PAGE_DIRTY 0x00000004
31
32/* MMU registers - the register locations for all cores are the
33 same. The method for getting to those locations differs between
34 2D and 3D, but the 2D and 3D register functions do that magic
35 for us */
36
37#define MH_MMU_CONFIG 0x0040
38#define MH_MMU_VA_RANGE 0x0041
39#define MH_MMU_PT_BASE 0x0042
40#define MH_MMU_PAGE_FAULT 0x0043
41#define MH_MMU_TRAN_ERROR 0x0044
42#define MH_MMU_INVALIDATE 0x0045
43#define MH_MMU_MPU_BASE 0x0046
44#define MH_MMU_MPU_END 0x0047
45
46#define MH_INTERRUPT_MASK 0x0A42
47#define MH_INTERRUPT_STATUS 0x0A43
48#define MH_INTERRUPT_CLEAR 0x0A44
49#define MH_AXI_ERROR 0x0A45
Jeremy Gebben4e8aada2011-07-12 10:07:47 -060050#define MH_ARBITER_CONFIG 0x0A40
51#define MH_DEBUG_CTRL 0x0A4E
52#define MH_DEBUG_DATA 0x0A4F
53#define MH_AXI_HALT_CONTROL 0x0A50
54#define MH_CLNT_INTF_CTRL_CONFIG1 0x0A54
55#define MH_CLNT_INTF_CTRL_CONFIG2 0x0A55
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070056
57/* MH_MMU_CONFIG bit definitions */
58
59#define MH_MMU_CONFIG__RB_W_CLNT_BEHAVIOR__SHIFT 0x00000004
60#define MH_MMU_CONFIG__CP_W_CLNT_BEHAVIOR__SHIFT 0x00000006
61#define MH_MMU_CONFIG__CP_R0_CLNT_BEHAVIOR__SHIFT 0x00000008
62#define MH_MMU_CONFIG__CP_R1_CLNT_BEHAVIOR__SHIFT 0x0000000a
63#define MH_MMU_CONFIG__CP_R2_CLNT_BEHAVIOR__SHIFT 0x0000000c
64#define MH_MMU_CONFIG__CP_R3_CLNT_BEHAVIOR__SHIFT 0x0000000e
65#define MH_MMU_CONFIG__CP_R4_CLNT_BEHAVIOR__SHIFT 0x00000010
66#define MH_MMU_CONFIG__VGT_R0_CLNT_BEHAVIOR__SHIFT 0x00000012
67#define MH_MMU_CONFIG__VGT_R1_CLNT_BEHAVIOR__SHIFT 0x00000014
68#define MH_MMU_CONFIG__TC_R_CLNT_BEHAVIOR__SHIFT 0x00000016
69#define MH_MMU_CONFIG__PA_W_CLNT_BEHAVIOR__SHIFT 0x00000018
70
71/* MMU Flags */
72#define KGSL_MMUFLAGS_TLBFLUSH 0x10000000
73#define KGSL_MMUFLAGS_PTUPDATE 0x20000000
74
75#define MH_INTERRUPT_MASK__AXI_READ_ERROR 0x00000001L
76#define MH_INTERRUPT_MASK__AXI_WRITE_ERROR 0x00000002L
77#define MH_INTERRUPT_MASK__MMU_PAGE_FAULT 0x00000004L
78
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070079#define KGSL_MMU_INT_MASK \
80 (MH_INTERRUPT_MASK__AXI_READ_ERROR | \
81 MH_INTERRUPT_MASK__AXI_WRITE_ERROR | \
82 MH_INTERRUPT_MASK__MMU_PAGE_FAULT)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070083
Shubhraprakash Das767fdda2011-08-15 15:49:45 -060084enum kgsl_mmutype {
85 KGSL_MMU_TYPE_GPU = 0,
86 KGSL_MMU_TYPE_IOMMU,
87 KGSL_MMU_TYPE_NONE
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070088};
89
90struct kgsl_pagetable {
91 spinlock_t lock;
92 struct kref refcount;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070093 unsigned int max_entries;
94 struct gen_pool *pool;
95 struct list_head list;
96 unsigned int name;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070097 struct kobject *kobj;
98
99 struct {
100 unsigned int entries;
101 unsigned int mapped;
102 unsigned int max_mapped;
103 unsigned int max_entries;
104 } stats;
Shubhraprakash Das767fdda2011-08-15 15:49:45 -0600105 const struct kgsl_mmu_pt_ops *pt_ops;
106 void *priv;
107};
108
109struct kgsl_mmu_ops {
110 int (*mmu_init) (struct kgsl_device *device);
111 int (*mmu_close) (struct kgsl_device *device);
112 int (*mmu_start) (struct kgsl_device *device);
113 int (*mmu_stop) (struct kgsl_device *device);
114 void (*mmu_setstate) (struct kgsl_device *device,
115 struct kgsl_pagetable *pagetable);
116 void (*mmu_device_setstate) (struct kgsl_device *device,
117 uint32_t flags);
118 void (*mmu_pagefault) (struct kgsl_device *device);
119 unsigned int (*mmu_get_current_ptbase)
120 (struct kgsl_device *device);
121};
122
123struct kgsl_mmu_pt_ops {
124 int (*mmu_map) (void *mmu_pt,
125 struct kgsl_memdesc *memdesc,
126 unsigned int protflags);
127 int (*mmu_unmap) (void *mmu_pt,
128 struct kgsl_memdesc *memdesc);
129 void *(*mmu_create_pagetable) (void);
130 void (*mmu_destroy_pagetable) (void *pt);
131 int (*mmu_pt_equal) (struct kgsl_pagetable *pt,
132 unsigned int pt_base);
133 unsigned int (*mmu_pt_get_flags) (struct kgsl_pagetable *pt,
134 enum kgsl_deviceid id);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700135};
136
137struct kgsl_mmu {
138 unsigned int refcnt;
139 uint32_t flags;
140 struct kgsl_device *device;
141 unsigned int config;
Shubhraprakash Das767fdda2011-08-15 15:49:45 -0600142 struct kgsl_memdesc setstate_memory;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700143 /* current page table object being used by device mmu */
144 struct kgsl_pagetable *defaultpagetable;
145 struct kgsl_pagetable *hwpagetable;
Shubhraprakash Das767fdda2011-08-15 15:49:45 -0600146 const struct kgsl_mmu_ops *mmu_ops;
147 void *priv;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700148};
149
Shubhraprakash Das767fdda2011-08-15 15:49:45 -0600150#include "kgsl_gpummu.h"
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700151
Shubhraprakash Das767fdda2011-08-15 15:49:45 -0600152extern struct kgsl_mmu_ops iommu_ops;
153extern struct kgsl_mmu_pt_ops iommu_pt_ops;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700154
155struct kgsl_pagetable *kgsl_mmu_getpagetable(unsigned long name);
Shubhraprakash Das767fdda2011-08-15 15:49:45 -0600156void kgsl_mmu_putpagetable(struct kgsl_pagetable *pagetable);
Jeremy Gebben4e8aada2011-07-12 10:07:47 -0600157void kgsl_mh_start(struct kgsl_device *device);
158void kgsl_mh_intrcallback(struct kgsl_device *device);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700159int kgsl_mmu_init(struct kgsl_device *device);
160int kgsl_mmu_start(struct kgsl_device *device);
161int kgsl_mmu_stop(struct kgsl_device *device);
162int kgsl_mmu_close(struct kgsl_device *device);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700163int kgsl_mmu_map(struct kgsl_pagetable *pagetable,
164 struct kgsl_memdesc *memdesc,
165 unsigned int protflags);
166int kgsl_mmu_map_global(struct kgsl_pagetable *pagetable,
167 struct kgsl_memdesc *memdesc, unsigned int protflags);
168int kgsl_mmu_unmap(struct kgsl_pagetable *pagetable,
169 struct kgsl_memdesc *memdesc);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700170unsigned int kgsl_virtaddr_to_physaddr(void *virtaddr);
171void kgsl_setstate(struct kgsl_device *device, uint32_t flags);
Shubhraprakash Das767fdda2011-08-15 15:49:45 -0600172void kgsl_mmu_device_setstate(struct kgsl_device *device, uint32_t flags);
173void kgsl_mmu_setstate(struct kgsl_device *device,
174 struct kgsl_pagetable *pt);
175int kgsl_mmu_get_ptname_from_ptbase(unsigned int pt_base);
176int kgsl_mmu_pt_get_flags(struct kgsl_pagetable *pt,
177 enum kgsl_deviceid id);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700178
Shubhraprakash Das767fdda2011-08-15 15:49:45 -0600179void kgsl_mmu_ptpool_destroy(void *ptpool);
180void *kgsl_mmu_ptpool_init(int ptsize, int entries);
181int kgsl_mmu_enabled(void);
182int kgsl_mmu_pt_equal(struct kgsl_pagetable *pt,
183 unsigned int pt_base);
184void kgsl_mmu_set_mmutype(char *mmutype);
185unsigned int kgsl_mmu_get_current_ptbase(struct kgsl_device *device);
186enum kgsl_mmutype kgsl_mmu_get_mmutype(void);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700187#endif /* __KGSL_MMU_H */