xref: /netbsd-src/sys/external/bsd/drm2/dist/drm/nouveau/nvkm/subdev/devinit/nouveau_nvkm_subdev_devinit_base.c (revision 41ec02673d281bbb3d38e6c78504ce6e30c228c1)
1 /*	$NetBSD: nouveau_nvkm_subdev_devinit_base.c,v 1.3 2021/12/18 23:45:39 riastradh Exp $	*/
2 
3 /*
4  * Copyright 2012 Red Hat Inc.
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a
7  * copy of this software and associated documentation files (the "Software"),
8  * to deal in the Software without restriction, including without limitation
9  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10  * and/or sell copies of the Software, and to permit persons to whom the
11  * Software is furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be included in
14  * all copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
19  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
20  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22  * OTHER DEALINGS IN THE SOFTWARE.
23  *
24  * Authors: Ben Skeggs
25  */
26 #include <sys/cdefs.h>
27 __KERNEL_RCSID(0, "$NetBSD: nouveau_nvkm_subdev_devinit_base.c,v 1.3 2021/12/18 23:45:39 riastradh Exp $");
28 
29 #include "priv.h"
30 
31 #include <core/option.h>
32 #include <subdev/vga.h>
33 
34 u32
nvkm_devinit_mmio(struct nvkm_devinit * init,u32 addr)35 nvkm_devinit_mmio(struct nvkm_devinit *init, u32 addr)
36 {
37 	if (init->func->mmio)
38 		addr = init->func->mmio(init, addr);
39 	return addr;
40 }
41 
42 int
nvkm_devinit_pll_set(struct nvkm_devinit * init,u32 type,u32 khz)43 nvkm_devinit_pll_set(struct nvkm_devinit *init, u32 type, u32 khz)
44 {
45 	return init->func->pll_set(init, type, khz);
46 }
47 
48 void
nvkm_devinit_meminit(struct nvkm_devinit * init)49 nvkm_devinit_meminit(struct nvkm_devinit *init)
50 {
51 	if (init->func->meminit)
52 		init->func->meminit(init);
53 }
54 
55 u64
nvkm_devinit_disable(struct nvkm_devinit * init)56 nvkm_devinit_disable(struct nvkm_devinit *init)
57 {
58 	if (init && init->func->disable)
59 		return init->func->disable(init);
60 	return 0;
61 }
62 
63 int
nvkm_devinit_post(struct nvkm_devinit * init,u64 * disable)64 nvkm_devinit_post(struct nvkm_devinit *init, u64 *disable)
65 {
66 	int ret = 0;
67 	if (init && init->func->post)
68 		ret = init->func->post(init, init->post);
69 	*disable = nvkm_devinit_disable(init);
70 	return ret;
71 }
72 
73 static int
nvkm_devinit_fini(struct nvkm_subdev * subdev,bool suspend)74 nvkm_devinit_fini(struct nvkm_subdev *subdev, bool suspend)
75 {
76 	struct nvkm_devinit *init = nvkm_devinit(subdev);
77 	/* force full reinit on resume */
78 	if (suspend)
79 		init->post = true;
80 	return 0;
81 }
82 
83 static int
nvkm_devinit_preinit(struct nvkm_subdev * subdev)84 nvkm_devinit_preinit(struct nvkm_subdev *subdev)
85 {
86 	struct nvkm_devinit *init = nvkm_devinit(subdev);
87 
88 	if (init->func->preinit)
89 		init->func->preinit(init);
90 
91 	/* Override the post flag during the first call if NvForcePost is set */
92 	if (init->force_post) {
93 		init->post = init->force_post;
94 		init->force_post = false;
95 	}
96 
97 	/* unlock the extended vga crtc regs */
98 	nvkm_lockvgac(subdev->device, false);
99 	return 0;
100 }
101 
102 static int
nvkm_devinit_init(struct nvkm_subdev * subdev)103 nvkm_devinit_init(struct nvkm_subdev *subdev)
104 {
105 	struct nvkm_devinit *init = nvkm_devinit(subdev);
106 	if (init->func->init)
107 		init->func->init(init);
108 	return 0;
109 }
110 
111 static void *
nvkm_devinit_dtor(struct nvkm_subdev * subdev)112 nvkm_devinit_dtor(struct nvkm_subdev *subdev)
113 {
114 	struct nvkm_devinit *init = nvkm_devinit(subdev);
115 	void *data = init;
116 
117 	if (init->func->dtor)
118 		data = init->func->dtor(init);
119 
120 	/* lock crtc regs */
121 	nvkm_lockvgac(subdev->device, true);
122 	return data;
123 }
124 
125 static const struct nvkm_subdev_func
126 nvkm_devinit = {
127 	.dtor = nvkm_devinit_dtor,
128 	.preinit = nvkm_devinit_preinit,
129 	.init = nvkm_devinit_init,
130 	.fini = nvkm_devinit_fini,
131 };
132 
133 void
nvkm_devinit_ctor(const struct nvkm_devinit_func * func,struct nvkm_device * device,int index,struct nvkm_devinit * init)134 nvkm_devinit_ctor(const struct nvkm_devinit_func *func,
135 		  struct nvkm_device *device, int index,
136 		  struct nvkm_devinit *init)
137 {
138 	nvkm_subdev_ctor(&nvkm_devinit, device, index, &init->subdev);
139 	init->func = func;
140 	init->force_post = nvkm_boolopt(device->cfgopt, "NvForcePost", false);
141 }
142