blob: cef5bbaa23ad30006f4e57daffcdc3501b60ebf8 [file] [log] [blame]
Angel Ponsae593872020-04-04 18:50:57 +02001/* SPDX-License-Identifier: GPL-2.0-only */
2/* This file is part of the coreboot project. */
Marc Jones24484842017-05-04 21:17:45 -06003
Marc Jones24484842017-05-04 21:17:45 -06004#include <device/device.h>
5#include <device/pci.h>
6#include <device/pci_ids.h>
Marc Jones24484842017-05-04 21:17:45 -06007#include <device/smbus.h>
Aaron Durbin178d6442020-01-28 11:10:23 -07008#include <device/smbus_host.h>
Marc Jones24484842017-05-04 21:17:45 -06009#include <cpu/x86/lapic.h>
10#include <arch/ioapic.h>
Marc Jonesdfeb1c42017-08-07 19:08:24 -060011#include <soc/southbridge.h>
Marc Jones24484842017-05-04 21:17:45 -060012
Marc Jones24484842017-05-04 21:17:45 -060013/*
Marc Jonesdfeb1c42017-08-07 19:08:24 -060014* The southbridge enables all USB controllers by default in SMBUS Control.
15* The southbridge enables SATA by default in SMBUS Control.
Marc Jones24484842017-05-04 21:17:45 -060016*/
17
Elyes HAOUAS777ccd42018-05-22 10:52:05 +020018static void sm_init(struct device *dev)
Marc Jones24484842017-05-04 21:17:45 -060019{
20 setup_ioapic(VIO_APIC_VADDR, CONFIG_MAX_CPUS);
21}
22
Richard Spiegelb40e1932018-10-24 12:51:21 -070023static u32 get_sm_mmio(struct device *dev)
Marc Jones24484842017-05-04 21:17:45 -060024{
Marc Jones24484842017-05-04 21:17:45 -060025 struct resource *res;
26 struct bus *pbus;
27
Marc Jones24484842017-05-04 21:17:45 -060028 pbus = get_pbus_smbus(dev);
Marc Jones24484842017-05-04 21:17:45 -060029 res = find_resource(pbus->dev, 0x90);
Richard Spiegelb40e1932018-10-24 12:51:21 -070030 if (res->base == SMB_BASE_ADDR)
Marshall Dawson5de47712019-05-01 16:14:42 -060031 return ACPIMMIO_SMBUS_BASE;
Marc Jones24484842017-05-04 21:17:45 -060032
Marshall Dawson5de47712019-05-01 16:14:42 -060033 return ACPIMMIO_ASF_BASE;
Richard Spiegelb40e1932018-10-24 12:51:21 -070034}
35
36static int lsmbus_recv_byte(struct device *dev)
37{
38 u8 device;
39
40 device = dev->path.i2c.device;
41 return do_smbus_recv_byte(get_sm_mmio(dev), device);
Marc Jones24484842017-05-04 21:17:45 -060042}
43
Elyes HAOUAS777ccd42018-05-22 10:52:05 +020044static int lsmbus_send_byte(struct device *dev, u8 val)
Marc Jones24484842017-05-04 21:17:45 -060045{
Richard Spiegelcd04e312017-11-08 14:58:30 -070046 u8 device;
Marc Jones24484842017-05-04 21:17:45 -060047
48 device = dev->path.i2c.device;
Richard Spiegelb40e1932018-10-24 12:51:21 -070049 return do_smbus_send_byte(get_sm_mmio(dev), device, val);
Marc Jones24484842017-05-04 21:17:45 -060050}
51
Elyes HAOUAS777ccd42018-05-22 10:52:05 +020052static int lsmbus_read_byte(struct device *dev, u8 address)
Marc Jones24484842017-05-04 21:17:45 -060053{
Richard Spiegelcd04e312017-11-08 14:58:30 -070054 u8 device;
Marc Jones24484842017-05-04 21:17:45 -060055
56 device = dev->path.i2c.device;
Richard Spiegelb40e1932018-10-24 12:51:21 -070057 return do_smbus_read_byte(get_sm_mmio(dev), device, address);
Marc Jones24484842017-05-04 21:17:45 -060058}
59
Elyes HAOUAS777ccd42018-05-22 10:52:05 +020060static int lsmbus_write_byte(struct device *dev, u8 address, u8 val)
Marc Jones24484842017-05-04 21:17:45 -060061{
Richard Spiegelcd04e312017-11-08 14:58:30 -070062 u8 device;
Marc Jones24484842017-05-04 21:17:45 -060063
64 device = dev->path.i2c.device;
Richard Spiegelb40e1932018-10-24 12:51:21 -070065 return do_smbus_write_byte(get_sm_mmio(dev), device, address, val);
Marc Jones24484842017-05-04 21:17:45 -060066}
67static struct smbus_bus_operations lops_smbus_bus = {
68 .recv_byte = lsmbus_recv_byte,
69 .send_byte = lsmbus_send_byte,
70 .read_byte = lsmbus_read_byte,
71 .write_byte = lsmbus_write_byte,
72};
73
Marc Jones24484842017-05-04 21:17:45 -060074static struct pci_operations lops_pci = {
75 .set_subsystem = pci_dev_set_subsystem,
76};
77static struct device_operations smbus_ops = {
Nico Huber2f8ba692020-04-05 14:05:24 +020078 .read_resources = noop_read_resources,
79 .set_resources = noop_set_resources,
Marc Jones24484842017-05-04 21:17:45 -060080 .enable_resources = pci_dev_enable_resources,
81 .init = sm_init,
82 .scan_bus = scan_smbus,
83 .ops_pci = &lops_pci,
84 .ops_smbus_bus = &lops_smbus_bus,
85};
86static const struct pci_driver smbus_driver __pci_driver = {
87 .ops = &smbus_ops,
88 .vendor = PCI_VENDOR_ID_AMD,
Martin Roth069ca662018-03-01 11:26:18 -070089 .device = PCI_DEVICE_ID_AMD_CZ_SMBUS,
Marc Jones24484842017-05-04 21:17:45 -060090};