Martin Roth | ebace9f | 2018-05-26 18:56:17 -0600 | [diff] [blame^] | 1 | /* |
| 2 | * This file is part of the coreboot project. |
| 3 | * |
| 4 | * This program is free software; you can redistribute it and/or modify |
| 5 | * it under the terms of the GNU General Public License as published by |
| 6 | * the Free Software Foundation; version 2 of the License. |
| 7 | * |
| 8 | * This program is distributed in the hope that it will be useful, |
| 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 11 | * GNU General Public License for more details. |
| 12 | */ |
| 13 | |
Eric Biederman | dbec2d4 | 2004-10-21 10:44:08 +0000 | [diff] [blame] | 14 | #include "amd8111_smbus.h" |
| 15 | |
Eric Biederman | 3d3f438 | 2003-07-12 01:48:30 +0000 | [diff] [blame] | 16 | #define SMBUS_IO_BASE 0x0f00 |
Eric Biederman | 05f26fc | 2003-06-11 21:55:00 +0000 | [diff] [blame] | 17 | |
Eric Biederman | 05f26fc | 2003-06-11 21:55:00 +0000 | [diff] [blame] | 18 | static void enable_smbus(void) |
| 19 | { |
Antonello Dettori | bf4224c | 2016-09-03 10:45:33 +0200 | [diff] [blame] | 20 | pci_devfn_t dev; |
Marc Jones | 0da5cde | 2007-12-19 01:36:46 +0000 | [diff] [blame] | 21 | uint8_t enable; |
| 22 | |
Eric Biederman | 540ae01 | 2003-06-12 17:55:54 +0000 | [diff] [blame] | 23 | dev = pci_locate_device(PCI_ID(0x1022, 0x746b), 0); |
| 24 | if (dev == PCI_DEV_INVALID) { |
Stefan Reinauer | 64ed2b7 | 2010-03-31 14:47:43 +0000 | [diff] [blame] | 25 | die("SMBUS controller not found\n"); |
Eric Biederman | 05f26fc | 2003-06-11 21:55:00 +0000 | [diff] [blame] | 26 | } |
Marc Jones | 0da5cde | 2007-12-19 01:36:46 +0000 | [diff] [blame] | 27 | |
Eric Biederman | 540ae01 | 2003-06-12 17:55:54 +0000 | [diff] [blame] | 28 | pci_write_config32(dev, 0x58, SMBUS_IO_BASE | 1); |
| 29 | enable = pci_read_config8(dev, 0x41); |
| 30 | pci_write_config8(dev, 0x41, enable | (1 << 7)); |
Marc Jones | 0da5cde | 2007-12-19 01:36:46 +0000 | [diff] [blame] | 31 | |
| 32 | /* check that we can see the smbus controller I/O. */ |
| 33 | if (inw(SMBUS_IO_BASE)==0xFF){ |
| 34 | die("SMBUS controller I/O not found\n"); |
| 35 | } |
| 36 | |
Eric Biederman | 83b991a | 2003-10-11 06:20:25 +0000 | [diff] [blame] | 37 | /* clear any lingering errors, so the transaction will run */ |
| 38 | outw(inw(SMBUS_IO_BASE + SMBGSTATUS), SMBUS_IO_BASE + SMBGSTATUS); |
Stefan Reinauer | 5ab52dd | 2015-01-05 13:01:01 -0800 | [diff] [blame] | 39 | printk(BIOS_SPEW, "SMBus controller enabled\n"); |
Eric Biederman | 05f26fc | 2003-06-11 21:55:00 +0000 | [diff] [blame] | 40 | } |
| 41 | |
Stefan Reinauer | 467a065 | 2010-04-25 14:37:18 +0000 | [diff] [blame] | 42 | static inline int smbus_recv_byte(unsigned device) |
Eric Biederman | 05f26fc | 2003-06-11 21:55:00 +0000 | [diff] [blame] | 43 | { |
Eric Biederman | dbec2d4 | 2004-10-21 10:44:08 +0000 | [diff] [blame] | 44 | return do_smbus_recv_byte(SMBUS_IO_BASE, device); |
Eric Biederman | 05f26fc | 2003-06-11 21:55:00 +0000 | [diff] [blame] | 45 | } |
| 46 | |
Stefan Reinauer | 467a065 | 2010-04-25 14:37:18 +0000 | [diff] [blame] | 47 | static inline int smbus_send_byte(unsigned device, unsigned char val) |
Eric Biederman | 05f26fc | 2003-06-11 21:55:00 +0000 | [diff] [blame] | 48 | { |
Eric Biederman | dbec2d4 | 2004-10-21 10:44:08 +0000 | [diff] [blame] | 49 | return do_smbus_send_byte(SMBUS_IO_BASE, device, val); |
Eric Biederman | 05f26fc | 2003-06-11 21:55:00 +0000 | [diff] [blame] | 50 | } |
| 51 | |
Stefan Reinauer | 467a065 | 2010-04-25 14:37:18 +0000 | [diff] [blame] | 52 | static inline int smbus_read_byte(unsigned device, unsigned address) |
Eric Biederman | 05f26fc | 2003-06-11 21:55:00 +0000 | [diff] [blame] | 53 | { |
Eric Biederman | dbec2d4 | 2004-10-21 10:44:08 +0000 | [diff] [blame] | 54 | return do_smbus_read_byte(SMBUS_IO_BASE, device, address); |
Eric Biederman | 05f26fc | 2003-06-11 21:55:00 +0000 | [diff] [blame] | 55 | } |
Stefan Reinauer | a84c6f8 | 2003-10-06 15:04:41 +0000 | [diff] [blame] | 56 | |
Stefan Reinauer | 467a065 | 2010-04-25 14:37:18 +0000 | [diff] [blame] | 57 | static inline int smbus_write_byte(unsigned device, unsigned address, unsigned char val) |
Stefan Reinauer | a84c6f8 | 2003-10-06 15:04:41 +0000 | [diff] [blame] | 58 | { |
Eric Biederman | dbec2d4 | 2004-10-21 10:44:08 +0000 | [diff] [blame] | 59 | return do_smbus_write_byte(SMBUS_IO_BASE, device, address, val); |
Stefan Reinauer | a84c6f8 | 2003-10-06 15:04:41 +0000 | [diff] [blame] | 60 | } |
Stefan Reinauer | 467a065 | 2010-04-25 14:37:18 +0000 | [diff] [blame] | 61 | |
Oskar Enoksson | 9bfa1c8 | 2011-10-14 02:16:48 +0200 | [diff] [blame] | 62 | static inline int smbus_block_read(unsigned device, unsigned cmd, u8 bytes, u8 *buf) |
| 63 | { |
| 64 | return do_smbus_block_read(SMBUS_IO_BASE, device, cmd, bytes, buf); |
| 65 | } |
| 66 | |
| 67 | static inline int smbus_block_write(unsigned device, unsigned cmd, u8 bytes, const u8 *buf) |
| 68 | { |
| 69 | return do_smbus_block_write(SMBUS_IO_BASE, device, cmd, bytes, buf); |
| 70 | } |