1/* $NetBSD: nouveau_nvkm_engine_gr_ctxgf117.c,v 1.3 2021/12/18 23:45:36 riastradh Exp $ */ 2 3/* 4 * Copyright 2013 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 <bskeggs@redhat.com> 25 */ 26#include <sys/cdefs.h> 27__KERNEL_RCSID(0, "$NetBSD: nouveau_nvkm_engine_gr_ctxgf117.c,v 1.3 2021/12/18 23:45:36 riastradh Exp $"); 28 29#include "ctxgf100.h" 30 31#include <subdev/fb.h> 32#include <subdev/mc.h> 33 34/******************************************************************************* 35 * PGRAPH context register lists 36 ******************************************************************************/ 37 38static const struct gf100_gr_init 39gf117_grctx_init_ds_0[] = { 40 { 0x405800, 1, 0x04, 0x0f8000bf }, 41 { 0x405830, 1, 0x04, 0x02180324 }, 42 { 0x405834, 1, 0x04, 0x08000000 }, 43 { 0x405838, 1, 0x04, 0x00000000 }, 44 { 0x405854, 1, 0x04, 0x00000000 }, 45 { 0x405870, 4, 0x04, 0x00000001 }, 46 { 0x405a00, 2, 0x04, 0x00000000 }, 47 { 0x405a18, 1, 0x04, 0x00000000 }, 48 {} 49}; 50 51static const struct gf100_gr_init 52gf117_grctx_init_pd_0[] = { 53 { 0x406020, 1, 0x04, 0x000103c1 }, 54 { 0x406028, 4, 0x04, 0x00000001 }, 55 { 0x4064a8, 1, 0x04, 0x00000000 }, 56 { 0x4064ac, 1, 0x04, 0x00003fff }, 57 { 0x4064b4, 3, 0x04, 0x00000000 }, 58 { 0x4064c0, 1, 0x04, 0x801a0078 }, 59 { 0x4064c4, 1, 0x04, 0x00c9ffff }, 60 { 0x4064d0, 8, 0x04, 0x00000000 }, 61 {} 62}; 63 64static const struct gf100_gr_pack 65gf117_grctx_pack_hub[] = { 66 { gf100_grctx_init_main_0 }, 67 { gf119_grctx_init_fe_0 }, 68 { gf100_grctx_init_pri_0 }, 69 { gf100_grctx_init_memfmt_0 }, 70 { gf117_grctx_init_ds_0 }, 71 { gf117_grctx_init_pd_0 }, 72 { gf100_grctx_init_rstr2d_0 }, 73 { gf100_grctx_init_scc_0 }, 74 { gf119_grctx_init_be_0 }, 75 {} 76}; 77 78static const struct gf100_gr_init 79gf117_grctx_init_setup_0[] = { 80 { 0x418800, 1, 0x04, 0x7006860a }, 81 { 0x418808, 3, 0x04, 0x00000000 }, 82 { 0x418828, 1, 0x04, 0x00008442 }, 83 { 0x418830, 1, 0x04, 0x10000001 }, 84 { 0x4188d8, 1, 0x04, 0x00000008 }, 85 { 0x4188e0, 1, 0x04, 0x01000000 }, 86 { 0x4188e8, 5, 0x04, 0x00000000 }, 87 { 0x4188fc, 1, 0x04, 0x20100018 }, 88 {} 89}; 90 91static const struct gf100_gr_pack 92gf117_grctx_pack_gpc_0[] = { 93 { gf100_grctx_init_gpc_unk_0 }, 94 { gf119_grctx_init_prop_0 }, 95 { gf119_grctx_init_gpc_unk_1 }, 96 { gf117_grctx_init_setup_0 }, 97 { gf100_grctx_init_zcull_0 }, 98 {} 99}; 100 101const struct gf100_gr_pack 102gf117_grctx_pack_gpc_1[] = { 103 { gf119_grctx_init_crstr_0 }, 104 { gf108_grctx_init_gpm_0 }, 105 { gf100_grctx_init_gcc_0 }, 106 {} 107}; 108 109const struct gf100_gr_init 110gf117_grctx_init_pe_0[] = { 111 { 0x419848, 1, 0x04, 0x00000000 }, 112 { 0x419864, 1, 0x04, 0x00000129 }, 113 { 0x419888, 1, 0x04, 0x00000000 }, 114 {} 115}; 116 117static const struct gf100_gr_init 118gf117_grctx_init_tex_0[] = { 119 { 0x419a00, 1, 0x04, 0x000001f0 }, 120 { 0x419a04, 1, 0x04, 0x00000001 }, 121 { 0x419a08, 1, 0x04, 0x00000023 }, 122 { 0x419a0c, 1, 0x04, 0x00020000 }, 123 { 0x419a10, 1, 0x04, 0x00000000 }, 124 { 0x419a14, 1, 0x04, 0x00000200 }, 125 { 0x419a1c, 1, 0x04, 0x00008000 }, 126 { 0x419a20, 1, 0x04, 0x00000800 }, 127 { 0x419ac4, 1, 0x04, 0x0017f440 }, 128 {} 129}; 130 131static const struct gf100_gr_init 132gf117_grctx_init_mpc_0[] = { 133 { 0x419c00, 1, 0x04, 0x0000000a }, 134 { 0x419c04, 1, 0x04, 0x00000006 }, 135 { 0x419c08, 1, 0x04, 0x00000002 }, 136 { 0x419c20, 1, 0x04, 0x00000000 }, 137 { 0x419c24, 1, 0x04, 0x00084210 }, 138 { 0x419c28, 1, 0x04, 0x3efbefbe }, 139 {} 140}; 141 142static const struct gf100_gr_pack 143gf117_grctx_pack_tpc[] = { 144 { gf117_grctx_init_pe_0 }, 145 { gf117_grctx_init_tex_0 }, 146 { gf117_grctx_init_mpc_0 }, 147 { gf104_grctx_init_l1c_0 }, 148 { gf119_grctx_init_sm_0 }, 149 {} 150}; 151 152static const struct gf100_gr_init 153gf117_grctx_init_pes_0[] = { 154 { 0x41be24, 1, 0x04, 0x00000002 }, 155 {} 156}; 157 158static const struct gf100_gr_init 159gf117_grctx_init_cbm_0[] = { 160 { 0x41bec0, 1, 0x04, 0x12180000 }, 161 { 0x41bec4, 1, 0x04, 0x00003fff }, 162 { 0x41bee4, 1, 0x04, 0x03240218 }, 163 {} 164}; 165 166const struct gf100_gr_init 167gf117_grctx_init_wwdx_0[] = { 168 { 0x41bf00, 1, 0x04, 0x0a418820 }, 169 { 0x41bf04, 1, 0x04, 0x062080e6 }, 170 { 0x41bf08, 1, 0x04, 0x020398a4 }, 171 { 0x41bf0c, 1, 0x04, 0x0e629062 }, 172 { 0x41bf10, 1, 0x04, 0x0a418820 }, 173 { 0x41bf14, 1, 0x04, 0x000000e6 }, 174 { 0x41bfd0, 1, 0x04, 0x00900103 }, 175 { 0x41bfe0, 1, 0x04, 0x00400001 }, 176 { 0x41bfe4, 1, 0x04, 0x00000000 }, 177 {} 178}; 179 180static const struct gf100_gr_pack 181gf117_grctx_pack_ppc[] = { 182 { gf117_grctx_init_pes_0 }, 183 { gf117_grctx_init_cbm_0 }, 184 { gf117_grctx_init_wwdx_0 }, 185 {} 186}; 187 188/******************************************************************************* 189 * PGRAPH context implementation 190 ******************************************************************************/ 191 192void 193gf117_grctx_generate_dist_skip_table(struct gf100_gr *gr) 194{ 195 struct nvkm_device *device = gr->base.engine.subdev.device; 196 int i; 197 198 for (i = 0; i < 8; i++) 199 nvkm_wr32(device, 0x4064d0 + (i * 0x04), 0x00000000); 200} 201 202void 203gf117_grctx_generate_rop_mapping(struct gf100_gr *gr) 204{ 205 struct nvkm_device *device = gr->base.engine.subdev.device; 206 u32 data[6] = {}, data2[2] = {}; 207 u8 shift, ntpcv; 208 int i; 209 210 /* Pack tile map into register format. */ 211 for (i = 0; i < 32; i++) 212 data[i / 6] |= (gr->tile[i] & 0x07) << ((i % 6) * 5); 213 214 /* Magic. */ 215 shift = 0; 216 ntpcv = gr->tpc_total; 217 while (!(ntpcv & (1 << 4))) { 218 ntpcv <<= 1; 219 shift++; 220 } 221 222 data2[0] = (ntpcv << 16); 223 data2[0] |= (shift << 21); 224 data2[0] |= (((1 << (0 + 5)) % ntpcv) << 24); 225 for (i = 1; i < 7; i++) 226 data2[1] |= ((1 << (i + 5)) % ntpcv) << ((i - 1) * 5); 227 228 /* GPC_BROADCAST */ 229 nvkm_wr32(device, 0x418bb8, (gr->tpc_total << 8) | 230 gr->screen_tile_row_offset); 231 for (i = 0; i < 6; i++) 232 nvkm_wr32(device, 0x418b08 + (i * 4), data[i]); 233 234 /* GPC_BROADCAST.TP_BROADCAST */ 235 nvkm_wr32(device, 0x41bfd0, (gr->tpc_total << 8) | 236 gr->screen_tile_row_offset | data2[0]); 237 nvkm_wr32(device, 0x41bfe4, data2[1]); 238 for (i = 0; i < 6; i++) 239 nvkm_wr32(device, 0x41bf00 + (i * 4), data[i]); 240 241 /* UNK78xx */ 242 nvkm_wr32(device, 0x4078bc, (gr->tpc_total << 8) | 243 gr->screen_tile_row_offset); 244 for (i = 0; i < 6; i++) 245 nvkm_wr32(device, 0x40780c + (i * 4), data[i]); 246} 247 248void 249gf117_grctx_generate_attrib(struct gf100_grctx *info) 250{ 251 struct gf100_gr *gr = info->gr; 252 const struct gf100_grctx_func *grctx = gr->func->grctx; 253 const u32 alpha = grctx->alpha_nr; 254 const u32 beta = grctx->attrib_nr; 255 const u32 size = 0x20 * (grctx->attrib_nr_max + grctx->alpha_nr_max); 256 const int s = 12; 257 const int b = mmio_vram(info, size * gr->tpc_total, (1 << s), false); 258 const int timeslice_mode = 1; 259 const int max_batches = 0xffff; 260 u32 bo = 0; 261 u32 ao = bo + grctx->attrib_nr_max * gr->tpc_total; 262 int gpc, ppc; 263 264 mmio_refn(info, 0x418810, 0x80000000, s, b); 265 mmio_refn(info, 0x419848, 0x10000000, s, b); 266 mmio_wr32(info, 0x405830, (beta << 16) | alpha); 267 mmio_wr32(info, 0x4064c4, ((alpha / 4) << 16) | max_batches); 268 269 for (gpc = 0; gpc < gr->gpc_nr; gpc++) { 270 for (ppc = 0; ppc < gr->ppc_nr[gpc]; ppc++) { 271 const u32 a = alpha * gr->ppc_tpc_nr[gpc][ppc]; 272 const u32 b = beta * gr->ppc_tpc_nr[gpc][ppc]; 273 const u32 t = timeslice_mode; 274 const u32 o = PPC_UNIT(gpc, ppc, 0); 275 if (!(gr->ppc_mask[gpc] & (1 << ppc))) 276 continue; 277 mmio_skip(info, o + 0xc0, (t << 28) | (b << 16) | ++bo); 278 mmio_wr32(info, o + 0xc0, (t << 28) | (b << 16) | --bo); 279 bo += grctx->attrib_nr_max * gr->ppc_tpc_nr[gpc][ppc]; 280 mmio_wr32(info, o + 0xe4, (a << 16) | ao); 281 ao += grctx->alpha_nr_max * gr->ppc_tpc_nr[gpc][ppc]; 282 } 283 } 284} 285 286const struct gf100_grctx_func 287gf117_grctx = { 288 .main = gf100_grctx_generate_main, 289 .unkn = gk104_grctx_generate_unkn, 290 .hub = gf117_grctx_pack_hub, 291 .gpc_0 = gf117_grctx_pack_gpc_0, 292 .gpc_1 = gf117_grctx_pack_gpc_1, 293 .zcull = gf100_grctx_pack_zcull, 294 .tpc = gf117_grctx_pack_tpc, 295 .ppc = gf117_grctx_pack_ppc, 296 .icmd = gf119_grctx_pack_icmd, 297 .mthd = gf119_grctx_pack_mthd, 298 .bundle = gf100_grctx_generate_bundle, 299 .bundle_size = 0x1800, 300 .pagepool = gf100_grctx_generate_pagepool, 301 .pagepool_size = 0x8000, 302 .attrib = gf117_grctx_generate_attrib, 303 .attrib_nr_max = 0x324, 304 .attrib_nr = 0x218, 305 .alpha_nr_max = 0x7ff, 306 .alpha_nr = 0x324, 307 .sm_id = gf100_grctx_generate_sm_id, 308 .tpc_nr = gf100_grctx_generate_tpc_nr, 309 .r4060a8 = gf100_grctx_generate_r4060a8, 310 .rop_mapping = gf117_grctx_generate_rop_mapping, 311 .alpha_beta_tables = gf100_grctx_generate_alpha_beta_tables, 312 .max_ways_evict = gf100_grctx_generate_max_ways_evict, 313 .dist_skip_table = gf117_grctx_generate_dist_skip_table, 314 .r419cb8 = gf100_grctx_generate_r419cb8, 315}; 316