linux/drivers/gpu/drm/nouveau/nvkm/subdev/bios/init.c
<<
>>
Prefs
   1/*
   2 * Copyright 2012 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
  23 */
  24#include <subdev/bios.h>
  25#include <subdev/bios/bit.h>
  26#include <subdev/bios/bmp.h>
  27#include <subdev/bios/conn.h>
  28#include <subdev/bios/dcb.h>
  29#include <subdev/bios/dp.h>
  30#include <subdev/bios/gpio.h>
  31#include <subdev/bios/init.h>
  32#include <subdev/bios/ramcfg.h>
  33
  34#include <subdev/devinit.h>
  35#include <subdev/gpio.h>
  36#include <subdev/i2c.h>
  37#include <subdev/vga.h>
  38
  39#define bioslog(lvl, fmt, args...) do {                                        \
  40        nvkm_printk(init->subdev, lvl, info, "0x%04x[%c]: "fmt,                \
  41                    init->offset, init_exec(init) ?                            \
  42                    '0' + (init->nested - 1) : ' ', ##args);                   \
  43} while(0)
  44#define cont(fmt, args...) do {                                                \
  45        if (init->subdev->debug >= NV_DBG_TRACE)                               \
  46                printk(fmt, ##args);                                           \
  47} while(0)
  48#define trace(fmt, args...) bioslog(TRACE, fmt, ##args)
  49#define warn(fmt, args...) bioslog(WARN, fmt, ##args)
  50#define error(fmt, args...) bioslog(ERROR, fmt, ##args)
  51
  52/******************************************************************************
  53 * init parser control flow helpers
  54 *****************************************************************************/
  55
  56static inline bool
  57init_exec(struct nvbios_init *init)
  58{
  59        return (init->execute == 1) || ((init->execute & 5) == 5);
  60}
  61
  62static inline void
  63init_exec_set(struct nvbios_init *init, bool exec)
  64{
  65        if (exec) init->execute &= 0xfd;
  66        else      init->execute |= 0x02;
  67}
  68
  69static inline void
  70init_exec_inv(struct nvbios_init *init)
  71{
  72        init->execute ^= 0x02;
  73}
  74
  75static inline void
  76init_exec_force(struct nvbios_init *init, bool exec)
  77{
  78        if (exec) init->execute |= 0x04;
  79        else      init->execute &= 0xfb;
  80}
  81
  82/******************************************************************************
  83 * init parser wrappers for normal register/i2c/whatever accessors
  84 *****************************************************************************/
  85
  86static inline int
  87init_or(struct nvbios_init *init)
  88{
  89        if (init_exec(init)) {
  90                if (init->outp)
  91                        return ffs(init->outp->or) - 1;
  92                error("script needs OR!!\n");
  93        }
  94        return 0;
  95}
  96
  97static inline int
  98init_link(struct nvbios_init *init)
  99{
 100        if (init_exec(init)) {
 101                if (init->outp)
 102                        return !(init->outp->sorconf.link & 1);
 103                error("script needs OR link\n");
 104        }
 105        return 0;
 106}
 107
 108static inline int
 109init_crtc(struct nvbios_init *init)
 110{
 111        if (init_exec(init)) {
 112                if (init->crtc >= 0)
 113                        return init->crtc;
 114                error("script needs crtc\n");
 115        }
 116        return 0;
 117}
 118
 119static u8
 120init_conn(struct nvbios_init *init)
 121{
 122        struct nvkm_bios *bios = init->bios;
 123        struct nvbios_connE connE;
 124        u8  ver, hdr;
 125        u32 conn;
 126
 127        if (init_exec(init)) {
 128                if (init->outp) {
 129                        conn = init->outp->connector;
 130                        conn = nvbios_connEp(bios, conn, &ver, &hdr, &connE);
 131                        if (conn)
 132                                return connE.type;
 133                }
 134
 135                error("script needs connector type\n");
 136        }
 137
 138        return 0xff;
 139}
 140
 141static inline u32
 142init_nvreg(struct nvbios_init *init, u32 reg)
 143{
 144        struct nvkm_devinit *devinit = init->bios->subdev.device->devinit;
 145
 146        /* C51 (at least) sometimes has the lower bits set which the VBIOS
 147         * interprets to mean that access needs to go through certain IO
 148         * ports instead.  The NVIDIA binary driver has been seen to access
 149         * these through the NV register address, so lets assume we can
 150         * do the same
 151         */
 152        reg &= ~0x00000003;
 153
 154        /* GF8+ display scripts need register addresses mangled a bit to
 155         * select a specific CRTC/OR
 156         */
 157        if (init->bios->subdev.device->card_type >= NV_50) {
 158                if (reg & 0x80000000) {
 159                        reg += init_crtc(init) * 0x800;
 160                        reg &= ~0x80000000;
 161                }
 162
 163                if (reg & 0x40000000) {
 164                        reg += init_or(init) * 0x800;
 165                        reg &= ~0x40000000;
 166                        if (reg & 0x20000000) {
 167                                reg += init_link(init) * 0x80;
 168                                reg &= ~0x20000000;
 169                        }
 170                }
 171        }
 172
 173        if (reg & ~0x00fffffc)
 174                warn("unknown bits in register 0x%08x\n", reg);
 175
 176        return nvkm_devinit_mmio(devinit, reg);
 177}
 178
 179static u32
 180init_rd32(struct nvbios_init *init, u32 reg)
 181{
 182        struct nvkm_device *device = init->bios->subdev.device;
 183        reg = init_nvreg(init, reg);
 184        if (reg != ~0 && init_exec(init))
 185                return nvkm_rd32(device, reg);
 186        return 0x00000000;
 187}
 188
 189static void
 190init_wr32(struct nvbios_init *init, u32 reg, u32 val)
 191{
 192        struct nvkm_device *device = init->bios->subdev.device;
 193        reg = init_nvreg(init, reg);
 194        if (reg != ~0 && init_exec(init))
 195                nvkm_wr32(device, reg, val);
 196}
 197
 198static u32
 199init_mask(struct nvbios_init *init, u32 reg, u32 mask, u32 val)
 200{
 201        struct nvkm_device *device = init->bios->subdev.device;
 202        reg = init_nvreg(init, reg);
 203        if (reg != ~0 && init_exec(init)) {
 204                u32 tmp = nvkm_rd32(device, reg);
 205                nvkm_wr32(device, reg, (tmp & ~mask) | val);
 206                return tmp;
 207        }
 208        return 0x00000000;
 209}
 210
 211static u8
 212init_rdport(struct nvbios_init *init, u16 port)
 213{
 214        if (init_exec(init))
 215                return nvkm_rdport(init->subdev->device, init->crtc, port);
 216        return 0x00;
 217}
 218
 219static void
 220init_wrport(struct nvbios_init *init, u16 port, u8 value)
 221{
 222        if (init_exec(init))
 223                nvkm_wrport(init->subdev->device, init->crtc, port, value);
 224}
 225
 226static u8
 227init_rdvgai(struct nvbios_init *init, u16 port, u8 index)
 228{
 229        struct nvkm_subdev *subdev = init->subdev;
 230        if (init_exec(init)) {
 231                int head = init->crtc < 0 ? 0 : init->crtc;
 232                return nvkm_rdvgai(subdev->device, head, port, index);
 233        }
 234        return 0x00;
 235}
 236
 237static void
 238init_wrvgai(struct nvbios_init *init, u16 port, u8 index, u8 value)
 239{
 240        struct nvkm_device *device = init->subdev->device;
 241
 242        /* force head 0 for updates to cr44, it only exists on first head */
 243        if (device->card_type < NV_50) {
 244                if (port == 0x03d4 && index == 0x44)
 245                        init->crtc = 0;
 246        }
 247
 248        if (init_exec(init)) {
 249                int head = init->crtc < 0 ? 0 : init->crtc;
 250                nvkm_wrvgai(device, head, port, index, value);
 251        }
 252
 253        /* select head 1 if cr44 write selected it */
 254        if (device->card_type < NV_50) {
 255                if (port == 0x03d4 && index == 0x44 && value == 3)
 256                        init->crtc = 1;
 257        }
 258}
 259
 260static struct i2c_adapter *
 261init_i2c(struct nvbios_init *init, int index)
 262{
 263        struct nvkm_i2c *i2c = init->bios->subdev.device->i2c;
 264        struct nvkm_i2c_bus *bus;
 265
 266        if (index == 0xff) {
 267                index = NVKM_I2C_BUS_PRI;
 268                if (init->outp && init->outp->i2c_upper_default)
 269                        index = NVKM_I2C_BUS_SEC;
 270        } else
 271        if (index == 0x80) {
 272                index = NVKM_I2C_BUS_PRI;
 273        } else
 274        if (index == 0x81) {
 275                index = NVKM_I2C_BUS_SEC;
 276        }
 277
 278        bus = nvkm_i2c_bus_find(i2c, index);
 279        return bus ? &bus->i2c : NULL;
 280}
 281
 282static int
 283init_rdi2cr(struct nvbios_init *init, u8 index, u8 addr, u8 reg)
 284{
 285        struct i2c_adapter *adap = init_i2c(init, index);
 286        if (adap && init_exec(init))
 287                return nvkm_rdi2cr(adap, addr, reg);
 288        return -ENODEV;
 289}
 290
 291static int
 292init_wri2cr(struct nvbios_init *init, u8 index, u8 addr, u8 reg, u8 val)
 293{
 294        struct i2c_adapter *adap = init_i2c(init, index);
 295        if (adap && init_exec(init))
 296                return nvkm_wri2cr(adap, addr, reg, val);
 297        return -ENODEV;
 298}
 299
 300static struct nvkm_i2c_aux *
 301init_aux(struct nvbios_init *init)
 302{
 303        struct nvkm_i2c *i2c = init->bios->subdev.device->i2c;
 304        if (!init->outp) {
 305                if (init_exec(init))
 306                        error("script needs output for aux\n");
 307                return NULL;
 308        }
 309        return nvkm_i2c_aux_find(i2c, init->outp->i2c_index);
 310}
 311
 312static u8
 313init_rdauxr(struct nvbios_init *init, u32 addr)
 314{
 315        struct nvkm_i2c_aux *aux = init_aux(init);
 316        u8 data;
 317
 318        if (aux && init_exec(init)) {
 319                int ret = nvkm_rdaux(aux, addr, &data, 1);
 320                if (ret == 0)
 321                        return data;
 322                trace("auxch read failed with %d\n", ret);
 323        }
 324
 325        return 0x00;
 326}
 327
 328static int
 329init_wrauxr(struct nvbios_init *init, u32 addr, u8 data)
 330{
 331        struct nvkm_i2c_aux *aux = init_aux(init);
 332        if (aux && init_exec(init)) {
 333                int ret = nvkm_wraux(aux, addr, &data, 1);
 334                if (ret)
 335                        trace("auxch write failed with %d\n", ret);
 336                return ret;
 337        }
 338        return -ENODEV;
 339}
 340
 341static void
 342init_prog_pll(struct nvbios_init *init, u32 id, u32 freq)
 343{
 344        struct nvkm_devinit *devinit = init->bios->subdev.device->devinit;
 345        if (init_exec(init)) {
 346                int ret = nvkm_devinit_pll_set(devinit, id, freq);
 347                if (ret)
 348                        warn("failed to prog pll 0x%08x to %dkHz\n", id, freq);
 349        }
 350}
 351
 352/******************************************************************************
 353 * parsing of bios structures that are required to execute init tables
 354 *****************************************************************************/
 355
 356static u16
 357init_table(struct nvkm_bios *bios, u16 *len)
 358{
 359        struct bit_entry bit_I;
 360
 361        if (!bit_entry(bios, 'I', &bit_I)) {
 362                *len = bit_I.length;
 363                return bit_I.offset;
 364        }
 365
 366        if (bmp_version(bios) >= 0x0510) {
 367                *len = 14;
 368                return bios->bmp_offset + 75;
 369        }
 370
 371        return 0x0000;
 372}
 373
 374static u16
 375init_table_(struct nvbios_init *init, u16 offset, const char *name)
 376{
 377        struct nvkm_bios *bios = init->bios;
 378        u16 len, data = init_table(bios, &len);
 379        if (data) {
 380                if (len >= offset + 2) {
 381                        data = nvbios_rd16(bios, data + offset);
 382                        if (data)
 383                                return data;
 384
 385                        warn("%s pointer invalid\n", name);
 386                        return 0x0000;
 387                }
 388
 389                warn("init data too short for %s pointer", name);
 390                return 0x0000;
 391        }
 392
 393        warn("init data not found\n");
 394        return 0x0000;
 395}
 396
 397#define init_script_table(b) init_table_((b), 0x00, "script table")
 398#define init_macro_index_table(b) init_table_((b), 0x02, "macro index table")
 399#define init_macro_table(b) init_table_((b), 0x04, "macro table")
 400#define init_condition_table(b) init_table_((b), 0x06, "condition table")
 401#define init_io_condition_table(b) init_table_((b), 0x08, "io condition table")
 402#define init_io_flag_condition_table(b) init_table_((b), 0x0a, "io flag conditon table")
 403#define init_function_table(b) init_table_((b), 0x0c, "function table")
 404#define init_xlat_table(b) init_table_((b), 0x10, "xlat table");
 405
 406static u16
 407init_script(struct nvkm_bios *bios, int index)
 408{
 409        struct nvbios_init init = { .bios = bios };
 410        u16 bmp_ver = bmp_version(bios), data;
 411
 412        if (bmp_ver && bmp_ver < 0x0510) {
 413                if (index > 1 || bmp_ver < 0x0100)
 414                        return 0x0000;
 415
 416                data = bios->bmp_offset + (bmp_ver < 0x0200 ? 14 : 18);
 417                return nvbios_rd16(bios, data + (index * 2));
 418        }
 419
 420        data = init_script_table(&init);
 421        if (data)
 422                return nvbios_rd16(bios, data + (index * 2));
 423
 424        return 0x0000;
 425}
 426
 427static u16
 428init_unknown_script(struct nvkm_bios *bios)
 429{
 430        u16 len, data = init_table(bios, &len);
 431        if (data && len >= 16)
 432                return nvbios_rd16(bios, data + 14);
 433        return 0x0000;
 434}
 435
 436static u8
 437init_ram_restrict_group_count(struct nvbios_init *init)
 438{
 439        return nvbios_ramcfg_count(init->bios);
 440}
 441
 442static u8
 443init_ram_restrict(struct nvbios_init *init)
 444{
 445        /* This appears to be the behaviour of the VBIOS parser, and *is*
 446         * important to cache the NV_PEXTDEV_BOOT0 on later chipsets to
 447         * avoid fucking up the memory controller (somehow) by reading it
 448         * on every INIT_RAM_RESTRICT_ZM_GROUP opcode.
 449         *
 450         * Preserving the non-caching behaviour on earlier chipsets just
 451         * in case *not* re-reading the strap causes similar breakage.
 452         */
 453        if (!init->ramcfg || init->bios->version.major < 0x70)
 454                init->ramcfg = 0x80000000 | nvbios_ramcfg_index(init->subdev);
 455        return (init->ramcfg & 0x7fffffff);
 456}
 457
 458static u8
 459init_xlat_(struct nvbios_init *init, u8 index, u8 offset)
 460{
 461        struct nvkm_bios *bios = init->bios;
 462        u16 table = init_xlat_table(init);
 463        if (table) {
 464                u16 data = nvbios_rd16(bios, table + (index * 2));
 465                if (data)
 466                        return nvbios_rd08(bios, data + offset);
 467                warn("xlat table pointer %d invalid\n", index);
 468        }
 469        return 0x00;
 470}
 471
 472/******************************************************************************
 473 * utility functions used by various init opcode handlers
 474 *****************************************************************************/
 475
 476static bool
 477init_condition_met(struct nvbios_init *init, u8 cond)
 478{
 479        struct nvkm_bios *bios = init->bios;
 480        u16 table = init_condition_table(init);
 481        if (table) {
 482                u32 reg = nvbios_rd32(bios, table + (cond * 12) + 0);
 483                u32 msk = nvbios_rd32(bios, table + (cond * 12) + 4);
 484                u32 val = nvbios_rd32(bios, table + (cond * 12) + 8);
 485                trace("\t[0x%02x] (R[0x%06x] & 0x%08x) == 0x%08x\n",
 486                      cond, reg, msk, val);
 487                return (init_rd32(init, reg) & msk) == val;
 488        }
 489        return false;
 490}
 491
 492static bool
 493init_io_condition_met(struct nvbios_init *init, u8 cond)
 494{
 495        struct nvkm_bios *bios = init->bios;
 496        u16 table = init_io_condition_table(init);
 497        if (table) {
 498                u16 port = nvbios_rd16(bios, table + (cond * 5) + 0);
 499                u8 index = nvbios_rd08(bios, table + (cond * 5) + 2);
 500                u8  mask = nvbios_rd08(bios, table + (cond * 5) + 3);
 501                u8 value = nvbios_rd08(bios, table + (cond * 5) + 4);
 502                trace("\t[0x%02x] (0x%04x[0x%02x] & 0x%02x) == 0x%02x\n",
 503                      cond, port, index, mask, value);
 504                return (init_rdvgai(init, port, index) & mask) == value;
 505        }
 506        return false;
 507}
 508
 509static bool
 510init_io_flag_condition_met(struct nvbios_init *init, u8 cond)
 511{
 512        struct nvkm_bios *bios = init->bios;
 513        u16 table = init_io_flag_condition_table(init);
 514        if (table) {
 515                u16 port = nvbios_rd16(bios, table + (cond * 9) + 0);
 516                u8 index = nvbios_rd08(bios, table + (cond * 9) + 2);
 517                u8  mask = nvbios_rd08(bios, table + (cond * 9) + 3);
 518                u8 shift = nvbios_rd08(bios, table + (cond * 9) + 4);
 519                u16 data = nvbios_rd16(bios, table + (cond * 9) + 5);
 520                u8 dmask = nvbios_rd08(bios, table + (cond * 9) + 7);
 521                u8 value = nvbios_rd08(bios, table + (cond * 9) + 8);
 522                u8 ioval = (init_rdvgai(init, port, index) & mask) >> shift;
 523                return (nvbios_rd08(bios, data + ioval) & dmask) == value;
 524        }
 525        return false;
 526}
 527
 528static inline u32
 529init_shift(u32 data, u8 shift)
 530{
 531        if (shift < 0x80)
 532                return data >> shift;
 533        return data << (0x100 - shift);
 534}
 535
 536static u32
 537init_tmds_reg(struct nvbios_init *init, u8 tmds)
 538{
 539        /* For mlv < 0x80, it is an index into a table of TMDS base addresses.
 540         * For mlv == 0x80 use the "or" value of the dcb_entry indexed by
 541         * CR58 for CR57 = 0 to index a table of offsets to the basic
 542         * 0x6808b0 address.
 543         * For mlv == 0x81 use the "or" value of the dcb_entry indexed by
 544         * CR58 for CR57 = 0 to index a table of offsets to the basic
 545         * 0x6808b0 address, and then flip the offset by 8.
 546         */
 547        const int pramdac_offset[13] = {
 548                0, 0, 0x8, 0, 0x2000, 0, 0, 0, 0x2008, 0, 0, 0, 0x2000 };
 549        const u32 pramdac_table[4] = {
 550                0x6808b0, 0x6808b8, 0x6828b0, 0x6828b8 };
 551
 552        if (tmds >= 0x80) {
 553                if (init->outp) {
 554                        u32 dacoffset = pramdac_offset[init->outp->or];
 555                        if (tmds == 0x81)
 556                                dacoffset ^= 8;
 557                        return 0x6808b0 + dacoffset;
 558                }
 559
 560                if (init_exec(init))
 561                        error("tmds opcodes need dcb\n");
 562        } else {
 563                if (tmds < ARRAY_SIZE(pramdac_table))
 564                        return pramdac_table[tmds];
 565
 566                error("tmds selector 0x%02x unknown\n", tmds);
 567        }
 568
 569        return 0;
 570}
 571
 572/******************************************************************************
 573 * init opcode handlers
 574 *****************************************************************************/
 575
 576/**
 577 * init_reserved - stub for various unknown/unused single-byte opcodes
 578 *
 579 */
 580static void
 581init_reserved(struct nvbios_init *init)
 582{
 583        u8 opcode = nvbios_rd08(init->bios, init->offset);
 584        u8 length, i;
 585
 586        switch (opcode) {
 587        case 0xaa:
 588                length = 4;
 589                break;
 590        default:
 591                length = 1;
 592                break;
 593        }
 594
 595        trace("RESERVED 0x%02x\t", opcode);
 596        for (i = 1; i < length; i++)
 597                cont(" 0x%02x", nvbios_rd08(init->bios, init->offset + i));
 598        cont("\n");
 599        init->offset += length;
 600}
 601
 602/**
 603 * INIT_DONE - opcode 0x71
 604 *
 605 */
 606static void
 607init_done(struct nvbios_init *init)
 608{
 609        trace("DONE\n");
 610        init->offset = 0x0000;
 611}
 612
 613/**
 614 * INIT_IO_RESTRICT_PROG - opcode 0x32
 615 *
 616 */
 617static void
 618init_io_restrict_prog(struct nvbios_init *init)
 619{
 620        struct nvkm_bios *bios = init->bios;
 621        u16 port = nvbios_rd16(bios, init->offset + 1);
 622        u8 index = nvbios_rd08(bios, init->offset + 3);
 623        u8  mask = nvbios_rd08(bios, init->offset + 4);
 624        u8 shift = nvbios_rd08(bios, init->offset + 5);
 625        u8 count = nvbios_rd08(bios, init->offset + 6);
 626        u32  reg = nvbios_rd32(bios, init->offset + 7);
 627        u8 conf, i;
 628
 629        trace("IO_RESTRICT_PROG\tR[0x%06x] = "
 630              "((0x%04x[0x%02x] & 0x%02x) >> %d) [{\n",
 631              reg, port, index, mask, shift);
 632        init->offset += 11;
 633
 634        conf = (init_rdvgai(init, port, index) & mask) >> shift;
 635        for (i = 0; i < count; i++) {
 636                u32 data = nvbios_rd32(bios, init->offset);
 637
 638                if (i == conf) {
 639                        trace("\t0x%08x *\n", data);
 640                        init_wr32(init, reg, data);
 641                } else {
 642                        trace("\t0x%08x\n", data);
 643                }
 644
 645                init->offset += 4;
 646        }
 647        trace("}]\n");
 648}
 649
 650/**
 651 * INIT_REPEAT - opcode 0x33
 652 *
 653 */
 654static void
 655init_repeat(struct nvbios_init *init)
 656{
 657        struct nvkm_bios *bios = init->bios;
 658        u8 count = nvbios_rd08(bios, init->offset + 1);
 659        u16 repeat = init->repeat;
 660
 661        trace("REPEAT\t0x%02x\n", count);
 662        init->offset += 2;
 663
 664        init->repeat = init->offset;
 665        init->repend = init->offset;
 666        while (count--) {
 667                init->offset = init->repeat;
 668                nvbios_exec(init);
 669                if (count)
 670                        trace("REPEAT\t0x%02x\n", count);
 671        }
 672        init->offset = init->repend;
 673        init->repeat = repeat;
 674}
 675
 676/**
 677 * INIT_IO_RESTRICT_PLL - opcode 0x34
 678 *
 679 */
 680static void
 681init_io_restrict_pll(struct nvbios_init *init)
 682{
 683        struct nvkm_bios *bios = init->bios;
 684        u16 port = nvbios_rd16(bios, init->offset + 1);
 685        u8 index = nvbios_rd08(bios, init->offset + 3);
 686        u8  mask = nvbios_rd08(bios, init->offset + 4);
 687        u8 shift = nvbios_rd08(bios, init->offset + 5);
 688        s8  iofc = nvbios_rd08(bios, init->offset + 6);
 689        u8 count = nvbios_rd08(bios, init->offset + 7);
 690        u32  reg = nvbios_rd32(bios, init->offset + 8);
 691        u8 conf, i;
 692
 693        trace("IO_RESTRICT_PLL\tR[0x%06x] =PLL= "
 694              "((0x%04x[0x%02x] & 0x%02x) >> 0x%02x) IOFCOND 0x%02x [{\n",
 695              reg, port, index, mask, shift, iofc);
 696        init->offset += 12;
 697
 698        conf = (init_rdvgai(init, port, index) & mask) >> shift;
 699        for (i = 0; i < count; i++) {
 700                u32 freq = nvbios_rd16(bios, init->offset) * 10;
 701
 702                if (i == conf) {
 703                        trace("\t%dkHz *\n", freq);
 704                        if (iofc > 0 && init_io_flag_condition_met(init, iofc))
 705                                freq *= 2;
 706                        init_prog_pll(init, reg, freq);
 707                } else {
 708                        trace("\t%dkHz\n", freq);
 709                }
 710
 711                init->offset += 2;
 712        }
 713        trace("}]\n");
 714}
 715
 716/**
 717 * INIT_END_REPEAT - opcode 0x36
 718 *
 719 */
 720static void
 721init_end_repeat(struct nvbios_init *init)
 722{
 723        trace("END_REPEAT\n");
 724        init->offset += 1;
 725
 726        if (init->repeat) {
 727                init->repend = init->offset;
 728                init->offset = 0;
 729        }
 730}
 731
 732/**
 733 * INIT_COPY - opcode 0x37
 734 *
 735 */
 736static void
 737init_copy(struct nvbios_init *init)
 738{
 739        struct nvkm_bios *bios = init->bios;
 740        u32  reg = nvbios_rd32(bios, init->offset + 1);
 741        u8 shift = nvbios_rd08(bios, init->offset + 5);
 742        u8 smask = nvbios_rd08(bios, init->offset + 6);
 743        u16 port = nvbios_rd16(bios, init->offset + 7);
 744        u8 index = nvbios_rd08(bios, init->offset + 9);
 745        u8  mask = nvbios_rd08(bios, init->offset + 10);
 746        u8  data;
 747
 748        trace("COPY\t0x%04x[0x%02x] &= 0x%02x |= "
 749              "((R[0x%06x] %s 0x%02x) & 0x%02x)\n",
 750              port, index, mask, reg, (shift & 0x80) ? "<<" : ">>",
 751              (shift & 0x80) ? (0x100 - shift) : shift, smask);
 752        init->offset += 11;
 753
 754        data  = init_rdvgai(init, port, index) & mask;
 755        data |= init_shift(init_rd32(init, reg), shift) & smask;
 756        init_wrvgai(init, port, index, data);
 757}
 758
 759/**
 760 * INIT_NOT - opcode 0x38
 761 *
 762 */
 763static void
 764init_not(struct nvbios_init *init)
 765{
 766        trace("NOT\n");
 767        init->offset += 1;
 768        init_exec_inv(init);
 769}
 770
 771/**
 772 * INIT_IO_FLAG_CONDITION - opcode 0x39
 773 *
 774 */
 775static void
 776init_io_flag_condition(struct nvbios_init *init)
 777{
 778        struct nvkm_bios *bios = init->bios;
 779        u8 cond = nvbios_rd08(bios, init->offset + 1);
 780
 781        trace("IO_FLAG_CONDITION\t0x%02x\n", cond);
 782        init->offset += 2;
 783
 784        if (!init_io_flag_condition_met(init, cond))
 785                init_exec_set(init, false);
 786}
 787
 788/**
 789 * INIT_GENERIC_CONDITION - opcode 0x3a
 790 *
 791 */
 792static void
 793init_generic_condition(struct nvbios_init *init)
 794{
 795        struct nvkm_bios *bios = init->bios;
 796        struct nvbios_dpout info;
 797        u8  cond = nvbios_rd08(bios, init->offset + 1);
 798        u8  size = nvbios_rd08(bios, init->offset + 2);
 799        u8  ver, hdr, cnt, len;
 800        u16 data;
 801
 802        trace("GENERIC_CONDITION\t0x%02x 0x%02x\n", cond, size);
 803        init->offset += 3;
 804
 805        switch (cond) {
 806        case 0:
 807                if (init_conn(init) != DCB_CONNECTOR_eDP)
 808                        init_exec_set(init, false);
 809                break;
 810        case 1:
 811        case 2:
 812                if ( init->outp &&
 813                    (data = nvbios_dpout_match(bios, DCB_OUTPUT_DP,
 814                                               (init->outp->or << 0) |
 815                                               (init->outp->sorconf.link << 6),
 816                                               &ver, &hdr, &cnt, &len, &info)))
 817                {
 818                        if (!(info.flags & cond))
 819                                init_exec_set(init, false);
 820                        break;
 821                }
 822
 823                if (init_exec(init))
 824                        warn("script needs dp output table data\n");
 825                break;
 826        case 5:
 827                if (!(init_rdauxr(init, 0x0d) & 1))
 828                        init_exec_set(init, false);
 829                break;
 830        default:
 831                warn("INIT_GENERIC_CONDITON: unknown 0x%02x\n", cond);
 832                init->offset += size;
 833                break;
 834        }
 835}
 836
 837/**
 838 * INIT_IO_MASK_OR - opcode 0x3b
 839 *
 840 */
 841static void
 842init_io_mask_or(struct nvbios_init *init)
 843{
 844        struct nvkm_bios *bios = init->bios;
 845        u8 index = nvbios_rd08(bios, init->offset + 1);
 846        u8    or = init_or(init);
 847        u8  data;
 848
 849        trace("IO_MASK_OR\t0x03d4[0x%02x] &= ~(1 << 0x%02x)\n", index, or);
 850        init->offset += 2;
 851
 852        data = init_rdvgai(init, 0x03d4, index);
 853        init_wrvgai(init, 0x03d4, index, data &= ~(1 << or));
 854}
 855
 856/**
 857 * INIT_IO_OR - opcode 0x3c
 858 *
 859 */
 860static void
 861init_io_or(struct nvbios_init *init)
 862{
 863        struct nvkm_bios *bios = init->bios;
 864        u8 index = nvbios_rd08(bios, init->offset + 1);
 865        u8    or = init_or(init);
 866        u8  data;
 867
 868        trace("IO_OR\t0x03d4[0x%02x] |= (1 << 0x%02x)\n", index, or);
 869        init->offset += 2;
 870
 871        data = init_rdvgai(init, 0x03d4, index);
 872        init_wrvgai(init, 0x03d4, index, data | (1 << or));
 873}
 874
 875/**
 876 * INIT_ANDN_REG - opcode 0x47
 877 *
 878 */
 879static void
 880init_andn_reg(struct nvbios_init *init)
 881{
 882        struct nvkm_bios *bios = init->bios;
 883        u32  reg = nvbios_rd32(bios, init->offset + 1);
 884        u32 mask = nvbios_rd32(bios, init->offset + 5);
 885
 886        trace("ANDN_REG\tR[0x%06x] &= ~0x%08x\n", reg, mask);
 887        init->offset += 9;
 888
 889        init_mask(init, reg, mask, 0);
 890}
 891
 892/**
 893 * INIT_OR_REG - opcode 0x48
 894 *
 895 */
 896static void
 897init_or_reg(struct nvbios_init *init)
 898{
 899        struct nvkm_bios *bios = init->bios;
 900        u32  reg = nvbios_rd32(bios, init->offset + 1);
 901        u32 mask = nvbios_rd32(bios, init->offset + 5);
 902
 903        trace("OR_REG\tR[0x%06x] |= 0x%08x\n", reg, mask);
 904        init->offset += 9;
 905
 906        init_mask(init, reg, 0, mask);
 907}
 908
 909/**
 910 * INIT_INDEX_ADDRESS_LATCHED - opcode 0x49
 911 *
 912 */
 913static void
 914init_idx_addr_latched(struct nvbios_init *init)
 915{
 916        struct nvkm_bios *bios = init->bios;
 917        u32 creg = nvbios_rd32(bios, init->offset + 1);
 918        u32 dreg = nvbios_rd32(bios, init->offset + 5);
 919        u32 mask = nvbios_rd32(bios, init->offset + 9);
 920        u32 data = nvbios_rd32(bios, init->offset + 13);
 921        u8 count = nvbios_rd08(bios, init->offset + 17);
 922
 923        trace("INDEX_ADDRESS_LATCHED\tR[0x%06x] : R[0x%06x]\n", creg, dreg);
 924        trace("\tCTRL &= 0x%08x |= 0x%08x\n", mask, data);
 925        init->offset += 18;
 926
 927        while (count--) {
 928                u8 iaddr = nvbios_rd08(bios, init->offset + 0);
 929                u8 idata = nvbios_rd08(bios, init->offset + 1);
 930
 931                trace("\t[0x%02x] = 0x%02x\n", iaddr, idata);
 932                init->offset += 2;
 933
 934                init_wr32(init, dreg, idata);
 935                init_mask(init, creg, ~mask, data | iaddr);
 936        }
 937}
 938
 939/**
 940 * INIT_IO_RESTRICT_PLL2 - opcode 0x4a
 941 *
 942 */
 943static void
 944init_io_restrict_pll2(struct nvbios_init *init)
 945{
 946        struct nvkm_bios *bios = init->bios;
 947        u16 port = nvbios_rd16(bios, init->offset + 1);
 948        u8 index = nvbios_rd08(bios, init->offset + 3);
 949        u8  mask = nvbios_rd08(bios, init->offset + 4);
 950        u8 shift = nvbios_rd08(bios, init->offset + 5);
 951        u8 count = nvbios_rd08(bios, init->offset + 6);
 952        u32  reg = nvbios_rd32(bios, init->offset + 7);
 953        u8  conf, i;
 954
 955        trace("IO_RESTRICT_PLL2\t"
 956              "R[0x%06x] =PLL= ((0x%04x[0x%02x] & 0x%02x) >> 0x%02x) [{\n",
 957              reg, port, index, mask, shift);
 958        init->offset += 11;
 959
 960        conf = (init_rdvgai(init, port, index) & mask) >> shift;
 961        for (i = 0; i < count; i++) {
 962                u32 freq = nvbios_rd32(bios, init->offset);
 963                if (i == conf) {
 964                        trace("\t%dkHz *\n", freq);
 965                        init_prog_pll(init, reg, freq);
 966                } else {
 967                        trace("\t%dkHz\n", freq);
 968                }
 969                init->offset += 4;
 970        }
 971        trace("}]\n");
 972}
 973
 974/**
 975 * INIT_PLL2 - opcode 0x4b
 976 *
 977 */
 978static void
 979init_pll2(struct nvbios_init *init)
 980{
 981        struct nvkm_bios *bios = init->bios;
 982        u32  reg = nvbios_rd32(bios, init->offset + 1);
 983        u32 freq = nvbios_rd32(bios, init->offset + 5);
 984
 985        trace("PLL2\tR[0x%06x] =PLL= %dkHz\n", reg, freq);
 986        init->offset += 9;
 987
 988        init_prog_pll(init, reg, freq);
 989}
 990
 991/**
 992 * INIT_I2C_BYTE - opcode 0x4c
 993 *
 994 */
 995static void
 996init_i2c_byte(struct nvbios_init *init)
 997{
 998        struct nvkm_bios *bios = init->bios;
 999        u8 index = nvbios_rd08(bios, init->offset + 1);
1000        u8  addr = nvbios_rd08(bios, init->offset + 2) >> 1;
1001        u8 count = nvbios_rd08(bios, init->offset + 3);
1002
1003        trace("I2C_BYTE\tI2C[0x%02x][0x%02x]\n", index, addr);
1004        init->offset += 4;
1005
1006        while (count--) {
1007                u8  reg = nvbios_rd08(bios, init->offset + 0);
1008                u8 mask = nvbios_rd08(bios, init->offset + 1);
1009                u8 data = nvbios_rd08(bios, init->offset + 2);
1010                int val;
1011
1012                trace("\t[0x%02x] &= 0x%02x |= 0x%02x\n", reg, mask, data);
1013                init->offset += 3;
1014
1015                val = init_rdi2cr(init, index, addr, reg);
1016                if (val < 0)
1017                        continue;
1018                init_wri2cr(init, index, addr, reg, (val & mask) | data);
1019        }
1020}
1021
1022/**
1023 * INIT_ZM_I2C_BYTE - opcode 0x4d
1024 *
1025 */
1026static void
1027init_zm_i2c_byte(struct nvbios_init *init)
1028{
1029        struct nvkm_bios *bios = init->bios;
1030        u8 index = nvbios_rd08(bios, init->offset + 1);
1031        u8  addr = nvbios_rd08(bios, init->offset + 2) >> 1;
1032        u8 count = nvbios_rd08(bios, init->offset + 3);
1033
1034        trace("ZM_I2C_BYTE\tI2C[0x%02x][0x%02x]\n", index, addr);
1035        init->offset += 4;
1036
1037        while (count--) {
1038                u8  reg = nvbios_rd08(bios, init->offset + 0);
1039                u8 data = nvbios_rd08(bios, init->offset + 1);
1040
1041                trace("\t[0x%02x] = 0x%02x\n", reg, data);
1042                init->offset += 2;
1043
1044                init_wri2cr(init, index, addr, reg, data);
1045        }
1046}
1047
1048/**
1049 * INIT_ZM_I2C - opcode 0x4e
1050 *
1051 */
1052static void
1053init_zm_i2c(struct nvbios_init *init)
1054{
1055        struct nvkm_bios *bios = init->bios;
1056        u8 index = nvbios_rd08(bios, init->offset + 1);
1057        u8  addr = nvbios_rd08(bios, init->offset + 2) >> 1;
1058        u8 count = nvbios_rd08(bios, init->offset + 3);
1059        u8 data[256], i;
1060
1061        trace("ZM_I2C\tI2C[0x%02x][0x%02x]\n", index, addr);
1062        init->offset += 4;
1063
1064        for (i = 0; i < count; i++) {
1065                data[i] = nvbios_rd08(bios, init->offset);
1066                trace("\t0x%02x\n", data[i]);
1067                init->offset++;
1068        }
1069
1070        if (init_exec(init)) {
1071                struct i2c_adapter *adap = init_i2c(init, index);
1072                struct i2c_msg msg = {
1073                        .addr = addr, .flags = 0, .len = count, .buf = data,
1074                };
1075                int ret;
1076
1077                if (adap && (ret = i2c_transfer(adap, &msg, 1)) != 1)
1078                        warn("i2c wr failed, %d\n", ret);
1079        }
1080}
1081
1082/**
1083 * INIT_TMDS - opcode 0x4f
1084 *
1085 */
1086static void
1087init_tmds(struct nvbios_init *init)
1088{
1089        struct nvkm_bios *bios = init->bios;
1090        u8 tmds = nvbios_rd08(bios, init->offset + 1);
1091        u8 addr = nvbios_rd08(bios, init->offset + 2);
1092        u8 mask = nvbios_rd08(bios, init->offset + 3);
1093        u8 data = nvbios_rd08(bios, init->offset + 4);
1094        u32 reg = init_tmds_reg(init, tmds);
1095
1096        trace("TMDS\tT[0x%02x][0x%02x] &= 0x%02x |= 0x%02x\n",
1097              tmds, addr, mask, data);
1098        init->offset += 5;
1099
1100        if (reg == 0)
1101                return;
1102
1103        init_wr32(init, reg + 0, addr | 0x00010000);
1104        init_wr32(init, reg + 4, data | (init_rd32(init, reg + 4) & mask));
1105        init_wr32(init, reg + 0, addr);
1106}
1107
1108/**
1109 * INIT_ZM_TMDS_GROUP - opcode 0x50
1110 *
1111 */
1112static void
1113init_zm_tmds_group(struct nvbios_init *init)
1114{
1115        struct nvkm_bios *bios = init->bios;
1116        u8  tmds = nvbios_rd08(bios, init->offset + 1);
1117        u8 count = nvbios_rd08(bios, init->offset + 2);
1118        u32  reg = init_tmds_reg(init, tmds);
1119
1120        trace("TMDS_ZM_GROUP\tT[0x%02x]\n", tmds);
1121        init->offset += 3;
1122
1123        while (count--) {
1124                u8 addr = nvbios_rd08(bios, init->offset + 0);
1125                u8 data = nvbios_rd08(bios, init->offset + 1);
1126
1127                trace("\t[0x%02x] = 0x%02x\n", addr, data);
1128                init->offset += 2;
1129
1130                init_wr32(init, reg + 4, data);
1131                init_wr32(init, reg + 0, addr);
1132        }
1133}
1134
1135/**
1136 * INIT_CR_INDEX_ADDRESS_LATCHED - opcode 0x51
1137 *
1138 */
1139static void
1140init_cr_idx_adr_latch(struct nvbios_init *init)
1141{
1142        struct nvkm_bios *bios = init->bios;
1143        u8 addr0 = nvbios_rd08(bios, init->offset + 1);
1144        u8 addr1 = nvbios_rd08(bios, init->offset + 2);
1145        u8  base = nvbios_rd08(bios, init->offset + 3);
1146        u8 count = nvbios_rd08(bios, init->offset + 4);
1147        u8 save0;
1148
1149        trace("CR_INDEX_ADDR C[%02x] C[%02x]\n", addr0, addr1);
1150        init->offset += 5;
1151
1152        save0 = init_rdvgai(init, 0x03d4, addr0);
1153        while (count--) {
1154                u8 data = nvbios_rd08(bios, init->offset);
1155
1156                trace("\t\t[0x%02x] = 0x%02x\n", base, data);
1157                init->offset += 1;
1158
1159                init_wrvgai(init, 0x03d4, addr0, base++);
1160                init_wrvgai(init, 0x03d4, addr1, data);
1161        }
1162        init_wrvgai(init, 0x03d4, addr0, save0);
1163}
1164
1165/**
1166 * INIT_CR - opcode 0x52
1167 *
1168 */
1169static void
1170init_cr(struct nvbios_init *init)
1171{
1172        struct nvkm_bios *bios = init->bios;
1173        u8 addr = nvbios_rd08(bios, init->offset + 1);
1174        u8 mask = nvbios_rd08(bios, init->offset + 2);
1175        u8 data = nvbios_rd08(bios, init->offset + 3);
1176        u8 val;
1177
1178        trace("CR\t\tC[0x%02x] &= 0x%02x |= 0x%02x\n", addr, mask, data);
1179        init->offset += 4;
1180
1181        val = init_rdvgai(init, 0x03d4, addr) & mask;
1182        init_wrvgai(init, 0x03d4, addr, val | data);
1183}
1184
1185/**
1186 * INIT_ZM_CR - opcode 0x53
1187 *
1188 */
1189static void
1190init_zm_cr(struct nvbios_init *init)
1191{
1192        struct nvkm_bios *bios = init->bios;
1193        u8 addr = nvbios_rd08(bios, init->offset + 1);
1194        u8 data = nvbios_rd08(bios, init->offset + 2);
1195
1196        trace("ZM_CR\tC[0x%02x] = 0x%02x\n", addr,  data);
1197        init->offset += 3;
1198
1199        init_wrvgai(init, 0x03d4, addr, data);
1200}
1201
1202/**
1203 * INIT_ZM_CR_GROUP - opcode 0x54
1204 *
1205 */
1206static void
1207init_zm_cr_group(struct nvbios_init *init)
1208{
1209        struct nvkm_bios *bios = init->bios;
1210        u8 count = nvbios_rd08(bios, init->offset + 1);
1211
1212        trace("ZM_CR_GROUP\n");
1213        init->offset += 2;
1214
1215        while (count--) {
1216                u8 addr = nvbios_rd08(bios, init->offset + 0);
1217                u8 data = nvbios_rd08(bios, init->offset + 1);
1218
1219                trace("\t\tC[0x%02x] = 0x%02x\n", addr, data);
1220                init->offset += 2;
1221
1222                init_wrvgai(init, 0x03d4, addr, data);
1223        }
1224}
1225
1226/**
1227 * INIT_CONDITION_TIME - opcode 0x56
1228 *
1229 */
1230static void
1231init_condition_time(struct nvbios_init *init)
1232{
1233        struct nvkm_bios *bios = init->bios;
1234        u8  cond = nvbios_rd08(bios, init->offset + 1);
1235        u8 retry = nvbios_rd08(bios, init->offset + 2);
1236        u8  wait = min((u16)retry * 50, 100);
1237
1238        trace("CONDITION_TIME\t0x%02x 0x%02x\n", cond, retry);
1239        init->offset += 3;
1240
1241        if (!init_exec(init))
1242                return;
1243
1244        while (wait--) {
1245                if (init_condition_met(init, cond))
1246                        return;
1247                mdelay(20);
1248        }
1249
1250        init_exec_set(init, false);
1251}
1252
1253/**
1254 * INIT_LTIME - opcode 0x57
1255 *
1256 */
1257static void
1258init_ltime(struct nvbios_init *init)
1259{
1260        struct nvkm_bios *bios = init->bios;
1261        u16 msec = nvbios_rd16(bios, init->offset + 1);
1262
1263        trace("LTIME\t0x%04x\n", msec);
1264        init->offset += 3;
1265
1266        if (init_exec(init))
1267                mdelay(msec);
1268}
1269
1270/**
1271 * INIT_ZM_REG_SEQUENCE - opcode 0x58
1272 *
1273 */
1274static void
1275init_zm_reg_sequence(struct nvbios_init *init)
1276{
1277        struct nvkm_bios *bios = init->bios;
1278        u32 base = nvbios_rd32(bios, init->offset + 1);
1279        u8 count = nvbios_rd08(bios, init->offset + 5);
1280
1281        trace("ZM_REG_SEQUENCE\t0x%02x\n", count);
1282        init->offset += 6;
1283
1284        while (count--) {
1285                u32 data = nvbios_rd32(bios, init->offset);
1286
1287                trace("\t\tR[0x%06x] = 0x%08x\n", base, data);
1288                init->offset += 4;
1289
1290                init_wr32(init, base, data);
1291                base += 4;
1292        }
1293}
1294
1295/**
1296 * INIT_PLL_INDIRECT - opcode 0x59
1297 *
1298 */
1299static void
1300init_pll_indirect(struct nvbios_init *init)
1301{
1302        struct nvkm_bios *bios = init->bios;
1303        u32  reg = nvbios_rd32(bios, init->offset + 1);
1304        u16 addr = nvbios_rd16(bios, init->offset + 5);
1305        u32 freq = (u32)nvbios_rd16(bios, addr) * 1000;
1306
1307        trace("PLL_INDIRECT\tR[0x%06x] =PLL= VBIOS[%04x] = %dkHz\n",
1308              reg, addr, freq);
1309        init->offset += 7;
1310
1311        init_prog_pll(init, reg, freq);
1312}
1313
1314/**
1315 * INIT_ZM_REG_INDIRECT - opcode 0x5a
1316 *
1317 */
1318static void
1319init_zm_reg_indirect(struct nvbios_init *init)
1320{
1321        struct nvkm_bios *bios = init->bios;
1322        u32  reg = nvbios_rd32(bios, init->offset + 1);
1323        u16 addr = nvbios_rd16(bios, init->offset + 5);
1324        u32 data = nvbios_rd32(bios, addr);
1325
1326        trace("ZM_REG_INDIRECT\tR[0x%06x] = VBIOS[0x%04x] = 0x%08x\n",
1327              reg, addr, data);
1328        init->offset += 7;
1329
1330        init_wr32(init, addr, data);
1331}
1332
1333/**
1334 * INIT_SUB_DIRECT - opcode 0x5b
1335 *
1336 */
1337static void
1338init_sub_direct(struct nvbios_init *init)
1339{
1340        struct nvkm_bios *bios = init->bios;
1341        u16 addr = nvbios_rd16(bios, init->offset + 1);
1342        u16 save;
1343
1344        trace("SUB_DIRECT\t0x%04x\n", addr);
1345
1346        if (init_exec(init)) {
1347                save = init->offset;
1348                init->offset = addr;
1349                if (nvbios_exec(init)) {
1350                        error("error parsing sub-table\n");
1351                        return;
1352                }
1353                init->offset = save;
1354        }
1355
1356        init->offset += 3;
1357}
1358
1359/**
1360 * INIT_JUMP - opcode 0x5c
1361 *
1362 */
1363static void
1364init_jump(struct nvbios_init *init)
1365{
1366        struct nvkm_bios *bios = init->bios;
1367        u16 offset = nvbios_rd16(bios, init->offset + 1);
1368
1369        trace("JUMP\t0x%04x\n", offset);
1370
1371        if (init_exec(init))
1372                init->offset = offset;
1373        else
1374                init->offset += 3;
1375}
1376
1377/**
1378 * INIT_I2C_IF - opcode 0x5e
1379 *
1380 */
1381static void
1382init_i2c_if(struct nvbios_init *init)
1383{
1384        struct nvkm_bios *bios = init->bios;
1385        u8 index = nvbios_rd08(bios, init->offset + 1);
1386        u8  addr = nvbios_rd08(bios, init->offset + 2);
1387        u8   reg = nvbios_rd08(bios, init->offset + 3);
1388        u8  mask = nvbios_rd08(bios, init->offset + 4);
1389        u8  data = nvbios_rd08(bios, init->offset + 5);
1390        u8 value;
1391
1392        trace("I2C_IF\tI2C[0x%02x][0x%02x][0x%02x] & 0x%02x == 0x%02x\n",
1393              index, addr, reg, mask, data);
1394        init->offset += 6;
1395        init_exec_force(init, true);
1396
1397        value = init_rdi2cr(init, index, addr, reg);
1398        if ((value & mask) != data)
1399                init_exec_set(init, false);
1400
1401        init_exec_force(init, false);
1402}
1403
1404/**
1405 * INIT_COPY_NV_REG - opcode 0x5f
1406 *
1407 */
1408static void
1409init_copy_nv_reg(struct nvbios_init *init)
1410{
1411        struct nvkm_bios *bios = init->bios;
1412        u32  sreg = nvbios_rd32(bios, init->offset + 1);
1413        u8  shift = nvbios_rd08(bios, init->offset + 5);
1414        u32 smask = nvbios_rd32(bios, init->offset + 6);
1415        u32  sxor = nvbios_rd32(bios, init->offset + 10);
1416        u32  dreg = nvbios_rd32(bios, init->offset + 14);
1417        u32 dmask = nvbios_rd32(bios, init->offset + 18);
1418        u32 data;
1419
1420        trace("COPY_NV_REG\tR[0x%06x] &= 0x%08x |= "
1421              "((R[0x%06x] %s 0x%02x) & 0x%08x ^ 0x%08x)\n",
1422              dreg, dmask, sreg, (shift & 0x80) ? "<<" : ">>",
1423              (shift & 0x80) ? (0x100 - shift) : shift, smask, sxor);
1424        init->offset += 22;
1425
1426        data = init_shift(init_rd32(init, sreg), shift);
1427        init_mask(init, dreg, ~dmask, (data & smask) ^ sxor);
1428}
1429
1430/**
1431 * INIT_ZM_INDEX_IO - opcode 0x62
1432 *
1433 */
1434static void
1435init_zm_index_io(struct nvbios_init *init)
1436{
1437        struct nvkm_bios *bios = init->bios;
1438        u16 port = nvbios_rd16(bios, init->offset + 1);
1439        u8 index = nvbios_rd08(bios, init->offset + 3);
1440        u8  data = nvbios_rd08(bios, init->offset + 4);
1441
1442        trace("ZM_INDEX_IO\tI[0x%04x][0x%02x] = 0x%02x\n", port, index, data);
1443        init->offset += 5;
1444
1445        init_wrvgai(init, port, index, data);
1446}
1447
1448/**
1449 * INIT_COMPUTE_MEM - opcode 0x63
1450 *
1451 */
1452static void
1453init_compute_mem(struct nvbios_init *init)
1454{
1455        struct nvkm_devinit *devinit = init->bios->subdev.device->devinit;
1456
1457        trace("COMPUTE_MEM\n");
1458        init->offset += 1;
1459
1460        init_exec_force(init, true);
1461        if (init_exec(init))
1462                nvkm_devinit_meminit(devinit);
1463        init_exec_force(init, false);
1464}
1465
1466/**
1467 * INIT_RESET - opcode 0x65
1468 *
1469 */
1470static void
1471init_reset(struct nvbios_init *init)
1472{
1473        struct nvkm_bios *bios = init->bios;
1474        u32   reg = nvbios_rd32(bios, init->offset + 1);
1475        u32 data1 = nvbios_rd32(bios, init->offset + 5);
1476        u32 data2 = nvbios_rd32(bios, init->offset + 9);
1477        u32 savepci19;
1478
1479        trace("RESET\tR[0x%08x] = 0x%08x, 0x%08x", reg, data1, data2);
1480        init->offset += 13;
1481        init_exec_force(init, true);
1482
1483        savepci19 = init_mask(init, 0x00184c, 0x00000f00, 0x00000000);
1484        init_wr32(init, reg, data1);
1485        udelay(10);
1486        init_wr32(init, reg, data2);
1487        init_wr32(init, 0x00184c, savepci19);
1488        init_mask(init, 0x001850, 0x00000001, 0x00000000);
1489
1490        init_exec_force(init, false);
1491}
1492
1493/**
1494 * INIT_CONFIGURE_MEM - opcode 0x66
1495 *
1496 */
1497static u16
1498init_configure_mem_clk(struct nvbios_init *init)
1499{
1500        u16 mdata = bmp_mem_init_table(init->bios);
1501        if (mdata)
1502                mdata += (init_rdvgai(init, 0x03d4, 0x3c) >> 4) * 66;
1503        return mdata;
1504}
1505
1506static void
1507init_configure_mem(struct nvbios_init *init)
1508{
1509        struct nvkm_bios *bios = init->bios;
1510        u16 mdata, sdata;
1511        u32 addr, data;
1512
1513        trace("CONFIGURE_MEM\n");
1514        init->offset += 1;
1515
1516        if (bios->version.major > 2) {
1517                init_done(init);
1518                return;
1519        }
1520        init_exec_force(init, true);
1521
1522        mdata = init_configure_mem_clk(init);
1523        sdata = bmp_sdr_seq_table(bios);
1524        if (nvbios_rd08(bios, mdata) & 0x01)
1525                sdata = bmp_ddr_seq_table(bios);
1526        mdata += 6; /* skip to data */
1527
1528        data = init_rdvgai(init, 0x03c4, 0x01);
1529        init_wrvgai(init, 0x03c4, 0x01, data | 0x20);
1530
1531        for (; (addr = nvbios_rd32(bios, sdata)) != 0xffffffff; sdata += 4) {
1532                switch (addr) {
1533                case 0x10021c: /* CKE_NORMAL */
1534                case 0x1002d0: /* CMD_REFRESH */
1535                case 0x1002d4: /* CMD_PRECHARGE */
1536                        data = 0x00000001;
1537                        break;
1538                default:
1539                        data = nvbios_rd32(bios, mdata);
1540                        mdata += 4;
1541                        if (data == 0xffffffff)
1542                                continue;
1543                        break;
1544                }
1545
1546                init_wr32(init, addr, data);
1547        }
1548
1549        init_exec_force(init, false);
1550}
1551
1552/**
1553 * INIT_CONFIGURE_CLK - opcode 0x67
1554 *
1555 */
1556static void
1557init_configure_clk(struct nvbios_init *init)
1558{
1559        struct nvkm_bios *bios = init->bios;
1560        u16 mdata, clock;
1561
1562        trace("CONFIGURE_CLK\n");
1563        init->offset += 1;
1564
1565        if (bios->version.major > 2) {
1566                init_done(init);
1567                return;
1568        }
1569        init_exec_force(init, true);
1570
1571        mdata = init_configure_mem_clk(init);
1572
1573        /* NVPLL */
1574        clock = nvbios_rd16(bios, mdata + 4) * 10;
1575        init_prog_pll(init, 0x680500, clock);
1576
1577        /* MPLL */
1578        clock = nvbios_rd16(bios, mdata + 2) * 10;
1579        if (nvbios_rd08(bios, mdata) & 0x01)
1580                clock *= 2;
1581        init_prog_pll(init, 0x680504, clock);
1582
1583        init_exec_force(init, false);
1584}
1585
1586/**
1587 * INIT_CONFIGURE_PREINIT - opcode 0x68
1588 *
1589 */
1590static void
1591init_configure_preinit(struct nvbios_init *init)
1592{
1593        struct nvkm_bios *bios = init->bios;
1594        u32 strap;
1595
1596        trace("CONFIGURE_PREINIT\n");
1597        init->offset += 1;
1598
1599        if (bios->version.major > 2) {
1600                init_done(init);
1601                return;
1602        }
1603        init_exec_force(init, true);
1604
1605        strap = init_rd32(init, 0x101000);
1606        strap = ((strap << 2) & 0xf0) | ((strap & 0x40) >> 6);
1607        init_wrvgai(init, 0x03d4, 0x3c, strap);
1608
1609        init_exec_force(init, false);
1610}
1611
1612/**
1613 * INIT_IO - opcode 0x69
1614 *
1615 */
1616static void
1617init_io(struct nvbios_init *init)
1618{
1619        struct nvkm_bios *bios = init->bios;
1620        u16 port = nvbios_rd16(bios, init->offset + 1);
1621        u8  mask = nvbios_rd16(bios, init->offset + 3);
1622        u8  data = nvbios_rd16(bios, init->offset + 4);
1623        u8 value;
1624
1625        trace("IO\t\tI[0x%04x] &= 0x%02x |= 0x%02x\n", port, mask, data);
1626        init->offset += 5;
1627
1628        /* ummm.. yes.. should really figure out wtf this is and why it's
1629         * needed some day..  it's almost certainly wrong, but, it also
1630         * somehow makes things work...
1631         */
1632        if (bios->subdev.device->card_type >= NV_50 &&
1633            port == 0x03c3 && data == 0x01) {
1634                init_mask(init, 0x614100, 0xf0800000, 0x00800000);
1635                init_mask(init, 0x00e18c, 0x00020000, 0x00020000);
1636                init_mask(init, 0x614900, 0xf0800000, 0x00800000);
1637                init_mask(init, 0x000200, 0x40000000, 0x00000000);
1638                mdelay(10);
1639                init_mask(init, 0x00e18c, 0x00020000, 0x00000000);
1640                init_mask(init, 0x000200, 0x40000000, 0x40000000);
1641                init_wr32(init, 0x614100, 0x00800018);
1642                init_wr32(init, 0x614900, 0x00800018);
1643                mdelay(10);
1644                init_wr32(init, 0x614100, 0x10000018);
1645                init_wr32(init, 0x614900, 0x10000018);
1646        }
1647
1648        value = init_rdport(init, port) & mask;
1649        init_wrport(init, port, data | value);
1650}
1651
1652/**
1653 * INIT_SUB - opcode 0x6b
1654 *
1655 */
1656static void
1657init_sub(struct nvbios_init *init)
1658{
1659        struct nvkm_bios *bios = init->bios;
1660        u8 index = nvbios_rd08(bios, init->offset + 1);
1661        u16 addr, save;
1662
1663        trace("SUB\t0x%02x\n", index);
1664
1665        addr = init_script(bios, index);
1666        if (addr && init_exec(init)) {
1667                save = init->offset;
1668                init->offset = addr;
1669                if (nvbios_exec(init)) {
1670                        error("error parsing sub-table\n");
1671                        return;
1672                }
1673                init->offset = save;
1674        }
1675
1676        init->offset += 2;
1677}
1678
1679/**
1680 * INIT_RAM_CONDITION - opcode 0x6d
1681 *
1682 */
1683static void
1684init_ram_condition(struct nvbios_init *init)
1685{
1686        struct nvkm_bios *bios = init->bios;
1687        u8  mask = nvbios_rd08(bios, init->offset + 1);
1688        u8 value = nvbios_rd08(bios, init->offset + 2);
1689
1690        trace("RAM_CONDITION\t"
1691              "(R[0x100000] & 0x%02x) == 0x%02x\n", mask, value);
1692        init->offset += 3;
1693
1694        if ((init_rd32(init, 0x100000) & mask) != value)
1695                init_exec_set(init, false);
1696}
1697
1698/**
1699 * INIT_NV_REG - opcode 0x6e
1700 *
1701 */
1702static void
1703init_nv_reg(struct nvbios_init *init)
1704{
1705        struct nvkm_bios *bios = init->bios;
1706        u32  reg = nvbios_rd32(bios, init->offset + 1);
1707        u32 mask = nvbios_rd32(bios, init->offset + 5);
1708        u32 data = nvbios_rd32(bios, init->offset + 9);
1709
1710        trace("NV_REG\tR[0x%06x] &= 0x%08x |= 0x%08x\n", reg, mask, data);
1711        init->offset += 13;
1712
1713        init_mask(init, reg, ~mask, data);
1714}
1715
1716/**
1717 * INIT_MACRO - opcode 0x6f
1718 *
1719 */
1720static void
1721init_macro(struct nvbios_init *init)
1722{
1723        struct nvkm_bios *bios = init->bios;
1724        u8  macro = nvbios_rd08(bios, init->offset + 1);
1725        u16 table;
1726
1727        trace("MACRO\t0x%02x\n", macro);
1728
1729        table = init_macro_table(init);
1730        if (table) {
1731                u32 addr = nvbios_rd32(bios, table + (macro * 8) + 0);
1732                u32 data = nvbios_rd32(bios, table + (macro * 8) + 4);
1733                trace("\t\tR[0x%06x] = 0x%08x\n", addr, data);
1734                init_wr32(init, addr, data);
1735        }
1736
1737        init->offset += 2;
1738}
1739
1740/**
1741 * INIT_RESUME - opcode 0x72
1742 *
1743 */
1744static void
1745init_resume(struct nvbios_init *init)
1746{
1747        trace("RESUME\n");
1748        init->offset += 1;
1749        init_exec_set(init, true);
1750}
1751
1752/**
1753 * INIT_STRAP_CONDITION - opcode 0x73
1754 *
1755 */
1756static void
1757init_strap_condition(struct nvbios_init *init)
1758{
1759        struct nvkm_bios *bios = init->bios;
1760        u32 mask = nvbios_rd32(bios, init->offset + 1);
1761        u32 value = nvbios_rd32(bios, init->offset + 5);
1762
1763        trace("STRAP_CONDITION\t(R[0x101000] & 0x%08x) == 0x%08x\n", mask, value);
1764        init->offset += 9;
1765
1766        if ((init_rd32(init, 0x101000) & mask) != value)
1767                init_exec_set(init, false);
1768}
1769
1770/**
1771 * INIT_TIME - opcode 0x74
1772 *
1773 */
1774static void
1775init_time(struct nvbios_init *init)
1776{
1777        struct nvkm_bios *bios = init->bios;
1778        u16 usec = nvbios_rd16(bios, init->offset + 1);
1779
1780        trace("TIME\t0x%04x\n", usec);
1781        init->offset += 3;
1782
1783        if (init_exec(init)) {
1784                if (usec < 1000)
1785                        udelay(usec);
1786                else
1787                        mdelay((usec + 900) / 1000);
1788        }
1789}
1790
1791/**
1792 * INIT_CONDITION - opcode 0x75
1793 *
1794 */
1795static void
1796init_condition(struct nvbios_init *init)
1797{
1798        struct nvkm_bios *bios = init->bios;
1799        u8 cond = nvbios_rd08(bios, init->offset + 1);
1800
1801        trace("CONDITION\t0x%02x\n", cond);
1802        init->offset += 2;
1803
1804        if (!init_condition_met(init, cond))
1805                init_exec_set(init, false);
1806}
1807
1808/**
1809 * INIT_IO_CONDITION - opcode 0x76
1810 *
1811 */
1812static void
1813init_io_condition(struct nvbios_init *init)
1814{
1815        struct nvkm_bios *bios = init->bios;
1816        u8 cond = nvbios_rd08(bios, init->offset + 1);
1817
1818        trace("IO_CONDITION\t0x%02x\n", cond);
1819        init->offset += 2;
1820
1821        if (!init_io_condition_met(init, cond))
1822                init_exec_set(init, false);
1823}
1824
1825/**
1826 * INIT_ZM_REG16 - opcode 0x77
1827 *
1828 */
1829static void
1830init_zm_reg16(struct nvbios_init *init)
1831{
1832        struct nvkm_bios *bios = init->bios;
1833        u32 addr = nvbios_rd32(bios, init->offset + 1);
1834        u16 data = nvbios_rd16(bios, init->offset + 5);
1835
1836        trace("ZM_REG\tR[0x%06x] = 0x%04x\n", addr, data);
1837        init->offset += 7;
1838
1839        init_wr32(init, addr, data);
1840}
1841
1842/**
1843 * INIT_INDEX_IO - opcode 0x78
1844 *
1845 */
1846static void
1847init_index_io(struct nvbios_init *init)
1848{
1849        struct nvkm_bios *bios = init->bios;
1850        u16 port = nvbios_rd16(bios, init->offset + 1);
1851        u8 index = nvbios_rd16(bios, init->offset + 3);
1852        u8  mask = nvbios_rd08(bios, init->offset + 4);
1853        u8  data = nvbios_rd08(bios, init->offset + 5);
1854        u8 value;
1855
1856        trace("INDEX_IO\tI[0x%04x][0x%02x] &= 0x%02x |= 0x%02x\n",
1857              port, index, mask, data);
1858        init->offset += 6;
1859
1860        value = init_rdvgai(init, port, index) & mask;
1861        init_wrvgai(init, port, index, data | value);
1862}
1863
1864/**
1865 * INIT_PLL - opcode 0x79
1866 *
1867 */
1868static void
1869init_pll(struct nvbios_init *init)
1870{
1871        struct nvkm_bios *bios = init->bios;
1872        u32  reg = nvbios_rd32(bios, init->offset + 1);
1873        u32 freq = nvbios_rd16(bios, init->offset + 5) * 10;
1874
1875        trace("PLL\tR[0x%06x] =PLL= %dkHz\n", reg, freq);
1876        init->offset += 7;
1877
1878        init_prog_pll(init, reg, freq);
1879}
1880
1881/**
1882 * INIT_ZM_REG - opcode 0x7a
1883 *
1884 */
1885static void
1886init_zm_reg(struct nvbios_init *init)
1887{
1888        struct nvkm_bios *bios = init->bios;
1889        u32 addr = nvbios_rd32(bios, init->offset + 1);
1890        u32 data = nvbios_rd32(bios, init->offset + 5);
1891
1892        trace("ZM_REG\tR[0x%06x] = 0x%08x\n", addr, data);
1893        init->offset += 9;
1894
1895        if (addr == 0x000200)
1896                data |= 0x00000001;
1897
1898        init_wr32(init, addr, data);
1899}
1900
1901/**
1902 * INIT_RAM_RESTRICT_PLL - opcde 0x87
1903 *
1904 */
1905static void
1906init_ram_restrict_pll(struct nvbios_init *init)
1907{
1908        struct nvkm_bios *bios = init->bios;
1909        u8  type = nvbios_rd08(bios, init->offset + 1);
1910        u8 count = init_ram_restrict_group_count(init);
1911        u8 strap = init_ram_restrict(init);
1912        u8 cconf;
1913
1914        trace("RAM_RESTRICT_PLL\t0x%02x\n", type);
1915        init->offset += 2;
1916
1917        for (cconf = 0; cconf < count; cconf++) {
1918                u32 freq = nvbios_rd32(bios, init->offset);
1919
1920                if (cconf == strap) {
1921                        trace("%dkHz *\n", freq);
1922                        init_prog_pll(init, type, freq);
1923                } else {
1924                        trace("%dkHz\n", freq);
1925                }
1926
1927                init->offset += 4;
1928        }
1929}
1930
1931/**
1932 * INIT_GPIO - opcode 0x8e
1933 *
1934 */
1935static void
1936init_gpio(struct nvbios_init *init)
1937{
1938        struct nvkm_gpio *gpio = init->bios->subdev.device->gpio;
1939
1940        trace("GPIO\n");
1941        init->offset += 1;
1942
1943        if (init_exec(init))
1944                nvkm_gpio_reset(gpio, DCB_GPIO_UNUSED);
1945}
1946
1947/**
1948 * INIT_RAM_RESTRICT_ZM_GROUP - opcode 0x8f
1949 *
1950 */
1951static void
1952init_ram_restrict_zm_reg_group(struct nvbios_init *init)
1953{
1954        struct nvkm_bios *bios = init->bios;
1955        u32 addr = nvbios_rd32(bios, init->offset + 1);
1956        u8  incr = nvbios_rd08(bios, init->offset + 5);
1957        u8   num = nvbios_rd08(bios, init->offset + 6);
1958        u8 count = init_ram_restrict_group_count(init);
1959        u8 index = init_ram_restrict(init);
1960        u8 i, j;
1961
1962        trace("RAM_RESTRICT_ZM_REG_GROUP\t"
1963              "R[0x%08x] 0x%02x 0x%02x\n", addr, incr, num);
1964        init->offset += 7;
1965
1966        for (i = 0; i < num; i++) {
1967                trace("\tR[0x%06x] = {\n", addr);
1968                for (j = 0; j < count; j++) {
1969                        u32 data = nvbios_rd32(bios, init->offset);
1970
1971                        if (j == index) {
1972                                trace("\t\t0x%08x *\n", data);
1973                                init_wr32(init, addr, data);
1974                        } else {
1975                                trace("\t\t0x%08x\n", data);
1976                        }
1977
1978                        init->offset += 4;
1979                }
1980                trace("\t}\n");
1981                addr += incr;
1982        }
1983}
1984
1985/**
1986 * INIT_COPY_ZM_REG - opcode 0x90
1987 *
1988 */
1989static void
1990init_copy_zm_reg(struct nvbios_init *init)
1991{
1992        struct nvkm_bios *bios = init->bios;
1993        u32 sreg = nvbios_rd32(bios, init->offset + 1);
1994        u32 dreg = nvbios_rd32(bios, init->offset + 5);
1995
1996        trace("COPY_ZM_REG\tR[0x%06x] = R[0x%06x]\n", dreg, sreg);
1997        init->offset += 9;
1998
1999        init_wr32(init, dreg, init_rd32(init, sreg));
2000}
2001
2002/**
2003 * INIT_ZM_REG_GROUP - opcode 0x91
2004 *
2005 */
2006static void
2007init_zm_reg_group(struct nvbios_init *init)
2008{
2009        struct nvkm_bios *bios = init->bios;
2010        u32 addr = nvbios_rd32(bios, init->offset + 1);
2011        u8 count = nvbios_rd08(bios, init->offset + 5);
2012
2013        trace("ZM_REG_GROUP\tR[0x%06x] =\n", addr);
2014        init->offset += 6;
2015
2016        while (count--) {
2017                u32 data = nvbios_rd32(bios, init->offset);
2018                trace("\t0x%08x\n", data);
2019                init_wr32(init, addr, data);
2020                init->offset += 4;
2021        }
2022}
2023
2024/**
2025 * INIT_XLAT - opcode 0x96
2026 *
2027 */
2028static void
2029init_xlat(struct nvbios_init *init)
2030{
2031        struct nvkm_bios *bios = init->bios;
2032        u32 saddr = nvbios_rd32(bios, init->offset + 1);
2033        u8 sshift = nvbios_rd08(bios, init->offset + 5);
2034        u8  smask = nvbios_rd08(bios, init->offset + 6);
2035        u8  index = nvbios_rd08(bios, init->offset + 7);
2036        u32 daddr = nvbios_rd32(bios, init->offset + 8);
2037        u32 dmask = nvbios_rd32(bios, init->offset + 12);
2038        u8  shift = nvbios_rd08(bios, init->offset + 16);
2039        u32 data;
2040
2041        trace("INIT_XLAT\tR[0x%06x] &= 0x%08x |= "
2042              "(X%02x((R[0x%06x] %s 0x%02x) & 0x%02x) << 0x%02x)\n",
2043              daddr, dmask, index, saddr, (sshift & 0x80) ? "<<" : ">>",
2044              (sshift & 0x80) ? (0x100 - sshift) : sshift, smask, shift);
2045        init->offset += 17;
2046
2047        data = init_shift(init_rd32(init, saddr), sshift) & smask;
2048        data = init_xlat_(init, index, data) << shift;
2049        init_mask(init, daddr, ~dmask, data);
2050}
2051
2052/**
2053 * INIT_ZM_MASK_ADD - opcode 0x97
2054 *
2055 */
2056static void
2057init_zm_mask_add(struct nvbios_init *init)
2058{
2059        struct nvkm_bios *bios = init->bios;
2060        u32 addr = nvbios_rd32(bios, init->offset + 1);
2061        u32 mask = nvbios_rd32(bios, init->offset + 5);
2062        u32  add = nvbios_rd32(bios, init->offset + 9);
2063        u32 data;
2064
2065        trace("ZM_MASK_ADD\tR[0x%06x] &= 0x%08x += 0x%08x\n", addr, mask, add);
2066        init->offset += 13;
2067
2068        data =  init_rd32(init, addr);
2069        data = (data & mask) | ((data + add) & ~mask);
2070        init_wr32(init, addr, data);
2071}
2072
2073/**
2074 * INIT_AUXCH - opcode 0x98
2075 *
2076 */
2077static void
2078init_auxch(struct nvbios_init *init)
2079{
2080        struct nvkm_bios *bios = init->bios;
2081        u32 addr = nvbios_rd32(bios, init->offset + 1);
2082        u8 count = nvbios_rd08(bios, init->offset + 5);
2083
2084        trace("AUXCH\tAUX[0x%08x] 0x%02x\n", addr, count);
2085        init->offset += 6;
2086
2087        while (count--) {
2088                u8 mask = nvbios_rd08(bios, init->offset + 0);
2089                u8 data = nvbios_rd08(bios, init->offset + 1);
2090                trace("\tAUX[0x%08x] &= 0x%02x |= 0x%02x\n", addr, mask, data);
2091                mask = init_rdauxr(init, addr) & mask;
2092                init_wrauxr(init, addr, mask | data);
2093                init->offset += 2;
2094        }
2095}
2096
2097/**
2098 * INIT_AUXCH - opcode 0x99
2099 *
2100 */
2101static void
2102init_zm_auxch(struct nvbios_init *init)
2103{
2104        struct nvkm_bios *bios = init->bios;
2105        u32 addr = nvbios_rd32(bios, init->offset + 1);
2106        u8 count = nvbios_rd08(bios, init->offset + 5);
2107
2108        trace("ZM_AUXCH\tAUX[0x%08x] 0x%02x\n", addr, count);
2109        init->offset += 6;
2110
2111        while (count--) {
2112                u8 data = nvbios_rd08(bios, init->offset + 0);
2113                trace("\tAUX[0x%08x] = 0x%02x\n", addr, data);
2114                init_wrauxr(init, addr, data);
2115                init->offset += 1;
2116        }
2117}
2118
2119/**
2120 * INIT_I2C_LONG_IF - opcode 0x9a
2121 *
2122 */
2123static void
2124init_i2c_long_if(struct nvbios_init *init)
2125{
2126        struct nvkm_bios *bios = init->bios;
2127        u8 index = nvbios_rd08(bios, init->offset + 1);
2128        u8  addr = nvbios_rd08(bios, init->offset + 2) >> 1;
2129        u8 reglo = nvbios_rd08(bios, init->offset + 3);
2130        u8 reghi = nvbios_rd08(bios, init->offset + 4);
2131        u8  mask = nvbios_rd08(bios, init->offset + 5);
2132        u8  data = nvbios_rd08(bios, init->offset + 6);
2133        struct i2c_adapter *adap;
2134
2135        trace("I2C_LONG_IF\t"
2136              "I2C[0x%02x][0x%02x][0x%02x%02x] & 0x%02x == 0x%02x\n",
2137              index, addr, reglo, reghi, mask, data);
2138        init->offset += 7;
2139
2140        adap = init_i2c(init, index);
2141        if (adap) {
2142                u8 i[2] = { reghi, reglo };
2143                u8 o[1] = {};
2144                struct i2c_msg msg[] = {
2145                        { .addr = addr, .flags = 0, .len = 2, .buf = i },
2146                        { .addr = addr, .flags = I2C_M_RD, .len = 1, .buf = o }
2147                };
2148                int ret;
2149
2150                ret = i2c_transfer(adap, msg, 2);
2151                if (ret == 2 && ((o[0] & mask) == data))
2152                        return;
2153        }
2154
2155        init_exec_set(init, false);
2156}
2157
2158/**
2159 * INIT_GPIO_NE - opcode 0xa9
2160 *
2161 */
2162static void
2163init_gpio_ne(struct nvbios_init *init)
2164{
2165        struct nvkm_bios *bios = init->bios;
2166        struct nvkm_gpio *gpio = bios->subdev.device->gpio;
2167        struct dcb_gpio_func func;
2168        u8 count = nvbios_rd08(bios, init->offset + 1);
2169        u8 idx = 0, ver, len;
2170        u16 data, i;
2171
2172        trace("GPIO_NE\t");
2173        init->offset += 2;
2174
2175        for (i = init->offset; i < init->offset + count; i++)
2176                cont("0x%02x ", nvbios_rd08(bios, i));
2177        cont("\n");
2178
2179        while ((data = dcb_gpio_parse(bios, 0, idx++, &ver, &len, &func))) {
2180                if (func.func != DCB_GPIO_UNUSED) {
2181                        for (i = init->offset; i < init->offset + count; i++) {
2182                                if (func.func == nvbios_rd08(bios, i))
2183                                        break;
2184                        }
2185
2186                        trace("\tFUNC[0x%02x]", func.func);
2187                        if (i == (init->offset + count)) {
2188                                cont(" *");
2189                                if (init_exec(init))
2190                                        nvkm_gpio_reset(gpio, func.func);
2191                        }
2192                        cont("\n");
2193                }
2194        }
2195
2196        init->offset += count;
2197}
2198
2199static struct nvbios_init_opcode {
2200        void (*exec)(struct nvbios_init *);
2201} init_opcode[] = {
2202        [0x32] = { init_io_restrict_prog },
2203        [0x33] = { init_repeat },
2204        [0x34] = { init_io_restrict_pll },
2205        [0x36] = { init_end_repeat },
2206        [0x37] = { init_copy },
2207        [0x38] = { init_not },
2208        [0x39] = { init_io_flag_condition },
2209        [0x3a] = { init_generic_condition },
2210        [0x3b] = { init_io_mask_or },
2211        [0x3c] = { init_io_or },
2212        [0x47] = { init_andn_reg },
2213        [0x48] = { init_or_reg },
2214        [0x49] = { init_idx_addr_latched },
2215        [0x4a] = { init_io_restrict_pll2 },
2216        [0x4b] = { init_pll2 },
2217        [0x4c] = { init_i2c_byte },
2218        [0x4d] = { init_zm_i2c_byte },
2219        [0x4e] = { init_zm_i2c },
2220        [0x4f] = { init_tmds },
2221        [0x50] = { init_zm_tmds_group },
2222        [0x51] = { init_cr_idx_adr_latch },
2223        [0x52] = { init_cr },
2224        [0x53] = { init_zm_cr },
2225        [0x54] = { init_zm_cr_group },
2226        [0x56] = { init_condition_time },
2227        [0x57] = { init_ltime },
2228        [0x58] = { init_zm_reg_sequence },
2229        [0x59] = { init_pll_indirect },
2230        [0x5a] = { init_zm_reg_indirect },
2231        [0x5b] = { init_sub_direct },
2232        [0x5c] = { init_jump },
2233        [0x5e] = { init_i2c_if },
2234        [0x5f] = { init_copy_nv_reg },
2235        [0x62] = { init_zm_index_io },
2236        [0x63] = { init_compute_mem },
2237        [0x65] = { init_reset },
2238        [0x66] = { init_configure_mem },
2239        [0x67] = { init_configure_clk },
2240        [0x68] = { init_configure_preinit },
2241        [0x69] = { init_io },
2242        [0x6b] = { init_sub },
2243        [0x6d] = { init_ram_condition },
2244        [0x6e] = { init_nv_reg },
2245        [0x6f] = { init_macro },
2246        [0x71] = { init_done },
2247        [0x72] = { init_resume },
2248        [0x73] = { init_strap_condition },
2249        [0x74] = { init_time },
2250        [0x75] = { init_condition },
2251        [0x76] = { init_io_condition },
2252        [0x77] = { init_zm_reg16 },
2253        [0x78] = { init_index_io },
2254        [0x79] = { init_pll },
2255        [0x7a] = { init_zm_reg },
2256        [0x87] = { init_ram_restrict_pll },
2257        [0x8c] = { init_reserved },
2258        [0x8d] = { init_reserved },
2259        [0x8e] = { init_gpio },
2260        [0x8f] = { init_ram_restrict_zm_reg_group },
2261        [0x90] = { init_copy_zm_reg },
2262        [0x91] = { init_zm_reg_group },
2263        [0x92] = { init_reserved },
2264        [0x96] = { init_xlat },
2265        [0x97] = { init_zm_mask_add },
2266        [0x98] = { init_auxch },
2267        [0x99] = { init_zm_auxch },
2268        [0x9a] = { init_i2c_long_if },
2269        [0xa9] = { init_gpio_ne },
2270        [0xaa] = { init_reserved },
2271};
2272
2273#define init_opcode_nr (sizeof(init_opcode) / sizeof(init_opcode[0]))
2274
2275int
2276nvbios_exec(struct nvbios_init *init)
2277{
2278        init->nested++;
2279        while (init->offset) {
2280                u8 opcode = nvbios_rd08(init->bios, init->offset);
2281                if (opcode >= init_opcode_nr || !init_opcode[opcode].exec) {
2282                        error("unknown opcode 0x%02x\n", opcode);
2283                        return -EINVAL;
2284                }
2285
2286                init_opcode[opcode].exec(init);
2287        }
2288        init->nested--;
2289        return 0;
2290}
2291
2292int
2293nvbios_init(struct nvkm_subdev *subdev, bool execute)
2294{
2295        struct nvkm_bios *bios = subdev->device->bios;
2296        int ret = 0;
2297        int i = -1;
2298        u16 data;
2299
2300        if (execute)
2301                nvkm_debug(subdev, "running init tables\n");
2302        while (!ret && (data = (init_script(bios, ++i)))) {
2303                struct nvbios_init init = {
2304                        .subdev = subdev,
2305                        .bios = bios,
2306                        .offset = data,
2307                        .outp = NULL,
2308                        .crtc = -1,
2309                        .execute = execute ? 1 : 0,
2310                };
2311
2312                ret = nvbios_exec(&init);
2313        }
2314
2315        /* the vbios parser will run this right after the normal init
2316         * tables, whereas the binary driver appears to run it later.
2317         */
2318        if (!ret && (data = init_unknown_script(bios))) {
2319                struct nvbios_init init = {
2320                        .subdev = subdev,
2321                        .bios = bios,
2322                        .offset = data,
2323                        .outp = NULL,
2324                        .crtc = -1,
2325                        .execute = execute ? 1 : 0,
2326                };
2327
2328                ret = nvbios_exec(&init);
2329        }
2330
2331        return ret;
2332}
2333