1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
|
/* linux/drivers/media/video/samsung/fimg2d4x/fimg2d_cache.h
*
* Copyright (c) 2011 Samsung Electronics Co., Ltd.
* http://www.samsung.com/
*
* Samsung Graphics 2D driver
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <asm/cacheflush.h>
#include <linux/dma-mapping.h>
#include <plat/cpu.h>
#include "fimg2d.h"
#define L1_CACHE_SIZE SZ_64K
#define L2_CACHE_SIZE SZ_1M
#define LINE_FLUSH_THRESHOLD SZ_1K
#define L1_DESCRIPTOR_SIZE SZ_16K
/* Get Modified virtual address to use 1MB page */
#define GET_MVA(V, P) ((V & 0xfff00000) | (P & 0x000fffff))
/**
* cache_opr - [kernel] cache operation mode
* @CACHE_INVAL: do cache invalidate
* @CACHE_CLEAN: do cache clean for src and msk image
* @CACHE_FLUSH: do cache clean and invalidate for dst image
* @CACHE_FLUSH_INNER_ALL: clean and invalidate for innercache
* @CACHE_FLUSH_ALL: clean and invalidate for whole caches
*/
enum cache_opr {
CACHE_INVAL,
CACHE_CLEAN,
CACHE_FLUSH,
CACHE_FLUSH_INNER_ALL,
CACHE_FLUSH_ALL
};
/**
* @PT_NORMAL: pagetable exists
* @PT_FAULT: invalid pagetable
*/
enum pt_status {
PT_NORMAL,
PT_FAULT,
};
static inline bool is_inner_flushall(size_t size)
{
if (soc_is_exynos5250())
return (size >= SZ_1M * 25) ? true : false;
else
return (size >= L1_CACHE_SIZE) ? true : false;
}
static inline bool is_outer_flushall(size_t size)
{
return (size >= L2_CACHE_SIZE) ? true : false;
}
static inline bool is_inner_flushrange(size_t hole)
{
if (!soc_is_exynos5250())
return true;
else {
if (hole < LINE_FLUSH_THRESHOLD)
return true;
else
return false; /* line-by-line flush */
}
}
static inline bool is_outer_flushrange(size_t hole)
{
if (hole < LINE_FLUSH_THRESHOLD)
return true;
else
return false; /* line-by-line flush */
}
static inline void fimg2d_dma_sync_inner(unsigned long addr, size_t size, int dir)
{
if (dir == DMA_TO_DEVICE)
dmac_map_area((void *)addr, size, dir);
else if (dir == DMA_BIDIRECTIONAL)
dmac_flush_range((void *)addr, (void *)(addr + size));
}
static inline void fimg2d_dma_unsync_inner(unsigned long addr, size_t size, int dir)
{
if (dir == DMA_TO_DEVICE)
dmac_unmap_area((void *)addr, size, dir);
}
void fimg2d_clean_outer_pagetable(struct mm_struct *mm, unsigned long addr, size_t size);
void fimg2d_clean_outer_pagetable_clone(unsigned long *pgd_clone, unsigned long addr, size_t size);
void fimg2d_clean_inner_pagetable_clone(unsigned long *pgd_clone, unsigned long addr, size_t size);
void fimg2d_dma_sync_outer(struct mm_struct *mm, unsigned long addr, size_t size, enum cache_opr opr);
enum pt_status fimg2d_check_pagetable(struct mm_struct *mm, unsigned long addr, size_t size);
enum pt_status fimg2d_migrate_pagetable(unsigned long *pgd_clone,
unsigned long vaddr, unsigned long paddr, size_t size);
void fimg2d_mmutable_value_replace(struct fimg2d_bltcmd *cmd,
unsigned long fault_addr, unsigned long l2d_value);
|