blob: dc4671cf369577b640c8bb7f013c64ab0dec3089 [file] [log] [blame]
Olav Haugan99660ca2012-12-04 13:30:41 -08001/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
2 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and
5 * only version 2 as published by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 */
12#include <linux/err.h>
13#include <linux/mutex.h>
14#include <linux/list.h>
Mitchel Humpherys9e1f9872013-02-28 13:30:44 -080015#include <linux/irqreturn.h>
Olav Haugan99660ca2012-12-04 13:30:41 -080016
17#ifndef MSM_IOMMU_PERFMON_H
18#define MSM_IOMMU_PERFMON_H
19
Olav Haugan99660ca2012-12-04 13:30:41 -080020/**
Olav Haugan99660ca2012-12-04 13:30:41 -080021 * struct iommu_pmon_counter - container for a performance counter.
22 * @counter_no: counter number within the group
23 * @absolute_counter_no: counter number within IOMMU PMU
24 * @value: cached counter value
25 * @overflow_count: no of times counter has overflowed
26 * @enabled: indicates whether counter is enabled or not
27 * @current_event_class: current selected event class, -1 if none
28 * @counter_dir: debugfs directory for this counter
29 * @cnt_group: group this counter belongs to
30 */
31struct iommu_pmon_counter {
32 unsigned int counter_no;
33 unsigned int absolute_counter_no;
34 unsigned long value;
35 unsigned long overflow_count;
36 unsigned int enabled;
37 int current_event_class;
38 struct dentry *counter_dir;
39 struct iommu_pmon_cnt_group *cnt_group;
40};
41
42/**
43 * struct iommu_pmon_cnt_group - container for a perf mon counter group.
44 * @grp_no: group number
45 * @num_counters: number of counters in this group
46 * @counters: list of counter in this group
47 * @group_dir: debugfs directory for this group
48 * @pmon: pointer to the iommu_pmon object this group belongs to
49 */
50struct iommu_pmon_cnt_group {
51 unsigned int grp_no;
52 unsigned int num_counters;
53 struct iommu_pmon_counter *counters;
54 struct dentry *group_dir;
55 struct iommu_pmon *pmon;
56};
57
58/**
59 * struct iommu_info - container for a perf mon iommu info.
60 * @iommu_name: name of the iommu from device tree
61 * @base: virtual base address for this iommu
62 * @evt_irq: irq number for event overflow interrupt
63 * @iommu_dev: pointer to iommu device
64 * @ops: iommu access operations pointer.
Olav Hauganef69e892013-02-04 13:47:08 -080065 * @hw_ops: iommu pm hw access operations pointer.
Olav Haugan463e6402013-04-15 10:53:32 -070066 * @always_on: 1 if iommu is always on, 0 otherwise.
Olav Haugan99660ca2012-12-04 13:30:41 -080067 */
68struct iommu_info {
69 const char *iommu_name;
70 void *base;
71 int evt_irq;
72 struct device *iommu_dev;
73 struct iommu_access_ops *ops;
Olav Hauganef69e892013-02-04 13:47:08 -080074 struct iommu_pm_hw_ops *hw_ops;
Olav Haugan463e6402013-04-15 10:53:32 -070075 unsigned int always_on;
Olav Haugan99660ca2012-12-04 13:30:41 -080076};
77
78/**
79 * struct iommu_pmon - main container for a perf mon data.
80 * @iommu_dir: debugfs directory for this iommu
81 * @iommu: iommu_info instance
82 * @iommu_list: iommu_list head
83 * @cnt_grp: list of counter groups
84 * @num_groups: number of counter groups
Olav Haugan0c2d9322013-01-31 18:35:30 -080085 * @num_counters: number of counters per group
86 * @event_cls_supported: an array of event classes supported for this PMU
87 * @nevent_cls_supported: number of event classes supported.
Olav Haugan99660ca2012-12-04 13:30:41 -080088 * @enabled: Indicates whether perf. mon is enabled or not
89 * @iommu_attached Indicates whether iommu is attached or not.
90 * @lock: mutex used to synchronize access to shared data
91 */
92struct iommu_pmon {
93 struct dentry *iommu_dir;
94 struct iommu_info iommu;
95 struct list_head iommu_list;
96 struct iommu_pmon_cnt_group *cnt_grp;
Olav Haugan0c2d9322013-01-31 18:35:30 -080097 u32 num_groups;
98 u32 num_counters;
99 u32 *event_cls_supported;
100 u32 nevent_cls_supported;
Olav Haugan99660ca2012-12-04 13:30:41 -0800101 unsigned int enabled;
102 unsigned int iommu_attach_count;
103 struct mutex lock;
104};
105
Olav Hauganef69e892013-02-04 13:47:08 -0800106/**
107 * struct iommu_hw_ops - Callbacks for accessing IOMMU HW
Olav Haugan7a2f99c2013-02-04 14:43:26 -0800108 * @initialize_hw: Call to do any initialization before enabling ovf interrupts
Olav Hauganef69e892013-02-04 13:47:08 -0800109 * @is_hw_access_ok: Returns 1 if we can access HW, 0 otherwise
110 * @grp_enable: Call to enable a counter group
111 * @grp_disable: Call to disable a counter group
112 * @enable_pm: Call to enable PM
113 * @disable_pm: Call to disable PM
114 * @reset_counters: Call to reset counters
115 * @check_for_overflow: Call to check for overflow
116 * @evt_ovfl_int_handler: Overflow interrupt handler callback
117 * @counter_enable: Call to enable counters
118 * @counter_disable: Call to disable counters
119 * @ovfl_int_enable: Call to enable overflow interrupts
120 * @ovfl_int_disable: Call to disable overflow interrupts
121 * @set_event_class: Call to set event class
122 * @read_counter: Call to read a counter value
123 */
124struct iommu_pm_hw_ops {
Olav Haugan7a2f99c2013-02-04 14:43:26 -0800125 void (*initialize_hw)(const struct iommu_pmon *);
Olav Hauganef69e892013-02-04 13:47:08 -0800126 unsigned int (*is_hw_access_OK)(const struct iommu_pmon *);
127 void (*grp_enable)(struct iommu_info *, unsigned int);
128 void (*grp_disable)(struct iommu_info *, unsigned int);
129 void (*enable_pm)(struct iommu_info *);
130 void (*disable_pm)(struct iommu_info *);
131 void (*reset_counters)(const struct iommu_info *);
132 void (*check_for_overflow)(struct iommu_pmon *);
133 irqreturn_t (*evt_ovfl_int_handler)(int, void *);
134 void (*counter_enable)(struct iommu_info *,
135 struct iommu_pmon_counter *);
136 void (*counter_disable)(struct iommu_info *,
137 struct iommu_pmon_counter *);
138 void (*ovfl_int_enable)(struct iommu_info *,
139 const struct iommu_pmon_counter *);
140 void (*ovfl_int_disable)(struct iommu_info *,
141 const struct iommu_pmon_counter *);
142 void (*set_event_class)(struct iommu_pmon *pmon, unsigned int,
143 unsigned int);
144 unsigned int (*read_counter)(struct iommu_pmon_counter *);
145};
146
Olav Haugan7a2f99c2013-02-04 14:43:26 -0800147extern struct iommu_access_ops iommu_access_ops_v0;
Olav Hauganef69e892013-02-04 13:47:08 -0800148extern struct iommu_access_ops iommu_access_ops_v1;
Olav Haugan7a2f99c2013-02-04 14:43:26 -0800149#define MSM_IOMMU_PMU_NO_EVENT_CLASS -1
Olav Haugan99660ca2012-12-04 13:30:41 -0800150
151#ifdef CONFIG_MSM_IOMMU_PMON
Olav Hauganef69e892013-02-04 13:47:08 -0800152
153/**
Olav Haugan7a2f99c2013-02-04 14:43:26 -0800154 * Get pointer to PMU hardware access functions for IOMMUv0 PMU
155 */
156struct iommu_pm_hw_ops *iommu_pm_get_hw_ops_v0(void);
157
158/**
Olav Hauganef69e892013-02-04 13:47:08 -0800159 * Get pointer to PMU hardware access functions for IOMMUv1 PMU
160 */
161struct iommu_pm_hw_ops *iommu_pm_get_hw_ops_v1(void);
162
Olav Haugan99660ca2012-12-04 13:30:41 -0800163/**
164 * Allocate memory for performance monitor structure. Must
Olav Haugan0c2d9322013-01-31 18:35:30 -0800165 * be called before iommu_pm_iommu_register
Olav Haugan99660ca2012-12-04 13:30:41 -0800166 */
Olav Haugan0c2d9322013-01-31 18:35:30 -0800167struct iommu_pmon *msm_iommu_pm_alloc(struct device *iommu_dev);
Olav Haugan99660ca2012-12-04 13:30:41 -0800168
169/**
170 * Free memory previously allocated with iommu_pm_alloc
171 */
172void msm_iommu_pm_free(struct device *iommu_dev);
173
174/**
175 * Register iommu with the performance monitor module.
176 */
Olav Haugan0c2d9322013-01-31 18:35:30 -0800177int msm_iommu_pm_iommu_register(struct iommu_pmon *info);
Olav Haugan99660ca2012-12-04 13:30:41 -0800178
179/**
180 * Unregister iommu with the performance monitor module.
181 */
182void msm_iommu_pm_iommu_unregister(struct device *dev);
183
184/**
185 * Called by iommu driver when attaching is complete
186 * Must NOT be called with IOMMU mutexes held.
187 * @param iommu_dev IOMMU device that is attached
188 */
189void msm_iommu_attached(struct device *dev);
190
191/**
192 * Called by iommu driver before detaching.
193 * Must NOT be called with IOMMU mutexes held.
194 * @param iommu_dev IOMMU device that is going to be detached
195 */
196void msm_iommu_detached(struct device *dev);
197#else
Olav Haugan7a2f99c2013-02-04 14:43:26 -0800198static inline struct iommu_pm_hw_ops *iommu_pm_get_hw_ops_v0(void)
199{
200 return NULL;
201}
202
Olav Hauganef69e892013-02-04 13:47:08 -0800203static inline struct iommu_pm_hw_ops *iommu_pm_get_hw_ops_v1(void)
204{
205 return NULL;
206}
207
Olav Haugan0c2d9322013-01-31 18:35:30 -0800208static inline struct iommu_pmon *msm_iommu_pm_alloc(struct device *iommu_dev)
Olav Haugan99660ca2012-12-04 13:30:41 -0800209{
210 return NULL;
211}
212
213static inline void msm_iommu_pm_free(struct device *iommu_dev)
214{
215 return;
216}
217
Olav Haugan0c2d9322013-01-31 18:35:30 -0800218static inline int msm_iommu_pm_iommu_register(struct iommu_pmon *info)
Olav Haugan99660ca2012-12-04 13:30:41 -0800219{
220 return -EIO;
221}
222
223static inline void msm_iommu_pm_iommu_unregister(struct device *dev)
224{
225}
226
227static inline void msm_iommu_attached(struct device *dev)
228{
229}
230
231static inline void msm_iommu_detached(struct device *dev)
232{
233}
234#endif
235#endif