Commit ccd27db8 authored by Ben Skeggs's avatar Ben Skeggs
Browse files

drm/nouveau/kms/nv50-: split base implementation by hardware class



Signed-off-by: default avatarBen Skeggs <bskeggs@redhat.com>
parent 09e1b78a
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -24,6 +24,8 @@ nouveau-y += dispnv50/wndw.o

nouveau-y += dispnv50/base.o
nouveau-y += dispnv50/base507c.o
nouveau-y += dispnv50/base827c.o
nouveau-y += dispnv50/base907c.o

nouveau-y += dispnv50/curs.o
nouveau-y += dispnv50/curs507a.o
+6 −6
Original line number Diff line number Diff line
@@ -31,12 +31,12 @@ nv50_base_new(struct nouveau_drm *drm, int head, struct nv50_wndw **pwndw)
		int version;
		int (*new)(struct nouveau_drm *, int, s32, struct nv50_wndw **);
	} bases[] = {
		{ GK110_DISP_BASE_CHANNEL_DMA, 0, base507c_new },
		{ GK104_DISP_BASE_CHANNEL_DMA, 0, base507c_new },
		{ GF110_DISP_BASE_CHANNEL_DMA, 0, base507c_new },
		{ GT214_DISP_BASE_CHANNEL_DMA, 0, base507c_new },
		{ GT200_DISP_BASE_CHANNEL_DMA, 0, base507c_new },
		{   G82_DISP_BASE_CHANNEL_DMA, 0, base507c_new },
		{ GK110_DISP_BASE_CHANNEL_DMA, 0, base907c_new },
		{ GK104_DISP_BASE_CHANNEL_DMA, 0, base907c_new },
		{ GF110_DISP_BASE_CHANNEL_DMA, 0, base907c_new },
		{ GT214_DISP_BASE_CHANNEL_DMA, 0, base827c_new },
		{ GT200_DISP_BASE_CHANNEL_DMA, 0, base827c_new },
		{   G82_DISP_BASE_CHANNEL_DMA, 0, base827c_new },
		{  NV50_DISP_BASE_CHANNEL_DMA, 0, base507c_new },
		{}
	};
+21 −0
Original line number Diff line number Diff line
@@ -3,6 +3,27 @@
#include "wndw.h"

int base507c_new(struct nouveau_drm *, int, s32, struct nv50_wndw **);
int base507c_new_(const struct nv50_wndw_func *, const u32 *format,
		  struct nouveau_drm *, int head, s32 oclass,
		  struct nv50_wndw **);
extern const u32 base507c_format[];
int base507c_acquire(struct nv50_wndw *, struct nv50_wndw_atom *,
		     struct nv50_head_atom *);
void base507c_release(struct nv50_wndw *, struct nv50_wndw_atom *,
		      struct nv50_head_atom *);
void base507c_sema_set(struct nv50_wndw *, struct nv50_wndw_atom *);
void base507c_sema_clr(struct nv50_wndw *);
void base507c_ntfy_reset(struct nouveau_bo *, u32);
void base507c_ntfy_set(struct nv50_wndw *, struct nv50_wndw_atom *);
void base507c_ntfy_clr(struct nv50_wndw *);
int base507c_ntfy_wait_begun(struct nouveau_bo *, u32, struct nvif_device *);
void base507c_image_clr(struct nv50_wndw *);
void base507c_lut(struct nv50_wndw *, struct nv50_wndw_atom *);
u32 base507c_update(struct nv50_wndw *, u32);

int base827c_new(struct nouveau_drm *, int, s32, struct nv50_wndw **);

int base907c_new(struct nouveau_drm *, int, s32, struct nv50_wndw **);

int nv50_base_new(struct nouveau_drm *, int head, struct nv50_wndw **);
#endif
+40 −61
Original line number Diff line number Diff line
@@ -21,7 +21,6 @@
 */
#include "base.h"

#include <nvif/class.h>
#include <nvif/cl507c.h>
#include <nvif/event.h>

@@ -29,23 +28,20 @@
#include <drm/drm_plane_helper.h>
#include "nouveau_bo.h"

static u32
u32
base507c_update(struct nv50_wndw *wndw, u32 interlock)
{
	u32 *push;

	if (!(push = evo_wait(&wndw->wndw, 2)))
		return 0;
	if ((push = evo_wait(&wndw->wndw, 2))) {
		evo_mthd(push, 0x0080, 1);
		evo_data(push, interlock);
		evo_kick(push, &wndw->wndw);

	if (wndw->wndw.base.user.oclass < GF110_DISP_BASE_CHANNEL_DMA)
		return interlock ? 2 << (wndw->id * 8) : 0;
	return interlock ? 2 << (wndw->id * 4) : 0;
	}
	return 0;
}

static void
void
base507c_lut(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw)
{
	u32 *push;
@@ -56,7 +52,7 @@ base507c_lut(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw)
	}
}

static void
void
base507c_image_clr(struct nv50_wndw *wndw)
{
	u32 *push;
@@ -72,7 +68,6 @@ base507c_image_clr(struct nv50_wndw *wndw)
static void
base507c_image_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw)
{
	const s32 oclass = wndw->wndw.base.user.oclass;
	u32 *push;
	if ((push = evo_wait(&wndw->wndw, 10))) {
		evo_mthd(push, 0x0084, 1);
@@ -80,56 +75,33 @@ base507c_image_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw)
			       asyw->image.interval << 4);
		evo_mthd(push, 0x00c0, 1);
		evo_data(push, asyw->image.handle);
		if (oclass < G82_DISP_BASE_CHANNEL_DMA) {
		evo_mthd(push, 0x0800, 5);
		evo_data(push, asyw->image.offset >> 8);
		evo_data(push, 0x00000000);
			evo_data(push, (asyw->image.h << 16) | asyw->image.w);
			evo_data(push, (asyw->image.layout << 20) |
					asyw->image.pitch |
					asyw->image.block);
			evo_data(push, (asyw->image.kind << 16) |
				       (asyw->image.format << 8));
		} else
		if (oclass < GF110_DISP_BASE_CHANNEL_DMA) {
			evo_mthd(push, 0x0800, 5);
			evo_data(push, asyw->image.offset >> 8);
			evo_data(push, 0x00000000);
			evo_data(push, (asyw->image.h << 16) | asyw->image.w);
			evo_data(push, (asyw->image.layout << 20) |
					asyw->image.pitch |
					asyw->image.block);
			evo_data(push, asyw->image.format << 8);
		} else {
			evo_mthd(push, 0x0400, 5);
			evo_data(push, asyw->image.offset >> 8);
			evo_data(push, 0x00000000);
			evo_data(push, (asyw->image.h << 16) | asyw->image.w);
			evo_data(push, (asyw->image.layout << 24) |
		evo_data(push, asyw->image.h << 16 | asyw->image.w);
		evo_data(push, asyw->image.layout << 20 |
			       asyw->image.pitch |
			       asyw->image.block);
			evo_data(push, asyw->image.format << 8);
		}
		evo_data(push, asyw->image.kind << 16 |
			       asyw->image.format << 8);
		evo_kick(push, &wndw->wndw);
	}
}

static int
base507c_ntfy_wait_begun(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw)
int
base507c_ntfy_wait_begun(struct nouveau_bo *bo, u32 offset,
			 struct nvif_device *device)
{
	struct nouveau_drm *drm = nouveau_drm(wndw->plane.dev);
	struct nv50_disp *disp = nv50_disp(wndw->plane.dev);
	if (nvif_msec(&drm->client.device, 2000ULL,
		u32 data = nouveau_bo_rd32(disp->sync, asyw->ntfy.offset / 4);
	s64 time = nvif_msec(device, 2000ULL,
		u32 data = nouveau_bo_rd32(bo, offset / 4);
		if ((data & 0xc0000000) == 0x40000000)
			break;
		usleep_range(1, 2);
	) < 0)
		return -ETIMEDOUT;
	return 0;
	);
	return time < 0 ? time : 0;
}

static void
void
base507c_ntfy_clr(struct nv50_wndw *wndw)
{
	u32 *push;
@@ -140,7 +112,7 @@ base507c_ntfy_clr(struct nv50_wndw *wndw)
	}
}

static void
void
base507c_ntfy_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw)
{
	u32 *push;
@@ -152,7 +124,13 @@ base507c_ntfy_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw)
	}
}

static void
void
base507c_ntfy_reset(struct nouveau_bo *bo, u32 offset)
{
	nouveau_bo_wr32(bo, offset / 4, 0x00000000);
}

void
base507c_sema_clr(struct nv50_wndw *wndw)
{
	u32 *push;
@@ -163,7 +141,7 @@ base507c_sema_clr(struct nv50_wndw *wndw)
	}
}

static void
void
base507c_sema_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw)
{
	u32 *push;
@@ -177,14 +155,14 @@ base507c_sema_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw)
	}
}

static void
void
base507c_release(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw,
		 struct nv50_head_atom *asyh)
{
	asyh->base.cpp = 0;
}

static int
int
base507c_acquire(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw,
		 struct nv50_head_atom *asyh)
{
@@ -229,7 +207,7 @@ base507c_acquire(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw,
	return 0;
}

static const u32
const u32
base507c_format[] = {
	DRM_FORMAT_C8,
	DRM_FORMAT_RGB565,
@@ -250,6 +228,7 @@ base507c = {
	.release = base507c_release,
	.sema_set = base507c_sema_set,
	.sema_clr = base507c_sema_clr,
	.ntfy_reset = base507c_ntfy_reset,
	.ntfy_set = base507c_ntfy_set,
	.ntfy_clr = base507c_ntfy_clr,
	.ntfy_wait_begun = base507c_ntfy_wait_begun,
@@ -259,7 +238,7 @@ base507c = {
	.update = base507c_update,
};

static int
int
base507c_new_(const struct nv50_wndw_func *func, const u32 *format,
	      struct nouveau_drm *drm, int head, s32 oclass,
	      struct nv50_wndw **pwndw)
+67 −0
Original line number Diff line number Diff line
/*
 * Copyright 2018 Red Hat Inc.
 *
 * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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.
 */
#include "base.h"

static void
base827c_image_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw)
{
	u32 *push;
	if ((push = evo_wait(&wndw->wndw, 10))) {
		evo_mthd(push, 0x0084, 1);
		evo_data(push, asyw->image.mode << 8 |
			       asyw->image.interval << 4);
		evo_mthd(push, 0x00c0, 1);
		evo_data(push, asyw->image.handle);
		evo_mthd(push, 0x0800, 5);
		evo_data(push, asyw->image.offset >> 8);
		evo_data(push, 0x00000000);
		evo_data(push, asyw->image.h << 16 | asyw->image.w);
		evo_data(push, asyw->image.layout << 20 |
			       asyw->image.pitch |
			       asyw->image.block);
		evo_data(push, asyw->image.format << 8);
		evo_kick(push, &wndw->wndw);
	}
}

static const struct nv50_wndw_func
base827c = {
	.acquire = base507c_acquire,
	.release = base507c_release,
	.sema_set = base507c_sema_set,
	.sema_clr = base507c_sema_clr,
	.ntfy_reset = base507c_ntfy_reset,
	.ntfy_set = base507c_ntfy_set,
	.ntfy_clr = base507c_ntfy_clr,
	.ntfy_wait_begun = base507c_ntfy_wait_begun,
	.image_set = base827c_image_set,
	.image_clr = base507c_image_clr,
	.lut = base507c_lut,
	.update = base507c_update,
};

int
base827c_new(struct nouveau_drm *drm, int head, s32 oclass,
	     struct nv50_wndw **pwndw)
{
	return base507c_new_(&base827c, base507c_format, drm, head, oclass, pwndw);
}
Loading