Home | History | Annotate | Line # | Download | only in disp
      1 /*	$NetBSD: nouveau_nvkm_engine_disp_tu102.c,v 1.2 2021/12/18 23:45:35 riastradh Exp $	*/
      2 
      3 /*
      4  * Copyright 2018 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 #include <sys/cdefs.h>
     25 __KERNEL_RCSID(0, "$NetBSD: nouveau_nvkm_engine_disp_tu102.c,v 1.2 2021/12/18 23:45:35 riastradh Exp $");
     26 
     27 #include "nv50.h"
     28 #include "head.h"
     29 #include "ior.h"
     30 #include "channv50.h"
     31 #include "rootnv50.h"
     32 
     33 #include <core/gpuobj.h>
     34 #include <subdev/timer.h>
     35 
     36 static int
     37 tu102_disp_init(struct nv50_disp *disp)
     38 {
     39 	struct nvkm_device *device = disp->base.engine.subdev.device;
     40 	struct nvkm_head *head;
     41 	int i, j;
     42 	u32 tmp;
     43 
     44 	/* Claim ownership of display. */
     45 	if (nvkm_rd32(device, 0x6254e8) & 0x00000002) {
     46 		nvkm_mask(device, 0x6254e8, 0x00000001, 0x00000000);
     47 		if (nvkm_msec(device, 2000,
     48 			if (!(nvkm_rd32(device, 0x6254e8) & 0x00000002))
     49 				break;
     50 		) < 0)
     51 			return -EBUSY;
     52 	}
     53 
     54 	/* Lock pin capabilities. */
     55 	tmp = 0x00000021; /*XXX*/
     56 	nvkm_wr32(device, 0x640008, tmp);
     57 
     58 	/* SOR capabilities. */
     59 	for (i = 0; i < disp->sor.nr; i++) {
     60 		tmp = nvkm_rd32(device, 0x61c000 + (i * 0x800));
     61 		nvkm_mask(device, 0x640000, 0x00000100 << i, 0x00000100 << i);
     62 		nvkm_wr32(device, 0x640144 + (i * 0x08), tmp);
     63 	}
     64 
     65 	/* Head capabilities. */
     66 	list_for_each_entry(head, &disp->base.head, head) {
     67 		const int id = head->id;
     68 
     69 		/* RG. */
     70 		tmp = nvkm_rd32(device, 0x616300 + (id * 0x800));
     71 		nvkm_wr32(device, 0x640048 + (id * 0x020), tmp);
     72 
     73 		/* POSTCOMP. */
     74 		for (j = 0; j < 5 * 4; j += 4) {
     75 			tmp = nvkm_rd32(device, 0x616140 + (id * 0x800) + j);
     76 			nvkm_wr32(device, 0x640680 + (id * 0x20) + j, tmp);
     77 		}
     78 	}
     79 
     80 	/* Window capabilities. */
     81 	for (i = 0; i < disp->wndw.nr; i++) {
     82 		nvkm_mask(device, 0x640004, 1 << i, 1 << i);
     83 		for (j = 0; j < 6 * 4; j += 4) {
     84 			tmp = nvkm_rd32(device, 0x630100 + (i * 0x800) + j);
     85 			nvkm_mask(device, 0x640780 + (i * 0x20) + j, 0xffffffff, tmp);
     86 		}
     87 		nvkm_mask(device, 0x64000c, 0x00000100, 0x00000100);
     88 	}
     89 
     90 	/* IHUB capabilities. */
     91 	for (i = 0; i < 3; i++) {
     92 		tmp = nvkm_rd32(device, 0x62e000 + (i * 0x04));
     93 		nvkm_wr32(device, 0x640010 + (i * 0x04), tmp);
     94 	}
     95 
     96 	nvkm_mask(device, 0x610078, 0x00000001, 0x00000001);
     97 
     98 	/* Setup instance memory. */
     99 	switch (nvkm_memory_target(disp->inst->memory)) {
    100 	case NVKM_MEM_TARGET_VRAM: tmp = 0x00000001; break;
    101 	case NVKM_MEM_TARGET_NCOH: tmp = 0x00000002; break;
    102 	case NVKM_MEM_TARGET_HOST: tmp = 0x00000003; break;
    103 	default:
    104 		break;
    105 	}
    106 	nvkm_wr32(device, 0x610010, 0x00000008 | tmp);
    107 	nvkm_wr32(device, 0x610014, disp->inst->addr >> 16);
    108 
    109 	/* CTRL_DISP: AWAKEN, ERROR, SUPERVISOR[1-3]. */
    110 	nvkm_wr32(device, 0x611cf0, 0x00000187); /* MSK. */
    111 	nvkm_wr32(device, 0x611db0, 0x00000187); /* EN. */
    112 
    113 	/* EXC_OTHER: CURSn, CORE. */
    114 	nvkm_wr32(device, 0x611cec, disp->head.mask << 16 |
    115 				    0x00000001); /* MSK. */
    116 	nvkm_wr32(device, 0x611dac, 0x00000000); /* EN. */
    117 
    118 	/* EXC_WINIM. */
    119 	nvkm_wr32(device, 0x611ce8, disp->wndw.mask); /* MSK. */
    120 	nvkm_wr32(device, 0x611da8, 0x00000000); /* EN. */
    121 
    122 	/* EXC_WIN. */
    123 	nvkm_wr32(device, 0x611ce4, disp->wndw.mask); /* MSK. */
    124 	nvkm_wr32(device, 0x611da4, 0x00000000); /* EN. */
    125 
    126 	/* HEAD_TIMING(n): VBLANK. */
    127 	list_for_each_entry(head, &disp->base.head, head) {
    128 		const u32 hoff = head->id * 4;
    129 		nvkm_wr32(device, 0x611cc0 + hoff, 0x00000004); /* MSK. */
    130 		nvkm_wr32(device, 0x611d80 + hoff, 0x00000000); /* EN. */
    131 	}
    132 
    133 	/* OR. */
    134 	nvkm_wr32(device, 0x611cf4, 0x00000000); /* MSK. */
    135 	nvkm_wr32(device, 0x611db4, 0x00000000); /* EN. */
    136 	return 0;
    137 }
    138 
    139 static const struct nv50_disp_func
    140 tu102_disp = {
    141 	.init = tu102_disp_init,
    142 	.fini = gv100_disp_fini,
    143 	.intr = gv100_disp_intr,
    144 	.uevent = &gv100_disp_chan_uevent,
    145 	.super = gv100_disp_super,
    146 	.root = &tu102_disp_root_oclass,
    147 	.wndw = { .cnt = gv100_disp_wndw_cnt },
    148 	.head = { .cnt = gv100_head_cnt, .new = gv100_head_new },
    149 	.sor = { .cnt = gv100_sor_cnt, .new = tu102_sor_new },
    150 	.ramht_size = 0x2000,
    151 };
    152 
    153 int
    154 tu102_disp_new(struct nvkm_device *device, int index, struct nvkm_disp **pdisp)
    155 {
    156 	return nv50_disp_new_(&tu102_disp, device, index, pdisp);
    157 }
    158