blob: e489a028ec9f8e49042a6157b9dfc4cdadbe1078 [file] [log] [blame]
Thierry Reding89184652014-04-16 09:24:44 +02001/*
2 * Copyright (C) 2014 NVIDIA Corporation
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 */
8
9#ifndef __SOC_TEGRA_MC_H__
10#define __SOC_TEGRA_MC_H__
11
Dmitry Osipenkoce2785a2018-12-12 23:38:56 +030012#include <linux/err.h>
Dmitry Osipenko20e92462018-04-13 14:33:49 +030013#include <linux/reset-controller.h>
Thierry Reding89184652014-04-16 09:24:44 +020014#include <linux/types.h>
15
16struct clk;
17struct device;
18struct page;
19
20struct tegra_smmu_enable {
21 unsigned int reg;
22 unsigned int bit;
23};
24
Mikko Perttunen3d9dd6f2015-03-12 15:48:02 +010025struct tegra_mc_timing {
26 unsigned long rate;
27
28 u32 *emem_data;
29};
30
Thierry Reding89184652014-04-16 09:24:44 +020031/* latency allowance */
32struct tegra_mc_la {
33 unsigned int reg;
34 unsigned int shift;
35 unsigned int mask;
36 unsigned int def;
37};
38
39struct tegra_mc_client {
40 unsigned int id;
41 const char *name;
42 unsigned int swgroup;
43
44 unsigned int fifo_size;
45
46 struct tegra_smmu_enable smmu;
47 struct tegra_mc_la la;
48};
49
50struct tegra_smmu_swgroup {
Thierry Redinge660df02015-01-23 09:45:35 +010051 const char *name;
Thierry Reding89184652014-04-16 09:24:44 +020052 unsigned int swgroup;
53 unsigned int reg;
54};
55
Thierry Reding2a8102d2017-10-12 16:29:19 +020056struct tegra_smmu_group_soc {
57 const char *name;
58 const unsigned int *swgroups;
59 unsigned int num_swgroups;
60};
61
Thierry Reding89184652014-04-16 09:24:44 +020062struct tegra_smmu_soc {
63 const struct tegra_mc_client *clients;
64 unsigned int num_clients;
65
66 const struct tegra_smmu_swgroup *swgroups;
67 unsigned int num_swgroups;
68
Thierry Reding2a8102d2017-10-12 16:29:19 +020069 const struct tegra_smmu_group_soc *groups;
70 unsigned int num_groups;
71
Thierry Reding89184652014-04-16 09:24:44 +020072 bool supports_round_robin_arbitration;
73 bool supports_request_limit;
74
Thierry Reding11cec152015-08-06 14:20:31 +020075 unsigned int num_tlb_lines;
Thierry Reding89184652014-04-16 09:24:44 +020076 unsigned int num_asids;
Thierry Reding89184652014-04-16 09:24:44 +020077};
78
79struct tegra_mc;
80struct tegra_smmu;
Dmitry Osipenkoce2785a2018-12-12 23:38:56 +030081struct gart_device;
Thierry Reding89184652014-04-16 09:24:44 +020082
83#ifdef CONFIG_TEGRA_IOMMU_SMMU
84struct tegra_smmu *tegra_smmu_probe(struct device *dev,
85 const struct tegra_smmu_soc *soc,
86 struct tegra_mc *mc);
Thierry Redingd1313e72015-01-23 09:49:25 +010087void tegra_smmu_remove(struct tegra_smmu *smmu);
Thierry Reding89184652014-04-16 09:24:44 +020088#else
89static inline struct tegra_smmu *
90tegra_smmu_probe(struct device *dev, const struct tegra_smmu_soc *soc,
91 struct tegra_mc *mc)
92{
93 return NULL;
94}
Thierry Redingd1313e72015-01-23 09:49:25 +010095
96static inline void tegra_smmu_remove(struct tegra_smmu *smmu)
97{
98}
Thierry Reding89184652014-04-16 09:24:44 +020099#endif
100
Dmitry Osipenkoce2785a2018-12-12 23:38:56 +0300101#ifdef CONFIG_TEGRA_IOMMU_GART
102struct gart_device *tegra_gart_probe(struct device *dev, struct tegra_mc *mc);
103int tegra_gart_suspend(struct gart_device *gart);
104int tegra_gart_resume(struct gart_device *gart);
105#else
106static inline struct gart_device *
107tegra_gart_probe(struct device *dev, struct tegra_mc *mc)
108{
109 return ERR_PTR(-ENODEV);
110}
111
112static inline int tegra_gart_suspend(struct gart_device *gart)
113{
114 return -ENODEV;
115}
116
117static inline int tegra_gart_resume(struct gart_device *gart)
118{
119 return -ENODEV;
120}
121#endif
122
Dmitry Osipenko20e92462018-04-13 14:33:49 +0300123struct tegra_mc_reset {
124 const char *name;
125 unsigned long id;
126 unsigned int control;
127 unsigned int status;
128 unsigned int reset;
129 unsigned int bit;
130};
131
132struct tegra_mc_reset_ops {
133 int (*hotreset_assert)(struct tegra_mc *mc,
134 const struct tegra_mc_reset *rst);
135 int (*hotreset_deassert)(struct tegra_mc *mc,
136 const struct tegra_mc_reset *rst);
137 int (*block_dma)(struct tegra_mc *mc,
138 const struct tegra_mc_reset *rst);
139 bool (*dma_idling)(struct tegra_mc *mc,
140 const struct tegra_mc_reset *rst);
141 int (*unblock_dma)(struct tegra_mc *mc,
142 const struct tegra_mc_reset *rst);
143 int (*reset_status)(struct tegra_mc *mc,
144 const struct tegra_mc_reset *rst);
145};
146
Thierry Reding89184652014-04-16 09:24:44 +0200147struct tegra_mc_soc {
148 const struct tegra_mc_client *clients;
149 unsigned int num_clients;
150
Mikko Perttunen3d9dd6f2015-03-12 15:48:02 +0100151 const unsigned long *emem_regs;
Thierry Reding89184652014-04-16 09:24:44 +0200152 unsigned int num_emem_regs;
153
154 unsigned int num_address_bits;
155 unsigned int atom_size;
156
Paul Walmsley3c01cf32015-06-04 19:33:48 +0000157 u8 client_id_mask;
158
Thierry Reding89184652014-04-16 09:24:44 +0200159 const struct tegra_smmu_soc *smmu;
Dmitry Osipenko1c74d5c2018-04-09 22:28:29 +0300160
161 u32 intmask;
Dmitry Osipenko20e92462018-04-13 14:33:49 +0300162
163 const struct tegra_mc_reset_ops *reset_ops;
164 const struct tegra_mc_reset *resets;
165 unsigned int num_resets;
Thierry Reding89184652014-04-16 09:24:44 +0200166};
167
168struct tegra_mc {
169 struct device *dev;
170 struct tegra_smmu *smmu;
Dmitry Osipenkoce2785a2018-12-12 23:38:56 +0300171 struct gart_device *gart;
Dmitry Osipenko96efa112018-12-12 23:38:52 +0300172 void __iomem *regs;
Thierry Reding89184652014-04-16 09:24:44 +0200173 struct clk *clk;
174 int irq;
175
176 const struct tegra_mc_soc *soc;
177 unsigned long tick;
Mikko Perttunen3d9dd6f2015-03-12 15:48:02 +0100178
179 struct tegra_mc_timing *timings;
180 unsigned int num_timings;
Dmitry Osipenko20e92462018-04-13 14:33:49 +0300181
182 struct reset_controller_dev reset;
183
184 spinlock_t lock;
Thierry Reding89184652014-04-16 09:24:44 +0200185};
186
Mikko Perttunen3d9dd6f2015-03-12 15:48:02 +0100187void tegra_mc_write_emem_configuration(struct tegra_mc *mc, unsigned long rate);
188unsigned int tegra_mc_get_emem_device_count(struct tegra_mc *mc);
189
Thierry Reding89184652014-04-16 09:24:44 +0200190#endif /* __SOC_TEGRA_MC_H__ */