aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-exynos/include/mach/cpufreq.h
blob: 9ef27df00d08ce3154ceb683b79c9019ebe7b93b (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
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
/* linux/arch/arm/mach-exynos/include/mach/cpufreq.h
 *
 * Copyright (c) 2010 Samsung Electronics Co., Ltd.
 *		http://www.samsung.com
 *
 * EXYNOS4 - CPUFreq support
 *
 * 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.
*/

/* CPU frequency level index for using cpufreq lock API
 * This should be same with cpufreq_frequency_table
*/

enum cpufreq_level_index {
	L0, L1, L2, L3, L4,
	L5, L6, L7, L8, L9,
	L10, L11, L12, L13, L14,
	L15, L16, L17, L18, L19,
	L20,
};

enum busfreq_level_request {
	BUS_L0,		/* MEM 400MHz BUS 200MHz */
	BUS_L1,		/* MEM 267MHz BUS 160MHz */
	BUS_L2,		/* MEM 133MHz BUS 133MHz */
	BUS_LEVEL_END,
};

enum cpufreq_lock_ID {
	DVFS_LOCK_ID_G2D,	/* G2D */
	DVFS_LOCK_ID_TV,	/* TV */
	DVFS_LOCK_ID_MFC,	/* MFC */
	DVFS_LOCK_ID_USB,	/* USB */
	DVFS_LOCK_ID_USB_IF,	/* USB_IF */
	DVFS_LOCK_ID_CAM,	/* CAM */
	DVFS_LOCK_ID_PM,	/* PM */
	DVFS_LOCK_ID_USER,	/* USER */
	DVFS_LOCK_ID_TMU,	/* TMU */
	DVFS_LOCK_ID_LPA,	/* LPA */
	DVFS_LOCK_ID_TSP,	/* TSP */
	DVFS_LOCK_ID_PEN,	/* E-PEN */
	DVFS_LOCK_ID_G3D,	/* G3D */
	DVFS_LOCK_ID_IR_LED,	/* IR_LED */
	DVFS_LOCK_ID_LCD,	/* LCD */
	DVFS_LOCK_ID_DRM,	/* DRM */
	DVFS_LOCK_ID_ROTATION_BOOSTER,	/* ROTATION_BOOSTER */

	/*
	 * QoS Request on DMA Latency.
	 *
	 * dvfs_lock is a non standard implementation that can be
	 * replaced with PM QoS framework.
	 * However, in this implementation, in order to provide
	 * a prototype and test of PM QoS on CPU (DMA Latency),
	 * PM QoS uses dvfs_lock on CPU until we have a full
	 * implementation in CPUFREQ framework of QoS.
	 */
	DVFS_LOCK_ID_QOS_DMA_LATENCY,
	DVFS_LOCK_ID_END,
};

int exynos_cpufreq_get_level(unsigned int freq,
			unsigned int *level);
int exynos_find_cpufreq_level_by_volt(unsigned int arm_volt,
			unsigned int *level);
int exynos_cpufreq_lock(unsigned int nId,
			enum cpufreq_level_index cpufreq_level);
void exynos_cpufreq_lock_free(unsigned int nId);

int exynos4_busfreq_lock(unsigned int nId,
			enum busfreq_level_request busfreq_level);
void exynos4_busfreq_lock_free(unsigned int nId);

int exynos_cpufreq_upper_limit(unsigned int nId,
			enum cpufreq_level_index cpufreq_level);
void exynos_cpufreq_upper_limit_free(unsigned int nId);

/*
 * This level fix API set highset priority level lock.
 * Please use this carefully, with other lock API
 */
int exynos_cpufreq_level_fix(unsigned int freq);
void exynos_cpufreq_level_unfix(void);
int exynos_cpufreq_is_fixed(void);

#define MAX_INDEX	10

#ifdef CONFIG_SLP
struct dvfs_qos_info {
	unsigned int qos_value;
	unsigned int min_freq;
	enum cpufreq_level_index level;
};
#endif

struct exynos_dvfs_info {
	unsigned long	mpll_freq_khz;
	unsigned int	pll_safe_idx;
	unsigned int	pm_lock_idx;
	unsigned int	max_support_idx;
	unsigned int	min_support_idx;
	unsigned int	gov_support_freq;
	struct clk	*cpu_clk;
	unsigned int	*volt_table;
	struct cpufreq_frequency_table	*freq_table;
	void (*set_freq)(unsigned int, unsigned int);
	bool (*need_apll_change)(unsigned int, unsigned int);

#ifdef CONFIG_SLP
	struct dvfs_qos_info *cpu_dma_latency;
#endif
};

extern struct exynos_dvfs_info *exynos_info;

#define SUPPORT_1400MHZ	(1<<31)
#define SUPPORT_1200MHZ	(1<<30)
#define SUPPORT_1000MHZ	(1<<29)
#define SUPPORT_FREQ_SHIFT	29
#define SUPPORT_FREQ_MASK	7

#if defined(CONFIG_ARCH_EXYNOS4)
extern int exynos4210_cpufreq_init(struct exynos_dvfs_info *);
extern int exynos4x12_cpufreq_init(struct exynos_dvfs_info *);
static inline int exynos5250_cpufreq_init(struct exynos_dvfs_info *info)
{
	return 0;
}

#elif defined(CONFIG_ARCH_EXYNOS5)
static inline int exynos4210_cpufreq_init(struct exynos_dvfs_info *info)
{
	return 0;
}

static inline int exynos4x12_cpufreq_init(struct exynos_dvfs_info *info)
{
	return 0;
}

extern int exynos5250_cpufreq_init(struct exynos_dvfs_info *);
#else
	#warning "Should define CONFIG_ARCH_EXYNOS4(5)\n"
#endif

#if defined(CONFIG_EXYNOS5250_ABB_WA)
/* These function and variables should be removed in EVT1 */
void exynos5250_set_arm_abbg(unsigned int arm_volt, unsigned int int_volt);
#endif