linux/drivers/gpu/drm/nouveau/nvkm/engine/disp/nv50.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 "nv50.h"
  25#include "rootnv50.h"
  26
  27#include <core/client.h>
  28#include <core/enum.h>
  29#include <core/gpuobj.h>
  30#include <subdev/bios.h>
  31#include <subdev/bios/disp.h>
  32#include <subdev/bios/init.h>
  33#include <subdev/bios/pll.h>
  34#include <subdev/devinit.h>
  35
  36static const struct nvkm_disp_oclass *
  37nv50_disp_root_(struct nvkm_disp *base)
  38{
  39        return nv50_disp(base)->func->root;
  40}
  41
  42static int
  43nv50_disp_outp_internal_crt_(struct nvkm_disp *base, int index,
  44                             struct dcb_output *dcb, struct nvkm_output **poutp)
  45{
  46        struct nv50_disp *disp = nv50_disp(base);
  47        return disp->func->outp.internal.crt(base, index, dcb, poutp);
  48}
  49
  50static int
  51nv50_disp_outp_internal_tmds_(struct nvkm_disp *base, int index,
  52                              struct dcb_output *dcb,
  53                              struct nvkm_output **poutp)
  54{
  55        struct nv50_disp *disp = nv50_disp(base);
  56        return disp->func->outp.internal.tmds(base, index, dcb, poutp);
  57}
  58
  59static int
  60nv50_disp_outp_internal_lvds_(struct nvkm_disp *base, int index,
  61                              struct dcb_output *dcb,
  62                              struct nvkm_output **poutp)
  63{
  64        struct nv50_disp *disp = nv50_disp(base);
  65        return disp->func->outp.internal.lvds(base, index, dcb, poutp);
  66}
  67
  68static int
  69nv50_disp_outp_internal_dp_(struct nvkm_disp *base, int index,
  70                            struct dcb_output *dcb, struct nvkm_output **poutp)
  71{
  72        struct nv50_disp *disp = nv50_disp(base);
  73        if (disp->func->outp.internal.dp)
  74                return disp->func->outp.internal.dp(base, index, dcb, poutp);
  75        return -ENODEV;
  76}
  77
  78static int
  79nv50_disp_outp_external_tmds_(struct nvkm_disp *base, int index,
  80                              struct dcb_output *dcb,
  81                              struct nvkm_output **poutp)
  82{
  83        struct nv50_disp *disp = nv50_disp(base);
  84        if (disp->func->outp.external.tmds)
  85                return disp->func->outp.external.tmds(base, index, dcb, poutp);
  86        return -ENODEV;
  87}
  88
  89static int
  90nv50_disp_outp_external_dp_(struct nvkm_disp *base, int index,
  91                            struct dcb_output *dcb, struct nvkm_output **poutp)
  92{
  93        struct nv50_disp *disp = nv50_disp(base);
  94        if (disp->func->outp.external.dp)
  95                return disp->func->outp.external.dp(base, index, dcb, poutp);
  96        return -ENODEV;
  97}
  98
  99static void
 100nv50_disp_vblank_fini_(struct nvkm_disp *base, int head)
 101{
 102        struct nv50_disp *disp = nv50_disp(base);
 103        disp->func->head.vblank_fini(disp, head);
 104}
 105
 106static void
 107nv50_disp_vblank_init_(struct nvkm_disp *base, int head)
 108{
 109        struct nv50_disp *disp = nv50_disp(base);
 110        disp->func->head.vblank_init(disp, head);
 111}
 112
 113static void
 114nv50_disp_intr_(struct nvkm_disp *base)
 115{
 116        struct nv50_disp *disp = nv50_disp(base);
 117        disp->func->intr(disp);
 118}
 119
 120static void *
 121nv50_disp_dtor_(struct nvkm_disp *base)
 122{
 123        struct nv50_disp *disp = nv50_disp(base);
 124        nvkm_event_fini(&disp->uevent);
 125        return disp;
 126}
 127
 128static const struct nvkm_disp_func
 129nv50_disp_ = {
 130        .dtor = nv50_disp_dtor_,
 131        .intr = nv50_disp_intr_,
 132        .root = nv50_disp_root_,
 133        .outp.internal.crt = nv50_disp_outp_internal_crt_,
 134        .outp.internal.tmds = nv50_disp_outp_internal_tmds_,
 135        .outp.internal.lvds = nv50_disp_outp_internal_lvds_,
 136        .outp.internal.dp = nv50_disp_outp_internal_dp_,
 137        .outp.external.tmds = nv50_disp_outp_external_tmds_,
 138        .outp.external.dp = nv50_disp_outp_external_dp_,
 139        .head.vblank_init = nv50_disp_vblank_init_,
 140        .head.vblank_fini = nv50_disp_vblank_fini_,
 141};
 142
 143int
 144nv50_disp_new_(const struct nv50_disp_func *func, struct nvkm_device *device,
 145               int index, int heads, struct nvkm_disp **pdisp)
 146{
 147        struct nv50_disp *disp;
 148        int ret;
 149
 150        if (!(disp = kzalloc(sizeof(*disp), GFP_KERNEL)))
 151                return -ENOMEM;
 152        INIT_WORK(&disp->supervisor, func->super);
 153        disp->func = func;
 154        *pdisp = &disp->base;
 155
 156        ret = nvkm_disp_ctor(&nv50_disp_, device, index, heads, &disp->base);
 157        if (ret)
 158                return ret;
 159
 160        return nvkm_event_init(func->uevent, 1, 1 + (heads * 4), &disp->uevent);
 161}
 162
 163void
 164nv50_disp_vblank_fini(struct nv50_disp *disp, int head)
 165{
 166        struct nvkm_device *device = disp->base.engine.subdev.device;
 167        nvkm_mask(device, 0x61002c, (4 << head), 0);
 168}
 169
 170void
 171nv50_disp_vblank_init(struct nv50_disp *disp, int head)
 172{
 173        struct nvkm_device *device = disp->base.engine.subdev.device;
 174        nvkm_mask(device, 0x61002c, (4 << head), (4 << head));
 175}
 176
 177static const struct nvkm_enum
 178nv50_disp_intr_error_type[] = {
 179        { 3, "ILLEGAL_MTHD" },
 180        { 4, "INVALID_VALUE" },
 181        { 5, "INVALID_STATE" },
 182        { 7, "INVALID_HANDLE" },
 183        {}
 184};
 185
 186static const struct nvkm_enum
 187nv50_disp_intr_error_code[] = {
 188        { 0x00, "" },
 189        {}
 190};
 191
 192static void
 193nv50_disp_intr_error(struct nv50_disp *disp, int chid)
 194{
 195        struct nvkm_subdev *subdev = &disp->base.engine.subdev;
 196        struct nvkm_device *device = subdev->device;
 197        u32 data = nvkm_rd32(device, 0x610084 + (chid * 0x08));
 198        u32 addr = nvkm_rd32(device, 0x610080 + (chid * 0x08));
 199        u32 code = (addr & 0x00ff0000) >> 16;
 200        u32 type = (addr & 0x00007000) >> 12;
 201        u32 mthd = (addr & 0x00000ffc);
 202        const struct nvkm_enum *ec, *et;
 203
 204        et = nvkm_enum_find(nv50_disp_intr_error_type, type);
 205        ec = nvkm_enum_find(nv50_disp_intr_error_code, code);
 206
 207        nvkm_error(subdev,
 208                   "ERROR %d [%s] %02x [%s] chid %d mthd %04x data %08x\n",
 209                   type, et ? et->name : "", code, ec ? ec->name : "",
 210                   chid, mthd, data);
 211
 212        if (chid < ARRAY_SIZE(disp->chan)) {
 213                switch (mthd) {
 214                case 0x0080:
 215                        nv50_disp_chan_mthd(disp->chan[chid], NV_DBG_ERROR);
 216                        break;
 217                default:
 218                        break;
 219                }
 220        }
 221
 222        nvkm_wr32(device, 0x610020, 0x00010000 << chid);
 223        nvkm_wr32(device, 0x610080 + (chid * 0x08), 0x90000000);
 224}
 225
 226static struct nvkm_output *
 227exec_lookup(struct nv50_disp *disp, int head, int or, u32 ctrl,
 228            u32 *data, u8 *ver, u8 *hdr, u8 *cnt, u8 *len,
 229            struct nvbios_outp *info)
 230{
 231        struct nvkm_subdev *subdev = &disp->base.engine.subdev;
 232        struct nvkm_bios *bios = subdev->device->bios;
 233        struct nvkm_output *outp;
 234        u16 mask, type;
 235
 236        if (or < 4) {
 237                type = DCB_OUTPUT_ANALOG;
 238                mask = 0;
 239        } else
 240        if (or < 8) {
 241                switch (ctrl & 0x00000f00) {
 242                case 0x00000000: type = DCB_OUTPUT_LVDS; mask = 1; break;
 243                case 0x00000100: type = DCB_OUTPUT_TMDS; mask = 1; break;
 244                case 0x00000200: type = DCB_OUTPUT_TMDS; mask = 2; break;
 245                case 0x00000500: type = DCB_OUTPUT_TMDS; mask = 3; break;
 246                case 0x00000800: type = DCB_OUTPUT_DP; mask = 1; break;
 247                case 0x00000900: type = DCB_OUTPUT_DP; mask = 2; break;
 248                default:
 249                        nvkm_error(subdev, "unknown SOR mc %08x\n", ctrl);
 250                        return NULL;
 251                }
 252                or  -= 4;
 253        } else {
 254                or   = or - 8;
 255                type = 0x0010;
 256                mask = 0;
 257                switch (ctrl & 0x00000f00) {
 258                case 0x00000000: type |= disp->pior.type[or]; break;
 259                default:
 260                        nvkm_error(subdev, "unknown PIOR mc %08x\n", ctrl);
 261                        return NULL;
 262                }
 263        }
 264
 265        mask  = 0x00c0 & (mask << 6);
 266        mask |= 0x0001 << or;
 267        mask |= 0x0100 << head;
 268
 269        list_for_each_entry(outp, &disp->base.outp, head) {
 270                if ((outp->info.hasht & 0xff) == type &&
 271                    (outp->info.hashm & mask) == mask) {
 272                        *data = nvbios_outp_match(bios, outp->info.hasht,
 273                                                        outp->info.hashm,
 274                                                  ver, hdr, cnt, len, info);
 275                        if (!*data)
 276                                return NULL;
 277                        return outp;
 278                }
 279        }
 280
 281        return NULL;
 282}
 283
 284static struct nvkm_output *
 285exec_script(struct nv50_disp *disp, int head, int id)
 286{
 287        struct nvkm_subdev *subdev = &disp->base.engine.subdev;
 288        struct nvkm_device *device = subdev->device;
 289        struct nvkm_bios *bios = device->bios;
 290        struct nvkm_output *outp;
 291        struct nvbios_outp info;
 292        u8  ver, hdr, cnt, len;
 293        u32 data, ctrl = 0;
 294        u32 reg;
 295        int i;
 296
 297        /* DAC */
 298        for (i = 0; !(ctrl & (1 << head)) && i < disp->func->dac.nr; i++)
 299                ctrl = nvkm_rd32(device, 0x610b5c + (i * 8));
 300
 301        /* SOR */
 302        if (!(ctrl & (1 << head))) {
 303                if (device->chipset  < 0x90 ||
 304                    device->chipset == 0x92 ||
 305                    device->chipset == 0xa0) {
 306                        reg = 0x610b74;
 307                } else {
 308                        reg = 0x610798;
 309                }
 310                for (i = 0; !(ctrl & (1 << head)) && i < disp->func->sor.nr; i++)
 311                        ctrl = nvkm_rd32(device, reg + (i * 8));
 312                i += 4;
 313        }
 314
 315        /* PIOR */
 316        if (!(ctrl & (1 << head))) {
 317                for (i = 0; !(ctrl & (1 << head)) && i < disp->func->pior.nr; i++)
 318                        ctrl = nvkm_rd32(device, 0x610b84 + (i * 8));
 319                i += 8;
 320        }
 321
 322        if (!(ctrl & (1 << head)))
 323                return NULL;
 324        i--;
 325
 326        outp = exec_lookup(disp, head, i, ctrl, &data, &ver, &hdr, &cnt, &len, &info);
 327        if (outp) {
 328                struct nvbios_init init = {
 329                        .subdev = subdev,
 330                        .bios = bios,
 331                        .offset = info.script[id],
 332                        .outp = &outp->info,
 333                        .crtc = head,
 334                        .execute = 1,
 335                };
 336
 337                nvbios_exec(&init);
 338        }
 339
 340        return outp;
 341}
 342
 343static struct nvkm_output *
 344exec_clkcmp(struct nv50_disp *disp, int head, int id, u32 pclk, u32 *conf)
 345{
 346        struct nvkm_subdev *subdev = &disp->base.engine.subdev;
 347        struct nvkm_device *device = subdev->device;
 348        struct nvkm_bios *bios = device->bios;
 349        struct nvkm_output *outp;
 350        struct nvbios_outp info1;
 351        struct nvbios_ocfg info2;
 352        u8  ver, hdr, cnt, len;
 353        u32 data, ctrl = 0;
 354        u32 reg;
 355        int i;
 356
 357        /* DAC */
 358        for (i = 0; !(ctrl & (1 << head)) && i < disp->func->dac.nr; i++)
 359                ctrl = nvkm_rd32(device, 0x610b58 + (i * 8));
 360
 361        /* SOR */
 362        if (!(ctrl & (1 << head))) {
 363                if (device->chipset  < 0x90 ||
 364                    device->chipset == 0x92 ||
 365                    device->chipset == 0xa0) {
 366                        reg = 0x610b70;
 367                } else {
 368                        reg = 0x610794;
 369                }
 370                for (i = 0; !(ctrl & (1 << head)) && i < disp->func->sor.nr; i++)
 371                        ctrl = nvkm_rd32(device, reg + (i * 8));
 372                i += 4;
 373        }
 374
 375        /* PIOR */
 376        if (!(ctrl & (1 << head))) {
 377                for (i = 0; !(ctrl & (1 << head)) && i < disp->func->pior.nr; i++)
 378                        ctrl = nvkm_rd32(device, 0x610b80 + (i * 8));
 379                i += 8;
 380        }
 381
 382        if (!(ctrl & (1 << head)))
 383                return NULL;
 384        i--;
 385
 386        outp = exec_lookup(disp, head, i, ctrl, &data, &ver, &hdr, &cnt, &len, &info1);
 387        if (!outp)
 388                return NULL;
 389
 390        if (outp->info.location == 0) {
 391                switch (outp->info.type) {
 392                case DCB_OUTPUT_TMDS:
 393                        *conf = (ctrl & 0x00000f00) >> 8;
 394                        if (*conf == 5)
 395                                *conf |= 0x0100;
 396                        break;
 397                case DCB_OUTPUT_LVDS:
 398                        *conf = disp->sor.lvdsconf;
 399                        break;
 400                case DCB_OUTPUT_DP:
 401                        *conf = (ctrl & 0x00000f00) >> 8;
 402                        break;
 403                case DCB_OUTPUT_ANALOG:
 404                default:
 405                        *conf = 0x00ff;
 406                        break;
 407                }
 408        } else {
 409                *conf = (ctrl & 0x00000f00) >> 8;
 410                pclk = pclk / 2;
 411        }
 412
 413        data = nvbios_ocfg_match(bios, data, *conf, &ver, &hdr, &cnt, &len, &info2);
 414        if (data && id < 0xff) {
 415                data = nvbios_oclk_match(bios, info2.clkcmp[id], pclk);
 416                if (data) {
 417                        struct nvbios_init init = {
 418                                .subdev = subdev,
 419                                .bios = bios,
 420                                .offset = data,
 421                                .outp = &outp->info,
 422                                .crtc = head,
 423                                .execute = 1,
 424                        };
 425
 426                        nvbios_exec(&init);
 427                }
 428        }
 429
 430        return outp;
 431}
 432
 433static void
 434nv50_disp_intr_unk10_0(struct nv50_disp *disp, int head)
 435{
 436        exec_script(disp, head, 1);
 437}
 438
 439static void
 440nv50_disp_intr_unk20_0(struct nv50_disp *disp, int head)
 441{
 442        struct nvkm_subdev *subdev = &disp->base.engine.subdev;
 443        struct nvkm_output *outp = exec_script(disp, head, 2);
 444
 445        /* the binary driver does this outside of the supervisor handling
 446         * (after the third supervisor from a detach).  we (currently?)
 447         * allow both detach/attach to happen in the same set of
 448         * supervisor interrupts, so it would make sense to execute this
 449         * (full power down?) script after all the detach phases of the
 450         * supervisor handling.  like with training if needed from the
 451         * second supervisor, nvidia doesn't do this, so who knows if it's
 452         * entirely safe, but it does appear to work..
 453         *
 454         * without this script being run, on some configurations i've
 455         * seen, switching from DP to TMDS on a DP connector may result
 456         * in a blank screen (SOR_PWR off/on can restore it)
 457         */
 458        if (outp && outp->info.type == DCB_OUTPUT_DP) {
 459                struct nvkm_output_dp *outpdp = nvkm_output_dp(outp);
 460                struct nvbios_init init = {
 461                        .subdev = subdev,
 462                        .bios = subdev->device->bios,
 463                        .outp = &outp->info,
 464                        .crtc = head,
 465                        .offset = outpdp->info.script[4],
 466                        .execute = 1,
 467                };
 468
 469                nvbios_exec(&init);
 470                atomic_set(&outpdp->lt.done, 0);
 471        }
 472}
 473
 474static void
 475nv50_disp_intr_unk20_1(struct nv50_disp *disp, int head)
 476{
 477        struct nvkm_device *device = disp->base.engine.subdev.device;
 478        struct nvkm_devinit *devinit = device->devinit;
 479        u32 pclk = nvkm_rd32(device, 0x610ad0 + (head * 0x540)) & 0x3fffff;
 480        if (pclk)
 481                nvkm_devinit_pll_set(devinit, PLL_VPLL0 + head, pclk);
 482}
 483
 484static void
 485nv50_disp_intr_unk20_2_dp(struct nv50_disp *disp, int head,
 486                          struct dcb_output *outp, u32 pclk)
 487{
 488        struct nvkm_subdev *subdev = &disp->base.engine.subdev;
 489        struct nvkm_device *device = subdev->device;
 490        const int link = !(outp->sorconf.link & 1);
 491        const int   or = ffs(outp->or) - 1;
 492        const u32 soff = (  or * 0x800);
 493        const u32 loff = (link * 0x080) + soff;
 494        const u32 ctrl = nvkm_rd32(device, 0x610794 + (or * 8));
 495        const u32 symbol = 100000;
 496        const s32 vactive = nvkm_rd32(device, 0x610af8 + (head * 0x540)) & 0xffff;
 497        const s32 vblanke = nvkm_rd32(device, 0x610ae8 + (head * 0x540)) & 0xffff;
 498        const s32 vblanks = nvkm_rd32(device, 0x610af0 + (head * 0x540)) & 0xffff;
 499        u32 dpctrl = nvkm_rd32(device, 0x61c10c + loff);
 500        u32 clksor = nvkm_rd32(device, 0x614300 + soff);
 501        int bestTU = 0, bestVTUi = 0, bestVTUf = 0, bestVTUa = 0;
 502        int TU, VTUi, VTUf, VTUa;
 503        u64 link_data_rate, link_ratio, unk;
 504        u32 best_diff = 64 * symbol;
 505        u32 link_nr, link_bw, bits;
 506        u64 value;
 507
 508        link_bw = (clksor & 0x000c0000) ? 270000 : 162000;
 509        link_nr = hweight32(dpctrl & 0x000f0000);
 510
 511        /* symbols/hblank - algorithm taken from comments in tegra driver */
 512        value = vblanke + vactive - vblanks - 7;
 513        value = value * link_bw;
 514        do_div(value, pclk);
 515        value = value - (3 * !!(dpctrl & 0x00004000)) - (12 / link_nr);
 516        nvkm_mask(device, 0x61c1e8 + soff, 0x0000ffff, value);
 517
 518        /* symbols/vblank - algorithm taken from comments in tegra driver */
 519        value = vblanks - vblanke - 25;
 520        value = value * link_bw;
 521        do_div(value, pclk);
 522        value = value - ((36 / link_nr) + 3) - 1;
 523        nvkm_mask(device, 0x61c1ec + soff, 0x00ffffff, value);
 524
 525        /* watermark / activesym */
 526        if      ((ctrl & 0xf0000) == 0x60000) bits = 30;
 527        else if ((ctrl & 0xf0000) == 0x50000) bits = 24;
 528        else                                  bits = 18;
 529
 530        link_data_rate = (pclk * bits / 8) / link_nr;
 531
 532        /* calculate ratio of packed data rate to link symbol rate */
 533        link_ratio = link_data_rate * symbol;
 534        do_div(link_ratio, link_bw);
 535
 536        for (TU = 64; TU >= 32; TU--) {
 537                /* calculate average number of valid symbols in each TU */
 538                u32 tu_valid = link_ratio * TU;
 539                u32 calc, diff;
 540
 541                /* find a hw representation for the fraction.. */
 542                VTUi = tu_valid / symbol;
 543                calc = VTUi * symbol;
 544                diff = tu_valid - calc;
 545                if (diff) {
 546                        if (diff >= (symbol / 2)) {
 547                                VTUf = symbol / (symbol - diff);
 548                                if (symbol - (VTUf * diff))
 549                                        VTUf++;
 550
 551                                if (VTUf <= 15) {
 552                                        VTUa  = 1;
 553                                        calc += symbol - (symbol / VTUf);
 554                                } else {
 555                                        VTUa  = 0;
 556                                        VTUf  = 1;
 557                                        calc += symbol;
 558                                }
 559                        } else {
 560                                VTUa  = 0;
 561                                VTUf  = min((int)(symbol / diff), 15);
 562                                calc += symbol / VTUf;
 563                        }
 564
 565                        diff = calc - tu_valid;
 566                } else {
 567                        /* no remainder, but the hw doesn't like the fractional
 568                         * part to be zero.  decrement the integer part and
 569                         * have the fraction add a whole symbol back
 570                         */
 571                        VTUa = 0;
 572                        VTUf = 1;
 573                        VTUi--;
 574                }
 575
 576                if (diff < best_diff) {
 577                        best_diff = diff;
 578                        bestTU = TU;
 579                        bestVTUa = VTUa;
 580                        bestVTUf = VTUf;
 581                        bestVTUi = VTUi;
 582                        if (diff == 0)
 583                                break;
 584                }
 585        }
 586
 587        if (!bestTU) {
 588                nvkm_error(subdev, "unable to find suitable dp config\n");
 589                return;
 590        }
 591
 592        /* XXX close to vbios numbers, but not right */
 593        unk  = (symbol - link_ratio) * bestTU;
 594        unk *= link_ratio;
 595        do_div(unk, symbol);
 596        do_div(unk, symbol);
 597        unk += 6;
 598
 599        nvkm_mask(device, 0x61c10c + loff, 0x000001fc, bestTU << 2);
 600        nvkm_mask(device, 0x61c128 + loff, 0x010f7f3f, bestVTUa << 24 |
 601                                                   bestVTUf << 16 |
 602                                                   bestVTUi << 8 | unk);
 603}
 604
 605static void
 606nv50_disp_intr_unk20_2(struct nv50_disp *disp, int head)
 607{
 608        struct nvkm_device *device = disp->base.engine.subdev.device;
 609        struct nvkm_output *outp;
 610        u32 pclk = nvkm_rd32(device, 0x610ad0 + (head * 0x540)) & 0x3fffff;
 611        u32 hval, hreg = 0x614200 + (head * 0x800);
 612        u32 oval, oreg;
 613        u32 mask, conf;
 614
 615        outp = exec_clkcmp(disp, head, 0xff, pclk, &conf);
 616        if (!outp)
 617                return;
 618
 619        /* we allow both encoder attach and detach operations to occur
 620         * within a single supervisor (ie. modeset) sequence.  the
 621         * encoder detach scripts quite often switch off power to the
 622         * lanes, which requires the link to be re-trained.
 623         *
 624         * this is not generally an issue as the sink "must" (heh)
 625         * signal an irq when it's lost sync so the driver can
 626         * re-train.
 627         *
 628         * however, on some boards, if one does not configure at least
 629         * the gpu side of the link *before* attaching, then various
 630         * things can go horribly wrong (PDISP disappearing from mmio,
 631         * third supervisor never happens, etc).
 632         *
 633         * the solution is simply to retrain here, if necessary.  last
 634         * i checked, the binary driver userspace does not appear to
 635         * trigger this situation (it forces an UPDATE between steps).
 636         */
 637        if (outp->info.type == DCB_OUTPUT_DP) {
 638                u32 soff = (ffs(outp->info.or) - 1) * 0x08;
 639                u32 ctrl, datarate;
 640
 641                if (outp->info.location == 0) {
 642                        ctrl = nvkm_rd32(device, 0x610794 + soff);
 643                        soff = 1;
 644                } else {
 645                        ctrl = nvkm_rd32(device, 0x610b80 + soff);
 646                        soff = 2;
 647                }
 648
 649                switch ((ctrl & 0x000f0000) >> 16) {
 650                case 6: datarate = pclk * 30; break;
 651                case 5: datarate = pclk * 24; break;
 652                case 2:
 653                default:
 654                        datarate = pclk * 18;
 655                        break;
 656                }
 657
 658                if (nvkm_output_dp_train(outp, datarate / soff, true))
 659                        OUTP_ERR(outp, "link not trained before attach");
 660        }
 661
 662        exec_clkcmp(disp, head, 0, pclk, &conf);
 663
 664        if (!outp->info.location && outp->info.type == DCB_OUTPUT_ANALOG) {
 665                oreg = 0x614280 + (ffs(outp->info.or) - 1) * 0x800;
 666                oval = 0x00000000;
 667                hval = 0x00000000;
 668                mask = 0xffffffff;
 669        } else
 670        if (!outp->info.location) {
 671                if (outp->info.type == DCB_OUTPUT_DP)
 672                        nv50_disp_intr_unk20_2_dp(disp, head, &outp->info, pclk);
 673                oreg = 0x614300 + (ffs(outp->info.or) - 1) * 0x800;
 674                oval = (conf & 0x0100) ? 0x00000101 : 0x00000000;
 675                hval = 0x00000000;
 676                mask = 0x00000707;
 677        } else {
 678                oreg = 0x614380 + (ffs(outp->info.or) - 1) * 0x800;
 679                oval = 0x00000001;
 680                hval = 0x00000001;
 681                mask = 0x00000707;
 682        }
 683
 684        nvkm_mask(device, hreg, 0x0000000f, hval);
 685        nvkm_mask(device, oreg, mask, oval);
 686}
 687
 688/* If programming a TMDS output on a SOR that can also be configured for
 689 * DisplayPort, make sure NV50_SOR_DP_CTRL_ENABLE is forced off.
 690 *
 691 * It looks like the VBIOS TMDS scripts make an attempt at this, however,
 692 * the VBIOS scripts on at least one board I have only switch it off on
 693 * link 0, causing a blank display if the output has previously been
 694 * programmed for DisplayPort.
 695 */
 696static void
 697nv50_disp_intr_unk40_0_tmds(struct nv50_disp *disp,
 698                            struct dcb_output *outp)
 699{
 700        struct nvkm_device *device = disp->base.engine.subdev.device;
 701        struct nvkm_bios *bios = device->bios;
 702        const int link = !(outp->sorconf.link & 1);
 703        const int   or = ffs(outp->or) - 1;
 704        const u32 loff = (or * 0x800) + (link * 0x80);
 705        const u16 mask = (outp->sorconf.link << 6) | outp->or;
 706        struct dcb_output match;
 707        u8  ver, hdr;
 708
 709        if (dcb_outp_match(bios, DCB_OUTPUT_DP, mask, &ver, &hdr, &match))
 710                nvkm_mask(device, 0x61c10c + loff, 0x00000001, 0x00000000);
 711}
 712
 713static void
 714nv50_disp_intr_unk40_0(struct nv50_disp *disp, int head)
 715{
 716        struct nvkm_device *device = disp->base.engine.subdev.device;
 717        struct nvkm_output *outp;
 718        u32 pclk = nvkm_rd32(device, 0x610ad0 + (head * 0x540)) & 0x3fffff;
 719        u32 conf;
 720
 721        outp = exec_clkcmp(disp, head, 1, pclk, &conf);
 722        if (!outp)
 723                return;
 724
 725        if (outp->info.location == 0 && outp->info.type == DCB_OUTPUT_TMDS)
 726                nv50_disp_intr_unk40_0_tmds(disp, &outp->info);
 727}
 728
 729void
 730nv50_disp_intr_supervisor(struct work_struct *work)
 731{
 732        struct nv50_disp *disp =
 733                container_of(work, struct nv50_disp, supervisor);
 734        struct nvkm_subdev *subdev = &disp->base.engine.subdev;
 735        struct nvkm_device *device = subdev->device;
 736        u32 super = nvkm_rd32(device, 0x610030);
 737        int head;
 738
 739        nvkm_debug(subdev, "supervisor %08x %08x\n", disp->super, super);
 740
 741        if (disp->super & 0x00000010) {
 742                nv50_disp_chan_mthd(disp->chan[0], NV_DBG_DEBUG);
 743                for (head = 0; head < disp->base.head.nr; head++) {
 744                        if (!(super & (0x00000020 << head)))
 745                                continue;
 746                        if (!(super & (0x00000080 << head)))
 747                                continue;
 748                        nv50_disp_intr_unk10_0(disp, head);
 749                }
 750        } else
 751        if (disp->super & 0x00000020) {
 752                for (head = 0; head < disp->base.head.nr; head++) {
 753                        if (!(super & (0x00000080 << head)))
 754                                continue;
 755                        nv50_disp_intr_unk20_0(disp, head);
 756                }
 757                for (head = 0; head < disp->base.head.nr; head++) {
 758                        if (!(super & (0x00000200 << head)))
 759                                continue;
 760                        nv50_disp_intr_unk20_1(disp, head);
 761                }
 762                for (head = 0; head < disp->base.head.nr; head++) {
 763                        if (!(super & (0x00000080 << head)))
 764                                continue;
 765                        nv50_disp_intr_unk20_2(disp, head);
 766                }
 767        } else
 768        if (disp->super & 0x00000040) {
 769                for (head = 0; head < disp->base.head.nr; head++) {
 770                        if (!(super & (0x00000080 << head)))
 771                                continue;
 772                        nv50_disp_intr_unk40_0(disp, head);
 773                }
 774        }
 775
 776        nvkm_wr32(device, 0x610030, 0x80000000);
 777}
 778
 779void
 780nv50_disp_intr(struct nv50_disp *disp)
 781{
 782        struct nvkm_device *device = disp->base.engine.subdev.device;
 783        u32 intr0 = nvkm_rd32(device, 0x610020);
 784        u32 intr1 = nvkm_rd32(device, 0x610024);
 785
 786        while (intr0 & 0x001f0000) {
 787                u32 chid = __ffs(intr0 & 0x001f0000) - 16;
 788                nv50_disp_intr_error(disp, chid);
 789                intr0 &= ~(0x00010000 << chid);
 790        }
 791
 792        while (intr0 & 0x0000001f) {
 793                u32 chid = __ffs(intr0 & 0x0000001f);
 794                nv50_disp_chan_uevent_send(disp, chid);
 795                intr0 &= ~(0x00000001 << chid);
 796        }
 797
 798        if (intr1 & 0x00000004) {
 799                nvkm_disp_vblank(&disp->base, 0);
 800                nvkm_wr32(device, 0x610024, 0x00000004);
 801        }
 802
 803        if (intr1 & 0x00000008) {
 804                nvkm_disp_vblank(&disp->base, 1);
 805                nvkm_wr32(device, 0x610024, 0x00000008);
 806        }
 807
 808        if (intr1 & 0x00000070) {
 809                disp->super = (intr1 & 0x00000070);
 810                schedule_work(&disp->supervisor);
 811                nvkm_wr32(device, 0x610024, disp->super);
 812        }
 813}
 814
 815static const struct nv50_disp_func
 816nv50_disp = {
 817        .intr = nv50_disp_intr,
 818        .uevent = &nv50_disp_chan_uevent,
 819        .super = nv50_disp_intr_supervisor,
 820        .root = &nv50_disp_root_oclass,
 821        .head.vblank_init = nv50_disp_vblank_init,
 822        .head.vblank_fini = nv50_disp_vblank_fini,
 823        .head.scanoutpos = nv50_disp_root_scanoutpos,
 824        .outp.internal.crt = nv50_dac_output_new,
 825        .outp.internal.tmds = nv50_sor_output_new,
 826        .outp.internal.lvds = nv50_sor_output_new,
 827        .outp.external.tmds = nv50_pior_output_new,
 828        .outp.external.dp = nv50_pior_dp_new,
 829        .dac.nr = 3,
 830        .dac.power = nv50_dac_power,
 831        .dac.sense = nv50_dac_sense,
 832        .sor.nr = 2,
 833        .sor.power = nv50_sor_power,
 834        .pior.nr = 3,
 835        .pior.power = nv50_pior_power,
 836};
 837
 838int
 839nv50_disp_new(struct nvkm_device *device, int index, struct nvkm_disp **pdisp)
 840{
 841        return nv50_disp_new_(&nv50_disp, device, index, 2, pdisp);
 842}
 843