linux/drivers/gpu/drm/nouveau/nvkm/subdev/bios/pll.c
<<
>>
Prefs
   1/*
   2 * Copyright 2005-2006 Erik Waling
   3 * Copyright 2006 Stephane Marchesin
   4 * Copyright 2007-2009 Stuart Bennett
   5 *
   6 * Permission is hereby granted, free of charge, to any person obtaining a
   7 * copy of this software and associated documentation files (the "Software"),
   8 * to deal in the Software without restriction, including without limitation
   9 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  10 * and/or sell copies of the Software, and to permit persons to whom the
  11 * Software is furnished to do so, subject to the following conditions:
  12 *
  13 * The above copyright notice and this permission notice shall be included in
  14 * all copies or substantial portions of the Software.
  15 *
  16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
  19 * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
  20 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
  21 * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  22 * SOFTWARE.
  23 */
  24#include <subdev/bios.h>
  25#include <subdev/bios/bit.h>
  26#include <subdev/bios/bmp.h>
  27#include <subdev/bios/pll.h>
  28#include <subdev/vga.h>
  29
  30
  31struct pll_mapping {
  32        u8  type;
  33        u32 reg;
  34};
  35
  36static struct pll_mapping
  37nv04_pll_mapping[] = {
  38        { PLL_CORE  , 0x680500 },
  39        { PLL_MEMORY, 0x680504 },
  40        { PLL_VPLL0 , 0x680508 },
  41        { PLL_VPLL1 , 0x680520 },
  42        {}
  43};
  44
  45static struct pll_mapping
  46nv40_pll_mapping[] = {
  47        { PLL_CORE  , 0x004000 },
  48        { PLL_MEMORY, 0x004020 },
  49        { PLL_VPLL0 , 0x680508 },
  50        { PLL_VPLL1 , 0x680520 },
  51        {}
  52};
  53
  54static struct pll_mapping
  55nv50_pll_mapping[] = {
  56        { PLL_CORE  , 0x004028 },
  57        { PLL_SHADER, 0x004020 },
  58        { PLL_UNK03 , 0x004000 },
  59        { PLL_MEMORY, 0x004008 },
  60        { PLL_UNK40 , 0x00e810 },
  61        { PLL_UNK41 , 0x00e818 },
  62        { PLL_UNK42 , 0x00e824 },
  63        { PLL_VPLL0 , 0x614100 },
  64        { PLL_VPLL1 , 0x614900 },
  65        {}
  66};
  67
  68static struct pll_mapping
  69g84_pll_mapping[] = {
  70        { PLL_CORE  , 0x004028 },
  71        { PLL_SHADER, 0x004020 },
  72        { PLL_MEMORY, 0x004008 },
  73        { PLL_VDEC  , 0x004030 },
  74        { PLL_UNK41 , 0x00e818 },
  75        { PLL_VPLL0 , 0x614100 },
  76        { PLL_VPLL1 , 0x614900 },
  77        {}
  78};
  79
  80static u32
  81pll_limits_table(struct nvkm_bios *bios, u8 *ver, u8 *hdr, u8 *cnt, u8 *len)
  82{
  83        struct bit_entry bit_C;
  84        u32 data = 0x0000;
  85
  86        if (!bit_entry(bios, 'C', &bit_C)) {
  87                if (bit_C.version == 1 && bit_C.length >= 10)
  88                        data = nvbios_rd16(bios, bit_C.offset + 8);
  89                if (bit_C.version == 2 && bit_C.length >= 4)
  90                        data = nvbios_rd32(bios, bit_C.offset + 0);
  91                if (data) {
  92                        *ver = nvbios_rd08(bios, data + 0);
  93                        *hdr = nvbios_rd08(bios, data + 1);
  94                        *len = nvbios_rd08(bios, data + 2);
  95                        *cnt = nvbios_rd08(bios, data + 3);
  96                        return data;
  97                }
  98        }
  99
 100        if (bmp_version(bios) >= 0x0524) {
 101                data = nvbios_rd16(bios, bios->bmp_offset + 142);
 102                if (data) {
 103                        *ver = nvbios_rd08(bios, data + 0);
 104                        *hdr = 1;
 105                        *cnt = 1;
 106                        *len = 0x18;
 107                        return data;
 108                }
 109        }
 110
 111        *ver = 0x00;
 112        return data;
 113}
 114
 115static struct pll_mapping *
 116pll_map(struct nvkm_bios *bios)
 117{
 118        struct nvkm_device *device = bios->subdev.device;
 119        switch (device->card_type) {
 120        case NV_04:
 121        case NV_10:
 122        case NV_11:
 123        case NV_20:
 124        case NV_30:
 125                return nv04_pll_mapping;
 126        case NV_40:
 127                return nv40_pll_mapping;
 128        case NV_50:
 129                if (device->chipset == 0x50)
 130                        return nv50_pll_mapping;
 131                else
 132                if (device->chipset <  0xa3 ||
 133                    device->chipset == 0xaa ||
 134                    device->chipset == 0xac)
 135                        return g84_pll_mapping;
 136                fallthrough;
 137        default:
 138                return NULL;
 139        }
 140}
 141
 142static u32
 143pll_map_reg(struct nvkm_bios *bios, u32 reg, u32 *type, u8 *ver, u8 *len)
 144{
 145        struct pll_mapping *map;
 146        u8  hdr, cnt;
 147        u32 data;
 148
 149        data = pll_limits_table(bios, ver, &hdr, &cnt, len);
 150        if (data && *ver >= 0x30) {
 151                data += hdr;
 152                while (cnt--) {
 153                        if (nvbios_rd32(bios, data + 3) == reg) {
 154                                *type = nvbios_rd08(bios, data + 0);
 155                                return data;
 156                        }
 157                        data += *len;
 158                }
 159                return 0x0000;
 160        }
 161
 162        map = pll_map(bios);
 163        while (map && map->reg) {
 164                if (map->reg == reg && *ver >= 0x20) {
 165                        u32 addr = (data += hdr);
 166                        *type = map->type;
 167                        while (cnt--) {
 168                                if (nvbios_rd32(bios, data) == map->reg)
 169                                        return data;
 170                                data += *len;
 171                        }
 172                        return addr;
 173                } else
 174                if (map->reg == reg) {
 175                        *type = map->type;
 176                        return data + 1;
 177                }
 178                map++;
 179        }
 180
 181        return 0x0000;
 182}
 183
 184static u32
 185pll_map_type(struct nvkm_bios *bios, u8 type, u32 *reg, u8 *ver, u8 *len)
 186{
 187        struct pll_mapping *map;
 188        u8  hdr, cnt;
 189        u32 data;
 190
 191        data = pll_limits_table(bios, ver, &hdr, &cnt, len);
 192        if (data && *ver >= 0x30) {
 193                data += hdr;
 194                while (cnt--) {
 195                        if (nvbios_rd08(bios, data + 0) == type) {
 196                                if (*ver < 0x50)
 197                                        *reg = nvbios_rd32(bios, data + 3);
 198                                else
 199                                        *reg = 0;
 200                                return data;
 201                        }
 202                        data += *len;
 203                }
 204                return 0x0000;
 205        }
 206
 207        map = pll_map(bios);
 208        while (map && map->reg) {
 209                if (map->type == type && *ver >= 0x20) {
 210                        u32 addr = (data += hdr);
 211                        *reg = map->reg;
 212                        while (cnt--) {
 213                                if (nvbios_rd32(bios, data) == map->reg)
 214                                        return data;
 215                                data += *len;
 216                        }
 217                        return addr;
 218                } else
 219                if (map->type == type) {
 220                        *reg = map->reg;
 221                        return data + 1;
 222                }
 223                map++;
 224        }
 225
 226        return 0x0000;
 227}
 228
 229int
 230nvbios_pll_parse(struct nvkm_bios *bios, u32 type, struct nvbios_pll *info)
 231{
 232        struct nvkm_subdev *subdev = &bios->subdev;
 233        struct nvkm_device *device = subdev->device;
 234        u8  ver, len;
 235        u32 reg = type;
 236        u32 data;
 237
 238        if (type > PLL_MAX) {
 239                reg  = type;
 240                data = pll_map_reg(bios, reg, &type, &ver, &len);
 241        } else {
 242                data = pll_map_type(bios, type, &reg, &ver, &len);
 243        }
 244
 245        if (ver && !data)
 246                return -ENOENT;
 247
 248        memset(info, 0, sizeof(*info));
 249        info->type = type;
 250        info->reg = reg;
 251
 252        switch (ver) {
 253        case 0x00:
 254                break;
 255        case 0x10:
 256        case 0x11:
 257                info->vco1.min_freq = nvbios_rd32(bios, data + 0);
 258                info->vco1.max_freq = nvbios_rd32(bios, data + 4);
 259                info->vco2.min_freq = nvbios_rd32(bios, data + 8);
 260                info->vco2.max_freq = nvbios_rd32(bios, data + 12);
 261                info->vco1.min_inputfreq = nvbios_rd32(bios, data + 16);
 262                info->vco2.min_inputfreq = nvbios_rd32(bios, data + 20);
 263                info->vco1.max_inputfreq = INT_MAX;
 264                info->vco2.max_inputfreq = INT_MAX;
 265
 266                info->max_p = 0x7;
 267                info->max_p_usable = 0x6;
 268
 269                /* these values taken from nv30/31/36 */
 270                switch (bios->version.chip) {
 271                case 0x36:
 272                        info->vco1.min_n = 0x5;
 273                        break;
 274                default:
 275                        info->vco1.min_n = 0x1;
 276                        break;
 277                }
 278                info->vco1.max_n = 0xff;
 279                info->vco1.min_m = 0x1;
 280                info->vco1.max_m = 0xd;
 281
 282                /*
 283                 * On nv30, 31, 36 (i.e. all cards with two stage PLLs with this
 284                 * table version (apart from nv35)), N2 is compared to
 285                 * maxN2 (0x46) and 10 * maxM2 (0x4), so set maxN2 to 0x28 and
 286                 * save a comparison
 287                 */
 288                info->vco2.min_n = 0x4;
 289                switch (bios->version.chip) {
 290                case 0x30:
 291                case 0x35:
 292                        info->vco2.max_n = 0x1f;
 293                        break;
 294                default:
 295                        info->vco2.max_n = 0x28;
 296                        break;
 297                }
 298                info->vco2.min_m = 0x1;
 299                info->vco2.max_m = 0x4;
 300                break;
 301        case 0x20:
 302        case 0x21:
 303                info->vco1.min_freq = nvbios_rd16(bios, data + 4) * 1000;
 304                info->vco1.max_freq = nvbios_rd16(bios, data + 6) * 1000;
 305                info->vco2.min_freq = nvbios_rd16(bios, data + 8) * 1000;
 306                info->vco2.max_freq = nvbios_rd16(bios, data + 10) * 1000;
 307                info->vco1.min_inputfreq = nvbios_rd16(bios, data + 12) * 1000;
 308                info->vco2.min_inputfreq = nvbios_rd16(bios, data + 14) * 1000;
 309                info->vco1.max_inputfreq = nvbios_rd16(bios, data + 16) * 1000;
 310                info->vco2.max_inputfreq = nvbios_rd16(bios, data + 18) * 1000;
 311                info->vco1.min_n = nvbios_rd08(bios, data + 20);
 312                info->vco1.max_n = nvbios_rd08(bios, data + 21);
 313                info->vco1.min_m = nvbios_rd08(bios, data + 22);
 314                info->vco1.max_m = nvbios_rd08(bios, data + 23);
 315                info->vco2.min_n = nvbios_rd08(bios, data + 24);
 316                info->vco2.max_n = nvbios_rd08(bios, data + 25);
 317                info->vco2.min_m = nvbios_rd08(bios, data + 26);
 318                info->vco2.max_m = nvbios_rd08(bios, data + 27);
 319
 320                info->max_p = nvbios_rd08(bios, data + 29);
 321                info->max_p_usable = info->max_p;
 322                if (bios->version.chip < 0x60)
 323                        info->max_p_usable = 0x6;
 324                info->bias_p = nvbios_rd08(bios, data + 30);
 325
 326                if (len > 0x22)
 327                        info->refclk = nvbios_rd32(bios, data + 31);
 328                break;
 329        case 0x30:
 330                data = nvbios_rd16(bios, data + 1);
 331
 332                info->vco1.min_freq = nvbios_rd16(bios, data + 0) * 1000;
 333                info->vco1.max_freq = nvbios_rd16(bios, data + 2) * 1000;
 334                info->vco2.min_freq = nvbios_rd16(bios, data + 4) * 1000;
 335                info->vco2.max_freq = nvbios_rd16(bios, data + 6) * 1000;
 336                info->vco1.min_inputfreq = nvbios_rd16(bios, data + 8) * 1000;
 337                info->vco2.min_inputfreq = nvbios_rd16(bios, data + 10) * 1000;
 338                info->vco1.max_inputfreq = nvbios_rd16(bios, data + 12) * 1000;
 339                info->vco2.max_inputfreq = nvbios_rd16(bios, data + 14) * 1000;
 340                info->vco1.min_n = nvbios_rd08(bios, data + 16);
 341                info->vco1.max_n = nvbios_rd08(bios, data + 17);
 342                info->vco1.min_m = nvbios_rd08(bios, data + 18);
 343                info->vco1.max_m = nvbios_rd08(bios, data + 19);
 344                info->vco2.min_n = nvbios_rd08(bios, data + 20);
 345                info->vco2.max_n = nvbios_rd08(bios, data + 21);
 346                info->vco2.min_m = nvbios_rd08(bios, data + 22);
 347                info->vco2.max_m = nvbios_rd08(bios, data + 23);
 348                info->max_p_usable = info->max_p = nvbios_rd08(bios, data + 25);
 349                info->bias_p = nvbios_rd08(bios, data + 27);
 350                info->refclk = nvbios_rd32(bios, data + 28);
 351                break;
 352        case 0x40:
 353                info->refclk = nvbios_rd16(bios, data + 9) * 1000;
 354                data = nvbios_rd16(bios, data + 1);
 355
 356                info->vco1.min_freq = nvbios_rd16(bios, data + 0) * 1000;
 357                info->vco1.max_freq = nvbios_rd16(bios, data + 2) * 1000;
 358                info->vco1.min_inputfreq = nvbios_rd16(bios, data + 4) * 1000;
 359                info->vco1.max_inputfreq = nvbios_rd16(bios, data + 6) * 1000;
 360                info->vco1.min_m = nvbios_rd08(bios, data + 8);
 361                info->vco1.max_m = nvbios_rd08(bios, data + 9);
 362                info->vco1.min_n = nvbios_rd08(bios, data + 10);
 363                info->vco1.max_n = nvbios_rd08(bios, data + 11);
 364                info->min_p = nvbios_rd08(bios, data + 12);
 365                info->max_p = nvbios_rd08(bios, data + 13);
 366                break;
 367        case 0x50:
 368                info->refclk = nvbios_rd16(bios, data + 1) * 1000;
 369                /* info->refclk_alt = nvbios_rd16(bios, data + 3) * 1000; */
 370                info->vco1.min_freq = nvbios_rd16(bios, data + 5) * 1000;
 371                info->vco1.max_freq = nvbios_rd16(bios, data + 7) * 1000;
 372                info->vco1.min_inputfreq = nvbios_rd16(bios, data + 9) * 1000;
 373                info->vco1.max_inputfreq = nvbios_rd16(bios, data + 11) * 1000;
 374                info->vco1.min_m = nvbios_rd08(bios, data + 13);
 375                info->vco1.max_m = nvbios_rd08(bios, data + 14);
 376                info->vco1.min_n = nvbios_rd08(bios, data + 15);
 377                info->vco1.max_n = nvbios_rd08(bios, data + 16);
 378                info->min_p = nvbios_rd08(bios, data + 17);
 379                info->max_p = nvbios_rd08(bios, data + 18);
 380                break;
 381        default:
 382                nvkm_error(subdev, "unknown pll limits version 0x%02x\n", ver);
 383                return -EINVAL;
 384        }
 385
 386        if (!info->refclk) {
 387                info->refclk = device->crystal;
 388                if (bios->version.chip == 0x51) {
 389                        u32 sel_clk = nvkm_rd32(device, 0x680524);
 390                        if ((info->reg == 0x680508 && sel_clk & 0x20) ||
 391                            (info->reg == 0x680520 && sel_clk & 0x80)) {
 392                                if (nvkm_rdvgac(device, 0, 0x27) < 0xa3)
 393                                        info->refclk = 200000;
 394                                else
 395                                        info->refclk = 25000;
 396                        }
 397                }
 398        }
 399
 400        /*
 401         * By now any valid limit table ought to have set a max frequency for
 402         * vco1, so if it's zero it's either a pre limit table bios, or one
 403         * with an empty limit table (seen on nv18)
 404         */
 405        if (!info->vco1.max_freq) {
 406                info->vco1.max_freq = nvbios_rd32(bios, bios->bmp_offset + 67);
 407                info->vco1.min_freq = nvbios_rd32(bios, bios->bmp_offset + 71);
 408                if (bmp_version(bios) < 0x0506) {
 409                        info->vco1.max_freq = 256000;
 410                        info->vco1.min_freq = 128000;
 411                }
 412
 413                info->vco1.min_inputfreq = 0;
 414                info->vco1.max_inputfreq = INT_MAX;
 415                info->vco1.min_n = 0x1;
 416                info->vco1.max_n = 0xff;
 417                info->vco1.min_m = 0x1;
 418
 419                if (device->crystal == 13500) {
 420                        /* nv05 does this, nv11 doesn't, nv10 unknown */
 421                        if (bios->version.chip < 0x11)
 422                                info->vco1.min_m = 0x7;
 423                        info->vco1.max_m = 0xd;
 424                } else {
 425                        if (bios->version.chip < 0x11)
 426                                info->vco1.min_m = 0x8;
 427                        info->vco1.max_m = 0xe;
 428                }
 429
 430                if (bios->version.chip <  0x17 ||
 431                    bios->version.chip == 0x1a ||
 432                    bios->version.chip == 0x20)
 433                        info->max_p = 4;
 434                else
 435                        info->max_p = 5;
 436                info->max_p_usable = info->max_p;
 437        }
 438
 439        return 0;
 440}
 441