1d2912cb1SThomas Gleixner /* SPDX-License-Identifier: GPL-2.0-only */
289184651SThierry Reding /*
389184651SThierry Reding * Copyright (C) 2014 NVIDIA Corporation
489184651SThierry Reding */
589184651SThierry Reding
689184651SThierry Reding #ifndef __SOC_TEGRA_MC_H__
789184651SThierry Reding #define __SOC_TEGRA_MC_H__
889184651SThierry Reding
906f07981SDmitry Osipenko #include <linux/bits.h>
10fbd31f5aSDmitry Osipenko #include <linux/debugfs.h>
11ce2785a7SDmitry Osipenko #include <linux/err.h>
1206f07981SDmitry Osipenko #include <linux/interconnect-provider.h>
131079a66bSThierry Reding #include <linux/irq.h>
1420e92462SDmitry Osipenko #include <linux/reset-controller.h>
1589184651SThierry Reding #include <linux/types.h>
169a38cb27SSumit Gupta #include <linux/tegra-icc.h>
1789184651SThierry Reding
1889184651SThierry Reding struct clk;
1989184651SThierry Reding struct device;
2089184651SThierry Reding struct page;
2189184651SThierry Reding
223d9dd6fdSMikko Perttunen struct tegra_mc_timing {
233d9dd6fdSMikko Perttunen unsigned long rate;
243d9dd6fdSMikko Perttunen
253d9dd6fdSMikko Perttunen u32 *emem_data;
263d9dd6fdSMikko Perttunen };
273d9dd6fdSMikko Perttunen
2889184651SThierry Reding struct tegra_mc_client {
2989184651SThierry Reding unsigned int id;
309a38cb27SSumit Gupta unsigned int bpmp_id;
319a38cb27SSumit Gupta enum tegra_icc_client_type type;
3289184651SThierry Reding const char *name;
33e8999938SThierry Reding /*
34e8999938SThierry Reding * For Tegra210 and earlier, this is the SWGROUP ID used for IOVA translations in the
35e8999938SThierry Reding * Tegra SMMU, whereas on Tegra186 and later this is the ID used to override the ARM SMMU
36e8999938SThierry Reding * stream ID used for IOVA translations for the given memory client.
37e8999938SThierry Reding */
38e8999938SThierry Reding union {
3989184651SThierry Reding unsigned int swgroup;
40e8999938SThierry Reding unsigned int sid;
41e8999938SThierry Reding };
4289184651SThierry Reding
4389184651SThierry Reding unsigned int fifo_size;
4489184651SThierry Reding
454f1ac76eSThierry Reding struct {
46e8999938SThierry Reding /* Tegra SMMU enable (Tegra210 and earlier) */
474f1ac76eSThierry Reding struct {
484f1ac76eSThierry Reding unsigned int reg;
494f1ac76eSThierry Reding unsigned int bit;
504f1ac76eSThierry Reding } smmu;
514f1ac76eSThierry Reding
524f1ac76eSThierry Reding /* latency allowance */
534f1ac76eSThierry Reding struct {
544f1ac76eSThierry Reding unsigned int reg;
554f1ac76eSThierry Reding unsigned int shift;
564f1ac76eSThierry Reding unsigned int mask;
574f1ac76eSThierry Reding unsigned int def;
584f1ac76eSThierry Reding } la;
59e8999938SThierry Reding
60e8999938SThierry Reding /* stream ID overrides (Tegra186 and later) */
61e8999938SThierry Reding struct {
62e8999938SThierry Reding unsigned int override;
63e8999938SThierry Reding unsigned int security;
64e8999938SThierry Reding } sid;
654f1ac76eSThierry Reding } regs;
6689184651SThierry Reding };
6789184651SThierry Reding
6889184651SThierry Reding struct tegra_smmu_swgroup {
69e660df07SThierry Reding const char *name;
7089184651SThierry Reding unsigned int swgroup;
7189184651SThierry Reding unsigned int reg;
7289184651SThierry Reding };
7389184651SThierry Reding
742a8102dfSThierry Reding struct tegra_smmu_group_soc {
752a8102dfSThierry Reding const char *name;
762a8102dfSThierry Reding const unsigned int *swgroups;
772a8102dfSThierry Reding unsigned int num_swgroups;
782a8102dfSThierry Reding };
792a8102dfSThierry Reding
8089184651SThierry Reding struct tegra_smmu_soc {
8189184651SThierry Reding const struct tegra_mc_client *clients;
8289184651SThierry Reding unsigned int num_clients;
8389184651SThierry Reding
8489184651SThierry Reding const struct tegra_smmu_swgroup *swgroups;
8589184651SThierry Reding unsigned int num_swgroups;
8689184651SThierry Reding
872a8102dfSThierry Reding const struct tegra_smmu_group_soc *groups;
882a8102dfSThierry Reding unsigned int num_groups;
892a8102dfSThierry Reding
9089184651SThierry Reding bool supports_round_robin_arbitration;
9189184651SThierry Reding bool supports_request_limit;
9289184651SThierry Reding
9311cec15bSThierry Reding unsigned int num_tlb_lines;
9489184651SThierry Reding unsigned int num_asids;
9589184651SThierry Reding };
9689184651SThierry Reding
9789184651SThierry Reding struct tegra_mc;
9889184651SThierry Reding struct tegra_smmu;
9989184651SThierry Reding
10089184651SThierry Reding #ifdef CONFIG_TEGRA_IOMMU_SMMU
10189184651SThierry Reding struct tegra_smmu *tegra_smmu_probe(struct device *dev,
10289184651SThierry Reding const struct tegra_smmu_soc *soc,
10389184651SThierry Reding struct tegra_mc *mc);
104d1313e78SThierry Reding void tegra_smmu_remove(struct tegra_smmu *smmu);
10589184651SThierry Reding #else
10689184651SThierry Reding static inline struct tegra_smmu *
tegra_smmu_probe(struct device * dev,const struct tegra_smmu_soc * soc,struct tegra_mc * mc)10789184651SThierry Reding tegra_smmu_probe(struct device *dev, const struct tegra_smmu_soc *soc,
10889184651SThierry Reding struct tegra_mc *mc)
10989184651SThierry Reding {
11089184651SThierry Reding return NULL;
11189184651SThierry Reding }
112d1313e78SThierry Reding
tegra_smmu_remove(struct tegra_smmu * smmu)113d1313e78SThierry Reding static inline void tegra_smmu_remove(struct tegra_smmu *smmu)
114d1313e78SThierry Reding {
115d1313e78SThierry Reding }
11689184651SThierry Reding #endif
11789184651SThierry Reding
11820e92462SDmitry Osipenko struct tegra_mc_reset {
11920e92462SDmitry Osipenko const char *name;
12020e92462SDmitry Osipenko unsigned long id;
12120e92462SDmitry Osipenko unsigned int control;
12220e92462SDmitry Osipenko unsigned int status;
12320e92462SDmitry Osipenko unsigned int reset;
12420e92462SDmitry Osipenko unsigned int bit;
12520e92462SDmitry Osipenko };
12620e92462SDmitry Osipenko
12720e92462SDmitry Osipenko struct tegra_mc_reset_ops {
12820e92462SDmitry Osipenko int (*hotreset_assert)(struct tegra_mc *mc,
12920e92462SDmitry Osipenko const struct tegra_mc_reset *rst);
13020e92462SDmitry Osipenko int (*hotreset_deassert)(struct tegra_mc *mc,
13120e92462SDmitry Osipenko const struct tegra_mc_reset *rst);
13220e92462SDmitry Osipenko int (*block_dma)(struct tegra_mc *mc,
13320e92462SDmitry Osipenko const struct tegra_mc_reset *rst);
13420e92462SDmitry Osipenko bool (*dma_idling)(struct tegra_mc *mc,
13520e92462SDmitry Osipenko const struct tegra_mc_reset *rst);
13620e92462SDmitry Osipenko int (*unblock_dma)(struct tegra_mc *mc,
13720e92462SDmitry Osipenko const struct tegra_mc_reset *rst);
13820e92462SDmitry Osipenko int (*reset_status)(struct tegra_mc *mc,
13920e92462SDmitry Osipenko const struct tegra_mc_reset *rst);
14020e92462SDmitry Osipenko };
14120e92462SDmitry Osipenko
14206f07981SDmitry Osipenko #define TEGRA_MC_ICC_TAG_DEFAULT 0
14306f07981SDmitry Osipenko #define TEGRA_MC_ICC_TAG_ISO BIT(0)
14406f07981SDmitry Osipenko
14506f07981SDmitry Osipenko struct tegra_mc_icc_ops {
14606f07981SDmitry Osipenko int (*set)(struct icc_node *src, struct icc_node *dst);
14706f07981SDmitry Osipenko int (*aggregate)(struct icc_node *node, u32 tag, u32 avg_bw,
14806f07981SDmitry Osipenko u32 peak_bw, u32 *agg_avg, u32 *agg_peak);
149*0dc5b8abSKrzysztof Kozlowski struct icc_node* (*xlate)(const struct of_phandle_args *spec, void *data);
150*0dc5b8abSKrzysztof Kozlowski struct icc_node_data *(*xlate_extended)(const struct of_phandle_args *spec,
15106f07981SDmitry Osipenko void *data);
1529a38cb27SSumit Gupta int (*get_bw)(struct icc_node *node, u32 *avg, u32 *peak);
15306f07981SDmitry Osipenko };
15406f07981SDmitry Osipenko
155*0dc5b8abSKrzysztof Kozlowski struct icc_node *tegra_mc_icc_xlate(const struct of_phandle_args *spec,
156*0dc5b8abSKrzysztof Kozlowski void *data);
157d1478aeaSThierry Reding extern const struct tegra_mc_icc_ops tegra_mc_icc_ops;
158d1478aeaSThierry Reding
1596cc884c1SThierry Reding struct tegra_mc_ops {
160c64738e9SThierry Reding /*
161c64738e9SThierry Reding * @probe: Callback to set up SoC-specific bits of the memory controller. This is called
162c64738e9SThierry Reding * after basic, common set up that is done by the SoC-agnostic bits.
163c64738e9SThierry Reding */
164c64738e9SThierry Reding int (*probe)(struct tegra_mc *mc);
1657355c7b9SThierry Reding void (*remove)(struct tegra_mc *mc);
166fe3b082aSAshish Mhetre int (*resume)(struct tegra_mc *mc);
1671079a66bSThierry Reding irqreturn_t (*handle_irq)(int irq, void *data);
168393d66fdSThierry Reding int (*probe_device)(struct tegra_mc *mc, struct device *dev);
1696cc884c1SThierry Reding };
1706cc884c1SThierry Reding
17189184651SThierry Reding struct tegra_mc_soc {
17289184651SThierry Reding const struct tegra_mc_client *clients;
17389184651SThierry Reding unsigned int num_clients;
17489184651SThierry Reding
1753d9dd6fdSMikko Perttunen const unsigned long *emem_regs;
17689184651SThierry Reding unsigned int num_emem_regs;
17789184651SThierry Reding
17889184651SThierry Reding unsigned int num_address_bits;
17989184651SThierry Reding unsigned int atom_size;
18089184651SThierry Reding
1817946920dSMikko Perttunen unsigned int num_carveouts;
1827946920dSMikko Perttunen
18354a85e09SAshish Mhetre u16 client_id_mask;
184a7cffa11SAshish Mhetre u8 num_channels;
1853c01cf3bSPaul Walmsley
18689184651SThierry Reding const struct tegra_smmu_soc *smmu;
1871c74d5c0SDmitry Osipenko
1881c74d5c0SDmitry Osipenko u32 intmask;
18954a85e09SAshish Mhetre u32 ch_intmask;
19054a85e09SAshish Mhetre u32 global_intstatus_channel_shift;
19154a85e09SAshish Mhetre bool has_addr_hi_reg;
19220e92462SDmitry Osipenko
19320e92462SDmitry Osipenko const struct tegra_mc_reset_ops *reset_ops;
19420e92462SDmitry Osipenko const struct tegra_mc_reset *resets;
19520e92462SDmitry Osipenko unsigned int num_resets;
19606f07981SDmitry Osipenko
19706f07981SDmitry Osipenko const struct tegra_mc_icc_ops *icc_ops;
1986cc884c1SThierry Reding const struct tegra_mc_ops *ops;
19989184651SThierry Reding };
20089184651SThierry Reding
20189184651SThierry Reding struct tegra_mc {
2029a38cb27SSumit Gupta struct tegra_bpmp *bpmp;
20389184651SThierry Reding struct device *dev;
20489184651SThierry Reding struct tegra_smmu *smmu;
20596efa118SDmitry Osipenko void __iomem *regs;
206a7cffa11SAshish Mhetre void __iomem *bcast_ch_regs;
207a7cffa11SAshish Mhetre void __iomem **ch_regs;
20889184651SThierry Reding struct clk *clk;
20989184651SThierry Reding int irq;
21089184651SThierry Reding
21189184651SThierry Reding const struct tegra_mc_soc *soc;
21289184651SThierry Reding unsigned long tick;
2133d9dd6fdSMikko Perttunen
2143d9dd6fdSMikko Perttunen struct tegra_mc_timing *timings;
2153d9dd6fdSMikko Perttunen unsigned int num_timings;
216e852af72SSumit Gupta unsigned int num_channels;
21720e92462SDmitry Osipenko
2189a38cb27SSumit Gupta bool bwmgr_mrq_supported;
21920e92462SDmitry Osipenko struct reset_controller_dev reset;
22020e92462SDmitry Osipenko
22106f07981SDmitry Osipenko struct icc_provider provider;
22206f07981SDmitry Osipenko
22320e92462SDmitry Osipenko spinlock_t lock;
224fbd31f5aSDmitry Osipenko
225fbd31f5aSDmitry Osipenko struct {
226fbd31f5aSDmitry Osipenko struct dentry *root;
227fbd31f5aSDmitry Osipenko } debugfs;
22889184651SThierry Reding };
22989184651SThierry Reding
230e34212c7SDmitry Osipenko int tegra_mc_write_emem_configuration(struct tegra_mc *mc, unsigned long rate);
2313d9dd6fdSMikko Perttunen unsigned int tegra_mc_get_emem_device_count(struct tegra_mc *mc);
2323d9dd6fdSMikko Perttunen
2336c6bd207SDmitry Osipenko #ifdef CONFIG_TEGRA_MC
2346c6bd207SDmitry Osipenko struct tegra_mc *devm_tegra_memory_controller_get(struct device *dev);
23547661ee1SThierry Reding int tegra_mc_probe_device(struct tegra_mc *mc, struct device *dev);
2367946920dSMikko Perttunen int tegra_mc_get_carveout_info(struct tegra_mc *mc, unsigned int id,
2377946920dSMikko Perttunen phys_addr_t *base, u64 *size);
2386c6bd207SDmitry Osipenko #else
2396c6bd207SDmitry Osipenko static inline struct tegra_mc *
devm_tegra_memory_controller_get(struct device * dev)2406c6bd207SDmitry Osipenko devm_tegra_memory_controller_get(struct device *dev)
2416c6bd207SDmitry Osipenko {
2423a0b6b5aSDmitry Osipenko return ERR_PTR(-ENODEV);
2436c6bd207SDmitry Osipenko }
2446c6bd207SDmitry Osipenko
24547661ee1SThierry Reding static inline int
tegra_mc_probe_device(struct tegra_mc * mc,struct device * dev)24647661ee1SThierry Reding tegra_mc_probe_device(struct tegra_mc *mc, struct device *dev)
24747661ee1SThierry Reding {
24847661ee1SThierry Reding return -ENODEV;
24947661ee1SThierry Reding }
2507946920dSMikko Perttunen
2517946920dSMikko Perttunen static inline int
tegra_mc_get_carveout_info(struct tegra_mc * mc,unsigned int id,phys_addr_t * base,u64 * size)2527946920dSMikko Perttunen tegra_mc_get_carveout_info(struct tegra_mc *mc, unsigned int id,
2537946920dSMikko Perttunen phys_addr_t *base, u64 *size)
2547946920dSMikko Perttunen {
2557946920dSMikko Perttunen return -ENODEV;
2567946920dSMikko Perttunen }
25747661ee1SThierry Reding #endif
258393d66fdSThierry Reding
25989184651SThierry Reding #endif /* __SOC_TEGRA_MC_H__ */
260