1 | /* SPDX-License-Identifier: MIT */ |
2 | /* |
3 | * Copyright © 2014-2019 Intel Corporation |
4 | */ |
5 | |
6 | #ifndef _INTEL_GUC_LOG_H_ |
7 | #define _INTEL_GUC_LOG_H_ |
8 | |
9 | #include <linux/mutex.h> |
10 | #include <linux/relay.h> |
11 | #include <linux/workqueue.h> |
12 | |
13 | #include "intel_guc_fwif.h" |
14 | #include "i915_gem.h" |
15 | |
16 | struct intel_guc; |
17 | |
18 | /* |
19 | * While we're using plain log level in i915, GuC controls are much more... |
20 | * "elaborate"? We have a couple of bits for verbosity, separate bit for actual |
21 | * log enabling, and separate bit for default logging - which "conveniently" |
22 | * ignores the enable bit. |
23 | */ |
24 | #define GUC_LOG_LEVEL_DISABLED 0 |
25 | #define GUC_LOG_LEVEL_NON_VERBOSE 1 |
26 | #define GUC_LOG_LEVEL_IS_ENABLED(x) ((x) > GUC_LOG_LEVEL_DISABLED) |
27 | #define GUC_LOG_LEVEL_IS_VERBOSE(x) ((x) > GUC_LOG_LEVEL_NON_VERBOSE) |
28 | #define GUC_LOG_LEVEL_TO_VERBOSITY(x) ({ \ |
29 | typeof(x) _x = (x); \ |
30 | GUC_LOG_LEVEL_IS_VERBOSE(_x) ? _x - 2 : 0; \ |
31 | }) |
32 | #define GUC_VERBOSITY_TO_LOG_LEVEL(x) ((x) + 2) |
33 | #define GUC_LOG_LEVEL_MAX GUC_VERBOSITY_TO_LOG_LEVEL(GUC_LOG_VERBOSITY_MAX) |
34 | |
35 | enum { |
36 | GUC_LOG_SECTIONS_CRASH, |
37 | GUC_LOG_SECTIONS_DEBUG, |
38 | GUC_LOG_SECTIONS_CAPTURE, |
39 | GUC_LOG_SECTIONS_LIMIT |
40 | }; |
41 | |
42 | struct intel_guc_log { |
43 | u32 level; |
44 | |
45 | /* Allocation settings */ |
46 | struct { |
47 | s32 bytes; /* Size in bytes */ |
48 | s32 units; /* GuC API units - 1MB or 4KB */ |
49 | s32 count; /* Number of API units */ |
50 | u32 flag; /* GuC API units flag */ |
51 | } sizes[GUC_LOG_SECTIONS_LIMIT]; |
52 | bool sizes_initialised; |
53 | |
54 | /* Combined buffer allocation */ |
55 | struct i915_vma *vma; |
56 | void *buf_addr; |
57 | |
58 | /* RelayFS support */ |
59 | struct { |
60 | bool buf_in_use; |
61 | bool started; |
62 | struct work_struct flush_work; |
63 | struct rchan *channel; |
64 | struct mutex lock; |
65 | u32 full_count; |
66 | } relay; |
67 | |
68 | /* logging related stats */ |
69 | struct { |
70 | u32 sampled_overflow; |
71 | u32 overflow; |
72 | u32 flush; |
73 | } stats[GUC_MAX_LOG_BUFFER]; |
74 | }; |
75 | |
76 | void intel_guc_log_init_early(struct intel_guc_log *log); |
77 | bool intel_guc_check_log_buf_overflow(struct intel_guc_log *log, enum guc_log_buffer_type type, |
78 | unsigned int full_cnt); |
79 | unsigned int intel_guc_get_log_buffer_size(struct intel_guc_log *log, |
80 | enum guc_log_buffer_type type); |
81 | size_t intel_guc_get_log_buffer_offset(struct intel_guc_log *log, enum guc_log_buffer_type type); |
82 | int intel_guc_log_create(struct intel_guc_log *log); |
83 | void intel_guc_log_destroy(struct intel_guc_log *log); |
84 | |
85 | int intel_guc_log_set_level(struct intel_guc_log *log, u32 level); |
86 | bool intel_guc_log_relay_created(const struct intel_guc_log *log); |
87 | int intel_guc_log_relay_open(struct intel_guc_log *log); |
88 | int intel_guc_log_relay_start(struct intel_guc_log *log); |
89 | void intel_guc_log_relay_flush(struct intel_guc_log *log); |
90 | void intel_guc_log_relay_close(struct intel_guc_log *log); |
91 | |
92 | void intel_guc_log_handle_flush_event(struct intel_guc_log *log); |
93 | |
94 | static inline u32 intel_guc_log_get_level(struct intel_guc_log *log) |
95 | { |
96 | return log->level; |
97 | } |
98 | |
99 | void intel_guc_log_info(struct intel_guc_log *log, struct drm_printer *p); |
100 | int intel_guc_log_dump(struct intel_guc_log *log, struct drm_printer *p, |
101 | bool dump_load_err); |
102 | |
103 | u32 intel_guc_log_section_size_capture(struct intel_guc_log *log); |
104 | |
105 | #endif |
106 | |