Back to home page

OSCL-LXR

 
 

    


0001 /*
0002  * Copyright 2018 Red Hat Inc.
0003  *
0004  * Permission is hereby granted, free of charge, to any person obtaining a
0005  * copy of this software and associated documentation files (the "Software"),
0006  * to deal in the Software without restriction, including without limitation
0007  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
0008  * and/or sell copies of the Software, and to permit persons to whom the
0009  * Software is furnished to do so, subject to the following conditions:
0010  *
0011  * The above copyright notice and this permission notice shall be included in
0012  * all copies or substantial portions of the Software.
0013  *
0014  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
0015  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
0016  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
0017  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
0018  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
0019  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
0020  * OTHER DEALINGS IN THE SOFTWARE.
0021  */
0022 #include "ovly.h"
0023 #include "atom.h"
0024 
0025 #include <drm/drm_atomic_helper.h>
0026 #include <drm/drm_fourcc.h>
0027 #include <drm/drm_plane_helper.h>
0028 
0029 #include <nvif/if0014.h>
0030 #include <nvif/push507c.h>
0031 
0032 #include <nvhw/class/cl507e.h>
0033 
0034 int
0035 ovly507e_scale_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw)
0036 {
0037     struct nvif_push *push = wndw->wndw.push;
0038     int ret;
0039 
0040     if ((ret = PUSH_WAIT(push, 4)))
0041         return ret;
0042 
0043     PUSH_MTHD(push, NV507E, SET_POINT_IN,
0044           NVVAL(NV507E, SET_POINT_IN, X, asyw->scale.sx) |
0045           NVVAL(NV507E, SET_POINT_IN, Y, asyw->scale.sy),
0046 
0047                 SET_SIZE_IN,
0048           NVVAL(NV507E, SET_SIZE_IN, WIDTH, asyw->scale.sw) |
0049           NVVAL(NV507E, SET_SIZE_IN, HEIGHT, asyw->scale.sh),
0050 
0051                 SET_SIZE_OUT,
0052           NVVAL(NV507E, SET_SIZE_OUT, WIDTH, asyw->scale.dw));
0053     return 0;
0054 }
0055 
0056 static int
0057 ovly507e_image_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw)
0058 {
0059     struct nvif_push *push = wndw->wndw.push;
0060     int ret;
0061 
0062     if ((ret = PUSH_WAIT(push, 12)))
0063         return ret;
0064 
0065     PUSH_MTHD(push, NV507E, SET_PRESENT_CONTROL,
0066           NVDEF(NV507E, SET_PRESENT_CONTROL, BEGIN_MODE, ASAP) |
0067           NVVAL(NV507E, SET_PRESENT_CONTROL, MIN_PRESENT_INTERVAL, asyw->image.interval));
0068 
0069     PUSH_MTHD(push, NV507E, SET_CONTEXT_DMA_ISO, asyw->image.handle[0]);
0070 
0071     PUSH_MTHD(push, NV507E, SET_COMPOSITION_CONTROL,
0072           NVDEF(NV507E, SET_COMPOSITION_CONTROL, MODE, OPAQUE_SUSPEND_BASE));
0073 
0074     PUSH_MTHD(push, NV507E, SURFACE_SET_OFFSET, asyw->image.offset[0] >> 8);
0075 
0076     PUSH_MTHD(push, NV507E, SURFACE_SET_SIZE,
0077           NVVAL(NV507E, SURFACE_SET_SIZE, WIDTH, asyw->image.w) |
0078           NVVAL(NV507E, SURFACE_SET_SIZE, HEIGHT, asyw->image.h),
0079 
0080                 SURFACE_SET_STORAGE,
0081           NVVAL(NV507E, SURFACE_SET_STORAGE, BLOCK_HEIGHT, asyw->image.blockh) |
0082           NVVAL(NV507E, SURFACE_SET_STORAGE, PITCH, (asyw->image.pitch[0] >> 8)) |
0083           NVVAL(NV507E, SURFACE_SET_STORAGE, PITCH, asyw->image.blocks[0]) |
0084           NVVAL(NV507E, SURFACE_SET_STORAGE, MEMORY_LAYOUT, asyw->image.layout),
0085 
0086                 SURFACE_SET_PARAMS,
0087           NVVAL(NV507E, SURFACE_SET_PARAMS, FORMAT, asyw->image.format) |
0088           NVVAL(NV507E, SURFACE_SET_PARAMS, COLOR_SPACE, asyw->image.colorspace) |
0089           NVVAL(NV507E, SURFACE_SET_PARAMS, KIND, asyw->image.kind) |
0090           NVDEF(NV507E, SURFACE_SET_PARAMS, PART_STRIDE, PARTSTRIDE_256));
0091     return 0;
0092 }
0093 
0094 void
0095 ovly507e_release(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw,
0096          struct nv50_head_atom *asyh)
0097 {
0098     asyh->ovly.cpp = 0;
0099 }
0100 
0101 int
0102 ovly507e_acquire(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw,
0103          struct nv50_head_atom *asyh)
0104 {
0105     const struct drm_framebuffer *fb = asyw->state.fb;
0106     int ret;
0107 
0108     ret = drm_atomic_helper_check_plane_state(&asyw->state, &asyh->state,
0109                           DRM_PLANE_HELPER_NO_SCALING,
0110                           DRM_PLANE_HELPER_NO_SCALING,
0111                           true, true);
0112     if (ret)
0113         return ret;
0114 
0115     asyh->ovly.cpp = fb->format->cpp[0];
0116     return 0;
0117 }
0118 
0119 #include "nouveau_bo.h"
0120 
0121 static const struct nv50_wndw_func
0122 ovly507e = {
0123     .acquire = ovly507e_acquire,
0124     .release = ovly507e_release,
0125     .ntfy_set = base507c_ntfy_set,
0126     .ntfy_clr = base507c_ntfy_clr,
0127     .ntfy_reset = base507c_ntfy_reset,
0128     .ntfy_wait_begun = base507c_ntfy_wait_begun,
0129     .image_set = ovly507e_image_set,
0130     .image_clr = base507c_image_clr,
0131     .scale_set = ovly507e_scale_set,
0132     .update = base507c_update,
0133 };
0134 
0135 static const u32
0136 ovly507e_format[] = {
0137     DRM_FORMAT_YUYV,
0138     DRM_FORMAT_UYVY,
0139     DRM_FORMAT_XRGB8888,
0140     DRM_FORMAT_XRGB1555,
0141     0
0142 };
0143 
0144 int
0145 ovly507e_new_(const struct nv50_wndw_func *func, const u32 *format,
0146           struct nouveau_drm *drm, int head, s32 oclass, u32 interlock_data,
0147           struct nv50_wndw **pwndw)
0148 {
0149     struct nvif_disp_chan_v0 args = {
0150         .id = head,
0151     };
0152     struct nv50_disp *disp = nv50_disp(drm->dev);
0153     struct nv50_wndw *wndw;
0154     int ret;
0155 
0156     ret = nv50_wndw_new_(func, drm->dev, DRM_PLANE_TYPE_OVERLAY,
0157                  "ovly", head, format, BIT(head),
0158                  NV50_DISP_INTERLOCK_OVLY, interlock_data,
0159                  &wndw);
0160     if (*pwndw = wndw, ret)
0161         return ret;
0162 
0163     ret = nv50_dmac_create(&drm->client.device, &disp->disp->object,
0164                    &oclass, 0, &args, sizeof(args),
0165                    disp->sync->offset, &wndw->wndw);
0166     if (ret) {
0167         NV_ERROR(drm, "ovly%04x allocation failed: %d\n", oclass, ret);
0168         return ret;
0169     }
0170 
0171     wndw->ntfy = NV50_DISP_OVLY_NTFY(wndw->id);
0172     wndw->sema = NV50_DISP_OVLY_SEM0(wndw->id);
0173     wndw->data = 0x00000000;
0174     return 0;
0175 }
0176 
0177 int
0178 ovly507e_new(struct nouveau_drm *drm, int head, s32 oclass,
0179          struct nv50_wndw **pwndw)
0180 {
0181     return ovly507e_new_(&ovly507e, ovly507e_format, drm, head, oclass,
0182                  0x00000004 << (head * 8), pwndw);
0183 }