wndwc37e.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386
  1. /*
  2. * Copyright 2018 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. #include "wndw.h"
  23. #include "atom.h"
  24. #include <drm/drm_atomic_helper.h>
  25. #include <nouveau_bo.h>
  26. #include <nvif/if0014.h>
  27. #include <nvif/pushc37b.h>
  28. #include <nvhw/class/clc37e.h>
  29. static int
  30. wndwc37e_csc_clr(struct nv50_wndw *wndw)
  31. {
  32. return 0;
  33. }
  34. static int
  35. wndwc37e_csc_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw)
  36. {
  37. struct nvif_push *push = wndw->wndw.push;
  38. int ret;
  39. if ((ret = PUSH_WAIT(push, 13)))
  40. return ret;
  41. PUSH_MTHD(push, NVC37E, SET_CSC_RED2RED, asyw->csc.matrix, 12);
  42. return 0;
  43. }
  44. static int
  45. wndwc37e_ilut_clr(struct nv50_wndw *wndw)
  46. {
  47. struct nvif_push *push = wndw->wndw.push;
  48. int ret;
  49. if ((ret = PUSH_WAIT(push, 2)))
  50. return ret;
  51. PUSH_MTHD(push, NVC37E, SET_CONTEXT_DMA_INPUT_LUT, 0x00000000);
  52. return 0;
  53. }
  54. static int
  55. wndwc37e_ilut_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw)
  56. {
  57. struct nvif_push *push = wndw->wndw.push;
  58. int ret;
  59. if ((ret = PUSH_WAIT(push, 4)))
  60. return ret;
  61. PUSH_MTHD(push, NVC37E, SET_CONTROL_INPUT_LUT,
  62. NVVAL(NVC37E, SET_CONTROL_INPUT_LUT, OUTPUT_MODE, asyw->xlut.i.output_mode) |
  63. NVVAL(NVC37E, SET_CONTROL_INPUT_LUT, RANGE, asyw->xlut.i.range) |
  64. NVVAL(NVC37E, SET_CONTROL_INPUT_LUT, SIZE, asyw->xlut.i.size),
  65. SET_OFFSET_INPUT_LUT, asyw->xlut.i.offset >> 8,
  66. SET_CONTEXT_DMA_INPUT_LUT, asyw->xlut.handle);
  67. return 0;
  68. }
  69. static void
  70. wndwc37e_ilut(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw, int size)
  71. {
  72. asyw->xlut.i.size = size == 1024 ? NVC37E_SET_CONTROL_INPUT_LUT_SIZE_SIZE_1025 :
  73. NVC37E_SET_CONTROL_INPUT_LUT_SIZE_SIZE_257;
  74. asyw->xlut.i.range = NVC37E_SET_CONTROL_INPUT_LUT_RANGE_UNITY;
  75. asyw->xlut.i.output_mode = NVC37E_SET_CONTROL_INPUT_LUT_OUTPUT_MODE_INTERPOLATE;
  76. asyw->xlut.i.load = head907d_olut_load;
  77. }
  78. int
  79. wndwc37e_blend_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw)
  80. {
  81. struct nvif_push *push = wndw->wndw.push;
  82. int ret;
  83. if ((ret = PUSH_WAIT(push, 8)))
  84. return ret;
  85. PUSH_MTHD(push, NVC37E, SET_COMPOSITION_CONTROL,
  86. NVDEF(NVC37E, SET_COMPOSITION_CONTROL, COLOR_KEY_SELECT, DISABLE) |
  87. NVVAL(NVC37E, SET_COMPOSITION_CONTROL, DEPTH, asyw->blend.depth),
  88. SET_COMPOSITION_CONSTANT_ALPHA,
  89. NVVAL(NVC37E, SET_COMPOSITION_CONSTANT_ALPHA, K1, asyw->blend.k1) |
  90. NVVAL(NVC37E, SET_COMPOSITION_CONSTANT_ALPHA, K2, 0),
  91. SET_COMPOSITION_FACTOR_SELECT,
  92. NVVAL(NVC37E, SET_COMPOSITION_FACTOR_SELECT, SRC_COLOR_FACTOR_MATCH_SELECT,
  93. asyw->blend.src_color) |
  94. NVVAL(NVC37E, SET_COMPOSITION_FACTOR_SELECT, SRC_COLOR_FACTOR_NO_MATCH_SELECT,
  95. asyw->blend.src_color) |
  96. NVVAL(NVC37E, SET_COMPOSITION_FACTOR_SELECT, DST_COLOR_FACTOR_MATCH_SELECT,
  97. asyw->blend.dst_color) |
  98. NVVAL(NVC37E, SET_COMPOSITION_FACTOR_SELECT, DST_COLOR_FACTOR_NO_MATCH_SELECT,
  99. asyw->blend.dst_color),
  100. SET_KEY_ALPHA,
  101. NVVAL(NVC37E, SET_KEY_ALPHA, MIN, 0x0000) |
  102. NVVAL(NVC37E, SET_KEY_ALPHA, MAX, 0xffff),
  103. SET_KEY_RED_CR,
  104. NVVAL(NVC37E, SET_KEY_RED_CR, MIN, 0x0000) |
  105. NVVAL(NVC37E, SET_KEY_RED_CR, MAX, 0xffff),
  106. SET_KEY_GREEN_Y,
  107. NVVAL(NVC37E, SET_KEY_GREEN_Y, MIN, 0x0000) |
  108. NVVAL(NVC37E, SET_KEY_GREEN_Y, MAX, 0xffff),
  109. SET_KEY_BLUE_CB,
  110. NVVAL(NVC37E, SET_KEY_BLUE_CB, MIN, 0x0000) |
  111. NVVAL(NVC37E, SET_KEY_BLUE_CB, MAX, 0xffff));
  112. return 0;
  113. }
  114. int
  115. wndwc37e_image_clr(struct nv50_wndw *wndw)
  116. {
  117. struct nvif_push *push = wndw->wndw.push;
  118. int ret;
  119. if ((ret = PUSH_WAIT(push, 4)))
  120. return ret;
  121. PUSH_MTHD(push, NVC37E, SET_PRESENT_CONTROL,
  122. NVVAL(NVC37E, SET_PRESENT_CONTROL, MIN_PRESENT_INTERVAL, 0) |
  123. NVDEF(NVC37E, SET_PRESENT_CONTROL, BEGIN_MODE, NON_TEARING));
  124. PUSH_MTHD(push, NVC37E, SET_CONTEXT_DMA_ISO(0), 0x00000000);
  125. return 0;
  126. }
  127. static int
  128. wndwc37e_image_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw)
  129. {
  130. struct nvif_push *push = wndw->wndw.push;
  131. int ret;
  132. if ((ret = PUSH_WAIT(push, 17)))
  133. return ret;
  134. PUSH_MTHD(push, NVC37E, SET_PRESENT_CONTROL,
  135. NVVAL(NVC37E, SET_PRESENT_CONTROL, MIN_PRESENT_INTERVAL, asyw->image.interval) |
  136. NVVAL(NVC37E, SET_PRESENT_CONTROL, BEGIN_MODE, asyw->image.mode) |
  137. NVDEF(NVC37E, SET_PRESENT_CONTROL, TIMESTAMP_MODE, DISABLE));
  138. PUSH_MTHD(push, NVC37E, SET_SIZE,
  139. NVVAL(NVC37E, SET_SIZE, WIDTH, asyw->image.w) |
  140. NVVAL(NVC37E, SET_SIZE, HEIGHT, asyw->image.h),
  141. SET_STORAGE,
  142. NVVAL(NVC37E, SET_STORAGE, BLOCK_HEIGHT, asyw->image.blockh) |
  143. NVVAL(NVC37E, SET_STORAGE, MEMORY_LAYOUT, asyw->image.layout),
  144. SET_PARAMS,
  145. NVVAL(NVC37E, SET_PARAMS, FORMAT, asyw->image.format) |
  146. NVVAL(NVC37E, SET_PARAMS, COLOR_SPACE, asyw->image.colorspace) |
  147. NVDEF(NVC37E, SET_PARAMS, INPUT_RANGE, BYPASS) |
  148. NVDEF(NVC37E, SET_PARAMS, UNDERREPLICATE, DISABLE) |
  149. NVDEF(NVC37E, SET_PARAMS, DE_GAMMA, NONE) |
  150. NVVAL(NVC37E, SET_PARAMS, CSC, asyw->csc.valid) |
  151. NVDEF(NVC37E, SET_PARAMS, CLAMP_BEFORE_BLEND, DISABLE) |
  152. NVDEF(NVC37E, SET_PARAMS, SWAP_UV, DISABLE),
  153. SET_PLANAR_STORAGE(0),
  154. NVVAL(NVC37E, SET_PLANAR_STORAGE, PITCH, asyw->image.blocks[0]) |
  155. NVVAL(NVC37E, SET_PLANAR_STORAGE, PITCH, asyw->image.pitch[0] >> 6));
  156. PUSH_MTHD(push, NVC37E, SET_CONTEXT_DMA_ISO(0), asyw->image.handle, 1);
  157. PUSH_MTHD(push, NVC37E, SET_OFFSET(0), asyw->image.offset[0] >> 8);
  158. PUSH_MTHD(push, NVC37E, SET_POINT_IN(0),
  159. NVVAL(NVC37E, SET_POINT_IN, X, asyw->state.src_x >> 16) |
  160. NVVAL(NVC37E, SET_POINT_IN, Y, asyw->state.src_y >> 16));
  161. PUSH_MTHD(push, NVC37E, SET_SIZE_IN,
  162. NVVAL(NVC37E, SET_SIZE_IN, WIDTH, asyw->state.src_w >> 16) |
  163. NVVAL(NVC37E, SET_SIZE_IN, HEIGHT, asyw->state.src_h >> 16));
  164. PUSH_MTHD(push, NVC37E, SET_SIZE_OUT,
  165. NVVAL(NVC37E, SET_SIZE_OUT, WIDTH, asyw->state.crtc_w) |
  166. NVVAL(NVC37E, SET_SIZE_OUT, HEIGHT, asyw->state.crtc_h));
  167. return 0;
  168. }
  169. int
  170. wndwc37e_ntfy_clr(struct nv50_wndw *wndw)
  171. {
  172. struct nvif_push *push = wndw->wndw.push;
  173. int ret;
  174. if ((ret = PUSH_WAIT(push, 2)))
  175. return ret;
  176. PUSH_MTHD(push, NVC37E, SET_CONTEXT_DMA_NOTIFIER, 0x00000000);
  177. return 0;
  178. }
  179. int
  180. wndwc37e_ntfy_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw)
  181. {
  182. struct nvif_push *push = wndw->wndw.push;
  183. int ret;
  184. if ((ret = PUSH_WAIT(push, 3)))
  185. return ret;
  186. PUSH_MTHD(push, NVC37E, SET_CONTEXT_DMA_NOTIFIER, asyw->ntfy.handle,
  187. SET_NOTIFIER_CONTROL,
  188. NVVAL(NVC37E, SET_NOTIFIER_CONTROL, MODE, asyw->ntfy.awaken) |
  189. NVVAL(NVC37E, SET_NOTIFIER_CONTROL, OFFSET, asyw->ntfy.offset >> 4));
  190. return 0;
  191. }
  192. int
  193. wndwc37e_sema_clr(struct nv50_wndw *wndw)
  194. {
  195. struct nvif_push *push = wndw->wndw.push;
  196. int ret;
  197. if ((ret = PUSH_WAIT(push, 2)))
  198. return ret;
  199. PUSH_MTHD(push, NVC37E, SET_CONTEXT_DMA_SEMAPHORE, 0x00000000);
  200. return 0;
  201. }
  202. int
  203. wndwc37e_sema_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw)
  204. {
  205. struct nvif_push *push = wndw->wndw.push;
  206. int ret;
  207. if ((ret = PUSH_WAIT(push, 5)))
  208. return ret;
  209. PUSH_MTHD(push, NVC37E, SET_SEMAPHORE_CONTROL, asyw->sema.offset,
  210. SET_SEMAPHORE_ACQUIRE, asyw->sema.acquire,
  211. SET_SEMAPHORE_RELEASE, asyw->sema.release,
  212. SET_CONTEXT_DMA_SEMAPHORE, asyw->sema.handle);
  213. return 0;
  214. }
  215. int
  216. wndwc37e_update(struct nv50_wndw *wndw, u32 *interlock)
  217. {
  218. struct nvif_push *push = wndw->wndw.push;
  219. int ret;
  220. if ((ret = PUSH_WAIT(push, 5)))
  221. return ret;
  222. PUSH_MTHD(push, NVC37E, SET_INTERLOCK_FLAGS, interlock[NV50_DISP_INTERLOCK_CURS] << 1 |
  223. interlock[NV50_DISP_INTERLOCK_CORE],
  224. SET_WINDOW_INTERLOCK_FLAGS, interlock[NV50_DISP_INTERLOCK_WNDW]);
  225. PUSH_MTHD(push, NVC37E, UPDATE, 0x00000001 |
  226. NVVAL(NVC37E, UPDATE, INTERLOCK_WITH_WIN_IMM,
  227. !!(interlock[NV50_DISP_INTERLOCK_WIMM] & wndw->interlock.data)));
  228. return PUSH_KICK(push);
  229. }
  230. void
  231. wndwc37e_release(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw,
  232. struct nv50_head_atom *asyh)
  233. {
  234. }
  235. int
  236. wndwc37e_acquire(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw,
  237. struct nv50_head_atom *asyh)
  238. {
  239. return drm_atomic_helper_check_plane_state(&asyw->state, &asyh->state,
  240. DRM_PLANE_NO_SCALING,
  241. DRM_PLANE_NO_SCALING,
  242. true, true);
  243. }
  244. static const u32
  245. wndwc37e_format[] = {
  246. DRM_FORMAT_C8,
  247. DRM_FORMAT_YUYV,
  248. DRM_FORMAT_UYVY,
  249. DRM_FORMAT_XRGB8888,
  250. DRM_FORMAT_ARGB8888,
  251. DRM_FORMAT_RGB565,
  252. DRM_FORMAT_XRGB1555,
  253. DRM_FORMAT_ARGB1555,
  254. DRM_FORMAT_XBGR2101010,
  255. DRM_FORMAT_ABGR2101010,
  256. DRM_FORMAT_XBGR8888,
  257. DRM_FORMAT_ABGR8888,
  258. DRM_FORMAT_XRGB2101010,
  259. DRM_FORMAT_ARGB2101010,
  260. DRM_FORMAT_XBGR16161616F,
  261. DRM_FORMAT_ABGR16161616F,
  262. 0
  263. };
  264. static const struct nv50_wndw_func
  265. wndwc37e = {
  266. .acquire = wndwc37e_acquire,
  267. .release = wndwc37e_release,
  268. .sema_set = wndwc37e_sema_set,
  269. .sema_clr = wndwc37e_sema_clr,
  270. .ntfy_set = wndwc37e_ntfy_set,
  271. .ntfy_clr = wndwc37e_ntfy_clr,
  272. .ntfy_reset = corec37d_ntfy_init,
  273. .ntfy_wait_begun = base507c_ntfy_wait_begun,
  274. .ilut = wndwc37e_ilut,
  275. .ilut_size = 1024,
  276. .xlut_set = wndwc37e_ilut_set,
  277. .xlut_clr = wndwc37e_ilut_clr,
  278. .csc = base907c_csc,
  279. .csc_set = wndwc37e_csc_set,
  280. .csc_clr = wndwc37e_csc_clr,
  281. .image_set = wndwc37e_image_set,
  282. .image_clr = wndwc37e_image_clr,
  283. .blend_set = wndwc37e_blend_set,
  284. .update = wndwc37e_update,
  285. };
  286. int
  287. wndwc37e_new_(const struct nv50_wndw_func *func, struct nouveau_drm *drm,
  288. enum drm_plane_type type, int index, s32 oclass, u32 heads,
  289. struct nv50_wndw **pwndw)
  290. {
  291. struct nvif_disp_chan_v0 args = {
  292. .id = index,
  293. };
  294. struct nv50_disp *disp = nv50_disp(drm->dev);
  295. struct nv50_wndw *wndw;
  296. int ret;
  297. ret = nv50_wndw_new_(func, drm->dev, type, "wndw", index,
  298. wndwc37e_format, heads, NV50_DISP_INTERLOCK_WNDW,
  299. BIT(index), &wndw);
  300. if (*pwndw = wndw, ret)
  301. return ret;
  302. ret = nv50_dmac_create(&drm->client.device, &disp->disp->object,
  303. &oclass, 0, &args, sizeof(args),
  304. disp->sync->offset, &wndw->wndw);
  305. if (ret) {
  306. NV_ERROR(drm, "qndw%04x allocation failed: %d\n", oclass, ret);
  307. return ret;
  308. }
  309. wndw->ntfy = NV50_DISP_WNDW_NTFY(wndw->id);
  310. wndw->sema = NV50_DISP_WNDW_SEM0(wndw->id);
  311. wndw->data = 0x00000000;
  312. return 0;
  313. }
  314. int
  315. wndwc37e_new(struct nouveau_drm *drm, enum drm_plane_type type, int index,
  316. s32 oclass, struct nv50_wndw **pwndw)
  317. {
  318. return wndwc37e_new_(&wndwc37e, drm, type, index, oclass,
  319. BIT(index >> 1), pwndw);
  320. }