1 /*
2  * Copyright 2015 Advanced Micro Devices, Inc.
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the "Software"),
6  * to deal in the Software without restriction, including without limitation
7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8  * and/or sell copies of the Software, and to permit persons to whom the
9  * Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice shall be included in
12  * all copies or substantial portions of the Software.
13  *
14  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
17  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20  * OTHER DEALINGS IN THE SOFTWARE.
21  *
22  * Authors: AMD
23  *
24  */
25 
26 /**
27  * This file defines external dependencies of Display Core.
28  */
29 
30 #ifndef __DM_SERVICES_H__
31 
32 #define __DM_SERVICES_H__
33 
34 /* TODO: remove when DC is complete. */
35 #include "dm_services_types.h"
36 #include "logger_interface.h"
37 #include "link_service_types.h"
38 
39 #undef DEPRECATED
40 
41 /*
42  *
43  * general debug capabilities
44  *
45  */
46 #if defined(CONFIG_DEBUG_KERNEL) || defined(CONFIG_DEBUG_DRIVER)
47 
48 #if defined(CONFIG_HAVE_KGDB) || defined(CONFIG_KGDB)
49 #define ASSERT_CRITICAL(expr) do {	\
50 	if (WARN_ON(!(expr))) { \
51 		kgdb_breakpoint(); \
52 	} \
53 } while (0)
54 #else
55 #define ASSERT_CRITICAL(expr) do {	\
56 	if (WARN_ON(!(expr))) { \
57 		; \
58 	} \
59 } while (0)
60 #endif
61 
62 #if defined(CONFIG_DEBUG_KERNEL_DC)
63 #define ASSERT(expr) ASSERT_CRITICAL(expr)
64 
65 #else
66 #define ASSERT(expr) WARN_ON(!(expr))
67 #endif
68 
69 #define BREAK_TO_DEBUGGER() ASSERT(0)
70 
71 #endif /* CONFIG_DEBUG_KERNEL || CONFIG_DEBUG_DRIVER */
72 
73 #define DC_ERR(...)  do { \
74 	dm_error(__VA_ARGS__); \
75 	BREAK_TO_DEBUGGER(); \
76 } while (0)
77 
78 #define dm_alloc(size) kzalloc(size, GFP_KERNEL)
79 #define dm_realloc(ptr, size) krealloc(ptr, size, GFP_KERNEL)
80 #define dm_free(ptr) kfree(ptr)
81 
82 irq_handler_idx dm_register_interrupt(
83 	struct dc_context *ctx,
84 	struct dc_interrupt_params *int_params,
85 	interrupt_handler ih,
86 	void *handler_args);
87 
88 
89 /*
90  *
91  * GPU registers access
92  *
93  */
94 
95 #define dm_read_reg(ctx, address)	\
96 		dm_read_reg_func(ctx, address, __func__)
97 
98 static inline uint32_t dm_read_reg_func(
99 	const struct dc_context *ctx,
100 	uint32_t address,
101 	const char *func_name)
102 {
103 	uint32_t value;
104 
105 	if (address == 0) {
106 		DC_ERR("invalid register read; address = 0\n");
107 		return 0;
108 	}
109 
110 	value = cgs_read_register(ctx->cgs_device, address);
111 
112 	return value;
113 }
114 
115 #define dm_write_reg(ctx, address, value)	\
116 	dm_write_reg_func(ctx, address, value, __func__)
117 
118 static inline void dm_write_reg_func(
119 	const struct dc_context *ctx,
120 	uint32_t address,
121 	uint32_t value,
122 	const char *func_name)
123 {
124 	if (address == 0) {
125 		DC_ERR("invalid register write. address = 0");
126 		return;
127 	}
128 	cgs_write_register(ctx->cgs_device, address, value);
129 }
130 
131 static inline uint32_t dm_read_index_reg(
132 	const struct dc_context *ctx,
133 	enum cgs_ind_reg addr_space,
134 	uint32_t index)
135 {
136 	return cgs_read_ind_register(ctx->cgs_device, addr_space, index);
137 }
138 
139 static inline void dm_write_index_reg(
140 	const struct dc_context *ctx,
141 	enum cgs_ind_reg addr_space,
142 	uint32_t index,
143 	uint32_t value)
144 {
145 	cgs_write_ind_register(ctx->cgs_device, addr_space, index, value);
146 }
147 
148 static inline uint32_t get_reg_field_value_ex(
149 	uint32_t reg_value,
150 	uint32_t mask,
151 	uint8_t shift)
152 {
153 	return (mask & reg_value) >> shift;
154 }
155 
156 #define get_reg_field_value(reg_value, reg_name, reg_field)\
157 	get_reg_field_value_ex(\
158 		(reg_value),\
159 		reg_name ## __ ## reg_field ## _MASK,\
160 		reg_name ## __ ## reg_field ## __SHIFT)
161 
162 static inline uint32_t set_reg_field_value_ex(
163 	uint32_t reg_value,
164 	uint32_t value,
165 	uint32_t mask,
166 	uint8_t shift)
167 {
168 	ASSERT(mask != 0);
169 	return (reg_value & ~mask) | (mask & (value << shift));
170 }
171 
172 #define set_reg_field_value(reg_value, value, reg_name, reg_field)\
173 	(reg_value) = set_reg_field_value_ex(\
174 		(reg_value),\
175 		(value),\
176 		reg_name ## __ ## reg_field ## _MASK,\
177 		reg_name ## __ ## reg_field ## __SHIFT)
178 
179 uint32_t generic_reg_update_ex(const struct dc_context *ctx,
180 		uint32_t addr, uint32_t reg_val, int n,
181 		uint8_t shift1, uint32_t mask1, uint32_t field_value1, ...);
182 
183 #define FD(reg_field)	reg_field ## __SHIFT, \
184 						reg_field ## _MASK
185 
186 /*
187  * return number of poll before condition is met
188  * return 0 if condition is not meet after specified time out tries
189  */
190 unsigned int generic_reg_wait(const struct dc_context *ctx,
191 	uint32_t addr, uint32_t mask, uint32_t shift, uint32_t condition_value,
192 	unsigned int delay_between_poll_us, unsigned int time_out_num_tries,
193 	const char *func_name);
194 
195 
196 /* These macros need to be used with soc15 registers in order to retrieve
197  * the actual offset.
198  */
199 #define REG_OFFSET(reg) (reg + DCE_BASE.instance[0].segment[reg##_BASE_IDX])
200 #define REG_BIF_OFFSET(reg) (reg + NBIF_BASE.instance[0].segment[reg##_BASE_IDX])
201 
202 #define dm_write_reg_soc15(ctx, reg, inst_offset, value)	\
203 		dm_write_reg_func(ctx, reg + DCE_BASE.instance[0].segment[reg##_BASE_IDX] + inst_offset, value, __func__)
204 
205 #define dm_read_reg_soc15(ctx, reg, inst_offset)	\
206 		dm_read_reg_func(ctx, reg + DCE_BASE.instance[0].segment[reg##_BASE_IDX] + inst_offset, __func__)
207 
208 #define generic_reg_update_soc15(ctx, inst_offset, reg_name, n, ...)\
209 		generic_reg_update_ex(ctx, DCE_BASE.instance[0].segment[mm##reg_name##_BASE_IDX] +  mm##reg_name + inst_offset, \
210 		dm_read_reg_func(ctx, mm##reg_name + DCE_BASE.instance[0].segment[mm##reg_name##_BASE_IDX] + inst_offset, __func__), \
211 		n, __VA_ARGS__)
212 
213 #define generic_reg_set_soc15(ctx, inst_offset, reg_name, n, ...)\
214 		generic_reg_update_ex(ctx, DCE_BASE.instance[0].segment[mm##reg_name##_BASE_IDX] + mm##reg_name + inst_offset, 0, \
215 		n, __VA_ARGS__)
216 
217 #define get_reg_field_value_soc15(reg_value, block, reg_num, reg_name, reg_field)\
218 	get_reg_field_value_ex(\
219 		(reg_value),\
220 		block ## reg_num ## _ ## reg_name ## __ ## reg_field ## _MASK,\
221 		block ## reg_num ## _ ## reg_name ## __ ## reg_field ## __SHIFT)
222 
223 #define set_reg_field_value_soc15(reg_value, value, block, reg_num, reg_name, reg_field)\
224 	(reg_value) = set_reg_field_value_ex(\
225 		(reg_value),\
226 		(value),\
227 		block ## reg_num ## _ ## reg_name ## __ ## reg_field ## _MASK,\
228 		block ## reg_num ## _ ## reg_name ## __ ## reg_field ## __SHIFT)
229 
230 /* TODO get rid of this pos*/
231 static inline bool wait_reg_func(
232 	const struct dc_context *ctx,
233 	uint32_t addr,
234 	uint32_t mask,
235 	uint8_t shift,
236 	uint32_t condition_value,
237 	unsigned int interval_us,
238 	unsigned int timeout_us)
239 {
240 	uint32_t field_value;
241 	uint32_t reg_val;
242 	unsigned int count = 0;
243 
244 	if (IS_FPGA_MAXIMUS_DC(ctx->dce_environment))
245 		timeout_us *= 655;  /* 6553 give about 30 second before time out */
246 
247 	do {
248 		/* try once without sleeping */
249 		if (count > 0) {
250 			if (interval_us >= 1000)
251 				msleep(interval_us/1000);
252 			else
253 				udelay(interval_us);
254 		}
255 		reg_val = dm_read_reg(ctx, addr);
256 		field_value = get_reg_field_value_ex(reg_val, mask, shift);
257 		count += interval_us;
258 
259 	} while (field_value != condition_value && count <= timeout_us);
260 
261 	ASSERT(count <= timeout_us);
262 
263 	return count <= timeout_us;
264 }
265 
266 #define wait_reg(ctx, inst_offset, reg_name, reg_field, condition_value)\
267 	wait_reg_func(\
268 		ctx,\
269 		mm##reg_name + inst_offset + DCE_BASE.instance[0].segment[mm##reg_name##_BASE_IDX],\
270 		reg_name ## __ ## reg_field ## _MASK,\
271 		reg_name ## __ ## reg_field ## __SHIFT,\
272 		condition_value,\
273 		20000,\
274 		200000)
275 
276 /**************************************
277  * Power Play (PP) interfaces
278  **************************************/
279 
280 /* DAL calls this function to notify PP about clocks it needs for the Mode Set.
281  * This is done *before* it changes DCE clock.
282  *
283  * If required clock is higher than current, then PP will increase the voltage.
284  *
285  * If required clock is lower than current, then PP will defer reduction of
286  * voltage until the call to dc_service_pp_post_dce_clock_change().
287  *
288  * \input - Contains clocks needed for Mode Set.
289  *
290  * \output - Contains clocks adjusted by PP which DAL should use for Mode Set.
291  *		Valid only if function returns zero.
292  *
293  * \returns	true - call is successful
294  *		false - call failed
295  */
296 bool dm_pp_pre_dce_clock_change(
297 	struct dc_context *ctx,
298 	struct dm_pp_gpu_clock_range *requested_state,
299 	struct dm_pp_gpu_clock_range *actual_state);
300 
301 /* The returned clocks range are 'static' system clocks which will be used for
302  * mode validation purposes.
303  *
304  * \returns	true - call is successful
305  *		false - call failed
306  */
307 bool dc_service_get_system_clocks_range(
308 	const struct dc_context *ctx,
309 	struct dm_pp_gpu_clock_range *sys_clks);
310 
311 /* Gets valid clocks levels from pplib
312  *
313  * input: clk_type - display clk / sclk / mem clk
314  *
315  * output: array of valid clock levels for given type in ascending order,
316  * with invalid levels filtered out
317  *
318  */
319 bool dm_pp_get_clock_levels_by_type(
320 	const struct dc_context *ctx,
321 	enum dm_pp_clock_type clk_type,
322 	struct dm_pp_clock_levels *clk_level_info);
323 
324 bool dm_pp_get_clock_levels_by_type_with_latency(
325 	const struct dc_context *ctx,
326 	enum dm_pp_clock_type clk_type,
327 	struct dm_pp_clock_levels_with_latency *clk_level_info);
328 
329 bool dm_pp_get_clock_levels_by_type_with_voltage(
330 	const struct dc_context *ctx,
331 	enum dm_pp_clock_type clk_type,
332 	struct dm_pp_clock_levels_with_voltage *clk_level_info);
333 
334 bool dm_pp_notify_wm_clock_changes(
335 	const struct dc_context *ctx,
336 	struct dm_pp_wm_sets_with_clock_ranges *wm_with_clock_ranges);
337 
338 bool dm_pp_notify_wm_clock_changes_soc15(
339 	const struct dc_context *ctx,
340 	struct dm_pp_wm_sets_with_clock_ranges_soc15 *wm_with_clock_ranges);
341 
342 /* DAL calls this function to notify PP about completion of Mode Set.
343  * For PP it means that current DCE clocks are those which were returned
344  * by dc_service_pp_pre_dce_clock_change(), in the 'output' parameter.
345  *
346  * If the clocks are higher than before, then PP does nothing.
347  *
348  * If the clocks are lower than before, then PP reduces the voltage.
349  *
350  * \returns	true - call is successful
351  *		false - call failed
352  */
353 bool dm_pp_apply_display_requirements(
354 	const struct dc_context *ctx,
355 	const struct dm_pp_display_configuration *pp_display_cfg);
356 
357 bool dm_pp_apply_power_level_change_request(
358 	const struct dc_context *ctx,
359 	struct dm_pp_power_level_change_request *level_change_req);
360 
361 bool dm_pp_apply_clock_for_voltage_request(
362 	const struct dc_context *ctx,
363 	struct dm_pp_clock_for_voltage_req *clock_for_voltage_req);
364 
365 bool dm_pp_get_static_clocks(
366 	const struct dc_context *ctx,
367 	struct dm_pp_static_clock_info *static_clk_info);
368 
369 /****** end of PP interfaces ******/
370 
371 struct persistent_data_flag {
372 	bool save_per_link;
373 	bool save_per_edid;
374 };
375 
376 /* Call to write data in registry editor for persistent data storage.
377  *
378  * \inputs      sink - identify edid/link for registry folder creation
379  *              module name - identify folders for registry
380  *              key name - identify keys within folders for registry
381  *              params - value to write in defined folder/key
382  *              size - size of the input params
383  *              flag - determine whether to save by link or edid
384  *
385  * \returns     true - call is successful
386  *              false - call failed
387  *
388  * sink         module         key
389  * -----------------------------------------------------------------------------
390  * NULL         NULL           NULL     - failure
391  * NULL         NULL           -        - create key with param value
392  *                                                      under base folder
393  * NULL         -              NULL     - create module folder under base folder
394  * -            NULL           NULL     - failure
395  * NULL         -              -        - create key under module folder
396  *                                            with no edid/link identification
397  * -            NULL           -        - create key with param value
398  *                                                       under base folder
399  * -            -              NULL     - create module folder under base folder
400  * -            -              -        - create key under module folder
401  *                                              with edid/link identification
402  */
403 bool dm_write_persistent_data(struct dc_context *ctx,
404 		const struct dc_sink *sink,
405 		const char *module_name,
406 		const char *key_name,
407 		void *params,
408 		unsigned int size,
409 		struct persistent_data_flag *flag);
410 
411 
412 /* Call to read data in registry editor for persistent data storage.
413  *
414  * \inputs      sink - identify edid/link for registry folder creation
415  *              module name - identify folders for registry
416  *              key name - identify keys within folders for registry
417  *              size - size of the output params
418  *              flag - determine whether it was save by link or edid
419  *
420  * \returns     params - value read from defined folder/key
421  *              true - call is successful
422  *              false - call failed
423  *
424  * sink         module         key
425  * -----------------------------------------------------------------------------
426  * NULL         NULL           NULL     - failure
427  * NULL         NULL           -        - read key under base folder
428  * NULL         -              NULL     - failure
429  * -            NULL           NULL     - failure
430  * NULL         -              -        - read key under module folder
431  *                                             with no edid/link identification
432  * -            NULL           -        - read key under base folder
433  * -            -              NULL     - failure
434  * -            -              -        - read key under module folder
435  *                                              with edid/link identification
436  */
437 bool dm_read_persistent_data(struct dc_context *ctx,
438 		const struct dc_sink *sink,
439 		const char *module_name,
440 		const char *key_name,
441 		void *params,
442 		unsigned int size,
443 		struct persistent_data_flag *flag);
444 
445 void dm_delay_in_microseconds
446 	(struct dc_context *ctx, unsigned int microSeconds);
447 
448 bool dm_query_extended_brightness_caps
449 	(struct dc_context *ctx, enum dm_acpi_display_type display,
450 			struct dm_acpi_atif_backlight_caps *pCaps);
451 
452 bool dm_dmcu_set_pipe(struct dc_context *ctx, unsigned int controller_id);
453 
454 /*
455  *
456  * print-out services
457  *
458  */
459 #define dm_log_to_buffer(buffer, size, fmt, args)\
460 	vsnprintf(buffer, size, fmt, args)
461 
462 #endif /* __DM_SERVICES_H__ */
463