blob: c5c1ed8990edf2559dfe6fef81a4ab86e0904496 [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
Furquan Shaikh38206882020-04-28 21:04:54 -07003#include <amdblocks/acpimmio_map.h>
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 <arch/ioapic.h>
Marc Jonesdfeb1c42017-08-07 19:08:24 -060010#include <soc/southbridge.h>
Marc Jones24484842017-05-04 21:17:45 -060011
Marc Jones24484842017-05-04 21:17:45 -060012/*
Marc Jonesdfeb1c42017-08-07 19:08:24 -060013* The southbridge enables all USB controllers by default in SMBUS Control.
14* The southbridge enables SATA by default in SMBUS Control.
Marc Jones24484842017-05-04 21:17:45 -060015*/
16
Elyes HAOUAS777ccd42018-05-22 10:52:05 +020017static void sm_init(struct device *dev)
Marc Jones24484842017-05-04 21:17:45 -060018{
19 setup_ioapic(VIO_APIC_VADDR, CONFIG_MAX_CPUS);
20}
21
Richard Spiegelb40e1932018-10-24 12:51:21 -070022static u32 get_sm_mmio(struct device *dev)
Marc Jones24484842017-05-04 21:17:45 -060023{
Marc Jones24484842017-05-04 21:17:45 -060024 struct resource *res;
25 struct bus *pbus;
26
Marc Jones24484842017-05-04 21:17:45 -060027 pbus = get_pbus_smbus(dev);
Marc Jones24484842017-05-04 21:17:45 -060028 res = find_resource(pbus->dev, 0x90);
Richard Spiegelb40e1932018-10-24 12:51:21 -070029 if (res->base == SMB_BASE_ADDR)
Marshall Dawson5de47712019-05-01 16:14:42 -060030 return ACPIMMIO_SMBUS_BASE;
Marc Jones24484842017-05-04 21:17:45 -060031
Marshall Dawson5de47712019-05-01 16:14:42 -060032 return ACPIMMIO_ASF_BASE;
Richard Spiegelb40e1932018-10-24 12:51:21 -070033}
34
35static int lsmbus_recv_byte(struct device *dev)
36{
37 u8 device;
38
39 device = dev->path.i2c.device;
40 return do_smbus_recv_byte(get_sm_mmio(dev), device);
Marc Jones24484842017-05-04 21:17:45 -060041}
42
Elyes HAOUAS777ccd42018-05-22 10:52:05 +020043static int lsmbus_send_byte(struct device *dev, u8 val)
Marc Jones24484842017-05-04 21:17:45 -060044{
Richard Spiegelcd04e312017-11-08 14:58:30 -070045 u8 device;
Marc Jones24484842017-05-04 21:17:45 -060046
47 device = dev->path.i2c.device;
Richard Spiegelb40e1932018-10-24 12:51:21 -070048 return do_smbus_send_byte(get_sm_mmio(dev), device, val);
Marc Jones24484842017-05-04 21:17:45 -060049}
50
Elyes HAOUAS777ccd42018-05-22 10:52:05 +020051static int lsmbus_read_byte(struct device *dev, u8 address)
Marc Jones24484842017-05-04 21:17:45 -060052{
Richard Spiegelcd04e312017-11-08 14:58:30 -070053 u8 device;
Marc Jones24484842017-05-04 21:17:45 -060054
55 device = dev->path.i2c.device;
Richard Spiegelb40e1932018-10-24 12:51:21 -070056 return do_smbus_read_byte(get_sm_mmio(dev), device, address);
Marc Jones24484842017-05-04 21:17:45 -060057}
58
Elyes HAOUAS777ccd42018-05-22 10:52:05 +020059static int lsmbus_write_byte(struct device *dev, u8 address, u8 val)
Marc Jones24484842017-05-04 21:17:45 -060060{
Richard Spiegelcd04e312017-11-08 14:58:30 -070061 u8 device;
Marc Jones24484842017-05-04 21:17:45 -060062
63 device = dev->path.i2c.device;
Richard Spiegelb40e1932018-10-24 12:51:21 -070064 return do_smbus_write_byte(get_sm_mmio(dev), device, address, val);
Marc Jones24484842017-05-04 21:17:45 -060065}
66static struct smbus_bus_operations lops_smbus_bus = {
67 .recv_byte = lsmbus_recv_byte,
68 .send_byte = lsmbus_send_byte,
69 .read_byte = lsmbus_read_byte,
70 .write_byte = lsmbus_write_byte,
71};
72
Marc Jones24484842017-05-04 21:17:45 -060073static struct device_operations smbus_ops = {
Nico Huber2f8ba692020-04-05 14:05:24 +020074 .read_resources = noop_read_resources,
75 .set_resources = noop_set_resources,
Marc Jones24484842017-05-04 21:17:45 -060076 .enable_resources = pci_dev_enable_resources,
77 .init = sm_init,
78 .scan_bus = scan_smbus,
Angel Pons1fc0edd2020-05-31 00:03:28 +020079 .ops_pci = &pci_dev_ops_pci,
Marc Jones24484842017-05-04 21:17:45 -060080 .ops_smbus_bus = &lops_smbus_bus,
81};
82static const struct pci_driver smbus_driver __pci_driver = {
83 .ops = &smbus_ops,
84 .vendor = PCI_VENDOR_ID_AMD,
Martin Roth069ca662018-03-01 11:26:18 -070085 .device = PCI_DEVICE_ID_AMD_CZ_SMBUS,
Marc Jones24484842017-05-04 21:17:45 -060086};