From c9b265a519a1afabd5faca58ab2363c0df336e44 Mon Sep 17 00:00:00 2001 From: Hoang Pham Date: Sun, 11 Jun 2017 02:10:27 -0700 Subject: tegra: central_actmon: refactor driver - Convert module platform actmon common driver into actmon core driver - Convert dependent drivers into SoCs module platform actmon drivers - This allows for the kernel to support multiple SoCs without a namespace clash avoiding need for different compile time options and no need to change actmon core driver for future chips Reviewed-on: http://git-master/r/1268709 (cherry picked from commit 7198bd1f18319d867f541f63cc282ac90a290e8f) Change-Id: I9ff5966c090b8faf3c6f2cc5c6a0308b864b9f7e Reviewed-on: https://git-master.nvidia.com/r/1499976 Reviewed-by: Timo Alho Tested-by: Timo Alho Signed-off-by: Hoang Pham Reviewed-on: https://git-master.nvidia.com/r/1730873 GVS: Gerrit_Virtual_Submit Reviewed-by: Sachin Nikam Reviewed-by: mobile promotions Tested-by: mobile promotions --- include/linux/platform/tegra/actmon_common.h | 192 +++++++++++++++++++++++++++ 1 file changed, 192 insertions(+) create mode 100644 include/linux/platform/tegra/actmon_common.h (limited to 'include/linux') diff --git a/include/linux/platform/tegra/actmon_common.h b/include/linux/platform/tegra/actmon_common.h new file mode 100644 index 000000000..b3a76d0b8 --- /dev/null +++ b/include/linux/platform/tegra/actmon_common.h @@ -0,0 +1,192 @@ +/* + * Copyright (C) 2016-2018, NVIDIA Corporation. All rights reserved. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ +#ifndef ACTMON_COMMON_H + +#include + +/* 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 { + MC_ALL, /* Should match with device sequence in dt */ + 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 *, 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; + + struct dev_reg_ops ops; + void (*actmon_dev_set_rate)(struct actmon_dev *, unsigned long); + unsigned long (*actmon_dev_get_rate)(struct actmon_dev *); + unsigned long (*actmon_dev_post_change_rate)(struct actmon_dev *, + void *v); + void (*actmon_dev_clk_enable)(struct actmon_dev *); + 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); +} + +int tegra_actmon_register(struct actmon_drv_data *actmon); +int tegra_actmon_remove(struct platform_device *pdev); +#endif /* ACTMON_COMMON_H */ -- cgit v1.2.2