dm_services.h 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424
  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. * This file defines external dependencies of Display Core.
  27. */
  28. #ifndef __DM_SERVICES_H__
  29. #define __DM_SERVICES_H__
  30. /* TODO: remove when DC is complete. */
  31. #include "dm_services_types.h"
  32. #include "logger_interface.h"
  33. #include "link_service_types.h"
  34. #undef DEPRECATED
  35. /*
  36. *
  37. * general debug capabilities
  38. *
  39. */
  40. #if defined(CONFIG_DEBUG_KERNEL) || defined(CONFIG_DEBUG_DRIVER)
  41. #if defined(CONFIG_HAVE_KGDB) || defined(CONFIG_KGDB)
  42. #define ASSERT_CRITICAL(expr) do { \
  43. if (WARN_ON(!(expr))) { \
  44. kgdb_breakpoint(); \
  45. } \
  46. } while (0)
  47. #else
  48. #define ASSERT_CRITICAL(expr) do { \
  49. if (WARN_ON(!(expr))) { \
  50. ; \
  51. } \
  52. } while (0)
  53. #endif
  54. #if defined(CONFIG_DEBUG_KERNEL_DC)
  55. #define ASSERT(expr) ASSERT_CRITICAL(expr)
  56. #else
  57. #define ASSERT(expr) WARN_ON(!(expr))
  58. #endif
  59. #define BREAK_TO_DEBUGGER() ASSERT(0)
  60. #endif /* CONFIG_DEBUG_KERNEL || CONFIG_DEBUG_DRIVER */
  61. #define DC_ERR(...) do { \
  62. dm_error(__VA_ARGS__); \
  63. BREAK_TO_DEBUGGER(); \
  64. } while (0)
  65. #define dm_alloc(size) kzalloc(size, GFP_KERNEL)
  66. #define dm_realloc(ptr, size) krealloc(ptr, size, GFP_KERNEL)
  67. #define dm_free(ptr) kfree(ptr)
  68. irq_handler_idx dm_register_interrupt(
  69. struct dc_context *ctx,
  70. struct dc_interrupt_params *int_params,
  71. interrupt_handler ih,
  72. void *handler_args);
  73. /*
  74. *
  75. * GPU registers access
  76. *
  77. */
  78. #define dm_read_reg(ctx, address) \
  79. dm_read_reg_func(ctx, address, __func__)
  80. static inline uint32_t dm_read_reg_func(
  81. const struct dc_context *ctx,
  82. uint32_t address,
  83. const char *func_name)
  84. {
  85. uint32_t value;
  86. if (address == 0) {
  87. DC_ERR("invalid register read. address = 0");
  88. return 0;
  89. }
  90. value = cgs_read_register(ctx->cgs_device, address);
  91. #if defined(__DAL_REGISTER_LOGGER__)
  92. if (true == dal_reg_logger_should_dump_register()) {
  93. dal_reg_logger_rw_count_increment();
  94. DRM_INFO("%s DC_READ_REG: 0x%x 0x%x\n", func_name, address, value);
  95. }
  96. #endif
  97. return value;
  98. }
  99. #define dm_write_reg(ctx, address, value) \
  100. dm_write_reg_func(ctx, address, value, __func__)
  101. static inline void dm_write_reg_func(
  102. const struct dc_context *ctx,
  103. uint32_t address,
  104. uint32_t value,
  105. const char *func_name)
  106. {
  107. #if defined(__DAL_REGISTER_LOGGER__)
  108. if (true == dal_reg_logger_should_dump_register()) {
  109. dal_reg_logger_rw_count_increment();
  110. DRM_INFO("%s DC_WRITE_REG: 0x%x 0x%x\n", func_name, address, value);
  111. }
  112. #endif
  113. if (address == 0) {
  114. DC_ERR("invalid register write. address = 0");
  115. return;
  116. }
  117. cgs_write_register(ctx->cgs_device, address, value);
  118. }
  119. static inline uint32_t dm_read_index_reg(
  120. const struct dc_context *ctx,
  121. enum cgs_ind_reg addr_space,
  122. uint32_t index)
  123. {
  124. return cgs_read_ind_register(ctx->cgs_device, addr_space, index);
  125. }
  126. static inline void dm_write_index_reg(
  127. const struct dc_context *ctx,
  128. enum cgs_ind_reg addr_space,
  129. uint32_t index,
  130. uint32_t value)
  131. {
  132. cgs_write_ind_register(ctx->cgs_device, addr_space, index, value);
  133. }
  134. static inline uint32_t get_reg_field_value_ex(
  135. uint32_t reg_value,
  136. uint32_t mask,
  137. uint8_t shift)
  138. {
  139. return (mask & reg_value) >> shift;
  140. }
  141. #define get_reg_field_value(reg_value, reg_name, reg_field)\
  142. get_reg_field_value_ex(\
  143. (reg_value),\
  144. reg_name ## __ ## reg_field ## _MASK,\
  145. reg_name ## __ ## reg_field ## __SHIFT)
  146. static inline uint32_t set_reg_field_value_ex(
  147. uint32_t reg_value,
  148. uint32_t value,
  149. uint32_t mask,
  150. uint8_t shift)
  151. {
  152. return (reg_value & ~mask) | (mask & (value << shift));
  153. }
  154. #define set_reg_field_value(reg_value, value, reg_name, reg_field)\
  155. (reg_value) = set_reg_field_value_ex(\
  156. (reg_value),\
  157. (value),\
  158. reg_name ## __ ## reg_field ## _MASK,\
  159. reg_name ## __ ## reg_field ## __SHIFT)
  160. uint32_t generic_reg_update_ex(const struct dc_context *ctx,
  161. uint32_t addr, uint32_t reg_val, int n,
  162. uint8_t shift1, uint32_t mask1, uint32_t field_value1, ...);
  163. #define FD(reg_field) reg_field ## __SHIFT, \
  164. reg_field ## _MASK
  165. /*
  166. * return number of poll before condition is met
  167. * return 0 if condition is not meet after specified time out tries
  168. */
  169. unsigned int generic_reg_wait(const struct dc_context *ctx,
  170. uint32_t addr, uint32_t mask, uint32_t shift, uint32_t condition_value,
  171. unsigned int delay_between_poll_us, unsigned int time_out_num_tries,
  172. const char *func_name);
  173. /**************************************
  174. * Power Play (PP) interfaces
  175. **************************************/
  176. /* DAL calls this function to notify PP about clocks it needs for the Mode Set.
  177. * This is done *before* it changes DCE clock.
  178. *
  179. * If required clock is higher than current, then PP will increase the voltage.
  180. *
  181. * If required clock is lower than current, then PP will defer reduction of
  182. * voltage until the call to dc_service_pp_post_dce_clock_change().
  183. *
  184. * \input - Contains clocks needed for Mode Set.
  185. *
  186. * \output - Contains clocks adjusted by PP which DAL should use for Mode Set.
  187. * Valid only if function returns zero.
  188. *
  189. * \returns true - call is successful
  190. * false - call failed
  191. */
  192. bool dm_pp_pre_dce_clock_change(
  193. struct dc_context *ctx,
  194. struct dm_pp_gpu_clock_range *requested_state,
  195. struct dm_pp_gpu_clock_range *actual_state);
  196. /* The returned clocks range are 'static' system clocks which will be used for
  197. * mode validation purposes.
  198. *
  199. * \returns true - call is successful
  200. * false - call failed
  201. */
  202. bool dc_service_get_system_clocks_range(
  203. const struct dc_context *ctx,
  204. struct dm_pp_gpu_clock_range *sys_clks);
  205. /* Gets valid clocks levels from pplib
  206. *
  207. * input: clk_type - display clk / sclk / mem clk
  208. *
  209. * output: array of valid clock levels for given type in ascending order,
  210. * with invalid levels filtered out
  211. *
  212. */
  213. bool dm_pp_get_clock_levels_by_type(
  214. const struct dc_context *ctx,
  215. enum dm_pp_clock_type clk_type,
  216. struct dm_pp_clock_levels *clk_level_info);
  217. bool dm_pp_get_clock_levels_by_type_with_latency(
  218. const struct dc_context *ctx,
  219. enum dm_pp_clock_type clk_type,
  220. struct dm_pp_clock_levels_with_latency *clk_level_info);
  221. bool dm_pp_get_clock_levels_by_type_with_voltage(
  222. const struct dc_context *ctx,
  223. enum dm_pp_clock_type clk_type,
  224. struct dm_pp_clock_levels_with_voltage *clk_level_info);
  225. bool dm_pp_notify_wm_clock_changes(
  226. const struct dc_context *ctx,
  227. struct dm_pp_wm_sets_with_clock_ranges *wm_with_clock_ranges);
  228. /* DAL calls this function to notify PP about completion of Mode Set.
  229. * For PP it means that current DCE clocks are those which were returned
  230. * by dc_service_pp_pre_dce_clock_change(), in the 'output' parameter.
  231. *
  232. * If the clocks are higher than before, then PP does nothing.
  233. *
  234. * If the clocks are lower than before, then PP reduces the voltage.
  235. *
  236. * \returns true - call is successful
  237. * false - call failed
  238. */
  239. bool dm_pp_apply_display_requirements(
  240. const struct dc_context *ctx,
  241. const struct dm_pp_display_configuration *pp_display_cfg);
  242. bool dm_pp_apply_power_level_change_request(
  243. const struct dc_context *ctx,
  244. struct dm_pp_power_level_change_request *level_change_req);
  245. bool dm_pp_apply_clock_for_voltage_request(
  246. const struct dc_context *ctx,
  247. struct dm_pp_clock_for_voltage_req *clock_for_voltage_req);
  248. bool dm_pp_get_static_clocks(
  249. const struct dc_context *ctx,
  250. struct dm_pp_static_clock_info *static_clk_info);
  251. /****** end of PP interfaces ******/
  252. enum platform_method {
  253. PM_GET_AVAILABLE_METHODS = 1 << 0,
  254. PM_GET_LID_STATE = 1 << 1,
  255. PM_GET_EXTENDED_BRIGHNESS_CAPS = 1 << 2
  256. };
  257. struct platform_info_params {
  258. enum platform_method method;
  259. void *data;
  260. };
  261. struct platform_info_brightness_caps {
  262. uint8_t ac_level_percentage;
  263. uint8_t dc_level_percentage;
  264. };
  265. struct platform_info_ext_brightness_caps {
  266. struct platform_info_brightness_caps basic_caps;
  267. struct data_point {
  268. uint8_t luminance;
  269. uint8_t signal_level;
  270. } data_points[99];
  271. uint8_t data_points_num;
  272. uint8_t min_input_signal;
  273. uint8_t max_input_signal;
  274. };
  275. bool dm_get_platform_info(
  276. struct dc_context *ctx,
  277. struct platform_info_params *params);
  278. struct persistent_data_flag {
  279. bool save_per_link;
  280. bool save_per_edid;
  281. };
  282. /* Call to write data in registry editor for persistent data storage.
  283. *
  284. * \inputs sink - identify edid/link for registry folder creation
  285. * module name - identify folders for registry
  286. * key name - identify keys within folders for registry
  287. * params - value to write in defined folder/key
  288. * size - size of the input params
  289. * flag - determine whether to save by link or edid
  290. *
  291. * \returns true - call is successful
  292. * false - call failed
  293. *
  294. * sink module key
  295. * -----------------------------------------------------------------------------
  296. * NULL NULL NULL - failure
  297. * NULL NULL - - create key with param value
  298. * under base folder
  299. * NULL - NULL - create module folder under base folder
  300. * - NULL NULL - failure
  301. * NULL - - - create key under module folder
  302. * with no edid/link identification
  303. * - NULL - - create key with param value
  304. * under base folder
  305. * - - NULL - create module folder under base folder
  306. * - - - - create key under module folder
  307. * with edid/link identification
  308. */
  309. bool dm_write_persistent_data(struct dc_context *ctx,
  310. const struct dc_sink *sink,
  311. const char *module_name,
  312. const char *key_name,
  313. void *params,
  314. unsigned int size,
  315. struct persistent_data_flag *flag);
  316. /* Call to read data in registry editor for persistent data storage.
  317. *
  318. * \inputs sink - identify edid/link for registry folder creation
  319. * module name - identify folders for registry
  320. * key name - identify keys within folders for registry
  321. * size - size of the output params
  322. * flag - determine whether it was save by link or edid
  323. *
  324. * \returns params - value read from defined folder/key
  325. * true - call is successful
  326. * false - call failed
  327. *
  328. * sink module key
  329. * -----------------------------------------------------------------------------
  330. * NULL NULL NULL - failure
  331. * NULL NULL - - read key under base folder
  332. * NULL - NULL - failure
  333. * - NULL NULL - failure
  334. * NULL - - - read key under module folder
  335. * with no edid/link identification
  336. * - NULL - - read key under base folder
  337. * - - NULL - failure
  338. * - - - - read key under module folder
  339. * with edid/link identification
  340. */
  341. bool dm_read_persistent_data(struct dc_context *ctx,
  342. const struct dc_sink *sink,
  343. const char *module_name,
  344. const char *key_name,
  345. void *params,
  346. unsigned int size,
  347. struct persistent_data_flag *flag);
  348. void dm_delay_in_microseconds
  349. (struct dc_context *ctx, unsigned int microSeconds);
  350. bool dm_query_extended_brightness_caps
  351. (struct dc_context *ctx, enum dm_acpi_display_type display,
  352. struct dm_acpi_atif_backlight_caps *pCaps);
  353. bool dm_dmcu_set_pipe(struct dc_context *ctx, unsigned int controller_id);
  354. /*
  355. *
  356. * print-out services
  357. *
  358. */
  359. #define dm_log_to_buffer(buffer, size, fmt, args)\
  360. vsnprintf(buffer, size, fmt, args)
  361. long dm_get_pid(void);
  362. long dm_get_tgid(void);
  363. #endif /* __DM_SERVICES_H__ */