linux/drivers/gpu/drm/nouveau/nvkm/engine/gr/gm107.c
<<
>>
Prefs
   1/*
   2 * Copyright 2013 Red Hat Inc.
   3 *
   4 * Permission is hereby granted, free of charge, to any person obtaining a
   5 * copy of this software and associated documentation files (the "Software"),
   6 * to deal in the Software without restriction, including without limitation
   7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
   8 * and/or sell copies of the Software, and to permit persons to whom the
   9 * Software is furnished to do so, subject to the following conditions:
  10 *
  11 * The above copyright notice and this permission notice shall be included in
  12 * all copies or substantial portions of the Software.
  13 *
  14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
  17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
  18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
  19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  20 * OTHER DEALINGS IN THE SOFTWARE.
  21 *
  22 * Authors: Ben Skeggs <bskeggs@redhat.com>
  23 */
  24#include "gf100.h"
  25#include "ctxgf100.h"
  26
  27#include <subdev/bios.h>
  28#include <subdev/bios/P0260.h>
  29#include <subdev/fb.h>
  30
  31#include <nvif/class.h>
  32
  33/*******************************************************************************
  34 * PGRAPH register lists
  35 ******************************************************************************/
  36
  37static const struct gf100_gr_init
  38gm107_gr_init_main_0[] = {
  39        { 0x400080,   1, 0x04, 0x003003c2 },
  40        { 0x400088,   1, 0x04, 0x0001bfe7 },
  41        { 0x40008c,   1, 0x04, 0x00060000 },
  42        { 0x400090,   1, 0x04, 0x00000030 },
  43        { 0x40013c,   1, 0x04, 0x003901f3 },
  44        { 0x400140,   1, 0x04, 0x00000100 },
  45        { 0x400144,   1, 0x04, 0x00000000 },
  46        { 0x400148,   1, 0x04, 0x00000110 },
  47        { 0x400138,   1, 0x04, 0x00000000 },
  48        { 0x400130,   2, 0x04, 0x00000000 },
  49        { 0x400124,   1, 0x04, 0x00000002 },
  50        {}
  51};
  52
  53static const struct gf100_gr_init
  54gm107_gr_init_ds_0[] = {
  55        { 0x405844,   1, 0x04, 0x00ffffff },
  56        { 0x405850,   1, 0x04, 0x00000000 },
  57        { 0x405900,   1, 0x04, 0x00000000 },
  58        { 0x405908,   1, 0x04, 0x00000000 },
  59        {}
  60};
  61
  62const struct gf100_gr_init
  63gm107_gr_init_scc_0[] = {
  64        { 0x40803c,   1, 0x04, 0x00000010 },
  65        {}
  66};
  67
  68static const struct gf100_gr_init
  69gm107_gr_init_sked_0[] = {
  70        { 0x407010,   1, 0x04, 0x00000000 },
  71        { 0x407040,   1, 0x04, 0x40440424 },
  72        { 0x407048,   1, 0x04, 0x0000000a },
  73        {}
  74};
  75
  76const struct gf100_gr_init
  77gm107_gr_init_prop_0[] = {
  78        { 0x418408,   1, 0x04, 0x00000000 },
  79        { 0x4184a0,   1, 0x04, 0x00000000 },
  80        {}
  81};
  82
  83const struct gf100_gr_init
  84gm107_gr_init_setup_1[] = {
  85        { 0x4188c8,   2, 0x04, 0x00000000 },
  86        { 0x4188d0,   1, 0x04, 0x00010000 },
  87        { 0x4188d4,   1, 0x04, 0x00010201 },
  88        {}
  89};
  90
  91const struct gf100_gr_init
  92gm107_gr_init_zcull_0[] = {
  93        { 0x418910,   1, 0x04, 0x00010001 },
  94        { 0x418914,   1, 0x04, 0x00000301 },
  95        { 0x418918,   1, 0x04, 0x00800000 },
  96        { 0x418930,   2, 0x04, 0x00000000 },
  97        { 0x418980,   1, 0x04, 0x77777770 },
  98        { 0x418984,   3, 0x04, 0x77777777 },
  99        {}
 100};
 101
 102const struct gf100_gr_init
 103gm107_gr_init_gpc_unk_1[] = {
 104        { 0x418d00,   1, 0x04, 0x00000000 },
 105        { 0x418f00,   1, 0x04, 0x00000400 },
 106        { 0x418f08,   1, 0x04, 0x00000000 },
 107        { 0x418e08,   1, 0x04, 0x00000000 },
 108        {}
 109};
 110
 111static const struct gf100_gr_init
 112gm107_gr_init_tpccs_0[] = {
 113        { 0x419dc4,   1, 0x04, 0x00000000 },
 114        { 0x419dc8,   1, 0x04, 0x00000501 },
 115        { 0x419dd0,   1, 0x04, 0x00000000 },
 116        { 0x419dd4,   1, 0x04, 0x00000100 },
 117        { 0x419dd8,   1, 0x04, 0x00000001 },
 118        { 0x419ddc,   1, 0x04, 0x00000002 },
 119        { 0x419de0,   1, 0x04, 0x00000001 },
 120        { 0x419d0c,   1, 0x04, 0x00000000 },
 121        { 0x419d10,   1, 0x04, 0x00000014 },
 122        {}
 123};
 124
 125const struct gf100_gr_init
 126gm107_gr_init_tex_0[] = {
 127        { 0x419ab0,   1, 0x04, 0x00000000 },
 128        { 0x419ab8,   1, 0x04, 0x000000e7 },
 129        { 0x419abc,   1, 0x04, 0x00000000 },
 130        { 0x419acc,   1, 0x04, 0x000000ff },
 131        { 0x419ac0,   1, 0x04, 0x00000000 },
 132        { 0x419aa8,   2, 0x04, 0x00000000 },
 133        { 0x419ad0,   2, 0x04, 0x00000000 },
 134        { 0x419ae0,   2, 0x04, 0x00000000 },
 135        { 0x419af0,   4, 0x04, 0x00000000 },
 136        {}
 137};
 138
 139static const struct gf100_gr_init
 140gm107_gr_init_pe_0[] = {
 141        { 0x419900,   1, 0x04, 0x000000ff },
 142        { 0x41980c,   1, 0x04, 0x00000010 },
 143        { 0x419844,   1, 0x04, 0x00000000 },
 144        { 0x419838,   1, 0x04, 0x000000ff },
 145        { 0x419850,   1, 0x04, 0x00000004 },
 146        { 0x419854,   2, 0x04, 0x00000000 },
 147        { 0x419894,   3, 0x04, 0x00100401 },
 148        {}
 149};
 150
 151const struct gf100_gr_init
 152gm107_gr_init_l1c_0[] = {
 153        { 0x419c98,   1, 0x04, 0x00000000 },
 154        { 0x419cc0,   2, 0x04, 0x00000000 },
 155        {}
 156};
 157
 158static const struct gf100_gr_init
 159gm107_gr_init_sm_0[] = {
 160        { 0x419e30,   1, 0x04, 0x000000ff },
 161        { 0x419e00,   1, 0x04, 0x00000000 },
 162        { 0x419ea0,   1, 0x04, 0x00000000 },
 163        { 0x419ee4,   1, 0x04, 0x00000000 },
 164        { 0x419ea4,   1, 0x04, 0x00000100 },
 165        { 0x419ea8,   1, 0x04, 0x01000000 },
 166        { 0x419ee8,   1, 0x04, 0x00000091 },
 167        { 0x419eb4,   1, 0x04, 0x00000000 },
 168        { 0x419ebc,   2, 0x04, 0x00000000 },
 169        { 0x419edc,   1, 0x04, 0x000c1810 },
 170        { 0x419ed8,   1, 0x04, 0x00000000 },
 171        { 0x419ee0,   1, 0x04, 0x00000000 },
 172        { 0x419f74,   1, 0x04, 0x00005155 },
 173        { 0x419f80,   4, 0x04, 0x00000000 },
 174        {}
 175};
 176
 177static const struct gf100_gr_init
 178gm107_gr_init_l1c_1[] = {
 179        { 0x419ccc,   2, 0x04, 0x00000000 },
 180        { 0x419c80,   1, 0x04, 0x3f006022 },
 181        { 0x419c88,   1, 0x04, 0x00000000 },
 182        {}
 183};
 184
 185static const struct gf100_gr_init
 186gm107_gr_init_pes_0[] = {
 187        { 0x41be50,   1, 0x04, 0x000000ff },
 188        { 0x41be04,   1, 0x04, 0x00000000 },
 189        { 0x41be08,   1, 0x04, 0x00000004 },
 190        { 0x41be0c,   1, 0x04, 0x00000008 },
 191        { 0x41be10,   1, 0x04, 0x0e3b8bc7 },
 192        { 0x41be14,   2, 0x04, 0x00000000 },
 193        { 0x41be3c,   5, 0x04, 0x00100401 },
 194        {}
 195};
 196
 197const struct gf100_gr_init
 198gm107_gr_init_wwdx_0[] = {
 199        { 0x41bfd4,   1, 0x04, 0x00800000 },
 200        { 0x41bfdc,   1, 0x04, 0x00000000 },
 201        {}
 202};
 203
 204const struct gf100_gr_init
 205gm107_gr_init_cbm_0[] = {
 206        { 0x41becc,   1, 0x04, 0x00000000 },
 207        {}
 208};
 209
 210static const struct gf100_gr_init
 211gm107_gr_init_be_0[] = {
 212        { 0x408890,   1, 0x04, 0x000000ff },
 213        { 0x40880c,   1, 0x04, 0x00000000 },
 214        { 0x408850,   1, 0x04, 0x00000004 },
 215        { 0x408878,   1, 0x04, 0x00c81603 },
 216        { 0x40887c,   1, 0x04, 0x80543432 },
 217        { 0x408880,   1, 0x04, 0x0010581e },
 218        { 0x408884,   1, 0x04, 0x00001205 },
 219        { 0x408974,   1, 0x04, 0x000000ff },
 220        { 0x408910,   9, 0x04, 0x00000000 },
 221        { 0x408950,   1, 0x04, 0x00000000 },
 222        { 0x408954,   1, 0x04, 0x0000ffff },
 223        { 0x408958,   1, 0x04, 0x00000034 },
 224        { 0x40895c,   1, 0x04, 0x8531a003 },
 225        { 0x408960,   1, 0x04, 0x0561985a },
 226        { 0x408964,   1, 0x04, 0x04e15c4f },
 227        { 0x408968,   1, 0x04, 0x02808833 },
 228        { 0x40896c,   1, 0x04, 0x01f02438 },
 229        { 0x408970,   1, 0x04, 0x00012c00 },
 230        { 0x408984,   1, 0x04, 0x00000000 },
 231        { 0x408988,   1, 0x04, 0x08040201 },
 232        { 0x40898c,   1, 0x04, 0x80402010 },
 233        {}
 234};
 235
 236static const struct gf100_gr_init
 237gm107_gr_init_sm_1[] = {
 238        { 0x419e5c,   1, 0x04, 0x00000000 },
 239        { 0x419e58,   1, 0x04, 0x00000000 },
 240        {}
 241};
 242
 243static const struct gf100_gr_pack
 244gm107_gr_pack_mmio[] = {
 245        { gm107_gr_init_main_0 },
 246        { gk110_gr_init_fe_0 },
 247        { gf100_gr_init_pri_0 },
 248        { gf100_gr_init_rstr2d_0 },
 249        { gf100_gr_init_pd_0 },
 250        { gm107_gr_init_ds_0 },
 251        { gm107_gr_init_scc_0 },
 252        { gm107_gr_init_sked_0 },
 253        { gk110_gr_init_cwd_0 },
 254        { gm107_gr_init_prop_0 },
 255        { gk208_gr_init_gpc_unk_0 },
 256        { gf100_gr_init_setup_0 },
 257        { gf100_gr_init_crstr_0 },
 258        { gm107_gr_init_setup_1 },
 259        { gm107_gr_init_zcull_0 },
 260        { gf100_gr_init_gpm_0 },
 261        { gm107_gr_init_gpc_unk_1 },
 262        { gf100_gr_init_gcc_0 },
 263        { gm107_gr_init_tpccs_0 },
 264        { gm107_gr_init_tex_0 },
 265        { gm107_gr_init_pe_0 },
 266        { gm107_gr_init_l1c_0 },
 267        { gf100_gr_init_mpc_0 },
 268        { gm107_gr_init_sm_0 },
 269        { gm107_gr_init_l1c_1 },
 270        { gm107_gr_init_pes_0 },
 271        { gm107_gr_init_wwdx_0 },
 272        { gm107_gr_init_cbm_0 },
 273        { gm107_gr_init_be_0 },
 274        { gm107_gr_init_sm_1 },
 275        {}
 276};
 277
 278/*******************************************************************************
 279 * PGRAPH engine/subdev functions
 280 ******************************************************************************/
 281
 282void
 283gm107_gr_init_bios(struct gf100_gr *gr)
 284{
 285        static const struct {
 286                u32 ctrl;
 287                u32 data;
 288        } regs[] = {
 289                { 0x419ed8, 0x419ee0 },
 290                { 0x419ad0, 0x419ad4 },
 291                { 0x419ae0, 0x419ae4 },
 292                { 0x419af0, 0x419af4 },
 293                { 0x419af8, 0x419afc },
 294        };
 295        struct nvkm_device *device = gr->base.engine.subdev.device;
 296        struct nvkm_bios *bios = device->bios;
 297        struct nvbios_P0260E infoE;
 298        struct nvbios_P0260X infoX;
 299        int E = -1, X;
 300        u8 ver, hdr;
 301
 302        while (nvbios_P0260Ep(bios, ++E, &ver, &hdr, &infoE)) {
 303                if (X = -1, E < ARRAY_SIZE(regs)) {
 304                        nvkm_wr32(device, regs[E].ctrl, infoE.data);
 305                        while (nvbios_P0260Xp(bios, ++X, &ver, &hdr, &infoX))
 306                                nvkm_wr32(device, regs[E].data, infoX.data);
 307                }
 308        }
 309}
 310
 311static int
 312gm107_gr_init(struct gf100_gr *gr)
 313{
 314        struct nvkm_device *device = gr->base.engine.subdev.device;
 315        struct nvkm_fb *fb = device->fb;
 316        const u32 magicgpc918 = DIV_ROUND_UP(0x00800000, gr->tpc_total);
 317        u32 data[TPC_MAX / 8] = {};
 318        u8  tpcnr[GPC_MAX];
 319        int gpc, tpc, rop;
 320        int i;
 321
 322        nvkm_wr32(device, GPC_BCAST(0x0880), 0x00000000);
 323        nvkm_wr32(device, GPC_BCAST(0x0890), 0x00000000);
 324        nvkm_wr32(device, GPC_BCAST(0x0894), 0x00000000);
 325        nvkm_wr32(device, GPC_BCAST(0x08b4), nvkm_memory_addr(fb->mmu_wr) >> 8);
 326        nvkm_wr32(device, GPC_BCAST(0x08b8), nvkm_memory_addr(fb->mmu_rd) >> 8);
 327
 328        gf100_gr_mmio(gr, gr->func->mmio);
 329
 330        gm107_gr_init_bios(gr);
 331
 332        nvkm_wr32(device, GPC_UNIT(0, 0x3018), 0x00000001);
 333
 334        memset(data, 0x00, sizeof(data));
 335        memcpy(tpcnr, gr->tpc_nr, sizeof(gr->tpc_nr));
 336        for (i = 0, gpc = -1; i < gr->tpc_total; i++) {
 337                do {
 338                        gpc = (gpc + 1) % gr->gpc_nr;
 339                } while (!tpcnr[gpc]);
 340                tpc = gr->tpc_nr[gpc] - tpcnr[gpc]--;
 341
 342                data[i / 8] |= tpc << ((i % 8) * 4);
 343        }
 344
 345        nvkm_wr32(device, GPC_BCAST(0x0980), data[0]);
 346        nvkm_wr32(device, GPC_BCAST(0x0984), data[1]);
 347        nvkm_wr32(device, GPC_BCAST(0x0988), data[2]);
 348        nvkm_wr32(device, GPC_BCAST(0x098c), data[3]);
 349
 350        for (gpc = 0; gpc < gr->gpc_nr; gpc++) {
 351                nvkm_wr32(device, GPC_UNIT(gpc, 0x0914),
 352                          gr->screen_tile_row_offset << 8 | gr->tpc_nr[gpc]);
 353                nvkm_wr32(device, GPC_UNIT(gpc, 0x0910), 0x00040000 |
 354                                                         gr->tpc_total);
 355                nvkm_wr32(device, GPC_UNIT(gpc, 0x0918), magicgpc918);
 356        }
 357
 358        nvkm_wr32(device, GPC_BCAST(0x3fd4), magicgpc918);
 359        nvkm_wr32(device, GPC_BCAST(0x08ac), nvkm_rd32(device, 0x100800));
 360
 361        gr->func->init_rop_active_fbps(gr);
 362
 363        nvkm_wr32(device, 0x400500, 0x00010001);
 364
 365        nvkm_wr32(device, 0x400100, 0xffffffff);
 366        nvkm_wr32(device, 0x40013c, 0xffffffff);
 367        nvkm_wr32(device, 0x400124, 0x00000002);
 368        nvkm_wr32(device, 0x409c24, 0x000e0000);
 369
 370        nvkm_wr32(device, 0x404000, 0xc0000000);
 371        nvkm_wr32(device, 0x404600, 0xc0000000);
 372        nvkm_wr32(device, 0x408030, 0xc0000000);
 373        nvkm_wr32(device, 0x404490, 0xc0000000);
 374        nvkm_wr32(device, 0x406018, 0xc0000000);
 375        nvkm_wr32(device, 0x407020, 0x40000000);
 376        nvkm_wr32(device, 0x405840, 0xc0000000);
 377        nvkm_wr32(device, 0x405844, 0x00ffffff);
 378        nvkm_mask(device, 0x419cc0, 0x00000008, 0x00000008);
 379
 380        gr->func->init_ppc_exceptions(gr);
 381
 382        for (gpc = 0; gpc < gr->gpc_nr; gpc++) {
 383                nvkm_wr32(device, GPC_UNIT(gpc, 0x0420), 0xc0000000);
 384                nvkm_wr32(device, GPC_UNIT(gpc, 0x0900), 0xc0000000);
 385                nvkm_wr32(device, GPC_UNIT(gpc, 0x1028), 0xc0000000);
 386                nvkm_wr32(device, GPC_UNIT(gpc, 0x0824), 0xc0000000);
 387                for (tpc = 0; tpc < gr->tpc_nr[gpc]; tpc++) {
 388                        nvkm_wr32(device, TPC_UNIT(gpc, tpc, 0x508), 0xffffffff);
 389                        nvkm_wr32(device, TPC_UNIT(gpc, tpc, 0x50c), 0xffffffff);
 390                        nvkm_wr32(device, TPC_UNIT(gpc, tpc, 0x224), 0xc0000000);
 391                        nvkm_wr32(device, TPC_UNIT(gpc, tpc, 0x48c), 0xc0000000);
 392                        nvkm_wr32(device, TPC_UNIT(gpc, tpc, 0x084), 0xc0000000);
 393                        nvkm_wr32(device, TPC_UNIT(gpc, tpc, 0x430), 0xc0000000);
 394                        nvkm_wr32(device, TPC_UNIT(gpc, tpc, 0x644), 0x00dffffe);
 395                        nvkm_wr32(device, TPC_UNIT(gpc, tpc, 0x64c), 0x00000005);
 396                }
 397                nvkm_wr32(device, GPC_UNIT(gpc, 0x2c90), 0xffffffff);
 398                nvkm_wr32(device, GPC_UNIT(gpc, 0x2c94), 0xffffffff);
 399        }
 400
 401        for (rop = 0; rop < gr->rop_nr; rop++) {
 402                nvkm_wr32(device, ROP_UNIT(rop, 0x144), 0x40000000);
 403                nvkm_wr32(device, ROP_UNIT(rop, 0x070), 0x40000000);
 404                nvkm_wr32(device, ROP_UNIT(rop, 0x204), 0xffffffff);
 405                nvkm_wr32(device, ROP_UNIT(rop, 0x208), 0xffffffff);
 406        }
 407
 408        nvkm_wr32(device, 0x400108, 0xffffffff);
 409        nvkm_wr32(device, 0x400138, 0xffffffff);
 410        nvkm_wr32(device, 0x400118, 0xffffffff);
 411        nvkm_wr32(device, 0x400130, 0xffffffff);
 412        nvkm_wr32(device, 0x40011c, 0xffffffff);
 413        nvkm_wr32(device, 0x400134, 0xffffffff);
 414
 415        nvkm_wr32(device, 0x400054, 0x2c350f63);
 416
 417        gf100_gr_zbc_init(gr);
 418
 419        return gf100_gr_init_ctxctl(gr);
 420}
 421
 422#include "fuc/hubgm107.fuc5.h"
 423
 424static struct gf100_gr_ucode
 425gm107_gr_fecs_ucode = {
 426        .code.data = gm107_grhub_code,
 427        .code.size = sizeof(gm107_grhub_code),
 428        .data.data = gm107_grhub_data,
 429        .data.size = sizeof(gm107_grhub_data),
 430};
 431
 432#include "fuc/gpcgm107.fuc5.h"
 433
 434static struct gf100_gr_ucode
 435gm107_gr_gpccs_ucode = {
 436        .code.data = gm107_grgpc_code,
 437        .code.size = sizeof(gm107_grgpc_code),
 438        .data.data = gm107_grgpc_data,
 439        .data.size = sizeof(gm107_grgpc_data),
 440};
 441
 442static const struct gf100_gr_func
 443gm107_gr = {
 444        .init = gm107_gr_init,
 445        .init_rop_active_fbps = gk104_gr_init_rop_active_fbps,
 446        .init_ppc_exceptions = gk104_gr_init_ppc_exceptions,
 447        .mmio = gm107_gr_pack_mmio,
 448        .fecs.ucode = &gm107_gr_fecs_ucode,
 449        .gpccs.ucode = &gm107_gr_gpccs_ucode,
 450        .rops = gf100_gr_rops,
 451        .ppc_nr = 2,
 452        .grctx = &gm107_grctx,
 453        .sclass = {
 454                { -1, -1, FERMI_TWOD_A },
 455                { -1, -1, KEPLER_INLINE_TO_MEMORY_B },
 456                { -1, -1, MAXWELL_A, &gf100_fermi },
 457                { -1, -1, MAXWELL_COMPUTE_A },
 458                {}
 459        }
 460};
 461
 462int
 463gm107_gr_new(struct nvkm_device *device, int index, struct nvkm_gr **pgr)
 464{
 465        return gf100_gr_new_(&gm107_gr, device, index, pgr);
 466}
 467