blob: c41445bcab6aa219a42a941b26bca5b3dc7b29f5 [file] [log] [blame]
Yinghai Luc65bd562007-02-01 00:10:05 +00001/*
Stefan Reinauer7e61e452008-01-18 10:35:56 +00002 * This file is part of the coreboot project.
Yinghai Luc65bd562007-02-01 00:10:05 +00003 *
4 * Copyright (C) 2004 Tyan Computer
5 * Written by Yinghai Lu <yhlu@tyan.com> for Tyan Computer.
6 * Copyright (C) 2006,2007 AMD
7 * Written by Yinghai Lu <yinghai.lu@amd.com> for AMD.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
Yinghai Luc65bd562007-02-01 00:10:05 +000018 */
19
20#include <console/console.h>
21#include <device/device.h>
22#include <device/pci.h>
23#include <device/pci_ids.h>
24#include <device/pci_ops.h>
25#include <device/smbus.h>
Yinghai Luc65bd562007-02-01 00:10:05 +000026#include <arch/io.h>
27#include "mcp55.h"
stepan836ae292010-12-08 05:42:47 +000028#include "smbus.h"
Yinghai Luc65bd562007-02-01 00:10:05 +000029
30static int lsmbus_recv_byte(device_t dev)
31{
32 unsigned device;
33 struct resource *res;
34 struct bus *pbus;
35
Stefan Reinauer2b34db82009-02-28 20:10:20 +000036 device = dev->path.i2c.device;
Yinghai Luc65bd562007-02-01 00:10:05 +000037 pbus = get_pbus_smbus(dev);
38
Myles Watson894a3472010-06-09 22:41:35 +000039 res = find_resource(pbus->dev, 0x20 + (pbus->link_num * 4));
Yinghai Luc65bd562007-02-01 00:10:05 +000040
41 return do_smbus_recv_byte(res->base, device);
42}
43
Uwe Hermannc7f0c8f2011-01-04 19:51:33 +000044static int lsmbus_send_byte(device_t dev, u8 val)
Yinghai Luc65bd562007-02-01 00:10:05 +000045{
46 unsigned device;
47 struct resource *res;
48 struct bus *pbus;
49
Stefan Reinauer2b34db82009-02-28 20:10:20 +000050 device = dev->path.i2c.device;
Yinghai Luc65bd562007-02-01 00:10:05 +000051 pbus = get_pbus_smbus(dev);
52
Myles Watson894a3472010-06-09 22:41:35 +000053 res = find_resource(pbus->dev, 0x20 + (pbus->link_num * 4));
Yinghai Luc65bd562007-02-01 00:10:05 +000054
55 return do_smbus_send_byte(res->base, device, val);
56}
57
Uwe Hermannc7f0c8f2011-01-04 19:51:33 +000058static int lsmbus_read_byte(device_t dev, u8 address)
Yinghai Luc65bd562007-02-01 00:10:05 +000059{
60 unsigned device;
61 struct resource *res;
62 struct bus *pbus;
63
Stefan Reinauer2b34db82009-02-28 20:10:20 +000064 device = dev->path.i2c.device;
Yinghai Luc65bd562007-02-01 00:10:05 +000065 pbus = get_pbus_smbus(dev);
66
Myles Watson894a3472010-06-09 22:41:35 +000067 res = find_resource(pbus->dev, 0x20 + (pbus->link_num * 4));
Yinghai Luc65bd562007-02-01 00:10:05 +000068
69 return do_smbus_read_byte(res->base, device, address);
70}
71
Uwe Hermannc7f0c8f2011-01-04 19:51:33 +000072static int lsmbus_write_byte(device_t dev, u8 address, u8 val)
Yinghai Luc65bd562007-02-01 00:10:05 +000073{
74 unsigned device;
75 struct resource *res;
76 struct bus *pbus;
77
Stefan Reinauer2b34db82009-02-28 20:10:20 +000078 device = dev->path.i2c.device;
Yinghai Luc65bd562007-02-01 00:10:05 +000079 pbus = get_pbus_smbus(dev);
80
Myles Watson894a3472010-06-09 22:41:35 +000081 res = find_resource(pbus->dev, 0x20 + (pbus->link_num * 4));
Yinghai Luc65bd562007-02-01 00:10:05 +000082
83 return do_smbus_write_byte(res->base, device, address, val);
84}
85static struct smbus_bus_operations lops_smbus_bus = {
86 .recv_byte = lsmbus_recv_byte,
87 .send_byte = lsmbus_send_byte,
88 .read_byte = lsmbus_read_byte,
89 .write_byte = lsmbus_write_byte,
90};
91
Martin Roth1858d6a2017-06-24 21:30:42 -060092#if IS_ENABLED(CONFIG_HAVE_ACPI_TABLES)
Yinghai Luc65bd562007-02-01 00:10:05 +000093unsigned pm_base;
94#endif
95
96static void mcp55_sm_read_resources(device_t dev)
97{
Yinghai Luc65bd562007-02-01 00:10:05 +000098 unsigned long index;
99
100 /* Get the normal pci resources of this device */
101 pci_dev_read_resources(dev);
102
103 for (index = 0x60; index <= 0x68; index+=4) { // We got another 3.
104 pci_get_resource(dev, index);
105 }
106 compact_resources(dev);
Yinghai Luc65bd562007-02-01 00:10:05 +0000107}
108
109static void mcp55_sm_init(device_t dev)
110{
Martin Roth1858d6a2017-06-24 21:30:42 -0600111#if IS_ENABLED(CONFIG_HAVE_ACPI_TABLES)
Yinghai Luc65bd562007-02-01 00:10:05 +0000112 struct resource *res;
113
114 res = find_resource(dev, 0x60);
115
116 if (res)
117 pm_base = res->base;
118#endif
119}
120
Yinghai Luc65bd562007-02-01 00:10:05 +0000121static struct device_operations smbus_ops = {
122 .read_resources = mcp55_sm_read_resources,
123 .set_resources = pci_dev_set_resources,
124 .enable_resources = pci_dev_enable_resources,
125 .init = mcp55_sm_init,
Kyösti Mälkkid0e212c2015-02-26 20:47:47 +0200126 .scan_bus = scan_smbus,
Yinghai Luc65bd562007-02-01 00:10:05 +0000127// .enable = mcp55_enable,
Jonathan Kollaschdca8b1b2010-10-29 20:40:06 +0000128 .ops_pci = &mcp55_pci_ops,
Yinghai Luc65bd562007-02-01 00:10:05 +0000129 .ops_smbus_bus = &lops_smbus_bus,
130};
Stefan Reinauerf1cf1f72007-10-24 09:08:58 +0000131static const struct pci_driver smbus_driver __pci_driver = {
Yinghai Luc65bd562007-02-01 00:10:05 +0000132 .ops = &smbus_ops,
133 .vendor = PCI_VENDOR_ID_NVIDIA,
134 .device = PCI_DEVICE_ID_NVIDIA_MCP55_SM2,
135};