blob: 7e8d8c32c41e9e8d7a3f1f6cc94b2c1d4e6b40d9 [file] [log] [blame]
Yinghai Luafd34e62006-02-16 17:22:19 +00001/*
Uwe Hermannc6a10622010-10-17 19:30:58 +00002 * This file is part of the coreboot project.
3 *
4 * Copyright (C) 2005 AMD
5 * Written by Yinghai Lu <yinghai.lu@amd.com> for AMD.
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; version 2 of the License.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
Yinghai Luafd34e62006-02-16 17:22:19 +000015 */
Uwe Hermannc6a10622010-10-17 19:30:58 +000016
Yinghai Luafd34e62006-02-16 17:22:19 +000017#include <console/console.h>
18#include <device/device.h>
19#include <device/pci.h>
20#include <device/pci_ids.h>
21#include "bcm5785.h"
22
23void bcm5785_enable(device_t dev)
24{
25 device_t sb_pci_main_dev;
26 device_t bus_dev;
Stefan Reinauerc51dc442010-04-07 01:44:04 +000027 // unsigned index;
Yinghai Luafd34e62006-02-16 17:22:19 +000028
29 /* See if we are on the behind the pcix bridge */
30 bus_dev = dev->bus->dev;
Stefan Reinauer14e22772010-04-27 06:56:47 +000031 if ((bus_dev->vendor == PCI_VENDOR_ID_SERVERWORKS) &&
Yinghai Luafd34e62006-02-16 17:22:19 +000032 (bus_dev->device == 0x0036 )) // device under PCI-X Bridge
33 {
34 unsigned devfn;
Stefan Reinauer2b34db82009-02-28 20:10:20 +000035 devfn = bus_dev->path.pci.devfn + (1 << 3);
Yinghai Luafd34e62006-02-16 17:22:19 +000036 sb_pci_main_dev = dev_find_slot(bus_dev->bus->secondary, devfn);
Stefan Reinauerc51dc442010-04-07 01:44:04 +000037 // index = ((dev->path.pci.devfn & ~7) >> 3) + 8;
Yinghai Luafd34e62006-02-16 17:22:19 +000038 } else if ((bus_dev->vendor == PCI_VENDOR_ID_SERVERWORKS) &&
39 (bus_dev->device == 0x0104)) // device under PCI Bridge( under PCI-X )
40 {
41 unsigned devfn;
Stefan Reinauer2b34db82009-02-28 20:10:20 +000042 devfn = bus_dev->bus->dev->path.pci.devfn + (1 << 3);
Yinghai Luafd34e62006-02-16 17:22:19 +000043 sb_pci_main_dev = dev_find_slot(bus_dev->bus->dev->bus->secondary, devfn);
Stefan Reinauerc51dc442010-04-07 01:44:04 +000044 // index = ((dev->path.pci.devfn & ~7) >> 3) + 8;
Yinghai Luafd34e62006-02-16 17:22:19 +000045 }
46 else { // same bus
47 unsigned devfn;
Stefan Reinauer2b34db82009-02-28 20:10:20 +000048 devfn = (dev->path.pci.devfn) & ~7;
Stefan Reinauer14e22772010-04-27 06:56:47 +000049 if( dev->vendor == PCI_VENDOR_ID_SERVERWORKS ) {
Yinghai Luafd34e62006-02-16 17:22:19 +000050 if(dev->device == 0x0036) //PCI-X Bridge
51 { devfn += (1<<3); }
52 else if(dev->device == 0x0223) // USB
53 { devfn -= (1<<3); }
54 }
55 sb_pci_main_dev = dev_find_slot(dev->bus->secondary, devfn);
Stefan Reinauerc51dc442010-04-07 01:44:04 +000056 // index = dev->path.pci.devfn & 7;
Yinghai Luafd34e62006-02-16 17:22:19 +000057 }
58 if (!sb_pci_main_dev) {
59 return;
60 }
61
62 // get index now
63#if 0
Stefan Reinauerc51dc442010-04-07 01:44:04 +000064 unsigned reg_old, reg;
Yinghai Luafd34e62006-02-16 17:22:19 +000065 if (index < 16) {
66 reg = reg_old = pci_read_config16(sb_pci_main_dev, 0x48);
67 reg &= ~(1 << index);
68 if (dev->enabled) {
69 reg |= (1 << index);
70 }
71 if (reg != reg_old) {
72 pci_write_config16(sb_pci_main_dev, 0x48, reg);
73 }
74 }
75 else if (index == 16) {
76 reg = reg_old = pci_read_config8(sb_pci_main_dev, 0x47);
77 reg &= ~(1 << 7);
78 if (!dev->enabled) {
79 reg |= (1 << 7);
80 }
81 if (reg != reg_old) {
82 pci_write_config8(sb_pci_main_dev, 0x47, reg);
83 }
84 }
85#endif
86}
87
88struct chip_operations southbridge_broadcom_bcm5785_ops = {
Uwe Hermanna7aa29b2006-11-05 18:50:49 +000089 CHIP_NAME("Serverworks BCM5785 Southbridge")
Yinghai Luafd34e62006-02-16 17:22:19 +000090 .enable_dev = bcm5785_enable,
91};