summaryrefslogtreecommitdiff
path: root/drivers/devfreq/devfreq_spdm.h
blob: c68f81cf8d4e3d538f95ab6af456bea2c7ef761f (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
/*
*Copyright (c) 2014-2015, The Linux Foundation. All rights reserved.
*
*This program is free software; you can redistribute it and/or modify
*it under the terms of the GNU General Public License version 2 and
*only version 2 as published by the Free Software Foundation.
*
*This program is distributed in the hope that it will be useful,
*but WITHOUT ANY WARRANTY; without even the implied warranty of
*MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
*GNU General Public License for more details.
*/

#ifndef DEVFREQ_SPDM_H
#define DEVFREQ_SPDM_H

#include <linux/list.h>
#include <soc/qcom/hvc.h>
#include <soc/qcom/scm.h>

enum pl_levels { SPDM_PL1, SPDM_PL2, SPDM_PL3, SPDM_PL_COUNT };
enum actions { SPDM_UP, SPDM_DOWN };
enum spdm_client { SPDM_CLIENT_CPU, SPDM_CLIENT_GPU, SPDM_CLIENT_COUNT };

struct spdm_config_data {
	/* in MB/s */
	u32 upstep;
	u32 downstep;
	u32 up_step_multp;

	u32 num_ports;
	u32 *ports;
	u32 aup;
	u32 adown;
	u32 bucket_size;

	/*
	 * If We define n PL levels we need n-1 frequencies to tell
	 * where to change from one pl to another
	 */
	/* hz */
	u32 pl_freqs[SPDM_PL_COUNT - 1];
	/*
	 * We have a low threshold and a high threhold for each pl to support
	 * the two port solution so we need twice as many entries as
	 * performance levels
	 */
	/* in 100th's of a percent */
	u32 reject_rate[SPDM_PL_COUNT * 2];
	u32 response_time_us[SPDM_PL_COUNT * 2];
	u32 cci_response_time_us[SPDM_PL_COUNT * 2];
	/* hz */
	u32 max_cci_freq;
	/* in MB/s */
	u32 max_vote;

};

struct spdm_data {
	/* bus scaling data */
	int cur_idx;
	struct msm_bus_scale_pdata *pdata;
	u32 bus_scale_client_id;
	/* in mb/s */
	u32 new_bw;

	/* devfreq data */
	struct devfreq *devfreq;
	struct devfreq_dev_profile *profile;
	unsigned long action;
	int window;
	struct clk *cci_clk;

	/* spdm hw/gov data */
	struct spdm_config_data config_data;

	enum spdm_client spdm_client;
	/* list used by governor to keep track of spdm devices */
	struct list_head list;

	struct dentry *debugfs_dir;

	bool enabled;
};

extern void spdm_init_debugfs(struct device *dev);
extern void spdm_remove_debugfs(struct spdm_data *data);

#define SPDM_HYP_FNID 5
#define SPDM_SCM_SVC_ID 0x9
#define SPDM_SCM_CMD_ID 0x4
#define SPDM_TZ_VERSION 0x20000 /* TZ SPDM driver version */
/* SPDM CMD ID's for hypervisor/SCM */
#define SPDM_CMD_GET_VERSION 0
#define SPDM_CMD_GET_BW_ALL 1
#define SPDM_CMD_GET_BW_SPECIFIC 2
#define SPDM_CMD_ENABLE 3
#define SPDM_CMD_DISABLE 4
#define SPDM_CMD_CFG_PORTS 5
#define SPDM_CMD_CFG_FLTR 6
#define SPDM_CMD_CFG_PL 7
#define SPDM_CMD_CFG_REJRATE_LOW 8
#define SPDM_CMD_CFG_REJRATE_MED 9
#define SPDM_CMD_CFG_REJRATE_HIGH 10
#define SPDM_CMD_CFG_RESPTIME_LOW 11
#define SPDM_CMD_CFG_RESPTIME_MED 12
#define SPDM_CMD_CFG_RESPTIME_HIGH 13
#define SPDM_CMD_CFG_CCIRESPTIME_LOW 14
#define SPDM_CMD_CFG_CCIRESPTIME_MED 15
#define SPDM_CMD_CFG_CCIRESPTIME_HIGH 16
#define SPDM_CMD_CFG_MAXCCI 17
#define SPDM_CMD_CFG_VOTES 18

#define SPDM_MAX_ARGS 6
#define SPDM_MAX_RETS 3

struct spdm_args {
	u64 arg[SPDM_MAX_ARGS];
	u64 ret[SPDM_MAX_RETS];
};

extern int __spdm_hyp_call(struct spdm_args *args, int num_args);
extern int __spdm_scm_call(struct spdm_args *args, int num_args);

#ifdef CONFIG_SPDM_SCM
#define spdm_ext_call __spdm_scm_call
#else
#define spdm_ext_call __spdm_hyp_call
#endif
#endif