blob: dcae83bf978c28fe8cefb4f1dabdda9c098e3d93 [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 Haugan99660ca2012-12-04 13:30:41 -080066 */
67struct iommu_info {
68 const char *iommu_name;
69 void *base;
70 int evt_irq;
71 struct device *iommu_dev;
72 struct iommu_access_ops *ops;
Olav Hauganef69e892013-02-04 13:47:08 -080073 struct iommu_pm_hw_ops *hw_ops;
Olav Haugan99660ca2012-12-04 13:30:41 -080074};
75
76/**
77 * struct iommu_pmon - main container for a perf mon data.
78 * @iommu_dir: debugfs directory for this iommu
79 * @iommu: iommu_info instance
80 * @iommu_list: iommu_list head
81 * @cnt_grp: list of counter groups
82 * @num_groups: number of counter groups
Olav Haugan0c2d9322013-01-31 18:35:30 -080083 * @num_counters: number of counters per group
84 * @event_cls_supported: an array of event classes supported for this PMU
85 * @nevent_cls_supported: number of event classes supported.
Olav Haugan99660ca2012-12-04 13:30:41 -080086 * @enabled: Indicates whether perf. mon is enabled or not
87 * @iommu_attached Indicates whether iommu is attached or not.
88 * @lock: mutex used to synchronize access to shared data
89 */
90struct iommu_pmon {
91 struct dentry *iommu_dir;
92 struct iommu_info iommu;
93 struct list_head iommu_list;
94 struct iommu_pmon_cnt_group *cnt_grp;
Olav Haugan0c2d9322013-01-31 18:35:30 -080095 u32 num_groups;
96 u32 num_counters;
97 u32 *event_cls_supported;
98 u32 nevent_cls_supported;
Olav Haugan99660ca2012-12-04 13:30:41 -080099 unsigned int enabled;
100 unsigned int iommu_attach_count;
101 struct mutex lock;
102};
103
Olav Hauganef69e892013-02-04 13:47:08 -0800104/**
105 * struct iommu_hw_ops - Callbacks for accessing IOMMU HW
Olav Haugan7a2f99c2013-02-04 14:43:26 -0800106 * @initialize_hw: Call to do any initialization before enabling ovf interrupts
Olav Hauganef69e892013-02-04 13:47:08 -0800107 * @is_hw_access_ok: Returns 1 if we can access HW, 0 otherwise
108 * @grp_enable: Call to enable a counter group
109 * @grp_disable: Call to disable a counter group
110 * @enable_pm: Call to enable PM
111 * @disable_pm: Call to disable PM
112 * @reset_counters: Call to reset counters
113 * @check_for_overflow: Call to check for overflow
114 * @evt_ovfl_int_handler: Overflow interrupt handler callback
115 * @counter_enable: Call to enable counters
116 * @counter_disable: Call to disable counters
117 * @ovfl_int_enable: Call to enable overflow interrupts
118 * @ovfl_int_disable: Call to disable overflow interrupts
119 * @set_event_class: Call to set event class
120 * @read_counter: Call to read a counter value
121 */
122struct iommu_pm_hw_ops {
Olav Haugan7a2f99c2013-02-04 14:43:26 -0800123 void (*initialize_hw)(const struct iommu_pmon *);
Olav Hauganef69e892013-02-04 13:47:08 -0800124 unsigned int (*is_hw_access_OK)(const struct iommu_pmon *);
125 void (*grp_enable)(struct iommu_info *, unsigned int);
126 void (*grp_disable)(struct iommu_info *, unsigned int);
127 void (*enable_pm)(struct iommu_info *);
128 void (*disable_pm)(struct iommu_info *);
129 void (*reset_counters)(const struct iommu_info *);
130 void (*check_for_overflow)(struct iommu_pmon *);
131 irqreturn_t (*evt_ovfl_int_handler)(int, void *);
132 void (*counter_enable)(struct iommu_info *,
133 struct iommu_pmon_counter *);
134 void (*counter_disable)(struct iommu_info *,
135 struct iommu_pmon_counter *);
136 void (*ovfl_int_enable)(struct iommu_info *,
137 const struct iommu_pmon_counter *);
138 void (*ovfl_int_disable)(struct iommu_info *,
139 const struct iommu_pmon_counter *);
140 void (*set_event_class)(struct iommu_pmon *pmon, unsigned int,
141 unsigned int);
142 unsigned int (*read_counter)(struct iommu_pmon_counter *);
143};
144
Olav Haugan7a2f99c2013-02-04 14:43:26 -0800145extern struct iommu_access_ops iommu_access_ops_v0;
Olav Hauganef69e892013-02-04 13:47:08 -0800146extern struct iommu_access_ops iommu_access_ops_v1;
Olav Haugan7a2f99c2013-02-04 14:43:26 -0800147#define MSM_IOMMU_PMU_NO_EVENT_CLASS -1
Olav Haugan99660ca2012-12-04 13:30:41 -0800148
149#ifdef CONFIG_MSM_IOMMU_PMON
Olav Hauganef69e892013-02-04 13:47:08 -0800150
151/**
Olav Haugan7a2f99c2013-02-04 14:43:26 -0800152 * Get pointer to PMU hardware access functions for IOMMUv0 PMU
153 */
154struct iommu_pm_hw_ops *iommu_pm_get_hw_ops_v0(void);
155
156/**
Olav Hauganef69e892013-02-04 13:47:08 -0800157 * Get pointer to PMU hardware access functions for IOMMUv1 PMU
158 */
159struct iommu_pm_hw_ops *iommu_pm_get_hw_ops_v1(void);
160
Olav Haugan99660ca2012-12-04 13:30:41 -0800161/**
162 * Allocate memory for performance monitor structure. Must
Olav Haugan0c2d9322013-01-31 18:35:30 -0800163 * be called before iommu_pm_iommu_register
Olav Haugan99660ca2012-12-04 13:30:41 -0800164 */
Olav Haugan0c2d9322013-01-31 18:35:30 -0800165struct iommu_pmon *msm_iommu_pm_alloc(struct device *iommu_dev);
Olav Haugan99660ca2012-12-04 13:30:41 -0800166
167/**
168 * Free memory previously allocated with iommu_pm_alloc
169 */
170void msm_iommu_pm_free(struct device *iommu_dev);
171
172/**
173 * Register iommu with the performance monitor module.
174 */
Olav Haugan0c2d9322013-01-31 18:35:30 -0800175int msm_iommu_pm_iommu_register(struct iommu_pmon *info);
Olav Haugan99660ca2012-12-04 13:30:41 -0800176
177/**
178 * Unregister iommu with the performance monitor module.
179 */
180void msm_iommu_pm_iommu_unregister(struct device *dev);
181
182/**
183 * Called by iommu driver when attaching is complete
184 * Must NOT be called with IOMMU mutexes held.
185 * @param iommu_dev IOMMU device that is attached
186 */
187void msm_iommu_attached(struct device *dev);
188
189/**
190 * Called by iommu driver before detaching.
191 * Must NOT be called with IOMMU mutexes held.
192 * @param iommu_dev IOMMU device that is going to be detached
193 */
194void msm_iommu_detached(struct device *dev);
195#else
Olav Haugan7a2f99c2013-02-04 14:43:26 -0800196static inline struct iommu_pm_hw_ops *iommu_pm_get_hw_ops_v0(void)
197{
198 return NULL;
199}
200
Olav Hauganef69e892013-02-04 13:47:08 -0800201static inline struct iommu_pm_hw_ops *iommu_pm_get_hw_ops_v1(void)
202{
203 return NULL;
204}
205
Olav Haugan0c2d9322013-01-31 18:35:30 -0800206static inline struct iommu_pmon *msm_iommu_pm_alloc(struct device *iommu_dev)
Olav Haugan99660ca2012-12-04 13:30:41 -0800207{
208 return NULL;
209}
210
211static inline void msm_iommu_pm_free(struct device *iommu_dev)
212{
213 return;
214}
215
Olav Haugan0c2d9322013-01-31 18:35:30 -0800216static inline int msm_iommu_pm_iommu_register(struct iommu_pmon *info)
Olav Haugan99660ca2012-12-04 13:30:41 -0800217{
218 return -EIO;
219}
220
221static inline void msm_iommu_pm_iommu_unregister(struct device *dev)
222{
223}
224
225static inline void msm_iommu_attached(struct device *dev)
226{
227}
228
229static inline void msm_iommu_detached(struct device *dev)
230{
231}
232#endif
233#endif