aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/samsung/fimg2d4x-exynos4/fimg2d_cache.h
blob: 7699a37f227fbd36d62782638b6c09e8923066fc (plain)
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);