blob: fc6462953d810f2fa60a1b479833ba44833bf89d [file] [log] [blame]
Jordan Crouse6d76c4d2012-03-26 09:50:43 -06001/* Copyright (c) 2002,2007-2012, Code Aurora Forum. All rights reserved.
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002 *
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 Das84fdb112012-04-04 12:49:31 -060016/*
17 * These defines control the split between ttbr1 and ttbr0 pagetables of IOMMU
18 * and what ranges of memory we map to them
19 */
20#define KGSL_IOMMU_GLOBAL_MEM_BASE 0xC0000000
21#define KGSL_IOMMU_GLOBAL_MEM_SIZE SZ_4M
22#define KGSL_IOMMU_TTBR1_SPLIT 2
23
Shubhraprakash Das767fdda2011-08-15 15:49:45 -060024#define KGSL_MMU_ALIGN_SHIFT 13
25#define KGSL_MMU_ALIGN_MASK (~((1 << KGSL_MMU_ALIGN_SHIFT) - 1))
26
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070027/* Identifier for the global page table */
28/* Per process page tables will probably pass in the thread group
29 as an identifier */
30
31#define KGSL_MMU_GLOBAL_PT 0
32
Shubhraprakash Das767fdda2011-08-15 15:49:45 -060033struct kgsl_device;
34
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070035#define GSL_PT_SUPER_PTE 8
36#define GSL_PT_PAGE_WV 0x00000001
37#define GSL_PT_PAGE_RV 0x00000002
38#define GSL_PT_PAGE_DIRTY 0x00000004
39
40/* MMU registers - the register locations for all cores are the
41 same. The method for getting to those locations differs between
42 2D and 3D, but the 2D and 3D register functions do that magic
43 for us */
44
45#define MH_MMU_CONFIG 0x0040
46#define MH_MMU_VA_RANGE 0x0041
47#define MH_MMU_PT_BASE 0x0042
48#define MH_MMU_PAGE_FAULT 0x0043
49#define MH_MMU_TRAN_ERROR 0x0044
50#define MH_MMU_INVALIDATE 0x0045
51#define MH_MMU_MPU_BASE 0x0046
52#define MH_MMU_MPU_END 0x0047
53
54#define MH_INTERRUPT_MASK 0x0A42
55#define MH_INTERRUPT_STATUS 0x0A43
56#define MH_INTERRUPT_CLEAR 0x0A44
57#define MH_AXI_ERROR 0x0A45
Jeremy Gebben4e8aada2011-07-12 10:07:47 -060058#define MH_ARBITER_CONFIG 0x0A40
59#define MH_DEBUG_CTRL 0x0A4E
60#define MH_DEBUG_DATA 0x0A4F
61#define MH_AXI_HALT_CONTROL 0x0A50
62#define MH_CLNT_INTF_CTRL_CONFIG1 0x0A54
63#define MH_CLNT_INTF_CTRL_CONFIG2 0x0A55
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070064
65/* MH_MMU_CONFIG bit definitions */
66
67#define MH_MMU_CONFIG__RB_W_CLNT_BEHAVIOR__SHIFT 0x00000004
68#define MH_MMU_CONFIG__CP_W_CLNT_BEHAVIOR__SHIFT 0x00000006
69#define MH_MMU_CONFIG__CP_R0_CLNT_BEHAVIOR__SHIFT 0x00000008
70#define MH_MMU_CONFIG__CP_R1_CLNT_BEHAVIOR__SHIFT 0x0000000a
71#define MH_MMU_CONFIG__CP_R2_CLNT_BEHAVIOR__SHIFT 0x0000000c
72#define MH_MMU_CONFIG__CP_R3_CLNT_BEHAVIOR__SHIFT 0x0000000e
73#define MH_MMU_CONFIG__CP_R4_CLNT_BEHAVIOR__SHIFT 0x00000010
74#define MH_MMU_CONFIG__VGT_R0_CLNT_BEHAVIOR__SHIFT 0x00000012
75#define MH_MMU_CONFIG__VGT_R1_CLNT_BEHAVIOR__SHIFT 0x00000014
76#define MH_MMU_CONFIG__TC_R_CLNT_BEHAVIOR__SHIFT 0x00000016
77#define MH_MMU_CONFIG__PA_W_CLNT_BEHAVIOR__SHIFT 0x00000018
78
79/* MMU Flags */
80#define KGSL_MMUFLAGS_TLBFLUSH 0x10000000
81#define KGSL_MMUFLAGS_PTUPDATE 0x20000000
82
83#define MH_INTERRUPT_MASK__AXI_READ_ERROR 0x00000001L
84#define MH_INTERRUPT_MASK__AXI_WRITE_ERROR 0x00000002L
85#define MH_INTERRUPT_MASK__MMU_PAGE_FAULT 0x00000004L
86
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070087#define KGSL_MMU_INT_MASK \
88 (MH_INTERRUPT_MASK__AXI_READ_ERROR | \
89 MH_INTERRUPT_MASK__AXI_WRITE_ERROR | \
90 MH_INTERRUPT_MASK__MMU_PAGE_FAULT)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070091
Shubhraprakash Das767fdda2011-08-15 15:49:45 -060092enum kgsl_mmutype {
93 KGSL_MMU_TYPE_GPU = 0,
94 KGSL_MMU_TYPE_IOMMU,
95 KGSL_MMU_TYPE_NONE
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070096};
97
98struct kgsl_pagetable {
99 spinlock_t lock;
100 struct kref refcount;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700101 unsigned int max_entries;
102 struct gen_pool *pool;
Shubhraprakash Das84fdb112012-04-04 12:49:31 -0600103 struct gen_pool *kgsl_pool;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700104 struct list_head list;
105 unsigned int name;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700106 struct kobject *kobj;
107
108 struct {
109 unsigned int entries;
110 unsigned int mapped;
111 unsigned int max_mapped;
112 unsigned int max_entries;
113 } stats;
Shubhraprakash Das767fdda2011-08-15 15:49:45 -0600114 const struct kgsl_mmu_pt_ops *pt_ops;
Shubhraprakash Dasf764e462012-04-26 15:38:09 -0600115 unsigned int tlb_flags;
Shubhraprakash Das767fdda2011-08-15 15:49:45 -0600116 void *priv;
117};
118
Shubhraprakash Das1c528262012-04-26 17:38:13 -0600119struct kgsl_mmu;
120
Shubhraprakash Das767fdda2011-08-15 15:49:45 -0600121struct kgsl_mmu_ops {
Shubhraprakash Das1c528262012-04-26 17:38:13 -0600122 int (*mmu_init) (struct kgsl_mmu *mmu);
123 int (*mmu_close) (struct kgsl_mmu *mmu);
124 int (*mmu_start) (struct kgsl_mmu *mmu);
Shubhraprakash Das79447952012-04-26 18:12:23 -0600125 void (*mmu_stop) (struct kgsl_mmu *mmu);
Shubhraprakash Das1c528262012-04-26 17:38:13 -0600126 void (*mmu_setstate) (struct kgsl_mmu *mmu,
Shubhraprakash Das767fdda2011-08-15 15:49:45 -0600127 struct kgsl_pagetable *pagetable);
Shubhraprakash Das1c528262012-04-26 17:38:13 -0600128 void (*mmu_device_setstate) (struct kgsl_mmu *mmu,
Shubhraprakash Das767fdda2011-08-15 15:49:45 -0600129 uint32_t flags);
Shubhraprakash Das1c528262012-04-26 17:38:13 -0600130 void (*mmu_pagefault) (struct kgsl_mmu *mmu);
Shubhraprakash Das767fdda2011-08-15 15:49:45 -0600131 unsigned int (*mmu_get_current_ptbase)
Shubhraprakash Das1c528262012-04-26 17:38:13 -0600132 (struct kgsl_mmu *mmu);
Shubhraprakash Das9fb38ac2012-05-01 00:41:30 -0600133 void (*mmu_disable_clk)
134 (struct kgsl_mmu *mmu);
135 int (*mmu_enable_clk)
136 (struct kgsl_mmu *mmu, int ctx_id);
Shubhraprakash Das767fdda2011-08-15 15:49:45 -0600137};
138
139struct kgsl_mmu_pt_ops {
140 int (*mmu_map) (void *mmu_pt,
141 struct kgsl_memdesc *memdesc,
Shubhraprakash Dasf764e462012-04-26 15:38:09 -0600142 unsigned int protflags,
143 unsigned int *tlb_flags);
Shubhraprakash Das767fdda2011-08-15 15:49:45 -0600144 int (*mmu_unmap) (void *mmu_pt,
145 struct kgsl_memdesc *memdesc);
146 void *(*mmu_create_pagetable) (void);
147 void (*mmu_destroy_pagetable) (void *pt);
148 int (*mmu_pt_equal) (struct kgsl_pagetable *pt,
149 unsigned int pt_base);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700150};
151
152struct kgsl_mmu {
153 unsigned int refcnt;
154 uint32_t flags;
155 struct kgsl_device *device;
156 unsigned int config;
Shubhraprakash Das767fdda2011-08-15 15:49:45 -0600157 struct kgsl_memdesc setstate_memory;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700158 /* current page table object being used by device mmu */
159 struct kgsl_pagetable *defaultpagetable;
160 struct kgsl_pagetable *hwpagetable;
Shubhraprakash Das767fdda2011-08-15 15:49:45 -0600161 const struct kgsl_mmu_ops *mmu_ops;
162 void *priv;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700163};
164
Shubhraprakash Das767fdda2011-08-15 15:49:45 -0600165#include "kgsl_gpummu.h"
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700166
Shubhraprakash Das767fdda2011-08-15 15:49:45 -0600167extern struct kgsl_mmu_ops iommu_ops;
168extern struct kgsl_mmu_pt_ops iommu_pt_ops;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700169
170struct kgsl_pagetable *kgsl_mmu_getpagetable(unsigned long name);
Shubhraprakash Das767fdda2011-08-15 15:49:45 -0600171void kgsl_mmu_putpagetable(struct kgsl_pagetable *pagetable);
Jeremy Gebben4e8aada2011-07-12 10:07:47 -0600172void kgsl_mh_start(struct kgsl_device *device);
173void kgsl_mh_intrcallback(struct kgsl_device *device);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700174int kgsl_mmu_init(struct kgsl_device *device);
175int kgsl_mmu_start(struct kgsl_device *device);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700176int kgsl_mmu_close(struct kgsl_device *device);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700177int kgsl_mmu_map(struct kgsl_pagetable *pagetable,
178 struct kgsl_memdesc *memdesc,
179 unsigned int protflags);
180int kgsl_mmu_map_global(struct kgsl_pagetable *pagetable,
181 struct kgsl_memdesc *memdesc, unsigned int protflags);
182int kgsl_mmu_unmap(struct kgsl_pagetable *pagetable,
183 struct kgsl_memdesc *memdesc);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700184unsigned int kgsl_virtaddr_to_physaddr(void *virtaddr);
Shubhraprakash Das1c528262012-04-26 17:38:13 -0600185void kgsl_setstate(struct kgsl_mmu *mmu, uint32_t flags);
Shubhraprakash Das767fdda2011-08-15 15:49:45 -0600186int kgsl_mmu_get_ptname_from_ptbase(unsigned int pt_base);
187int kgsl_mmu_pt_get_flags(struct kgsl_pagetable *pt,
188 enum kgsl_deviceid id);
Shubhraprakash Das767fdda2011-08-15 15:49:45 -0600189void kgsl_mmu_ptpool_destroy(void *ptpool);
Jordan Crouse6d76c4d2012-03-26 09:50:43 -0600190void *kgsl_mmu_ptpool_init(int entries);
Shubhraprakash Das767fdda2011-08-15 15:49:45 -0600191int kgsl_mmu_enabled(void);
Shubhraprakash Das767fdda2011-08-15 15:49:45 -0600192void kgsl_mmu_set_mmutype(char *mmutype);
Shubhraprakash Das767fdda2011-08-15 15:49:45 -0600193enum kgsl_mmutype kgsl_mmu_get_mmutype(void);
Jordan Crouse6d76c4d2012-03-26 09:50:43 -0600194unsigned int kgsl_mmu_get_ptsize(void);
Shubhraprakash Das79447952012-04-26 18:12:23 -0600195
196/*
197 * Static inline functions of MMU that simply call the SMMU specific
198 * function using a function pointer. These functions can be thought
199 * of as wrappers around the actual function
200 */
201
202static inline unsigned int kgsl_mmu_get_current_ptbase(struct kgsl_mmu *mmu)
203{
204 if (mmu->mmu_ops && mmu->mmu_ops->mmu_get_current_ptbase)
205 return mmu->mmu_ops->mmu_get_current_ptbase(mmu);
206 else
207 return 0;
208}
209
210static inline void kgsl_mmu_setstate(struct kgsl_mmu *mmu,
211 struct kgsl_pagetable *pagetable)
212{
213 if (mmu->mmu_ops && mmu->mmu_ops->mmu_setstate)
214 mmu->mmu_ops->mmu_setstate(mmu, pagetable);
215}
216
217static inline void kgsl_mmu_device_setstate(struct kgsl_mmu *mmu,
218 uint32_t flags)
219{
220 if (mmu->mmu_ops && mmu->mmu_ops->mmu_device_setstate)
221 mmu->mmu_ops->mmu_device_setstate(mmu, flags);
222}
223
224static inline void kgsl_mmu_stop(struct kgsl_mmu *mmu)
225{
226 if (mmu->mmu_ops && mmu->mmu_ops->mmu_stop)
227 mmu->mmu_ops->mmu_stop(mmu);
228}
229
230static inline int kgsl_mmu_pt_equal(struct kgsl_pagetable *pt,
231 unsigned int pt_base)
232{
233 if (KGSL_MMU_TYPE_NONE == kgsl_mmu_get_mmutype())
234 return 1;
235 else
236 return pt->pt_ops->mmu_pt_equal(pt, pt_base);
237}
238
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700239#endif /* __KGSL_MMU_H */