blob: 25997d2e9d6fbb4f8a0550fc1133b4acf88bde74 [file] [log] [blame]
zbao246e84b2012-07-13 18:47:03 +08001/*
2 * This file is part of the coreboot project.
3 *
4 * Copyright (C) 2010 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.
zbao246e84b2012-07-13 18:47:03 +080014 */
15
16#include <console/console.h>
Kyösti Mälkki13f66502019-03-03 08:01:05 +020017#include <device/mmio.h>
zbao246e84b2012-07-13 18:47:03 +080018#include <device/device.h>
19#include <device/pci.h>
Kyösti Mälkki0bc06ab2018-05-20 15:41:05 +030020#include <device/pci_def.h>
zbao246e84b2012-07-13 18:47:03 +080021#include <device/pci_ids.h>
22#include <device/pci_ops.h>
zbao246e84b2012-07-13 18:47:03 +080023#include "hudson.h"
Kyösti Mälkki29d9c562014-10-16 21:35:48 +030024#include "imc.h"
zbao246e84b2012-07-13 18:47:03 +080025#include "smbus.h"
Alexandru Gagniuc86777e32014-04-20 14:36:29 -050026#include "smi.h"
zbao246e84b2012-07-13 18:47:03 +080027
Alexandru Gagniuc342ac642014-04-14 16:44:19 -050028/* Offsets from ACPI_MMIO_BASE
29 * This is defined by AGESA, but we don't include AGESA headers to avoid
Martin Roth3c3a50c2014-12-16 20:50:26 -070030 * polluting the namespace.
Alexandru Gagniuc342ac642014-04-14 16:44:19 -050031 */
32#define PM_MMIO_BASE 0xfed80300
33
Alexandru Gagniuc342ac642014-04-14 16:44:19 -050034void pm_write8(u8 reg, u8 value)
zbao246e84b2012-07-13 18:47:03 +080035{
Stefan Reinauer772029f2015-07-30 16:23:50 -070036 write8((void *)((uintptr_t)PM_MMIO_BASE + reg), value);
zbao246e84b2012-07-13 18:47:03 +080037}
38
Alexandru Gagniuc342ac642014-04-14 16:44:19 -050039u8 pm_read8(u8 reg)
zbao246e84b2012-07-13 18:47:03 +080040{
Stefan Reinauer772029f2015-07-30 16:23:50 -070041 return read8((void *)((uintptr_t)PM_MMIO_BASE + reg));
zbao246e84b2012-07-13 18:47:03 +080042}
43
Alexandru Gagniuc342ac642014-04-14 16:44:19 -050044void pm_write16(u8 reg, u16 value)
zbao246e84b2012-07-13 18:47:03 +080045{
Stefan Reinauer772029f2015-07-30 16:23:50 -070046 write16((void *)((uintptr_t)PM_MMIO_BASE + reg), value);
zbao246e84b2012-07-13 18:47:03 +080047}
48
Alexandru Gagniuc342ac642014-04-14 16:44:19 -050049u16 pm_read16(u16 reg)
zbao246e84b2012-07-13 18:47:03 +080050{
Stefan Reinauer772029f2015-07-30 16:23:50 -070051 return read16((void *)((uintptr_t)PM_MMIO_BASE + reg));
zbao246e84b2012-07-13 18:47:03 +080052}
53
Alexandru Gagniucd2e5f682014-04-16 16:33:03 -050054#define PM_REG_USB_ENABLE 0xef
55
56enum usb_enable {
57 USB_EN_DEVFN_12_0 = (1 << 0),
58 USB_EN_DEVFN_12_2 = (1 << 1),
59 USB_EN_DEVFN_13_0 = (1 << 2),
60 USB_EN_DEVFN_13_2 = (1 << 3),
61 USB_EN_DEVFN_16_0 = (1 << 4),
62 USB_EN_DEVFN_16_2 = (1 << 5),
63};
64
65static void hudson_disable_usb(u8 disable)
66{
67 u8 reg8;
68
69 /* Bit 7 handles routing, 6 is reserved. we don't mess with those */
70 disable &= 0x3f;
71
72 reg8 = pm_read8(PM_REG_USB_ENABLE);
73 reg8 &= ~disable;
74 pm_write8(PM_REG_USB_ENABLE, reg8);
75}
76
Elyes HAOUASa93e7542018-05-19 14:30:47 +020077void hudson_enable(struct device *dev)
zbao246e84b2012-07-13 18:47:03 +080078{
Martin Rothf5726ea2013-01-18 12:55:40 -070079 printk(BIOS_DEBUG, "hudson_enable()\n");
Dave Frodinea909632013-05-31 08:15:57 -060080 switch (dev->path.pci.devfn) {
Tobias Diedrichae3adff2014-11-08 00:38:33 +010081 case PCI_DEVFN(0x14, 5):
82 if (dev->enabled == 0) {
Kyösti Mälkki0bc06ab2018-05-20 15:41:05 +030083 u32 usb_device_id = pci_read_config16(dev, PCI_DEVICE_ID);
Tobias Diedrichae3adff2014-11-08 00:38:33 +010084 u8 reg8;
Kyösti Mälkki9d9a5522016-11-19 22:14:59 +020085 if (usb_device_id == PCI_DEVICE_ID_AMD_SB900_USB_20_5) {
Tobias Diedrichae3adff2014-11-08 00:38:33 +010086 /* turn off and remove device 0:14.5 from PCI space */
87 reg8 = pm_read8(0xef);
88 reg8 &= ~(1 << 6);
89 pm_write8(0xef, reg8);
90 }
91 }
92 break;
93
Alexandru Gagniucd2e5f682014-04-16 16:33:03 -050094 case PCI_DEVFN(0x14, 7):
Dave Frodinea909632013-05-31 08:15:57 -060095 if (dev->enabled == 0) {
Kyösti Mälkki0bc06ab2018-05-20 15:41:05 +030096 u32 sd_device_id = pci_read_config16(dev, PCI_DEVICE_ID);
Dave Frodinea909632013-05-31 08:15:57 -060097 /* turn off the SDHC controller in the PM reg */
Alexandru Gagniuc342ac642014-04-14 16:44:19 -050098 u8 reg8;
Dave Frodinea909632013-05-31 08:15:57 -060099 if (sd_device_id == PCI_DEVICE_ID_AMD_HUDSON_SD) {
Alexandru Gagniuc342ac642014-04-14 16:44:19 -0500100 reg8 = pm_read8(0xe7);
101 reg8 &= ~(1 << 0);
102 pm_write8(0xe7, reg8);
Dave Frodinea909632013-05-31 08:15:57 -0600103 }
104 else if (sd_device_id == PCI_DEVICE_ID_AMD_YANGTZE_SD) {
Alexandru Gagniuc342ac642014-04-14 16:44:19 -0500105 reg8 = pm_read8(0xe8);
106 reg8 &= ~(1 << 0);
107 pm_write8(0xe8, reg8);
Dave Frodinea909632013-05-31 08:15:57 -0600108 }
109 /* remove device 0:14.7 from PCI space */
Alexandru Gagniuc342ac642014-04-14 16:44:19 -0500110 reg8 = pm_read8(0xd3);
111 reg8 &= ~(1 << 6);
112 pm_write8(0xd3, reg8);
Dave Frodinea909632013-05-31 08:15:57 -0600113 }
114 break;
Alexandru Gagniucd2e5f682014-04-16 16:33:03 -0500115
116 /* Make sure to disable other functions if function 0 is disabled */
117 case PCI_DEVFN(0x12, 0):
118 if (dev->enabled == 0)
119 hudson_disable_usb(USB_EN_DEVFN_12_0);
120 case PCI_DEVFN(0x12, 2): /* Fall through */
121 if (dev->enabled == 0)
122 hudson_disable_usb(USB_EN_DEVFN_12_2);
123 break;
124 case PCI_DEVFN(0x13, 0):
125 if (dev->enabled == 0)
126 hudson_disable_usb(USB_EN_DEVFN_13_0);
127 case PCI_DEVFN(0x13, 2): /* Fall through */
128 if (dev->enabled == 0)
129 hudson_disable_usb(USB_EN_DEVFN_13_2);
130 break;
131 case PCI_DEVFN(0x16, 0):
132 if (dev->enabled == 0)
133 hudson_disable_usb(USB_EN_DEVFN_16_0);
134 case PCI_DEVFN(0x16, 2): /* Fall through */
135 if (dev->enabled == 0)
136 hudson_disable_usb(USB_EN_DEVFN_16_2);
137 break;
Dave Frodinea909632013-05-31 08:15:57 -0600138 default:
139 break;
140 }
zbao246e84b2012-07-13 18:47:03 +0800141}
142
zbao246e84b2012-07-13 18:47:03 +0800143
Alexandru Gagniuc86777e32014-04-20 14:36:29 -0500144static void hudson_init_acpi_ports(void)
145{
146 /* We use some of these ports in SMM regardless of whether or not
147 * ACPI tables are generated. Enable these ports indiscriminately.
148 */
149
150 pm_write16(0x60, ACPI_PM_EVT_BLK);
151 pm_write16(0x62, ACPI_PM1_CNT_BLK);
152 pm_write16(0x64, ACPI_PM_TMR_BLK);
153 pm_write16(0x68, ACPI_GPE0_BLK);
Timothy Pearson033bb4b2015-02-10 22:21:39 -0600154 /* CpuControl is in \_PR.CP00, 6 bytes */
Alexandru Gagniuc86777e32014-04-20 14:36:29 -0500155 pm_write16(0x66, ACPI_CPU_CONTROL);
156
Julius Wernercd49cce2019-03-05 16:53:33 -0800157 if (CONFIG(HAVE_SMI_HANDLER)) {
Alexandru Gagniuc86777e32014-04-20 14:36:29 -0500158 pm_write16(0x6a, ACPI_SMI_CTL_PORT);
159 hudson_enable_acpi_cmd_smi();
160 } else {
161 pm_write16(0x6a, 0);
162 }
163
164 /* AcpiDecodeEnable, When set, SB uses the contents of the PM registers
165 * at index 60-6B to decode ACPI I/O address. AcpiSmiEn & SmiCmdEn
166 */
167 pm_write8(0x74, 1<<0 | 1<<1 | 1<<4 | 1<<2);
168}
169
170static void hudson_init(void *chip_info)
171{
172 hudson_init_acpi_ports();
173}
174
Kyösti Mälkki29d9c562014-10-16 21:35:48 +0300175static void hudson_final(void *chip_info)
176{
Kyösti Mälkki29d9c562014-10-16 21:35:48 +0300177 /* AMD AGESA does not enable thermal zone, so we enable it here. */
Julius Wernercd49cce2019-03-05 16:53:33 -0800178 if (CONFIG(HUDSON_IMC_FWM) &&
179 !CONFIG(ACPI_ENABLE_THERMAL_ZONE))
Kyösti Mälkkieb064b32017-08-24 21:20:10 +0300180 enable_imc_thermal_zone();
Kyösti Mälkki29d9c562014-10-16 21:35:48 +0300181}
182
zbao246e84b2012-07-13 18:47:03 +0800183struct chip_operations southbridge_amd_agesa_hudson_ops = {
184 CHIP_NAME("ATI HUDSON")
185 .enable_dev = hudson_enable,
Kyösti Mälkki29d9c562014-10-16 21:35:48 +0300186 .init = hudson_init,
187 .final = hudson_final
zbao246e84b2012-07-13 18:47:03 +0800188};