blob: d4f428f343537da597fd3e7ffe7ae26b26c44b47 [file] [log] [blame]
Marc Jones24484842017-05-04 21:17:45 -06001/*
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.
14 */
15
16#include <console/console.h>
17#include <device/device.h>
18#include <device/pci.h>
19#include <device/pci_ids.h>
20#include <device/pci_ops.h>
21#include <device/smbus.h>
22#include <pc80/mc146818rtc.h>
23#include <arch/io.h>
24#include <cpu/x86/lapic.h>
25#include <arch/ioapic.h>
26#include <stdlib.h>
Marc Jonesdfeb1c42017-08-07 19:08:24 -060027#include <soc/southbridge.h>
Marc Jones24484842017-05-04 21:17:45 -060028#include <soc/smbus.h>
29
Marc Jones24484842017-05-04 21:17:45 -060030/*
Marc Jonesdfeb1c42017-08-07 19:08:24 -060031* The southbridge enables all USB controllers by default in SMBUS Control.
32* The southbridge enables SATA by default in SMBUS Control.
Marc Jones24484842017-05-04 21:17:45 -060033*/
34
35static void sm_init(device_t dev)
36{
37 setup_ioapic(VIO_APIC_VADDR, CONFIG_MAX_CPUS);
38}
39
40static int lsmbus_recv_byte(device_t dev)
41{
Richard Spiegelcd04e312017-11-08 14:58:30 -070042 u8 device;
Marc Jones24484842017-05-04 21:17:45 -060043 struct resource *res;
44 struct bus *pbus;
45
46 device = dev->path.i2c.device;
47 pbus = get_pbus_smbus(dev);
48
49 res = find_resource(pbus->dev, 0x90);
50
51 return do_smbus_recv_byte(res->base, device);
52}
53
54static int lsmbus_send_byte(device_t dev, u8 val)
55{
Richard Spiegelcd04e312017-11-08 14:58:30 -070056 u8 device;
Marc Jones24484842017-05-04 21:17:45 -060057 struct resource *res;
58 struct bus *pbus;
59
60 device = dev->path.i2c.device;
61 pbus = get_pbus_smbus(dev);
62
63 res = find_resource(pbus->dev, 0x90);
64
65 return do_smbus_send_byte(res->base, device, val);
66}
67
68static int lsmbus_read_byte(device_t dev, u8 address)
69{
Richard Spiegelcd04e312017-11-08 14:58:30 -070070 u8 device;
Marc Jones24484842017-05-04 21:17:45 -060071 struct resource *res;
72 struct bus *pbus;
73
74 device = dev->path.i2c.device;
75 pbus = get_pbus_smbus(dev);
76
77 res = find_resource(pbus->dev, 0x90);
78
79 return do_smbus_read_byte(res->base, device, address);
80}
81
82static int lsmbus_write_byte(device_t dev, u8 address, u8 val)
83{
Richard Spiegelcd04e312017-11-08 14:58:30 -070084 u8 device;
Marc Jones24484842017-05-04 21:17:45 -060085 struct resource *res;
86 struct bus *pbus;
87
88 device = dev->path.i2c.device;
89 pbus = get_pbus_smbus(dev);
90
91 res = find_resource(pbus->dev, 0x90);
92
93 return do_smbus_write_byte(res->base, device, address, val);
94}
95static struct smbus_bus_operations lops_smbus_bus = {
96 .recv_byte = lsmbus_recv_byte,
97 .send_byte = lsmbus_send_byte,
98 .read_byte = lsmbus_read_byte,
99 .write_byte = lsmbus_write_byte,
100};
101
Marc Jones24484842017-05-04 21:17:45 -0600102static struct pci_operations lops_pci = {
103 .set_subsystem = pci_dev_set_subsystem,
104};
105static struct device_operations smbus_ops = {
Richard Spiegelcd04e312017-11-08 14:58:30 -0700106 .read_resources = DEVICE_NOOP,
107 .set_resources = DEVICE_NOOP,
Marc Jones24484842017-05-04 21:17:45 -0600108 .enable_resources = pci_dev_enable_resources,
109 .init = sm_init,
110 .scan_bus = scan_smbus,
111 .ops_pci = &lops_pci,
112 .ops_smbus_bus = &lops_smbus_bus,
113};
114static const struct pci_driver smbus_driver __pci_driver = {
115 .ops = &smbus_ops,
116 .vendor = PCI_VENDOR_ID_AMD,
Martin Roth069ca662018-03-01 11:26:18 -0700117 .device = PCI_DEVICE_ID_AMD_CZ_SMBUS,
Marc Jones24484842017-05-04 21:17:45 -0600118};