xref: /openbmc/linux/drivers/gpu/drm/amd/display/dc/dm_services.h (revision 2612e3bbc0386368a850140a6c9b990cd496a5ec)
14562236bSHarry Wentland /*
24562236bSHarry Wentland  * Copyright 2015 Advanced Micro Devices, Inc.
34562236bSHarry Wentland  *
44562236bSHarry Wentland  * Permission is hereby granted, free of charge, to any person obtaining a
54562236bSHarry Wentland  * copy of this software and associated documentation files (the "Software"),
64562236bSHarry Wentland  * to deal in the Software without restriction, including without limitation
74562236bSHarry Wentland  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
84562236bSHarry Wentland  * and/or sell copies of the Software, and to permit persons to whom the
94562236bSHarry Wentland  * Software is furnished to do so, subject to the following conditions:
104562236bSHarry Wentland  *
114562236bSHarry Wentland  * The above copyright notice and this permission notice shall be included in
124562236bSHarry Wentland  * all copies or substantial portions of the Software.
134562236bSHarry Wentland  *
144562236bSHarry Wentland  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
154562236bSHarry Wentland  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
164562236bSHarry Wentland  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
174562236bSHarry Wentland  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
184562236bSHarry Wentland  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
194562236bSHarry Wentland  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
204562236bSHarry Wentland  * OTHER DEALINGS IN THE SOFTWARE.
214562236bSHarry Wentland  *
224562236bSHarry Wentland  * Authors: AMD
234562236bSHarry Wentland  *
244562236bSHarry Wentland  */
254562236bSHarry Wentland 
264562236bSHarry Wentland /**
274562236bSHarry Wentland  * This file defines external dependencies of Display Core.
284562236bSHarry Wentland  */
294562236bSHarry Wentland 
304562236bSHarry Wentland #ifndef __DM_SERVICES_H__
314562236bSHarry Wentland 
324562236bSHarry Wentland #define __DM_SERVICES_H__
334562236bSHarry Wentland 
344562236bSHarry Wentland /* TODO: remove when DC is complete. */
354562236bSHarry Wentland #include "dm_services_types.h"
364562236bSHarry Wentland #include "logger_interface.h"
374562236bSHarry Wentland #include "link_service_types.h"
384562236bSHarry Wentland 
394562236bSHarry Wentland #undef DEPRECATED
404562236bSHarry Wentland 
413a1627b0SNicholas Kazlauskas struct dmub_srv;
423a1627b0SNicholas Kazlauskas struct dc_dmub_srv;
43e97cc04fSJosip Pavic union dmub_rb_cmd;
443a1627b0SNicholas Kazlauskas 
454562236bSHarry Wentland irq_handler_idx dm_register_interrupt(
464562236bSHarry Wentland 	struct dc_context *ctx,
474562236bSHarry Wentland 	struct dc_interrupt_params *int_params,
484562236bSHarry Wentland 	interrupt_handler ih,
494562236bSHarry Wentland 	void *handler_args);
504562236bSHarry Wentland 
514562236bSHarry Wentland /*
524562236bSHarry Wentland  *
534562236bSHarry Wentland  * GPU registers access
544562236bSHarry Wentland  *
554562236bSHarry Wentland  */
569d83722dSRodrigo Siqueira uint32_t dm_read_reg_func(const struct dc_context *ctx, uint32_t address,
57901f4f97SYongqiang Sun 			  const char *func_name);
589d83722dSRodrigo Siqueira 
59e9d7dc62SDave Airlie /* enable for debugging new code, this adds 50k to the driver size. */
60e9d7dc62SDave Airlie /* #define DM_CHECK_ADDR_0 */
61e9d7dc62SDave Airlie 
629d83722dSRodrigo Siqueira void dm_write_reg_func(const struct dc_context *ctx, uint32_t address,
639d83722dSRodrigo Siqueira 		       uint32_t value, const char *func_name);
649d83722dSRodrigo Siqueira 
654562236bSHarry Wentland #define dm_read_reg(ctx, address)	\
664562236bSHarry Wentland 	dm_read_reg_func(ctx, address, __func__)
674562236bSHarry Wentland 
684562236bSHarry Wentland #define dm_write_reg(ctx, address, value)	\
694562236bSHarry Wentland 	dm_write_reg_func(ctx, address, value, __func__)
704562236bSHarry Wentland 
dm_read_index_reg(const struct dc_context * ctx,enum cgs_ind_reg addr_space,uint32_t index)714562236bSHarry Wentland static inline uint32_t dm_read_index_reg(
724562236bSHarry Wentland 	const struct dc_context *ctx,
734562236bSHarry Wentland 	enum cgs_ind_reg addr_space,
744562236bSHarry Wentland 	uint32_t index)
754562236bSHarry Wentland {
764562236bSHarry Wentland 	return cgs_read_ind_register(ctx->cgs_device, addr_space, index);
774562236bSHarry Wentland }
784562236bSHarry Wentland 
dm_write_index_reg(const struct dc_context * ctx,enum cgs_ind_reg addr_space,uint32_t index,uint32_t value)794562236bSHarry Wentland static inline void dm_write_index_reg(
804562236bSHarry Wentland 	const struct dc_context *ctx,
814562236bSHarry Wentland 	enum cgs_ind_reg addr_space,
824562236bSHarry Wentland 	uint32_t index,
834562236bSHarry Wentland 	uint32_t value)
844562236bSHarry Wentland {
854562236bSHarry Wentland 	cgs_write_ind_register(ctx->cgs_device, addr_space, index, value);
864562236bSHarry Wentland }
874562236bSHarry Wentland 
get_reg_field_value_ex(uint32_t reg_value,uint32_t mask,uint8_t shift)884562236bSHarry Wentland static inline uint32_t get_reg_field_value_ex(
894562236bSHarry Wentland 	uint32_t reg_value,
904562236bSHarry Wentland 	uint32_t mask,
914562236bSHarry Wentland 	uint8_t shift)
924562236bSHarry Wentland {
934562236bSHarry Wentland 	return (mask & reg_value) >> shift;
944562236bSHarry Wentland }
954562236bSHarry Wentland 
964562236bSHarry Wentland #define get_reg_field_value(reg_value, reg_name, reg_field)\
974562236bSHarry Wentland 	get_reg_field_value_ex(\
984562236bSHarry Wentland 		(reg_value),\
994562236bSHarry Wentland 		reg_name ## __ ## reg_field ## _MASK,\
1004562236bSHarry Wentland 		reg_name ## __ ## reg_field ## __SHIFT)
1014562236bSHarry Wentland 
set_reg_field_value_ex(uint32_t reg_value,uint32_t value,uint32_t mask,uint8_t shift)1024562236bSHarry Wentland static inline uint32_t set_reg_field_value_ex(
1034562236bSHarry Wentland 	uint32_t reg_value,
1044562236bSHarry Wentland 	uint32_t value,
1054562236bSHarry Wentland 	uint32_t mask,
1064562236bSHarry Wentland 	uint8_t shift)
1074562236bSHarry Wentland {
108bf727263STony Cheng 	ASSERT(mask != 0);
1094562236bSHarry Wentland 	return (reg_value & ~mask) | (mask & (value << shift));
1104562236bSHarry Wentland }
1114562236bSHarry Wentland 
1124562236bSHarry Wentland #define set_reg_field_value(reg_value, value, reg_name, reg_field)\
1134562236bSHarry Wentland 	(reg_value) = set_reg_field_value_ex(\
1144562236bSHarry Wentland 		(reg_value),\
1154562236bSHarry Wentland 		(value),\
1164562236bSHarry Wentland 		reg_name ## __ ## reg_field ## _MASK,\
1174562236bSHarry Wentland 		reg_name ## __ ## reg_field ## __SHIFT)
1184562236bSHarry Wentland 
119148cccf2SYongqiang Sun uint32_t generic_reg_set_ex(const struct dc_context *ctx,
1204562236bSHarry Wentland 		uint32_t addr, uint32_t reg_val, int n,
1214562236bSHarry Wentland 		uint8_t shift1, uint32_t mask1, uint32_t field_value1, ...);
1224562236bSHarry Wentland 
123148cccf2SYongqiang Sun uint32_t generic_reg_update_ex(const struct dc_context *ctx,
124148cccf2SYongqiang Sun 		uint32_t addr, int n,
125148cccf2SYongqiang Sun 		uint8_t shift1, uint32_t mask1, uint32_t field_value1, ...);
126148cccf2SYongqiang Sun 
1273a1627b0SNicholas Kazlauskas struct dc_dmub_srv *dc_dmub_srv_create(struct dc *dc, struct dmub_srv *dmub);
1283a1627b0SNicholas Kazlauskas void dc_dmub_srv_destroy(struct dc_dmub_srv **dmub_srv);
1293a1627b0SNicholas Kazlauskas 
1303a1627b0SNicholas Kazlauskas void reg_sequence_start_gather(const struct dc_context *ctx);
1313a1627b0SNicholas Kazlauskas void reg_sequence_start_execute(const struct dc_context *ctx);
1323a1627b0SNicholas Kazlauskas void reg_sequence_wait_done(const struct dc_context *ctx);
1333a1627b0SNicholas Kazlauskas 
1344562236bSHarry Wentland #define FD(reg_field)	reg_field ## __SHIFT, \
1354562236bSHarry Wentland 						reg_field ## _MASK
1364562236bSHarry Wentland 
1374562236bSHarry Wentland /*
1384562236bSHarry Wentland  * return number of poll before condition is met
1394562236bSHarry Wentland  * return 0 if condition is not meet after specified time out tries
1404562236bSHarry Wentland  */
141335d5d7bSYongqiang Sun void generic_reg_wait(const struct dc_context *ctx,
1424562236bSHarry Wentland 	uint32_t addr, uint32_t mask, uint32_t shift, uint32_t condition_value,
1434562236bSHarry Wentland 	unsigned int delay_between_poll_us, unsigned int time_out_num_tries,
144daf6b57dSDmytro Laktyushkin 	const char *func_name, int line);
1454562236bSHarry Wentland 
146c1f2e015SSu Sung Chung unsigned int snprintf_count(char *pBuf, unsigned int bufSize, char *fmt, ...);
1472c8ad2d5SAlex Deucher 
1482c8ad2d5SAlex Deucher /* These macros need to be used with soc15 registers in order to retrieve
1492c8ad2d5SAlex Deucher  * the actual offset.
1502c8ad2d5SAlex Deucher  */
1512c8ad2d5SAlex Deucher #define dm_write_reg_soc15(ctx, reg, inst_offset, value)	\
1522c8ad2d5SAlex Deucher 		dm_write_reg_func(ctx, reg + DCE_BASE.instance[0].segment[reg##_BASE_IDX] + inst_offset, value, __func__)
1532c8ad2d5SAlex Deucher 
1542c8ad2d5SAlex Deucher #define dm_read_reg_soc15(ctx, reg, inst_offset)	\
1552c8ad2d5SAlex Deucher 		dm_read_reg_func(ctx, reg + DCE_BASE.instance[0].segment[reg##_BASE_IDX] + inst_offset, __func__)
1562c8ad2d5SAlex Deucher 
1572c8ad2d5SAlex Deucher #define generic_reg_update_soc15(ctx, inst_offset, reg_name, n, ...)\
1582c8ad2d5SAlex Deucher 		generic_reg_update_ex(ctx, DCE_BASE.instance[0].segment[mm##reg_name##_BASE_IDX] +  mm##reg_name + inst_offset, \
1592c8ad2d5SAlex Deucher 		n, __VA_ARGS__)
1602c8ad2d5SAlex Deucher 
1612c8ad2d5SAlex Deucher #define generic_reg_set_soc15(ctx, inst_offset, reg_name, n, ...)\
162148cccf2SYongqiang Sun 		generic_reg_set_ex(ctx, DCE_BASE.instance[0].segment[mm##reg_name##_BASE_IDX] + mm##reg_name + inst_offset, 0, \
1632c8ad2d5SAlex Deucher 		n, __VA_ARGS__)
1642c8ad2d5SAlex Deucher 
1652c8ad2d5SAlex Deucher #define get_reg_field_value_soc15(reg_value, block, reg_num, reg_name, reg_field)\
1662c8ad2d5SAlex Deucher 	get_reg_field_value_ex(\
1672c8ad2d5SAlex Deucher 		(reg_value),\
1682c8ad2d5SAlex Deucher 		block ## reg_num ## _ ## reg_name ## __ ## reg_field ## _MASK,\
1692c8ad2d5SAlex Deucher 		block ## reg_num ## _ ## reg_name ## __ ## reg_field ## __SHIFT)
1702c8ad2d5SAlex Deucher 
1712c8ad2d5SAlex Deucher #define set_reg_field_value_soc15(reg_value, value, block, reg_num, reg_name, reg_field)\
1722c8ad2d5SAlex Deucher 	(reg_value) = set_reg_field_value_ex(\
1732c8ad2d5SAlex Deucher 		(reg_value),\
1742c8ad2d5SAlex Deucher 		(value),\
1752c8ad2d5SAlex Deucher 		block ## reg_num ## _ ## reg_name ## __ ## reg_field ## _MASK,\
1762c8ad2d5SAlex Deucher 		block ## reg_num ## _ ## reg_name ## __ ## reg_field ## __SHIFT)
1772c8ad2d5SAlex Deucher 
1784562236bSHarry Wentland /**************************************
1794562236bSHarry Wentland  * Power Play (PP) interfaces
1804562236bSHarry Wentland  **************************************/
1814562236bSHarry Wentland 
1824562236bSHarry Wentland /* Gets valid clocks levels from pplib
1834562236bSHarry Wentland  *
1844562236bSHarry Wentland  * input: clk_type - display clk / sclk / mem clk
1854562236bSHarry Wentland  *
1864562236bSHarry Wentland  * output: array of valid clock levels for given type in ascending order,
1874562236bSHarry Wentland  * with invalid levels filtered out
1884562236bSHarry Wentland  *
1894562236bSHarry Wentland  */
1904562236bSHarry Wentland bool dm_pp_get_clock_levels_by_type(
1914562236bSHarry Wentland 	const struct dc_context *ctx,
1924562236bSHarry Wentland 	enum dm_pp_clock_type clk_type,
1934562236bSHarry Wentland 	struct dm_pp_clock_levels *clk_level_info);
1944562236bSHarry Wentland 
1954562236bSHarry Wentland bool dm_pp_get_clock_levels_by_type_with_latency(
1964562236bSHarry Wentland 	const struct dc_context *ctx,
1974562236bSHarry Wentland 	enum dm_pp_clock_type clk_type,
1984562236bSHarry Wentland 	struct dm_pp_clock_levels_with_latency *clk_level_info);
1994562236bSHarry Wentland 
2004562236bSHarry Wentland bool dm_pp_get_clock_levels_by_type_with_voltage(
2014562236bSHarry Wentland 	const struct dc_context *ctx,
2024562236bSHarry Wentland 	enum dm_pp_clock_type clk_type,
2034562236bSHarry Wentland 	struct dm_pp_clock_levels_with_voltage *clk_level_info);
2044562236bSHarry Wentland 
2054562236bSHarry Wentland bool dm_pp_notify_wm_clock_changes(
2064562236bSHarry Wentland 	const struct dc_context *ctx,
2074562236bSHarry Wentland 	struct dm_pp_wm_sets_with_clock_ranges *wm_with_clock_ranges);
2084562236bSHarry Wentland 
2090f1a6ad7SJun Lei void dm_pp_get_funcs(struct dc_context *ctx,
2100f1a6ad7SJun Lei 		struct pp_smu_funcs *funcs);
2112c8ad2d5SAlex Deucher 
2124562236bSHarry Wentland /* DAL calls this function to notify PP about completion of Mode Set.
2134562236bSHarry Wentland  * For PP it means that current DCE clocks are those which were returned
2144562236bSHarry Wentland  * by dc_service_pp_pre_dce_clock_change(), in the 'output' parameter.
2154562236bSHarry Wentland  *
2164562236bSHarry Wentland  * If the clocks are higher than before, then PP does nothing.
2174562236bSHarry Wentland  *
2184562236bSHarry Wentland  * If the clocks are lower than before, then PP reduces the voltage.
2194562236bSHarry Wentland  *
2204562236bSHarry Wentland  * \returns	true - call is successful
2214562236bSHarry Wentland  *		false - call failed
2224562236bSHarry Wentland  */
2234562236bSHarry Wentland bool dm_pp_apply_display_requirements(
2244562236bSHarry Wentland 	const struct dc_context *ctx,
2254562236bSHarry Wentland 	const struct dm_pp_display_configuration *pp_display_cfg);
2264562236bSHarry Wentland 
2274562236bSHarry Wentland bool dm_pp_apply_power_level_change_request(
2284562236bSHarry Wentland 	const struct dc_context *ctx,
2294562236bSHarry Wentland 	struct dm_pp_power_level_change_request *level_change_req);
2304562236bSHarry Wentland 
2314562236bSHarry Wentland bool dm_pp_apply_clock_for_voltage_request(
2324562236bSHarry Wentland 	const struct dc_context *ctx,
2334562236bSHarry Wentland 	struct dm_pp_clock_for_voltage_req *clock_for_voltage_req);
2344562236bSHarry Wentland 
2354562236bSHarry Wentland bool dm_pp_get_static_clocks(
2364562236bSHarry Wentland 	const struct dc_context *ctx,
2374562236bSHarry Wentland 	struct dm_pp_static_clock_info *static_clk_info);
2384562236bSHarry Wentland 
2394562236bSHarry Wentland /****** end of PP interfaces ******/
2404562236bSHarry Wentland 
2414562236bSHarry Wentland struct persistent_data_flag {
2424562236bSHarry Wentland 	bool save_per_link;
2434562236bSHarry Wentland 	bool save_per_edid;
2444562236bSHarry Wentland };
2454562236bSHarry Wentland 
2464562236bSHarry Wentland bool dm_query_extended_brightness_caps
2474562236bSHarry Wentland 	(struct dc_context *ctx, enum dm_acpi_display_type display,
2484562236bSHarry Wentland 			struct dm_acpi_atif_backlight_caps *pCaps);
2494562236bSHarry Wentland 
2504562236bSHarry Wentland bool dm_dmcu_set_pipe(struct dc_context *ctx, unsigned int controller_id);
2514562236bSHarry Wentland 
2524562236bSHarry Wentland /*
2534562236bSHarry Wentland  *
2544562236bSHarry Wentland  * print-out services
2554562236bSHarry Wentland  *
2564562236bSHarry Wentland  */
2574562236bSHarry Wentland #define dm_log_to_buffer(buffer, size, fmt, args)\
2584562236bSHarry Wentland 	vsnprintf(buffer, size, fmt, args)
2594562236bSHarry Wentland 
dm_get_timestamp(struct dc_context * ctx)260eeb2c3c2SArnd Bergmann static inline unsigned long long dm_get_timestamp(struct dc_context *ctx)
261eeb2c3c2SArnd Bergmann {
262eeb2c3c2SArnd Bergmann 	return ktime_get_raw_ns();
263eeb2c3c2SArnd Bergmann }
264215a6f05SDmytro Laktyushkin 
26578d5d04dSCharlene Liu unsigned long long dm_get_elapse_time_in_ns(struct dc_context *ctx,
26678d5d04dSCharlene Liu 		unsigned long long current_time_stamp,
26778d5d04dSCharlene Liu 		unsigned long long last_time_stamp);
26878d5d04dSCharlene Liu 
2692248eb6bSTony Cheng /*
270dce46c53STony Cheng  * performance tracing
271dce46c53STony Cheng  */
2729d83722dSRodrigo Siqueira void dm_perf_trace_timestamp(const char *func_name, unsigned int line, struct dc_context *ctx);
273dce46c53STony Cheng 
2749d83722dSRodrigo Siqueira #define PERF_TRACE()	dm_perf_trace_timestamp(__func__, __LINE__, CTX)
2759d83722dSRodrigo Siqueira #define PERF_TRACE_CTX(__CTX)	dm_perf_trace_timestamp(__func__, __LINE__, __CTX)
276dce46c53STony Cheng 
277dce46c53STony Cheng /*
278e97cc04fSJosip Pavic  * DMUB Interfaces
279e97cc04fSJosip Pavic  */
280e97cc04fSJosip Pavic bool dm_execute_dmub_cmd(const struct dc_context *ctx, union dmub_rb_cmd *cmd, enum dm_dmub_wait_type wait_type);
281e97cc04fSJosip Pavic bool dm_execute_dmub_cmd_list(const struct dc_context *ctx, unsigned int count, union dmub_rb_cmd *cmd, enum dm_dmub_wait_type wait_type);
282e97cc04fSJosip Pavic 
283e97cc04fSJosip Pavic /*
2842248eb6bSTony Cheng  * Debug and verification hooks
2852248eb6bSTony Cheng  */
2862248eb6bSTony Cheng 
28746659a83SNicholas Kazlauskas void dm_dtn_log_begin(struct dc_context *ctx,
28846659a83SNicholas Kazlauskas 	struct dc_log_buffer_ctx *log_ctx);
28946659a83SNicholas Kazlauskas void dm_dtn_log_append_v(struct dc_context *ctx,
29046659a83SNicholas Kazlauskas 	struct dc_log_buffer_ctx *log_ctx,
29146659a83SNicholas Kazlauskas 	const char *msg, ...);
29246659a83SNicholas Kazlauskas void dm_dtn_log_end(struct dc_context *ctx,
29346659a83SNicholas Kazlauskas 	struct dc_log_buffer_ctx *log_ctx);
2942248eb6bSTony Cheng 
295*bf7fda0bSRodrigo Siqueira char *dce_version_to_string(const int version);
296*bf7fda0bSRodrigo Siqueira 
2974562236bSHarry Wentland #endif /* __DM_SERVICES_H__ */
298