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