/* SPDX-License-Identifier: GPL-2.0 */ /* * Copyright (c) 2019 MediaTek Inc. * Author: Ming-Fan Chen */ #ifndef MMQOS_MTK_H #define MMQOS_MTK_H //#include #include "mtk-interconnect-provider.h" #include #include #include #include #include #define MMQOS_NO_LINK (0xffffffff) #define MMQOS_MAX_COMM_NUM (3) #define MMQOS_MAX_COMM_PORT_NUM (10) #define MMQOS_COMM_CHANNEL_NUM (2) #define MMQOS_MAX_DUAL_PIPE_LARB_NUM (2) #define MMQOS_MAX_REPORT_LARB_NUM (9) #define RECORD_NUM (10) enum mmqos_state_level { MMQOS_DISABLE = 0, OSTD_ENABLE = BIT(0), BWL_ENABLE = BIT(1), DVFSRC_ENABLE = BIT(2), COMM_OSTDL_ENABLE = BIT(3), BWL_MIN_ENABLE = BIT(4), BWL_NO_QOSBOUND = BIT(5), MMQOS_ENABLE = BIT(0) | BIT(1) | BIT(2), }; enum { MD_SCEN_NONE, MD_SCEN_SUB6_EXT, }; struct hrt_record { u8 idx; u64 time[RECORD_NUM]; u32 avail_hrt[RECORD_NUM]; u32 cam_max_hrt[RECORD_NUM]; u32 cam_hrt[RECORD_NUM]; struct mutex lock; }; struct cam_hrt_record { u8 idx; u64 time[RECORD_NUM]; u32 cam_max_hrt[RECORD_NUM]; }; struct mmqos_hrt { u32 hrt_bw[HRT_TYPE_NUM]; u32 hrt_ratio[HRT_TYPE_NUM]; u32 hrt_total_bw; u32 cam_max_bw; u32 cam_occu_bw; u32 md_speech_bw[4]; u32 emi_ratio; bool blocking; bool cam_bw_inc; struct delayed_work work; struct blocking_notifier_head hrt_bw_throttle_notifier; atomic_t lock_count; wait_queue_head_t hrt_wait; struct mutex blocking_lock; bool in_speech; u8 md_type; u8 md_scen; struct hrt_record hrt_rec; struct cam_hrt_record cam_hrt_rec; }; struct mmqos_base_node { struct icc_node *icc_node; u32 mix_bw; }; struct common_node { struct mmqos_base_node *base; struct device *comm_dev; struct regulator *comm_reg; const char *clk_name; struct clk *clk; u64 freq; u64 smi_clk; u32 volt; struct list_head list; struct icc_path *icc_path; struct icc_path *icc_hrt_path; struct work_struct work; struct list_head comm_port_list; }; struct larb_node { struct mmqos_base_node *base; struct device *larb_dev; struct work_struct work; struct icc_path *icc_path; u32 old_avg_bw; u32 old_peak_bw; u8 channel; u8 dual_pipe_id; bool is_write; bool is_report_bw_larbs; }; struct mtk_node_desc { const char *name; u32 id; u32 link; u16 bw_ratio; u8 channel; bool is_write; }; struct mtk_mmqos_desc { const struct mtk_node_desc *nodes; const size_t num_nodes; const char * const *comm_muxes; const char * const *comm_icc_path_names; const char * const *comm_icc_hrt_path_names; const char * const *larb_icc_path_names; const u32 max_ratio; const struct mmqos_hrt hrt; const struct mmqos_hrt hrt_LPDDR4; const u32 dual_pipe_larbs[MMQOS_MAX_DUAL_PIPE_LARB_NUM]; const u8 comm_port_channels[MMQOS_MAX_COMM_NUM][MMQOS_MAX_COMM_PORT_NUM]; const u8 comm_port_hrt_types[MMQOS_MAX_COMM_NUM][MMQOS_MAX_COMM_PORT_NUM]; const u8 md_scen; const u32 mmqos_state; const u32 report_bw_larbs[MMQOS_MAX_REPORT_LARB_NUM]; }; #define DEFINE_MNODE(_name, _id, _bw_ratio, _is_write, _channel, _link) { \ .name = #_name, \ .id = _id, \ .bw_ratio = _bw_ratio, \ .is_write = _is_write, \ .channel = _channel, \ .link = _link, \ } int mtk_mmqos_probe(struct platform_device *pdev); int mtk_mmqos_remove(struct platform_device *pdev); /* For HRT */ void mtk_mmqos_init_hrt(struct mmqos_hrt *hrt); int mtk_mmqos_register_hrt_sysfs(struct device *dev); void mtk_mmqos_unregister_hrt_sysfs(struct device *dev); enum MMQOS_PROFILE_LEVEL { MMQOS_PROFILE_MET = 0, MMQOS_PROFILE_SYSTRACE = 1, MMQOS_PROFILE_DETAIL_SYSTRACE = 2, MMQOS_PROFILE_MAX /* Always keep at the end */ }; /* For MET */ bool mmqos_met_enabled(void); /* For systrace */ bool mmqos_systrace_enabled(void); bool mmqos_detail_systrace_enabled(void); int tracing_mark_write(char *fmt, ...); #define TRACE_MSG_LEN 1024 #define MMQOS_TRACE_FORCE_BEGIN_TID(tid, fmt, args...) \ tracing_mark_write("B|%d|" fmt "\n", tid, ##args) #define MMQOS_TRACE_FORCE_BEGIN(fmt, args...) \ MMQOS_TRACE_FORCE_BEGIN_TID(current->tgid, fmt, ##args) #define MMQOS_TRACE_FORCE_END() \ tracing_mark_write("E\n") #define MMQOS_SYSTRACE_BEGIN(fmt, args...) do { \ if (mmqos_systrace_enabled()) { \ MMQOS_TRACE_FORCE_BEGIN(fmt, ##args); \ } \ } while (0) #define MMQOS_SYSTRACE_END() do { \ if (mmqos_systrace_enabled()) { \ MMQOS_TRACE_FORCE_END(); \ } \ } while (0) #define MMQOS_DETAIL_SYSTRACE_BEGIN(fmt, args...) do { \ if (mmqos_detail_systrace_enabled()) { \ MMQOS_TRACE_FORCE_BEGIN(fmt, ##args); \ } \ } while (0) #define MMQOS_DETAIL_SYSTRACE_END() do { \ if (mmqos_detail_systrace_enabled()) { \ MMQOS_TRACE_FORCE_END(); \ } \ } while (0) #endif /* MMQOS_MTK_H */