ovly507e.c 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  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 "ovly.h"
  23. #include "atom.h"
  24. #include <drm/drm_atomic_helper.h>
  25. #include <drm/drm_fourcc.h>
  26. #include <nvif/if0014.h>
  27. #include <nvif/push507c.h>
  28. #include <nvhw/class/cl507e.h>
  29. int
  30. ovly507e_scale_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw)
  31. {
  32. struct nvif_push *push = wndw->wndw.push;
  33. int ret;
  34. if ((ret = PUSH_WAIT(push, 4)))
  35. return ret;
  36. PUSH_MTHD(push, NV507E, SET_POINT_IN,
  37. NVVAL(NV507E, SET_POINT_IN, X, asyw->scale.sx) |
  38. NVVAL(NV507E, SET_POINT_IN, Y, asyw->scale.sy),
  39. SET_SIZE_IN,
  40. NVVAL(NV507E, SET_SIZE_IN, WIDTH, asyw->scale.sw) |
  41. NVVAL(NV507E, SET_SIZE_IN, HEIGHT, asyw->scale.sh),
  42. SET_SIZE_OUT,
  43. NVVAL(NV507E, SET_SIZE_OUT, WIDTH, asyw->scale.dw));
  44. return 0;
  45. }
  46. static int
  47. ovly507e_image_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw)
  48. {
  49. struct nvif_push *push = wndw->wndw.push;
  50. int ret;
  51. if ((ret = PUSH_WAIT(push, 12)))
  52. return ret;
  53. PUSH_MTHD(push, NV507E, SET_PRESENT_CONTROL,
  54. NVDEF(NV507E, SET_PRESENT_CONTROL, BEGIN_MODE, ASAP) |
  55. NVVAL(NV507E, SET_PRESENT_CONTROL, MIN_PRESENT_INTERVAL, asyw->image.interval));
  56. PUSH_MTHD(push, NV507E, SET_CONTEXT_DMA_ISO, asyw->image.handle[0]);
  57. PUSH_MTHD(push, NV507E, SET_COMPOSITION_CONTROL,
  58. NVDEF(NV507E, SET_COMPOSITION_CONTROL, MODE, OPAQUE_SUSPEND_BASE));
  59. PUSH_MTHD(push, NV507E, SURFACE_SET_OFFSET, asyw->image.offset[0] >> 8);
  60. PUSH_MTHD(push, NV507E, SURFACE_SET_SIZE,
  61. NVVAL(NV507E, SURFACE_SET_SIZE, WIDTH, asyw->image.w) |
  62. NVVAL(NV507E, SURFACE_SET_SIZE, HEIGHT, asyw->image.h),
  63. SURFACE_SET_STORAGE,
  64. NVVAL(NV507E, SURFACE_SET_STORAGE, BLOCK_HEIGHT, asyw->image.blockh) |
  65. NVVAL(NV507E, SURFACE_SET_STORAGE, PITCH, (asyw->image.pitch[0] >> 8)) |
  66. NVVAL(NV507E, SURFACE_SET_STORAGE, PITCH, asyw->image.blocks[0]) |
  67. NVVAL(NV507E, SURFACE_SET_STORAGE, MEMORY_LAYOUT, asyw->image.layout),
  68. SURFACE_SET_PARAMS,
  69. NVVAL(NV507E, SURFACE_SET_PARAMS, FORMAT, asyw->image.format) |
  70. NVVAL(NV507E, SURFACE_SET_PARAMS, COLOR_SPACE, asyw->image.colorspace) |
  71. NVVAL(NV507E, SURFACE_SET_PARAMS, KIND, asyw->image.kind) |
  72. NVDEF(NV507E, SURFACE_SET_PARAMS, PART_STRIDE, PARTSTRIDE_256));
  73. return 0;
  74. }
  75. void
  76. ovly507e_release(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw,
  77. struct nv50_head_atom *asyh)
  78. {
  79. asyh->ovly.cpp = 0;
  80. }
  81. int
  82. ovly507e_acquire(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw,
  83. struct nv50_head_atom *asyh)
  84. {
  85. const struct drm_framebuffer *fb = asyw->state.fb;
  86. int ret;
  87. ret = drm_atomic_helper_check_plane_state(&asyw->state, &asyh->state,
  88. DRM_PLANE_NO_SCALING,
  89. DRM_PLANE_NO_SCALING,
  90. true, true);
  91. if (ret)
  92. return ret;
  93. asyh->ovly.cpp = fb->format->cpp[0];
  94. return 0;
  95. }
  96. #include "nouveau_bo.h"
  97. static const struct nv50_wndw_func
  98. ovly507e = {
  99. .acquire = ovly507e_acquire,
  100. .release = ovly507e_release,
  101. .ntfy_set = base507c_ntfy_set,
  102. .ntfy_clr = base507c_ntfy_clr,
  103. .ntfy_reset = base507c_ntfy_reset,
  104. .ntfy_wait_begun = base507c_ntfy_wait_begun,
  105. .image_set = ovly507e_image_set,
  106. .image_clr = base507c_image_clr,
  107. .scale_set = ovly507e_scale_set,
  108. .update = base507c_update,
  109. };
  110. static const u32
  111. ovly507e_format[] = {
  112. DRM_FORMAT_YUYV,
  113. DRM_FORMAT_UYVY,
  114. DRM_FORMAT_XRGB8888,
  115. DRM_FORMAT_XRGB1555,
  116. 0
  117. };
  118. int
  119. ovly507e_new_(const struct nv50_wndw_func *func, const u32 *format,
  120. struct nouveau_drm *drm, int head, s32 oclass, u32 interlock_data,
  121. struct nv50_wndw **pwndw)
  122. {
  123. struct nvif_disp_chan_v0 args = {
  124. .id = head,
  125. };
  126. struct nv50_disp *disp = nv50_disp(drm->dev);
  127. struct nv50_wndw *wndw;
  128. int ret;
  129. ret = nv50_wndw_new_(func, drm->dev, DRM_PLANE_TYPE_OVERLAY,
  130. "ovly", head, format, BIT(head),
  131. NV50_DISP_INTERLOCK_OVLY, interlock_data,
  132. &wndw);
  133. if (*pwndw = wndw, ret)
  134. return ret;
  135. ret = nv50_dmac_create(&drm->client.device, &disp->disp->object,
  136. &oclass, 0, &args, sizeof(args),
  137. disp->sync->offset, &wndw->wndw);
  138. if (ret) {
  139. NV_ERROR(drm, "ovly%04x allocation failed: %d\n", oclass, ret);
  140. return ret;
  141. }
  142. wndw->ntfy = NV50_DISP_OVLY_NTFY(wndw->id);
  143. wndw->sema = NV50_DISP_OVLY_SEM0(wndw->id);
  144. wndw->data = 0x00000000;
  145. return 0;
  146. }
  147. int
  148. ovly507e_new(struct nouveau_drm *drm, int head, s32 oclass,
  149. struct nv50_wndw **pwndw)
  150. {
  151. return ovly507e_new_(&ovly507e, ovly507e_format, drm, head, oclass,
  152. 0x00000004 << (head * 8), pwndw);
  153. }