diff --git a/drivers/platform/tegra/Makefile b/drivers/platform/tegra/Makefile index cc7775e7..75d5f0b6 100644 --- a/drivers/platform/tegra/Makefile +++ b/drivers/platform/tegra/Makefile @@ -4,9 +4,6 @@ tegra-bootloader-debug-objs := tegra_bootloader_debug.o obj-m += tegra-bootloader-debug.o -tegra-cactmon-objs := cactmon.o -tegra-cactmon-objs += actmon_common.o -obj-m += tegra-cactmon.o obj-m += tegra-cactmon-mc-all.o obj-m += tegra-fsicom.o diff --git a/drivers/platform/tegra/actmon_common.c b/drivers/platform/tegra/actmon_common.c deleted file mode 100644 index 9e1c3470..00000000 --- a/drivers/platform/tegra/actmon_common.c +++ /dev/null @@ -1,1118 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -// Copyright (c) 2022-2023, NVIDIA CORPORATION, All rights reserved. - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -/* Global definitions */ -static struct actmon_drv_data *actmon; -static struct device *mon_dev; - -#include -static u8 max_dram_channels; -static u8 ch_num; - -#define offs(dev_reg_offs) (actmon->base + dev_reg_offs) - -static inline unsigned long do_percent(unsigned long val, unsigned int pct) -{ - return val * pct / 100; -} - -static inline int actmon_dev_avg_wmark_set( - struct actmon_dev *dev) -{ - u32 band = dev->avg_band_freq * actmon->sample_period; - u32 avg = dev->avg_count; - int ret = -EINVAL; - - if (!dev->ops.set_avg_up_wm) - goto end; - else - dev->ops.set_avg_up_wm(avg + band, offs(dev->reg_offs)); - - avg = max(avg, band); - - if (!dev->ops.set_avg_dn_wm) - goto end; - else - dev->ops.set_avg_dn_wm(avg - band, offs(dev->reg_offs)); - return 0; -end: - return ret; -} - -/* actmon_dev_avg_freq_get should be invoked in spinlock */ -static unsigned long actmon_dev_avg_freq_get( - struct actmon_dev *dev) -{ - u64 val; - - if (dev->ops.get_avg_cnt) - dev->avg_count = dev->ops.get_avg_cnt(offs(dev->reg_offs)); - - if (dev->type == ACTMON_FREQ_SAMPLER) - return dev->avg_count / actmon->sample_period; - - val = (u64)dev->avg_count * dev->cur_freq; - do_div(val, actmon->freq * actmon->sample_period); - return (u32)val; -} - -#ifdef CONFIG_DEBUG_FS -static void actmon_dev_disable(struct actmon_dev *dev) -{ - u32 val; - unsigned long flags; - - spin_lock_irqsave(&dev->lock, flags); - - if (dev->state == ACTMON_ON) { - dev->state = ACTMON_OFF; - disable_irq(actmon->virq); - /* - * To avoid extra interrupt after disabling actmon - * clear interrupt (set intr_status register) - * disable global int_en(GLB_INT_EN_0 register) - * disable actmon (DEV_CTRL_ENB field) - */ - dev->ops.set_intr_st(0xffffffff, offs(dev->reg_offs)); - - if (actmon->ops.set_glb_intr) - actmon->ops.set_glb_intr(0x00, actmon->base); - - val = actmon_dev_readl(offs(dev->reg_offs), - ACTMON_CMN_DEV_CTRL); - val &= ~ACTMON_CMN_DEV_CTRL_ENB; - actmon_dev_writel(offs(dev->reg_offs), ACTMON_CMN_DEV_CTRL, - val); - actmon_wmb(); - } - spin_unlock_irqrestore(&dev->lock, flags); -} -#endif - -static void actmon_dev_enable(struct actmon_dev *dev) -{ - unsigned long flags; - u32 val = 0; - - spin_lock_irqsave(&dev->lock, flags); - - if (dev->state == ACTMON_OFF) { - dev->state = ACTMON_ON; - val = actmon_dev_readl(offs(dev->reg_offs), - ACTMON_CMN_DEV_CTRL); - val |= ACTMON_CMN_DEV_CTRL_ENB; - actmon_dev_writel(offs(dev->reg_offs), ACTMON_CMN_DEV_CTRL, - val); - if (actmon->ops.set_glb_intr) - actmon->ops.set_glb_intr(0xFF, actmon->base); - actmon_wmb(); - - if (dev->actmon_dev_clk_enable) - dev->actmon_dev_clk_enable(dev); - - enable_irq(actmon->virq); - } - - spin_unlock_irqrestore(&dev->lock, flags); -} - -static inline void actmon_dev_up_wmark_set( - struct actmon_dev *dev) -{ - unsigned long freq = (dev->type == ACTMON_FREQ_SAMPLER) ? - dev->cur_freq : actmon->freq; - u32 val; - - val = freq * actmon->sample_period; - dev->ops.set_dev_up_wm(do_percent(val, dev->boost_up_threshold), - offs(dev->reg_offs)); -} - -static inline void actmon_dev_down_wmark_set( - struct actmon_dev *dev) -{ - unsigned long freq = (dev->type == ACTMON_FREQ_SAMPLER) ? - dev->cur_freq : actmon->freq; - u32 val; - - val = freq * actmon->sample_period; - dev->ops.set_dev_dn_wm(do_percent(val, - dev->boost_down_threshold), offs(dev->reg_offs)); -} - -static inline int actmon_dev_wmark_set(struct actmon_dev *dev) -{ - unsigned long freq = (dev->type == ACTMON_FREQ_SAMPLER) ? - dev->cur_freq : actmon->freq; - int ret = -EINVAL; - u32 val; - - val = freq * actmon->sample_period; - - if (!dev->ops.set_dev_up_wm) - goto end; - else - dev->ops.set_dev_up_wm(do_percent(val, dev->boost_up_threshold), - offs(dev->reg_offs)); - - if (!dev->ops.set_dev_dn_wm) - goto end; - else - dev->ops.set_dev_dn_wm(do_percent(val, - dev->boost_down_threshold), offs(dev->reg_offs)); - return 0; - -end: - return ret; -} - -static ssize_t avgactv_show(struct kobject *kobj, - struct kobj_attribute *attr, char *buf) -{ - struct actmon_dev *dev = container_of(attr, struct actmon_dev, - avgact_attr); - unsigned long val = 0; - unsigned long flags; - - spin_lock_irqsave(&dev->lock, flags); - val = actmon_dev_avg_freq_get(dev); - spin_unlock_irqrestore(&dev->lock, flags); - - return scnprintf(buf, PAGE_SIZE, "%lu\n", val); -} - -#ifdef CONFIG_DEBUG_FS - -#define RW_MODE (S_IWUSR | S_IRUGO) -#define RO_MODE S_IRUGO - -static struct dentry *dbgfs_root; - -static int type_show(struct seq_file *s, void *data) -{ - struct actmon_dev *dev = s->private; - - seq_printf(s, "%s\n", (dev->type == ACTMON_LOAD_SAMPLER) ? - "Load Activity Monitor" : "Frequency Activity Monitor"); - return 0; -} -static int type_open(struct inode *inode, struct file *file) -{ - return single_open(file, type_show, inode->i_private); -} -static const struct file_operations type_fops = { - .open = type_open, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, -}; - -static int step_get(void *data, u64 *val) -{ - struct actmon_dev *dev = data; - - *val = dev->boost_freq_step * 100 / dev->max_freq; - return 0; -} -static int step_set(void *data, u64 val) -{ - struct actmon_dev *dev = data; - unsigned long flags; - - if (val > 100) - val = 100; - - spin_lock_irqsave(&dev->lock, flags); - dev->boost_freq_step = do_percent(dev->max_freq, (unsigned int)val); - spin_unlock_irqrestore(&dev->lock, flags); - return 0; -} -DEFINE_SIMPLE_ATTRIBUTE(step_fops, step_get, step_set, - "%llu\n"); - -static int up_threshold_get(void *data, u64 *val) -{ - struct actmon_dev *dev = data; - - *val = dev->boost_up_threshold; - return 0; -} -static int up_threshold_set(void *data, u64 val) -{ - unsigned int up_threshold = (unsigned int)val; - struct actmon_dev *dev = data; - unsigned long flags; - - if (up_threshold > 100) - up_threshold = 100; - - spin_lock_irqsave(&dev->lock, flags); - - if (up_threshold <= dev->boost_down_threshold) - up_threshold = dev->boost_down_threshold; - if (up_threshold) - dev->avg_sustain_coef = 100 * 100 / up_threshold; - dev->boost_up_threshold = up_threshold; - - actmon_dev_up_wmark_set(dev); - actmon_wmb(); - - spin_unlock_irqrestore(&dev->lock, flags); - return 0; -} -DEFINE_SIMPLE_ATTRIBUTE(up_threshold_fops, - up_threshold_get, up_threshold_set, "%llu\n"); - -static int down_threshold_get(void *data, u64 *val) -{ - struct actmon_dev *dev = data; - - *val = dev->boost_down_threshold; - return 0; -} -static int down_threshold_set(void *data, u64 val) -{ - unsigned int down_threshold = (unsigned int)val; - struct actmon_dev *dev = data; - unsigned long flags; - - spin_lock_irqsave(&dev->lock, flags); - - if (down_threshold >= dev->boost_up_threshold) - down_threshold = dev->boost_up_threshold; - dev->boost_down_threshold = down_threshold; - - actmon_dev_down_wmark_set(dev); - actmon_wmb(); - - spin_unlock_irqrestore(&dev->lock, flags); - return 0; -} -DEFINE_SIMPLE_ATTRIBUTE(down_threshold_fops, - down_threshold_get, down_threshold_set, "%llu\n"); - -static int state_get(void *data, u64 *val) -{ - struct actmon_dev *dev = data; - - *val = dev->state; - return 0; -} -static int state_set(void *data, u64 val) -{ - struct actmon_dev *dev = data; - - if (val) - actmon_dev_enable(dev); - else - actmon_dev_disable(dev); - return 0; -} -DEFINE_SIMPLE_ATTRIBUTE(state_fops, state_get, state_set, - "%llu\n"); - -static int period_get(void *data, u64 *val) -{ - *val = actmon->sample_period; - return 0; -} - -static int period_set(void *data, u64 val) -{ - unsigned long flags; - u8 period = (u8)val; - int i; - - if (period) { - actmon->sample_period = period; - actmon->ops.set_sample_prd(period - 1, actmon->base); - - for (i = 0; i < MAX_DEVICES; i++) { - struct actmon_dev *dev = &actmon->devices[i]; - - if (!dev->dn) - continue; - - spin_lock_irqsave(&dev->lock, flags); - actmon_dev_wmark_set(dev); - spin_unlock_irqrestore(&dev->lock, flags); - } - actmon_wmb(); - return 0; - } - return -EINVAL; -} -DEFINE_SIMPLE_ATTRIBUTE(period_fops, period_get, - period_set, "%llu\n"); - -static int up_wmark_get(void *data, u64 *val) -{ - struct actmon_dev *dev = data; - - *val = dev->up_wmark_window; - return 0; -} -static int up_wmark_set(void *data, u64 val) -{ - struct actmon_dev *dev = data; - u8 wmark = (unsigned int)val; - unsigned long flags; - - spin_lock_irqsave(&dev->lock, flags); - - dev->up_wmark_window = wmark; - val = actmon_dev_readl(offs(dev->reg_offs), ACTMON_CMN_DEV_CTRL); - val |= (((dev->up_wmark_window - 1) << - ACTMON_CMN_DEV_CTRL_UP_WMARK_NUM_SHIFT) & - ACTMON_CMN_DEV_CTRL_UP_WMARK_NUM_MASK); - actmon_dev_writel(offs(dev->reg_offs), ACTMON_CMN_DEV_CTRL, val); - actmon_wmb(); - - spin_unlock_irqrestore(&dev->lock, flags); - return 0; -} -DEFINE_SIMPLE_ATTRIBUTE(up_wmark_fops, up_wmark_get, - up_wmark_set, "%llu\n"); - -static int down_wmark_get(void *data, u64 *val) -{ - struct actmon_dev *dev = data; - - *val = dev->down_wmark_window; - return 0; -} -static int down_wmark_set(void *data, u64 val) -{ - struct actmon_dev *dev = data; - u8 wmark = (unsigned int)val; - unsigned long flags; - - spin_lock_irqsave(&dev->lock, flags); - - dev->down_wmark_window = wmark; - val = actmon_dev_readl(offs(dev->reg_offs), ACTMON_CMN_DEV_CTRL); - val |= (((dev->down_wmark_window - 1) << - ACTMON_CMN_DEV_CTRL_DOWN_WMARK_NUM_SHIFT) & - ACTMON_CMN_DEV_CTRL_DOWN_WMARK_NUM_MASK); - actmon_dev_writel(offs(dev->reg_offs), ACTMON_CMN_DEV_CTRL, val); - actmon_wmb(); - - spin_unlock_irqrestore(&dev->lock, flags); - return 0; -} -DEFINE_SIMPLE_ATTRIBUTE(down_wmark_fops, - down_wmark_get, down_wmark_set, "%llu\n"); - -static int actmon_debugfs_create_dev(struct actmon_dev *dev) -{ - struct dentry *dir, *d; - - if (dev->state == ACTMON_UNINITIALIZED) - return 0; - - dir = debugfs_create_dir(dev->dev_name, dbgfs_root); - if (!dir) - return -ENOMEM; - - d = debugfs_create_file( - "actv_type", RO_MODE, dir, dev, &type_fops); - if (!d) - return -ENOMEM; - - d = debugfs_create_file( - "boost_step", RW_MODE, dir, dev, &step_fops); - if (!d) - return -ENOMEM; - - debugfs_create_u32( - "boost_rate_dec", RW_MODE, dir, (u32 *)&dev->boost_down_coef); - - debugfs_create_u32( - "boost_rate_inc", RW_MODE, dir, (u32 *)&dev->boost_up_coef); - - d = debugfs_create_file( - "boost_threshold_dn", RW_MODE, dir, dev, &down_threshold_fops); - if (!d) - return -ENOMEM; - - d = debugfs_create_file( - "boost_threshold_up", RW_MODE, dir, dev, &up_threshold_fops); - if (!d) - return -ENOMEM; - - d = debugfs_create_file( - "state", RW_MODE, dir, dev, &state_fops); - if (!d) - return -ENOMEM; - - d = debugfs_create_file( - "up_wmark", RW_MODE, dir, dev, &up_wmark_fops); - if (!d) - return -ENOMEM; - - d = debugfs_create_file( - "down_wmark", RW_MODE, dir, dev, &down_wmark_fops); - if (!d) - return -ENOMEM; - - return 0; -} - -static int actmon_debugfs_init(void) -{ - int ret = -ENOMEM; - struct dentry *d = NULL; - int i; - - dbgfs_root = debugfs_create_dir("tegra_central_actmon", NULL); - if (!dbgfs_root) - return ret; - - d = debugfs_create_file("period", RW_MODE, dbgfs_root, NULL, - &period_fops); - if (!d) - goto err_out; - - for (i = 0; i < MAX_DEVICES; i++) { - if (actmon->devices[i].dn) { - ret = actmon_debugfs_create_dev(&actmon->devices[i]); - if (ret) - goto err_out; - } - } - return 0; - -err_out: - debugfs_remove_recursive(dbgfs_root); - return ret; -} -#endif - -/* Activity monitor sampling operations */ -static irqreturn_t actmon_dev_isr(int irq, void *dev_id) -{ - - struct actmon_dev *dev = (struct actmon_dev *)dev_id; - unsigned long flags; - u32 int_val = 0; - u32 val; - - if (!actmon->ops.get_glb_intr_st) - return IRQ_NONE; - val = actmon->ops.get_glb_intr_st(actmon->base) & - dev->glb_status_irq_mask; - if (!val) - return IRQ_NONE; - - spin_lock_irqsave(&dev->lock, flags); - - if (!dev->ops.get_avg_cnt) { - dev_err(mon_dev, "get_avg_cnt operation is not registered\n"); - return IRQ_NONE; - } - dev->avg_count = dev->ops.get_avg_cnt(offs(dev->reg_offs)); - actmon_dev_avg_wmark_set(dev); - - if (!dev->ops.get_dev_intr_enb) { - dev_err(mon_dev, "get_dev_intr_enb operation is not registered\n"); - return IRQ_NONE; - } - int_val = dev->ops.get_dev_intr_enb(offs(dev->reg_offs)); - - if (!dev->ops.get_intr_st) { - dev_err(mon_dev, "get_intr_st operation is not registered\n"); - return IRQ_NONE; - } - val = dev->ops.get_intr_st(offs(dev->reg_offs)); - - if (val & ACTMON_CMN_DEV_INTR_UP_WMARK) { - dev_dbg(mon_dev, "raw_cnt_up:%u\n", - dev->ops.get_raw_cnt(offs(dev->reg_offs))); - if (!dev->ops.enb_dev_wm) { - dev_err(mon_dev, "enb_dev_wm operation is not registered\n"); - return IRQ_NONE; - } - dev->ops.enb_dev_wm(&int_val); - - dev->boost_freq = dev->boost_freq_step + - do_percent(dev->boost_freq, dev->boost_up_coef); - if (dev->boost_freq >= dev->max_freq) { - dev->boost_freq = dev->max_freq; - if (!dev->ops.disb_dev_up_wm) { - dev_err(mon_dev, - "disb_dev_up_wm operation is not registered\n"); - return IRQ_NONE; - } - dev->ops.disb_dev_up_wm(&int_val); - } - } else if (val & ACTMON_CMN_DEV_INTR_DOWN_WMARK) { - dev_dbg(mon_dev, "raw_cnt_down:%u\n", - dev->ops.get_raw_cnt(offs(dev->reg_offs))); - if (!dev->ops.enb_dev_wm) { - dev_err(mon_dev, "enb_dev_wm operation is not registered\n"); - return IRQ_NONE; - } - dev->ops.enb_dev_wm(&int_val); - - dev->boost_freq = - do_percent(dev->boost_freq, dev->boost_down_coef); - - if (dev->boost_freq == 0) { - if (!dev->ops.disb_dev_dn_wm) { - dev_err(mon_dev, "disb_dev_dn_wm operation is not registered\n"); - return IRQ_NONE; - } - dev->ops.disb_dev_dn_wm(&int_val); - } - } - - if (!dev->ops.enb_dev_intr) { - dev_err(mon_dev, "enb_dev_intr operation is not registered\n"); - return IRQ_NONE; - } - dev->ops.enb_dev_intr(int_val, offs(dev->reg_offs)); - - /* clr all */ - if (!dev->ops.set_intr_st) { - dev_err(mon_dev, "set_intr_st operation is not registered\n"); - return IRQ_NONE; - } - dev->ops.set_intr_st(0xffffffff, offs(dev->reg_offs)); - - actmon_wmb(); - spin_unlock_irqrestore(&dev->lock, flags); - - return IRQ_WAKE_THREAD; -} - -static irqreturn_t actmon_dev_fn(int irq, void *dev_id) -{ - struct actmon_dev *dev = (struct actmon_dev *)dev_id; - unsigned long flags, freq; - - spin_lock_irqsave(&dev->lock, flags); - - if (dev->state != ACTMON_ON) { - spin_unlock_irqrestore(&dev->lock, flags); - return IRQ_HANDLED; - } - - freq = actmon_dev_avg_freq_get(dev); - dev->avg_actv_freq = freq; - freq = do_percent(freq, dev->avg_sustain_coef); - freq += dev->boost_freq; - - dev->target_freq = freq; - - spin_unlock_irqrestore(&dev->lock, flags); - - dev_dbg(mon_dev, "%s(kHz): avg: %lu, boost: %lu, target: %lu, current: %lu\n", - dev->dev_name, dev->avg_actv_freq, dev->boost_freq, dev->target_freq, - dev->cur_freq); - - dev->actmon_dev_set_rate(dev, freq); - - return IRQ_HANDLED; -} - - -/* Activity monitor configuration and control */ -static int actmon_dev_configure(struct actmon_dev *dev, - unsigned long freq) -{ - int ret = -EINVAL; - - dev->cur_freq = freq; - dev->target_freq = freq; - dev->avg_actv_freq = freq; - - if (dev->type == ACTMON_FREQ_SAMPLER) { - dev->avg_count = dev->cur_freq * actmon->sample_period; - dev->avg_band_freq = dev->max_freq * - ACTMON_DEFAULT_AVG_BAND / 1000; - } else { - dev->avg_count = actmon->freq * actmon->sample_period; - dev->avg_band_freq = actmon->freq * - ACTMON_DEFAULT_AVG_BAND / 1000; - } - - if (!dev->ops.set_init_avg) - goto end; - else - dev->ops.set_init_avg(dev->avg_count, offs(dev->reg_offs)); - - BUG_ON(!dev->boost_up_threshold); - - dev->avg_sustain_coef = 100 * 100 / dev->boost_up_threshold; - - if (actmon_dev_avg_wmark_set(dev)) - goto end; - - if (actmon_dev_wmark_set(dev)) - goto end; - - if (!dev->ops.set_cnt_wt) - goto end; - else - dev->ops.set_cnt_wt(dev->count_weight, offs(dev->reg_offs)); - - if (!dev->ops.set_intr_st) - goto end; - else - dev->ops.set_intr_st(0xffffffff, offs(dev->reg_offs)); - - if (!dev->ops.init_dev_cntrl) - goto end; - else - dev->ops.init_dev_cntrl(dev, offs(dev->reg_offs)); - - if (!dev->ops.enb_dev_intr_all) - goto end; - else - dev->ops.enb_dev_intr_all(offs(dev->reg_offs)); - - actmon_wmb(); - return 0; -end: - return ret; -} - -static int actmon_rate_notify_cb( - struct notifier_block *nb, unsigned long rate, void *v) -{ - unsigned long flags; - struct actmon_dev *dev = container_of( - nb, struct actmon_dev, rate_change_nb); - - spin_lock_irqsave(&dev->lock, flags); - - if (dev->actmon_dev_post_change_rate) - dev->cur_freq = dev->actmon_dev_post_change_rate(dev, v) / - 1000; - else - dev->cur_freq = rate / 1000; - - dev_dbg(mon_dev, "rate:%lu\n", dev->cur_freq); - - if (dev->type == ACTMON_FREQ_SAMPLER) { - actmon_dev_wmark_set(dev); - actmon_wmb(); - } - - spin_unlock_irqrestore(&dev->lock, flags); - return NOTIFY_OK; -}; - -static int actmon_dev_parse_dt(struct actmon_dev *dev, - struct platform_device *pdev) -{ - int ret = 0; - const void *prop; - - if (dev->bwmgr_disable) { - dev->dram_clk_handle = of_clk_get_by_name(dev->dn, "emc"); - if (IS_ERR_OR_NULL(dev->dram_clk_handle)) { - dev_err(mon_dev, "couldn't find emc clock\n"); - dev->dram_clk_handle = NULL; - } - } - - ret = of_property_read_u32(dev->dn, "nvidia,reg_offs", &dev->reg_offs); - if (ret) { - dev_err(mon_dev, " property is not provided for the device %s\n", - dev->dn->name); - ret = -EINVAL; - goto err_out; - } - - ret = of_property_read_u32(dev->dn, "nvidia,irq_mask", - &dev->glb_status_irq_mask); - if (ret) { - dev_err(mon_dev, " property is not provided for the device %s\n", - dev->dn->name); - ret = -EINVAL; - goto err_out; - } - - prop = of_get_property(dev->dn, "nvidia,suspend_freq", NULL); - if (prop) - dev->suspend_freq = of_read_ulong(prop, 1); - else { - dev->suspend_freq = DEFAULT_SUSPEND_FREQ; - dev_info(mon_dev, " property is not provided by the device %s setting up default value:%lu\n", - dev->dn->name, dev->suspend_freq); - } - - prop = of_get_property(dev->dn, "nvidia,boost_freq_step", NULL); - if (prop) - dev->boost_freq_step = of_read_ulong(prop, 1); - else { - dev->boost_freq_step = EMC_PLLP_FREQ_MAX; - dev_info(mon_dev, " property is not provided for the device %s setting up default value:%lu\n", - dev->dn->name, dev->boost_freq_step); - } - - ret = of_property_read_u32(dev->dn, "nvidia,boost_up_coef", - &dev->boost_up_coef); - if (ret) { - dev->boost_up_coef = DEFAULT_BOOST_UP_COEF; - dev_info(mon_dev, " property is not provided for the device %s setting up default value:%u\n", - dev->dn->name, dev->boost_up_coef); - } - - ret = of_property_read_u32(dev->dn, "nvidia,boost_down_coef", - &dev->boost_down_coef); - if (ret) { - dev->boost_down_coef = DEFAULT_BOOST_DOWN_COEF; - dev_info(mon_dev, " property is not provided for the device %s setting up default value:%u\n", - dev->dn->name, dev->boost_down_coef); - } - - ret = of_property_read_u32(dev->dn, "nvidia,boost_up_threshold", - &dev->boost_up_threshold); - if (ret) { - dev->boost_up_threshold = DEFAULT_BOOST_UP_THRESHOLD; - dev_info(mon_dev, " property is not provided for the device %s setting up default value:%u\n", - dev->dn->name, dev->boost_up_threshold); - } - - ret = of_property_read_u32(dev->dn, "nvidia,boost_down_threshold", - &dev->boost_down_threshold); - if (ret) { - dev->boost_down_threshold = DEFAULT_BOOST_DOWN_THRESHOLD; - dev_info(mon_dev, " property is not provided for the device %s setting up default value:%u\n", - dev->dn->name, dev->boost_down_threshold); - } - - ret = of_property_read_u8(dev->dn, "nvidia,up_wmark_window", - &dev->up_wmark_window); - if (ret) { - dev->up_wmark_window = DEFAULT_UP_WMARK_WINDOW; - dev_info(mon_dev, " property is not provided for the device %s setting up default value:%u\n", - dev->dn->name, dev->up_wmark_window); - } - - ret = of_property_read_u8(dev->dn, "nvidia,down_wmark_window", - &dev->down_wmark_window); - if (ret) { - dev->down_wmark_window = DEFAULT_DOWN_WMARK_WINDOW; - dev_info(mon_dev, " property is not provided for the device %s setting up default value:%u\n", - dev->dn->name, dev->down_wmark_window); - } - - ret = of_property_read_u8(dev->dn, "nvidia,avg_window_log2", - &dev->avg_window_log2); - if (ret) { - dev->avg_window_log2 = DEFAULT_EWMA_COEF_K; - dev_info(mon_dev, " property is not provided for the device %s setting up default value:%u\n", - dev->dn->name, dev->avg_window_log2); - } - - ret = of_property_read_u32(dev->dn, "nvidia,count_weight", - &dev->count_weight); - if (ret) { - dev->count_weight = DEFAULT_COUNT_WEIGHT; - dev_info(mon_dev, " property is not provided for the device %s setting up default value:%u\n", - dev->dn->name, dev->count_weight); - } - - ret = of_property_read_u8(dev->dn, "nvidia,max_dram_channels", - &max_dram_channels); - if (ret) { - dev_info(mon_dev, " property is not provided for the device %s\n",dev->dn->name); - } - -#if IS_ENABLED(CONFIG_ARCH_TEGRA_23x_SOC) - ch_num = get_dram_num_channels(); -#else - ch_num = tegra_bwmgr_get_dram_num_channels(); -#endif - - if (ch_num && max_dram_channels) - dev->count_weight *= (u32)(max_dram_channels / ch_num); - - ret = of_property_read_u32(dev->dn, "nvidia,type", - &dev->type); - if (ret) { - dev->type = DEFAULT_ACTMON_TYPE; - dev_info(mon_dev, " property is not provided for the device %s setting up default value:%u\n", - dev->dn->name, dev->type); - } - return 0; - -err_out: - return ret; -} - -static int actmon_dev_init(struct actmon_dev *dev, - struct platform_device *pdev) -{ - unsigned long freq; - int t234_compat; - int ret = 0; - - t234_compat = of_device_is_compatible(pdev->dev.of_node , "nvidia,tegra234-cactmon"); - - spin_lock_init(&dev->lock); - - dev->bwmgr_disable = !!(t234_compat); - - dev_info(&pdev->dev, "bwmgr_disable = %d\n", dev->bwmgr_disable); - - ret = actmon_dev_parse_dt(dev, pdev); - if (ret) { - dev_err(mon_dev, "nvidia, type property is not provided for the device %s\n", - dev->dn->name); - ret = -EINVAL; - goto err_out; - } - dev->state = ACTMON_UNINITIALIZED; - - /* By default register rate change notifier */ - dev->rate_change_nb.notifier_call = actmon_rate_notify_cb; - - ret = actmon->actmon_dev_platform_init(dev, pdev); - if (ret) { - dev_err(mon_dev, "actmon device %s platform initialization failed\n", - dev->dn->name); - ret = -EINVAL; - goto err_out; - } - - freq = dev->actmon_dev_get_rate(dev) / 1000; - - ret = actmon_dev_configure(dev, freq); - if (ret) { - dev_err(mon_dev, "Failed %s configuration\n", - dev_name(&pdev->dev)); - return ret; - } - - ret = devm_request_threaded_irq(&pdev->dev, - actmon->virq, actmon_dev_isr, actmon_dev_fn, - IRQ_TYPE_LEVEL_HIGH | IRQF_SHARED, - dev_name(&pdev->dev), dev); - if (ret) { - dev_err(mon_dev, "Failed irq %d request for.%s\n", - actmon->virq, dev_name(&pdev->dev)); - goto err_out; - } - - disable_irq(actmon->virq); - dev->state = ACTMON_OFF; - actmon_dev_enable(dev); - return 0; - -err_out: - if (actmon->dev_free_resource) - actmon->dev_free_resource(dev, pdev); - - return ret; -} - -static int actmon_clock_disable(struct platform_device *pdev) -{ - if (actmon->clock_deinit) - return actmon->clock_deinit(pdev); - else - return -EINVAL; -} - -static int actmon_clock_enable(struct platform_device *pdev) -{ - int ret = -EINVAL; - - if (actmon->clock_init) - ret = actmon->clock_init(pdev); - - return ret; -} -static int actmon_map_resource(struct platform_device *pdev) -{ - struct resource *res = NULL; - int ret = 0; - - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!res) { - dev_err(mon_dev, "Failed to get resource for actmon device\n"); - return -EINVAL; - } - - actmon->base = devm_ioremap_resource(mon_dev, res); - if (IS_ERR(actmon->base)) { - dev_err(mon_dev, "Failed to iomap resource reg 0 %d:\n", ret); - return PTR_ERR(actmon->base); - } - - res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); - if (!res) { - dev_err(mon_dev, "Failed to get virtual irq for actmon interrupt\n"); - if (actmon->base) - devm_iounmap(mon_dev, actmon->base); - return -EINVAL; - } - actmon->virq = res->start; - return 0; -} - -static inline int actmon_reset_init(struct platform_device *pdev) -{ - int ret = -EINVAL; - - if (actmon->reset_init) - ret = actmon->reset_init(pdev); - - return ret; -} -static int actmon_set_sample_prd(struct platform_device *pdev) -{ - int ret = 0; - - ret = of_property_read_u8(mon_dev->of_node, "nvidia,sample_period", - &actmon->sample_period); - if (ret) { - actmon->sample_period = ACTMON_DEFAULT_SAMPLING_PERIOD; - dev_err(mon_dev, " property is not provided for the device %s setting up default value:%u\n", - mon_dev->of_node->name, actmon->sample_period); - ret = 0; - } - - if (!actmon->ops.set_sample_prd) - ret = -EINVAL; - else - actmon->ops.set_sample_prd(actmon->sample_period - 1, - actmon->base); - - return ret; -} -static int actmon_reset_deinit(struct platform_device *pdev) -{ - int ret = -EINVAL; - - if (actmon->reset_deinit) - ret = actmon->reset_deinit(pdev); - - return ret; -} - -int tegra_actmon_register(struct actmon_drv_data *actmon_data) -{ - struct device_node *dn = NULL; - struct platform_device *pdev; - int ret = 0; - u32 i; - - actmon = actmon_data; - pdev = actmon->pdev; - mon_dev = &pdev->dev; - dev_info(mon_dev, "in actmon_register()...\n"); - - ret = actmon_map_resource(pdev); - if (ret) - return ret; - - ret = actmon_clock_enable(pdev); - if (ret) - return ret; - - ret = actmon_reset_init(pdev); - if (ret) - goto err_reset; - - ret = actmon_set_sample_prd(pdev); - if (ret) - goto err_sample; - - if (actmon->ops.set_glb_intr) - actmon->ops.set_glb_intr(0xff, actmon->base); - - actmon->actmon_kobj = kobject_create_and_add("actmon_avg_activity", - kernel_kobj); - if (!actmon->actmon_kobj) - dev_err(mon_dev, "Couldn't create avg_actv kobj\n"); - - for (i = 0; i < MAX_DEVICES; i++) { - dn = of_get_next_available_child(pdev->dev.of_node, dn); - if (!dn) - break; - actmon->devices[i].dn = dn; - /* Initialize actmon devices */ - ret = actmon_dev_init(&actmon->devices[i], pdev); - dev_info(mon_dev, "initialization %s for the device %s\n", - ret ? "Failed" : "Completed", dn->name); - if (ret) - goto err_reset; - - sysfs_attr_init(&actmon->devices[i].avgact_attr.attr); - actmon->devices[i].avgact_attr.attr.name = dn->name; - actmon->devices[i].avgact_attr.attr.mode = S_IRUGO; - actmon->devices[i].avgact_attr.show = avgactv_show; - - ret = sysfs_create_file(actmon->actmon_kobj, - &actmon->devices[i].avgact_attr.attr); - if (ret) - dev_err(mon_dev, "Couldn't create avg_actv files\n"); - } - -#ifdef CONFIG_DEBUG_FS - if (debugfs_initialized()) - ret = actmon_debugfs_init(); -#endif - if (ret == 0) - return 0; - - for (i = 0; i < MAX_DEVICES; i++) { - if (actmon->devices[i].dn) - sysfs_remove_file(actmon->actmon_kobj, - &actmon->devices[i].avgact_attr.attr); - actmon->dev_free_resource(&actmon->devices[i], pdev); - } -err_reset: - actmon_reset_deinit(pdev); -err_sample: - actmon_clock_disable(pdev); - - return ret; -} -EXPORT_SYMBOL_GPL(tegra_actmon_register); - -int tegra_actmon_remove(struct platform_device *pdev) -{ - int i; - -#ifdef CONFIG_DEBUG_FS - debugfs_remove_recursive(dbgfs_root); -#endif - - for (i = 0; i < MAX_DEVICES; i++) { - if (actmon->devices[i].dn) - sysfs_remove_file(actmon->actmon_kobj, - &actmon->devices[i].avgact_attr.attr); - actmon->dev_free_resource(&actmon->devices[i], pdev); - } - - actmon_reset_deinit(pdev); - actmon_clock_disable(pdev); - - return 0; -} -EXPORT_SYMBOL_GPL(tegra_actmon_remove); - diff --git a/drivers/platform/tegra/cactmon.c b/drivers/platform/tegra/cactmon.c deleted file mode 100644 index c4cd32c2..00000000 --- a/drivers/platform/tegra/cactmon.c +++ /dev/null @@ -1,580 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -// Copyright (c) 2022, NVIDIA CORPORATION, All rights reserved. - -#include -#include -#include -#if IS_ENABLED(CONFIG_INTERCONNECT) -#include -#include -#endif -#include -#include - -#include - -/************ START OF REG DEFINITION **************/ -/* Actmon common registers */ -#define ACTMON_GLB_CTRL 0x00 -#define ACTMON_GLB_INT_EN 0x04 -#define ACTMON_GLB_INT_STATUS 0x08 - -/* Actmon device registers */ -/* ACTMON_*_CTRL_0 offset */ -#define ACTMON_DEV_CTRL 0x00 -/* ACTMON_*_CTRL_0 bit definitions */ -#define ACTMON_DEV_CTRL_UP_WMARK_NUM_SHIFT 26 -#define ACTMON_DEV_CTRL_UP_WMARK_NUM_MASK (0x7 << 26) -#define ACTMON_DEV_CTRL_DOWN_WMARK_NUM_SHIFT 21 -#define ACTMON_DEV_CTRL_DOWN_WMARK_NUM_MASK (0x7 << 21) -#define ACTMON_DEV_CTRL_PERIODIC_ENB (0x1 << 13) -#define ACTMON_DEV_CTRL_K_VAL_SHIFT 10 -#define ACTMON_DEV_CTRL_K_VAL_MASK (0x7 << 10) - -/* ACTMON_*_INTR_ENABLE_0 */ -#define ACTMON_DEV_INTR_ENB 0x04 -/* ACTMON_*_INTR_ENABLE_0 bit definitions */ -#define ACTMON_DEV_INTR_UP_WMARK_ENB (0x1 << 31) -#define ACTMON_DEV_INTR_DOWN_WMARK_ENB (0x1 << 30) -#define ACTMON_DEV_INTR_AVG_UP_WMARK_ENB (0x1 << 29) -#define ACTMON_DEV_INTR_AVG_DOWN_WMARK_ENB (0x1 << 28) - -/* ACTMON_*_INTR_STAUS_0 */ -#define ACTMON_DEV_INTR_STATUS 0x08 -/* ACTMON_*_UPPER_WMARK_0 */ -#define ACTMON_DEV_UP_WMARK 0x0c -/* ACTMON_*_LOWER_WMARK_0 */ -#define ACTMON_DEV_DOWN_WMARK 0x10 -/* ACTMON_*_AVG_UPPER_WMARK_0 */ -#define ACTMON_DEV_AVG_UP_WMARK 0x14 -/* ACTMON_*_AVG_LOWER_WMARK_0 */ -#define ACTMON_DEV_AVG_DOWN_WMARK 0x18 -/* ACTMON_*_AVG_INIT_AVG_0 */ -#define ACTMON_DEV_INIT_AVG 0x1c -/* ACTMON_*_COUNT_0 */ -#define ACTMON_DEV_COUNT 0x20 -/* ACTMON_*_AVG_COUNT_0 */ -#define ACTMON_DEV_AVG_COUNT 0x24 -/* ACTMON_*_AVG_COUNT_WEIGHT_0 */ -#define ACTMON_DEV_COUNT_WEGHT 0x28 -/* ACTMON_*_CUMULATIVE_COUNT_0 */ -#define ACTMON_DEV_CUMULATIVE_COUNT 0x2c -/************ END OF REG DEFINITION **************/ - -/******** start of actmon register operations **********/ -static void set_prd(u32 val, void __iomem *base) -{ - __raw_writel(val, base + ACTMON_GLB_CTRL); -} - -static void set_glb_intr(u32 val, void __iomem *base) -{ - __raw_writel(val, base + ACTMON_GLB_INT_EN); -} - -static u32 get_glb_intr_st(void __iomem *base) -{ - return __raw_readl(base + ACTMON_GLB_INT_STATUS); -} -/******** end of actmon register operations **********/ - -/*********start of actmon device register operations***********/ -static void set_init_avg(u32 val, void __iomem *base) -{ - __raw_writel(val, base + ACTMON_DEV_INIT_AVG); -} - -static void set_avg_up_wm(u32 val, void __iomem *base) -{ - __raw_writel(val, base + ACTMON_DEV_AVG_UP_WMARK); -} - -static void set_avg_dn_wm(u32 val, void __iomem *base) -{ - __raw_writel(val, base + ACTMON_DEV_AVG_DOWN_WMARK); -} - -static void set_dev_up_wm(u32 val, void __iomem *base) -{ - __raw_writel(val, base + ACTMON_DEV_UP_WMARK); -} - -static void set_dev_dn_wm(u32 val, void __iomem *base) -{ - __raw_writel(val, base + ACTMON_DEV_DOWN_WMARK); -} - -static void set_cnt_wt(u32 val, void __iomem *base) -{ - __raw_writel(val, base + ACTMON_DEV_COUNT_WEGHT); -} - -static void set_intr_st(u32 val, void __iomem *base) -{ - __raw_writel(val, base + ACTMON_DEV_INTR_STATUS); -} - -static u32 get_intr_st(void __iomem *base) -{ - return __raw_readl(base + ACTMON_DEV_INTR_STATUS); -} - -static void init_dev_cntrl(struct actmon_dev *dev, void __iomem *base) -{ - u32 val = 0; - - val |= ACTMON_DEV_CTRL_PERIODIC_ENB; - val |= (((dev->avg_window_log2 - 1) << ACTMON_DEV_CTRL_K_VAL_SHIFT) - & ACTMON_DEV_CTRL_K_VAL_MASK); - val |= (((dev->down_wmark_window - 1) << - ACTMON_DEV_CTRL_DOWN_WMARK_NUM_SHIFT) & - ACTMON_DEV_CTRL_DOWN_WMARK_NUM_MASK); - val |= (((dev->up_wmark_window - 1) << - ACTMON_DEV_CTRL_UP_WMARK_NUM_SHIFT) & - ACTMON_DEV_CTRL_UP_WMARK_NUM_MASK); - - __raw_writel(val, base + ACTMON_DEV_CTRL); -} - -static void enb_dev_intr_all(void __iomem *base) -{ - u32 val = 0; - - val |= (ACTMON_DEV_INTR_UP_WMARK_ENB | - ACTMON_DEV_INTR_DOWN_WMARK_ENB | - ACTMON_DEV_INTR_AVG_UP_WMARK_ENB | - ACTMON_DEV_INTR_AVG_DOWN_WMARK_ENB); - - __raw_writel(val, base + ACTMON_DEV_INTR_ENB); -} - -static void enb_dev_intr(u32 val, void __iomem *base) -{ - __raw_writel(val, base + ACTMON_DEV_INTR_ENB); -} - -static u32 get_dev_intr(void __iomem *base) -{ - return __raw_readl(base + ACTMON_DEV_INTR_ENB); -} - -static u32 get_avg_cnt(void __iomem *base) -{ - return __raw_readl(base + ACTMON_DEV_AVG_COUNT); -} - -static u32 get_raw_cnt(void __iomem *base) -{ - return __raw_readl(base + ACTMON_DEV_COUNT); -} - -static void enb_dev_wm(u32 *val) -{ - *val |= (ACTMON_DEV_INTR_UP_WMARK_ENB | - ACTMON_DEV_INTR_DOWN_WMARK_ENB); -} - -static void disb_dev_up_wm(u32 *val) -{ - *val &= ~ACTMON_DEV_INTR_UP_WMARK_ENB; -} - -static void disb_dev_dn_wm(u32 *val) -{ - *val &= ~ACTMON_DEV_INTR_DOWN_WMARK_ENB; -} - -/*********end of actmon device register operations***********/ - -static void actmon_dev_reg_ops_init(struct actmon_dev *adev) -{ - adev->ops.set_init_avg = set_init_avg; - adev->ops.set_avg_up_wm = set_avg_up_wm; - adev->ops.set_avg_dn_wm = set_avg_dn_wm; - adev->ops.set_dev_up_wm = set_dev_up_wm; - adev->ops.set_dev_dn_wm = set_dev_dn_wm; - adev->ops.set_cnt_wt = set_cnt_wt; - adev->ops.set_intr_st = set_intr_st; - adev->ops.get_intr_st = get_intr_st; - adev->ops.init_dev_cntrl = init_dev_cntrl; - adev->ops.enb_dev_intr_all = enb_dev_intr_all; - adev->ops.enb_dev_intr = enb_dev_intr; - adev->ops.get_dev_intr_enb = get_dev_intr; - adev->ops.get_avg_cnt = get_avg_cnt; - adev->ops.get_raw_cnt = get_raw_cnt; - adev->ops.enb_dev_wm = enb_dev_wm; - adev->ops.disb_dev_up_wm = disb_dev_up_wm; - adev->ops.disb_dev_dn_wm = disb_dev_dn_wm; -} - -static unsigned long actmon_dev_get_max_rate(struct actmon_dev *adev) -{ - unsigned long rate = 0; - - if (!adev->bwmgr_disable) - return tegra_bwmgr_get_max_emc_rate(); - - if (adev->dram_clk_handle) { - rate = clk_round_rate(adev->dram_clk_handle, ULONG_MAX); - return rate; - } - - return 0; -} - -static unsigned long actmon_dev_get_rate(struct actmon_dev *adev) -{ - unsigned long rate = 0; - - if (!adev->bwmgr_disable) - return tegra_bwmgr_get_emc_rate(); - - if (adev->dram_clk_handle) { - rate = clk_get_rate(adev->dram_clk_handle); - return rate; - } - - return 0; -} - -static unsigned long actmon_dev_post_change_rate( - struct actmon_dev *adev, void *cclk) -{ - struct clk_notifier_data *clk_data = cclk; - - return clk_data->new_rate; -} - -/* TBD: Use the implementation from mc_utils */ -#if IS_ENABLED(CONFIG_INTERCONNECT) -#define BYTES_PER_CLK_PER_CH 4 -#define CH_16 16 -#define CH_16_BYTES_PER_CLK (BYTES_PER_CLK_PER_CH * CH_16) - -unsigned long emc_freq_to_bw(unsigned long freq) -{ - return freq * CH_16_BYTES_PER_CLK; -} -#endif - -static void icc_set_rate(struct actmon_dev *adev, unsigned long freq) -{ -#if IS_ENABLED(CONFIG_INTERCONNECT) - struct icc_path *icc_path_handle = NULL; - u32 floor_bw_kbps = 0; - - icc_path_handle = (struct icc_path *)adev->clnt; - floor_bw_kbps = emc_freq_to_bw(freq); - - icc_set_bw(icc_path_handle, 0, floor_bw_kbps); -#endif -} - -static void actmon_dev_set_rate(struct actmon_dev *adev, - unsigned long freq) -{ - struct tegra_bwmgr_client *bwclnt = NULL; - - if (!adev->bwmgr_disable) { - bwclnt = (struct tegra_bwmgr_client *)adev->clnt; - - tegra_bwmgr_set_emc(bwclnt, freq * 1000, - TEGRA_BWMGR_SET_EMC_FLOOR); - } else { - icc_set_rate(adev, freq); - } -} - -static int cactmon_bwmgr_register( - struct actmon_dev *adev, struct platform_device *pdev) -{ - struct tegra_bwmgr_client *bwclnt = (struct tegra_bwmgr_client *) - adev->clnt; - struct device *mon_dev = &pdev->dev; - int ret = 0; - - bwclnt = tegra_bwmgr_register(TEGRA_BWMGR_CLIENT_MON); - if (IS_ERR_OR_NULL(bwclnt)) { - ret = -ENODEV; - dev_err(mon_dev, "emc bw manager registration failed for %s\n", - adev->dn->name); - return ret; - } - - adev->clnt = bwclnt; - - return ret; -} - - -static void cactmon_bwmgr_unregister( - struct actmon_dev *adev, struct platform_device *pdev) -{ - struct tegra_bwmgr_client *bwclnt = (struct tegra_bwmgr_client *) - adev->clnt; - struct device *mon_dev = &pdev->dev; - - if (bwclnt) { - dev_dbg(mon_dev, "unregistering BW manager for %s\n", - adev->dn->name); - tegra_bwmgr_unregister(bwclnt); - adev->clnt = NULL; - } -} - -static int cactmon_icc_register( - struct actmon_dev *adev, struct platform_device *pdev) -{ - int ret = 0; - -#if IS_ENABLED(CONFIG_INTERCONNECT) - struct icc_path *icc_path_handle = NULL; - struct device *mon_dev = &pdev->dev; - - icc_path_handle = icc_get(mon_dev, TEGRA_ICC_CACTMON, TEGRA_ICC_PRIMARY); - if (IS_ERR_OR_NULL(icc_path_handle)) { - ret = -ENODEV; - dev_err(mon_dev, "icc registration failed for %s\n", - adev->dn->name); - return ret; - } - - adev->clnt = icc_path_handle; -#endif - - return ret; -} - -static void cactmon_icc_unregister( - struct actmon_dev *adev, struct platform_device *pdev) -{ -#if IS_ENABLED(CONFIG_INTERCONNECT) - struct icc_path *icc_path_handle = (struct icc_path *) - adev->clnt; - struct device *mon_dev = &pdev->dev; - - if (icc_path_handle) { - dev_dbg(mon_dev, "unregistering icc for %s\n", - adev->dn->name); - icc_put(icc_path_handle); - adev->clnt = NULL; - } -#endif -} - -static int cactmon_register_bw( - struct actmon_dev *adev, struct platform_device *pdev) -{ - int ret = 0; - - if (adev->bwmgr_disable) - ret = cactmon_icc_register(adev, pdev); - else - ret = cactmon_bwmgr_register(adev, pdev); - - return ret; -} - -static void cactmon_unregister_bw( - struct actmon_dev *adev, struct platform_device *pdev) -{ - if (adev->bwmgr_disable) - cactmon_icc_unregister(adev, pdev); - else - cactmon_bwmgr_unregister(adev, pdev); -} - -static int actmon_dev_platform_init(struct actmon_dev *adev, - struct platform_device *pdev) -{ - struct tegra_bwmgr_client *bwclnt; - int ret = 0; - - ret = cactmon_register_bw(adev, pdev); - if (ret) - goto end; - - adev->dev_name = adev->dn->name; - adev->max_freq = actmon_dev_get_max_rate(adev); - - if (!adev->bwmgr_disable) { - bwclnt = (struct tegra_bwmgr_client *) adev->clnt; - tegra_bwmgr_set_emc(bwclnt, adev->max_freq, - TEGRA_BWMGR_SET_EMC_FLOOR); - } else { - icc_set_rate(adev, adev->max_freq); - } - - adev->max_freq /= 1000; - actmon_dev_reg_ops_init(adev); - adev->actmon_dev_set_rate = actmon_dev_set_rate; - adev->actmon_dev_get_rate = actmon_dev_get_rate; - if (adev->rate_change_nb.notifier_call) { - if (!adev->bwmgr_disable) - ret = tegra_bwmgr_notifier_register(&adev->rate_change_nb); - else - ret = clk_notifier_register(adev->dram_clk_handle, &adev->rate_change_nb); - - if (ret) { - pr_err("Failed to register bw manager rate change notifier for %s\n", - adev->dev_name); - return ret; - } - } - adev->actmon_dev_post_change_rate = actmon_dev_post_change_rate; -end: - return ret; -} - -static void cactmon_free_resource( - struct actmon_dev *adev, struct platform_device *pdev) -{ - int ret = 0; - - if (adev->rate_change_nb.notifier_call) { - if (!adev->bwmgr_disable) - ret = tegra_bwmgr_notifier_unregister(&adev->rate_change_nb); - else - ret = clk_notifier_unregister(adev->dram_clk_handle, &adev->rate_change_nb); - - if (ret) { - pr_err("Failed to register bw manager rate change notifier for %s\n", - adev->dev_name); - } - } - cactmon_unregister_bw(adev, pdev); -} - -static int cactmon_reset_dinit(struct platform_device *pdev) -{ - struct actmon_drv_data *actmon = platform_get_drvdata(pdev); - struct device *mon_dev = &pdev->dev; - int ret = -EINVAL; - - if (actmon->actmon_rst) { - ret = reset_control_assert(actmon->actmon_rst); - if (ret) - dev_err(mon_dev, "failed to assert actmon\n"); - } - - return ret; -} - -static int cactmon_reset_init(struct platform_device *pdev) -{ - struct actmon_drv_data *actmon = platform_get_drvdata(pdev); - struct device *mon_dev = &pdev->dev; - int ret = 0; - - actmon->actmon_rst = devm_reset_control_get(mon_dev, "actmon_rst"); - if (IS_ERR(actmon->actmon_rst)) { - ret = PTR_ERR(actmon->actmon_rst); - dev_err(mon_dev, "can not get actmon reset%d\n", ret); - } - - /* Make actmon out of reset */ - ret = reset_control_deassert(actmon->actmon_rst); - if (ret) - dev_err(mon_dev, "failed to deassert actmon\n"); - - return ret; -} - - -static int cactmon_clk_disable(struct platform_device *pdev) -{ - struct actmon_drv_data *actmon = platform_get_drvdata(pdev); - struct device *mon_dev = &pdev->dev; - int ret = 0; - - if (actmon->actmon_clk) { - clk_disable_unprepare(actmon->actmon_clk); - devm_clk_put(mon_dev, actmon->actmon_clk); - actmon->actmon_clk = NULL; - dev_dbg(mon_dev, "actmon clocks disabled\n"); - } - - return ret; -} - -static int cactmon_clk_enable(struct platform_device *pdev) -{ - struct actmon_drv_data *actmon = platform_get_drvdata(pdev); - struct device *mon_dev = &pdev->dev; - int ret = 0; - - actmon->actmon_clk = devm_clk_get(mon_dev, "actmon"); - if (IS_ERR_OR_NULL(actmon->actmon_clk)) { - dev_err(mon_dev, "unable to find actmon clock\n"); - ret = PTR_ERR(actmon->actmon_clk); - return ret; - } - - ret = clk_prepare_enable(actmon->actmon_clk); - if (ret) { - dev_err(mon_dev, "unable to enable actmon clock\n"); - goto end; - } - - actmon->freq = clk_get_rate(actmon->actmon_clk) / 1000; - - return 0; -end: - devm_clk_put(mon_dev, actmon->actmon_clk); - return ret; -} - -static struct actmon_drv_data actmon_data = { - .clock_init = cactmon_clk_enable, - .clock_deinit = cactmon_clk_disable, - .reset_init = cactmon_reset_init, - .reset_deinit = cactmon_reset_dinit, - .dev_free_resource = cactmon_free_resource, - .actmon_dev_platform_init = actmon_dev_platform_init, - .ops.set_sample_prd = set_prd, - .ops.set_glb_intr = set_glb_intr, - .ops.get_glb_intr_st = get_glb_intr_st, -}; - -static const struct of_device_id tegra_actmon_of_match[] = { - { .compatible = "nvidia,tegra194-cactmon", .data = &actmon_data, }, - { .compatible = "nvidia,tegra186-cactmon", .data = &actmon_data, }, - { .compatible = "nvidia,tegra234-cactmon", .data = &actmon_data, }, - {}, -}; - -static int __init tegra_actmon_probe(struct platform_device *pdev) -{ - int ret = 0; - const struct of_device_id *of_id; - struct actmon_drv_data *actmon; - - of_id = of_match_node(tegra_actmon_of_match, pdev->dev.of_node); - if (of_id == NULL) { - pr_err("No matching of node\n"); - ret = -ENODATA; - return ret; - } - actmon = (struct actmon_drv_data *)of_id->data; - platform_set_drvdata(pdev, actmon); - actmon->pdev = pdev; - ret = tegra_actmon_register(actmon); - return ret; -} - -static struct platform_driver tegra19x_actmon_driver __refdata = { - .probe = tegra_actmon_probe, - .remove = tegra_actmon_remove, - .driver = { - .name = "tegra_actmon", - .owner = THIS_MODULE, - .of_match_table = of_match_ptr(tegra_actmon_of_match), - }, -}; - -module_platform_driver(tegra19x_actmon_driver); - -MODULE_DESCRIPTION("Central Tegra Activity Monitor"); -MODULE_AUTHOR("Laxman Dewangan "); -MODULE_LICENSE("GPL v2"); -