coreboot-v3/southbridge/nvidia/ck804/ck804.c
<<
>>
Prefs
   1/*
   2 * Copyright 2004 Tyan Computer
   3 *  by yhlu@tyan.com
   4 */
   5
   6#include <console.h>
   7#include <io.h>
   8#include <device/device.h>
   9#include <device/pci.h>
  10#include <device/pci_ids.h>
  11#include <device/pci_ops.h>
  12#include "ck804.h"
  13
  14static u32 final_reg;
  15
  16void ck804_set_subsystem(struct device *dev, u16 vendor, u16 device)
  17{
  18        pci_write_config32(dev, 0x40, (device << 16) | vendor);
  19}
  20
  21static struct device * find_lpc_dev(struct device * dev, unsigned devfn)
  22{
  23        struct device * lpc_dev;
  24
  25        lpc_dev = dev_find_slot(dev->bus->secondary, devfn);
  26        if (!lpc_dev)
  27                return lpc_dev;
  28
  29        if ((lpc_dev->id.pci.vendor != PCI_VENDOR_ID_NVIDIA)
  30                || ((lpc_dev->id.pci.device != PCI_DEVICE_ID_NVIDIA_CK804_LPC)
  31                && (lpc_dev->id.pci.device != PCI_DEVICE_ID_NVIDIA_CK804_PRO)
  32                && (lpc_dev->id.pci.device != PCI_DEVICE_ID_NVIDIA_CK804_SLAVE)))
  33        {
  34                u32 id;
  35                id = pci_read_config32(lpc_dev, PCI_VENDOR_ID);
  36                if ((id != (PCI_VENDOR_ID_NVIDIA |
  37                      (PCI_DEVICE_ID_NVIDIA_CK804_LPC << 16)))
  38                    && (id != (PCI_VENDOR_ID_NVIDIA |
  39                         (PCI_DEVICE_ID_NVIDIA_CK804_PRO << 16)))
  40                    && (id != (PCI_VENDOR_ID_NVIDIA |
  41                         (PCI_DEVICE_ID_NVIDIA_CK804_SLAVE << 16))))
  42                {
  43                        lpc_dev = 0;
  44                }
  45        }
  46
  47        return lpc_dev;
  48}
  49
  50void ck804_enable(struct device * dev)
  51{
  52        struct device * lpc_dev;
  53        unsigned index = 0, index2 = 0;
  54        u32 vendorid;
  55        u16 deviceid, devfn;
  56        u32 reg_old, reg;
  57        u8 byte;
  58
  59        if (dev->id.pci.device == 0x0000) {
  60                vendorid = pci_read_config32(dev, PCI_VENDOR_ID);
  61                deviceid = (vendorid >> 16) & 0xffff;
  62                /* vendorid &= 0xffff; */
  63        } else {
  64                /* vendorid = dev->id.pci.vendor; */
  65                deviceid = dev->id.pci.device;
  66        }
  67
  68        devfn = (dev->path.pci.devfn) & ~7;
  69        switch (deviceid) {
  70        case PCI_DEVICE_ID_NVIDIA_CK804_SM:
  71                index = 16;
  72                break;
  73        case PCI_DEVICE_ID_NVIDIA_CK804_USB:
  74                devfn -= (1 << 3);
  75                index = 8;
  76                break;
  77        case PCI_DEVICE_ID_NVIDIA_CK804_USB2:
  78                devfn -= (1 << 3);
  79                index = 20;
  80                break;
  81        case PCI_DEVICE_ID_NVIDIA_CK804_NIC:
  82                devfn -= (9 << 3);
  83                index = 10;
  84                break;
  85        case PCI_DEVICE_ID_NVIDIA_CK804_NIC_BRIDGE:
  86                devfn -= (9 << 3);
  87                index = 10;
  88                break;
  89        case PCI_DEVICE_ID_NVIDIA_CK804_ACI:
  90                devfn -= (3 << 3);
  91                index = 12;
  92                break;
  93        case PCI_DEVICE_ID_NVIDIA_CK804_MCI:
  94                devfn -= (3 << 3);
  95                index = 13;
  96                break;
  97        case PCI_DEVICE_ID_NVIDIA_CK804_IDE:
  98                devfn -= (5 << 3);
  99                index = 14;
 100                break;
 101        case PCI_DEVICE_ID_NVIDIA_CK804_SATA0:
 102                devfn -= (6 << 3);
 103                index = 22;
 104                break;
 105        case PCI_DEVICE_ID_NVIDIA_CK804_SATA1:
 106                devfn -= (7 << 3);
 107                index = 18;
 108                break;
 109        case PCI_DEVICE_ID_NVIDIA_CK804_PCI:
 110                devfn -= (8 << 3);
 111                index = 15;
 112                break;
 113        case PCI_DEVICE_ID_NVIDIA_CK804_PCI_E:
 114                devfn -= (0xa << 3);
 115                index2 = 19;
 116                break;
 117        default:
 118                index = 0;
 119        }
 120
 121        if (index2 != 0) {
 122                int i;
 123                for (i = 0; i < 4; i++) {
 124                        lpc_dev = find_lpc_dev(dev, devfn - (i << 3));
 125                        if (!lpc_dev)
 126                                continue;
 127                        index2 -= i;
 128                        break;
 129                }
 130
 131                if (lpc_dev) {
 132                        reg_old = reg = pci_read_config32(lpc_dev, 0xe4);
 133                        if (!dev->enabled)
 134                                reg |= (1 << index2);
 135                        if (reg != reg_old)
 136                                pci_write_config32(lpc_dev, 0xe4, reg);
 137                }
 138
 139                index2 = 0;
 140                return;
 141        }
 142
 143        lpc_dev = find_lpc_dev(dev, devfn);
 144        if (!lpc_dev)
 145                return;
 146
 147        if (index == 0) {
 148                final_reg = pci_read_config32(lpc_dev, 0xe8);
 149                final_reg &= ~((1 << 16) | (1 << 8) | (1 << 20) | (1 << 10)
 150                        | (1 << 12) | (1 << 13) | (1 << 14) | (1 << 22)
 151                        | (1 << 18) | (1 << 15));
 152                pci_write_config32(lpc_dev, 0xe8, final_reg);
 153
 154                reg_old = reg = pci_read_config32(lpc_dev, 0xe4);
 155                reg |= (1 << 20);
 156                if (reg != reg_old)
 157                        pci_write_config32(lpc_dev, 0xe4, reg);
 158
 159                byte = pci_read_config8(lpc_dev, 0x74);
 160                byte |= ((1 << 1));
 161                pci_write_config8(dev, 0x74, byte);
 162
 163                byte = pci_read_config8(lpc_dev, 0xdd);
 164                byte |= ((1 << 0) | (1 << 3));
 165                pci_write_config8(dev, 0xdd, byte);
 166
 167                return;
 168        }
 169
 170        if (!dev->enabled)
 171                final_reg |= (1 << index);
 172
 173        if (index == 10) {
 174                reg_old = pci_read_config32(lpc_dev, 0xe8);
 175                if (final_reg != reg_old)
 176                        pci_write_config32(lpc_dev, 0xe8, final_reg);
 177        }
 178}
 179
 180struct pci_operations ck804_ops_pci = {
 181        .set_subsystem = ck804_set_subsystem,
 182};
 183
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.