diff --git a/drivers/gpu/drm/nouveau/dispnv50/curs507a.c b/drivers/gpu/drm/nouveau/dispnv50/curs507a.c index 2468e91b36db..babf680c25fd 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/curs507a.c +++ b/drivers/gpu/drm/nouveau/dispnv50/curs507a.c @@ -47,13 +47,15 @@ curs507a_update(struct nv50_wndw *wndw, u32 *interlock) nvif_wr32(&wndw->wimm.base.user, 0x0080, 0x00000000); } -static void +static int curs507a_point(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw) { - if (curs507a_space(wndw)) { + int ret = nvif_chan_wait(&wndw->wimm, 1); + if (ret == 0) { nvif_wr32(&wndw->wimm.base.user, 0x0084, asyw->point.y << 16 | asyw->point.x); } + return ret; } const struct nv50_wimm_func diff --git a/drivers/gpu/drm/nouveau/dispnv50/cursc37a.c b/drivers/gpu/drm/nouveau/dispnv50/cursc37a.c index 96dff4f09f57..45c1c33e950a 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/cursc37a.c +++ b/drivers/gpu/drm/nouveau/dispnv50/cursc37a.c @@ -29,13 +29,15 @@ cursc37a_update(struct nv50_wndw *wndw, u32 *interlock) nvif_wr32(&wndw->wimm.base.user, 0x0200, 0x00000001); } -static void +static int cursc37a_point(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw) { - if (curs507a_space(wndw)) { + int ret = nvif_chan_wait(&wndw->wimm, 1); + if (ret == 0) { nvif_wr32(&wndw->wimm.base.user, 0x0208, asyw->point.y << 16 | asyw->point.x); } + return ret; } static const struct nv50_wimm_func diff --git a/drivers/gpu/drm/nouveau/dispnv50/wimmc37b.c b/drivers/gpu/drm/nouveau/dispnv50/wimmc37b.c index f7dbd965e4e7..4eb5abfb8ebf 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/wimmc37b.c +++ b/drivers/gpu/drm/nouveau/dispnv50/wimmc37b.c @@ -24,6 +24,7 @@ #include "wndw.h" #include +#include static void wimmc37b_update(struct nv50_wndw *wndw, u32 *interlock) @@ -39,15 +40,17 @@ wimmc37b_update(struct nv50_wndw *wndw, u32 *interlock) } } -static void +static int wimmc37b_point(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw) { - u32 *push; - if ((push = evo_wait(&wndw->wimm, 2))) { - evo_mthd(push, 0x0208, 1); - evo_data(push, asyw->point.y << 16 | asyw->point.x); - evo_kick(push, &wndw->wimm); - } + struct nvif_push *push = wndw->wimm.push; + int ret; + + if ((ret = PUSH_WAIT(push, 2))) + return ret; + + PUSH_NVSQ(push, NVC37B, 0x0208, asyw->point.y << 16 | asyw->point.x); + return 0; } static const struct nv50_wimm_func diff --git a/drivers/gpu/drm/nouveau/dispnv50/wndw.h b/drivers/gpu/drm/nouveau/dispnv50/wndw.h index a7412b9d3a98..53e496bfbc9d 100644 --- a/drivers/gpu/drm/nouveau/dispnv50/wndw.h +++ b/drivers/gpu/drm/nouveau/dispnv50/wndw.h @@ -91,7 +91,7 @@ void base907c_csc(struct nv50_wndw *, struct nv50_wndw_atom *, const struct drm_color_ctm *); struct nv50_wimm_func { - void (*point)(struct nv50_wndw *, struct nv50_wndw_atom *); + int (*point)(struct nv50_wndw *, struct nv50_wndw_atom *); void (*update)(struct nv50_wndw *, u32 *interlock); }; @@ -99,6 +99,13 @@ struct nv50_wimm_func { extern const struct nv50_wimm_func curs507a; bool curs507a_space(struct nv50_wndw *); +static inline __must_check int +nvif_chan_wait(struct nv50_dmac *dmac, u32 size) +{ + struct nv50_wndw *wndw = container_of(dmac, typeof(*wndw), wimm); + return curs507a_space(wndw) ? 0 : -ETIMEDOUT; +} + int wndwc37e_new(struct nouveau_drm *, enum drm_plane_type, int, s32, struct nv50_wndw **); int wndwc37e_new_(const struct nv50_wndw_func *, struct nouveau_drm *, diff --git a/drivers/gpu/drm/nouveau/include/nvhw/class/clc37b.h b/drivers/gpu/drm/nouveau/include/nvhw/class/clc37b.h new file mode 100644 index 000000000000..0f7323bfa09b --- /dev/null +++ b/drivers/gpu/drm/nouveau/include/nvhw/class/clc37b.h @@ -0,0 +1,49 @@ +/* + * Copyright (c) 1993-2017, NVIDIA CORPORATION. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + + +#ifndef _clC37b_h_ +#define _clC37b_h_ + +// dma opcode instructions +#define NVC37B_DMA +#define NVC37B_DMA_OPCODE 31:29 +#define NVC37B_DMA_OPCODE_METHOD 0x00000000 +#define NVC37B_DMA_OPCODE_JUMP 0x00000001 +#define NVC37B_DMA_OPCODE_NONINC_METHOD 0x00000002 +#define NVC37B_DMA_OPCODE_SET_SUBDEVICE_MASK 0x00000003 +#define NVC37B_DMA_METHOD_COUNT 27:18 +#define NVC37B_DMA_METHOD_OFFSET 13:2 +#define NVC37B_DMA_DATA 31:0 +#define NVC37B_DMA_DATA_NOP 0x00000000 +#define NVC37B_DMA_JUMP_OFFSET 11:2 +#define NVC37B_DMA_SET_SUBDEVICE_MASK_VALUE 11:0 + +// class methods +#define NVC37B_UPDATE (0x00000200) +#define NVC37B_UPDATE_INTERLOCK_WITH_WINDOW 1:1 +#define NVC37B_UPDATE_INTERLOCK_WITH_WINDOW_DISABLE (0x00000000) +#define NVC37B_UPDATE_INTERLOCK_WITH_WINDOW_ENABLE (0x00000001) +#define NVC37B_SET_POINT_OUT(b) (0x00000208 + (b)*0x00000004) +#define NVC37B_SET_POINT_OUT_X 15:0 +#define NVC37B_SET_POINT_OUT_Y 31:16 +#endif // _clC37b_h diff --git a/drivers/gpu/drm/nouveau/include/nvif/pushc37b.h b/drivers/gpu/drm/nouveau/include/nvif/pushc37b.h new file mode 100644 index 000000000000..8f0c45703e33 --- /dev/null +++ b/drivers/gpu/drm/nouveau/include/nvif/pushc37b.h @@ -0,0 +1,18 @@ +#ifndef __NVIF_PUSHC37B_H__ +#define __NVIF_PUSHC37B_H__ +#include + +#include + +#define PUSH_HDR(p,m,c) do { \ + PUSH_ASSERT(!((m) & ~DRF_SMASK(NVC37B_DMA_METHOD_OFFSET)), "mthd"); \ + PUSH_ASSERT(!((c) & ~DRF_MASK(NVC37B_DMA_METHOD_COUNT)), "size"); \ + PUSH_DATA__((p), NVDEF(NVC37B, DMA, OPCODE, METHOD) | \ + NVVAL(NVC37B, DMA, METHOD_COUNT, (c)) | \ + NVVAL(NVC37B, DMA, METHOD_OFFSET, (m) >> 2), \ + " mthd 0x%04x size %d - %s", (u32)(m), (u32)(c), __func__); \ +} while(0) + +#define PUSH_MTHD_HDR(p,s,m,c) PUSH_HDR(p,m,c) +#define PUSH_MTHD_INC 4:4 +#endif