mirror of
git://nv-tegra.nvidia.com/linux-nv-oot.git
synced 2025-12-24 02:01:36 +03:00
platform/tegra: Add Tegra Central Activity Monitor driver
Actmon is a hardware block that can be used to track the activity of certain hardware units. It can boost EMC clock depending on the memory traffic among various client. It is called central actmon as it monitors central activity for example MC activity. Add central activity monitor driver. Bug 3625675 Change-Id: I1a5918e7d84bc247f694f53f965c28888b773c91 Signed-off-by: Laxman Dewangan <ldewangan@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/c/linux-nv-oot/+/2705395 GVS: Gerrit_Virtual_Submit
This commit is contained in:
committed by
mobile promotions
parent
d75309658f
commit
527743a5c3
198
include/linux/platform/tegra/actmon_common.h
Normal file
198
include/linux/platform/tegra/actmon_common.h
Normal file
@@ -0,0 +1,198 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
// Copyright (c) 2022, NVIDIA CORPORATION, All rights reserved.
|
||||
|
||||
#ifndef ACTMON_COMMON_H
|
||||
|
||||
#include <linux/io.h>
|
||||
|
||||
/* START: These device register offsets have common value across socs */
|
||||
#define ACTMON_CMN_DEV_CTRL 0x00
|
||||
#define ACTMON_CMN_DEV_CTRL_ENB (0x1 << 31)
|
||||
#define ACTMON_CMN_DEV_CTRL_UP_WMARK_NUM_SHIFT 26
|
||||
#define ACTMON_CMN_DEV_CTRL_UP_WMARK_NUM_MASK (0x7 << 26)
|
||||
#define ACTMON_CMN_DEV_CTRL_DOWN_WMARK_NUM_SHIFT 21
|
||||
#define ACTMON_CMN_DEV_CTRL_DOWN_WMARK_NUM_MASK (0x7 << 21)
|
||||
|
||||
/* Common dev interrupt status bits across socs */
|
||||
#define ACTMON_CMN_DEV_INTR_UP_WMARK (0x1 << 31)
|
||||
#define ACTMON_CMN_DEV_INTR_DOWN_WMARK (0x1 << 30)
|
||||
/* END: common device regs across socs */
|
||||
|
||||
#define ACTMON_DEFAULT_AVG_WINDOW_LOG2 7
|
||||
#define ACTMON_DEFAULT_AVG_BAND 6 /* 1/10 of % */
|
||||
#define ACTMON_DEFAULT_SAMPLING_PERIOD 7
|
||||
|
||||
#define DEFAULT_SUSPEND_FREQ 204000
|
||||
#define DEFAULT_BOOST_UP_COEF 200
|
||||
#define DEFAULT_BOOST_DOWN_COEF 50
|
||||
#define DEFAULT_BOOST_UP_THRESHOLD 30
|
||||
#define DEFAULT_BOOST_DOWN_THRESHOLD 20
|
||||
#define DEFAULT_UP_WMARK_WINDOW 3
|
||||
#define DEFAULT_DOWN_WMARK_WINDOW 2
|
||||
#define DEFAULT_EWMA_COEF_K 6
|
||||
#define DEFAULT_COUNT_WEIGHT 0x53
|
||||
#define FREQ_SAMPLER 1
|
||||
#define LOAD_SAMPLER 0
|
||||
#define DEFAULT_ACTMON_TYPE FREQ_SAMPLER
|
||||
/* Maximum frequency EMC is running at when sourced from PLLP. This is
|
||||
* really a short-cut, but it is true for all Tegra3 platforms
|
||||
*/
|
||||
#define EMC_PLLP_FREQ_MAX 204000
|
||||
|
||||
enum actmon_devices { /* Should match with device sequence in dt */
|
||||
MC_ALL, /* instance 1 */
|
||||
MC_CPU, /* instance 0 */
|
||||
MAX_DEVICES,
|
||||
};
|
||||
|
||||
enum actmon_type {
|
||||
ACTMON_LOAD_SAMPLER,
|
||||
ACTMON_FREQ_SAMPLER,
|
||||
};
|
||||
|
||||
enum actmon_state {
|
||||
ACTMON_UNINITIALIZED = -1,
|
||||
ACTMON_OFF = 0,
|
||||
ACTMON_ON = 1,
|
||||
ACTMON_SUSPENDED = 2,
|
||||
};
|
||||
struct actmon_dev;
|
||||
struct actmon_drv_data;
|
||||
struct dev_reg_ops {
|
||||
void (*set_init_avg)(u32 value, void __iomem *base);
|
||||
void (*set_avg_up_wm)(u32 value, void __iomem *base);
|
||||
void (*set_avg_dn_wm)(u32 value, void __iomem *base);
|
||||
void (*set_dev_up_wm)(u32 value, void __iomem *base);
|
||||
void (*set_dev_dn_wm)(u32 value, void __iomem *base);
|
||||
void (*enb_dev_wm)(u32 *value);
|
||||
void (*disb_dev_up_wm)(u32 *value);
|
||||
void (*disb_dev_dn_wm)(u32 *value);
|
||||
void (*set_intr_st)(u32 value, void __iomem *base);
|
||||
void (*init_dev_cntrl)(struct actmon_dev *dev, void __iomem *base);
|
||||
void (*enb_dev_intr)(u32 value, void __iomem *base);
|
||||
void (*enb_dev_intr_all)(void __iomem *base);
|
||||
void (*set_cnt_wt)(u32 value, void __iomem *base);
|
||||
u32 (*get_intr_st)(void __iomem *base);
|
||||
u32 (*get_dev_intr_enb)(void __iomem *base);
|
||||
u32 (*get_dev_intr)(void __iomem *base);
|
||||
u32 (*get_raw_cnt)(void __iomem *base);
|
||||
u32 (*get_avg_cnt)(void __iomem *base);
|
||||
u32 (*get_cum_cnt)(void __iomem *base);
|
||||
};
|
||||
|
||||
/* Units:
|
||||
* - frequency in kHz
|
||||
* - coefficients, and thresholds in %
|
||||
* - sampling period in ms
|
||||
* - window in sample periods (value = setting + 1)
|
||||
*/
|
||||
struct actmon_dev {
|
||||
struct device_node *dn;
|
||||
u32 reg_offs;
|
||||
u32 glb_status_irq_mask;
|
||||
const char *dev_name;
|
||||
const char *con_id;
|
||||
void *clnt;
|
||||
|
||||
unsigned long max_freq;
|
||||
unsigned long target_freq;
|
||||
unsigned long cur_freq;
|
||||
unsigned long suspend_freq;
|
||||
|
||||
unsigned long avg_actv_freq;
|
||||
unsigned long avg_band_freq;
|
||||
unsigned int avg_sustain_coef;
|
||||
u32 avg_count;
|
||||
u32 avg_dependency_threshold;
|
||||
|
||||
unsigned long boost_freq;
|
||||
unsigned long boost_freq_step;
|
||||
unsigned int boost_up_coef;
|
||||
unsigned int boost_down_coef;
|
||||
unsigned int boost_up_threshold;
|
||||
unsigned int boost_down_threshold;
|
||||
|
||||
u8 up_wmark_window;
|
||||
u8 down_wmark_window;
|
||||
u8 avg_window_log2;
|
||||
u32 count_weight;
|
||||
|
||||
enum actmon_type type;
|
||||
enum actmon_state state;
|
||||
enum actmon_state saved_state;
|
||||
|
||||
bool bwmgr_disable;
|
||||
struct clk *dram_clk_handle;
|
||||
|
||||
struct dev_reg_ops ops;
|
||||
void (*actmon_dev_set_rate)(struct actmon_dev *adev, unsigned long freq);
|
||||
unsigned long (*actmon_dev_get_rate)(struct actmon_dev *adev);
|
||||
unsigned long (*actmon_dev_post_change_rate)(struct actmon_dev *adev,
|
||||
void *v);
|
||||
void (*actmon_dev_clk_enable)(struct actmon_dev *adev);
|
||||
spinlock_t lock;
|
||||
struct notifier_block rate_change_nb;
|
||||
struct kobj_attribute avgact_attr;
|
||||
};
|
||||
|
||||
struct actmon_reg_ops {
|
||||
void (*set_sample_prd)(u32 value, void __iomem *base);
|
||||
void (*set_glb_intr)(u32 value, void __iomem *base);
|
||||
u32 (*get_glb_intr_st)(void __iomem *base);
|
||||
};
|
||||
struct actmon_drv_data {
|
||||
void __iomem *base;
|
||||
struct platform_device *pdev;
|
||||
int virq;
|
||||
struct clk *actmon_clk;
|
||||
u8 sample_period;
|
||||
unsigned long freq;
|
||||
struct reset_control *actmon_rst;
|
||||
struct actmon_dev devices[MAX_DEVICES];
|
||||
int (*actmon_dev_platform_init)(struct actmon_dev *adev,
|
||||
struct platform_device *pdev);
|
||||
int (*clock_init)(struct platform_device *pdev);
|
||||
int (*clock_deinit)(struct platform_device *pdev);
|
||||
int (*reset_init)(struct platform_device *pdev);
|
||||
int (*reset_deinit)(struct platform_device *pdev);
|
||||
void (*dev_free_resource)(struct actmon_dev *adev,
|
||||
struct platform_device *pdev);
|
||||
struct actmon_reg_ops ops;
|
||||
#ifdef CONFIG_DEBUG_FS
|
||||
struct dentry *dfs_root;
|
||||
#endif
|
||||
struct kobject *actmon_kobj;
|
||||
};
|
||||
|
||||
static inline void actmon_wmb(void)
|
||||
{
|
||||
dsb(sy);
|
||||
}
|
||||
|
||||
static inline u32 actmon_dev_readl(void __iomem *base,
|
||||
u32 offset)
|
||||
{
|
||||
return __raw_readl(base + offset);
|
||||
}
|
||||
|
||||
static inline void actmon_dev_writel(void __iomem *base, u32
|
||||
offset, u32 val)
|
||||
{
|
||||
__raw_writel(val, base + offset);
|
||||
}
|
||||
|
||||
#if defined(CONFIG_TEGRA_CENTRAL_ACTMON)
|
||||
int tegra_actmon_register(struct actmon_drv_data *actmon);
|
||||
int tegra_actmon_remove(struct platform_device *pdev);
|
||||
#else
|
||||
static inline int tegra_actmon_register(struct actmon_drv_data *actmon)
|
||||
{
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static inline int tegra_actmon_remove(struct platform_device *pdev)
|
||||
{
|
||||
return -EINVAL;
|
||||
}
|
||||
#endif
|
||||
#endif /* ACTMON_COMMON_H */
|
||||
381
include/linux/platform/tegra/emc_bwmgr.h
Normal file
381
include/linux/platform/tegra/emc_bwmgr.h
Normal file
@@ -0,0 +1,381 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
// Copyright (c) 2022, NVIDIA CORPORATION, All rights reserved.
|
||||
|
||||
#ifndef __EMC_BWMGR_H
|
||||
#define __EMC_BWMGR_H
|
||||
|
||||
#include <linux/clk.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/of_address.h>
|
||||
#include <linux/platform/tegra/iso_client.h>
|
||||
#include <soc/tegra/bpmp-abi.h>
|
||||
|
||||
/* keep in sync with tegra_bwmgr_client_names */
|
||||
enum tegra_bwmgr_client_id {
|
||||
TEGRA_BWMGR_CLIENT_CPU_CLUSTER_0,
|
||||
TEGRA_BWMGR_CLIENT_CPU_CLUSTER_1,
|
||||
TEGRA_BWMGR_CLIENT_CPU_CLUSTER_2,
|
||||
TEGRA_BWMGR_CLIENT_CPU_CLUSTER_3,
|
||||
TEGRA_BWMGR_CLIENT_DISP0,
|
||||
TEGRA_BWMGR_CLIENT_DISP1,
|
||||
TEGRA_BWMGR_CLIENT_DISP2,
|
||||
TEGRA_BWMGR_CLIENT_DISP1_LA_EMC,
|
||||
TEGRA_BWMGR_CLIENT_DISP2_LA_EMC,
|
||||
TEGRA_BWMGR_CLIENT_USBD,
|
||||
TEGRA_BWMGR_CLIENT_XHCI,
|
||||
TEGRA_BWMGR_CLIENT_SDMMC1,
|
||||
TEGRA_BWMGR_CLIENT_SDMMC2,
|
||||
TEGRA_BWMGR_CLIENT_SDMMC3,
|
||||
TEGRA_BWMGR_CLIENT_SDMMC4,
|
||||
TEGRA_BWMGR_CLIENT_MON,
|
||||
TEGRA_BWMGR_CLIENT_GPU,
|
||||
TEGRA_BWMGR_CLIENT_MSENC,
|
||||
TEGRA_BWMGR_CLIENT_NVENC1,
|
||||
TEGRA_BWMGR_CLIENT_NVJPG,
|
||||
TEGRA_BWMGR_CLIENT_NVDEC,
|
||||
TEGRA_BWMGR_CLIENT_NVDEC1,
|
||||
TEGRA_BWMGR_CLIENT_TSEC,
|
||||
TEGRA_BWMGR_CLIENT_TSECB,
|
||||
TEGRA_BWMGR_CLIENT_VI,
|
||||
TEGRA_BWMGR_CLIENT_ISPA,
|
||||
TEGRA_BWMGR_CLIENT_ISPB,
|
||||
TEGRA_BWMGR_CLIENT_CAMERA,
|
||||
TEGRA_BWMGR_CLIENT_CAMERA_NON_ISO,
|
||||
TEGRA_BWMGR_CLIENT_CAMRTC,
|
||||
TEGRA_BWMGR_CLIENT_ISOMGR,
|
||||
TEGRA_BWMGR_CLIENT_THERMAL_CAP,
|
||||
TEGRA_BWMGR_CLIENT_VIC,
|
||||
TEGRA_BWMGR_CLIENT_APE_ADSP,
|
||||
TEGRA_BWMGR_CLIENT_APE_ADMA,
|
||||
TEGRA_BWMGR_CLIENT_PCIE,
|
||||
TEGRA_BWMGR_CLIENT_PCIE_1,
|
||||
TEGRA_BWMGR_CLIENT_PCIE_2,
|
||||
TEGRA_BWMGR_CLIENT_PCIE_3,
|
||||
TEGRA_BWMGR_CLIENT_PCIE_4,
|
||||
TEGRA_BWMGR_CLIENT_PCIE_5,
|
||||
TEGRA_BWMGR_CLIENT_BBC_0,
|
||||
TEGRA_BWMGR_CLIENT_EQOS,
|
||||
TEGRA_BWMGR_CLIENT_SE0,
|
||||
TEGRA_BWMGR_CLIENT_SE1,
|
||||
TEGRA_BWMGR_CLIENT_SE2,
|
||||
TEGRA_BWMGR_CLIENT_SE3,
|
||||
TEGRA_BWMGR_CLIENT_SE4,
|
||||
TEGRA_BWMGR_CLIENT_NVPMODEL,
|
||||
TEGRA_BWMGR_CLIENT_DEBUG,
|
||||
TEGRA_BWMGR_CLIENT_DLA0,
|
||||
TEGRA_BWMGR_CLIENT_DLA1,
|
||||
TEGRA_BWMGR_CLIENT_COUNT /* Should always be last */
|
||||
};
|
||||
|
||||
enum tegra_bwmgr_request_type {
|
||||
TEGRA_BWMGR_SET_EMC_FLOOR, /* lower bound */
|
||||
TEGRA_BWMGR_SET_EMC_CAP, /* upper bound */
|
||||
TEGRA_BWMGR_SET_EMC_ISO_CAP, /* upper bound that affects ISO Bw */
|
||||
TEGRA_BWMGR_SET_EMC_SHARED_BW, /* shared bw request */
|
||||
TEGRA_BWMGR_SET_EMC_SHARED_BW_ISO, /* for use by ISO Mgr only */
|
||||
TEGRA_BWMGR_SET_EMC_REQ_COUNT /* Should always be last */
|
||||
};
|
||||
|
||||
enum bwmgr_dram_types {
|
||||
DRAM_TYPE_NONE,
|
||||
DRAM_TYPE_LPDDR4_16CH_ECC,
|
||||
DRAM_TYPE_LPDDR4_8CH_ECC,
|
||||
DRAM_TYPE_LPDDR4_4CH_ECC,
|
||||
DRAM_TYPE_LPDDR4_2CH_ECC,
|
||||
DRAM_TYPE_LPDDR4_16CH,
|
||||
DRAM_TYPE_LPDDR4_8CH,
|
||||
DRAM_TYPE_LPDDR4_4CH,
|
||||
DRAM_TYPE_LPDDR4_2CH,
|
||||
DRAM_TYPE_LPDDR3_2CH,
|
||||
DRAM_TYPE_DDR3_2CH
|
||||
};
|
||||
|
||||
extern u8 bwmgr_dram_efficiency;
|
||||
extern u8 bwmgr_dram_num_channels;
|
||||
/* flag to determine supported memory and channel configuration */
|
||||
extern u8 bwmgr_dram_config_supported;
|
||||
extern u32 *bwmgr_dram_iso_eff_table;
|
||||
extern u32 *bwmgr_dram_noniso_eff_table;
|
||||
extern u32 *bwmgr_max_nvdis_bw_reqd;
|
||||
extern u32 *bwmgr_max_vi_bw_reqd;
|
||||
extern int *bwmgr_slope;
|
||||
extern u32 *bwmgr_vi_bw_reqd_offset;
|
||||
extern int bwmgr_iso_bw_percentage;
|
||||
extern enum bwmgr_dram_types bwmgr_dram_type;
|
||||
extern int emc_to_dram_freq_factor;
|
||||
extern struct mrq_emc_dvfs_latency_response bwmgr_emc_dvfs;
|
||||
|
||||
struct tegra_bwmgr_client;
|
||||
|
||||
struct bwmgr_ops {
|
||||
unsigned long (*freq_to_bw)(unsigned long freq);
|
||||
unsigned long (*bw_to_freq)(unsigned long bw);
|
||||
u32 (*dvfs_latency)(u32 ufreq);
|
||||
unsigned long (*bwmgr_apply_efficiency)(
|
||||
unsigned long total_bw, unsigned long iso_bw,
|
||||
unsigned long max_rate, u64 usage_flags,
|
||||
unsigned long *iso_bw_min, unsigned long iso_bw_nvdis,
|
||||
unsigned long iso_bw_vi);
|
||||
unsigned long (*get_best_iso_freq)(long iso_bw,
|
||||
long iso_bw_nvdis, long iso_bw_vi);
|
||||
void (*update_efficiency)(unsigned long dram_refresh_rate);
|
||||
u32 (*get_max_iso_bw)(enum tegra_iso_client client);
|
||||
};
|
||||
|
||||
struct bwmgr_ops *bwmgr_eff_init_t21x(void);
|
||||
struct bwmgr_ops *bwmgr_eff_init_t18x(void);
|
||||
struct bwmgr_ops *bwmgr_eff_init_t19x(void);
|
||||
|
||||
#if defined(CONFIG_TEGRA_BWMGR)
|
||||
/**
|
||||
* tegra_bwmgr_register - register an EMC Bandwidth Manager client.
|
||||
* Also see tegra_bwmgr_unregister().
|
||||
* @client client id from tegra_bwmgr_client_id
|
||||
*
|
||||
* Returns a valid handle on successful registration, NULL on error.
|
||||
*/
|
||||
struct tegra_bwmgr_client *tegra_bwmgr_register(
|
||||
enum tegra_bwmgr_client_id client);
|
||||
|
||||
/**
|
||||
* tegra_bwmgr_unregister - unregister an EMC Bandwidth Manager client.
|
||||
* Callers should match register/unregister calls.
|
||||
* Persistence of old requests across
|
||||
* register/unregister calls is undefined.
|
||||
* Also see tegra_bwmgr_set_emc()
|
||||
*
|
||||
* @handle handle acquired during tegra_bwmgr_register
|
||||
*/
|
||||
void tegra_bwmgr_unregister(struct tegra_bwmgr_client *handle);
|
||||
|
||||
/**
|
||||
* tegra_bwmgr_get_dram_num_channels - get the number of DRAM channels
|
||||
*
|
||||
* Returns the number of DRAM channels that are configured on the underlying
|
||||
* platform.
|
||||
*/
|
||||
u8 tegra_bwmgr_get_dram_num_channels(void);
|
||||
|
||||
/**
|
||||
* tegra_bwmgr_get_emc_rate - get the current EMC rate.
|
||||
*
|
||||
* Returns current memory clock rate in Hz.
|
||||
*/
|
||||
unsigned long tegra_bwmgr_get_emc_rate(void);
|
||||
|
||||
/**
|
||||
* tegra_bwmgr_get_max_emc_rate - get the max EMC rate.
|
||||
*
|
||||
* Returns the max memory clock rate in Hz.
|
||||
*/
|
||||
unsigned long tegra_bwmgr_get_max_emc_rate(void);
|
||||
|
||||
/**
|
||||
* tegra_bwmgr_get_core_emc_rate - get the actual emc frequency calculated
|
||||
* using the dram frequency and emc_to_dram
|
||||
* conversion factor.
|
||||
*
|
||||
* Returns the core emc rate in Hz.
|
||||
*/
|
||||
unsigned long tegra_bwmgr_get_core_emc_rate(void);
|
||||
|
||||
/**
|
||||
* tegra_bwmgr_round_rate - round up to next EMC rate which can be provided
|
||||
*
|
||||
* @bw Input rate
|
||||
*
|
||||
* Returns the next higher rate from the Input rate that EMC can run at.
|
||||
*/
|
||||
unsigned long tegra_bwmgr_round_rate(unsigned long bw);
|
||||
|
||||
/**
|
||||
* tegra_bwmgr_set_emc - request to bwmgr to set an EMC rate parameter.
|
||||
* Actual clock rate depends on aggregation of
|
||||
* requests by all clients. If needed, use
|
||||
* tegra_bwmgr_get_emc_rate() to get the rate after
|
||||
* a tegra_bwmgr_set_emc() call.
|
||||
*
|
||||
* Call tegra_bwmgr_set_emc() with same request type and
|
||||
* val = 0 to clear request.
|
||||
*
|
||||
* @handle handle acquired during tegra_bwmgr_register
|
||||
* @val value to be set in Hz, 0 to clear old request of the same type
|
||||
* @req chosen type from tegra_bwmgr_request_type
|
||||
*
|
||||
* Returns success (0) or negative errno.
|
||||
*/
|
||||
int tegra_bwmgr_set_emc(struct tegra_bwmgr_client *handle, unsigned long val,
|
||||
enum tegra_bwmgr_request_type req);
|
||||
|
||||
/**
|
||||
* tegra_bwmgr_get_client_info - outputs the value previously set with
|
||||
* tegra_bwmgr_set_emc or 0 if no value has been set.
|
||||
*
|
||||
* @handle handle acquired during tegra_bwmgr_register
|
||||
* @out_val bandwidth value in Hz
|
||||
* @req chosen type from tegra_bwmgr_request_type
|
||||
*
|
||||
* Returns success (0) or negative errno.
|
||||
*/
|
||||
int tegra_bwmgr_get_client_info(struct tegra_bwmgr_client *handle,
|
||||
unsigned long *out_val,
|
||||
enum tegra_bwmgr_request_type req);
|
||||
|
||||
/**
|
||||
* tegra_bwmgr_notifier_register - register a notifier callback when
|
||||
* emc rate changes. Must be called from non-atomic
|
||||
* context. The callback must not call any bwmgr API.
|
||||
* @nb linux notifier block
|
||||
*
|
||||
* Returns success (0) or negative errno.
|
||||
*/
|
||||
int tegra_bwmgr_notifier_register(struct notifier_block *nb);
|
||||
|
||||
/**
|
||||
* tegra_bwmgr_notifier_unregister - unregister a notifier callback.
|
||||
* @nb linux notifier block
|
||||
*
|
||||
* Returns success (0) or negative errno.
|
||||
*/
|
||||
int tegra_bwmgr_notifier_unregister(struct notifier_block *nb);
|
||||
|
||||
/*
|
||||
* Initialize bwmgr.
|
||||
* This api would be called by .init_machine during boot.
|
||||
* bwmgr clients, don't call this api.
|
||||
*/
|
||||
int __init bwmgr_init(void);
|
||||
|
||||
void __exit bwmgr_exit(void);
|
||||
|
||||
#else /* CONFIG_TEGRA_BWMGR */
|
||||
|
||||
static inline struct tegra_bwmgr_client *tegra_bwmgr_register(
|
||||
enum tegra_bwmgr_client_id client_id)
|
||||
{
|
||||
static int i;
|
||||
/* return a dummy handle to allow client to function
|
||||
* as if bwmgr were enabled.
|
||||
*/
|
||||
return (struct tegra_bwmgr_client *) &i;
|
||||
}
|
||||
|
||||
static inline void tegra_bwmgr_unregister(struct tegra_bwmgr_client *handle) {}
|
||||
|
||||
static inline int bwmgr_init(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void bwmgr_exit(void) {}
|
||||
|
||||
static inline u8 tegra_bwmgr_get_dram_num_channels(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline unsigned long tegra_bwmgr_get_emc_rate(void)
|
||||
{
|
||||
static struct clk *bwmgr_emc_clk;
|
||||
struct device_node *dn;
|
||||
|
||||
if (!bwmgr_emc_clk) {
|
||||
dn = of_find_compatible_node(NULL, NULL, "nvidia,bwmgr");
|
||||
if (dn == NULL) {
|
||||
pr_err("bwmgr: dt node not found.\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
bwmgr_emc_clk = of_clk_get(dn, 0);
|
||||
if (IS_ERR_OR_NULL(bwmgr_emc_clk)) {
|
||||
pr_err("bwmgr: couldn't find emc clock.\n");
|
||||
bwmgr_emc_clk = NULL;
|
||||
WARN_ON(true);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return clk_get_rate(bwmgr_emc_clk);
|
||||
}
|
||||
|
||||
static inline unsigned long tegra_bwmgr_get_max_emc_rate(void)
|
||||
{
|
||||
static struct clk *bwmgr_emc_clk;
|
||||
struct device_node *dn;
|
||||
|
||||
if (!bwmgr_emc_clk) {
|
||||
dn = of_find_compatible_node(NULL, NULL, "nvidia,bwmgr");
|
||||
if (dn == NULL) {
|
||||
pr_err("bwmgr: dt node not found.\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
bwmgr_emc_clk = of_clk_get(dn, 0);
|
||||
if (IS_ERR_OR_NULL(bwmgr_emc_clk)) {
|
||||
pr_err("bwmgr: couldn't find emc clock.\n");
|
||||
bwmgr_emc_clk = NULL;
|
||||
WARN_ON(true);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Use LONG_MAX as clk_round_rate treats rate argument as signed */
|
||||
return clk_round_rate(bwmgr_emc_clk, LONG_MAX);
|
||||
}
|
||||
|
||||
static inline unsigned long tegra_bwmgr_get_core_emc_rate(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
static inline unsigned long tegra_bwmgr_round_rate(unsigned long bw)
|
||||
{
|
||||
static struct clk *bwmgr_emc_clk;
|
||||
struct device_node *dn;
|
||||
|
||||
if (!bwmgr_emc_clk) {
|
||||
dn = of_find_compatible_node(NULL, NULL, "nvidia,bwmgr");
|
||||
if (dn == NULL) {
|
||||
pr_err("bwmgr: dt node not found.\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
bwmgr_emc_clk = of_clk_get(dn, 0);
|
||||
if (IS_ERR_OR_NULL(bwmgr_emc_clk)) {
|
||||
pr_err("bwmgr: couldn't find emc clock.\n");
|
||||
bwmgr_emc_clk = NULL;
|
||||
WARN_ON(true);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return clk_round_rate(bwmgr_emc_clk, bw);
|
||||
}
|
||||
|
||||
static inline int tegra_bwmgr_set_emc(struct tegra_bwmgr_client *handle,
|
||||
unsigned long val, enum tegra_bwmgr_request_type req)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int tegra_bwmgr_get_client_info(struct tegra_bwmgr_client *handle,
|
||||
unsigned long *out_val,
|
||||
enum tegra_bwmgr_request_type req)
|
||||
{
|
||||
if (!out_val)
|
||||
return -EINVAL;
|
||||
*out_val = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int tegra_bwmgr_notifier_register(struct notifier_block *nb)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int tegra_bwmgr_notifier_unregister(struct notifier_block *nb)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_TEGRA_BWMGR */
|
||||
#endif /* __EMC_BWMGR_H */
|
||||
22
include/linux/platform/tegra/iso_client.h
Normal file
22
include/linux/platform/tegra/iso_client.h
Normal file
@@ -0,0 +1,22 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
// Copyright (c) 2022, NVIDIA CORPORATION, All rights reserved.
|
||||
|
||||
#ifndef _INCLUDE_MACH_ISO_CLIENT_H
|
||||
#define _INCLUDE_MACH_ISO_CLIENT_H
|
||||
|
||||
enum tegra_iso_client {
|
||||
TEGRA_ISO_CLIENT_DISP_0,
|
||||
TEGRA_ISO_CLIENT_DISP_1,
|
||||
TEGRA_ISO_CLIENT_DISP_2,
|
||||
TEGRA_ISO_CLIENT_VI_0,
|
||||
TEGRA_ISO_CLIENT_VI_1,
|
||||
TEGRA_ISO_CLIENT_ISP_A,
|
||||
TEGRA_ISO_CLIENT_ISP_B,
|
||||
TEGRA_ISO_CLIENT_BBC_0,
|
||||
TEGRA_ISO_CLIENT_TEGRA_CAMERA,
|
||||
TEGRA_ISO_CLIENT_APE_ADMA,
|
||||
TEGRA_ISO_CLIENT_EQOS,
|
||||
TEGRA_ISO_CLIENT_COUNT
|
||||
};
|
||||
|
||||
#endif /* _INCLUDE_MACH_ISO_CLIENT_H */
|
||||
93
include/linux/platform/tegra/mc_utils.h
Normal file
93
include/linux/platform/tegra/mc_utils.h
Normal file
@@ -0,0 +1,93 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
// Copyright (c) 2022, NVIDIA CORPORATION, All rights reserved.
|
||||
|
||||
#ifndef __TEGRA_MC_UTILS_H
|
||||
#define __TEGRA_MC_UTILS_H
|
||||
|
||||
enum dram_types {
|
||||
DRAM_TYPE_INVAL,
|
||||
DRAM_TYPE_LPDDR5_16CH_ECC_1RANK,
|
||||
DRAM_TYPE_LPDDR5_16CH_ECC_2RANK,
|
||||
DRAM_TYPE_LPDDR5_8CH_ECC_1RANK,
|
||||
DRAM_TYPE_LPDDR5_8CH_ECC_2RANK,
|
||||
DRAM_TYPE_LPDDR5_4CH_ECC_1RANK,
|
||||
DRAM_TYPE_LPDDR5_4CH_ECC_2RANK,
|
||||
DRAM_TYPE_LPDDR5_16CH_1RANK,
|
||||
DRAM_TYPE_LPDDR5_16CH_2RANK,
|
||||
DRAM_TYPE_LPDDR5_8CH_1RANK,
|
||||
DRAM_TYPE_LPDDR5_8CH_2RANK,
|
||||
DRAM_TYPE_LPDDR5_4CH_1RANK,
|
||||
DRAM_TYPE_LPDDR5_4CH_2RANK,
|
||||
DRAM_TYPE_LPDDR4_16CH_ECC_1RANK,
|
||||
DRAM_TYPE_LPDDR4_16CH_ECC_2RANK,
|
||||
DRAM_TYPE_LPDDR4_8CH_ECC_1RANK,
|
||||
DRAM_TYPE_LPDDR4_8CH_ECC_2RANK,
|
||||
DRAM_TYPE_LPDDR4_4CH_ECC_1RANK,
|
||||
DRAM_TYPE_LPDDR4_4CH_ECC_2RANK,
|
||||
DRAM_TYPE_LPDDR4_16CH_1RANK,
|
||||
DRAM_TYPE_LPDDR4_16CH_2RANK,
|
||||
DRAM_TYPE_LPDDR4_8CH_1RANK,
|
||||
DRAM_TYPE_LPDDR4_8CH_2RANK,
|
||||
DRAM_TYPE_LPDDR4_4CH_1RANK,
|
||||
DRAM_TYPE_LPDDR4_4CH_2RANK,
|
||||
};
|
||||
|
||||
void tegra_mc_utils_init(void);
|
||||
|
||||
/*
|
||||
* Utility API to convert the given frequency to Bandwidth.
|
||||
*
|
||||
* @freq Frequency to convert. It can be in any unit - the resulting Bandwidth
|
||||
* will be in the same unit as passed. E.g KHz leads to KBps and Hz
|
||||
* leads to Bps.
|
||||
*
|
||||
* Converts EMC clock frequency into theoretical BW. This
|
||||
* does not account for a realistic utilization of the EMC bus. That is the
|
||||
* various overheads (refresh, bank commands, etc) that a real system sees
|
||||
* are not computed.
|
||||
*
|
||||
* Return: Converted Bandwidth.
|
||||
*/
|
||||
unsigned long emc_freq_to_bw(unsigned long freq);
|
||||
|
||||
/*
|
||||
* Utility API to convert the given Bandwidth to frequency.
|
||||
*
|
||||
* @bw Bandwidth to convert. It can be in any unit - the resulting frequency
|
||||
* will be in the same unit as passed. E.g KBps leads to KHz and Bps leads
|
||||
* to Hz.
|
||||
*
|
||||
* Converts BW into theoretical EMC clock frequency.
|
||||
*
|
||||
* Return: Converted Frequency.
|
||||
*/
|
||||
unsigned long emc_bw_to_freq(unsigned long bw);
|
||||
|
||||
/*
|
||||
* Return dram types or dram configuration.
|
||||
*
|
||||
* Return dram configuration based upon ecc/channel/Rank
|
||||
*
|
||||
* Return: dram type.
|
||||
*/
|
||||
enum dram_types tegra_dram_types(void);
|
||||
|
||||
/*
|
||||
* Return Number of channels of dram.
|
||||
*
|
||||
* Return number of dram channels
|
||||
*
|
||||
* Return: dram channels.
|
||||
*/
|
||||
u8 get_dram_num_channels(void);
|
||||
|
||||
/*
|
||||
* Return mc_clk from dram_clk.
|
||||
*
|
||||
* Return DRAM clock in MHZ to MC clk in MHz.
|
||||
*
|
||||
* dram_clk: dram clk in MHz
|
||||
* Return: mc clk in MHz.
|
||||
*/
|
||||
unsigned long dram_clk_to_mc_clk(unsigned long dram_clk);
|
||||
#endif /* __TEGRA_MC_UTILS_H */
|
||||
Reference in New Issue
Block a user