blob: 4430daf9c78f22c75584bc7d33a6e7783f43d2a4 [file] [log] [blame]
Omar Ramirez Luna5cc28e62010-06-23 16:01:59 +03001/*
2 * hw_mmu.c
3 *
4 * DSP-BIOS Bridge driver support functions for TI OMAP processors.
5 *
6 * API definitions to setup MMU TLB and PTE
7 *
8 * Copyright (C) 2007 Texas Instruments, Inc.
9 *
10 * This package is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
13 *
14 * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
15 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
16 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
17 */
18
19#include <GlobalTypes.h>
20#include <linux/io.h>
21#include "MMURegAcM.h"
22#include <hw_defs.h>
23#include <hw_mmu.h>
24#include <linux/types.h>
25
26#define MMU_BASE_VAL_MASK 0xFC00
27#define MMU_PAGE_MAX 3
28#define MMU_ELEMENTSIZE_MAX 3
29#define MMU_ADDR_MASK 0xFFFFF000
30#define MMU_TTB_MASK 0xFFFFC000
31#define MMU_SECTION_ADDR_MASK 0xFFF00000
32#define MMU_SSECTION_ADDR_MASK 0xFF000000
33#define MMU_PAGE_TABLE_MASK 0xFFFFFC00
34#define MMU_LARGE_PAGE_MASK 0xFFFF0000
35#define MMU_SMALL_PAGE_MASK 0xFFFFF000
36
37#define MMU_LOAD_TLB 0x00000001
Felipe Contreras4574fae2010-07-04 16:34:31 +030038#define MMU_GFLUSH 0x60
Omar Ramirez Luna5cc28e62010-06-23 16:01:59 +030039
40/*
41 * hw_mmu_page_size_t: Enumerated Type used to specify the MMU Page Size(SLSS)
42 */
43enum hw_mmu_page_size_t {
44 HW_MMU_SECTION,
45 HW_MMU_LARGE_PAGE,
46 HW_MMU_SMALL_PAGE,
47 HW_MMU_SUPERSECTION
48};
49
50/*
51 * FUNCTION : mmu_flush_entry
52 *
53 * INPUTS:
54 *
Rene Sapiensa6bff482010-07-08 18:11:08 -050055 * Identifier : base_address
Omar Ramirez Luna5cc28e62010-06-23 16:01:59 +030056 * Type : const u32
57 * Description : Base Address of instance of MMU module
58 *
59 * RETURNS:
60 *
61 * Type : hw_status
62 * Description : RET_OK -- No errors occured
63 * RET_BAD_NULL_PARAM -- A Pointer
64 * Paramater was set to NULL
65 *
66 * PURPOSE: : Flush the TLB entry pointed by the
67 * lock counter register
68 * even if this entry is set protected
69 *
70 * METHOD: : Check the Input parameter and Flush a
71 * single entry in the TLB.
72 */
Rene Sapiensa6bff482010-07-08 18:11:08 -050073static hw_status mmu_flush_entry(const void __iomem *base_address);
Omar Ramirez Luna5cc28e62010-06-23 16:01:59 +030074
75/*
76 * FUNCTION : mmu_set_cam_entry
77 *
78 * INPUTS:
79 *
Rene Sapiensa6bff482010-07-08 18:11:08 -050080 * Identifier : base_address
Omar Ramirez Luna5cc28e62010-06-23 16:01:59 +030081 * TypE : const u32
82 * Description : Base Address of instance of MMU module
83 *
84 * Identifier : pageSize
85 * TypE : const u32
86 * Description : It indicates the page size
87 *
88 * Identifier : preservedBit
89 * Type : const u32
90 * Description : It indicates the TLB entry is preserved entry
91 * or not
92 *
93 * Identifier : validBit
94 * Type : const u32
95 * Description : It indicates the TLB entry is valid entry or not
96 *
97 *
98 * Identifier : virtual_addr_tag
99 * Type : const u32
100 * Description : virtual Address
101 *
102 * RETURNS:
103 *
104 * Type : hw_status
105 * Description : RET_OK -- No errors occured
106 * RET_BAD_NULL_PARAM -- A Pointer Paramater
107 * was set to NULL
108 * RET_PARAM_OUT_OF_RANGE -- Input Parameter out
109 * of Range
110 *
111 * PURPOSE: : Set MMU_CAM reg
112 *
113 * METHOD: : Check the Input parameters and set the CAM entry.
114 */
Rene Sapiensa6bff482010-07-08 18:11:08 -0500115static hw_status mmu_set_cam_entry(const void __iomem *base_address,
Omar Ramirez Luna5cc28e62010-06-23 16:01:59 +0300116 const u32 pageSize,
117 const u32 preservedBit,
118 const u32 validBit,
119 const u32 virtual_addr_tag);
120
121/*
122 * FUNCTION : mmu_set_ram_entry
123 *
124 * INPUTS:
125 *
Rene Sapiensa6bff482010-07-08 18:11:08 -0500126 * Identifier : base_address
Omar Ramirez Luna5cc28e62010-06-23 16:01:59 +0300127 * Type : const u32
128 * Description : Base Address of instance of MMU module
129 *
130 * Identifier : physicalAddr
131 * Type : const u32
132 * Description : Physical Address to which the corresponding
133 * virtual Address shouldpoint
134 *
135 * Identifier : endianism
136 * Type : hw_endianism_t
137 * Description : endianism for the given page
138 *
139 * Identifier : element_size
140 * Type : hw_element_size_t
141 * Description : The element size ( 8,16, 32 or 64 bit)
142 *
143 * Identifier : mixed_size
144 * Type : hw_mmu_mixed_size_t
145 * Description : Element Size to follow CPU or TLB
146 *
147 * RETURNS:
148 *
149 * Type : hw_status
150 * Description : RET_OK -- No errors occured
151 * RET_BAD_NULL_PARAM -- A Pointer Paramater
152 * was set to NULL
153 * RET_PARAM_OUT_OF_RANGE -- Input Parameter
154 * out of Range
155 *
156 * PURPOSE: : Set MMU_CAM reg
157 *
158 * METHOD: : Check the Input parameters and set the RAM entry.
159 */
Rene Sapiensa6bff482010-07-08 18:11:08 -0500160static hw_status mmu_set_ram_entry(const void __iomem *base_address,
Omar Ramirez Luna5cc28e62010-06-23 16:01:59 +0300161 const u32 physicalAddr,
162 enum hw_endianism_t endianism,
163 enum hw_element_size_t element_size,
164 enum hw_mmu_mixed_size_t mixed_size);
165
166/* HW FUNCTIONS */
167
Rene Sapiensa6bff482010-07-08 18:11:08 -0500168hw_status hw_mmu_enable(const void __iomem *base_address)
Omar Ramirez Luna5cc28e62010-06-23 16:01:59 +0300169{
170 hw_status status = RET_OK;
171
Rene Sapiensa6bff482010-07-08 18:11:08 -0500172 MMUMMU_CNTLMMU_ENABLE_WRITE32(base_address, HW_SET);
Omar Ramirez Luna5cc28e62010-06-23 16:01:59 +0300173
174 return status;
175}
176
Rene Sapiensa6bff482010-07-08 18:11:08 -0500177hw_status hw_mmu_disable(const void __iomem *base_address)
Omar Ramirez Luna5cc28e62010-06-23 16:01:59 +0300178{
179 hw_status status = RET_OK;
180
Rene Sapiensa6bff482010-07-08 18:11:08 -0500181 MMUMMU_CNTLMMU_ENABLE_WRITE32(base_address, HW_CLEAR);
Omar Ramirez Luna5cc28e62010-06-23 16:01:59 +0300182
183 return status;
184}
185
Rene Sapiensa6bff482010-07-08 18:11:08 -0500186hw_status hw_mmu_num_locked_set(const void __iomem *base_address,
Omar Ramirez Luna5cc28e62010-06-23 16:01:59 +0300187 u32 numLockedEntries)
188{
189 hw_status status = RET_OK;
190
Rene Sapiensa6bff482010-07-08 18:11:08 -0500191 MMUMMU_LOCK_BASE_VALUE_WRITE32(base_address, numLockedEntries);
Omar Ramirez Luna5cc28e62010-06-23 16:01:59 +0300192
193 return status;
194}
195
Rene Sapiensa6bff482010-07-08 18:11:08 -0500196hw_status hw_mmu_victim_num_set(const void __iomem *base_address,
Omar Ramirez Luna5cc28e62010-06-23 16:01:59 +0300197 u32 victimEntryNum)
198{
199 hw_status status = RET_OK;
200
Rene Sapiensa6bff482010-07-08 18:11:08 -0500201 MMUMMU_LOCK_CURRENT_VICTIM_WRITE32(base_address, victimEntryNum);
Omar Ramirez Luna5cc28e62010-06-23 16:01:59 +0300202
203 return status;
204}
205
Rene Sapiensa6bff482010-07-08 18:11:08 -0500206hw_status hw_mmu_event_ack(const void __iomem *base_address, u32 irqMask)
Omar Ramirez Luna5cc28e62010-06-23 16:01:59 +0300207{
208 hw_status status = RET_OK;
209
Rene Sapiensa6bff482010-07-08 18:11:08 -0500210 MMUMMU_IRQSTATUS_WRITE_REGISTER32(base_address, irqMask);
Omar Ramirez Luna5cc28e62010-06-23 16:01:59 +0300211
212 return status;
213}
214
Rene Sapiensa6bff482010-07-08 18:11:08 -0500215hw_status hw_mmu_event_disable(const void __iomem *base_address, u32 irqMask)
Omar Ramirez Luna5cc28e62010-06-23 16:01:59 +0300216{
217 hw_status status = RET_OK;
218 u32 irq_reg;
219
Rene Sapiensa6bff482010-07-08 18:11:08 -0500220 irq_reg = MMUMMU_IRQENABLE_READ_REGISTER32(base_address);
Omar Ramirez Luna5cc28e62010-06-23 16:01:59 +0300221
Rene Sapiensa6bff482010-07-08 18:11:08 -0500222 MMUMMU_IRQENABLE_WRITE_REGISTER32(base_address, irq_reg & ~irqMask);
Omar Ramirez Luna5cc28e62010-06-23 16:01:59 +0300223
224 return status;
225}
226
Rene Sapiensa6bff482010-07-08 18:11:08 -0500227hw_status hw_mmu_event_enable(const void __iomem *base_address, u32 irqMask)
Omar Ramirez Luna5cc28e62010-06-23 16:01:59 +0300228{
229 hw_status status = RET_OK;
230 u32 irq_reg;
231
Rene Sapiensa6bff482010-07-08 18:11:08 -0500232 irq_reg = MMUMMU_IRQENABLE_READ_REGISTER32(base_address);
Omar Ramirez Luna5cc28e62010-06-23 16:01:59 +0300233
Rene Sapiensa6bff482010-07-08 18:11:08 -0500234 MMUMMU_IRQENABLE_WRITE_REGISTER32(base_address, irq_reg | irqMask);
Omar Ramirez Luna5cc28e62010-06-23 16:01:59 +0300235
236 return status;
237}
238
Rene Sapiensa6bff482010-07-08 18:11:08 -0500239hw_status hw_mmu_event_status(const void __iomem *base_address, u32 *irqMask)
Omar Ramirez Luna5cc28e62010-06-23 16:01:59 +0300240{
241 hw_status status = RET_OK;
242
Rene Sapiensa6bff482010-07-08 18:11:08 -0500243 *irqMask = MMUMMU_IRQSTATUS_READ_REGISTER32(base_address);
Omar Ramirez Luna5cc28e62010-06-23 16:01:59 +0300244
245 return status;
246}
247
Rene Sapiensa6bff482010-07-08 18:11:08 -0500248hw_status hw_mmu_fault_addr_read(const void __iomem *base_address, u32 *addr)
Omar Ramirez Luna5cc28e62010-06-23 16:01:59 +0300249{
250 hw_status status = RET_OK;
251
252 /*Check the input Parameters */
Rene Sapiensa6bff482010-07-08 18:11:08 -0500253 CHECK_INPUT_PARAM(base_address, 0, RET_BAD_NULL_PARAM,
Omar Ramirez Luna5cc28e62010-06-23 16:01:59 +0300254 RES_MMU_BASE + RES_INVALID_INPUT_PARAM);
255
256 /* read values from register */
Rene Sapiensa6bff482010-07-08 18:11:08 -0500257 *addr = MMUMMU_FAULT_AD_READ_REGISTER32(base_address);
Omar Ramirez Luna5cc28e62010-06-23 16:01:59 +0300258
259 return status;
260}
261
Rene Sapiensa6bff482010-07-08 18:11:08 -0500262hw_status hw_mmu_ttb_set(const void __iomem *base_address, u32 TTBPhysAddr)
Omar Ramirez Luna5cc28e62010-06-23 16:01:59 +0300263{
264 hw_status status = RET_OK;
265 u32 load_ttb;
266
267 /*Check the input Parameters */
Rene Sapiensa6bff482010-07-08 18:11:08 -0500268 CHECK_INPUT_PARAM(base_address, 0, RET_BAD_NULL_PARAM,
Omar Ramirez Luna5cc28e62010-06-23 16:01:59 +0300269 RES_MMU_BASE + RES_INVALID_INPUT_PARAM);
270
271 load_ttb = TTBPhysAddr & ~0x7FUL;
272 /* write values to register */
Rene Sapiensa6bff482010-07-08 18:11:08 -0500273 MMUMMU_TTB_WRITE_REGISTER32(base_address, load_ttb);
Omar Ramirez Luna5cc28e62010-06-23 16:01:59 +0300274
275 return status;
276}
277
Rene Sapiensa6bff482010-07-08 18:11:08 -0500278hw_status hw_mmu_twl_enable(const void __iomem *base_address)
Omar Ramirez Luna5cc28e62010-06-23 16:01:59 +0300279{
280 hw_status status = RET_OK;
281
Rene Sapiensa6bff482010-07-08 18:11:08 -0500282 MMUMMU_CNTLTWL_ENABLE_WRITE32(base_address, HW_SET);
Omar Ramirez Luna5cc28e62010-06-23 16:01:59 +0300283
284 return status;
285}
286
Rene Sapiensa6bff482010-07-08 18:11:08 -0500287hw_status hw_mmu_twl_disable(const void __iomem *base_address)
Omar Ramirez Luna5cc28e62010-06-23 16:01:59 +0300288{
289 hw_status status = RET_OK;
290
Rene Sapiensa6bff482010-07-08 18:11:08 -0500291 MMUMMU_CNTLTWL_ENABLE_WRITE32(base_address, HW_CLEAR);
Omar Ramirez Luna5cc28e62010-06-23 16:01:59 +0300292
293 return status;
294}
295
Rene Sapiensa6bff482010-07-08 18:11:08 -0500296hw_status hw_mmu_tlb_flush(const void __iomem *base_address, u32 virtualAddr,
Omar Ramirez Luna5cc28e62010-06-23 16:01:59 +0300297 u32 pageSize)
298{
299 hw_status status = RET_OK;
300 u32 virtual_addr_tag;
301 enum hw_mmu_page_size_t pg_size_bits;
302
303 switch (pageSize) {
304 case HW_PAGE_SIZE4KB:
305 pg_size_bits = HW_MMU_SMALL_PAGE;
306 break;
307
308 case HW_PAGE_SIZE64KB:
309 pg_size_bits = HW_MMU_LARGE_PAGE;
310 break;
311
312 case HW_PAGE_SIZE1MB:
313 pg_size_bits = HW_MMU_SECTION;
314 break;
315
316 case HW_PAGE_SIZE16MB:
317 pg_size_bits = HW_MMU_SUPERSECTION;
318 break;
319
320 default:
321 return RET_FAIL;
322 }
323
324 /* Generate the 20-bit tag from virtual address */
325 virtual_addr_tag = ((virtualAddr & MMU_ADDR_MASK) >> 12);
326
Rene Sapiensa6bff482010-07-08 18:11:08 -0500327 mmu_set_cam_entry(base_address, pg_size_bits, 0, 0, virtual_addr_tag);
Omar Ramirez Luna5cc28e62010-06-23 16:01:59 +0300328
Rene Sapiensa6bff482010-07-08 18:11:08 -0500329 mmu_flush_entry(base_address);
Omar Ramirez Luna5cc28e62010-06-23 16:01:59 +0300330
331 return status;
332}
333
Rene Sapiensa6bff482010-07-08 18:11:08 -0500334hw_status hw_mmu_tlb_add(const void __iomem *base_address,
Omar Ramirez Luna5cc28e62010-06-23 16:01:59 +0300335 u32 physicalAddr,
336 u32 virtualAddr,
337 u32 pageSize,
338 u32 entryNum,
339 struct hw_mmu_map_attrs_t *map_attrs,
340 s8 preservedBit, s8 validBit)
341{
342 hw_status status = RET_OK;
343 u32 lock_reg;
344 u32 virtual_addr_tag;
345 enum hw_mmu_page_size_t mmu_pg_size;
346
347 /*Check the input Parameters */
Rene Sapiensa6bff482010-07-08 18:11:08 -0500348 CHECK_INPUT_PARAM(base_address, 0, RET_BAD_NULL_PARAM,
Omar Ramirez Luna5cc28e62010-06-23 16:01:59 +0300349 RES_MMU_BASE + RES_INVALID_INPUT_PARAM);
350 CHECK_INPUT_RANGE_MIN0(pageSize, MMU_PAGE_MAX, RET_PARAM_OUT_OF_RANGE,
351 RES_MMU_BASE + RES_INVALID_INPUT_PARAM);
352 CHECK_INPUT_RANGE_MIN0(map_attrs->element_size, MMU_ELEMENTSIZE_MAX,
353 RET_PARAM_OUT_OF_RANGE, RES_MMU_BASE +
354 RES_INVALID_INPUT_PARAM);
355
356 switch (pageSize) {
357 case HW_PAGE_SIZE4KB:
358 mmu_pg_size = HW_MMU_SMALL_PAGE;
359 break;
360
361 case HW_PAGE_SIZE64KB:
362 mmu_pg_size = HW_MMU_LARGE_PAGE;
363 break;
364
365 case HW_PAGE_SIZE1MB:
366 mmu_pg_size = HW_MMU_SECTION;
367 break;
368
369 case HW_PAGE_SIZE16MB:
370 mmu_pg_size = HW_MMU_SUPERSECTION;
371 break;
372
373 default:
374 return RET_FAIL;
375 }
376
Rene Sapiensa6bff482010-07-08 18:11:08 -0500377 lock_reg = MMUMMU_LOCK_READ_REGISTER32(base_address);
Omar Ramirez Luna5cc28e62010-06-23 16:01:59 +0300378
379 /* Generate the 20-bit tag from virtual address */
380 virtual_addr_tag = ((virtualAddr & MMU_ADDR_MASK) >> 12);
381
382 /* Write the fields in the CAM Entry Register */
Rene Sapiensa6bff482010-07-08 18:11:08 -0500383 mmu_set_cam_entry(base_address, mmu_pg_size, preservedBit, validBit,
Omar Ramirez Luna5cc28e62010-06-23 16:01:59 +0300384 virtual_addr_tag);
385
386 /* Write the different fields of the RAM Entry Register */
387 /* endianism of the page,Element Size of the page (8, 16, 32, 64 bit) */
Rene Sapiensa6bff482010-07-08 18:11:08 -0500388 mmu_set_ram_entry(base_address, physicalAddr, map_attrs->endianism,
Omar Ramirez Luna5cc28e62010-06-23 16:01:59 +0300389 map_attrs->element_size, map_attrs->mixed_size);
390
391 /* Update the MMU Lock Register */
392 /* currentVictim between lockedBaseValue and (MMU_Entries_Number - 1) */
Rene Sapiensa6bff482010-07-08 18:11:08 -0500393 MMUMMU_LOCK_CURRENT_VICTIM_WRITE32(base_address, entryNum);
Omar Ramirez Luna5cc28e62010-06-23 16:01:59 +0300394
395 /* Enable loading of an entry in TLB by writing 1
396 into LD_TLB_REG register */
Rene Sapiensa6bff482010-07-08 18:11:08 -0500397 MMUMMU_LD_TLB_WRITE_REGISTER32(base_address, MMU_LOAD_TLB);
Omar Ramirez Luna5cc28e62010-06-23 16:01:59 +0300398
Rene Sapiensa6bff482010-07-08 18:11:08 -0500399 MMUMMU_LOCK_WRITE_REGISTER32(base_address, lock_reg);
Omar Ramirez Luna5cc28e62010-06-23 16:01:59 +0300400
401 return status;
402}
403
404hw_status hw_mmu_pte_set(const u32 pg_tbl_va,
405 u32 physicalAddr,
406 u32 virtualAddr,
407 u32 pageSize, struct hw_mmu_map_attrs_t *map_attrs)
408{
409 hw_status status = RET_OK;
410 u32 pte_addr, pte_val;
411 s32 num_entries = 1;
412
413 switch (pageSize) {
414 case HW_PAGE_SIZE4KB:
415 pte_addr = hw_mmu_pte_addr_l2(pg_tbl_va,
416 virtualAddr &
417 MMU_SMALL_PAGE_MASK);
418 pte_val =
419 ((physicalAddr & MMU_SMALL_PAGE_MASK) |
420 (map_attrs->endianism << 9) | (map_attrs->
421 element_size << 4) |
422 (map_attrs->mixed_size << 11) | 2);
423 break;
424
425 case HW_PAGE_SIZE64KB:
426 num_entries = 16;
427 pte_addr = hw_mmu_pte_addr_l2(pg_tbl_va,
428 virtualAddr &
429 MMU_LARGE_PAGE_MASK);
430 pte_val =
431 ((physicalAddr & MMU_LARGE_PAGE_MASK) |
432 (map_attrs->endianism << 9) | (map_attrs->
433 element_size << 4) |
434 (map_attrs->mixed_size << 11) | 1);
435 break;
436
437 case HW_PAGE_SIZE1MB:
438 pte_addr = hw_mmu_pte_addr_l1(pg_tbl_va,
439 virtualAddr &
440 MMU_SECTION_ADDR_MASK);
441 pte_val =
442 ((((physicalAddr & MMU_SECTION_ADDR_MASK) |
443 (map_attrs->endianism << 15) | (map_attrs->
444 element_size << 10) |
445 (map_attrs->mixed_size << 17)) & ~0x40000) | 0x2);
446 break;
447
448 case HW_PAGE_SIZE16MB:
449 num_entries = 16;
450 pte_addr = hw_mmu_pte_addr_l1(pg_tbl_va,
451 virtualAddr &
452 MMU_SSECTION_ADDR_MASK);
453 pte_val =
454 (((physicalAddr & MMU_SSECTION_ADDR_MASK) |
455 (map_attrs->endianism << 15) | (map_attrs->
456 element_size << 10) |
457 (map_attrs->mixed_size << 17)
458 ) | 0x40000 | 0x2);
459 break;
460
461 case HW_MMU_COARSE_PAGE_SIZE:
462 pte_addr = hw_mmu_pte_addr_l1(pg_tbl_va,
463 virtualAddr &
464 MMU_SECTION_ADDR_MASK);
465 pte_val = (physicalAddr & MMU_PAGE_TABLE_MASK) | 1;
466 break;
467
468 default:
469 return RET_FAIL;
470 }
471
472 while (--num_entries >= 0)
473 ((u32 *) pte_addr)[num_entries] = pte_val;
474
475 return status;
476}
477
478hw_status hw_mmu_pte_clear(const u32 pg_tbl_va, u32 virtualAddr, u32 page_size)
479{
480 hw_status status = RET_OK;
481 u32 pte_addr;
482 s32 num_entries = 1;
483
484 switch (page_size) {
485 case HW_PAGE_SIZE4KB:
486 pte_addr = hw_mmu_pte_addr_l2(pg_tbl_va,
487 virtualAddr &
488 MMU_SMALL_PAGE_MASK);
489 break;
490
491 case HW_PAGE_SIZE64KB:
492 num_entries = 16;
493 pte_addr = hw_mmu_pte_addr_l2(pg_tbl_va,
494 virtualAddr &
495 MMU_LARGE_PAGE_MASK);
496 break;
497
498 case HW_PAGE_SIZE1MB:
499 case HW_MMU_COARSE_PAGE_SIZE:
500 pte_addr = hw_mmu_pte_addr_l1(pg_tbl_va,
501 virtualAddr &
502 MMU_SECTION_ADDR_MASK);
503 break;
504
505 case HW_PAGE_SIZE16MB:
506 num_entries = 16;
507 pte_addr = hw_mmu_pte_addr_l1(pg_tbl_va,
508 virtualAddr &
509 MMU_SSECTION_ADDR_MASK);
510 break;
511
512 default:
513 return RET_FAIL;
514 }
515
516 while (--num_entries >= 0)
517 ((u32 *) pte_addr)[num_entries] = 0;
518
519 return status;
520}
521
522/* mmu_flush_entry */
Rene Sapiensa6bff482010-07-08 18:11:08 -0500523static hw_status mmu_flush_entry(const void __iomem *base_address)
Omar Ramirez Luna5cc28e62010-06-23 16:01:59 +0300524{
525 hw_status status = RET_OK;
526 u32 flush_entry_data = 0x1;
527
528 /*Check the input Parameters */
Rene Sapiensa6bff482010-07-08 18:11:08 -0500529 CHECK_INPUT_PARAM(base_address, 0, RET_BAD_NULL_PARAM,
Omar Ramirez Luna5cc28e62010-06-23 16:01:59 +0300530 RES_MMU_BASE + RES_INVALID_INPUT_PARAM);
531
532 /* write values to register */
Rene Sapiensa6bff482010-07-08 18:11:08 -0500533 MMUMMU_FLUSH_ENTRY_WRITE_REGISTER32(base_address, flush_entry_data);
Omar Ramirez Luna5cc28e62010-06-23 16:01:59 +0300534
535 return status;
536}
537
538/* mmu_set_cam_entry */
Rene Sapiensa6bff482010-07-08 18:11:08 -0500539static hw_status mmu_set_cam_entry(const void __iomem *base_address,
Omar Ramirez Luna5cc28e62010-06-23 16:01:59 +0300540 const u32 pageSize,
541 const u32 preservedBit,
542 const u32 validBit,
543 const u32 virtual_addr_tag)
544{
545 hw_status status = RET_OK;
546 u32 mmu_cam_reg;
547
548 /*Check the input Parameters */
Rene Sapiensa6bff482010-07-08 18:11:08 -0500549 CHECK_INPUT_PARAM(base_address, 0, RET_BAD_NULL_PARAM,
Omar Ramirez Luna5cc28e62010-06-23 16:01:59 +0300550 RES_MMU_BASE + RES_INVALID_INPUT_PARAM);
551
552 mmu_cam_reg = (virtual_addr_tag << 12);
553 mmu_cam_reg = (mmu_cam_reg) | (pageSize) | (validBit << 2) |
554 (preservedBit << 3);
555
556 /* write values to register */
Rene Sapiensa6bff482010-07-08 18:11:08 -0500557 MMUMMU_CAM_WRITE_REGISTER32(base_address, mmu_cam_reg);
Omar Ramirez Luna5cc28e62010-06-23 16:01:59 +0300558
559 return status;
560}
561
562/* mmu_set_ram_entry */
Rene Sapiensa6bff482010-07-08 18:11:08 -0500563static hw_status mmu_set_ram_entry(const void __iomem *base_address,
Omar Ramirez Luna5cc28e62010-06-23 16:01:59 +0300564 const u32 physicalAddr,
565 enum hw_endianism_t endianism,
566 enum hw_element_size_t element_size,
567 enum hw_mmu_mixed_size_t mixed_size)
568{
569 hw_status status = RET_OK;
570 u32 mmu_ram_reg;
571
572 /*Check the input Parameters */
Rene Sapiensa6bff482010-07-08 18:11:08 -0500573 CHECK_INPUT_PARAM(base_address, 0, RET_BAD_NULL_PARAM,
Omar Ramirez Luna5cc28e62010-06-23 16:01:59 +0300574 RES_MMU_BASE + RES_INVALID_INPUT_PARAM);
575 CHECK_INPUT_RANGE_MIN0(element_size, MMU_ELEMENTSIZE_MAX,
576 RET_PARAM_OUT_OF_RANGE, RES_MMU_BASE +
577 RES_INVALID_INPUT_PARAM);
578
579 mmu_ram_reg = (physicalAddr & MMU_ADDR_MASK);
580 mmu_ram_reg = (mmu_ram_reg) | ((endianism << 9) | (element_size << 7) |
581 (mixed_size << 6));
582
583 /* write values to register */
Rene Sapiensa6bff482010-07-08 18:11:08 -0500584 MMUMMU_RAM_WRITE_REGISTER32(base_address, mmu_ram_reg);
Omar Ramirez Luna5cc28e62010-06-23 16:01:59 +0300585
586 return status;
587
588}
Felipe Contreras4574fae2010-07-04 16:34:31 +0300589
590void hw_mmu_tlb_flush_all(const void __iomem *base)
591{
592 __raw_writeb(1, base + MMU_GFLUSH);
593}