Files
android_kernel_samsung_sm86…/msm/sde_dbg.h
Christopher Braga 8f1d4ca416 disp: msm: sde: Update LUT DMA reg dump ranges and offsets
Update the LUT DMA register range registration to target
specific ranges of valid registers instead of the full
memory region of the LUT DMA module. This ensures that
unused LUT DMA register regions are not dumped.

Change-Id: I3739692ae7fcfd5777bb8774dd34c16ab87c3ae1
Signed-off-by: Christopher Braga <quic_cbraga@quicinc.com>
2022-12-02 13:05:55 -05:00

556 lines
17 KiB
C

/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved.
* Copyright (c) 2016-2021, The Linux Foundation. All rights reserved.
*/
#ifndef SDE_DBG_H_
#define SDE_DBG_H_
#include <stdarg.h>
#include <linux/debugfs.h>
#include <linux/list.h>
#include <soc/qcom/minidump.h>
#include <drm/drm_print.h>
/* select an uncommon hex value for the limiter */
#define SDE_EVTLOG_DATA_LIMITER (0xC0DEBEEF)
#define SDE_EVTLOG_FUNC_ENTRY 0x1111
#define SDE_EVTLOG_FUNC_EXIT 0x2222
#define SDE_EVTLOG_FUNC_CASE1 0x3333
#define SDE_EVTLOG_FUNC_CASE2 0x4444
#define SDE_EVTLOG_FUNC_CASE3 0x5555
#define SDE_EVTLOG_FUNC_CASE4 0x6666
#define SDE_EVTLOG_FUNC_CASE5 0x7777
#define SDE_EVTLOG_FUNC_CASE6 0x8888
#define SDE_EVTLOG_FUNC_CASE7 0x9999
#define SDE_EVTLOG_FUNC_CASE8 0xaaaa
#define SDE_EVTLOG_FUNC_CASE9 0xbbbb
#define SDE_EVTLOG_FUNC_CASE10 0xcccc
#define SDE_EVTLOG_PANIC 0xdead
#define SDE_EVTLOG_FATAL 0xbad
#define SDE_EVTLOG_ERROR 0xebad
#define SDE_EVTLOG_H32(val) (val >> 32)
#define SDE_EVTLOG_L32(val) (val & 0xffffffff)
#define LUTDMA_DBG_NAME "reg_dma"
/* flags to enable the HW block dumping */
#define SDE_DBG_SDE BIT(0)
#define SDE_DBG_RSC BIT(1)
#define SDE_DBG_SID BIT(2)
#define SDE_DBG_LUTDMA BIT(3)
#define SDE_DBG_VBIF_RT BIT(4)
#define SDE_DBG_DSI BIT(5)
/* flags to enable the HW block debugbus dumping */
#define SDE_DBG_SDE_DBGBUS BIT(12)
#define SDE_DBG_RSC_DBGBUS BIT(13)
#define SDE_DBG_LUTDMA_DBGBUS BIT(14)
#define SDE_DBG_VBIF_RT_DBGBUS BIT(15)
#define SDE_DBG_DSI_DBGBUS BIT(16)
/* mask to enable all the built-in register blocks */
#define SDE_DBG_BUILT_IN_ALL 0xffffff
/* keeping DP separate as DP specific clks needs to be enabled for accessing */
#define SDE_DBG_DP BIT(24)
#define SDE_DBG_DP_DBGBUS BIT(25)
#define SDE_DBG_DUMP_DATA_LIMITER (NULL)
enum sde_dbg_evtlog_flag {
SDE_EVTLOG_CRITICAL = BIT(0),
SDE_EVTLOG_IRQ = BIT(1),
SDE_EVTLOG_VERBOSE = BIT(2),
SDE_EVTLOG_EXTERNAL = BIT(3),
SDE_EVTLOG_ALWAYS = -1
};
enum sde_dbg_dump_flag {
SDE_DBG_DUMP_IN_LOG = BIT(0),
SDE_DBG_DUMP_IN_MEM = BIT(1),
SDE_DBG_DUMP_IN_LOG_LIMITED = BIT(2),
SDE_DBG_DUMP_IN_COREDUMP = BIT(3),
};
enum sde_dbg_dump_context {
SDE_DBG_DUMP_PROC_CTX,
SDE_DBG_DUMP_IRQ_CTX,
SDE_DBG_DUMP_CLK_ENABLED_CTX,
};
/*
* Set in_coredump as default mode. Any existing script which rely on
* dump_mode to be in_mem should now explicitly run the cmd
* "adb shell echo 2 > /sys/kernel/debug/dri/0/debug/reg_dump" before
* doing the test cases.
*/
#define SDE_DBG_DEFAULT_DUMP_MODE SDE_DBG_DUMP_IN_MEM
/*
* Define blocks for register write logging.
*/
#define SDE_REG_LOG_DEFAULT 0
#define SDE_REG_LOG_NONE 1
#define SDE_REG_LOG_CDM 2
#define SDE_REG_LOG_DSPP 3
#define SDE_REG_LOG_INTF 4
#define SDE_REG_LOG_LM 5
#define SDE_REG_LOG_CTL 6
#define SDE_REG_LOG_PINGPONG 7
#define SDE_REG_LOG_SSPP 8
#define SDE_REG_LOG_WB 9
#define SDE_REG_LOG_TOP 10
#define SDE_REG_LOG_VBIF 11
#define SDE_REG_LOG_DSC 12
#define SDE_REG_LOG_ROT 13
#define SDE_REG_LOG_DS 14
#define SDE_REG_LOG_REGDMA 15
#define SDE_REG_LOG_UIDLE 16
#define SDE_REG_LOG_SID 16
#define SDE_REG_LOG_QDSS 17
/*
* 0-32 are reserved for sde_reg_write due to log masks
* Additional blocks are assigned from 33 to avoid conflict
*/
#define SDE_REG_LOG_RSCC 33
#define SDE_EVTLOG_DEFAULT_ENABLE (SDE_EVTLOG_CRITICAL | SDE_EVTLOG_IRQ | SDE_EVTLOG_EXTERNAL)
/*
* evtlog will print this number of entries when it is called through
* sysfs node or panic. This prevents kernel log from evtlog message
* flood.
*/
#define SDE_EVTLOG_PRINT_ENTRY 256
/*
* evtlog keeps this number of entries in memory for debug purpose. This
* number must be greater than print entry to prevent out of bound evtlog
* entry array access.
*/
#if IS_ENABLED(CONFIG_DRM_MSM_LOW_MEM_FOOTPRINT)
#define SDE_EVTLOG_ENTRY (SDE_EVTLOG_PRINT_ENTRY * 8)
#else
#define SDE_EVTLOG_ENTRY (SDE_EVTLOG_PRINT_ENTRY * 32)
#endif /* IS_ENABLED(CONFIG_DRM_MSM_LOW_MEM_FOOTPRINT) */
#define SDE_EVTLOG_MAX_DATA 15
#define SDE_EVTLOG_BUF_MAX 512
#define SDE_EVTLOG_BUF_ALIGN 32
struct sde_dbg_power_ctrl {
void *handle;
void *client;
int (*enable_fn)(void *handle, void *client, bool enable);
};
struct sde_dbg_evtlog_log {
s64 time;
const char *name;
int line;
u32 data[SDE_EVTLOG_MAX_DATA];
u32 data_cnt;
int pid;
u8 cpu;
};
/**
* @last_dump: Index of last entry to be output during evtlog dumps
* @filter_list: Linked list of currently active filter strings
*/
struct sde_dbg_evtlog {
struct sde_dbg_evtlog_log logs[SDE_EVTLOG_ENTRY];
u32 first;
u32 last;
u32 last_dump;
atomic_t curr;
u32 next;
u32 enable;
u32 dump_mode;
char *dumped_evtlog;
u32 log_size;
spinlock_t spin_lock;
struct list_head filter_list;
};
extern struct sde_dbg_evtlog *sde_dbg_base_evtlog;
/*
* reglog keeps this number of entries in memory for debug purpose. This
* number must be greater than number of possible writes in at least one
* single commit.
*/
#if IS_ENABLED(CONFIG_DRM_MSM_LOW_MEM_FOOTPRINT)
#define SDE_REGLOG_ENTRY 256
#else
#define SDE_REGLOG_ENTRY 1024
#endif /* IS_ENABLED(CONFIG_DRM_MSM_LOW_MEM_FOOTPRINT) */
struct sde_dbg_reglog_log {
s64 time;
u32 pid;
u32 addr;
u32 val;
u8 blk_id;
};
/**
* @last_dump: Index of last entry to be output during reglog dumps
* @filter_list: Linked list of currently active filter strings
*/
struct sde_dbg_reglog {
struct sde_dbg_reglog_log logs[SDE_REGLOG_ENTRY];
u32 first;
u32 last;
u32 last_dump;
atomic64_t curr;
u32 next;
u32 enable;
u32 enable_mask;
};
extern struct sde_dbg_reglog *sde_dbg_base_reglog;
/**
* SDE_REG_LOG - Write register write to the register log
*/
#define SDE_REG_LOG(blk_id, val, addr) sde_reglog_log(blk_id, val, addr)
/**
* SDE_EVT32 - Write a list of 32bit values to the event log, default area
* ... - variable arguments
*/
#define SDE_EVT32(...) sde_evtlog_log(sde_dbg_base_evtlog, __func__, \
__LINE__, SDE_EVTLOG_ALWAYS, ##__VA_ARGS__, \
SDE_EVTLOG_DATA_LIMITER)
/**
* SDE_EVT32_VERBOSE - Write a list of 32bit values for verbose event logging
* ... - variable arguments
*/
#define SDE_EVT32_VERBOSE(...) sde_evtlog_log(sde_dbg_base_evtlog, __func__, \
__LINE__, SDE_EVTLOG_VERBOSE, ##__VA_ARGS__, \
SDE_EVTLOG_DATA_LIMITER)
/**
* SDE_EVT32_IRQ - Write a list of 32bit values to the event log, IRQ area
* ... - variable arguments
*/
#define SDE_EVT32_IRQ(...) sde_evtlog_log(sde_dbg_base_evtlog, __func__, \
__LINE__, SDE_EVTLOG_IRQ, ##__VA_ARGS__, \
SDE_EVTLOG_DATA_LIMITER)
/**
* SDE_EVT32_EXTERNAL - Write a list of 32bit values for external display events
* ... - variable arguments
*/
#define SDE_EVT32_EXTERNAL(...) sde_evtlog_log(sde_dbg_base_evtlog, __func__, \
__LINE__, SDE_EVTLOG_EXTERNAL, ##__VA_ARGS__, \
SDE_EVTLOG_DATA_LIMITER)
/**
* SDE_DBG_DUMP - trigger dumping of all sde_dbg facilities
* @dump_blk_mask: mask of all the hw blk-ids that has to be dumped
* @va_args: list of named register dump ranges and regions to dump, as
* registered previously through sde_dbg_reg_register_base and
* sde_dbg_reg_register_dump_range.
* Including the special name "panic" will trigger a panic after
* the dumping work has completed.
*/
#define SDE_DBG_DUMP(dump_blk_mask, ...) sde_dbg_dump(SDE_DBG_DUMP_PROC_CTX, __func__, \
dump_blk_mask, ##__VA_ARGS__, SDE_DBG_DUMP_DATA_LIMITER)
/**
* SDE_DBG_DUMP_WQ - trigger dumping of all sde_dbg facilities, queuing the work
* @dump_blk_mask: mask of all the hw blk-ids that has to be dumped
* @va_args: list of named register dump ranges and regions to dump, as
* registered previously through sde_dbg_reg_register_base and
* sde_dbg_reg_register_dump_range.
* Including the special name "panic" will trigger a panic after
* the dumping work has completed.
*/
#define SDE_DBG_DUMP_WQ(dump_blk_mask, ...) sde_dbg_dump(SDE_DBG_DUMP_IRQ_CTX, __func__, \
dump_blk_mask, ##__VA_ARGS__, SDE_DBG_DUMP_DATA_LIMITER)
/**
* SDE_DBG_DUMP_CLK_EN - trigger dumping of all sde_dbg facilities, without clk
* @dump_blk_mask: mask of all the hw blk-ids that has to be dumped
* @va_args: list of named register dump ranges and regions to dump, as
* registered previously through sde_dbg_reg_register_base and
* sde_dbg_reg_register_dump_range.
* Including the special name "panic" will trigger a panic after
* the dumping work has completed.
*/
#define SDE_DBG_DUMP_CLK_EN(dump_blk_mask, ...) sde_dbg_dump(SDE_DBG_DUMP_CLK_ENABLED_CTX, \
__func__, dump_blk_mask, ##__VA_ARGS__, SDE_DBG_DUMP_DATA_LIMITER)
/**
* SDE_DBG_EVT_CTRL - trigger a different driver events
* event: event that trigger different behavior in the driver
*/
#define SDE_DBG_CTRL(...) sde_dbg_ctrl(__func__, ##__VA_ARGS__, \
SDE_DBG_DUMP_DATA_LIMITER)
/**
* sde_mini_dump_add_va_region - add required va memory region to minidump.
* @size: size of the memory region to be added
* @name: minidump partition name
* @virt_addr: pointer to memory region
* Returns: none
*/
void sde_mini_dump_add_va_region(const char *name, u32 size, void *virt_addr);
/**
* sde_evtlog_init - allocate a new event log object
* Returns: evtlog or -ERROR
*/
struct sde_dbg_evtlog *sde_evtlog_init(void);
/**
* sde_reglog_init - allocate a new reg log object
* Returns: reglog or -ERROR
*/
struct sde_dbg_reglog *sde_reglog_init(void);
/**
* sde_evtlog_destroy - destroy previously allocated event log
* @evtlog: pointer to evtlog
* Returns: none
*/
void sde_evtlog_destroy(struct sde_dbg_evtlog *evtlog);
/**
* sde_reglog_destroy - destroy previously allocated reg log
* @reglog: pointer to reglog
* Returns: none
*/
void sde_reglog_destroy(struct sde_dbg_reglog *reglog);
/**
* sde_evtlog_log - log an entry into the event log.
* log collection may be enabled/disabled entirely via debugfs
* log area collection may be filtered by user provided flags via debugfs.
* @evtlog: pointer to evtlog
* @name: function name of call site
* @line: line number of call site
* @flag: log area filter flag checked against user's debugfs request
* Returns: none
*/
void sde_evtlog_log(struct sde_dbg_evtlog *evtlog, const char *name, int line,
int flag, ...);
/**
* sde_reglog_log - log an entry into the reg log.
* log collection may be enabled/disabled entirely via debugfs
* log area collection may be filtered by user provided flags via debugfs.
* @reglog: pointer to evtlog
* Returns: none
*/
void sde_reglog_log(u8 blk_id, u32 val, u32 addr);
/**
* sde_evtlog_dump_to_buffer - parse one line of evtlog to a given buffer
* @evtlog: pointer to evtlog
* @evtlog_buf: buffer to store evtlog
* @evtlog_buf_size: lenght of the buffer
* @update_last_entry: whether update last dump marker
* @full_dump: 1, print the whole evtlog captured; 0, print last 256 lines of log
* Returns: log size
*/
ssize_t sde_evtlog_dump_to_buffer(struct sde_dbg_evtlog *evtlog,
char *evtlog_buf, ssize_t evtlog_buf_size,
bool update_last_entry, bool full_dump);
/**
* sde_evtlog_count - count the current log size for print
* @evtlog: pointer to evtlog
* Returns: log size
*/
u32 sde_evtlog_count(struct sde_dbg_evtlog *evtlog);
/**
* sde_evtlog_is_enabled - check whether log collection is enabled for given
* event log and log area flag
* @evtlog: pointer to evtlog
* @flag: log area filter flag
* Returns: none
*/
bool sde_evtlog_is_enabled(struct sde_dbg_evtlog *evtlog, u32 flag);
/**
* sde_evtlog_dump_to_buffer - print content of event log to the given buffer
* @evtlog: pointer to evtlog
* @evtlog_buf: target buffer to print into
* @evtlog_buf_size: size of target buffer
* @update_last_entry: whether or not to stop at most recent entry
* @full_dump: whether to dump full or to limit print entries
* Returns: number of bytes written to buffer
*/
ssize_t sde_evtlog_dump_to_buffer(struct sde_dbg_evtlog *evtlog,
char *evtlog_buf, ssize_t evtlog_buf_size,
bool update_last_entry, bool full_dump);
/**
* sde_dbg_init_dbg_buses - initialize debug bus dumping support for the chipset
* @hw_rev: Chipset revision
*/
void sde_dbg_init_dbg_buses(u32 hw_rev);
/**
* sde_dbg_init - initialize global sde debug facilities: evtlog, regdump
* @dev: device handle
* Returns: 0 or -ERROR
*/
int sde_dbg_init(struct device *dev);
/**
* sde_dbg_debugfs_register - register entries at the given debugfs dir
* @dev: pointer to device
* Returns: 0 or -ERROR
*/
int sde_dbg_debugfs_register(struct device *dev);
/**
* sde_dbg_destroy - destroy the global sde debug facilities
* Returns: none
*/
void sde_dbg_destroy(void);
/**
* sde_dbg_dump - trigger dumping of all sde_dbg facilities
* @queue_work: whether to queue the dumping work to the work_struct
* @name: string indicating origin of dump
* @dump_blk_mask: mask of all the hw blk-ids that has to be dumped
* @va_args: list of named register dump ranges and regions to dump, as
* registered previously through sde_dbg_reg_register_base and
* sde_dbg_reg_register_dump_range.
* Including the special name "panic" will trigger a panic after
* the dumping work has completed.
* Returns: none
*/
void sde_dbg_dump(enum sde_dbg_dump_context mode, const char *name, u64 dump_blk_mask, ...);
/**
* sde_dbg_ctrl - trigger specific actions for the driver with debugging
* purposes. Those actions need to be enabled by the debugfs entry
* so the driver executes those actions in the corresponding calls.
* @va_args: list of actions to trigger
* Returns: none
*/
void sde_dbg_ctrl(const char *name, ...);
/**
* sde_dbg_reg_register_base - register a hw register address section for later
* dumping. call this before calling sde_dbg_reg_register_dump_range
* to be able to specify sub-ranges within the base hw range.
* @name: name of base region
* @base: base pointer of region
* @max_offset: length of region
* @phys_addr: physical address of region
* @blk_id: hw block id
* Returns: 0 or -ERROR
*/
int sde_dbg_reg_register_base(const char *name, void __iomem *base,
size_t max_offset, unsigned long phys_addr, u64 blk_id);
/**
* sde_dbg_reg_register_cb - register a hw register callback for later
* dumping.
* @name: name of base region
* @cb: callback of external region
* @cb_ptr: private pointer of external region
* Returns: 0 or -ERROR
*/
int sde_dbg_reg_register_cb(const char *name, void (*cb)(void *), void *ptr);
/**
* sde_dbg_reg_unregister_cb - register a hw unregister callback for later
* dumping.
* @name: name of base region
* @cb: callback of external region
* @cb_ptr: private pointer of external region
* Returns: None
*/
void sde_dbg_reg_unregister_cb(const char *name, void (*cb)(void *), void *ptr);
/**
* sde_dbg_reg_register_dump_range - register a hw register sub-region for
* later register dumping associated with base specified by
* sde_dbg_reg_register_base
* @base_name: name of base region
* @range_name: name of sub-range within base region
* @offset_start: sub-range's start offset from base's base pointer
* @offset_end: sub-range's end offset from base's base pointer
* @xin_id: xin id
* Returns: none
*/
void sde_dbg_reg_register_dump_range(const char *base_name,
const char *range_name, u32 offset_start, u32 offset_end,
uint32_t xin_id);
/**
* sde_dbg_dsi_ctrl_register - register a dsi ctrl for debugbus dumping
* @base: iomem base address for dsi controller
* @name: name of the dsi controller
* Returns: 0 or -ERROR
*/
int sde_dbg_dsi_ctrl_register(void __iomem *base, const char *name);
/**
* sde_dbg_set_sde_top_offset - set the target specific offset from mdss base
* address of the top registers. Used for accessing debug bus controls.
* @blk_off: offset from mdss base of the top block
*/
void sde_dbg_set_sde_top_offset(u32 blk_off);
/**
* sde_dbg_set_hw_ownership_status - set the VM HW ownership status
* @enable: flag to control HW ownership status
*/
void sde_dbg_set_hw_ownership_status(bool enable);
/**
* sde_evtlog_set_filter - update evtlog filtering
* @evtlog: pointer to evtlog
* @filter: pointer to optional function name filter, set to NULL to disable
*/
void sde_evtlog_set_filter(struct sde_dbg_evtlog *evtlog, char *filter);
/**
* sde_evtlog_get_filter - query configured evtlog filters
* @evtlog: pointer to evtlog
* @index: filter index to retrieve
* @buf: pointer to output filter buffer
* @bufsz: size of output filter buffer
* Returns: zero if a filter string was returned
*/
int sde_evtlog_get_filter(struct sde_dbg_evtlog *evtlog, int index,
char *buf, size_t bufsz);
#ifndef CONFIG_DRM_SDE_RSC
static inline void sde_rsc_debug_dump(u32 mux_sel)
{
}
#else
/**
* sde_rsc_debug_dump - sde rsc debug dump status
* @mux_sel:» select mux on rsc debug bus
*/
void sde_rsc_debug_dump(u32 mux_sel);
#endif
/**
* sde_dbg_update_dump_mode - update dump mode to in_coredump mode if devcoredump
* fueature is enabled. Default dump mode is in_mem, if HW recovery feature is
* enabled, this function will be called to set dump mode to in_coredump option.
* @enable_coredump: if enable_coredump is true, update dump mode to in_coredump,
* otherwise reset the dump mode to default mode.
*/
void sde_dbg_update_dump_mode(bool enable_coredump);
#endif /* SDE_DBG_H_ */