123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207 |
- /* SPDX-License-Identifier: GPL-2.0-only */
- /*
- * Copyright (c) 2014-2020, The Linux Foundation. All rights reserved.
- * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
- */
- #ifndef _QCOM_BWMON_H
- #define _QCOM_BWMON_H
- #include <linux/kernel.h>
- #include <soc/qcom/dcvs.h>
- #define NUM_MBPS_ZONES 10
- #define UP_WAKE 1
- #define DOWN_WAKE 2
- #define MBYTE (1ULL << 20)
- #define MBPS_TO_KHZ(mbps, w) (mult_frac(mbps, MBYTE, w * 1000ULL))
- #define KHZ_TO_MBPS(khz, w) (mult_frac(w * 1000ULL, khz, MBYTE))
- #define to_bwmon(ptr) container_of(ptr, struct bwmon, hw)
- enum mon_reg_type {
- MON1,
- MON2,
- MON3,
- };
- struct bwmon_spec {
- bool wrap_on_thres;
- bool overflow;
- bool throt_adj;
- bool hw_sampling;
- bool has_global_base;
- enum mon_reg_type reg_type;
- };
- struct bwmon_second_map {
- u32 src_freq;
- u32 dst_freq;
- };
- /**
- * struct bw_hwmon - dev BW HW monitor info
- * @start_hwmon: Start the HW monitoring of the dev BW
- * @stop_hwmon: Stop the HW monitoring of dev BW
- * @set_thres: Set the count threshold to generate an IRQ
- * @set_hw_events: Set hw settings for up/down wake events
- * @get_bytes_and_clear: Get the bytes transferred since the last call
- * and reset the counter to start over.
- * @set_throttle_adj: Set throttle adjust field to the given value
- * @get_throttle_adj: Get the value written to throttle adjust field
- * @dev: Pointer to device tied to this HW monitor
- * @dcvs_hw: DCVS HW type that this HW is monitoring for
- * @dcvs_path: DCVS Path type that this monitor votes on
- * @node: Pointer to hwmon node that contains tunables
- * @last_update_ts: Time that the last bwmon work was queued
- * @work: bwmon monitor work
- * @is_active: Toggled when HW monitor is started/stopped
- * @up_wake_mbps: Setting for HW monitor to send IRQ for up wake
- * @down_wake_mbps: Setting for HW monitor to send IRQ fow down wake
- * @down_cnt: Setting for down sample count needed for wake
- */
- struct bw_hwmon {
- int (*start_hwmon)(struct bw_hwmon *hw,
- unsigned long mbps);
- void (*stop_hwmon)(struct bw_hwmon *hw);
- unsigned long (*set_thres)(struct bw_hwmon *hw,
- unsigned long bytes);
- unsigned long (*set_hw_events)(struct bw_hwmon *hw,
- unsigned int sample_ms);
- unsigned long (*get_bytes_and_clear)(struct bw_hwmon *hw);
- int (*set_throttle_adj)(struct bw_hwmon *hw,
- uint adj);
- u32 (*get_throttle_adj)(struct bw_hwmon *hw);
- struct device *dev;
- enum dcvs_hw_type dcvs_hw;
- enum dcvs_path_type dcvs_path;
- u32 dcvs_width;
- enum dcvs_hw_type second_dcvs_hw;
- u32 second_dcvs_width;
- bool second_vote_supported;
- u32 second_vote_limit;
- struct bwmon_second_map *second_map;
- struct hwmon_node *node;
- ktime_t last_update_ts;
- struct work_struct work;
- bool is_active;
- unsigned long up_wake_mbps;
- unsigned long down_wake_mbps;
- unsigned int down_cnt;
- };
- struct bwmon {
- void __iomem *base;
- void __iomem *global_base;
- unsigned int mport;
- int irq;
- const struct bwmon_spec *spec;
- struct device *dev;
- struct bw_hwmon hw;
- u32 hw_timer_hz;
- u32 throttle_adj;
- u32 sample_size_ms;
- u32 intr_status;
- u8 count_shift;
- u32 thres_lim;
- u32 byte_mask;
- u32 byte_match;
- };
- struct hwmon_node {
- u32 hw_min_freq;
- u32 hw_max_freq;
- u32 min_freq;
- u32 max_freq;
- struct dcvs_freq cur_freqs[2];
- u32 window_ms;
- unsigned int guard_band_mbps;
- unsigned int decay_rate;
- unsigned int io_percent;
- unsigned int bw_step;
- unsigned int sample_ms;
- unsigned int up_scale;
- unsigned int up_thres;
- unsigned int down_thres;
- unsigned int down_count;
- unsigned int hist_memory;
- unsigned int hyst_trigger_count;
- unsigned int hyst_length;
- unsigned int idle_length;
- unsigned int idle_mbps;
- unsigned int ab_scale;
- unsigned int mbps_zones[NUM_MBPS_ZONES];
- unsigned long prev_ab;
- unsigned long bytes;
- unsigned long max_mbps;
- unsigned long hist_max_mbps;
- unsigned long hist_mem;
- unsigned long hyst_peak;
- unsigned long hyst_mbps;
- unsigned long hyst_trig_win;
- unsigned long hyst_en;
- unsigned long idle_en;
- unsigned long prev_req;
- unsigned int wake;
- unsigned int down_cnt;
- ktime_t prev_ts;
- ktime_t hist_max_ts;
- bool sampled;
- bool mon_started;
- struct list_head list;
- struct bw_hwmon *hw;
- struct kobject kobj;
- struct mutex mon_lock;
- struct mutex update_lock;
- };
- /* BWMON register offsets */
- #define GLB_INT_STATUS(m) ((m)->global_base + 0x100)
- #define GLB_INT_CLR(m) ((m)->global_base + 0x108)
- #define GLB_INT_EN(m) ((m)->global_base + 0x10C)
- #define MON_INT_STATUS(m) ((m)->base + 0x100)
- #define MON_INT_STATUS_MASK 0x03
- #define MON2_INT_STATUS_MASK 0xF0
- #define MON2_INT_STATUS_SHIFT 4
- #define MON_INT_CLR(m) ((m)->base + 0x108)
- #define MON_INT_EN(m) ((m)->base + 0x10C)
- #define MON_INT_ENABLE 0x1
- #define MON_EN(m) ((m)->base + 0x280)
- #define MON_CLEAR(m) ((m)->base + 0x284)
- #define MON_CNT(m) ((m)->base + 0x288)
- #define MON_THRES(m) ((m)->base + 0x290)
- #define MON_MASK(m) ((m)->base + 0x298)
- #define MON_MATCH(m) ((m)->base + 0x29C)
- #define MON2_EN(m) ((m)->base + 0x2A0)
- #define MON2_CLEAR(m) ((m)->base + 0x2A4)
- #define MON2_SW(m) ((m)->base + 0x2A8)
- #define MON2_THRES_HI(m) ((m)->base + 0x2AC)
- #define MON2_THRES_MED(m) ((m)->base + 0x2B0)
- #define MON2_THRES_LO(m) ((m)->base + 0x2B4)
- #define MON2_ZONE_ACTIONS(m) ((m)->base + 0x2B8)
- #define MON2_ZONE_CNT_THRES(m) ((m)->base + 0x2BC)
- #define MON2_BYTE_CNT(m) ((m)->base + 0x2D0)
- #define MON2_WIN_TIMER(m) ((m)->base + 0x2D4)
- #define MON2_ZONE_CNT(m) ((m)->base + 0x2D8)
- #define MON2_ZONE_MAX(m, zone) ((m)->base + 0x2E0 + 0x4 * zone)
- #define MON3_INT_STATUS(m) ((m)->base + 0x00)
- #define MON3_INT_CLR(m) ((m)->base + 0x08)
- #define MON3_INT_EN(m) ((m)->base + 0x0C)
- #define MON3_INT_STATUS_MASK 0x0F
- #define MON3_EN(m) ((m)->base + 0x10)
- #define MON3_CLEAR(m) ((m)->base + 0x14)
- #define MON3_MASK(m) ((m)->base + 0x18)
- #define MON3_MATCH(m) ((m)->base + 0x1C)
- #define MON3_SW(m) ((m)->base + 0x20)
- #define MON3_THRES_HI(m) ((m)->base + 0x24)
- #define MON3_THRES_MED(m) ((m)->base + 0x28)
- #define MON3_THRES_LO(m) ((m)->base + 0x2C)
- #define MON3_ZONE_ACTIONS(m) ((m)->base + 0x30)
- #define MON3_ZONE_CNT_THRES(m) ((m)->base + 0x34)
- #define MON3_BYTE_CNT(m) ((m)->base + 0x38)
- #define MON3_WIN_TIMER(m) ((m)->base + 0x3C)
- #define MON3_ZONE_CNT(m) ((m)->base + 0x40)
- #define MON3_ZONE_MAX(m, zone) ((m)->base + 0x44 + 0x4 * zone)
- #endif /* _QCOM_BWMON_H */
|