linux/drivers/gpu/drm/nouveau/core/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
  25#include <subdev/vga.h>
  26#include <subdev/bios.h>
  27#include <subdev/bios/bit.h>
  28#include <subdev/bios/bmp.h>
  29#include <subdev/bios/pll.h>
  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
  69nv84_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 u16
  81pll_limits_table(struct nouveau_bios *bios, u8 *ver, u8 *hdr, u8 *cnt, u8 *len)
  82{
  83        struct bit_entry bit_C;
  84
  85        if (!bit_entry(bios, 'C', &bit_C) && bit_C.length >= 10) {
  86                u16 data = nv_ro16(bios, bit_C.offset + 8);
  87                if (data) {
  88                        *ver = nv_ro08(bios, data + 0);
  89                        *hdr = nv_ro08(bios, data + 1);
  90                        *len = nv_ro08(bios, data + 2);
  91                        *cnt = nv_ro08(bios, data + 3);
  92                        return data;
  93                }
  94        }
  95
  96        if (bmp_version(bios) >= 0x0524) {
  97                u16 data = nv_ro16(bios, bios->bmp_offset + 142);
  98                if (data) {
  99                        *ver = nv_ro08(bios, data + 0);
 100                        *hdr = 1;
 101                        *cnt = 1;
 102                        *len = 0x18;
 103                        return data;
 104                }
 105        }
 106
 107        *ver = 0x00;
 108        return 0x0000;
 109}
 110
 111static struct pll_mapping *
 112pll_map(struct nouveau_bios *bios)
 113{
 114        switch (nv_device(bios)->card_type) {
 115        case NV_04:
 116        case NV_10:
 117        case NV_11:
 118        case NV_20:
 119        case NV_30:
 120                return nv04_pll_mapping;
 121                break;
 122        case NV_40:
 123                return nv40_pll_mapping;
 124        case NV_50:
 125                if (nv_device(bios)->chipset == 0x50)
 126                        return nv50_pll_mapping;
 127                else
 128                if (nv_device(bios)->chipset <  0xa3 ||
 129                    nv_device(bios)->chipset == 0xaa ||
 130                    nv_device(bios)->chipset == 0xac)
 131                        return nv84_pll_mapping;
 132        default:
 133                return NULL;
 134        }
 135}
 136
 137static u16
 138pll_map_reg(struct nouveau_bios *bios, u32 reg, u32 *type, u8 *ver, u8 *len)
 139{
 140        struct pll_mapping *map;
 141        u8  hdr, cnt;
 142        u16 data;
 143
 144        data = pll_limits_table(bios, ver, &hdr, &cnt, len);
 145        if (data && *ver >= 0x30) {
 146                data += hdr;
 147                while (cnt--) {
 148                        if (nv_ro32(bios, data + 3) == reg) {
 149                                *type = nv_ro08(bios, data + 0);
 150                                return data;
 151                        }
 152                        data += *len;
 153                }
 154                return 0x0000;
 155        }
 156
 157        map = pll_map(bios);
 158        while (map->reg) {
 159                if (map->reg == reg && *ver >= 0x20) {
 160                        u16 addr = (data += hdr);
 161                        *type = map->type;
 162                        while (cnt--) {
 163                                if (nv_ro32(bios, data) == map->reg)
 164                                        return data;
 165                                data += *len;
 166                        }
 167                        return addr;
 168                } else
 169                if (map->reg == reg) {
 170                        *type = map->type;
 171                        return data + 1;
 172                }
 173                map++;
 174        }
 175
 176        return 0x0000;
 177}
 178
 179static u16
 180pll_map_type(struct nouveau_bios *bios, u8 type, u32 *reg, u8 *ver, u8 *len)
 181{
 182        struct pll_mapping *map;
 183        u8  hdr, cnt;
 184        u16 data;
 185
 186        data = pll_limits_table(bios, ver, &hdr, &cnt, len);
 187        if (data && *ver >= 0x30) {
 188                data += hdr;
 189                while (cnt--) {
 190                        if (nv_ro08(bios, data + 0) == type) {
 191                                *reg = nv_ro32(bios, data + 3);
 192                                return data;
 193                        }
 194                        data += *len;
 195                }
 196                return 0x0000;
 197        }
 198
 199        map = pll_map(bios);
 200        while (map->reg) {
 201                if (map->type == type && *ver >= 0x20) {
 202                        u16 addr = (data += hdr);
 203                        *reg = map->reg;
 204                        while (cnt--) {
 205                                if (nv_ro32(bios, data) == map->reg)
 206                                        return data;
 207                                data += *len;
 208                        }
 209                        return addr;
 210                } else
 211                if (map->type == type) {
 212                        *reg = map->reg;
 213                        return data + 1;
 214                }
 215                map++;
 216        }
 217
 218        return 0x0000;
 219}
 220
 221int
 222nvbios_pll_parse(struct nouveau_bios *bios, u32 type, struct nvbios_pll *info)
 223{
 224        u8  ver, len;
 225        u32 reg = type;
 226        u16 data;
 227
 228        if (type > PLL_MAX) {
 229                reg  = type;
 230                data = pll_map_reg(bios, reg, &type, &ver, &len);
 231        } else {
 232                data = pll_map_type(bios, type, &reg, &ver, &len);
 233        }
 234
 235        if (ver && !data)
 236                return -ENOENT;
 237
 238        memset(info, 0, sizeof(*info));
 239        info->type = type;
 240        info->reg = reg;
 241
 242        switch (ver) {
 243        case 0x00:
 244                break;
 245        case 0x10:
 246        case 0x11:
 247                info->vco1.min_freq = nv_ro32(bios, data + 0);
 248                info->vco1.max_freq = nv_ro32(bios, data + 4);
 249                info->vco2.min_freq = nv_ro32(bios, data + 8);
 250                info->vco2.max_freq = nv_ro32(bios, data + 12);
 251                info->vco1.min_inputfreq = nv_ro32(bios, data + 16);
 252                info->vco2.min_inputfreq = nv_ro32(bios, data + 20);
 253                info->vco1.max_inputfreq = INT_MAX;
 254                info->vco2.max_inputfreq = INT_MAX;
 255
 256                info->max_p = 0x7;
 257                info->max_p_usable = 0x6;
 258
 259                /* these values taken from nv30/31/36 */
 260                switch (bios->version.chip) {
 261                case 0x36:
 262                        info->vco1.min_n = 0x5;
 263                        break;
 264                default:
 265                        info->vco1.min_n = 0x1;
 266                        break;
 267                }
 268                info->vco1.max_n = 0xff;
 269                info->vco1.min_m = 0x1;
 270                info->vco1.max_m = 0xd;
 271
 272                /*
 273                 * On nv30, 31, 36 (i.e. all cards with two stage PLLs with this
 274                 * table version (apart from nv35)), N2 is compared to
 275                 * maxN2 (0x46) and 10 * maxM2 (0x4), so set maxN2 to 0x28 and
 276                 * save a comparison
 277                 */
 278                info->vco2.min_n = 0x4;
 279                switch (bios->version.chip) {
 280                case 0x30:
 281                case 0x35:
 282                        info->vco2.max_n = 0x1f;
 283                        break;
 284                default:
 285                        info->vco2.max_n = 0x28;
 286                        break;
 287                }
 288                info->vco2.min_m = 0x1;
 289                info->vco2.max_m = 0x4;
 290                break;
 291        case 0x20:
 292        case 0x21:
 293                info->vco1.min_freq = nv_ro16(bios, data + 4) * 1000;
 294                info->vco1.max_freq = nv_ro16(bios, data + 6) * 1000;
 295                info->vco2.min_freq = nv_ro16(bios, data + 8) * 1000;
 296                info->vco2.max_freq = nv_ro16(bios, data + 10) * 1000;
 297                info->vco1.min_inputfreq = nv_ro16(bios, data + 12) * 1000;
 298                info->vco2.min_inputfreq = nv_ro16(bios, data + 14) * 1000;
 299                info->vco1.max_inputfreq = nv_ro16(bios, data + 16) * 1000;
 300                info->vco2.max_inputfreq = nv_ro16(bios, data + 18) * 1000;
 301                info->vco1.min_n = nv_ro08(bios, data + 20);
 302                info->vco1.max_n = nv_ro08(bios, data + 21);
 303                info->vco1.min_m = nv_ro08(bios, data + 22);
 304                info->vco1.max_m = nv_ro08(bios, data + 23);
 305                info->vco2.min_n = nv_ro08(bios, data + 24);
 306                info->vco2.max_n = nv_ro08(bios, data + 25);
 307                info->vco2.min_m = nv_ro08(bios, data + 26);
 308                info->vco2.max_m = nv_ro08(bios, data + 27);
 309
 310                info->max_p = nv_ro08(bios, data + 29);
 311                info->max_p_usable = info->max_p;
 312                if (bios->version.chip < 0x60)
 313                        info->max_p_usable = 0x6;
 314                info->bias_p = nv_ro08(bios, data + 30);
 315
 316                if (len > 0x22)
 317                        info->refclk = nv_ro32(bios, data + 31);
 318                break;
 319        case 0x30:
 320                data = nv_ro16(bios, data + 1);
 321
 322                info->vco1.min_freq = nv_ro16(bios, data + 0) * 1000;
 323                info->vco1.max_freq = nv_ro16(bios, data + 2) * 1000;
 324                info->vco2.min_freq = nv_ro16(bios, data + 4) * 1000;
 325                info->vco2.max_freq = nv_ro16(bios, data + 6) * 1000;
 326                info->vco1.min_inputfreq = nv_ro16(bios, data + 8) * 1000;
 327                info->vco2.min_inputfreq = nv_ro16(bios, data + 10) * 1000;
 328                info->vco1.max_inputfreq = nv_ro16(bios, data + 12) * 1000;
 329                info->vco2.max_inputfreq = nv_ro16(bios, data + 14) * 1000;
 330                info->vco1.min_n = nv_ro08(bios, data + 16);
 331                info->vco1.max_n = nv_ro08(bios, data + 17);
 332                info->vco1.min_m = nv_ro08(bios, data + 18);
 333                info->vco1.max_m = nv_ro08(bios, data + 19);
 334                info->vco2.min_n = nv_ro08(bios, data + 20);
 335                info->vco2.max_n = nv_ro08(bios, data + 21);
 336                info->vco2.min_m = nv_ro08(bios, data + 22);
 337                info->vco2.max_m = nv_ro08(bios, data + 23);
 338                info->max_p_usable = info->max_p = nv_ro08(bios, data + 25);
 339                info->bias_p = nv_ro08(bios, data + 27);
 340                info->refclk = nv_ro32(bios, data + 28);
 341                break;
 342        case 0x40:
 343                info->refclk = nv_ro16(bios, data + 9) * 1000;
 344                data = nv_ro16(bios, data + 1);
 345
 346                info->vco1.min_freq = nv_ro16(bios, data + 0) * 1000;
 347                info->vco1.max_freq = nv_ro16(bios, data + 2) * 1000;
 348                info->vco1.min_inputfreq = nv_ro16(bios, data + 4) * 1000;
 349                info->vco1.max_inputfreq = nv_ro16(bios, data + 6) * 1000;
 350                info->vco1.min_m = nv_ro08(bios, data + 8);
 351                info->vco1.max_m = nv_ro08(bios, data + 9);
 352                info->vco1.min_n = nv_ro08(bios, data + 10);
 353                info->vco1.max_n = nv_ro08(bios, data + 11);
 354                info->min_p = nv_ro08(bios, data + 12);
 355                info->max_p = nv_ro08(bios, data + 13);
 356                break;
 357        default:
 358                nv_error(bios, "unknown pll limits version 0x%02x\n", ver);
 359                return -EINVAL;
 360        }
 361
 362        if (!info->refclk) {
 363                info->refclk = nv_device(bios)->crystal;
 364                if (bios->version.chip == 0x51) {
 365                        u32 sel_clk = nv_rd32(bios, 0x680524);
 366                        if ((info->reg == 0x680508 && sel_clk & 0x20) ||
 367                            (info->reg == 0x680520 && sel_clk & 0x80)) {
 368                                if (nv_rdvgac(bios, 0, 0x27) < 0xa3)
 369                                        info->refclk = 200000;
 370                                else
 371                                        info->refclk = 25000;
 372                        }
 373                }
 374        }
 375
 376        /*
 377         * By now any valid limit table ought to have set a max frequency for
 378         * vco1, so if it's zero it's either a pre limit table bios, or one
 379         * with an empty limit table (seen on nv18)
 380         */
 381        if (!info->vco1.max_freq) {
 382                info->vco1.max_freq = nv_ro32(bios, bios->bmp_offset + 67);
 383                info->vco1.min_freq = nv_ro32(bios, bios->bmp_offset + 71);
 384                if (bmp_version(bios) < 0x0506) {
 385                        info->vco1.max_freq = 256000;
 386                        info->vco1.min_freq = 128000;
 387                }
 388
 389                info->vco1.min_inputfreq = 0;
 390                info->vco1.max_inputfreq = INT_MAX;
 391                info->vco1.min_n = 0x1;
 392                info->vco1.max_n = 0xff;
 393                info->vco1.min_m = 0x1;
 394
 395                if (nv_device(bios)->crystal == 13500) {
 396                        /* nv05 does this, nv11 doesn't, nv10 unknown */
 397                        if (bios->version.chip < 0x11)
 398                                info->vco1.min_m = 0x7;
 399                        info->vco1.max_m = 0xd;
 400                } else {
 401                        if (bios->version.chip < 0x11)
 402                                info->vco1.min_m = 0x8;
 403                        info->vco1.max_m = 0xe;
 404                }
 405
 406                if (bios->version.chip <  0x17 ||
 407                    bios->version.chip == 0x1a ||
 408                    bios->version.chip == 0x20)
 409                        info->max_p = 4;
 410                else
 411                        info->max_p = 5;
 412                info->max_p_usable = info->max_p;
 413        }
 414
 415        return 0;
 416}
 417