coreboot
coreboot is an Open Source project aimed at replacing the proprietary BIOS found in most computers.
hudson.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 
3 #include <amdblocks/acpimmio.h>
4 #include <console/console.h>
5 #include <device/mmio.h>
6 #include <device/device.h>
7 #include <device/pci.h>
8 #include <device/pci_def.h>
9 #include <device/pci_ids.h>
10 #include <device/pci_ops.h>
11 #include "hudson.h"
12 #include "imc.h"
13 #include "smbus.h"
14 #include "smi.h"
15 
16 #define PM_REG_USB_ENABLE 0xef
17 
18 enum usb_enable {
19  USB_EN_DEVFN_12_0 = (1 << 0),
20  USB_EN_DEVFN_12_2 = (1 << 1),
21  USB_EN_DEVFN_13_0 = (1 << 2),
22  USB_EN_DEVFN_13_2 = (1 << 3),
23  USB_EN_DEVFN_16_0 = (1 << 4),
24  USB_EN_DEVFN_16_2 = (1 << 5),
25 };
26 
27 static void hudson_disable_usb(u8 disable)
28 {
29  u8 reg8;
30 
31  /* Bit 7 handles routing, 6 is reserved. we don't mess with those */
32  disable &= 0x3f;
33 
35  reg8 &= ~disable;
37 }
38 
39 void hudson_enable(struct device *dev)
40 {
41  printk(BIOS_DEBUG, "%s()\n", __func__);
42  switch (dev->path.pci.devfn) {
43  case PCI_DEVFN(0x14, 5):
44  if (dev->enabled == 0) {
45  u32 usb_device_id = pci_read_config16(dev, PCI_DEVICE_ID);
46  u8 reg8;
47  if (usb_device_id == PCI_DID_AMD_SB900_USB_20_5) {
48  /* turn off and remove device 0:14.5 from PCI space */
49  reg8 = pm_read8(0xef);
50  reg8 &= ~(1 << 6);
51  pm_write8(0xef, reg8);
52  }
53  }
54  break;
55 
56  case PCI_DEVFN(0x14, 7):
57  if (dev->enabled == 0) {
58  u32 sd_device_id = pci_read_config16(dev, PCI_DEVICE_ID);
59  /* turn off the SDHC controller in the PM reg */
60  u8 reg8;
61  if (sd_device_id == PCI_DID_AMD_HUDSON_SD) {
62  reg8 = pm_read8(0xe7);
63  reg8 &= ~(1 << 0);
64  pm_write8(0xe7, reg8);
65  } else if (sd_device_id == PCI_DID_AMD_YANGTZE_SD) {
66  reg8 = pm_read8(0xe8);
67  reg8 &= ~(1 << 0);
68  pm_write8(0xe8, reg8);
69  }
70  /* remove device 0:14.7 from PCI space */
71  reg8 = pm_read8(0xd3);
72  reg8 &= ~(1 << 6);
73  pm_write8(0xd3, reg8);
74  }
75  break;
76 
77  /* Make sure to disable other functions if function 0 is disabled */
78  case PCI_DEVFN(0x12, 0):
79  if (dev->enabled == 0)
82  case PCI_DEVFN(0x12, 2):
83  if (dev->enabled == 0)
85  break;
86  case PCI_DEVFN(0x13, 0):
87  if (dev->enabled == 0)
90  case PCI_DEVFN(0x13, 2):
91  if (dev->enabled == 0)
93  break;
94  case PCI_DEVFN(0x16, 0):
95  if (dev->enabled == 0)
98  case PCI_DEVFN(0x16, 2):
99  if (dev->enabled == 0)
101  break;
102  default:
103  break;
104  }
105 }
106 
107 static void hudson_init_acpi_ports(void)
108 {
109  /* We use some of these ports in SMM regardless of whether or not
110  * ACPI tables are generated. Enable these ports indiscriminately.
111  */
112 
116  pm_write16(0x68, ACPI_GPE0_BLK);
117  /* CpuControl is in \_PR.CP00, 6 bytes */
119 
120  if (CONFIG(HAVE_SMI_HANDLER)) {
123  } else {
124  pm_write16(0x6a, 0);
125  }
126 
127  /* AcpiDecodeEnable, When set, SB uses the contents of the PM registers
128  * at index 60-6B to decode ACPI I/O address. AcpiSmiEn & SmiCmdEn
129  */
130  pm_write8(0x74, 1<<0 | 1<<1 | 1<<4 | 1<<2);
131 }
132 
133 static void hudson_init(void *chip_info)
134 {
136 }
137 
138 static void hudson_final(void *chip_info)
139 {
140  /* AMD AGESA does not enable thermal zone, so we enable it here. */
141  if (CONFIG(HUDSON_IMC_FWM) &&
142  !CONFIG(ACPI_ENABLE_THERMAL_ZONE))
144 }
145 
147  CHIP_NAME("ATI HUDSON")
148  .enable_dev = hudson_enable,
149  .init = hudson_init,
150  .final = hudson_final
151 };
static uint8_t pm_read8(uint8_t reg)
Definition: acpimmio.h:166
static void pm_write16(uint8_t reg, uint16_t value)
Definition: acpimmio.h:186
static void pm_write8(uint8_t reg, uint8_t value)
Definition: acpimmio.h:181
void hudson_enable(struct device *dev)
Definition: hudson.c:39
#define PM_REG_USB_ENABLE
Definition: hudson.c:16
struct chip_operations southbridge_amd_agesa_hudson_ops
Definition: hudson.c:146
static void hudson_init_acpi_ports(void)
Definition: hudson.c:107
static void hudson_init(void *chip_info)
Definition: hudson.c:133
usb_enable
Definition: hudson.c:18
@ USB_EN_DEVFN_16_0
Definition: hudson.c:23
@ USB_EN_DEVFN_12_2
Definition: hudson.c:20
@ USB_EN_DEVFN_16_2
Definition: hudson.c:24
@ USB_EN_DEVFN_13_2
Definition: hudson.c:22
@ USB_EN_DEVFN_13_0
Definition: hudson.c:21
@ USB_EN_DEVFN_12_0
Definition: hudson.c:19
static void hudson_final(void *chip_info)
Definition: hudson.c:138
static void hudson_disable_usb(u8 disable)
Definition: hudson.c:27
#define ACPI_SMI_CTL_PORT
Definition: hudson.h:25
void enable_imc_thermal_zone(void)
Definition: imc.c:43
#define ACPI_CPU_CONTROL
Definition: iomap.h:45
#define ACPI_PM1_CNT_BLK
Definition: iomap.h:43
#define ACPI_PM_TMR_BLK
Definition: iomap.h:44
#define ACPI_GPE0_BLK
Definition: iomap.h:46
#define ACPI_PM_EVT_BLK
Definition: iomap.h:40
#define printk(level,...)
Definition: stdlib.h:16
#define __fallthrough
Definition: compiler.h:39
@ CONFIG
Definition: dsi_common.h:201
#define CHIP_NAME(X)
Definition: device.h:32
static __always_inline u16 pci_read_config16(const struct device *dev, u16 reg)
Definition: pci_ops.h:52
#define BIOS_DEBUG
BIOS_DEBUG - Verbose output.
Definition: loglevel.h:128
#define PCI_DEVFN(slot, func)
Definition: pci_def.h:548
#define PCI_DEVICE_ID
Definition: pci_def.h:9
#define PCI_DID_AMD_HUDSON_SD
Definition: pci_ids.h:539
#define PCI_DID_AMD_YANGTZE_SD
Definition: pci_ids.h:540
#define PCI_DID_AMD_SB900_USB_20_5
Definition: pci_ids.h:537
void hudson_enable_acpi_cmd_smi(void)
Enable SMIs on writes to ACPI SMI command port.
Definition: smi_util.c:76
uint32_t u32
Definition: stdint.h:51
uint8_t u8
Definition: stdint.h:45
struct pci_path pci
Definition: path.h:116
Definition: device.h:107
struct device_path path
Definition: device.h:115
unsigned int enabled
Definition: device.h:122
unsigned int devfn
Definition: path.h:54