coreboot-v3/southbridge/amd/rs690/gfx.c
<<
>>
Prefs
   1/*
   2 * This file is part of the coreboot project.
   3 *
   4 * Copyright (C) 2008 Advanced Micro Devices, Inc.
   5 *
   6 * This program is free software; you can redistribute it and/or modify
   7 * it under the terms of the GNU General Public License as published by
   8 * the Free Software Foundation; version 2 of the License.
   9 *
  10 * This program is distributed in the hope that it will be useful,
  11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13 * GNU General Public License for more details.
  14 *
  15 * You should have received a copy of the GNU General Public License
  16 * along with this program; if not, write to the Free Software
  17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
  18 */
  19
  20/*
  21 *  for rs690 internal graphics device
  22 *  device id of internal grphics:
  23 *      RS690M/T: 0x791f
  24 *    RS690:       0x791e
  25 */
  26#include <types.h>
  27#include <lib.h>
  28#include <console.h>
  29#include <device/pci.h>
  30#include <msr.h>
  31#include <legacy.h>
  32#include <device/pci_ids.h>
  33#include <statictree.h>
  34#include <config.h>
  35#include "rs690.h"
  36
  37#define CLK_CNTL_INDEX  0x8
  38#define CLK_CNTL_DATA   0xC
  39
  40static u32 clkind_read(struct device * dev, u32 index)
  41{
  42        u32 gfx_bar2 = pci_read_config32(dev, PCI_BASE_ADDRESS_2) & ~0xF;
  43
  44        *(u32*)(gfx_bar2+CLK_CNTL_INDEX) = index & 0x7F;
  45        return *(u32*)(gfx_bar2+CLK_CNTL_DATA);
  46}
  47
  48static void clkind_write(struct device * dev, u32 index, u32 data)
  49{
  50        u32 gfx_bar2 = pci_read_config32(dev, PCI_BASE_ADDRESS_2) & ~0xF;
  51        /* printk(BIOS_INFO, "gfx bar 2 %02x\n", gfx_bar2); */
  52
  53        *(u32*)(gfx_bar2+CLK_CNTL_INDEX) = index | 1<<7;
  54        *(u32*)(gfx_bar2+CLK_CNTL_DATA)  = data;
  55}
  56
  57/*
  58* pci_dev_read_resources thinks it is a IO type.
  59* We have to force it to mem type.
  60*/
  61static void rs690_gfx_read_resources(struct device * dev)
  62{
  63        printk(BIOS_INFO, "rs690_gfx_read_resources.\n");
  64
  65        /* The initial value of 0x24 is 0xFFFFFFFF, which is confusing.
  66           Even if we write 0xFFFFFFFF into it, it will be 0xFFF00000,
  67           which tells us it is a memory address base.
  68         */
  69        pci_write_config32(dev, PCI_BASE_ADDRESS_5, 0x00000000);
  70
  71        /* Get the normal pci resources of this device */
  72        pci_dev_read_resources(dev);
  73        compact_resources(dev);
  74}
  75
  76static void internal_gfx_pci_dev_init(struct device *dev)
  77{
  78        unsigned short deviceid, vendorid;
  79        struct southbridge_amd_rs690_gfx_config *cfg = dev->device_configuration;
  80        deviceid = pci_read_config16(dev, PCI_DEVICE_ID);
  81        vendorid = pci_read_config16(dev, PCI_VENDOR_ID);
  82        printk(BIOS_INFO, "internal_gfx_pci_dev_init device=%x, vendor=%x, vga_rom_address=0x%lx.\n",
  83             deviceid, vendorid, cfg->vga_rom_address);
  84
  85        pci_dev_init(dev);
  86
  87        /* clk ind */
  88        clkind_write(dev, 0x08, 0x01);
  89        clkind_write(dev, 0x0C, 0x22);
  90        clkind_write(dev, 0x0F, 0x0);
  91        clkind_write(dev, 0x11, 0x0);
  92        clkind_write(dev, 0x12, 0x0);
  93        clkind_write(dev, 0x14, 0x0);
  94        clkind_write(dev, 0x15, 0x0);
  95        clkind_write(dev, 0x16, 0x0);
  96        clkind_write(dev, 0x17, 0x0);
  97        clkind_write(dev, 0x18, 0x0);
  98        clkind_write(dev, 0x19, 0x0);
  99        clkind_write(dev, 0x1A, 0x0);
 100        clkind_write(dev, 0x1B, 0x0);
 101        clkind_write(dev, 0x1C, 0x0);
 102        clkind_write(dev, 0x1D, 0x0);
 103        clkind_write(dev, 0x1E, 0x0);
 104        clkind_write(dev, 0x26, 0x0);
 105        clkind_write(dev, 0x27, 0x0);
 106        clkind_write(dev, 0x28, 0x0);
 107        clkind_write(dev, 0x5C, 0x0);
 108}
 109
 110static void rs690_gfx_set_resources(struct device *dev)
 111{
 112#warning This does nothing.  Implement it or remove it.
 113        printk(BIOS_INFO, "rs690_gfx_set_resources.\n");
 114        pci_set_resources(dev);
 115}
 116
 117/*
 118* Set registers in RS690 and CPU to enable the internal GFX.
 119* Please refer to CIM source code and BKDG.
 120* Does this enable for pci scanning or enable for operation? 
 121*/
 122static void rs690_internal_gfx_enable(struct device * dev)
 123{
 124        u32 l_dword;
 125        int i;
 126        struct device * k8_f0 = 0, *k8_f2 = 0;
 127        struct device * nb_dev = dev_find_slot(0, 0);
 128
 129        printk(BIOS_INFO, "rs690_internal_gfx_enable dev=%p, nb_dev=%p.\n", dev,
 130                    nb_dev);
 131
 132        /* set APERTURE_SIZE, 128M. */
 133        l_dword = pci_read_config32(nb_dev, 0x8c);
 134        printk(BIOS_INFO, "nb_dev, 0x8c=0x%x\n", l_dword);
 135        l_dword &= 0xffffff8f;
 136        pci_write_config32(nb_dev, 0x8c, l_dword);
 137
 138        /* set TOM */
 139        rs690_set_tom(nb_dev);
 140        
 141        /* LPC DMA Deadlock workaround? */
 142        k8_f0 = dev_find_slot(0, PCI_DEVFN(0x18, 0));
 143        l_dword = pci_read_config32(k8_f0, 0x68);
 144        l_dword &= ~(1 << 22);
 145        l_dword |= (1 << 21);
 146        pci_write_config32(k8_f0, 0x68, l_dword);
 147
 148        /* Enable 64bit mode. */
 149        set_nbmc_enable_bits(nb_dev, 0x5f, 0, 1 << 9);
 150        set_nbmc_enable_bits(nb_dev, 0xb0, 0, 1 << 8);
 151
 152        /* 64bit Latency. */
 153        set_nbmc_enable_bits(nb_dev, 0x5f, 0x7c00, 0x800);
 154
 155        /* UMA dual channel control register. */
 156        nbmc_write_index(nb_dev, 0x86, 0x3d);
 157
 158        /* check the setting later!! */
 159        set_htiu_enable_bits(nb_dev, 0x07, 1 << 7, 0);
 160
 161        /* UMA mode, powerdown memory PLL. */
 162        set_nbmc_enable_bits(nb_dev, 0x74, 0, 1 << 31);
 163
 164        /* Copy CPU DDR Controller to NB MC. */
 165        /* Why K8_MC_REG80 is special? */
 166        k8_f2 = dev_find_slot(0, PCI_DEVFN(0x18, 2));
 167        for (i = 0; i <= (0x80 - 0x40) / 4; i++) {
 168                l_dword = pci_read_config32(k8_f2, 0x40 + i * 4);
 169                nbmc_write_index(nb_dev, 0x63 + i, l_dword);
 170        }
 171
 172        /* Set K8 MC for UMA, Family F. */
 173        l_dword = pci_read_config32(k8_f2, 0xa0);
 174        l_dword |= 0x2c;
 175        pci_write_config32(k8_f2, 0xa0, l_dword);
 176        l_dword = pci_read_config32(k8_f2, 0x94);
 177        l_dword &= 0xf0ffffff;
 178        l_dword |= 0x07000000;
 179        pci_write_config32(k8_f2, 0x94, l_dword);
 180
 181        /* set FB size and location. */
 182        nbmc_write_index(nb_dev, 0x1b, 0x00);
 183        l_dword = nbmc_read_index(nb_dev, 0x1c);
 184        l_dword &= 0xffff0;
 185        l_dword |= 0x400 << 20;
 186        l_dword |= 0x4;
 187        nbmc_write_index(nb_dev, 0x1c, l_dword);
 188        l_dword = nbmc_read_index(nb_dev, 0x1d);
 189        l_dword &= 0xfffff000;
 190        l_dword |= 0x0400;
 191        nbmc_write_index(nb_dev, 0x1d, l_dword);
 192        nbmc_write_index(nb_dev, 0x100, 0x3fff3800);
 193
 194        /* Program MC table. */
 195        set_nbmc_enable_bits(nb_dev, 0x00, 0, 1 << 31);
 196        l_dword = nbmc_read_index(nb_dev, 0x91);
 197        l_dword |= 0x5;
 198        nbmc_write_index(nb_dev, 0x91, l_dword);
 199        set_nbmc_enable_bits(nb_dev, 0xb1, 0, 1 << 6);
 200        set_nbmc_enable_bits(nb_dev, 0xc3, 0, 1);
 201
 202        /* TODO: the optimization of voltage and frequency */
 203}
 204
 205static struct pci_operations lops_pci = {
 206        .set_subsystem = pci_dev_set_subsystem,
 207};
 208
 209/* step 12 ~ step 14 from rpr */
 210static void single_port_configuration(struct device * nb_dev, struct device * dev)
 211{
 212        u8 result, width;
 213        u32 reg32;
 214        struct southbridge_amd_rs690_gfx_config *cfg = nb_dev->device_configuration;
 215
 216        printk(BIOS_INFO, "rs690_gfx_init single_port_configuration.\n");
 217
 218        /* step 12 training, releases hold training for GFX port 0 (device 2) */
 219        set_nbmisc_enable_bits(nb_dev, 0x8, 1 << 4, 0<<4);
 220        PcieReleasePortTraining(nb_dev, dev, 2);
 221        result = PcieTrainPort(nb_dev, dev, 2);
 222        printk(BIOS_INFO, "rs690_gfx_init single_port_configuration step12.\n");
 223
 224        /* step 13 Power Down Control */
 225        /* step 13.1 Enables powering down transmitter and receiver pads along with PLL macros. */
 226        set_pcie_enable_bits(nb_dev, 0x40, 1 << 0, 1 << 0);
 227
 228        /* step 13.a Link Training was NOT successful */
 229        if (!result) {
 230                set_nbmisc_enable_bits(nb_dev, 0x8, 0, 0x3 << 4); /* prevent from training. */
 231                set_nbmisc_enable_bits(nb_dev, 0xc, 0, 0x3 << 2); /* hide the GFX bridge. */
 232                if (cfg->gfx_tmds)
 233                        nbpcie_ind_write_index(nb_dev, 0x65, 0xccf0f0);
 234                else {
 235                        nbpcie_ind_write_index(nb_dev, 0x65, 0xffffffff);
 236                        set_nbmisc_enable_bits(nb_dev, 0x7, 1 << 3, 1 << 3);
 237                }
 238        } else {                /* step 13.b Link Training was successful */
 239
 240                reg32 = nbpcie_p_read_index(dev, 0xa2);
 241                width = (reg32 >> 4) & 0x7;
 242                printk(BIOS_DEBUG, "GFX LC_LINK_WIDTH = 0x%x.\n", width);
 243                switch (width) {
 244                case 1:
 245                case 2:
 246                        nbpcie_ind_write_index(nb_dev, 0x65,
 247                                               cfg->gfx_lane_reversal ? 0x7f7f : 0xccfefe);
 248                        break;
 249                case 4:
 250                        nbpcie_ind_write_index(nb_dev, 0x65,
 251                                               cfg->gfx_lane_reversal ? 0x3f3f : 0xccfcfc);
 252                        break;
 253                case 8:
 254                        nbpcie_ind_write_index(nb_dev, 0x65,
 255                                               cfg->gfx_lane_reversal ? 0x0f0f : 0xccf0f0);
 256                        break;
 257                }
 258        }
 259        printk(BIOS_INFO, "rs690_gfx_init single_port_configuration step13.\n");
 260
 261        /* step 14 Reset Enumeration Timer, disables the shortening of the enumeration timer */
 262        set_pcie_enable_bits(dev, 0x70, 1 << 19, 0 << 19);
 263        printk(BIOS_INFO, "rs690_gfx_init single_port_configuration step14.\n");
 264}
 265
 266/* step 15 ~ step 18 from rpr */
 267static void dual_port_configuration(struct device * nb_dev, struct device * dev)
 268{
 269        u8 result, width;
 270        u32 reg32;
 271        struct southbridge_amd_rs690_gfx_config *cfg = nb_dev->device_configuration;
 272
 273        /* step 15: Training for Device 2 */
 274        set_nbmisc_enable_bits(nb_dev, 0x8, 1 << 4, 0 << 4);
 275        /* Releases hold training for GFX port 0 (device 2) */
 276        PcieReleasePortTraining(nb_dev, dev, 2);
 277        /* PCIE Link Training Sequence */
 278        result = PcieTrainPort(nb_dev, dev, 2);
 279
 280        /* step 16: Power Down Control for Device 2 */
 281        /* step 16.a Link Training was NOT successful */
 282        if (!result) {
 283                /* Powers down all lanes for port A */
 284                nbpcie_ind_write_index(nb_dev, 0x65, 0x0f0f);
 285        } else {                /* step 16.b Link Training was successful */
 286
 287                reg32 = nbpcie_p_read_index(dev, 0xa2);
 288                width = (reg32 >> 4) & 0x7;
 289                printk(BIOS_DEBUG, "GFX LC_LINK_WIDTH = 0x%x.\n", width);
 290                switch (width) {
 291                case 1:
 292                case 2:
 293                        nbpcie_ind_write_index(nb_dev, 0x65,
 294                                               cfg->gfx_lane_reversal ? 0x0707 : 0x0e0e);
 295                        break;
 296                case 4:
 297                        nbpcie_ind_write_index(nb_dev, 0x65,
 298                                               cfg->gfx_lane_reversal ? 0x0303 : 0x0c0c);
 299                        break;
 300                }
 301        }
 302
 303        /* step 17: Training for Device 3 */
 304        set_nbmisc_enable_bits(nb_dev, 0x8, 1 << 5, 0 << 5);
 305        /* Releases hold training for GFX port 0 (device 3) */
 306        PcieReleasePortTraining(nb_dev, dev, 3);
 307        /* PCIE Link Training Sequence */
 308        result = PcieTrainPort(nb_dev, dev, 3);
 309
 310        /*step 18: Power Down Control for Device 3 */
 311        /* step 18.a Link Training was NOT successful */
 312        if (!result) {
 313                /* Powers down all lanes for port B and PLL1 */
 314                nbpcie_ind_write_index(nb_dev, 0x65, 0xccf0f0);
 315        } else {                /* step 18.b Link Training was successful */
 316
 317                reg32 = nbpcie_p_read_index(dev, 0xa2);
 318                width = (reg32 >> 4) & 0x7;
 319                printk(BIOS_DEBUG, "GFX LC_LINK_WIDTH = 0x%x.\n", width);
 320                switch (width) {
 321                case 1:
 322                case 2:
 323                        nbpcie_ind_write_index(nb_dev, 0x65,
 324                                               cfg->gfx_lane_reversal ? 0x7070 : 0xe0e0);
 325                        break;
 326                case 4:
 327                        nbpcie_ind_write_index(nb_dev, 0x65,
 328                                               cfg->gfx_lane_reversal ? 0x3030 : 0xc0c0);
 329                        break;
 330                }
 331        }
 332}
 333
 334
 335/* For single port GFX configuration Only 
 336* width:
 337*       000 = x16
 338*       001 = x1
 339*       010 = x2
 340*       011 = x4
 341*       100 = x8
 342*       101 = x12 (not supported)
 343*       110 = x16
 344*/
 345static void dynamic_link_width_control(struct device * nb_dev, struct device * dev, u8 width)
 346{
 347        u32 reg32;
 348        struct device * sb_dev;
 349        struct southbridge_amd_rs690_gfx_config *cfg = nb_dev->device_configuration;
 350
 351        /* step 5.9.1.1 */
 352        reg32 = nbpcie_p_read_index(dev, 0xa2);
 353
 354        /* step 5.9.1.2 */
 355        set_pcie_enable_bits(nb_dev, 0x40, 1 << 0, 1 << 0);
 356        /* step 5.9.1.3 */
 357        set_pcie_enable_bits(dev, 0xa2, 3 << 0, width << 0);
 358        /* step 5.9.1.4 */
 359        set_pcie_enable_bits(dev, 0xa2, 1 << 8, 1 << 8);
 360        /* step 5.9.2.4 */
 361        if (0 == cfg->gfx_reconfiguration)
 362                set_pcie_enable_bits(dev, 0xa2, 1 << 11, 1 << 11);
 363
 364        /* step 5.9.1.5 */
 365        do {
 366                reg32 = nbpcie_p_read_index(dev, 0xa2);
 367        }
 368        while (reg32 & 0x100);
 369
 370        /* step 5.9.1.6 */
 371        sb_dev = dev_find_slot(0, PCI_DEVFN(8, 0));
 372        do {
 373                reg32 = pci_ext_read_config32(nb_dev, sb_dev,
 374                                          PCIE_VC0_RESOURCE_STATUS);
 375        } while (reg32 & VC_NEGOTIATION_PENDING);
 376
 377        /* step 5.9.1.7 */
 378        reg32 = nbpcie_p_read_index(dev, 0xa2);
 379        if (((reg32 & 0x70) >> 4) != 0x6) {
 380                /* the unused lanes should be powered off. */
 381        }
 382
 383        /* step 5.9.1.8 */
 384        set_pcie_enable_bits(nb_dev, 0x40, 1 << 0, 0 << 0);
 385}
 386
 387/*
 388* GFX Core initialization, dev2, dev3
 389*/
 390void rs690_gfx_init(struct device * nb_dev, struct device * dev, u32 port)
 391{
 392        u16 reg16;
 393        struct southbridge_amd_rs690_gfx_config *cfg = nb_dev->device_configuration;
 394
 395        printk(BIOS_INFO, "rs690_gfx_init, nb_dev=%p dev=%p, port=0x%x.\n",
 396                    nb_dev, dev, port);
 397
 398        /* step 0, REFCLK_SEL, skip A11 revision */
 399        set_nbmisc_enable_bits(nb_dev, 0x6a, 1 << 9,
 400                               cfg->gfx_dev2_dev3 ? 1 << 9 : 0 << 9);
 401        printk(BIOS_INFO, "rs690_gfx_init step0.\n");
 402
 403        /* step 1, lane reversal (only need if CMOS option is enabled) */
 404        if (cfg->gfx_lane_reversal) {
 405                set_nbmisc_enable_bits(nb_dev, 0x33, 1 << 2, 1 << 2);
 406                if (cfg->gfx_dual_slot)
 407                        set_nbmisc_enable_bits(nb_dev, 0x33, 1 << 3, 1 << 3);
 408        }
 409        printk(BIOS_INFO, "rs690_gfx_init step1.\n");
 410
 411        /* step 1.1, dual-slot gfx configuration (only need if CMOS option is enabled) */
 412        /* AMD calls the configuration CrossFire */
 413        if (cfg->gfx_dual_slot)
 414                set_nbmisc_enable_bits(nb_dev, 0x0, 0xf << 8, 5 << 8);
 415        printk(BIOS_INFO, "rs690_gfx_init step2.\n");
 416
 417        /* step 2, TMDS, (only need if CMOS option is enabled) */
 418        if (cfg->gfx_tmds) {
 419        }
 420
 421        /* step 3, GFX overclocking, (only need if CMOS option is enabled) */
 422        /* skip */
 423
 424        /* step 4, reset the GFX link */
 425        /* step 4.1 asserts both calibration reset and global reset */
 426        set_nbmisc_enable_bits(nb_dev, 0x8, 0x3 << 14, 0x3 << 14);
 427
 428        /* step 4.2 de-asserts calibration reset */
 429        set_nbmisc_enable_bits(nb_dev, 0x8, 1 << 14, 0 << 14);
 430
 431        /* step 4.3 wait for at least 200us */
 432        udelay(200);
 433
 434        /* step 4.4 de-asserts global reset */
 435        set_nbmisc_enable_bits(nb_dev, 0x8, 1 << 15, 0 << 15);
 436
 437        /* step 4.5 asserts both calibration reset and global reset */
 438        /* a weird step in RPR, don't do that */
 439        /* set_nbmisc_enable_bits(nb_dev, 0x8, 0x3 << 14, 0x3 << 14); */
 440
 441        /* step 4.6 bring external GFX device out of reset, wait for 1ms */
 442        mdelay(1);
 443        printk(BIOS_INFO, "rs690_gfx_init step4.\n");
 444
 445        /* step 5 program PCIE memory mapped configuration space */
 446        /* done by enable_pci_bar3() before */
 447
 448        /* step 6 SBIOS compile flags */
 449
 450        /* step 7 compliance state, (only need if CMOS option is enabled) */
 451        /* the compliance stete is just for test. refer to 4.2.5.2 of PCIe specification */
 452        if (cfg->gfx_compliance) {
 453                /* force compliance */
 454                set_nbmisc_enable_bits(nb_dev, 0x32, 1 << 6, 1 << 6);
 455                /* release hold training for device 2. GFX initialization is done. */
 456                set_nbmisc_enable_bits(nb_dev, 0x8, 1 << 4, 0 << 4);
 457                dynamic_link_width_control(nb_dev, dev, cfg->gfx_link_width);
 458                printk(BIOS_INFO, "rs690_gfx_init step7.\n");
 459                return;
 460        }
 461
 462        /* step 8 common initialization */
 463        /* step 8.1 sets RCB timeout to be 25ms */
 464        set_pcie_enable_bits(dev, 0x70, 7 << 16, 3 << 16);
 465        printk(BIOS_INFO, "rs690_gfx_init step8.1.\n");
 466
 467        /* step 8.2 disables slave ordering logic */
 468        set_pcie_enable_bits(nb_dev, 0x20, 1 << 8, 1 << 8);
 469        printk(BIOS_INFO, "rs690_gfx_init step8.2.\n");
 470
 471        /* step 8.3 sets DMA payload size to 64 bytes */
 472        set_pcie_enable_bits(nb_dev, 0x10, 7 << 10, 4 << 10);
 473        printk(BIOS_INFO, "rs690_gfx_init step8.3.\n");
 474
 475        /* step 8.4 if the LTSSM could not see all 8 TS1 during Polling Active, it can still 
 476         * time out and go back to Detect Idle.*/
 477        set_pcie_enable_bits(dev, 0x02, 1 << 14, 1 << 14);
 478        printk(BIOS_INFO, "rs690_gfx_init step8.4.\n");
 479
 480        /* step 8.5 shortens the enumeration timer */
 481        set_pcie_enable_bits(dev, 0x70, 1 << 19, 1 << 19);
 482        printk(BIOS_INFO, "rs690_gfx_init step8.5.\n");
 483
 484        /* step 8.6 blocks DMA traffic during C3 state */
 485        set_pcie_enable_bits(dev, 0x10, 1 << 0, 0 << 0);
 486        printk(BIOS_INFO, "rs690_gfx_init step8.6.\n");
 487
 488        /* step 8.7 Do not gate the electrical idle form the PHY
 489         * step 8.8 Enables the escape from L1L23 */
 490        set_pcie_enable_bits(dev, 0xa0, 3 << 30, 3 << 30);
 491        printk(BIOS_INFO, "rs690_gfx_init step8.8.\n");
 492
 493        /* step 8.9 Setting this register to 0x1 will workaround a PCI Compliance failure reported by Vista DTM. 
 494         * SLOT_IMPLEMENTED@PCIE_CAP */
 495        reg16 = pci_read_config16(dev, 0x5a);
 496        reg16 |= 0x100;
 497        pci_write_config16(dev, 0x5a, reg16);
 498        printk(BIOS_INFO, "rs690_gfx_init step8.9.\n");
 499
 500        /* step 8.10 Setting this register to 0x1 will hide the Advanced Error Rporting Capabilities in the PCIE Brider.
 501         * This will workaround several failures reported by the PCI Compliance test under Vista DTM. */
 502        set_nbmisc_enable_bits(nb_dev, 0x33, 1 << 31, 0 << 31);
 503        printk(BIOS_INFO, "rs690_gfx_init step8.10.\n");
 504
 505        /* step 8.11 Sets REGS_DLP_IGNORE_IN_L1_EN to ignore DLLPs during L1 so that txclk can be turned off. */
 506        set_pcie_enable_bits(nb_dev, 0x02, 1 << 0, 1 << 0);
 507        printk(BIOS_INFO, "rs690_gfx_init step8.11.\n");
 508
 509        /* step 8.12 Sets REGS_LC_DONT_GO_TO_L0S_IF_L1_ARMED to prevent lc to go to from L0 to Rcv_L0s if L1 is armed. */
 510        set_pcie_enable_bits(nb_dev, 0x02, 1 << 6, 1 << 6);
 511        printk(BIOS_INFO, "rs690_gfx_init step8.12.\n");
 512
 513        /* step 8.13 Sets CMGOOD_OVERRIDE. */
 514        set_nbmisc_enable_bits(nb_dev, 0x6a, 1 << 17, 1 << 17);
 515        printk(BIOS_INFO, "rs690_gfx_init step8.13.\n");
 516
 517        /* step 9 Enable TLP Flushing, for non-AMD GFX devices and Hot-Plug devices only. */
 518        /* skip */
 519
 520        /* step 10 Optional Features, only needed if CMOS option is enabled. */
 521        /* step 10.a: L0s */
 522        /* enabling L0s in the RS690 GFX port(s) */
 523        set_pcie_enable_bits(nb_dev, 0xF9, 3 << 13, 2 << 13);
 524        set_pcie_enable_bits(dev, 0xA0, 0xf << 8, 8 << 8);
 525        reg16 = pci_read_config16(dev, 0x68);
 526        reg16 |= 1 << 0;
 527        /* L0s is intended as a power saving state */
 528        /* pci_write_config16(dev, 0x68, reg16); */
 529
 530        /* enabling L0s in the External GFX Device(s) */
 531
 532        /* step 10.b: active state power management (ASPM L1) */
 533        /* TO DO */
 534
 535        /* step 10.c: turning off PLL During L1/L23 */
 536        set_pcie_enable_bits(nb_dev, 0x40, 1 << 3, 1 << 3);
 537        set_pcie_enable_bits(nb_dev, 0x40, 1 << 9, 1 << 9);
 538
 539        /* step 10.d: TXCLK clock gating */
 540        set_nbmisc_enable_bits(nb_dev, 0x7, 3, 3);
 541        set_nbmisc_enable_bits(nb_dev, 0x7, 1 << 22, 1 << 22);
 542        set_pcie_enable_bits(nb_dev, 0x11, 0xf << 4, 0xc << 4);
 543
 544        /* step 10.e: LCLK clock gating, done in rs690_config_misc_clk() */
 545
 546        /* step 11 Poll GPIO to determine whether it is single-port or dual-port configuration.  
 547         * While details will be added later in the document, for now assue the single-port configuration. */
 548        /* skip */
 549
 550        /* Single-port/Dual-port configureation. */
 551        switch (cfg->gfx_dual_slot) {
 552        case 0:
 553                single_port_configuration(nb_dev, dev);
 554                break;
 555        case 1:
 556                dual_port_configuration(nb_dev, dev);
 557                break;
 558        default:
 559                printk(BIOS_INFO, "Incorrect configuration of external gfx slot.\n");
 560                break;
 561        }
 562}
 563
 564struct device_operations rs690_gfx = {
 565        .id = {.type = DEVICE_ID_PCI,
 566                {.pci = {.vendor = PCI_VENDOR_ID_ATI,
 567                         .device = PCI_DEVICE_ID_ATI_RS690MT_INT_GFX}}},
 568        .constructor             = default_device_constructor,
 569        .phase3_chip_setup_dev   = rs690_enable,
 570        .phase3_enable           = rs690_internal_gfx_enable,
 571        .phase3_scan             = 0,
 572        .phase4_read_resources   = rs690_gfx_read_resources,
 573        .phase4_set_resources    = rs690_gfx_set_resources,
 574        .phase5_enable_resources = pci_dev_enable_resources,
 575        .phase6_init             = internal_gfx_pci_dev_init,
 576        .ops_pci                 = &lops_pci,
 577};
 578
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.