141227Sjdp/*	$NetBSD: nouveau_nvkm_engine_disp_piocnv50.c,v 1.3 2021/12/18 23:45:35 riastradh Exp $	*/
241227Sjdp
341227Sjdp/*
4115470Sdes * Copyright 2012 Red Hat Inc.
587398Sdes *
641227Sjdp * Permission is hereby granted, free of charge, to any person obtaining a
787398Sdes * copy of this software and associated documentation files (the "Software"),
887398Sdes * to deal in the Software without restriction, including without limitation
987398Sdes * the rights to use, copy, modify, merge, publish, distribute, sublicense,
1087398Sdes * and/or sell copies of the Software, and to permit persons to whom the
1187398Sdes * Software is furnished to do so, subject to the following conditions:
1241227Sjdp *
1341227Sjdp * The above copyright notice and this permission notice shall be included in
1441227Sjdp * all copies or substantial portions of the Software.
1541227Sjdp *
1641227Sjdp * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1741227Sjdp * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1841227Sjdp * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
1941227Sjdp * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
2087398Sdes * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
2187398Sdes * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
2287398Sdes * OTHER DEALINGS IN THE SOFTWARE.
2341227Sjdp *
2441227Sjdp * Authors: Ben Skeggs
2541227Sjdp */
2641227Sjdp#include <sys/cdefs.h>
2741227Sjdp__KERNEL_RCSID(0, "$NetBSD: nouveau_nvkm_engine_disp_piocnv50.c,v 1.3 2021/12/18 23:45:35 riastradh Exp $");
2841227Sjdp
2941227Sjdp#include "channv50.h"
3041227Sjdp#include "rootnv50.h"
3141227Sjdp
3241227Sjdp#include <subdev/timer.h>
3341227Sjdp
3441227Sjdpstatic void
3541227Sjdpnv50_disp_pioc_fini(struct nv50_disp_chan *chan)
3641227Sjdp{
3784218Sdillon	struct nv50_disp *disp = chan->disp;
3884218Sdillon	struct nvkm_subdev *subdev = &disp->base.engine.subdev;
3984218Sdillon	struct nvkm_device *device = subdev->device;
4041227Sjdp	int ctrl = chan->chid.ctrl;
41122571Ssobomax	int user = chan->chid.user;
42122571Ssobomax
4341227Sjdp	nvkm_mask(device, 0x610200 + (ctrl * 0x10), 0x00000001, 0x00000000);
4441227Sjdp	if (nvkm_msec(device, 2000,
4541227Sjdp		if (!(nvkm_rd32(device, 0x610200 + (ctrl * 0x10)) & 0x00030000))
4641227Sjdp			break;
4741227Sjdp	) < 0) {
4841227Sjdp		nvkm_error(subdev, "ch %d timeout: %08x\n", user,
4941227Sjdp			   nvkm_rd32(device, 0x610200 + (ctrl * 0x10)));
5041227Sjdp	}
5187398Sdes}
5290229Sdes
5341227Sjdpstatic int
5490229Sdesnv50_disp_pioc_init(struct nv50_disp_chan *chan)
5541227Sjdp{
56115465Sdes	struct nv50_disp *disp = chan->disp;
57115465Sdes	struct nvkm_subdev *subdev = &disp->base.engine.subdev;
58115465Sdes	struct nvkm_device *device = subdev->device;
59122571Ssobomax	int ctrl = chan->chid.ctrl;
6041227Sjdp	int user = chan->chid.user;
6179476Smarkm
6293984Sdes	nvkm_wr32(device, 0x610200 + (ctrl * 0x10), 0x00002000);
6379476Smarkm	if (nvkm_msec(device, 2000,
6441227Sjdp		if (!(nvkm_rd32(device, 0x610200 + (ctrl * 0x10)) & 0x00030000))
65122571Ssobomax			break;
66122571Ssobomax	) < 0) {
6741227Sjdp		nvkm_error(subdev, "ch %d timeout0: %08x\n", user,
6841227Sjdp			   nvkm_rd32(device, 0x610200 + (ctrl * 0x10)));
69166136Spjd		return -EBUSY;
7041227Sjdp	}
7141227Sjdp
7241227Sjdp	nvkm_wr32(device, 0x610200 + (ctrl * 0x10), 0x00000001);
7341227Sjdp	if (nvkm_msec(device, 2000,
7441227Sjdp		u32 tmp = nvkm_rd32(device, 0x610200 + (ctrl * 0x10));
7541227Sjdp		if ((tmp & 0x00030000) == 0x00010000)
7641227Sjdp			break;
77122571Ssobomax	) < 0) {
78122571Ssobomax		nvkm_error(subdev, "ch %d timeout1: %08x\n", user,
7941227Sjdp			   nvkm_rd32(device, 0x610200 + (ctrl * 0x10)));
80122571Ssobomax		return -EBUSY;
81122571Ssobomax	}
82122571Ssobomax
83122571Ssobomax	return 0;
84122571Ssobomax}
8541227Sjdp
8641227Sjdpconst struct nv50_disp_chan_func
8741227Sjdpnv50_disp_pioc_func = {
8894564Sdes	.init = nv50_disp_pioc_init,
8941227Sjdp	.fini = nv50_disp_pioc_fini,
90122571Ssobomax	.intr = nv50_disp_chan_intr,
91122571Ssobomax	.user = nv50_disp_chan_user,
92122571Ssobomax};
93122571Ssobomax