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