1 | /* SPDX-License-Identifier: GPL-2.0-only */ |
2 | /* |
3 | * Copyright (C) 2014 NVIDIA Corporation |
4 | */ |
5 | |
6 | #ifndef __SOC_TEGRA_MC_H__ |
7 | #define __SOC_TEGRA_MC_H__ |
8 | |
9 | #include <linux/bits.h> |
10 | #include <linux/debugfs.h> |
11 | #include <linux/err.h> |
12 | #include <linux/interconnect-provider.h> |
13 | #include <linux/irq.h> |
14 | #include <linux/reset-controller.h> |
15 | #include <linux/types.h> |
16 | #include <linux/tegra-icc.h> |
17 | |
18 | struct clk; |
19 | struct device; |
20 | struct page; |
21 | |
22 | struct tegra_mc_timing { |
23 | unsigned long rate; |
24 | |
25 | u32 *emem_data; |
26 | }; |
27 | |
28 | struct tegra_mc_client { |
29 | unsigned int id; |
30 | unsigned int bpmp_id; |
31 | enum tegra_icc_client_type type; |
32 | const char *name; |
33 | /* |
34 | * For Tegra210 and earlier, this is the SWGROUP ID used for IOVA translations in the |
35 | * Tegra SMMU, whereas on Tegra186 and later this is the ID used to override the ARM SMMU |
36 | * stream ID used for IOVA translations for the given memory client. |
37 | */ |
38 | union { |
39 | unsigned int swgroup; |
40 | unsigned int sid; |
41 | }; |
42 | |
43 | unsigned int fifo_size; |
44 | |
45 | struct { |
46 | /* Tegra SMMU enable (Tegra210 and earlier) */ |
47 | struct { |
48 | unsigned int reg; |
49 | unsigned int bit; |
50 | } smmu; |
51 | |
52 | /* latency allowance */ |
53 | struct { |
54 | unsigned int reg; |
55 | unsigned int shift; |
56 | unsigned int mask; |
57 | unsigned int def; |
58 | } la; |
59 | |
60 | /* stream ID overrides (Tegra186 and later) */ |
61 | struct { |
62 | unsigned int override; |
63 | unsigned int security; |
64 | } sid; |
65 | } regs; |
66 | }; |
67 | |
68 | struct tegra_smmu_swgroup { |
69 | const char *name; |
70 | unsigned int swgroup; |
71 | unsigned int reg; |
72 | }; |
73 | |
74 | struct tegra_smmu_group_soc { |
75 | const char *name; |
76 | const unsigned int *swgroups; |
77 | unsigned int num_swgroups; |
78 | }; |
79 | |
80 | struct tegra_smmu_soc { |
81 | const struct tegra_mc_client *clients; |
82 | unsigned int num_clients; |
83 | |
84 | const struct tegra_smmu_swgroup *swgroups; |
85 | unsigned int num_swgroups; |
86 | |
87 | const struct tegra_smmu_group_soc *groups; |
88 | unsigned int num_groups; |
89 | |
90 | bool supports_round_robin_arbitration; |
91 | bool supports_request_limit; |
92 | |
93 | unsigned int num_tlb_lines; |
94 | unsigned int num_asids; |
95 | }; |
96 | |
97 | struct tegra_mc; |
98 | struct tegra_smmu; |
99 | |
100 | #ifdef CONFIG_TEGRA_IOMMU_SMMU |
101 | struct tegra_smmu *tegra_smmu_probe(struct device *dev, |
102 | const struct tegra_smmu_soc *soc, |
103 | struct tegra_mc *mc); |
104 | void tegra_smmu_remove(struct tegra_smmu *smmu); |
105 | #else |
106 | static inline struct tegra_smmu * |
107 | tegra_smmu_probe(struct device *dev, const struct tegra_smmu_soc *soc, |
108 | struct tegra_mc *mc) |
109 | { |
110 | return NULL; |
111 | } |
112 | |
113 | static inline void tegra_smmu_remove(struct tegra_smmu *smmu) |
114 | { |
115 | } |
116 | #endif |
117 | |
118 | struct tegra_mc_reset { |
119 | const char *name; |
120 | unsigned long id; |
121 | unsigned int control; |
122 | unsigned int status; |
123 | unsigned int reset; |
124 | unsigned int bit; |
125 | }; |
126 | |
127 | struct tegra_mc_reset_ops { |
128 | int (*hotreset_assert)(struct tegra_mc *mc, |
129 | const struct tegra_mc_reset *rst); |
130 | int (*hotreset_deassert)(struct tegra_mc *mc, |
131 | const struct tegra_mc_reset *rst); |
132 | int (*block_dma)(struct tegra_mc *mc, |
133 | const struct tegra_mc_reset *rst); |
134 | bool (*dma_idling)(struct tegra_mc *mc, |
135 | const struct tegra_mc_reset *rst); |
136 | int (*unblock_dma)(struct tegra_mc *mc, |
137 | const struct tegra_mc_reset *rst); |
138 | int (*reset_status)(struct tegra_mc *mc, |
139 | const struct tegra_mc_reset *rst); |
140 | }; |
141 | |
142 | #define TEGRA_MC_ICC_TAG_DEFAULT 0 |
143 | #define TEGRA_MC_ICC_TAG_ISO BIT(0) |
144 | |
145 | struct tegra_mc_icc_ops { |
146 | int (*set)(struct icc_node *src, struct icc_node *dst); |
147 | int (*aggregate)(struct icc_node *node, u32 tag, u32 avg_bw, |
148 | u32 peak_bw, u32 *agg_avg, u32 *agg_peak); |
149 | struct icc_node* (*xlate)(const struct of_phandle_args *spec, void *data); |
150 | struct icc_node_data *(*xlate_extended)(const struct of_phandle_args *spec, |
151 | void *data); |
152 | int (*get_bw)(struct icc_node *node, u32 *avg, u32 *peak); |
153 | }; |
154 | |
155 | struct icc_node *tegra_mc_icc_xlate(const struct of_phandle_args *spec, |
156 | void *data); |
157 | extern const struct tegra_mc_icc_ops tegra_mc_icc_ops; |
158 | |
159 | struct tegra_mc_ops { |
160 | /* |
161 | * @probe: Callback to set up SoC-specific bits of the memory controller. This is called |
162 | * after basic, common set up that is done by the SoC-agnostic bits. |
163 | */ |
164 | int (*probe)(struct tegra_mc *mc); |
165 | void (*remove)(struct tegra_mc *mc); |
166 | int (*resume)(struct tegra_mc *mc); |
167 | irqreturn_t (*handle_irq)(int irq, void *data); |
168 | int (*probe_device)(struct tegra_mc *mc, struct device *dev); |
169 | }; |
170 | |
171 | struct tegra_mc_soc { |
172 | const struct tegra_mc_client *clients; |
173 | unsigned int num_clients; |
174 | |
175 | const unsigned long *emem_regs; |
176 | unsigned int num_emem_regs; |
177 | |
178 | unsigned int num_address_bits; |
179 | unsigned int atom_size; |
180 | |
181 | unsigned int num_carveouts; |
182 | |
183 | u16 client_id_mask; |
184 | u8 num_channels; |
185 | |
186 | const struct tegra_smmu_soc *smmu; |
187 | |
188 | u32 intmask; |
189 | u32 ch_intmask; |
190 | u32 global_intstatus_channel_shift; |
191 | bool has_addr_hi_reg; |
192 | |
193 | const struct tegra_mc_reset_ops *reset_ops; |
194 | const struct tegra_mc_reset *resets; |
195 | unsigned int num_resets; |
196 | |
197 | const struct tegra_mc_icc_ops *icc_ops; |
198 | const struct tegra_mc_ops *ops; |
199 | }; |
200 | |
201 | struct tegra_mc { |
202 | struct tegra_bpmp *bpmp; |
203 | struct device *dev; |
204 | struct tegra_smmu *smmu; |
205 | void __iomem *regs; |
206 | void __iomem *bcast_ch_regs; |
207 | void __iomem **ch_regs; |
208 | struct clk *clk; |
209 | int irq; |
210 | |
211 | const struct tegra_mc_soc *soc; |
212 | unsigned long tick; |
213 | |
214 | struct tegra_mc_timing *timings; |
215 | unsigned int num_timings; |
216 | unsigned int num_channels; |
217 | |
218 | bool bwmgr_mrq_supported; |
219 | struct reset_controller_dev reset; |
220 | |
221 | struct icc_provider provider; |
222 | |
223 | spinlock_t lock; |
224 | |
225 | struct { |
226 | struct dentry *root; |
227 | } debugfs; |
228 | }; |
229 | |
230 | int tegra_mc_write_emem_configuration(struct tegra_mc *mc, unsigned long rate); |
231 | unsigned int tegra_mc_get_emem_device_count(struct tegra_mc *mc); |
232 | |
233 | #ifdef CONFIG_TEGRA_MC |
234 | struct tegra_mc *devm_tegra_memory_controller_get(struct device *dev); |
235 | int tegra_mc_probe_device(struct tegra_mc *mc, struct device *dev); |
236 | int tegra_mc_get_carveout_info(struct tegra_mc *mc, unsigned int id, |
237 | phys_addr_t *base, u64 *size); |
238 | #else |
239 | static inline struct tegra_mc * |
240 | devm_tegra_memory_controller_get(struct device *dev) |
241 | { |
242 | return ERR_PTR(-ENODEV); |
243 | } |
244 | |
245 | static inline int |
246 | tegra_mc_probe_device(struct tegra_mc *mc, struct device *dev) |
247 | { |
248 | return -ENODEV; |
249 | } |
250 | |
251 | static inline int |
252 | tegra_mc_get_carveout_info(struct tegra_mc *mc, unsigned int id, |
253 | phys_addr_t *base, u64 *size) |
254 | { |
255 | return -ENODEV; |
256 | } |
257 | #endif |
258 | |
259 | #endif /* __SOC_TEGRA_MC_H__ */ |
260 | |