blob: e8b7c0fce63074bdcc992a0bf69f8f47282246aa [file] [log] [blame]
Angel Ponsae593872020-04-04 18:50:57 +02001/* SPDX-License-Identifier: GPL-2.0-only */
Marc Jones24484842017-05-04 21:17:45 -06002
Kyösti Mälkkid7865202020-07-01 13:15:27 +03003#include <amdblocks/acpimmio.h>
Felix Held604ffa62021-02-12 00:43:20 +01004#include <amdblocks/ioapic.h>
Marc Jones24484842017-05-04 21:17:45 -06005#include <device/device.h>
6#include <device/pci.h>
7#include <device/pci_ids.h>
Marc Jones24484842017-05-04 21:17:45 -06008#include <device/smbus.h>
Aaron Durbin178d6442020-01-28 11:10:23 -07009#include <device/smbus_host.h>
Marc Jones24484842017-05-04 21:17:45 -060010#include <arch/ioapic.h>
Marc Jones24484842017-05-04 21:17:45 -060011
Elyes HAOUAS777ccd42018-05-22 10:52:05 +020012static void sm_init(struct device *dev)
Marc Jones24484842017-05-04 21:17:45 -060013{
Felix Held1b332052021-02-11 03:01:18 +010014 fch_enable_ioapic_decode();
Felix Held604ffa62021-02-12 00:43:20 +010015 setup_ioapic(VIO_APIC_VADDR, FCH_IOAPIC_ID);
Felix Held34fc29a2021-02-11 02:43:07 +010016 fch_configure_hpet();
Marc Jones24484842017-05-04 21:17:45 -060017}
18
Richard Spiegelb40e1932018-10-24 12:51:21 -070019static u32 get_sm_mmio(struct device *dev)
Marc Jones24484842017-05-04 21:17:45 -060020{
Felix Held8199b882021-01-05 00:03:20 +010021 /*
22 * Since SMBus and ASF controller are behind the same PCIe device, we don't know behind
23 * which controller a device is. We assume here that the devices are behind the SMBus
24 * controller. The proper solution would be to handle those as MMIO devices instead of
25 * PCI ones.
26 */
27 return (uintptr_t)acpimmio_smbus;
Richard Spiegelb40e1932018-10-24 12:51:21 -070028}
29
30static int lsmbus_recv_byte(struct device *dev)
31{
32 u8 device;
33
34 device = dev->path.i2c.device;
35 return do_smbus_recv_byte(get_sm_mmio(dev), device);
Marc Jones24484842017-05-04 21:17:45 -060036}
37
Elyes HAOUAS777ccd42018-05-22 10:52:05 +020038static int lsmbus_send_byte(struct device *dev, u8 val)
Marc Jones24484842017-05-04 21:17:45 -060039{
Richard Spiegelcd04e312017-11-08 14:58:30 -070040 u8 device;
Marc Jones24484842017-05-04 21:17:45 -060041
42 device = dev->path.i2c.device;
Richard Spiegelb40e1932018-10-24 12:51:21 -070043 return do_smbus_send_byte(get_sm_mmio(dev), device, val);
Marc Jones24484842017-05-04 21:17:45 -060044}
45
Elyes HAOUAS777ccd42018-05-22 10:52:05 +020046static int lsmbus_read_byte(struct device *dev, u8 address)
Marc Jones24484842017-05-04 21:17:45 -060047{
Richard Spiegelcd04e312017-11-08 14:58:30 -070048 u8 device;
Marc Jones24484842017-05-04 21:17:45 -060049
50 device = dev->path.i2c.device;
Richard Spiegelb40e1932018-10-24 12:51:21 -070051 return do_smbus_read_byte(get_sm_mmio(dev), device, address);
Marc Jones24484842017-05-04 21:17:45 -060052}
53
Elyes HAOUAS777ccd42018-05-22 10:52:05 +020054static int lsmbus_write_byte(struct device *dev, u8 address, u8 val)
Marc Jones24484842017-05-04 21:17:45 -060055{
Richard Spiegelcd04e312017-11-08 14:58:30 -070056 u8 device;
Marc Jones24484842017-05-04 21:17:45 -060057
58 device = dev->path.i2c.device;
Richard Spiegelb40e1932018-10-24 12:51:21 -070059 return do_smbus_write_byte(get_sm_mmio(dev), device, address, val);
Marc Jones24484842017-05-04 21:17:45 -060060}
Felix Held66b4f012021-02-16 23:53:43 +010061
Marc Jones24484842017-05-04 21:17:45 -060062static struct smbus_bus_operations lops_smbus_bus = {
63 .recv_byte = lsmbus_recv_byte,
64 .send_byte = lsmbus_send_byte,
65 .read_byte = lsmbus_read_byte,
66 .write_byte = lsmbus_write_byte,
67};
68
Felix Held66b4f012021-02-16 23:53:43 +010069#if CONFIG(HAVE_ACPI_TABLES)
70static const char *smbus_acpi_name(const struct device *dev)
71{
72 return "SBUS";
73}
74#endif
75
Marc Jones24484842017-05-04 21:17:45 -060076static struct device_operations smbus_ops = {
Felix Held66b4f012021-02-16 23:53:43 +010077 .read_resources = noop_read_resources,
78 .set_resources = noop_set_resources,
79 .enable_resources = pci_dev_enable_resources,
80 .init = sm_init,
81 .scan_bus = scan_smbus,
82 .ops_pci = &pci_dev_ops_pci,
83 .ops_smbus_bus = &lops_smbus_bus,
84#if CONFIG(HAVE_ACPI_TABLES)
85 .acpi_name = smbus_acpi_name,
86#endif
Marc Jones24484842017-05-04 21:17:45 -060087};
Felix Held66b4f012021-02-16 23:53:43 +010088
Marc Jones24484842017-05-04 21:17:45 -060089static const struct pci_driver smbus_driver __pci_driver = {
90 .ops = &smbus_ops,
Felix Singer43b7f412022-03-07 04:34:52 +010091 .vendor = PCI_VID_AMD,
Felix Held43cf27d2021-10-27 18:31:16 +020092 /* PCI device ID is used on all integrated FCHs except Family 16h Models 00h-3Fh */
Felix Singer43b7f412022-03-07 04:34:52 +010093 .device = PCI_DID_AMD_CZ_SMBUS,
Marc Jones24484842017-05-04 21:17:45 -060094};