1*b843c749SSergey Zigachev /*
2*b843c749SSergey Zigachev * Copyright 2015 Advanced Micro Devices, Inc.
3*b843c749SSergey Zigachev *
4*b843c749SSergey Zigachev * Permission is hereby granted, free of charge, to any person obtaining a
5*b843c749SSergey Zigachev * copy of this software and associated documentation files (the "Software"),
6*b843c749SSergey Zigachev * to deal in the Software without restriction, including without limitation
7*b843c749SSergey Zigachev * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8*b843c749SSergey Zigachev * and/or sell copies of the Software, and to permit persons to whom the
9*b843c749SSergey Zigachev * Software is furnished to do so, subject to the following conditions:
10*b843c749SSergey Zigachev *
11*b843c749SSergey Zigachev * The above copyright notice and this permission notice shall be included in
12*b843c749SSergey Zigachev * all copies or substantial portions of the Software.
13*b843c749SSergey Zigachev *
14*b843c749SSergey Zigachev * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15*b843c749SSergey Zigachev * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16*b843c749SSergey Zigachev * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17*b843c749SSergey Zigachev * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18*b843c749SSergey Zigachev * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19*b843c749SSergey Zigachev * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20*b843c749SSergey Zigachev * OTHER DEALINGS IN THE SOFTWARE.
21*b843c749SSergey Zigachev *
22*b843c749SSergey Zigachev * Authors: AMD
23*b843c749SSergey Zigachev *
24*b843c749SSergey Zigachev */
25*b843c749SSergey Zigachev
26*b843c749SSergey Zigachev /**
27*b843c749SSergey Zigachev * This file defines external dependencies of Display Core.
28*b843c749SSergey Zigachev */
29*b843c749SSergey Zigachev
30*b843c749SSergey Zigachev #ifndef __DM_SERVICES_H__
31*b843c749SSergey Zigachev
32*b843c749SSergey Zigachev #define __DM_SERVICES_H__
33*b843c749SSergey Zigachev
34*b843c749SSergey Zigachev /* TODO: remove when DC is complete. */
35*b843c749SSergey Zigachev #include "dm_services_types.h"
36*b843c749SSergey Zigachev #include "logger_interface.h"
37*b843c749SSergey Zigachev #include "link_service_types.h"
38*b843c749SSergey Zigachev
39*b843c749SSergey Zigachev #undef DEPRECATED
40*b843c749SSergey Zigachev
41*b843c749SSergey Zigachev irq_handler_idx dm_register_interrupt(
42*b843c749SSergey Zigachev struct dc_context *ctx,
43*b843c749SSergey Zigachev struct dc_interrupt_params *int_params,
44*b843c749SSergey Zigachev interrupt_handler ih,
45*b843c749SSergey Zigachev void *handler_args);
46*b843c749SSergey Zigachev
47*b843c749SSergey Zigachev
48*b843c749SSergey Zigachev /*
49*b843c749SSergey Zigachev *
50*b843c749SSergey Zigachev * GPU registers access
51*b843c749SSergey Zigachev *
52*b843c749SSergey Zigachev */
53*b843c749SSergey Zigachev
54*b843c749SSergey Zigachev /* enable for debugging new code, this adds 50k to the driver size. */
55*b843c749SSergey Zigachev /* #define DM_CHECK_ADDR_0 */
56*b843c749SSergey Zigachev
57*b843c749SSergey Zigachev #define dm_read_reg(ctx, address) \
58*b843c749SSergey Zigachev dm_read_reg_func(ctx, address, __func__)
59*b843c749SSergey Zigachev
dm_read_reg_func(const struct dc_context * ctx,uint32_t address,const char * func_name)60*b843c749SSergey Zigachev static inline uint32_t dm_read_reg_func(
61*b843c749SSergey Zigachev const struct dc_context *ctx,
62*b843c749SSergey Zigachev uint32_t address,
63*b843c749SSergey Zigachev const char *func_name)
64*b843c749SSergey Zigachev {
65*b843c749SSergey Zigachev uint32_t value;
66*b843c749SSergey Zigachev #ifdef DM_CHECK_ADDR_0
67*b843c749SSergey Zigachev if (address == 0) {
68*b843c749SSergey Zigachev DC_ERR("invalid register read; address = 0\n");
69*b843c749SSergey Zigachev return 0;
70*b843c749SSergey Zigachev }
71*b843c749SSergey Zigachev #endif
72*b843c749SSergey Zigachev value = cgs_read_register(ctx->cgs_device, address);
73*b843c749SSergey Zigachev
74*b843c749SSergey Zigachev return value;
75*b843c749SSergey Zigachev }
76*b843c749SSergey Zigachev
77*b843c749SSergey Zigachev #define dm_write_reg(ctx, address, value) \
78*b843c749SSergey Zigachev dm_write_reg_func(ctx, address, value, __func__)
79*b843c749SSergey Zigachev
dm_write_reg_func(const struct dc_context * ctx,uint32_t address,uint32_t value,const char * func_name)80*b843c749SSergey Zigachev static inline void dm_write_reg_func(
81*b843c749SSergey Zigachev const struct dc_context *ctx,
82*b843c749SSergey Zigachev uint32_t address,
83*b843c749SSergey Zigachev uint32_t value,
84*b843c749SSergey Zigachev const char *func_name)
85*b843c749SSergey Zigachev {
86*b843c749SSergey Zigachev #ifdef DM_CHECK_ADDR_0
87*b843c749SSergey Zigachev if (address == 0) {
88*b843c749SSergey Zigachev DC_ERR("invalid register write. address = 0");
89*b843c749SSergey Zigachev return;
90*b843c749SSergey Zigachev }
91*b843c749SSergey Zigachev #endif
92*b843c749SSergey Zigachev cgs_write_register(ctx->cgs_device, address, value);
93*b843c749SSergey Zigachev }
94*b843c749SSergey Zigachev
dm_read_index_reg(const struct dc_context * ctx,enum cgs_ind_reg addr_space,uint32_t index)95*b843c749SSergey Zigachev static inline uint32_t dm_read_index_reg(
96*b843c749SSergey Zigachev const struct dc_context *ctx,
97*b843c749SSergey Zigachev enum cgs_ind_reg addr_space,
98*b843c749SSergey Zigachev uint32_t index)
99*b843c749SSergey Zigachev {
100*b843c749SSergey Zigachev return cgs_read_ind_register(ctx->cgs_device, addr_space, index);
101*b843c749SSergey Zigachev }
102*b843c749SSergey Zigachev
dm_write_index_reg(const struct dc_context * ctx,enum cgs_ind_reg addr_space,uint32_t index,uint32_t value)103*b843c749SSergey Zigachev static inline void dm_write_index_reg(
104*b843c749SSergey Zigachev const struct dc_context *ctx,
105*b843c749SSergey Zigachev enum cgs_ind_reg addr_space,
106*b843c749SSergey Zigachev uint32_t index,
107*b843c749SSergey Zigachev uint32_t value)
108*b843c749SSergey Zigachev {
109*b843c749SSergey Zigachev cgs_write_ind_register(ctx->cgs_device, addr_space, index, value);
110*b843c749SSergey Zigachev }
111*b843c749SSergey Zigachev
get_reg_field_value_ex(uint32_t reg_value,uint32_t mask,uint8_t shift)112*b843c749SSergey Zigachev static inline uint32_t get_reg_field_value_ex(
113*b843c749SSergey Zigachev uint32_t reg_value,
114*b843c749SSergey Zigachev uint32_t mask,
115*b843c749SSergey Zigachev uint8_t shift)
116*b843c749SSergey Zigachev {
117*b843c749SSergey Zigachev return (mask & reg_value) >> shift;
118*b843c749SSergey Zigachev }
119*b843c749SSergey Zigachev
120*b843c749SSergey Zigachev #define get_reg_field_value(reg_value, reg_name, reg_field)\
121*b843c749SSergey Zigachev get_reg_field_value_ex(\
122*b843c749SSergey Zigachev (reg_value),\
123*b843c749SSergey Zigachev reg_name ## __ ## reg_field ## _MASK,\
124*b843c749SSergey Zigachev reg_name ## __ ## reg_field ## __SHIFT)
125*b843c749SSergey Zigachev
set_reg_field_value_ex(uint32_t reg_value,uint32_t value,uint32_t mask,uint8_t shift)126*b843c749SSergey Zigachev static inline uint32_t set_reg_field_value_ex(
127*b843c749SSergey Zigachev uint32_t reg_value,
128*b843c749SSergey Zigachev uint32_t value,
129*b843c749SSergey Zigachev uint32_t mask,
130*b843c749SSergey Zigachev uint8_t shift)
131*b843c749SSergey Zigachev {
132*b843c749SSergey Zigachev ASSERT(mask != 0);
133*b843c749SSergey Zigachev return (reg_value & ~mask) | (mask & (value << shift));
134*b843c749SSergey Zigachev }
135*b843c749SSergey Zigachev
136*b843c749SSergey Zigachev #define set_reg_field_value(reg_value, value, reg_name, reg_field)\
137*b843c749SSergey Zigachev (reg_value) = set_reg_field_value_ex(\
138*b843c749SSergey Zigachev (reg_value),\
139*b843c749SSergey Zigachev (value),\
140*b843c749SSergey Zigachev reg_name ## __ ## reg_field ## _MASK,\
141*b843c749SSergey Zigachev reg_name ## __ ## reg_field ## __SHIFT)
142*b843c749SSergey Zigachev
143*b843c749SSergey Zigachev uint32_t generic_reg_update_ex(const struct dc_context *ctx,
144*b843c749SSergey Zigachev uint32_t addr, uint32_t reg_val, int n,
145*b843c749SSergey Zigachev uint8_t shift1, uint32_t mask1, uint32_t field_value1, ...);
146*b843c749SSergey Zigachev
147*b843c749SSergey Zigachev #define FD(reg_field) reg_field ## __SHIFT, \
148*b843c749SSergey Zigachev reg_field ## _MASK
149*b843c749SSergey Zigachev
150*b843c749SSergey Zigachev /*
151*b843c749SSergey Zigachev * return number of poll before condition is met
152*b843c749SSergey Zigachev * return 0 if condition is not meet after specified time out tries
153*b843c749SSergey Zigachev */
154*b843c749SSergey Zigachev unsigned int generic_reg_wait(const struct dc_context *ctx,
155*b843c749SSergey Zigachev uint32_t addr, uint32_t mask, uint32_t shift, uint32_t condition_value,
156*b843c749SSergey Zigachev unsigned int delay_between_poll_us, unsigned int time_out_num_tries,
157*b843c749SSergey Zigachev const char *func_name, int line);
158*b843c749SSergey Zigachev
159*b843c749SSergey Zigachev
160*b843c749SSergey Zigachev /* These macros need to be used with soc15 registers in order to retrieve
161*b843c749SSergey Zigachev * the actual offset.
162*b843c749SSergey Zigachev */
163*b843c749SSergey Zigachev #define dm_write_reg_soc15(ctx, reg, inst_offset, value) \
164*b843c749SSergey Zigachev dm_write_reg_func(ctx, reg + DCE_BASE.instance[0].segment[reg##_BASE_IDX] + inst_offset, value, __func__)
165*b843c749SSergey Zigachev
166*b843c749SSergey Zigachev #define dm_read_reg_soc15(ctx, reg, inst_offset) \
167*b843c749SSergey Zigachev dm_read_reg_func(ctx, reg + DCE_BASE.instance[0].segment[reg##_BASE_IDX] + inst_offset, __func__)
168*b843c749SSergey Zigachev
169*b843c749SSergey Zigachev #define generic_reg_update_soc15(ctx, inst_offset, reg_name, n, ...)\
170*b843c749SSergey Zigachev generic_reg_update_ex(ctx, DCE_BASE.instance[0].segment[mm##reg_name##_BASE_IDX] + mm##reg_name + inst_offset, \
171*b843c749SSergey Zigachev dm_read_reg_func(ctx, mm##reg_name + DCE_BASE.instance[0].segment[mm##reg_name##_BASE_IDX] + inst_offset, __func__), \
172*b843c749SSergey Zigachev n, __VA_ARGS__)
173*b843c749SSergey Zigachev
174*b843c749SSergey Zigachev #define generic_reg_set_soc15(ctx, inst_offset, reg_name, n, ...)\
175*b843c749SSergey Zigachev generic_reg_update_ex(ctx, DCE_BASE.instance[0].segment[mm##reg_name##_BASE_IDX] + mm##reg_name + inst_offset, 0, \
176*b843c749SSergey Zigachev n, __VA_ARGS__)
177*b843c749SSergey Zigachev
178*b843c749SSergey Zigachev #define get_reg_field_value_soc15(reg_value, block, reg_num, reg_name, reg_field)\
179*b843c749SSergey Zigachev get_reg_field_value_ex(\
180*b843c749SSergey Zigachev (reg_value),\
181*b843c749SSergey Zigachev block ## reg_num ## _ ## reg_name ## __ ## reg_field ## _MASK,\
182*b843c749SSergey Zigachev block ## reg_num ## _ ## reg_name ## __ ## reg_field ## __SHIFT)
183*b843c749SSergey Zigachev
184*b843c749SSergey Zigachev #define set_reg_field_value_soc15(reg_value, value, block, reg_num, reg_name, reg_field)\
185*b843c749SSergey Zigachev (reg_value) = set_reg_field_value_ex(\
186*b843c749SSergey Zigachev (reg_value),\
187*b843c749SSergey Zigachev (value),\
188*b843c749SSergey Zigachev block ## reg_num ## _ ## reg_name ## __ ## reg_field ## _MASK,\
189*b843c749SSergey Zigachev block ## reg_num ## _ ## reg_name ## __ ## reg_field ## __SHIFT)
190*b843c749SSergey Zigachev
191*b843c749SSergey Zigachev /**************************************
192*b843c749SSergey Zigachev * Power Play (PP) interfaces
193*b843c749SSergey Zigachev **************************************/
194*b843c749SSergey Zigachev
195*b843c749SSergey Zigachev /* Gets valid clocks levels from pplib
196*b843c749SSergey Zigachev *
197*b843c749SSergey Zigachev * input: clk_type - display clk / sclk / mem clk
198*b843c749SSergey Zigachev *
199*b843c749SSergey Zigachev * output: array of valid clock levels for given type in ascending order,
200*b843c749SSergey Zigachev * with invalid levels filtered out
201*b843c749SSergey Zigachev *
202*b843c749SSergey Zigachev */
203*b843c749SSergey Zigachev bool dm_pp_get_clock_levels_by_type(
204*b843c749SSergey Zigachev const struct dc_context *ctx,
205*b843c749SSergey Zigachev enum dm_pp_clock_type clk_type,
206*b843c749SSergey Zigachev struct dm_pp_clock_levels *clk_level_info);
207*b843c749SSergey Zigachev
208*b843c749SSergey Zigachev bool dm_pp_get_clock_levels_by_type_with_latency(
209*b843c749SSergey Zigachev const struct dc_context *ctx,
210*b843c749SSergey Zigachev enum dm_pp_clock_type clk_type,
211*b843c749SSergey Zigachev struct dm_pp_clock_levels_with_latency *clk_level_info);
212*b843c749SSergey Zigachev
213*b843c749SSergey Zigachev bool dm_pp_get_clock_levels_by_type_with_voltage(
214*b843c749SSergey Zigachev const struct dc_context *ctx,
215*b843c749SSergey Zigachev enum dm_pp_clock_type clk_type,
216*b843c749SSergey Zigachev struct dm_pp_clock_levels_with_voltage *clk_level_info);
217*b843c749SSergey Zigachev
218*b843c749SSergey Zigachev bool dm_pp_notify_wm_clock_changes(
219*b843c749SSergey Zigachev const struct dc_context *ctx,
220*b843c749SSergey Zigachev struct dm_pp_wm_sets_with_clock_ranges *wm_with_clock_ranges);
221*b843c749SSergey Zigachev
222*b843c749SSergey Zigachev void dm_pp_get_funcs_rv(struct dc_context *ctx,
223*b843c749SSergey Zigachev struct pp_smu_funcs_rv *funcs);
224*b843c749SSergey Zigachev
225*b843c749SSergey Zigachev /* DAL calls this function to notify PP about completion of Mode Set.
226*b843c749SSergey Zigachev * For PP it means that current DCE clocks are those which were returned
227*b843c749SSergey Zigachev * by dc_service_pp_pre_dce_clock_change(), in the 'output' parameter.
228*b843c749SSergey Zigachev *
229*b843c749SSergey Zigachev * If the clocks are higher than before, then PP does nothing.
230*b843c749SSergey Zigachev *
231*b843c749SSergey Zigachev * If the clocks are lower than before, then PP reduces the voltage.
232*b843c749SSergey Zigachev *
233*b843c749SSergey Zigachev * \returns true - call is successful
234*b843c749SSergey Zigachev * false - call failed
235*b843c749SSergey Zigachev */
236*b843c749SSergey Zigachev bool dm_pp_apply_display_requirements(
237*b843c749SSergey Zigachev const struct dc_context *ctx,
238*b843c749SSergey Zigachev const struct dm_pp_display_configuration *pp_display_cfg);
239*b843c749SSergey Zigachev
240*b843c749SSergey Zigachev bool dm_pp_apply_power_level_change_request(
241*b843c749SSergey Zigachev const struct dc_context *ctx,
242*b843c749SSergey Zigachev struct dm_pp_power_level_change_request *level_change_req);
243*b843c749SSergey Zigachev
244*b843c749SSergey Zigachev bool dm_pp_apply_clock_for_voltage_request(
245*b843c749SSergey Zigachev const struct dc_context *ctx,
246*b843c749SSergey Zigachev struct dm_pp_clock_for_voltage_req *clock_for_voltage_req);
247*b843c749SSergey Zigachev
248*b843c749SSergey Zigachev bool dm_pp_get_static_clocks(
249*b843c749SSergey Zigachev const struct dc_context *ctx,
250*b843c749SSergey Zigachev struct dm_pp_static_clock_info *static_clk_info);
251*b843c749SSergey Zigachev
252*b843c749SSergey Zigachev /****** end of PP interfaces ******/
253*b843c749SSergey Zigachev
254*b843c749SSergey Zigachev struct persistent_data_flag {
255*b843c749SSergey Zigachev bool save_per_link;
256*b843c749SSergey Zigachev bool save_per_edid;
257*b843c749SSergey Zigachev };
258*b843c749SSergey Zigachev
259*b843c749SSergey Zigachev /* Call to write data in registry editor for persistent data storage.
260*b843c749SSergey Zigachev *
261*b843c749SSergey Zigachev * \inputs sink - identify edid/link for registry folder creation
262*b843c749SSergey Zigachev * module name - identify folders for registry
263*b843c749SSergey Zigachev * key name - identify keys within folders for registry
264*b843c749SSergey Zigachev * params - value to write in defined folder/key
265*b843c749SSergey Zigachev * size - size of the input params
266*b843c749SSergey Zigachev * flag - determine whether to save by link or edid
267*b843c749SSergey Zigachev *
268*b843c749SSergey Zigachev * \returns true - call is successful
269*b843c749SSergey Zigachev * false - call failed
270*b843c749SSergey Zigachev *
271*b843c749SSergey Zigachev * sink module key
272*b843c749SSergey Zigachev * -----------------------------------------------------------------------------
273*b843c749SSergey Zigachev * NULL NULL NULL - failure
274*b843c749SSergey Zigachev * NULL NULL - - create key with param value
275*b843c749SSergey Zigachev * under base folder
276*b843c749SSergey Zigachev * NULL - NULL - create module folder under base folder
277*b843c749SSergey Zigachev * - NULL NULL - failure
278*b843c749SSergey Zigachev * NULL - - - create key under module folder
279*b843c749SSergey Zigachev * with no edid/link identification
280*b843c749SSergey Zigachev * - NULL - - create key with param value
281*b843c749SSergey Zigachev * under base folder
282*b843c749SSergey Zigachev * - - NULL - create module folder under base folder
283*b843c749SSergey Zigachev * - - - - create key under module folder
284*b843c749SSergey Zigachev * with edid/link identification
285*b843c749SSergey Zigachev */
286*b843c749SSergey Zigachev bool dm_write_persistent_data(struct dc_context *ctx,
287*b843c749SSergey Zigachev const struct dc_sink *sink,
288*b843c749SSergey Zigachev const char *module_name,
289*b843c749SSergey Zigachev const char *key_name,
290*b843c749SSergey Zigachev void *params,
291*b843c749SSergey Zigachev unsigned int size,
292*b843c749SSergey Zigachev struct persistent_data_flag *flag);
293*b843c749SSergey Zigachev
294*b843c749SSergey Zigachev
295*b843c749SSergey Zigachev /* Call to read data in registry editor for persistent data storage.
296*b843c749SSergey Zigachev *
297*b843c749SSergey Zigachev * \inputs sink - identify edid/link for registry folder creation
298*b843c749SSergey Zigachev * module name - identify folders for registry
299*b843c749SSergey Zigachev * key name - identify keys within folders for registry
300*b843c749SSergey Zigachev * size - size of the output params
301*b843c749SSergey Zigachev * flag - determine whether it was save by link or edid
302*b843c749SSergey Zigachev *
303*b843c749SSergey Zigachev * \returns params - value read from defined folder/key
304*b843c749SSergey Zigachev * true - call is successful
305*b843c749SSergey Zigachev * false - call failed
306*b843c749SSergey Zigachev *
307*b843c749SSergey Zigachev * sink module key
308*b843c749SSergey Zigachev * -----------------------------------------------------------------------------
309*b843c749SSergey Zigachev * NULL NULL NULL - failure
310*b843c749SSergey Zigachev * NULL NULL - - read key under base folder
311*b843c749SSergey Zigachev * NULL - NULL - failure
312*b843c749SSergey Zigachev * - NULL NULL - failure
313*b843c749SSergey Zigachev * NULL - - - read key under module folder
314*b843c749SSergey Zigachev * with no edid/link identification
315*b843c749SSergey Zigachev * - NULL - - read key under base folder
316*b843c749SSergey Zigachev * - - NULL - failure
317*b843c749SSergey Zigachev * - - - - read key under module folder
318*b843c749SSergey Zigachev * with edid/link identification
319*b843c749SSergey Zigachev */
320*b843c749SSergey Zigachev bool dm_read_persistent_data(struct dc_context *ctx,
321*b843c749SSergey Zigachev const struct dc_sink *sink,
322*b843c749SSergey Zigachev const char *module_name,
323*b843c749SSergey Zigachev const char *key_name,
324*b843c749SSergey Zigachev void *params,
325*b843c749SSergey Zigachev unsigned int size,
326*b843c749SSergey Zigachev struct persistent_data_flag *flag);
327*b843c749SSergey Zigachev
328*b843c749SSergey Zigachev bool dm_query_extended_brightness_caps
329*b843c749SSergey Zigachev (struct dc_context *ctx, enum dm_acpi_display_type display,
330*b843c749SSergey Zigachev struct dm_acpi_atif_backlight_caps *pCaps);
331*b843c749SSergey Zigachev
332*b843c749SSergey Zigachev bool dm_dmcu_set_pipe(struct dc_context *ctx, unsigned int controller_id);
333*b843c749SSergey Zigachev
334*b843c749SSergey Zigachev /*
335*b843c749SSergey Zigachev *
336*b843c749SSergey Zigachev * print-out services
337*b843c749SSergey Zigachev *
338*b843c749SSergey Zigachev */
339*b843c749SSergey Zigachev #define dm_log_to_buffer(buffer, size, fmt, args)\
340*b843c749SSergey Zigachev vsnprintf(buffer, size, fmt, args)
341*b843c749SSergey Zigachev
dm_get_timestamp(struct dc_context * ctx)342*b843c749SSergey Zigachev static inline unsigned long long dm_get_timestamp(struct dc_context *ctx)
343*b843c749SSergey Zigachev {
344*b843c749SSergey Zigachev return ktime_get_raw_ns();
345*b843c749SSergey Zigachev }
346*b843c749SSergey Zigachev
347*b843c749SSergey Zigachev unsigned long long dm_get_elapse_time_in_ns(struct dc_context *ctx,
348*b843c749SSergey Zigachev unsigned long long current_time_stamp,
349*b843c749SSergey Zigachev unsigned long long last_time_stamp);
350*b843c749SSergey Zigachev
351*b843c749SSergey Zigachev /*
352*b843c749SSergey Zigachev * performance tracing
353*b843c749SSergey Zigachev */
354*b843c749SSergey Zigachev void dm_perf_trace_timestamp(const char *func_name, unsigned int line);
355*b843c749SSergey Zigachev #define PERF_TRACE() dm_perf_trace_timestamp(__func__, __LINE__)
356*b843c749SSergey Zigachev
357*b843c749SSergey Zigachev
358*b843c749SSergey Zigachev /*
359*b843c749SSergey Zigachev * Debug and verification hooks
360*b843c749SSergey Zigachev */
361*b843c749SSergey Zigachev
362*b843c749SSergey Zigachev void dm_dtn_log_begin(struct dc_context *ctx);
363*b843c749SSergey Zigachev void dm_dtn_log_append_v(struct dc_context *ctx, const char *msg, ...);
364*b843c749SSergey Zigachev void dm_dtn_log_end(struct dc_context *ctx);
365*b843c749SSergey Zigachev
366*b843c749SSergey Zigachev #endif /* __DM_SERVICES_H__ */
367