nouveau_pm.h 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283
  1. /*
  2. * Copyright 2010 Red Hat 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: Ben Skeggs
  23. */
  24. #ifndef __NOUVEAU_PM_H__
  25. #define __NOUVEAU_PM_H__
  26. #include <subdev/bios/pll.h>
  27. #include <subdev/clock.h>
  28. struct nouveau_pm_voltage_level {
  29. u32 voltage; /* microvolts */
  30. u8 vid;
  31. };
  32. struct nouveau_pm_voltage {
  33. bool supported;
  34. u8 version;
  35. u8 vid_mask;
  36. struct nouveau_pm_voltage_level *level;
  37. int nr_level;
  38. };
  39. /* Exclusive upper limits */
  40. #define NV_MEM_CL_DDR2_MAX 8
  41. #define NV_MEM_WR_DDR2_MAX 9
  42. #define NV_MEM_CL_DDR3_MAX 17
  43. #define NV_MEM_WR_DDR3_MAX 17
  44. #define NV_MEM_CL_GDDR3_MAX 16
  45. #define NV_MEM_WR_GDDR3_MAX 18
  46. #define NV_MEM_CL_GDDR5_MAX 21
  47. #define NV_MEM_WR_GDDR5_MAX 20
  48. struct nouveau_pm_memtiming {
  49. int id;
  50. u32 reg[9];
  51. u32 mr[4];
  52. u8 tCWL;
  53. u8 odt;
  54. u8 drive_strength;
  55. };
  56. struct nouveau_pm_tbl_header {
  57. u8 version;
  58. u8 header_len;
  59. u8 entry_cnt;
  60. u8 entry_len;
  61. };
  62. struct nouveau_pm_tbl_entry {
  63. u8 tWR;
  64. u8 tWTR;
  65. u8 tCL;
  66. u8 tRC;
  67. u8 empty_4;
  68. u8 tRFC; /* Byte 5 */
  69. u8 empty_6;
  70. u8 tRAS; /* Byte 7 */
  71. u8 empty_8;
  72. u8 tRP; /* Byte 9 */
  73. u8 tRCDRD;
  74. u8 tRCDWR;
  75. u8 tRRD;
  76. u8 tUNK_13;
  77. u8 RAM_FT1; /* 14, a bitmask of random RAM features */
  78. u8 empty_15;
  79. u8 tUNK_16;
  80. u8 empty_17;
  81. u8 tUNK_18;
  82. u8 tCWL;
  83. u8 tUNK_20, tUNK_21;
  84. };
  85. struct nouveau_pm_profile;
  86. struct nouveau_pm_profile_func {
  87. void (*destroy)(struct nouveau_pm_profile *);
  88. void (*init)(struct nouveau_pm_profile *);
  89. void (*fini)(struct nouveau_pm_profile *);
  90. struct nouveau_pm_level *(*select)(struct nouveau_pm_profile *);
  91. };
  92. struct nouveau_pm_profile {
  93. const struct nouveau_pm_profile_func *func;
  94. struct list_head head;
  95. char name[8];
  96. };
  97. #define NOUVEAU_PM_MAX_LEVEL 8
  98. struct nouveau_pm_level {
  99. struct nouveau_pm_profile profile;
  100. struct device_attribute dev_attr;
  101. char name[32];
  102. int id;
  103. struct nouveau_pm_memtiming timing;
  104. u32 memory;
  105. u16 memscript;
  106. u32 core;
  107. u32 shader;
  108. u32 rop;
  109. u32 copy;
  110. u32 daemon;
  111. u32 vdec;
  112. u32 dom6;
  113. u32 unka0; /* nva3:nvc0 */
  114. u32 hub01; /* nvc0- */
  115. u32 hub06; /* nvc0- */
  116. u32 hub07; /* nvc0- */
  117. u32 volt_min; /* microvolts */
  118. u32 volt_max;
  119. u8 fanspeed;
  120. };
  121. struct nouveau_pm_temp_sensor_constants {
  122. u16 offset_constant;
  123. s16 offset_mult;
  124. s16 offset_div;
  125. s16 slope_mult;
  126. s16 slope_div;
  127. };
  128. struct nouveau_pm_threshold_temp {
  129. s16 critical;
  130. s16 down_clock;
  131. };
  132. struct nouveau_pm {
  133. struct drm_device *dev;
  134. struct nouveau_pm_voltage voltage;
  135. struct nouveau_pm_level perflvl[NOUVEAU_PM_MAX_LEVEL];
  136. int nr_perflvl;
  137. struct nouveau_pm_temp_sensor_constants sensor_constants;
  138. struct nouveau_pm_threshold_temp threshold_temp;
  139. struct nouveau_pm_profile *profile_ac;
  140. struct nouveau_pm_profile *profile_dc;
  141. struct nouveau_pm_profile *profile;
  142. struct list_head profiles;
  143. struct nouveau_pm_level boot;
  144. struct nouveau_pm_level *cur;
  145. struct device *hwmon;
  146. struct notifier_block acpi_nb;
  147. int (*clocks_get)(struct drm_device *, struct nouveau_pm_level *);
  148. void *(*clocks_pre)(struct drm_device *, struct nouveau_pm_level *);
  149. int (*clocks_set)(struct drm_device *, void *);
  150. int (*voltage_get)(struct drm_device *);
  151. int (*voltage_set)(struct drm_device *, int voltage);
  152. };
  153. static inline struct nouveau_pm *
  154. nouveau_pm(struct drm_device *dev)
  155. {
  156. return nouveau_drm(dev)->pm;
  157. }
  158. struct nouveau_mem_exec_func {
  159. struct drm_device *dev;
  160. void (*precharge)(struct nouveau_mem_exec_func *);
  161. void (*refresh)(struct nouveau_mem_exec_func *);
  162. void (*refresh_auto)(struct nouveau_mem_exec_func *, bool);
  163. void (*refresh_self)(struct nouveau_mem_exec_func *, bool);
  164. void (*wait)(struct nouveau_mem_exec_func *, u32 nsec);
  165. u32 (*mrg)(struct nouveau_mem_exec_func *, int mr);
  166. void (*mrs)(struct nouveau_mem_exec_func *, int mr, u32 data);
  167. void (*clock_set)(struct nouveau_mem_exec_func *);
  168. void (*timing_set)(struct nouveau_mem_exec_func *);
  169. void *priv;
  170. };
  171. /* nouveau_mem.c */
  172. int nouveau_mem_exec(struct nouveau_mem_exec_func *,
  173. struct nouveau_pm_level *);
  174. /* nouveau_pm.c */
  175. int nouveau_pm_init(struct drm_device *dev);
  176. void nouveau_pm_fini(struct drm_device *dev);
  177. void nouveau_pm_resume(struct drm_device *dev);
  178. extern const struct nouveau_pm_profile_func nouveau_pm_static_profile_func;
  179. void nouveau_pm_trigger(struct drm_device *dev);
  180. /* nouveau_volt.c */
  181. void nouveau_volt_init(struct drm_device *);
  182. void nouveau_volt_fini(struct drm_device *);
  183. int nouveau_volt_vid_lookup(struct drm_device *, int voltage);
  184. int nouveau_volt_lvl_lookup(struct drm_device *, int vid);
  185. int nouveau_voltage_gpio_get(struct drm_device *);
  186. int nouveau_voltage_gpio_set(struct drm_device *, int voltage);
  187. /* nouveau_perf.c */
  188. void nouveau_perf_init(struct drm_device *);
  189. void nouveau_perf_fini(struct drm_device *);
  190. u8 *nouveau_perf_rammap(struct drm_device *, u32 freq, u8 *ver,
  191. u8 *hdr, u8 *cnt, u8 *len);
  192. u8 *nouveau_perf_ramcfg(struct drm_device *, u32 freq, u8 *ver, u8 *len);
  193. u8 *nouveau_perf_timing(struct drm_device *, u32 freq, u8 *ver, u8 *len);
  194. /* nouveau_mem.c */
  195. void nouveau_mem_timing_init(struct drm_device *);
  196. void nouveau_mem_timing_fini(struct drm_device *);
  197. /* nv04_pm.c */
  198. int nv04_pm_clocks_get(struct drm_device *, struct nouveau_pm_level *);
  199. void *nv04_pm_clocks_pre(struct drm_device *, struct nouveau_pm_level *);
  200. int nv04_pm_clocks_set(struct drm_device *, void *);
  201. /* nv40_pm.c */
  202. int nv40_pm_clocks_get(struct drm_device *, struct nouveau_pm_level *);
  203. void *nv40_pm_clocks_pre(struct drm_device *, struct nouveau_pm_level *);
  204. int nv40_pm_clocks_set(struct drm_device *, void *);
  205. int nv40_pm_pwm_get(struct drm_device *, int, u32 *, u32 *);
  206. int nv40_pm_pwm_set(struct drm_device *, int, u32, u32);
  207. /* nv50_pm.c */
  208. int nv50_pm_clocks_get(struct drm_device *, struct nouveau_pm_level *);
  209. void *nv50_pm_clocks_pre(struct drm_device *, struct nouveau_pm_level *);
  210. int nv50_pm_clocks_set(struct drm_device *, void *);
  211. int nv50_pm_pwm_get(struct drm_device *, int, u32 *, u32 *);
  212. int nv50_pm_pwm_set(struct drm_device *, int, u32, u32);
  213. /* nva3_pm.c */
  214. int nva3_pm_clocks_get(struct drm_device *, struct nouveau_pm_level *);
  215. void *nva3_pm_clocks_pre(struct drm_device *, struct nouveau_pm_level *);
  216. int nva3_pm_clocks_set(struct drm_device *, void *);
  217. /* nvc0_pm.c */
  218. int nvc0_pm_clocks_get(struct drm_device *, struct nouveau_pm_level *);
  219. void *nvc0_pm_clocks_pre(struct drm_device *, struct nouveau_pm_level *);
  220. int nvc0_pm_clocks_set(struct drm_device *, void *);
  221. /* nouveau_mem.c */
  222. int nouveau_mem_timing_calc(struct drm_device *, u32 freq,
  223. struct nouveau_pm_memtiming *);
  224. void nouveau_mem_timing_read(struct drm_device *,
  225. struct nouveau_pm_memtiming *);
  226. static inline int
  227. nva3_calc_pll(struct drm_device *dev, struct nvbios_pll *pll, u32 freq,
  228. int *N, int *fN, int *M, int *P)
  229. {
  230. struct nouveau_device *device = nouveau_dev(dev);
  231. struct nouveau_clock *clk = nouveau_clock(device);
  232. struct nouveau_pll_vals pv;
  233. int ret;
  234. ret = clk->pll_calc(clk, pll, freq, &pv);
  235. *N = pv.N1;
  236. *M = pv.M1;
  237. *P = pv.log2P;
  238. return ret;
  239. }
  240. #endif