linux/drivers/gpu/drm/nouveau/nvkm/engine/disp/gf119.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 <subdev/bios.h>
  28#include <subdev/bios/disp.h>
  29#include <subdev/bios/init.h>
  30#include <subdev/bios/pll.h>
  31#include <subdev/devinit.h>
  32
  33void
  34gf119_disp_vblank_init(struct nv50_disp *disp, int head)
  35{
  36        struct nvkm_device *device = disp->base.engine.subdev.device;
  37        nvkm_mask(device, 0x6100c0 + (head * 0x800), 0x00000001, 0x00000001);
  38}
  39
  40void
  41gf119_disp_vblank_fini(struct nv50_disp *disp, int head)
  42{
  43        struct nvkm_device *device = disp->base.engine.subdev.device;
  44        nvkm_mask(device, 0x6100c0 + (head * 0x800), 0x00000001, 0x00000000);
  45}
  46
  47static struct nvkm_output *
  48exec_lookup(struct nv50_disp *disp, int head, int or, u32 ctrl,
  49            u32 *data, u8 *ver, u8 *hdr, u8 *cnt, u8 *len,
  50            struct nvbios_outp *info)
  51{
  52        struct nvkm_subdev *subdev = &disp->base.engine.subdev;
  53        struct nvkm_bios *bios = subdev->device->bios;
  54        struct nvkm_output *outp;
  55        u16 mask, type;
  56
  57        if (or < 4) {
  58                type = DCB_OUTPUT_ANALOG;
  59                mask = 0;
  60        } else {
  61                or -= 4;
  62                switch (ctrl & 0x00000f00) {
  63                case 0x00000000: type = DCB_OUTPUT_LVDS; mask = 1; break;
  64                case 0x00000100: type = DCB_OUTPUT_TMDS; mask = 1; break;
  65                case 0x00000200: type = DCB_OUTPUT_TMDS; mask = 2; break;
  66                case 0x00000500: type = DCB_OUTPUT_TMDS; mask = 3; break;
  67                case 0x00000800: type = DCB_OUTPUT_DP; mask = 1; break;
  68                case 0x00000900: type = DCB_OUTPUT_DP; mask = 2; break;
  69                default:
  70                        nvkm_error(subdev, "unknown SOR mc %08x\n", ctrl);
  71                        return NULL;
  72                }
  73        }
  74
  75        mask  = 0x00c0 & (mask << 6);
  76        mask |= 0x0001 << or;
  77        mask |= 0x0100 << head;
  78
  79        list_for_each_entry(outp, &disp->base.outp, head) {
  80                if ((outp->info.hasht & 0xff) == type &&
  81                    (outp->info.hashm & mask) == mask) {
  82                        *data = nvbios_outp_match(bios, outp->info.hasht,
  83                                                        outp->info.hashm,
  84                                                  ver, hdr, cnt, len, info);
  85                        if (!*data)
  86                                return NULL;
  87                        return outp;
  88                }
  89        }
  90
  91        return NULL;
  92}
  93
  94static struct nvkm_output *
  95exec_script(struct nv50_disp *disp, int head, int id)
  96{
  97        struct nvkm_subdev *subdev = &disp->base.engine.subdev;
  98        struct nvkm_device *device = subdev->device;
  99        struct nvkm_bios *bios = device->bios;
 100        struct nvkm_output *outp;
 101        struct nvbios_outp info;
 102        u8  ver, hdr, cnt, len;
 103        u32 data, ctrl = 0;
 104        int or;
 105
 106        for (or = 0; !(ctrl & (1 << head)) && or < 8; or++) {
 107                ctrl = nvkm_rd32(device, 0x640180 + (or * 0x20));
 108                if (ctrl & (1 << head))
 109                        break;
 110        }
 111
 112        if (or == 8)
 113                return NULL;
 114
 115        outp = exec_lookup(disp, head, or, ctrl, &data, &ver, &hdr, &cnt, &len, &info);
 116        if (outp) {
 117                struct nvbios_init init = {
 118                        .subdev = subdev,
 119                        .bios = bios,
 120                        .offset = info.script[id],
 121                        .outp = &outp->info,
 122                        .crtc = head,
 123                        .execute = 1,
 124                };
 125
 126                nvbios_exec(&init);
 127        }
 128
 129        return outp;
 130}
 131
 132static struct nvkm_output *
 133exec_clkcmp(struct nv50_disp *disp, int head, int id, u32 pclk, u32 *conf)
 134{
 135        struct nvkm_subdev *subdev = &disp->base.engine.subdev;
 136        struct nvkm_device *device = subdev->device;
 137        struct nvkm_bios *bios = device->bios;
 138        struct nvkm_output *outp;
 139        struct nvbios_outp info1;
 140        struct nvbios_ocfg info2;
 141        u8  ver, hdr, cnt, len;
 142        u32 data, ctrl = 0;
 143        int or;
 144
 145        for (or = 0; !(ctrl & (1 << head)) && or < 8; or++) {
 146                ctrl = nvkm_rd32(device, 0x660180 + (or * 0x20));
 147                if (ctrl & (1 << head))
 148                        break;
 149        }
 150
 151        if (or == 8)
 152                return NULL;
 153
 154        outp = exec_lookup(disp, head, or, ctrl, &data, &ver, &hdr, &cnt, &len, &info1);
 155        if (!outp)
 156                return NULL;
 157
 158        switch (outp->info.type) {
 159        case DCB_OUTPUT_TMDS:
 160                *conf = (ctrl & 0x00000f00) >> 8;
 161                if (pclk >= 165000)
 162                        *conf |= 0x0100;
 163                break;
 164        case DCB_OUTPUT_LVDS:
 165                *conf = disp->sor.lvdsconf;
 166                break;
 167        case DCB_OUTPUT_DP:
 168                *conf = (ctrl & 0x00000f00) >> 8;
 169                break;
 170        case DCB_OUTPUT_ANALOG:
 171        default:
 172                *conf = 0x00ff;
 173                break;
 174        }
 175
 176        data = nvbios_ocfg_match(bios, data, *conf, &ver, &hdr, &cnt, &len, &info2);
 177        if (data && id < 0xff) {
 178                data = nvbios_oclk_match(bios, info2.clkcmp[id], pclk);
 179                if (data) {
 180                        struct nvbios_init init = {
 181                                .subdev = subdev,
 182                                .bios = bios,
 183                                .offset = data,
 184                                .outp = &outp->info,
 185                                .crtc = head,
 186                                .execute = 1,
 187                        };
 188
 189                        nvbios_exec(&init);
 190                }
 191        }
 192
 193        return outp;
 194}
 195
 196static void
 197gf119_disp_intr_unk1_0(struct nv50_disp *disp, int head)
 198{
 199        exec_script(disp, head, 1);
 200}
 201
 202static void
 203gf119_disp_intr_unk2_0(struct nv50_disp *disp, int head)
 204{
 205        struct nvkm_subdev *subdev = &disp->base.engine.subdev;
 206        struct nvkm_output *outp = exec_script(disp, head, 2);
 207
 208        /* see note in nv50_disp_intr_unk20_0() */
 209        if (outp && outp->info.type == DCB_OUTPUT_DP) {
 210                struct nvkm_output_dp *outpdp = nvkm_output_dp(outp);
 211                struct nvbios_init init = {
 212                        .subdev = subdev,
 213                        .bios = subdev->device->bios,
 214                        .outp = &outp->info,
 215                        .crtc = head,
 216                        .offset = outpdp->info.script[4],
 217                        .execute = 1,
 218                };
 219
 220                nvbios_exec(&init);
 221                atomic_set(&outpdp->lt.done, 0);
 222        }
 223}
 224
 225static void
 226gf119_disp_intr_unk2_1(struct nv50_disp *disp, int head)
 227{
 228        struct nvkm_device *device = disp->base.engine.subdev.device;
 229        struct nvkm_devinit *devinit = device->devinit;
 230        u32 pclk = nvkm_rd32(device, 0x660450 + (head * 0x300)) / 1000;
 231        if (pclk)
 232                nvkm_devinit_pll_set(devinit, PLL_VPLL0 + head, pclk);
 233        nvkm_wr32(device, 0x612200 + (head * 0x800), 0x00000000);
 234}
 235
 236static void
 237gf119_disp_intr_unk2_2_tu(struct nv50_disp *disp, int head,
 238                          struct dcb_output *outp)
 239{
 240        struct nvkm_device *device = disp->base.engine.subdev.device;
 241        const int or = ffs(outp->or) - 1;
 242        const u32 ctrl = nvkm_rd32(device, 0x660200 + (or   * 0x020));
 243        const u32 conf = nvkm_rd32(device, 0x660404 + (head * 0x300));
 244        const s32 vactive = nvkm_rd32(device, 0x660414 + (head * 0x300)) & 0xffff;
 245        const s32 vblanke = nvkm_rd32(device, 0x66041c + (head * 0x300)) & 0xffff;
 246        const s32 vblanks = nvkm_rd32(device, 0x660420 + (head * 0x300)) & 0xffff;
 247        const u32 pclk = nvkm_rd32(device, 0x660450 + (head * 0x300)) / 1000;
 248        const u32 link = ((ctrl & 0xf00) == 0x800) ? 0 : 1;
 249        const u32 hoff = (head * 0x800);
 250        const u32 soff = (  or * 0x800);
 251        const u32 loff = (link * 0x080) + soff;
 252        const u32 symbol = 100000;
 253        const u32 TU = 64;
 254        u32 dpctrl = nvkm_rd32(device, 0x61c10c + loff);
 255        u32 clksor = nvkm_rd32(device, 0x612300 + soff);
 256        u32 datarate, link_nr, link_bw, bits;
 257        u64 ratio, value;
 258
 259        link_nr  = hweight32(dpctrl & 0x000f0000);
 260        link_bw  = (clksor & 0x007c0000) >> 18;
 261        link_bw *= 27000;
 262
 263        /* symbols/hblank - algorithm taken from comments in tegra driver */
 264        value = vblanke + vactive - vblanks - 7;
 265        value = value * link_bw;
 266        do_div(value, pclk);
 267        value = value - (3 * !!(dpctrl & 0x00004000)) - (12 / link_nr);
 268        nvkm_mask(device, 0x616620 + hoff, 0x0000ffff, value);
 269
 270        /* symbols/vblank - algorithm taken from comments in tegra driver */
 271        value = vblanks - vblanke - 25;
 272        value = value * link_bw;
 273        do_div(value, pclk);
 274        value = value - ((36 / link_nr) + 3) - 1;
 275        nvkm_mask(device, 0x616624 + hoff, 0x00ffffff, value);
 276
 277        /* watermark */
 278        if      ((conf & 0x3c0) == 0x180) bits = 30;
 279        else if ((conf & 0x3c0) == 0x140) bits = 24;
 280        else                              bits = 18;
 281        datarate = (pclk * bits) / 8;
 282
 283        ratio  = datarate;
 284        ratio *= symbol;
 285        do_div(ratio, link_nr * link_bw);
 286
 287        value  = (symbol - ratio) * TU;
 288        value *= ratio;
 289        do_div(value, symbol);
 290        do_div(value, symbol);
 291
 292        value += 5;
 293        value |= 0x08000000;
 294
 295        nvkm_wr32(device, 0x616610 + hoff, value);
 296}
 297
 298static void
 299gf119_disp_intr_unk2_2(struct nv50_disp *disp, int head)
 300{
 301        struct nvkm_device *device = disp->base.engine.subdev.device;
 302        struct nvkm_output *outp;
 303        u32 pclk = nvkm_rd32(device, 0x660450 + (head * 0x300)) / 1000;
 304        u32 conf, addr, data;
 305
 306        outp = exec_clkcmp(disp, head, 0xff, pclk, &conf);
 307        if (!outp)
 308                return;
 309
 310        /* see note in nv50_disp_intr_unk20_2() */
 311        if (outp->info.type == DCB_OUTPUT_DP) {
 312                u32 sync = nvkm_rd32(device, 0x660404 + (head * 0x300));
 313                switch ((sync & 0x000003c0) >> 6) {
 314                case 6: pclk = pclk * 30; break;
 315                case 5: pclk = pclk * 24; break;
 316                case 2:
 317                default:
 318                        pclk = pclk * 18;
 319                        break;
 320                }
 321
 322                if (nvkm_output_dp_train(outp, pclk, true))
 323                        OUTP_ERR(outp, "link not trained before attach");
 324        } else {
 325                if (disp->func->sor.magic)
 326                        disp->func->sor.magic(outp);
 327        }
 328
 329        exec_clkcmp(disp, head, 0, pclk, &conf);
 330
 331        if (outp->info.type == DCB_OUTPUT_ANALOG) {
 332                addr = 0x612280 + (ffs(outp->info.or) - 1) * 0x800;
 333                data = 0x00000000;
 334        } else {
 335                addr = 0x612300 + (ffs(outp->info.or) - 1) * 0x800;
 336                data = (conf & 0x0100) ? 0x00000101 : 0x00000000;
 337                switch (outp->info.type) {
 338                case DCB_OUTPUT_TMDS:
 339                        nvkm_mask(device, addr, 0x007c0000, 0x00280000);
 340                        break;
 341                case DCB_OUTPUT_DP:
 342                        gf119_disp_intr_unk2_2_tu(disp, head, &outp->info);
 343                        break;
 344                default:
 345                        break;
 346                }
 347        }
 348
 349        nvkm_mask(device, addr, 0x00000707, data);
 350}
 351
 352static void
 353gf119_disp_intr_unk4_0(struct nv50_disp *disp, int head)
 354{
 355        struct nvkm_device *device = disp->base.engine.subdev.device;
 356        u32 pclk = nvkm_rd32(device, 0x660450 + (head * 0x300)) / 1000;
 357        u32 conf;
 358
 359        exec_clkcmp(disp, head, 1, pclk, &conf);
 360}
 361
 362void
 363gf119_disp_intr_supervisor(struct work_struct *work)
 364{
 365        struct nv50_disp *disp =
 366                container_of(work, struct nv50_disp, supervisor);
 367        struct nvkm_subdev *subdev = &disp->base.engine.subdev;
 368        struct nvkm_device *device = subdev->device;
 369        u32 mask[4];
 370        int head;
 371
 372        nvkm_debug(subdev, "supervisor %d\n", ffs(disp->super));
 373        for (head = 0; head < disp->base.head.nr; head++) {
 374                mask[head] = nvkm_rd32(device, 0x6101d4 + (head * 0x800));
 375                nvkm_debug(subdev, "head %d: %08x\n", head, mask[head]);
 376        }
 377
 378        if (disp->super & 0x00000001) {
 379                nv50_disp_chan_mthd(disp->chan[0], NV_DBG_DEBUG);
 380                for (head = 0; head < disp->base.head.nr; head++) {
 381                        if (!(mask[head] & 0x00001000))
 382                                continue;
 383                        nvkm_debug(subdev, "supervisor 1.0 - head %d\n", head);
 384                        gf119_disp_intr_unk1_0(disp, head);
 385                }
 386        } else
 387        if (disp->super & 0x00000002) {
 388                for (head = 0; head < disp->base.head.nr; head++) {
 389                        if (!(mask[head] & 0x00001000))
 390                                continue;
 391                        nvkm_debug(subdev, "supervisor 2.0 - head %d\n", head);
 392                        gf119_disp_intr_unk2_0(disp, head);
 393                }
 394                for (head = 0; head < disp->base.head.nr; head++) {
 395                        if (!(mask[head] & 0x00010000))
 396                                continue;
 397                        nvkm_debug(subdev, "supervisor 2.1 - head %d\n", head);
 398                        gf119_disp_intr_unk2_1(disp, head);
 399                }
 400                for (head = 0; head < disp->base.head.nr; head++) {
 401                        if (!(mask[head] & 0x00001000))
 402                                continue;
 403                        nvkm_debug(subdev, "supervisor 2.2 - head %d\n", head);
 404                        gf119_disp_intr_unk2_2(disp, head);
 405                }
 406        } else
 407        if (disp->super & 0x00000004) {
 408                for (head = 0; head < disp->base.head.nr; head++) {
 409                        if (!(mask[head] & 0x00001000))
 410                                continue;
 411                        nvkm_debug(subdev, "supervisor 3.0 - head %d\n", head);
 412                        gf119_disp_intr_unk4_0(disp, head);
 413                }
 414        }
 415
 416        for (head = 0; head < disp->base.head.nr; head++)
 417                nvkm_wr32(device, 0x6101d4 + (head * 0x800), 0x00000000);
 418        nvkm_wr32(device, 0x6101d0, 0x80000000);
 419}
 420
 421static void
 422gf119_disp_intr_error(struct nv50_disp *disp, int chid)
 423{
 424        struct nvkm_subdev *subdev = &disp->base.engine.subdev;
 425        struct nvkm_device *device = subdev->device;
 426        u32 mthd = nvkm_rd32(device, 0x6101f0 + (chid * 12));
 427        u32 data = nvkm_rd32(device, 0x6101f4 + (chid * 12));
 428        u32 unkn = nvkm_rd32(device, 0x6101f8 + (chid * 12));
 429
 430        nvkm_error(subdev, "chid %d mthd %04x data %08x %08x %08x\n",
 431                   chid, (mthd & 0x0000ffc), data, mthd, unkn);
 432
 433        if (chid < ARRAY_SIZE(disp->chan)) {
 434                switch (mthd & 0xffc) {
 435                case 0x0080:
 436                        nv50_disp_chan_mthd(disp->chan[chid], NV_DBG_ERROR);
 437                        break;
 438                default:
 439                        break;
 440                }
 441        }
 442
 443        nvkm_wr32(device, 0x61009c, (1 << chid));
 444        nvkm_wr32(device, 0x6101f0 + (chid * 12), 0x90000000);
 445}
 446
 447void
 448gf119_disp_intr(struct nv50_disp *disp)
 449{
 450        struct nvkm_subdev *subdev = &disp->base.engine.subdev;
 451        struct nvkm_device *device = subdev->device;
 452        u32 intr = nvkm_rd32(device, 0x610088);
 453        int i;
 454
 455        if (intr & 0x00000001) {
 456                u32 stat = nvkm_rd32(device, 0x61008c);
 457                while (stat) {
 458                        int chid = __ffs(stat); stat &= ~(1 << chid);
 459                        nv50_disp_chan_uevent_send(disp, chid);
 460                        nvkm_wr32(device, 0x61008c, 1 << chid);
 461                }
 462                intr &= ~0x00000001;
 463        }
 464
 465        if (intr & 0x00000002) {
 466                u32 stat = nvkm_rd32(device, 0x61009c);
 467                int chid = ffs(stat) - 1;
 468                if (chid >= 0)
 469                        gf119_disp_intr_error(disp, chid);
 470                intr &= ~0x00000002;
 471        }
 472
 473        if (intr & 0x00100000) {
 474                u32 stat = nvkm_rd32(device, 0x6100ac);
 475                if (stat & 0x00000007) {
 476                        disp->super = (stat & 0x00000007);
 477                        schedule_work(&disp->supervisor);
 478                        nvkm_wr32(device, 0x6100ac, disp->super);
 479                        stat &= ~0x00000007;
 480                }
 481
 482                if (stat) {
 483                        nvkm_warn(subdev, "intr24 %08x\n", stat);
 484                        nvkm_wr32(device, 0x6100ac, stat);
 485                }
 486
 487                intr &= ~0x00100000;
 488        }
 489
 490        for (i = 0; i < disp->base.head.nr; i++) {
 491                u32 mask = 0x01000000 << i;
 492                if (mask & intr) {
 493                        u32 stat = nvkm_rd32(device, 0x6100bc + (i * 0x800));
 494                        if (stat & 0x00000001)
 495                                nvkm_disp_vblank(&disp->base, i);
 496                        nvkm_mask(device, 0x6100bc + (i * 0x800), 0, 0);
 497                        nvkm_rd32(device, 0x6100c0 + (i * 0x800));
 498                }
 499        }
 500}
 501
 502int
 503gf119_disp_new_(const struct nv50_disp_func *func, struct nvkm_device *device,
 504                int index, struct nvkm_disp **pdisp)
 505{
 506        u32 heads = nvkm_rd32(device, 0x022448);
 507        return nv50_disp_new_(func, device, index, heads, pdisp);
 508}
 509
 510static const struct nv50_disp_func
 511gf119_disp = {
 512        .intr = gf119_disp_intr,
 513        .uevent = &gf119_disp_chan_uevent,
 514        .super = gf119_disp_intr_supervisor,
 515        .root = &gf119_disp_root_oclass,
 516        .head.vblank_init = gf119_disp_vblank_init,
 517        .head.vblank_fini = gf119_disp_vblank_fini,
 518        .head.scanoutpos = gf119_disp_root_scanoutpos,
 519        .outp.internal.crt = nv50_dac_output_new,
 520        .outp.internal.tmds = nv50_sor_output_new,
 521        .outp.internal.lvds = nv50_sor_output_new,
 522        .outp.internal.dp = gf119_sor_dp_new,
 523        .dac.nr = 3,
 524        .dac.power = nv50_dac_power,
 525        .dac.sense = nv50_dac_sense,
 526        .sor.nr = 4,
 527        .sor.power = nv50_sor_power,
 528        .sor.hda_eld = gf119_hda_eld,
 529        .sor.hdmi = gf119_hdmi_ctrl,
 530};
 531
 532int
 533gf119_disp_new(struct nvkm_device *device, int index, struct nvkm_disp **pdisp)
 534{
 535        return gf119_disp_new_(&gf119_disp, device, index, pdisp);
 536}
 537