289 lines · 6.7 KB · C
RawDownload
/* SPDX-License-Identifier: GPL-2.0-only *//* * Copyright (C) 2014-2026 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/interrupt.h>#include <linux/irq.h>#include <linux/reset-controller.h>#include <linux/tegra-icc.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;	unsigned int bpmp_id;	enum tegra_icc_client_type type;	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; #ifdef CONFIG_TEGRA_IOMMU_SMMUstruct 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);#elsestatic 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 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* (*xlate)(const struct of_phandle_args *spec, void *data);	struct icc_node_data *(*xlate_extended)(const struct of_phandle_args *spec,						void *data);	int (*get_bw)(struct icc_node *node, u32 *avg, u32 *peak);}; struct icc_node *tegra_mc_icc_xlate(const struct of_phandle_args *spec,				    void *data);extern const struct tegra_mc_icc_ops tegra_mc_icc_ops; 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);	void (*resume)(struct tegra_mc *mc);	int (*probe_device)(struct tegra_mc *mc, struct device *dev);}; struct tegra_mc_regs {	unsigned int cfg_channel_enable;	unsigned int err_status;	unsigned int err_add;	unsigned int err_add_hi;	unsigned int err_vpr_status;	unsigned int err_vpr_add;	unsigned int err_sec_status;	unsigned int err_sec_add;	unsigned int err_mts_status;	unsigned int err_mts_add;	unsigned int err_gen_co_status;	unsigned int err_gen_co_add;	unsigned int err_route_status;	unsigned int err_route_add;}; struct tegra_mc_intmask {	u32 reg;	u32 mask;}; 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; 	unsigned int num_carveouts; 	u16 client_id_mask;	u8 num_channels; 	const struct tegra_smmu_soc *smmu; 	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;	const struct tegra_mc_regs *regs; 	const irq_handler_t *handle_irq;	unsigned int num_interrupts;	unsigned int mc_addr_hi_mask;	unsigned int mc_err_status_type_mask;	const struct tegra_mc_intmask *intmasks;	unsigned int num_intmasks;}; struct tegra_mc {	struct tegra_bpmp *bpmp;	struct device *dev;	struct tegra_smmu *smmu;	void __iomem *regs;	void __iomem *bcast_ch_regs;	void __iomem **ch_regs;	struct clk *clk; 	const struct tegra_mc_soc *soc;	unsigned long tick; 	struct tegra_mc_timing *timings;	unsigned int num_timings;	unsigned int num_channels; 	bool bwmgr_mrq_supported;	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_MCstruct tegra_mc *devm_tegra_memory_controller_get(struct device *dev);int tegra_mc_probe_device(struct tegra_mc *mc, struct device *dev);int tegra_mc_get_carveout_info(struct tegra_mc *mc, unsigned int id,                               phys_addr_t *base, u64 *size);#elsestatic inline struct tegra_mc *devm_tegra_memory_controller_get(struct device *dev){	return ERR_PTR(-ENODEV);} static inline inttegra_mc_probe_device(struct tegra_mc *mc, struct device *dev){	return -ENODEV;} static inline inttegra_mc_get_carveout_info(struct tegra_mc *mc, unsigned int id,                           phys_addr_t *base, u64 *size){	return -ENODEV;}#endif extern const struct tegra_mc_regs tegra20_mc_regs; #endif /* __SOC_TEGRA_MC_H__ */