1243791Sdim/* 2243791Sdim * Copyright 2013 Red Hat Inc. 3243791Sdim * 4243791Sdim * Permission is hereby granted, free of charge, to any person obtaining a 5243791Sdim * copy of this software and associated documentation files (the "Software"), 6243791Sdim * to deal in the Software without restriction, including without limitation 7243791Sdim * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8243791Sdim * and/or sell copies of the Software, and to permit persons to whom the 9243791Sdim * Software is furnished to do so, subject to the following conditions: 10243791Sdim * 11243791Sdim * The above copyright notice and this permission notice shall be included in 12243791Sdim * all copies or substantial portions of the Software. 13243791Sdim * 14243791Sdim * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15243791Sdim * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16243791Sdim * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 17243791Sdim * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR 18243791Sdim * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 19243791Sdim * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 20243791Sdim * OTHER DEALINGS IN THE SOFTWARE. 21243791Sdim * 22243791Sdim * Authors: Ben Skeggs <bskeggs@redhat.com> 23249423Sdim */ 24249423Sdim#include "ctxgf100.h" 25249423Sdim 26249423Sdim#include <subdev/fb.h> 27249423Sdim#include <subdev/mc.h> 28249423Sdim 29243791Sdim/******************************************************************************* 30243791Sdim * PGRAPH context register lists 31243791Sdim ******************************************************************************/ 32249423Sdim 33249423Sdimstatic const struct gf100_gr_init 34249423Sdimgf117_grctx_init_ds_0[] = { 35249423Sdim { 0x405800, 1, 0x04, 0x0f8000bf }, 36243791Sdim { 0x405830, 1, 0x04, 0x02180324 }, 37243791Sdim { 0x405834, 1, 0x04, 0x08000000 }, 38243791Sdim { 0x405838, 1, 0x04, 0x00000000 }, 39249423Sdim { 0x405854, 1, 0x04, 0x00000000 }, 40243791Sdim { 0x405870, 4, 0x04, 0x00000001 }, 41243791Sdim { 0x405a00, 2, 0x04, 0x00000000 }, 42243791Sdim { 0x405a18, 1, 0x04, 0x00000000 }, 43243791Sdim {} 44243791Sdim}; 45243791Sdim 46243791Sdimstatic const struct gf100_gr_init 47249423Sdimgf117_grctx_init_pd_0[] = { 48249423Sdim { 0x406020, 1, 0x04, 0x000103c1 }, 49249423Sdim { 0x406028, 4, 0x04, 0x00000001 }, 50249423Sdim { 0x4064a8, 1, 0x04, 0x00000000 }, 51249423Sdim { 0x4064ac, 1, 0x04, 0x00003fff }, 52249423Sdim { 0x4064b4, 3, 0x04, 0x00000000 }, 53249423Sdim { 0x4064c0, 1, 0x04, 0x801a0078 }, 54249423Sdim { 0x4064c4, 1, 0x04, 0x00c9ffff }, 55249423Sdim { 0x4064d0, 8, 0x04, 0x00000000 }, 56249423Sdim {} 57243791Sdim}; 58243791Sdim 59243791Sdimstatic const struct gf100_gr_pack 60243791Sdimgf117_grctx_pack_hub[] = { 61243791Sdim { gf100_grctx_init_main_0 }, 62243791Sdim { gf119_grctx_init_fe_0 }, 63243791Sdim { gf100_grctx_init_pri_0 }, 64243791Sdim { gf100_grctx_init_memfmt_0 }, 65249423Sdim { gf117_grctx_init_ds_0 }, 66243791Sdim { gf117_grctx_init_pd_0 }, 67243791Sdim { gf100_grctx_init_rstr2d_0 }, 68243791Sdim { gf100_grctx_init_scc_0 }, 69243791Sdim { gf119_grctx_init_be_0 }, 70243791Sdim {} 71243791Sdim}; 72249423Sdim 73243791Sdimstatic const struct gf100_gr_init 74243791Sdimgf117_grctx_init_setup_0[] = { 75243791Sdim { 0x418800, 1, 0x04, 0x7006860a }, 76243791Sdim { 0x418808, 3, 0x04, 0x00000000 }, 77243791Sdim { 0x418828, 1, 0x04, 0x00008442 }, 78243791Sdim { 0x418830, 1, 0x04, 0x10000001 }, 79243791Sdim { 0x4188d8, 1, 0x04, 0x00000008 }, 80243791Sdim { 0x4188e0, 1, 0x04, 0x01000000 }, 81249423Sdim { 0x4188e8, 5, 0x04, 0x00000000 }, 82243791Sdim { 0x4188fc, 1, 0x04, 0x20100018 }, 83243791Sdim {} 84243791Sdim}; 85243791Sdim 86243791Sdimstatic const struct gf100_gr_pack 87243791Sdimgf117_grctx_pack_gpc_0[] = { 88243791Sdim { gf100_grctx_init_gpc_unk_0 }, 89243791Sdim { gf119_grctx_init_prop_0 }, 90243791Sdim { gf119_grctx_init_gpc_unk_1 }, 91243791Sdim { gf117_grctx_init_setup_0 }, 92243791Sdim { gf100_grctx_init_zcull_0 }, 93243791Sdim {} 94243791Sdim}; 95249423Sdim 96243791Sdimconst struct gf100_gr_pack 97243791Sdimgf117_grctx_pack_gpc_1[] = { 98243791Sdim { gf119_grctx_init_crstr_0 }, 99243791Sdim { gf108_grctx_init_gpm_0 }, 100243791Sdim { gf100_grctx_init_gcc_0 }, 101243791Sdim {} 102243791Sdim}; 103243791Sdim 104243791Sdimconst struct gf100_gr_init 105243791Sdimgf117_grctx_init_pe_0[] = { 106243791Sdim { 0x419848, 1, 0x04, 0x00000000 }, 107243791Sdim { 0x419864, 1, 0x04, 0x00000129 }, 108243791Sdim { 0x419888, 1, 0x04, 0x00000000 }, 109243791Sdim {} 110243791Sdim}; 111243791Sdim 112243791Sdimstatic const struct gf100_gr_init 113243791Sdimgf117_grctx_init_tex_0[] = { 114243791Sdim { 0x419a00, 1, 0x04, 0x000001f0 }, 115243791Sdim { 0x419a04, 1, 0x04, 0x00000001 }, 116243791Sdim { 0x419a08, 1, 0x04, 0x00000023 }, 117243791Sdim { 0x419a0c, 1, 0x04, 0x00020000 }, 118243791Sdim { 0x419a10, 1, 0x04, 0x00000000 }, 119243791Sdim { 0x419a14, 1, 0x04, 0x00000200 }, 120243791Sdim { 0x419a1c, 1, 0x04, 0x00008000 }, 121243791Sdim { 0x419a20, 1, 0x04, 0x00000800 }, 122243791Sdim { 0x419ac4, 1, 0x04, 0x0017f440 }, 123243791Sdim {} 124243791Sdim}; 125243791Sdim 126243791Sdimstatic const struct gf100_gr_init 127243791Sdimgf117_grctx_init_mpc_0[] = { 128243791Sdim { 0x419c00, 1, 0x04, 0x0000000a }, 129243791Sdim { 0x419c04, 1, 0x04, 0x00000006 }, 130243791Sdim { 0x419c08, 1, 0x04, 0x00000002 }, 131243791Sdim { 0x419c20, 1, 0x04, 0x00000000 }, 132243791Sdim { 0x419c24, 1, 0x04, 0x00084210 }, 133243791Sdim { 0x419c28, 1, 0x04, 0x3efbefbe }, 134243791Sdim {} 135243791Sdim}; 136243791Sdim 137243791Sdimstatic const struct gf100_gr_pack 138243791Sdimgf117_grctx_pack_tpc[] = { 139243791Sdim { gf117_grctx_init_pe_0 }, 140243791Sdim { gf117_grctx_init_tex_0 }, 141243791Sdim { gf117_grctx_init_mpc_0 }, 142243791Sdim { gf104_grctx_init_l1c_0 }, 143243791Sdim { gf119_grctx_init_sm_0 }, 144243791Sdim {} 145243791Sdim}; 146243791Sdim 147243791Sdimstatic const struct gf100_gr_init 148243791Sdimgf117_grctx_init_pes_0[] = { 149243791Sdim { 0x41be24, 1, 0x04, 0x00000002 }, 150243791Sdim {} 151243791Sdim}; 152243791Sdim 153243791Sdimstatic const struct gf100_gr_init 154243791Sdimgf117_grctx_init_cbm_0[] = { 155243791Sdim { 0x41bec0, 1, 0x04, 0x12180000 }, 156243791Sdim { 0x41bec4, 1, 0x04, 0x00003fff }, 157243791Sdim { 0x41bee4, 1, 0x04, 0x03240218 }, 158243791Sdim {} 159243791Sdim}; 160243791Sdim 161243791Sdimconst struct gf100_gr_init 162243791Sdimgf117_grctx_init_wwdx_0[] = { 163243791Sdim { 0x41bf00, 1, 0x04, 0x0a418820 }, 164243791Sdim { 0x41bf04, 1, 0x04, 0x062080e6 }, 165243791Sdim { 0x41bf08, 1, 0x04, 0x020398a4 }, 166243791Sdim { 0x41bf0c, 1, 0x04, 0x0e629062 }, 167243791Sdim { 0x41bf10, 1, 0x04, 0x0a418820 }, 168243791Sdim { 0x41bf14, 1, 0x04, 0x000000e6 }, 169243791Sdim { 0x41bfd0, 1, 0x04, 0x00900103 }, 170243791Sdim { 0x41bfe0, 1, 0x04, 0x00400001 }, 171243791Sdim { 0x41bfe4, 1, 0x04, 0x00000000 }, 172243791Sdim {} 173243791Sdim}; 174243791Sdim 175243791Sdimstatic const struct gf100_gr_pack 176243791Sdimgf117_grctx_pack_ppc[] = { 177243791Sdim { gf117_grctx_init_pes_0 }, 178249423Sdim { gf117_grctx_init_cbm_0 }, 179249423Sdim { gf117_grctx_init_wwdx_0 }, 180243791Sdim {} 181249423Sdim}; 182249423Sdim 183243791Sdim/******************************************************************************* 184243791Sdim * PGRAPH context implementation 185243791Sdim ******************************************************************************/ 186249423Sdim 187249423Sdimvoid 188243791Sdimgf117_grctx_generate_dist_skip_table(struct gf100_gr *gr) 189243791Sdim{ 190243791Sdim struct nvkm_device *device = gr->base.engine.subdev.device; 191243791Sdim int i; 192243791Sdim 193243791Sdim for (i = 0; i < 8; i++) 194243791Sdim nvkm_wr32(device, 0x4064d0 + (i * 0x04), 0x00000000); 195249423Sdim} 196249423Sdim 197243791Sdimvoid 198249423Sdimgf117_grctx_generate_rop_mapping(struct gf100_gr *gr) 199249423Sdim{ 200249423Sdim struct nvkm_device *device = gr->base.engine.subdev.device; 201249423Sdim u32 data[6] = {}, data2[2] = {}; 202249423Sdim u8 shift, ntpcv; 203249423Sdim int i; 204249423Sdim 205249423Sdim /* Pack tile map into register format. */ 206249423Sdim for (i = 0; i < 32; i++) 207249423Sdim data[i / 6] |= (gr->tile[i] & 0x07) << ((i % 6) * 5); 208249423Sdim 209249423Sdim /* Magic. */ 210249423Sdim shift = 0; 211249423Sdim ntpcv = gr->tpc_total; 212249423Sdim while (!(ntpcv & (1 << 4))) { 213249423Sdim ntpcv <<= 1; 214249423Sdim shift++; 215249423Sdim } 216243791Sdim 217249423Sdim data2[0] = (ntpcv << 16); 218249423Sdim data2[0] |= (shift << 21); 219249423Sdim data2[0] |= (((1 << (0 + 5)) % ntpcv) << 24); 220249423Sdim for (i = 1; i < 7; i++) 221243791Sdim data2[1] |= ((1 << (i + 5)) % ntpcv) << ((i - 1) * 5); 222249423Sdim 223243791Sdim /* GPC_BROADCAST */ 224243791Sdim nvkm_wr32(device, 0x418bb8, (gr->tpc_total << 8) | 225249423Sdim gr->screen_tile_row_offset); 226243791Sdim for (i = 0; i < 6; i++) 227243791Sdim nvkm_wr32(device, 0x418b08 + (i * 4), data[i]); 228243791Sdim 229243791Sdim /* GPC_BROADCAST.TP_BROADCAST */ 230249423Sdim nvkm_wr32(device, 0x41bfd0, (gr->tpc_total << 8) | 231249423Sdim gr->screen_tile_row_offset | data2[0]); 232243791Sdim nvkm_wr32(device, 0x41bfe4, data2[1]); 233249423Sdim for (i = 0; i < 6; i++) 234249423Sdim nvkm_wr32(device, 0x41bf00 + (i * 4), data[i]); 235249423Sdim 236243791Sdim /* UNK78xx */ 237243791Sdim nvkm_wr32(device, 0x4078bc, (gr->tpc_total << 8) | 238243791Sdim gr->screen_tile_row_offset); 239243791Sdim for (i = 0; i < 6; i++) 240249423Sdim nvkm_wr32(device, 0x40780c + (i * 4), data[i]); 241249423Sdim} 242243791Sdim 243243791Sdimvoid 244243791Sdimgf117_grctx_generate_attrib(struct gf100_gr_chan *chan) 245243791Sdim{ 246249423Sdim struct gf100_gr *gr = chan->gr; 247249423Sdim const struct gf100_grctx_func *grctx = gr->func->grctx; 248249423Sdim const u32 alpha = grctx->alpha_nr; 249243791Sdim const u32 beta = grctx->attrib_nr; 250243791Sdim const int timeslice_mode = 1; 251243791Sdim const int max_batches = 0xffff; 252243791Sdim u32 bo = 0; 253243791Sdim u32 ao = bo + grctx->attrib_nr_max * gr->tpc_total; 254249423Sdim int gpc, ppc; 255243791Sdim 256243791Sdim gf100_grctx_patch_wr32(chan, 0x405830, (beta << 16) | alpha); 257243791Sdim gf100_grctx_patch_wr32(chan, 0x4064c4, ((alpha / 4) << 16) | max_batches); 258243791Sdim 259243791Sdim for (gpc = 0; gpc < gr->gpc_nr; gpc++) { 260249423Sdim for (ppc = 0; ppc < gr->func->ppc_nr; ppc++) { 261249423Sdim const u32 a = alpha * gr->ppc_tpc_nr[gpc][ppc]; 262249423Sdim const u32 b = beta * gr->ppc_tpc_nr[gpc][ppc]; 263243791Sdim const u32 t = timeslice_mode; 264249423Sdim const u32 o = PPC_UNIT(gpc, ppc, 0); 265249423Sdim 266249423Sdim if (!(gr->ppc_mask[gpc] & (1 << ppc))) 267243791Sdim continue; 268249423Sdim 269249423Sdim gf100_grctx_patch_wr32(chan, o + 0xc0, (t << 28) | (b << 16) | bo); 270249423Sdim bo += grctx->attrib_nr_max * gr->ppc_tpc_nr[gpc][ppc]; 271249423Sdim gf100_grctx_patch_wr32(chan, o + 0xe4, (a << 16) | ao); 272249423Sdim ao += grctx->alpha_nr_max * gr->ppc_tpc_nr[gpc][ppc]; 273249423Sdim } 274249423Sdim } 275249423Sdim} 276249423Sdim 277249423Sdimconst struct gf100_grctx_func 278249423Sdimgf117_grctx = { 279243791Sdim .main = gf100_grctx_generate_main, 280243791Sdim .unkn = gk104_grctx_generate_unkn, 281243791Sdim .hub = gf117_grctx_pack_hub, 282243791Sdim .gpc_0 = gf117_grctx_pack_gpc_0, 283243791Sdim .gpc_1 = gf117_grctx_pack_gpc_1, 284243791Sdim .zcull = gf100_grctx_pack_zcull, 285243791Sdim .tpc = gf117_grctx_pack_tpc, 286243791Sdim .ppc = gf117_grctx_pack_ppc, 287249423Sdim .icmd = gf119_grctx_pack_icmd, 288243791Sdim .mthd = gf119_grctx_pack_mthd, 289243791Sdim .bundle = gf100_grctx_generate_bundle, 290243791Sdim .bundle_size = 0x1800, 291243791Sdim .pagepool = gf100_grctx_generate_pagepool, 292249423Sdim .pagepool_size = 0x8000, 293243791Sdim .attrib_cb_size = gf100_grctx_generate_attrib_cb_size, 294243791Sdim .attrib_cb = gf100_grctx_generate_attrib_cb, 295249423Sdim .attrib = gf117_grctx_generate_attrib, 296249423Sdim .attrib_nr_max = 0x324, 297249423Sdim .attrib_nr = 0x218, 298243791Sdim .alpha_nr_max = 0x7ff, 299243791Sdim .alpha_nr = 0x324, 300243791Sdim .sm_id = gf100_grctx_generate_sm_id, 301243791Sdim .tpc_nr = gf100_grctx_generate_tpc_nr, 302243791Sdim .r4060a8 = gf100_grctx_generate_r4060a8, 303243791Sdim .rop_mapping = gf117_grctx_generate_rop_mapping, 304249423Sdim .alpha_beta_tables = gf100_grctx_generate_alpha_beta_tables, 305249423Sdim .max_ways_evict = gf100_grctx_generate_max_ways_evict, 306243791Sdim .dist_skip_table = gf117_grctx_generate_dist_skip_table, 307249423Sdim .r419cb8 = gf100_grctx_generate_r419cb8, 308249423Sdim}; 309249423Sdim