blob: 99acccb903658647229eeac358c54fd1a8d7e583 [file] [log] [blame]
Shubhraprakash Das79447952012-04-26 18:12:23 -06001/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
Shubhraprakash Das767fdda2011-08-15 15:49:45 -06002 *
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#include <linux/types.h>
14#include <linux/device.h>
15#include <linux/spinlock.h>
16#include <linux/genalloc.h>
17#include <linux/slab.h>
18#include <linux/iommu.h>
Shubhraprakash Das767fdda2011-08-15 15:49:45 -060019#include <linux/msm_kgsl.h>
20
21#include "kgsl.h"
22#include "kgsl_device.h"
23#include "kgsl_mmu.h"
24#include "kgsl_sharedmem.h"
Shubhraprakash Daseb6df1d2012-05-01 00:55:35 -060025#include "kgsl_iommu.h"
Shubhraprakash Das767fdda2011-08-15 15:49:45 -060026
Shubhraprakash Das9fb38ac2012-05-01 00:41:30 -060027/*
28 * kgsl_iommu_disable_clk - Disable iommu clocks
29 * @mmu - Pointer to mmu structure
30 *
31 * Disables iommu clocks
32 * Return - void
33 */
34static void kgsl_iommu_disable_clk(struct kgsl_mmu *mmu)
35{
36 struct kgsl_iommu *iommu = mmu->priv;
37 struct msm_iommu_drvdata *iommu_drvdata;
38 int i, j;
39
40 for (i = 0; i < iommu->unit_count; i++) {
41 struct kgsl_iommu_unit *iommu_unit = &iommu->iommu_units[i];
42 for (j = 0; j < iommu_unit->dev_count; j++) {
43 if (!iommu_unit->dev[j].clk_enabled)
44 continue;
45 iommu_drvdata = dev_get_drvdata(
46 iommu_unit->dev[j].dev->parent);
47 if (iommu_drvdata->clk)
48 clk_disable_unprepare(iommu_drvdata->clk);
49 clk_disable_unprepare(iommu_drvdata->pclk);
50 iommu_unit->dev[j].clk_enabled = false;
51 }
52 }
53}
54
55/*
56 * kgsl_iommu_enable_clk - Enable iommu clocks
57 * @mmu - Pointer to mmu structure
58 * @ctx_id - The context bank whose clocks are to be turned on
59 *
60 * Enables iommu clocks of a given context
61 * Return: 0 on success else error code
62 */
63static int kgsl_iommu_enable_clk(struct kgsl_mmu *mmu,
64 int ctx_id)
65{
66 int ret = 0;
67 int i, j;
68 struct kgsl_iommu *iommu = mmu->priv;
69 struct msm_iommu_drvdata *iommu_drvdata;
70
71 for (i = 0; i < iommu->unit_count; i++) {
72 struct kgsl_iommu_unit *iommu_unit = &iommu->iommu_units[i];
73 for (j = 0; j < iommu_unit->dev_count; j++) {
74 if (iommu_unit->dev[j].clk_enabled ||
75 ctx_id != iommu_unit->dev[j].ctx_id)
76 continue;
77 iommu_drvdata =
78 dev_get_drvdata(iommu_unit->dev[j].dev->parent);
79 ret = clk_prepare_enable(iommu_drvdata->pclk);
80 if (ret)
81 goto done;
82 if (iommu_drvdata->clk) {
83 ret = clk_prepare_enable(iommu_drvdata->clk);
84 if (ret) {
85 clk_disable_unprepare(
86 iommu_drvdata->pclk);
87 goto done;
88 }
89 }
90 iommu_unit->dev[j].clk_enabled = true;
91 }
92 }
93done:
94 if (ret)
95 kgsl_iommu_disable_clk(mmu);
96 return ret;
97}
98
Shubhraprakash Das767fdda2011-08-15 15:49:45 -060099static int kgsl_iommu_pt_equal(struct kgsl_pagetable *pt,
100 unsigned int pt_base)
101{
Shubhraprakash Das528aa462012-03-01 14:56:28 -0700102 struct iommu_domain *domain = pt ? pt->priv : NULL;
103 return domain && pt_base && ((unsigned int)domain == pt_base);
Shubhraprakash Das767fdda2011-08-15 15:49:45 -0600104}
105
106static void kgsl_iommu_destroy_pagetable(void *mmu_specific_pt)
107{
108 struct iommu_domain *domain = mmu_specific_pt;
109 if (domain)
110 iommu_domain_free(domain);
111}
112
113void *kgsl_iommu_create_pagetable(void)
114{
115 struct iommu_domain *domain = iommu_domain_alloc(0);
116 if (!domain)
117 KGSL_CORE_ERR("Failed to create iommu domain\n");
118
119 return domain;
120}
121
Shubhraprakash Daseb6df1d2012-05-01 00:55:35 -0600122/*
123 * kgsl_detach_pagetable_iommu_domain - Detach the IOMMU unit from a
124 * pagetable
125 * @mmu - Pointer to the device mmu structure
126 * @priv - Flag indicating whether the private or user context is to be
127 * detached
128 *
129 * Detach the IOMMU unit with the domain that is contained in the
130 * hwpagetable of the given mmu. After detaching the IOMMU unit is not
131 * in use because the PTBR will not be set after a detach
132 * Return - void
133 */
Shubhraprakash Das767fdda2011-08-15 15:49:45 -0600134static void kgsl_detach_pagetable_iommu_domain(struct kgsl_mmu *mmu)
135{
136 struct iommu_domain *domain;
137 struct kgsl_iommu *iommu = mmu->priv;
Shubhraprakash Daseb6df1d2012-05-01 00:55:35 -0600138 int i, j;
Shubhraprakash Das767fdda2011-08-15 15:49:45 -0600139
140 BUG_ON(mmu->hwpagetable == NULL);
141 BUG_ON(mmu->hwpagetable->priv == NULL);
142
143 domain = mmu->hwpagetable->priv;
144
Shubhraprakash Daseb6df1d2012-05-01 00:55:35 -0600145 for (i = 0; i < iommu->unit_count; i++) {
146 struct kgsl_iommu_unit *iommu_unit = &iommu->iommu_units[i];
147 for (j = 0; j < iommu_unit->dev_count; j++) {
148 if (iommu_unit->dev[j].attached) {
149 iommu_detach_device(domain,
150 iommu_unit->dev[j].dev);
151 iommu_unit->dev[j].attached = false;
152 KGSL_MEM_INFO(mmu->device, "iommu %p detached "
153 "from user dev of MMU: %p\n",
154 domain, mmu);
155 }
156 }
Shubhraprakash Das767fdda2011-08-15 15:49:45 -0600157 }
158}
159
Shubhraprakash Daseb6df1d2012-05-01 00:55:35 -0600160/*
161 * kgsl_attach_pagetable_iommu_domain - Attach the IOMMU unit to a
162 * pagetable, i.e set the IOMMU's PTBR to the pagetable address and
163 * setup other IOMMU registers for the device so that it becomes
164 * active
165 * @mmu - Pointer to the device mmu structure
166 * @priv - Flag indicating whether the private or user context is to be
167 * attached
168 *
169 * Attach the IOMMU unit with the domain that is contained in the
170 * hwpagetable of the given mmu.
171 * Return - 0 on success else error code
172 */
Shubhraprakash Das767fdda2011-08-15 15:49:45 -0600173static int kgsl_attach_pagetable_iommu_domain(struct kgsl_mmu *mmu)
174{
175 struct iommu_domain *domain;
Shubhraprakash Das767fdda2011-08-15 15:49:45 -0600176 struct kgsl_iommu *iommu = mmu->priv;
Shubhraprakash Daseb6df1d2012-05-01 00:55:35 -0600177 int i, j, ret = 0;
Shubhraprakash Das767fdda2011-08-15 15:49:45 -0600178
179 BUG_ON(mmu->hwpagetable == NULL);
180 BUG_ON(mmu->hwpagetable->priv == NULL);
181
182 domain = mmu->hwpagetable->priv;
183
Shubhraprakash Daseb6df1d2012-05-01 00:55:35 -0600184 /*
185 * Loop through all the iommu devcies under all iommu units and
186 * attach the domain
187 */
188 for (i = 0; i < iommu->unit_count; i++) {
189 struct kgsl_iommu_unit *iommu_unit = &iommu->iommu_units[i];
190 for (j = 0; j < iommu_unit->dev_count; j++) {
191 if (!iommu_unit->dev[j].attached) {
192 ret = iommu_attach_device(domain,
193 iommu_unit->dev[j].dev);
194 if (ret) {
195 KGSL_MEM_ERR(mmu->device,
196 "Failed to attach device, err %d\n",
Jordan Crouse46cf4bb2012-02-21 08:54:52 -0700197 ret);
Shubhraprakash Daseb6df1d2012-05-01 00:55:35 -0600198 goto done;
199 }
200 iommu_unit->dev[j].attached = true;
201 KGSL_MEM_INFO(mmu->device,
202 "iommu pt %p attached to dev %p, ctx_id %d\n",
203 domain, iommu_unit->dev[j].dev,
204 iommu_unit->dev[j].ctx_id);
Jordan Crouse46cf4bb2012-02-21 08:54:52 -0700205 }
Shubhraprakash Das767fdda2011-08-15 15:49:45 -0600206 }
Shubhraprakash Das767fdda2011-08-15 15:49:45 -0600207 }
208done:
209 return ret;
210}
211
Shubhraprakash Daseb6df1d2012-05-01 00:55:35 -0600212/*
213 * _get_iommu_ctxs - Get device pointer to IOMMU contexts
214 * @mmu - Pointer to mmu device
215 * data - Pointer to the platform data containing information about
216 * iommu devices for one iommu unit
217 * unit_id - The IOMMU unit number. This is not a specific ID but just
218 * a serial number. The serial numbers are treated as ID's of the
219 * IOMMU units
220 *
221 * Return - 0 on success else error code
222 */
223static int _get_iommu_ctxs(struct kgsl_mmu *mmu,
224 struct kgsl_device_iommu_data *data, unsigned int unit_id)
Jordan Crouse46cf4bb2012-02-21 08:54:52 -0700225{
Shubhraprakash Daseb6df1d2012-05-01 00:55:35 -0600226 struct kgsl_iommu *iommu = mmu->priv;
227 struct kgsl_iommu_unit *iommu_unit = &iommu->iommu_units[unit_id];
Jordan Crouse46cf4bb2012-02-21 08:54:52 -0700228 int i;
229
Shubhraprakash Daseb6df1d2012-05-01 00:55:35 -0600230 if (data->iommu_ctx_count > KGSL_IOMMU_MAX_DEVS_PER_UNIT) {
231 KGSL_CORE_ERR("Too many iommu devices defined for an "
232 "IOMMU unit\n");
233 return -EINVAL;
234 }
Jordan Crouse46cf4bb2012-02-21 08:54:52 -0700235
Shubhraprakash Daseb6df1d2012-05-01 00:55:35 -0600236 for (i = 0; i < data->iommu_ctx_count; i++) {
237 if (!data->iommu_ctxs[i].iommu_ctx_name)
Jordan Crouse46cf4bb2012-02-21 08:54:52 -0700238 continue;
239
Shubhraprakash Daseb6df1d2012-05-01 00:55:35 -0600240 iommu_unit->dev[iommu_unit->dev_count].dev =
241 msm_iommu_get_ctx(data->iommu_ctxs[i].iommu_ctx_name);
242 if (iommu_unit->dev[iommu_unit->dev_count].dev == NULL) {
243 KGSL_CORE_ERR("Failed to get iommu dev handle for "
244 "device %s\n", data->iommu_ctxs[i].iommu_ctx_name);
Jordan Crouse46cf4bb2012-02-21 08:54:52 -0700245 return -EINVAL;
246 }
Shubhraprakash Daseb6df1d2012-05-01 00:55:35 -0600247 if (KGSL_IOMMU_CONTEXT_USER != data->iommu_ctxs[i].ctx_id &&
248 KGSL_IOMMU_CONTEXT_PRIV != data->iommu_ctxs[i].ctx_id) {
249 KGSL_CORE_ERR("Invalid context ID defined: %d\n",
250 data->iommu_ctxs[i].ctx_id);
251 return -EINVAL;
252 }
253 iommu_unit->dev[iommu_unit->dev_count].ctx_id =
254 data->iommu_ctxs[i].ctx_id;
255 KGSL_DRV_INFO(mmu->device,
256 "Obtained dev handle %p for iommu context %s\n",
257 iommu_unit->dev[iommu_unit->dev_count].dev,
258 data->iommu_ctxs[i].iommu_ctx_name);
Jordan Crouse46cf4bb2012-02-21 08:54:52 -0700259
Shubhraprakash Daseb6df1d2012-05-01 00:55:35 -0600260 iommu_unit->dev_count++;
Jordan Crouse46cf4bb2012-02-21 08:54:52 -0700261 }
262
263 return 0;
264}
265
Shubhraprakash Daseb6df1d2012-05-01 00:55:35 -0600266/*
267 * kgsl_get_iommu_ctxt - Get device pointer to IOMMU contexts
268 * @mmu - Pointer to mmu device
269 *
270 * Get the device pointers for the IOMMU user and priv contexts of the
271 * kgsl device
272 * Return - 0 on success else error code
273 */
274static int kgsl_get_iommu_ctxt(struct kgsl_mmu *mmu)
Shubhraprakash Das767fdda2011-08-15 15:49:45 -0600275{
Shubhraprakash Daseb6df1d2012-05-01 00:55:35 -0600276 struct platform_device *pdev =
277 container_of(mmu->device->parentdev, struct platform_device,
278 dev);
279 struct kgsl_device_platform_data *pdata_dev = pdev->dev.platform_data;
280 struct kgsl_iommu *iommu = mmu->device->mmu.priv;
Jordan Crouse46cf4bb2012-02-21 08:54:52 -0700281 int i, ret = 0;
282
Shubhraprakash Daseb6df1d2012-05-01 00:55:35 -0600283 /* Go through the IOMMU data and get all the context devices */
284 if (KGSL_IOMMU_MAX_UNITS < pdata_dev->iommu_count) {
285 KGSL_CORE_ERR("Too many IOMMU units defined\n");
286 ret = -EINVAL;
287 goto done;
288 }
Jordan Crouse46cf4bb2012-02-21 08:54:52 -0700289
Shubhraprakash Daseb6df1d2012-05-01 00:55:35 -0600290 for (i = 0; i < pdata_dev->iommu_count; i++) {
291 ret = _get_iommu_ctxs(mmu, &pdata_dev->iommu_data[i], i);
Jordan Crouse46cf4bb2012-02-21 08:54:52 -0700292 if (ret)
293 break;
Shubhraprakash Das767fdda2011-08-15 15:49:45 -0600294 }
Shubhraprakash Daseb6df1d2012-05-01 00:55:35 -0600295 iommu->unit_count = pdata_dev->iommu_count;
296done:
Jordan Crouse46cf4bb2012-02-21 08:54:52 -0700297 return ret;
Shubhraprakash Das767fdda2011-08-15 15:49:45 -0600298}
299
Shubhraprakash Das1c528262012-04-26 17:38:13 -0600300static void kgsl_iommu_setstate(struct kgsl_mmu *mmu,
Shubhraprakash Das767fdda2011-08-15 15:49:45 -0600301 struct kgsl_pagetable *pagetable)
302{
Shubhraprakash Das767fdda2011-08-15 15:49:45 -0600303 if (mmu->flags & KGSL_FLAGS_STARTED) {
304 /* page table not current, then setup mmu to use new
305 * specified page table
306 */
307 if (mmu->hwpagetable != pagetable) {
Shubhraprakash Das1c528262012-04-26 17:38:13 -0600308 kgsl_idle(mmu->device, KGSL_TIMEOUT_DEFAULT);
Shubhraprakash Das767fdda2011-08-15 15:49:45 -0600309 kgsl_detach_pagetable_iommu_domain(mmu);
310 mmu->hwpagetable = pagetable;
311 if (mmu->hwpagetable)
312 kgsl_attach_pagetable_iommu_domain(mmu);
313 }
314 }
315}
316
Shubhraprakash Das1c528262012-04-26 17:38:13 -0600317static int kgsl_iommu_init(struct kgsl_mmu *mmu)
Shubhraprakash Das767fdda2011-08-15 15:49:45 -0600318{
319 /*
320 * intialize device mmu
321 *
322 * call this with the global lock held
323 */
324 int status = 0;
Shubhraprakash Das767fdda2011-08-15 15:49:45 -0600325 struct kgsl_iommu *iommu;
326
Shubhraprakash Das767fdda2011-08-15 15:49:45 -0600327 iommu = kzalloc(sizeof(struct kgsl_iommu), GFP_KERNEL);
328 if (!iommu) {
329 KGSL_CORE_ERR("kzalloc(%d) failed\n",
330 sizeof(struct kgsl_iommu));
331 return -ENOMEM;
332 }
333
Shubhraprakash Das767fdda2011-08-15 15:49:45 -0600334 mmu->priv = iommu;
Shubhraprakash Daseb6df1d2012-05-01 00:55:35 -0600335 status = kgsl_get_iommu_ctxt(mmu);
336 if (status)
337 goto done;
Shubhraprakash Das767fdda2011-08-15 15:49:45 -0600338
Shubhraprakash Das1c528262012-04-26 17:38:13 -0600339 dev_info(mmu->device->dev, "|%s| MMU type set for device is IOMMU\n",
Shubhraprakash Das767fdda2011-08-15 15:49:45 -0600340 __func__);
Shubhraprakash Daseb6df1d2012-05-01 00:55:35 -0600341done:
342 if (status) {
343 kfree(iommu);
344 mmu->priv = NULL;
345 }
Shubhraprakash Das767fdda2011-08-15 15:49:45 -0600346 return status;
347}
348
Shubhraprakash Das1c528262012-04-26 17:38:13 -0600349static int kgsl_iommu_start(struct kgsl_mmu *mmu)
Shubhraprakash Das767fdda2011-08-15 15:49:45 -0600350{
351 int status;
Shubhraprakash Das767fdda2011-08-15 15:49:45 -0600352
353 if (mmu->flags & KGSL_FLAGS_STARTED)
354 return 0;
355
Shubhraprakash Das1c528262012-04-26 17:38:13 -0600356 kgsl_regwrite(mmu->device, MH_MMU_CONFIG, 0x00000000);
Shubhraprakash Das767fdda2011-08-15 15:49:45 -0600357 if (mmu->defaultpagetable == NULL)
358 mmu->defaultpagetable =
359 kgsl_mmu_getpagetable(KGSL_MMU_GLOBAL_PT);
360 /* Return error if the default pagetable doesn't exist */
361 if (mmu->defaultpagetable == NULL)
362 return -ENOMEM;
363 mmu->hwpagetable = mmu->defaultpagetable;
364
365 status = kgsl_attach_pagetable_iommu_domain(mmu);
Shubhraprakash Daseb6df1d2012-05-01 00:55:35 -0600366 if (!status) {
Shubhraprakash Das767fdda2011-08-15 15:49:45 -0600367 mmu->flags |= KGSL_FLAGS_STARTED;
Shubhraprakash Daseb6df1d2012-05-01 00:55:35 -0600368 } else {
369 kgsl_detach_pagetable_iommu_domain(mmu);
370 mmu->hwpagetable = NULL;
371 }
Shubhraprakash Das767fdda2011-08-15 15:49:45 -0600372
373 return status;
374}
375
376static int
377kgsl_iommu_unmap(void *mmu_specific_pt,
378 struct kgsl_memdesc *memdesc)
379{
380 int ret;
381 unsigned int range = memdesc->size;
Shubhraprakash Das767fdda2011-08-15 15:49:45 -0600382 struct iommu_domain *domain = (struct iommu_domain *)
383 mmu_specific_pt;
384
385 /* All GPU addresses as assigned are page aligned, but some
386 functions purturb the gpuaddr with an offset, so apply the
387 mask here to make sure we have the right address */
388
389 unsigned int gpuaddr = memdesc->gpuaddr & KGSL_MMU_ALIGN_MASK;
390
391 if (range == 0 || gpuaddr == 0)
392 return 0;
393
Shubhraprakash Das08894b92011-10-14 11:42:25 -0600394 ret = iommu_unmap_range(domain, gpuaddr, range);
395 if (ret)
396 KGSL_CORE_ERR("iommu_unmap_range(%p, %x, %d) failed "
397 "with err: %d\n", domain, gpuaddr,
398 range, ret);
Shubhraprakash Das767fdda2011-08-15 15:49:45 -0600399
400 return 0;
401}
402
403static int
404kgsl_iommu_map(void *mmu_specific_pt,
405 struct kgsl_memdesc *memdesc,
Shubhraprakash Dasf764e462012-04-26 15:38:09 -0600406 unsigned int protflags,
407 unsigned int *tlb_flags)
Shubhraprakash Das767fdda2011-08-15 15:49:45 -0600408{
Shubhraprakash Das08894b92011-10-14 11:42:25 -0600409 int ret;
Shubhraprakash Das767fdda2011-08-15 15:49:45 -0600410 unsigned int iommu_virt_addr;
Jordan Croused17e9aa2011-10-12 16:57:48 -0600411 struct iommu_domain *domain = mmu_specific_pt;
Shubhraprakash Das767fdda2011-08-15 15:49:45 -0600412
413 BUG_ON(NULL == domain);
414
Shubhraprakash Das767fdda2011-08-15 15:49:45 -0600415
Jordan Croused17e9aa2011-10-12 16:57:48 -0600416 iommu_virt_addr = memdesc->gpuaddr;
417
Shubhraprakash Das08894b92011-10-14 11:42:25 -0600418 ret = iommu_map_range(domain, iommu_virt_addr, memdesc->sg,
Olav Hauganf310cf22012-05-08 08:42:49 -0700419 memdesc->size, (IOMMU_READ | IOMMU_WRITE));
Shubhraprakash Das08894b92011-10-14 11:42:25 -0600420 if (ret) {
421 KGSL_CORE_ERR("iommu_map_range(%p, %x, %p, %d, %d) "
422 "failed with err: %d\n", domain,
423 iommu_virt_addr, memdesc->sg, memdesc->size,
Stepan Moskovchenko6ee3be82011-11-08 15:24:53 -0800424 0, ret);
Shubhraprakash Das08894b92011-10-14 11:42:25 -0600425 return ret;
Shubhraprakash Das767fdda2011-08-15 15:49:45 -0600426 }
427
Shubhraprakash Dasf764e462012-04-26 15:38:09 -0600428#ifdef CONFIG_KGSL_PER_PROCESS_PAGE_TABLE
429 /*
430 * Flushing only required if per process pagetables are used. With
431 * global case, flushing will happen inside iommu_map function
432 */
433 if (!ret)
434 *tlb_flags = UINT_MAX;
435#endif
Shubhraprakash Das767fdda2011-08-15 15:49:45 -0600436 return ret;
437}
438
Shubhraprakash Das79447952012-04-26 18:12:23 -0600439static void kgsl_iommu_stop(struct kgsl_mmu *mmu)
Shubhraprakash Das767fdda2011-08-15 15:49:45 -0600440{
441 /*
442 * stop device mmu
443 *
444 * call this with the global lock held
445 */
Shubhraprakash Das767fdda2011-08-15 15:49:45 -0600446
447 if (mmu->flags & KGSL_FLAGS_STARTED) {
448 /* detach iommu attachment */
449 kgsl_detach_pagetable_iommu_domain(mmu);
Shubhraprakash Daseb6df1d2012-05-01 00:55:35 -0600450 mmu->hwpagetable = NULL;
Shubhraprakash Das767fdda2011-08-15 15:49:45 -0600451
452 mmu->flags &= ~KGSL_FLAGS_STARTED;
453 }
Shubhraprakash Das767fdda2011-08-15 15:49:45 -0600454}
455
Shubhraprakash Das1c528262012-04-26 17:38:13 -0600456static int kgsl_iommu_close(struct kgsl_mmu *mmu)
Shubhraprakash Das767fdda2011-08-15 15:49:45 -0600457{
Shubhraprakash Das767fdda2011-08-15 15:49:45 -0600458 if (mmu->defaultpagetable)
459 kgsl_mmu_putpagetable(mmu->defaultpagetable);
460
461 return 0;
462}
463
464static unsigned int
Shubhraprakash Das1c528262012-04-26 17:38:13 -0600465kgsl_iommu_get_current_ptbase(struct kgsl_mmu *mmu)
Shubhraprakash Das767fdda2011-08-15 15:49:45 -0600466{
467 /* Current base is always the hwpagetables domain as we
468 * do not use per process pagetables right not for iommu.
469 * This will change when we switch to per process pagetables.
470 */
Shubhraprakash Das1c528262012-04-26 17:38:13 -0600471 return (unsigned int)mmu->hwpagetable->priv;
Shubhraprakash Das767fdda2011-08-15 15:49:45 -0600472}
473
474struct kgsl_mmu_ops iommu_ops = {
475 .mmu_init = kgsl_iommu_init,
476 .mmu_close = kgsl_iommu_close,
477 .mmu_start = kgsl_iommu_start,
478 .mmu_stop = kgsl_iommu_stop,
479 .mmu_setstate = kgsl_iommu_setstate,
480 .mmu_device_setstate = NULL,
481 .mmu_pagefault = NULL,
482 .mmu_get_current_ptbase = kgsl_iommu_get_current_ptbase,
Shubhraprakash Das9fb38ac2012-05-01 00:41:30 -0600483 .mmu_enable_clk = kgsl_iommu_enable_clk,
484 .mmu_disable_clk = kgsl_iommu_disable_clk,
Shubhraprakash Das767fdda2011-08-15 15:49:45 -0600485};
486
487struct kgsl_mmu_pt_ops iommu_pt_ops = {
488 .mmu_map = kgsl_iommu_map,
489 .mmu_unmap = kgsl_iommu_unmap,
490 .mmu_create_pagetable = kgsl_iommu_create_pagetable,
491 .mmu_destroy_pagetable = kgsl_iommu_destroy_pagetable,
492 .mmu_pt_equal = kgsl_iommu_pt_equal,
Shubhraprakash Das767fdda2011-08-15 15:49:45 -0600493};