1  /* SPDX-License-Identifier: GPL-2.0 */
2  /*
3   * Support for Intel Camera Imaging ISP subsystem.
4   * Copyright (c) 2015, Intel Corporation.
5   *
6   * This program is free software; you can redistribute it and/or modify it
7   * under the terms and conditions of the GNU General Public License,
8   * version 2, as published by the Free Software Foundation.
9   *
10   * This program is distributed in the hope it will be useful, but WITHOUT
11   * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12   * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
13   * more details.
14   */
15  
16  #ifndef __CSS_TRACE_H_
17  #define __CSS_TRACE_H_
18  
19  #include <type_support.h>
20  #include "sh_css_internal.h"	/* for SH_CSS_MAX_SP_THREADS */
21  
22  /*
23  	structs and constants for tracing
24  */
25  
26  /* one tracer item: major, minor and counter. The counter value can be used for GP data */
27  struct trace_item_t {
28  	u8   major;
29  	u8   minor;
30  	u16  counter;
31  };
32  
33  #define MAX_SCRATCH_DATA	4
34  #define MAX_CMD_DATA		2
35  
36  /* trace header: holds the version and the topology of the tracer. */
37  struct trace_header_t {
38  	/* 1st dword: descriptor */
39  	u8   version;
40  	u8   max_threads;
41  	u16  max_tracer_points;
42  	/* 2nd field: command + data */
43  	/* 2nd dword */
44  	u32  command;
45  	/* 3rd & 4th dword */
46  	u32  data[MAX_CMD_DATA];
47  	/* 3rd field: debug pointer */
48  	/* 5th & 6th dword: debug pointer mechanism */
49  	u32  debug_ptr_signature;
50  	u32  debug_ptr_value;
51  	/* Rest of the header: status & scratch data */
52  	u8   thr_status_byte[SH_CSS_MAX_SP_THREADS];
53  	u16  thr_status_word[SH_CSS_MAX_SP_THREADS];
54  	u32  thr_status_dword[SH_CSS_MAX_SP_THREADS];
55  	u32  scratch_debug[MAX_SCRATCH_DATA];
56  };
57  
58  /* offsets for master_port read/write */
59  #define HDR_HDR_OFFSET              0	/* offset of the header */
60  #define HDR_COMMAND_OFFSET          offsetof(struct trace_header_t, command)
61  #define HDR_DATA_OFFSET             offsetof(struct trace_header_t, data)
62  #define HDR_DEBUG_SIGNATURE_OFFSET  offsetof(struct trace_header_t, debug_ptr_signature)
63  #define HDR_DEBUG_POINTER_OFFSET    offsetof(struct trace_header_t, debug_ptr_value)
64  #define HDR_STATUS_OFFSET           offsetof(struct trace_header_t, thr_status_byte)
65  #define HDR_STATUS_OFFSET_BYTE      offsetof(struct trace_header_t, thr_status_byte)
66  #define HDR_STATUS_OFFSET_WORD      offsetof(struct trace_header_t, thr_status_word)
67  #define HDR_STATUS_OFFSET_DWORD     offsetof(struct trace_header_t, thr_status_dword)
68  #define HDR_STATUS_OFFSET_SCRATCH   offsetof(struct trace_header_t, scratch_debug)
69  
70  /*
71  Trace version history:
72   1: initial version, hdr = descr, command & ptr.
73   2: added ISP + 24-bit fields.
74   3: added thread ID.
75   4: added status in header.
76  */
77  #define TRACER_VER			4
78  
79  #define TRACE_BUFF_ADDR       0xA000
80  #define TRACE_BUFF_SIZE       0x1000	/* 4K allocated */
81  
82  #define TRACE_ENABLE_SP0 0
83  #define TRACE_ENABLE_SP1 0
84  #define TRACE_ENABLE_ISP 0
85  
86  enum TRACE_CORE_ID {
87  	TRACE_SP0_ID,
88  	TRACE_SP1_ID,
89  	TRACE_ISP_ID
90  };
91  
92  /* TODO: add timing format? */
93  enum TRACE_DUMP_FORMAT {
94  	TRACE_DUMP_FORMAT_POINT_NO_TID,
95  	TRACE_DUMP_FORMAT_VALUE24,
96  	TRACE_DUMP_FORMAT_VALUE24_TIMING,
97  	TRACE_DUMP_FORMAT_VALUE24_TIMING_DELTA,
98  	TRACE_DUMP_FORMAT_POINT
99  };
100  
101  /* currently divided as follows:*/
102  #if (TRACE_ENABLE_SP0 + TRACE_ENABLE_SP1 + TRACE_ENABLE_ISP == 3)
103  /* can be divided as needed */
104  #define TRACE_SP0_SIZE (TRACE_BUFF_SIZE / 4)
105  #define TRACE_SP1_SIZE (TRACE_BUFF_SIZE / 4)
106  #define TRACE_ISP_SIZE (TRACE_BUFF_SIZE / 2)
107  #elif (TRACE_ENABLE_SP0 + TRACE_ENABLE_SP1 + TRACE_ENABLE_ISP == 2)
108  #if TRACE_ENABLE_SP0
109  #define TRACE_SP0_SIZE (TRACE_BUFF_SIZE / 2)
110  #else
111  #define TRACE_SP0_SIZE (0)
112  #endif
113  #if TRACE_ENABLE_SP1
114  #define TRACE_SP1_SIZE (TRACE_BUFF_SIZE / 2)
115  #else
116  #define TRACE_SP1_SIZE (0)
117  #endif
118  #if TRACE_ENABLE_ISP
119  #define TRACE_ISP_SIZE (TRACE_BUFF_SIZE / 2)
120  #else
121  #define TRACE_ISP_SIZE (0)
122  #endif
123  #elif (TRACE_ENABLE_SP0 + TRACE_ENABLE_SP1 + TRACE_ENABLE_ISP == 1)
124  #if TRACE_ENABLE_SP0
125  #define TRACE_SP0_SIZE (TRACE_BUFF_SIZE)
126  #else
127  #define TRACE_SP0_SIZE (0)
128  #endif
129  #if TRACE_ENABLE_SP1
130  #define TRACE_SP1_SIZE (TRACE_BUFF_SIZE)
131  #else
132  #define TRACE_SP1_SIZE (0)
133  #endif
134  #if TRACE_ENABLE_ISP
135  #define TRACE_ISP_SIZE (TRACE_BUFF_SIZE)
136  #else
137  #define TRACE_ISP_SIZE (0)
138  #endif
139  #else
140  #define TRACE_SP0_SIZE (0)
141  #define TRACE_SP1_SIZE (0)
142  #define TRACE_ISP_SIZE (0)
143  #endif
144  
145  #define TRACE_SP0_ADDR (TRACE_BUFF_ADDR)
146  #define TRACE_SP1_ADDR (TRACE_SP0_ADDR + TRACE_SP0_SIZE)
147  #define TRACE_ISP_ADDR (TRACE_SP1_ADDR + TRACE_SP1_SIZE)
148  
149  /* check if it's a legal division */
150  #if (TRACE_BUFF_SIZE < TRACE_SP0_SIZE + TRACE_SP1_SIZE + TRACE_ISP_SIZE)
151  #error trace sizes are not divided correctly and are above limit
152  #endif
153  
154  #define TRACE_SP0_HEADER_ADDR (TRACE_SP0_ADDR)
155  #define TRACE_SP0_HEADER_SIZE (sizeof(struct trace_header_t))
156  #define TRACE_SP0_ITEM_SIZE   (sizeof(struct trace_item_t))
157  #define TRACE_SP0_DATA_ADDR   (TRACE_SP0_HEADER_ADDR + TRACE_SP0_HEADER_SIZE)
158  #define TRACE_SP0_DATA_SIZE   (TRACE_SP0_SIZE - TRACE_SP0_HEADER_SIZE)
159  #define TRACE_SP0_MAX_POINTS  (TRACE_SP0_DATA_SIZE / TRACE_SP0_ITEM_SIZE)
160  
161  #define TRACE_SP1_HEADER_ADDR (TRACE_SP1_ADDR)
162  #define TRACE_SP1_HEADER_SIZE (sizeof(struct trace_header_t))
163  #define TRACE_SP1_ITEM_SIZE   (sizeof(struct trace_item_t))
164  #define TRACE_SP1_DATA_ADDR   (TRACE_SP1_HEADER_ADDR + TRACE_SP1_HEADER_SIZE)
165  #define TRACE_SP1_DATA_SIZE   (TRACE_SP1_SIZE - TRACE_SP1_HEADER_SIZE)
166  #define TRACE_SP1_MAX_POINTS  (TRACE_SP1_DATA_SIZE / TRACE_SP1_ITEM_SIZE)
167  
168  #define TRACE_ISP_HEADER_ADDR (TRACE_ISP_ADDR)
169  #define TRACE_ISP_HEADER_SIZE (sizeof(struct trace_header_t))
170  #define TRACE_ISP_ITEM_SIZE   (sizeof(struct trace_item_t))
171  #define TRACE_ISP_DATA_ADDR   (TRACE_ISP_HEADER_ADDR + TRACE_ISP_HEADER_SIZE)
172  #define TRACE_ISP_DATA_SIZE   (TRACE_ISP_SIZE - TRACE_ISP_HEADER_SIZE)
173  #define TRACE_ISP_MAX_POINTS  (TRACE_ISP_DATA_SIZE / TRACE_ISP_ITEM_SIZE)
174  
175  /* common majors */
176  /* SP0 */
177  #define MAJOR_MAIN              1
178  #define MAJOR_ISP_STAGE_ENTRY   2
179  #define MAJOR_DMA_PRXY          3
180  #define MAJOR_START_ISP         4
181  /* SP1 */
182  #define MAJOR_OBSERVER_ISP0_EVENT          21
183  #define MAJOR_OBSERVER_OUTPUT_FORM_EVENT   22
184  #define MAJOR_OBSERVER_OUTPUT_SCAL_EVENT   23
185  #define MAJOR_OBSERVER_IF_ACK              24
186  #define MAJOR_OBSERVER_SP0_EVENT           25
187  #define MAJOR_OBSERVER_SP_TERMINATE_EVENT  26
188  #define MAJOR_OBSERVER_DMA_ACK             27
189  #define MAJOR_OBSERVER_ACC_ACK             28
190  
191  #define DEBUG_PTR_SIGNATURE     0xABCD	/* signature for the debug parameter pointer */
192  
193  /* command codes (1st byte) */
194  typedef enum {
195  	CMD_SET_ONE_MAJOR = 1,		/* mask in one major. 2nd byte in the command is the major code */
196  	CMD_UNSET_ONE_MAJOR = 2,	/* mask out one major. 2nd byte in the command is the major code */
197  	CMD_SET_ALL_MAJORS = 3,		/* set the major print mask. the full mask is in the data DWORD */
198  	CMD_SET_VERBOSITY = 4		/* set verbosity level */
199  } DBG_commands;
200  
201  /* command signature */
202  #define CMD_SIGNATURE	0xAABBCC00
203  
204  /* shared macros in traces infrastructure */
205  /* increment the pointer cyclicly */
206  #define DBG_NEXT_ITEM(x, max_items) (((x + 1) >= max_items) ? 0 : x + 1)
207  #define DBG_PREV_ITEM(x, max_items) ((x) ? x - 1 : max_items - 1)
208  
209  #define FIELD_MASK(width) (((1 << (width)) - 1))
210  #define FIELD_PACK(value, mask, offset) (((value) & (mask)) << (offset))
211  #define FIELD_UNPACK(value, mask, offset) (((value) >> (offset)) & (mask))
212  
213  #define FIELD_VALUE_OFFSET		(0)
214  #define FIELD_VALUE_WIDTH		(16)
215  #define FIELD_VALUE_MASK		FIELD_MASK(FIELD_VALUE_WIDTH)
216  #define FIELD_VALUE_PACK(f)		FIELD_PACK(f, FIELD_VALUE_MASK, FIELD_VALUE_OFFSET)
217  #define FIELD_VALUE_UNPACK(f)		FIELD_UNPACK(f, FIELD_VALUE_MASK, FIELD_VALUE_OFFSET)
218  
219  #define FIELD_MINOR_OFFSET		(FIELD_VALUE_OFFSET + FIELD_VALUE_WIDTH)
220  #define FIELD_MINOR_WIDTH		(8)
221  #define FIELD_MINOR_MASK		FIELD_MASK(FIELD_MINOR_WIDTH)
222  #define FIELD_MINOR_PACK(f)		FIELD_PACK(f, FIELD_MINOR_MASK, FIELD_MINOR_OFFSET)
223  #define FIELD_MINOR_UNPACK(f)		FIELD_UNPACK(f, FIELD_MINOR_MASK, FIELD_MINOR_OFFSET)
224  
225  #define FIELD_MAJOR_OFFSET		(FIELD_MINOR_OFFSET + FIELD_MINOR_WIDTH)
226  #define FIELD_MAJOR_WIDTH		(5)
227  #define FIELD_MAJOR_MASK		FIELD_MASK(FIELD_MAJOR_WIDTH)
228  #define FIELD_MAJOR_PACK(f)		FIELD_PACK(f, FIELD_MAJOR_MASK, FIELD_MAJOR_OFFSET)
229  #define FIELD_MAJOR_UNPACK(f)		FIELD_UNPACK(f, FIELD_MAJOR_MASK, FIELD_MAJOR_OFFSET)
230  
231  /* for quick traces - only insertion, compatible with the regular point */
232  #define FIELD_FULL_MAJOR_WIDTH		(8)
233  #define FIELD_FULL_MAJOR_MASK		FIELD_MASK(FIELD_FULL_MAJOR_WIDTH)
234  #define FIELD_FULL_MAJOR_PACK(f)	FIELD_PACK(f, FIELD_FULL_MAJOR_MASK, FIELD_MAJOR_OFFSET)
235  
236  /* The following 2 fields are used only when FIELD_TID value is 111b.
237   * it means we don't want to use thread id, but format. In this case,
238   * the last 2 MSB bits of the major field will indicates the format
239   */
240  #define FIELD_MAJOR_W_FMT_OFFSET	FIELD_MAJOR_OFFSET
241  #define FIELD_MAJOR_W_FMT_WIDTH		(3)
242  #define FIELD_MAJOR_W_FMT_MASK		FIELD_MASK(FIELD_MAJOR_W_FMT_WIDTH)
243  #define FIELD_MAJOR_W_FMT_PACK(f)	FIELD_PACK(f, FIELD_MAJOR_W_FMT_MASK, FIELD_MAJOR_W_FMT_OFFSET)
244  #define FIELD_MAJOR_W_FMT_UNPACK(f)	FIELD_UNPACK(f, FIELD_MAJOR_W_FMT_MASK, FIELD_MAJOR_W_FMT_OFFSET)
245  
246  #define FIELD_FORMAT_OFFSET		(FIELD_MAJOR_OFFSET + FIELD_MAJOR_W_FMT_WIDTH)
247  #define FIELD_FORMAT_WIDTH		(2)
248  #define FIELD_FORMAT_MASK		FIELD_MASK(FIELD_MAJOR_W_FMT_WIDTH)
249  #define FIELD_FORMAT_PACK(f)		FIELD_PACK(f, FIELD_FORMAT_MASK, FIELD_FORMAT_OFFSET)
250  #define FIELD_FORMAT_UNPACK(f)		FIELD_UNPACK(f, FIELD_FORMAT_MASK, FIELD_FORMAT_OFFSET)
251  
252  #define FIELD_TID_SEL_FORMAT_PAT	(7)
253  
254  #define FIELD_TID_OFFSET		(FIELD_MAJOR_OFFSET + FIELD_MAJOR_WIDTH)
255  #define FIELD_TID_WIDTH			(3)
256  #define FIELD_TID_MASK			FIELD_MASK(FIELD_TID_WIDTH)
257  #define FIELD_TID_PACK(f)		FIELD_PACK(f, FIELD_TID_MASK, FIELD_TID_OFFSET)
258  #define FIELD_TID_UNPACK(f)		FIELD_UNPACK(f, FIELD_TID_MASK, FIELD_TID_OFFSET)
259  
260  #define FIELD_VALUE_24_OFFSET		(0)
261  #define FIELD_VALUE_24_WIDTH		(24)
262  #define FIELD_VALUE_24_MASK		FIELD_MASK(FIELD_VALUE_24_WIDTH)
263  #define FIELD_VALUE_24_PACK(f)		FIELD_PACK(f, FIELD_VALUE_24_MASK, FIELD_VALUE_24_OFFSET)
264  #define FIELD_VALUE_24_UNPACK(f)	FIELD_UNPACK(f, FIELD_VALUE_24_MASK, FIELD_VALUE_24_OFFSET)
265  
266  #define PACK_TRACEPOINT(tid, major, minor, value)	\
267  	(FIELD_TID_PACK(tid) | FIELD_MAJOR_PACK(major) | FIELD_MINOR_PACK(minor) | FIELD_VALUE_PACK(value))
268  
269  #define PACK_QUICK_TRACEPOINT(major, minor)	\
270  	(FIELD_FULL_MAJOR_PACK(major) | FIELD_MINOR_PACK(minor))
271  
272  #define PACK_FORMATTED_TRACEPOINT(format, major, minor, value)	\
273  	(FIELD_TID_PACK(FIELD_TID_SEL_FORMAT_PAT) | FIELD_FORMAT_PACK(format) | FIELD_MAJOR_PACK(major) | FIELD_MINOR_PACK(minor) | FIELD_VALUE_PACK(value))
274  
275  #define PACK_TRACE_VALUE24(major, value)	\
276  	(FIELD_TID_PACK(FIELD_TID_SEL_FORMAT_PAT) | FIELD_MAJOR_PACK(major) | FIELD_VALUE_24_PACK(value))
277  
278  #endif /* __CSS_TRACE_H_ */
279