Yinghai Lu | c65bd56 | 2007-02-01 00:10:05 +0000 | [diff] [blame] | 1 | /* |
Stefan Reinauer | 7e61e45 | 2008-01-18 10:35:56 +0000 | [diff] [blame] | 2 | * This file is part of the coreboot project. |
Yinghai Lu | c65bd56 | 2007-02-01 00:10:05 +0000 | [diff] [blame] | 3 | * |
| 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 Lu | c65bd56 | 2007-02-01 00:10:05 +0000 | [diff] [blame] | 18 | */ |
| 19 | |
stepan | 836ae29 | 2010-12-08 05:42:47 +0000 | [diff] [blame] | 20 | #include "smbus.h" |
Yinghai Lu | c65bd56 | 2007-02-01 00:10:05 +0000 | [diff] [blame] | 21 | |
| 22 | #define SMBUS0_IO_BASE 0x1000 |
Uwe Hermann | c7f0c8f | 2011-01-04 19:51:33 +0000 | [diff] [blame] | 23 | #define SMBUS1_IO_BASE (0x1000 + (1 << 8)) |
| 24 | /* Size: 0x40 */ |
Yinghai Lu | c65bd56 | 2007-02-01 00:10:05 +0000 | [diff] [blame] | 25 | |
| 26 | static void enable_smbus(void) |
| 27 | { |
Antonello Dettori | 8126daf | 2016-09-03 10:45:33 +0200 | [diff] [blame] | 28 | pci_devfn_t dev; |
Yinghai Lu | c65bd56 | 2007-02-01 00:10:05 +0000 | [diff] [blame] | 29 | dev = pci_locate_device(PCI_ID(0x10de, 0x0368), 0); |
Stefan Reinauer | d55e26f | 2010-04-25 13:54:30 +0000 | [diff] [blame] | 30 | |
Ward Vandewege | f648d61 | 2010-11-08 17:41:43 +0000 | [diff] [blame] | 31 | if (dev == PCI_DEV_INVALID) |
| 32 | die("SMBus controller not found\n"); |
Yinghai Lu | c65bd56 | 2007-02-01 00:10:05 +0000 | [diff] [blame] | 33 | |
Uwe Hermann | c7f0c8f | 2011-01-04 19:51:33 +0000 | [diff] [blame] | 34 | /* Set SMBus I/O base. */ |
Yinghai Lu | c65bd56 | 2007-02-01 00:10:05 +0000 | [diff] [blame] | 35 | pci_write_config32(dev, 0x20, SMBUS0_IO_BASE | 1); |
| 36 | pci_write_config32(dev, 0x24, SMBUS1_IO_BASE | 1); |
Uwe Hermann | c7f0c8f | 2011-01-04 19:51:33 +0000 | [diff] [blame] | 37 | |
| 38 | /* Set SMBus I/O space enable. */ |
Yinghai Lu | c65bd56 | 2007-02-01 00:10:05 +0000 | [diff] [blame] | 39 | pci_write_config16(dev, 0x4, 0x01); |
Uwe Hermann | c7f0c8f | 2011-01-04 19:51:33 +0000 | [diff] [blame] | 40 | |
| 41 | /* Clear any lingering errors, so the transaction will run. */ |
Yinghai Lu | c65bd56 | 2007-02-01 00:10:05 +0000 | [diff] [blame] | 42 | outb(inb(SMBUS0_IO_BASE + SMBHSTSTAT), SMBUS0_IO_BASE + SMBHSTSTAT); |
| 43 | outb(inb(SMBUS1_IO_BASE + SMBHSTSTAT), SMBUS1_IO_BASE + SMBHSTSTAT); |
| 44 | } |
| 45 | |
Stefan Reinauer | d55e26f | 2010-04-25 13:54:30 +0000 | [diff] [blame] | 46 | static inline int smbus_recv_byte(unsigned device) |
Yinghai Lu | c65bd56 | 2007-02-01 00:10:05 +0000 | [diff] [blame] | 47 | { |
| 48 | return do_smbus_recv_byte(SMBUS0_IO_BASE, device); |
| 49 | } |
Stefan Reinauer | d55e26f | 2010-04-25 13:54:30 +0000 | [diff] [blame] | 50 | |
| 51 | static inline int smbus_send_byte(unsigned device, unsigned char val) |
Yinghai Lu | c65bd56 | 2007-02-01 00:10:05 +0000 | [diff] [blame] | 52 | { |
| 53 | return do_smbus_send_byte(SMBUS0_IO_BASE, device, val); |
| 54 | } |
Stefan Reinauer | d55e26f | 2010-04-25 13:54:30 +0000 | [diff] [blame] | 55 | |
| 56 | static inline int smbus_read_byte(unsigned device, unsigned address) |
Yinghai Lu | c65bd56 | 2007-02-01 00:10:05 +0000 | [diff] [blame] | 57 | { |
| 58 | return do_smbus_read_byte(SMBUS0_IO_BASE, device, address); |
| 59 | } |
Stefan Reinauer | d55e26f | 2010-04-25 13:54:30 +0000 | [diff] [blame] | 60 | |
Uwe Hermann | c7f0c8f | 2011-01-04 19:51:33 +0000 | [diff] [blame] | 61 | static inline int smbus_write_byte(unsigned device, unsigned address, |
| 62 | unsigned char val) |
Yinghai Lu | c65bd56 | 2007-02-01 00:10:05 +0000 | [diff] [blame] | 63 | { |
| 64 | return do_smbus_write_byte(SMBUS0_IO_BASE, device, address, val); |
| 65 | } |
| 66 | |
Stefan Reinauer | d55e26f | 2010-04-25 13:54:30 +0000 | [diff] [blame] | 67 | static inline int smbusx_recv_byte(unsigned smb_index, unsigned device) |
Yinghai Lu | c65bd56 | 2007-02-01 00:10:05 +0000 | [diff] [blame] | 68 | { |
Uwe Hermann | c7f0c8f | 2011-01-04 19:51:33 +0000 | [diff] [blame] | 69 | return do_smbus_recv_byte(SMBUS0_IO_BASE + (smb_index << 8), device); |
Yinghai Lu | c65bd56 | 2007-02-01 00:10:05 +0000 | [diff] [blame] | 70 | } |
Stefan Reinauer | d55e26f | 2010-04-25 13:54:30 +0000 | [diff] [blame] | 71 | |
Uwe Hermann | c7f0c8f | 2011-01-04 19:51:33 +0000 | [diff] [blame] | 72 | static inline int smbusx_send_byte(unsigned smb_index, unsigned device, |
| 73 | unsigned char val) |
Yinghai Lu | c65bd56 | 2007-02-01 00:10:05 +0000 | [diff] [blame] | 74 | { |
Uwe Hermann | c7f0c8f | 2011-01-04 19:51:33 +0000 | [diff] [blame] | 75 | return do_smbus_send_byte(SMBUS0_IO_BASE + (smb_index << 8), |
| 76 | device, val); |
Yinghai Lu | c65bd56 | 2007-02-01 00:10:05 +0000 | [diff] [blame] | 77 | } |
Stefan Reinauer | d55e26f | 2010-04-25 13:54:30 +0000 | [diff] [blame] | 78 | |
Uwe Hermann | c7f0c8f | 2011-01-04 19:51:33 +0000 | [diff] [blame] | 79 | static inline int smbusx_read_byte(unsigned smb_index, unsigned device, |
| 80 | unsigned address) |
Yinghai Lu | c65bd56 | 2007-02-01 00:10:05 +0000 | [diff] [blame] | 81 | { |
Uwe Hermann | c7f0c8f | 2011-01-04 19:51:33 +0000 | [diff] [blame] | 82 | return do_smbus_read_byte(SMBUS0_IO_BASE + (smb_index << 8), |
| 83 | device, address); |
Yinghai Lu | c65bd56 | 2007-02-01 00:10:05 +0000 | [diff] [blame] | 84 | } |
Stefan Reinauer | d55e26f | 2010-04-25 13:54:30 +0000 | [diff] [blame] | 85 | |
Uwe Hermann | c7f0c8f | 2011-01-04 19:51:33 +0000 | [diff] [blame] | 86 | static inline int smbusx_write_byte(unsigned smb_index, unsigned device, |
| 87 | unsigned address, unsigned char val) |
Yinghai Lu | c65bd56 | 2007-02-01 00:10:05 +0000 | [diff] [blame] | 88 | { |
Uwe Hermann | c7f0c8f | 2011-01-04 19:51:33 +0000 | [diff] [blame] | 89 | return do_smbus_write_byte(SMBUS0_IO_BASE + (smb_index << 8), |
| 90 | device, address, val); |
Yinghai Lu | c65bd56 | 2007-02-01 00:10:05 +0000 | [diff] [blame] | 91 | } |