xref: /openbmc/linux/include/soc/tegra/mc.h (revision d1478aea)
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;
99ce2785a7SDmitry Osipenko struct gart_device;
10089184651SThierry Reding 
10189184651SThierry Reding #ifdef CONFIG_TEGRA_IOMMU_SMMU
10289184651SThierry Reding struct tegra_smmu *tegra_smmu_probe(struct device *dev,
10389184651SThierry Reding 				    const struct tegra_smmu_soc *soc,
10489184651SThierry Reding 				    struct tegra_mc *mc);
105d1313e78SThierry Reding void tegra_smmu_remove(struct tegra_smmu *smmu);
10689184651SThierry Reding #else
10789184651SThierry Reding static inline struct tegra_smmu *
tegra_smmu_probe(struct device * dev,const struct tegra_smmu_soc * soc,struct tegra_mc * mc)10889184651SThierry Reding tegra_smmu_probe(struct device *dev, const struct tegra_smmu_soc *soc,
10989184651SThierry Reding 		 struct tegra_mc *mc)
11089184651SThierry Reding {
11189184651SThierry Reding 	return NULL;
11289184651SThierry Reding }
113d1313e78SThierry Reding 
tegra_smmu_remove(struct tegra_smmu * smmu)114d1313e78SThierry Reding static inline void tegra_smmu_remove(struct tegra_smmu *smmu)
115d1313e78SThierry Reding {
116d1313e78SThierry Reding }
11789184651SThierry Reding #endif
11889184651SThierry Reding 
119ce2785a7SDmitry Osipenko #ifdef CONFIG_TEGRA_IOMMU_GART
120ce2785a7SDmitry Osipenko struct gart_device *tegra_gart_probe(struct device *dev, struct tegra_mc *mc);
121ce2785a7SDmitry Osipenko int tegra_gart_suspend(struct gart_device *gart);
122ce2785a7SDmitry Osipenko int tegra_gart_resume(struct gart_device *gart);
123ce2785a7SDmitry Osipenko #else
124ce2785a7SDmitry Osipenko static inline struct gart_device *
tegra_gart_probe(struct device * dev,struct tegra_mc * mc)125ce2785a7SDmitry Osipenko tegra_gart_probe(struct device *dev, struct tegra_mc *mc)
126ce2785a7SDmitry Osipenko {
127ce2785a7SDmitry Osipenko 	return ERR_PTR(-ENODEV);
128ce2785a7SDmitry Osipenko }
129ce2785a7SDmitry Osipenko 
tegra_gart_suspend(struct gart_device * gart)130ce2785a7SDmitry Osipenko static inline int tegra_gart_suspend(struct gart_device *gart)
131ce2785a7SDmitry Osipenko {
132ce2785a7SDmitry Osipenko 	return -ENODEV;
133ce2785a7SDmitry Osipenko }
134ce2785a7SDmitry Osipenko 
tegra_gart_resume(struct gart_device * gart)135ce2785a7SDmitry Osipenko static inline int tegra_gart_resume(struct gart_device *gart)
136ce2785a7SDmitry Osipenko {
137ce2785a7SDmitry Osipenko 	return -ENODEV;
138ce2785a7SDmitry Osipenko }
139ce2785a7SDmitry Osipenko #endif
140ce2785a7SDmitry Osipenko 
14120e92462SDmitry Osipenko struct tegra_mc_reset {
14220e92462SDmitry Osipenko 	const char *name;
14320e92462SDmitry Osipenko 	unsigned long id;
14420e92462SDmitry Osipenko 	unsigned int control;
14520e92462SDmitry Osipenko 	unsigned int status;
14620e92462SDmitry Osipenko 	unsigned int reset;
14720e92462SDmitry Osipenko 	unsigned int bit;
14820e92462SDmitry Osipenko };
14920e92462SDmitry Osipenko 
15020e92462SDmitry Osipenko struct tegra_mc_reset_ops {
15120e92462SDmitry Osipenko 	int (*hotreset_assert)(struct tegra_mc *mc,
15220e92462SDmitry Osipenko 			       const struct tegra_mc_reset *rst);
15320e92462SDmitry Osipenko 	int (*hotreset_deassert)(struct tegra_mc *mc,
15420e92462SDmitry Osipenko 				 const struct tegra_mc_reset *rst);
15520e92462SDmitry Osipenko 	int (*block_dma)(struct tegra_mc *mc,
15620e92462SDmitry Osipenko 			 const struct tegra_mc_reset *rst);
15720e92462SDmitry Osipenko 	bool (*dma_idling)(struct tegra_mc *mc,
15820e92462SDmitry Osipenko 			   const struct tegra_mc_reset *rst);
15920e92462SDmitry Osipenko 	int (*unblock_dma)(struct tegra_mc *mc,
16020e92462SDmitry Osipenko 			   const struct tegra_mc_reset *rst);
16120e92462SDmitry Osipenko 	int (*reset_status)(struct tegra_mc *mc,
16220e92462SDmitry Osipenko 			    const struct tegra_mc_reset *rst);
16320e92462SDmitry Osipenko };
16420e92462SDmitry Osipenko 
16506f07981SDmitry Osipenko #define TEGRA_MC_ICC_TAG_DEFAULT				0
16606f07981SDmitry Osipenko #define TEGRA_MC_ICC_TAG_ISO					BIT(0)
16706f07981SDmitry Osipenko 
16806f07981SDmitry Osipenko struct tegra_mc_icc_ops {
16906f07981SDmitry Osipenko 	int (*set)(struct icc_node *src, struct icc_node *dst);
17006f07981SDmitry Osipenko 	int (*aggregate)(struct icc_node *node, u32 tag, u32 avg_bw,
17106f07981SDmitry Osipenko 			 u32 peak_bw, u32 *agg_avg, u32 *agg_peak);
1729a38cb27SSumit Gupta 	struct icc_node* (*xlate)(struct of_phandle_args *spec, void *data);
17306f07981SDmitry Osipenko 	struct icc_node_data *(*xlate_extended)(struct of_phandle_args *spec,
17406f07981SDmitry Osipenko 						void *data);
1759a38cb27SSumit Gupta 	int (*get_bw)(struct icc_node *node, u32 *avg, u32 *peak);
17606f07981SDmitry Osipenko };
17706f07981SDmitry Osipenko 
178*d1478aeaSThierry Reding struct icc_node *tegra_mc_icc_xlate(struct of_phandle_args *spec, void *data);
179*d1478aeaSThierry Reding extern const struct tegra_mc_icc_ops tegra_mc_icc_ops;
180*d1478aeaSThierry Reding 
1816cc884c1SThierry Reding struct tegra_mc_ops {
182c64738e9SThierry Reding 	/*
183c64738e9SThierry Reding 	 * @probe: Callback to set up SoC-specific bits of the memory controller. This is called
184c64738e9SThierry Reding 	 * after basic, common set up that is done by the SoC-agnostic bits.
185c64738e9SThierry Reding 	 */
186c64738e9SThierry Reding 	int (*probe)(struct tegra_mc *mc);
1877355c7b9SThierry Reding 	void (*remove)(struct tegra_mc *mc);
1885c9016f0SThierry Reding 	int (*suspend)(struct tegra_mc *mc);
1895c9016f0SThierry Reding 	int (*resume)(struct tegra_mc *mc);
1901079a66bSThierry Reding 	irqreturn_t (*handle_irq)(int irq, void *data);
191393d66fdSThierry Reding 	int (*probe_device)(struct tegra_mc *mc, struct device *dev);
1926cc884c1SThierry Reding };
1936cc884c1SThierry Reding 
19489184651SThierry Reding struct tegra_mc_soc {
19589184651SThierry Reding 	const struct tegra_mc_client *clients;
19689184651SThierry Reding 	unsigned int num_clients;
19789184651SThierry Reding 
1983d9dd6fdSMikko Perttunen 	const unsigned long *emem_regs;
19989184651SThierry Reding 	unsigned int num_emem_regs;
20089184651SThierry Reding 
20189184651SThierry Reding 	unsigned int num_address_bits;
20289184651SThierry Reding 	unsigned int atom_size;
20389184651SThierry Reding 
2047946920dSMikko Perttunen 	unsigned int num_carveouts;
2057946920dSMikko Perttunen 
20654a85e09SAshish Mhetre 	u16 client_id_mask;
207a7cffa11SAshish Mhetre 	u8 num_channels;
2083c01cf3bSPaul Walmsley 
20989184651SThierry Reding 	const struct tegra_smmu_soc *smmu;
2101c74d5c0SDmitry Osipenko 
2111c74d5c0SDmitry Osipenko 	u32 intmask;
21254a85e09SAshish Mhetre 	u32 ch_intmask;
21354a85e09SAshish Mhetre 	u32 global_intstatus_channel_shift;
21454a85e09SAshish Mhetre 	bool has_addr_hi_reg;
21520e92462SDmitry Osipenko 
21620e92462SDmitry Osipenko 	const struct tegra_mc_reset_ops *reset_ops;
21720e92462SDmitry Osipenko 	const struct tegra_mc_reset *resets;
21820e92462SDmitry Osipenko 	unsigned int num_resets;
21906f07981SDmitry Osipenko 
22006f07981SDmitry Osipenko 	const struct tegra_mc_icc_ops *icc_ops;
2216cc884c1SThierry Reding 	const struct tegra_mc_ops *ops;
22289184651SThierry Reding };
22389184651SThierry Reding 
22489184651SThierry Reding struct tegra_mc {
2259a38cb27SSumit Gupta 	struct tegra_bpmp *bpmp;
22689184651SThierry Reding 	struct device *dev;
22789184651SThierry Reding 	struct tegra_smmu *smmu;
228ce2785a7SDmitry Osipenko 	struct gart_device *gart;
22996efa118SDmitry Osipenko 	void __iomem *regs;
230a7cffa11SAshish Mhetre 	void __iomem *bcast_ch_regs;
231a7cffa11SAshish Mhetre 	void __iomem **ch_regs;
23289184651SThierry Reding 	struct clk *clk;
23389184651SThierry Reding 	int irq;
23489184651SThierry Reding 
23589184651SThierry Reding 	const struct tegra_mc_soc *soc;
23689184651SThierry Reding 	unsigned long tick;
2373d9dd6fdSMikko Perttunen 
2383d9dd6fdSMikko Perttunen 	struct tegra_mc_timing *timings;
2393d9dd6fdSMikko Perttunen 	unsigned int num_timings;
240e852af72SSumit Gupta 	unsigned int num_channels;
24120e92462SDmitry Osipenko 
2429a38cb27SSumit Gupta 	bool bwmgr_mrq_supported;
24320e92462SDmitry Osipenko 	struct reset_controller_dev reset;
24420e92462SDmitry Osipenko 
24506f07981SDmitry Osipenko 	struct icc_provider provider;
24606f07981SDmitry Osipenko 
24720e92462SDmitry Osipenko 	spinlock_t lock;
248fbd31f5aSDmitry Osipenko 
249fbd31f5aSDmitry Osipenko 	struct {
250fbd31f5aSDmitry Osipenko 		struct dentry *root;
251fbd31f5aSDmitry Osipenko 	} debugfs;
25289184651SThierry Reding };
25389184651SThierry Reding 
254e34212c7SDmitry Osipenko int tegra_mc_write_emem_configuration(struct tegra_mc *mc, unsigned long rate);
2553d9dd6fdSMikko Perttunen unsigned int tegra_mc_get_emem_device_count(struct tegra_mc *mc);
2563d9dd6fdSMikko Perttunen 
2576c6bd207SDmitry Osipenko #ifdef CONFIG_TEGRA_MC
2586c6bd207SDmitry Osipenko struct tegra_mc *devm_tegra_memory_controller_get(struct device *dev);
25947661ee1SThierry Reding int tegra_mc_probe_device(struct tegra_mc *mc, struct device *dev);
2607946920dSMikko Perttunen int tegra_mc_get_carveout_info(struct tegra_mc *mc, unsigned int id,
2617946920dSMikko Perttunen                                phys_addr_t *base, u64 *size);
2626c6bd207SDmitry Osipenko #else
2636c6bd207SDmitry Osipenko static inline struct tegra_mc *
devm_tegra_memory_controller_get(struct device * dev)2646c6bd207SDmitry Osipenko devm_tegra_memory_controller_get(struct device *dev)
2656c6bd207SDmitry Osipenko {
2663a0b6b5aSDmitry Osipenko 	return ERR_PTR(-ENODEV);
2676c6bd207SDmitry Osipenko }
2686c6bd207SDmitry Osipenko 
26947661ee1SThierry Reding static inline int
tegra_mc_probe_device(struct tegra_mc * mc,struct device * dev)27047661ee1SThierry Reding tegra_mc_probe_device(struct tegra_mc *mc, struct device *dev)
27147661ee1SThierry Reding {
27247661ee1SThierry Reding 	return -ENODEV;
27347661ee1SThierry Reding }
2747946920dSMikko Perttunen 
2757946920dSMikko Perttunen static inline int
tegra_mc_get_carveout_info(struct tegra_mc * mc,unsigned int id,phys_addr_t * base,u64 * size)2767946920dSMikko Perttunen tegra_mc_get_carveout_info(struct tegra_mc *mc, unsigned int id,
2777946920dSMikko Perttunen                            phys_addr_t *base, u64 *size)
2787946920dSMikko Perttunen {
2797946920dSMikko Perttunen 	return -ENODEV;
2807946920dSMikko Perttunen }
28147661ee1SThierry Reding #endif
282393d66fdSThierry Reding 
28389184651SThierry Reding #endif /* __SOC_TEGRA_MC_H__ */
284