blob: c03c7524a695c9050c5321d0f88d3097b7d23a55 [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/**
21 * struct iommu_access_ops - Callbacks for accessing IOMMU
22 * @iommu_power_on: Turn on clocks/power to unit
23 * @iommu_power_off: Turn off clocks/power to unit
24 * @iommu_lock_acquire: Acquire any locks needed
25 * @iommu_lock_release: Release locks needed
26 */
27struct iommu_access_ops {
28 int (*iommu_power_on)(void *);
29 int (*iommu_power_off)(void *);
30 void (*iommu_lock_acquire)(void);
31 void (*iommu_lock_release)(void);
32};
33
34/**
35 * struct iommu_pmon_counter - container for a performance counter.
36 * @counter_no: counter number within the group
37 * @absolute_counter_no: counter number within IOMMU PMU
38 * @value: cached counter value
39 * @overflow_count: no of times counter has overflowed
40 * @enabled: indicates whether counter is enabled or not
41 * @current_event_class: current selected event class, -1 if none
42 * @counter_dir: debugfs directory for this counter
43 * @cnt_group: group this counter belongs to
44 */
45struct iommu_pmon_counter {
46 unsigned int counter_no;
47 unsigned int absolute_counter_no;
48 unsigned long value;
49 unsigned long overflow_count;
50 unsigned int enabled;
51 int current_event_class;
52 struct dentry *counter_dir;
53 struct iommu_pmon_cnt_group *cnt_group;
54};
55
56/**
57 * struct iommu_pmon_cnt_group - container for a perf mon counter group.
58 * @grp_no: group number
59 * @num_counters: number of counters in this group
60 * @counters: list of counter in this group
61 * @group_dir: debugfs directory for this group
62 * @pmon: pointer to the iommu_pmon object this group belongs to
63 */
64struct iommu_pmon_cnt_group {
65 unsigned int grp_no;
66 unsigned int num_counters;
67 struct iommu_pmon_counter *counters;
68 struct dentry *group_dir;
69 struct iommu_pmon *pmon;
70};
71
72/**
73 * struct iommu_info - container for a perf mon iommu info.
74 * @iommu_name: name of the iommu from device tree
75 * @base: virtual base address for this iommu
76 * @evt_irq: irq number for event overflow interrupt
77 * @iommu_dev: pointer to iommu device
78 * @ops: iommu access operations pointer.
Olav Hauganef69e892013-02-04 13:47:08 -080079 * @hw_ops: iommu pm hw access operations pointer.
Olav Haugan99660ca2012-12-04 13:30:41 -080080 */
81struct iommu_info {
82 const char *iommu_name;
83 void *base;
84 int evt_irq;
85 struct device *iommu_dev;
86 struct iommu_access_ops *ops;
Olav Hauganef69e892013-02-04 13:47:08 -080087 struct iommu_pm_hw_ops *hw_ops;
Olav Haugan99660ca2012-12-04 13:30:41 -080088};
89
90/**
91 * struct iommu_pmon - main container for a perf mon data.
92 * @iommu_dir: debugfs directory for this iommu
93 * @iommu: iommu_info instance
94 * @iommu_list: iommu_list head
95 * @cnt_grp: list of counter groups
96 * @num_groups: number of counter groups
Olav Haugan0c2d9322013-01-31 18:35:30 -080097 * @num_counters: number of counters per group
98 * @event_cls_supported: an array of event classes supported for this PMU
99 * @nevent_cls_supported: number of event classes supported.
Olav Haugan99660ca2012-12-04 13:30:41 -0800100 * @enabled: Indicates whether perf. mon is enabled or not
101 * @iommu_attached Indicates whether iommu is attached or not.
102 * @lock: mutex used to synchronize access to shared data
103 */
104struct iommu_pmon {
105 struct dentry *iommu_dir;
106 struct iommu_info iommu;
107 struct list_head iommu_list;
108 struct iommu_pmon_cnt_group *cnt_grp;
Olav Haugan0c2d9322013-01-31 18:35:30 -0800109 u32 num_groups;
110 u32 num_counters;
111 u32 *event_cls_supported;
112 u32 nevent_cls_supported;
Olav Haugan99660ca2012-12-04 13:30:41 -0800113 unsigned int enabled;
114 unsigned int iommu_attach_count;
115 struct mutex lock;
116};
117
Olav Hauganef69e892013-02-04 13:47:08 -0800118/**
119 * struct iommu_hw_ops - Callbacks for accessing IOMMU HW
Olav Haugan7a2f99c2013-02-04 14:43:26 -0800120 * @initialize_hw: Call to do any initialization before enabling ovf interrupts
Olav Hauganef69e892013-02-04 13:47:08 -0800121 * @is_hw_access_ok: Returns 1 if we can access HW, 0 otherwise
122 * @grp_enable: Call to enable a counter group
123 * @grp_disable: Call to disable a counter group
124 * @enable_pm: Call to enable PM
125 * @disable_pm: Call to disable PM
126 * @reset_counters: Call to reset counters
127 * @check_for_overflow: Call to check for overflow
128 * @evt_ovfl_int_handler: Overflow interrupt handler callback
129 * @counter_enable: Call to enable counters
130 * @counter_disable: Call to disable counters
131 * @ovfl_int_enable: Call to enable overflow interrupts
132 * @ovfl_int_disable: Call to disable overflow interrupts
133 * @set_event_class: Call to set event class
134 * @read_counter: Call to read a counter value
135 */
136struct iommu_pm_hw_ops {
Olav Haugan7a2f99c2013-02-04 14:43:26 -0800137 void (*initialize_hw)(const struct iommu_pmon *);
Olav Hauganef69e892013-02-04 13:47:08 -0800138 unsigned int (*is_hw_access_OK)(const struct iommu_pmon *);
139 void (*grp_enable)(struct iommu_info *, unsigned int);
140 void (*grp_disable)(struct iommu_info *, unsigned int);
141 void (*enable_pm)(struct iommu_info *);
142 void (*disable_pm)(struct iommu_info *);
143 void (*reset_counters)(const struct iommu_info *);
144 void (*check_for_overflow)(struct iommu_pmon *);
145 irqreturn_t (*evt_ovfl_int_handler)(int, void *);
146 void (*counter_enable)(struct iommu_info *,
147 struct iommu_pmon_counter *);
148 void (*counter_disable)(struct iommu_info *,
149 struct iommu_pmon_counter *);
150 void (*ovfl_int_enable)(struct iommu_info *,
151 const struct iommu_pmon_counter *);
152 void (*ovfl_int_disable)(struct iommu_info *,
153 const struct iommu_pmon_counter *);
154 void (*set_event_class)(struct iommu_pmon *pmon, unsigned int,
155 unsigned int);
156 unsigned int (*read_counter)(struct iommu_pmon_counter *);
157};
158
Olav Haugan7a2f99c2013-02-04 14:43:26 -0800159extern struct iommu_access_ops iommu_access_ops_v0;
Olav Hauganef69e892013-02-04 13:47:08 -0800160extern struct iommu_access_ops iommu_access_ops_v1;
Olav Haugan7a2f99c2013-02-04 14:43:26 -0800161#define MSM_IOMMU_PMU_NO_EVENT_CLASS -1
Olav Haugan99660ca2012-12-04 13:30:41 -0800162
163#ifdef CONFIG_MSM_IOMMU_PMON
Olav Hauganef69e892013-02-04 13:47:08 -0800164
165/**
Olav Haugan7a2f99c2013-02-04 14:43:26 -0800166 * Get pointer to PMU hardware access functions for IOMMUv0 PMU
167 */
168struct iommu_pm_hw_ops *iommu_pm_get_hw_ops_v0(void);
169
170/**
Olav Hauganef69e892013-02-04 13:47:08 -0800171 * Get pointer to PMU hardware access functions for IOMMUv1 PMU
172 */
173struct iommu_pm_hw_ops *iommu_pm_get_hw_ops_v1(void);
174
Olav Haugan99660ca2012-12-04 13:30:41 -0800175/**
176 * Allocate memory for performance monitor structure. Must
Olav Haugan0c2d9322013-01-31 18:35:30 -0800177 * be called before iommu_pm_iommu_register
Olav Haugan99660ca2012-12-04 13:30:41 -0800178 */
Olav Haugan0c2d9322013-01-31 18:35:30 -0800179struct iommu_pmon *msm_iommu_pm_alloc(struct device *iommu_dev);
Olav Haugan99660ca2012-12-04 13:30:41 -0800180
181/**
182 * Free memory previously allocated with iommu_pm_alloc
183 */
184void msm_iommu_pm_free(struct device *iommu_dev);
185
186/**
187 * Register iommu with the performance monitor module.
188 */
Olav Haugan0c2d9322013-01-31 18:35:30 -0800189int msm_iommu_pm_iommu_register(struct iommu_pmon *info);
Olav Haugan99660ca2012-12-04 13:30:41 -0800190
191/**
192 * Unregister iommu with the performance monitor module.
193 */
194void msm_iommu_pm_iommu_unregister(struct device *dev);
195
196/**
197 * Called by iommu driver when attaching is complete
198 * Must NOT be called with IOMMU mutexes held.
199 * @param iommu_dev IOMMU device that is attached
200 */
201void msm_iommu_attached(struct device *dev);
202
203/**
204 * Called by iommu driver before detaching.
205 * Must NOT be called with IOMMU mutexes held.
206 * @param iommu_dev IOMMU device that is going to be detached
207 */
208void msm_iommu_detached(struct device *dev);
209#else
Olav Haugan7a2f99c2013-02-04 14:43:26 -0800210static inline struct iommu_pm_hw_ops *iommu_pm_get_hw_ops_v0(void)
211{
212 return NULL;
213}
214
Olav Hauganef69e892013-02-04 13:47:08 -0800215static inline struct iommu_pm_hw_ops *iommu_pm_get_hw_ops_v1(void)
216{
217 return NULL;
218}
219
Olav Haugan0c2d9322013-01-31 18:35:30 -0800220static inline struct iommu_pmon *msm_iommu_pm_alloc(struct device *iommu_dev)
Olav Haugan99660ca2012-12-04 13:30:41 -0800221{
222 return NULL;
223}
224
225static inline void msm_iommu_pm_free(struct device *iommu_dev)
226{
227 return;
228}
229
Olav Haugan0c2d9322013-01-31 18:35:30 -0800230static inline int msm_iommu_pm_iommu_register(struct iommu_pmon *info)
Olav Haugan99660ca2012-12-04 13:30:41 -0800231{
232 return -EIO;
233}
234
235static inline void msm_iommu_pm_iommu_unregister(struct device *dev)
236{
237}
238
239static inline void msm_iommu_attached(struct device *dev)
240{
241}
242
243static inline void msm_iommu_detached(struct device *dev)
244{
245}
246#endif
247#endif