blob: f57952ede05462ae5f64bdcc81792daec3a0c681 [file] [log] [blame]
Martin Rothebace9f2018-05-26 18:56:17 -06001/*
2 * This file is part of the coreboot project.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; version 2 of the License.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 */
13
Eric Biederman83b991a2003-10-11 06:20:25 +000014#include <console/console.h>
15#include <device/device.h>
16#include <device/pci.h>
17#include <device/pci_ids.h>
Eric Biederman83b991a2003-10-11 06:20:25 +000018#include "amd8111.h"
19
Elyes HAOUAS39733a02018-05-19 14:45:20 +020020void amd8111_enable(struct device *dev)
Eric Biederman83b991a2003-10-11 06:20:25 +000021{
Elyes HAOUAS39733a02018-05-19 14:45:20 +020022 struct device *lpc_dev;
23 struct device *bus_dev;
Eric Biederman83b991a2003-10-11 06:20:25 +000024 unsigned index;
Eric Biedermandbec2d42004-10-21 10:44:08 +000025 unsigned reg_old, reg;
Yinghai Luf19e2c72004-10-21 01:52:21 +000026
Myles Watson43bb9cd2008-12-18 18:24:11 +000027 /* See if we are on the bus behind the amd8111 pci bridge */
Eric Biederman83b991a2003-10-11 06:20:25 +000028 bus_dev = dev->bus->dev;
Stefan Reinauer14e22772010-04-27 06:56:47 +000029 if ((bus_dev->vendor == PCI_VENDOR_ID_AMD) &&
30 (bus_dev->device == PCI_DEVICE_ID_AMD_8111_PCI))
Eric Biedermandbec2d42004-10-21 10:44:08 +000031 {
Eric Biederman83b991a2003-10-11 06:20:25 +000032 unsigned devfn;
Stefan Reinauer2b34db82009-02-28 20:10:20 +000033 devfn = bus_dev->path.pci.devfn + (1 << 3);
Eric Biederman83b991a2003-10-11 06:20:25 +000034 lpc_dev = dev_find_slot(bus_dev->bus->secondary, devfn);
Stefan Reinauer2b34db82009-02-28 20:10:20 +000035 index = ((dev->path.pci.devfn & ~7) >> 3) + 8;
36 if (dev->path.pci.devfn == 2) { /* EHCI */
Eric Biedermandbec2d42004-10-21 10:44:08 +000037 index = 16;
38 }
Eric Biederman83b991a2003-10-11 06:20:25 +000039 } else {
40 unsigned devfn;
Stefan Reinauer2b34db82009-02-28 20:10:20 +000041 devfn = (dev->path.pci.devfn) & ~7;
Eric Biederman83b991a2003-10-11 06:20:25 +000042 lpc_dev = dev_find_slot(dev->bus->secondary, devfn);
Stefan Reinauer2b34db82009-02-28 20:10:20 +000043 index = dev->path.pci.devfn & 7;
Eric Biederman83b991a2003-10-11 06:20:25 +000044 }
Eric Biedermandbec2d42004-10-21 10:44:08 +000045 if ((!lpc_dev) || (index >= 17)) {
Eric Biederman83b991a2003-10-11 06:20:25 +000046 return;
47 }
Eric Biederman5cd81732004-03-11 15:01:31 +000048 if ((lpc_dev->vendor != PCI_VENDOR_ID_AMD) ||
Stefan Reinauer14e22772010-04-27 06:56:47 +000049 (lpc_dev->device != PCI_DEVICE_ID_AMD_8111_ISA))
Eric Biedermandbec2d42004-10-21 10:44:08 +000050 {
Eric Biederman5cd81732004-03-11 15:01:31 +000051 uint32_t id;
52 id = pci_read_config32(lpc_dev, PCI_VENDOR_ID);
53 if (id != (PCI_VENDOR_ID_AMD | (PCI_DEVICE_ID_AMD_8111_ISA << 16))) {
54 return;
55 }
56 }
Yinghai Lu7ccff4e2004-05-05 18:03:42 +000057
Eric Biedermandbec2d42004-10-21 10:44:08 +000058 if (index < 16) {
59 reg = reg_old = pci_read_config16(lpc_dev, 0x48);
60 reg &= ~(1 << index);
61 if (dev->enabled) {
62 reg |= (1 << index);
Yinghai Lu7ccff4e2004-05-05 18:03:42 +000063 }
Eric Biedermandbec2d42004-10-21 10:44:08 +000064 if (reg != reg_old) {
65 pci_write_config16(lpc_dev, 0x48, reg);
66 }
Yinghai Lu7ccff4e2004-05-05 18:03:42 +000067 }
Eric Biedermandbec2d42004-10-21 10:44:08 +000068 else if (index == 16) {
69 reg = reg_old = pci_read_config8(lpc_dev, 0x47);
70 reg &= ~(1 << 7);
71 if (!dev->enabled) {
72 reg |= (1 << 7);
73 }
74 if (reg != reg_old) {
75 pci_write_config8(lpc_dev, 0x47, reg);
76 }
Eric Biederman83b991a2003-10-11 06:20:25 +000077 }
Eric Biederman83b991a2003-10-11 06:20:25 +000078}
79
Eric Biederman7003ba42004-10-16 06:20:29 +000080struct chip_operations southbridge_amd_amd8111_ops = {
Uwe Hermanna7aa29b2006-11-05 18:50:49 +000081 CHIP_NAME("AMD-8111 Southbridge")
Stefan Reinauer14e22772010-04-27 06:56:47 +000082 /* This only called when this device is listed in the
Jason Schildtab327a32005-10-13 00:44:34 +000083 * static device tree.
84 */
Li-Ta Lo9e17d4f2004-05-13 16:49:53 +000085 .enable_dev = amd8111_enable,
Eric Biederman83b991a2003-10-11 06:20:25 +000086};