aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-exynos/include/mach/busfreq_exynos5.h
blob: fe00bd1bb0eade7f38a76dd4e8d493a5e691b8ad (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
/* linux/arch/arm/mach-exynos/include/mach/busfreq_exynos5.h
 *
 * Copyright (c) 2010 Samsung Electronics Co., Ltd.
 *		http://www.samsung.com
 *
 * EXYNOS4 - BUSFreq 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.
*/

#ifndef __ASM_ARCH_BUSFREQ_H
#define __ASM_ARCH_BUSFREQ_H __FILE__

#include <linux/notifier.h>
#include <linux/earlysuspend.h>

#include <mach/ppmu.h>

#define MAX_LOAD		100
#define LOAD_HISTORY_SIZE	5
#define DIVIDING_FACTOR		10000

#define TIMINGROW_OFFSET	0x34

enum busfreq_level_idx {
	LV_0,
	LV_1,
	LV_2,
	LV_3,
	LV_INT_END,
	LV_MIF_END = LV_3,
};

struct opp;
struct device;
struct busfreq_table;

struct busfreq_data {
	bool use;
	struct device *dev[PPMU_TYPE_END];
	struct delayed_work worker;
	unsigned long curr_freq[PPMU_TYPE_END];
	unsigned long max_freq[PPMU_TYPE_END];
	unsigned long min_freq[PPMU_TYPE_END];
	struct regulator *vdd_reg[PPMU_TYPE_END];
	unsigned int sampling_rate;
	struct kobject *busfreq_kobject;
	struct busfreq_table *table[PPMU_TYPE_END];
	unsigned long long time_in_state[PPMU_TYPE_END][LV_INT_END];
	unsigned long long last_time[PPMU_TYPE_END];
	unsigned int load_history[PPMU_END][LOAD_HISTORY_SIZE];
	int index;

	struct notifier_block exynos_buspm_notifier;
	struct notifier_block exynos_reboot_notifier;
	struct notifier_block exynos_request_notifier;
	struct early_suspend busfreq_early_suspend_handler;
	struct attribute_group busfreq_attr_group;
	int (*init)	(struct device *dev, struct busfreq_data *data);
	void (*monitor) (struct busfreq_data *data, struct opp **mif_opp,
			struct opp **int_opp);
	void (*target)	(struct busfreq_data *data, enum ppmu_type type, int index);
	unsigned int (*get_int_volt) (unsigned long freq);
	int (*get_table_index) (unsigned long freq, enum ppmu_type type);
	void (*busfreq_prepare) (int index);
	void (*busfreq_post) (int index);
	void (*busfreq_suspend) (void);
	void (*busfreq_resume) (void);

	/* Dividers calculated at boot/probe-time */
	unsigned int lex_divtable[LV_INT_END];
	unsigned int r0x_divtable[LV_INT_END];
	unsigned int r1x_divtable[LV_INT_END];
	unsigned int cdrex_divtable[LV_MIF_END];
	unsigned int cdrex2_divtable[LV_MIF_END];
};

struct busfreq_table {
	unsigned int idx;
	unsigned int mem_clk;
	unsigned int volt;
	unsigned int clk_topdiv;
	unsigned int clk_dmc0div;
	unsigned int clk_dmc1div;
};

void exynos_request_apply(unsigned long freq);
unsigned long step_down(struct busfreq_data *data, enum ppmu_type type, int step);

int exynos5250_init(struct device *dev, struct busfreq_data *data);
#endif /* __ASM_ARCH_BUSFREQ_H */