printk_foo -> printk(BIOS_FOO, ...)
[coreboot.git] / src / southbridge / amd / sb700 / sb700.c
1 /*
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  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
18  */
19
20 #include <console/console.h>
21
22 #include <arch/io.h>
23
24 #include <device/device.h>
25 #include <device/pci.h>
26 #include <device/pci_ids.h>
27 #include <device/pci_ops.h>
28 #include "sb700.h"
29
30 static device_t find_sm_dev(device_t dev, u32 devfn)
31 {
32         device_t sm_dev;
33
34         sm_dev = dev_find_slot(dev->bus->secondary, devfn);
35         if (!sm_dev)
36                 return sm_dev;
37
38         if ((sm_dev->vendor != PCI_VENDOR_ID_ATI) ||
39             ((sm_dev->device != PCI_DEVICE_ID_ATI_SB700_SM))) {
40                 u32 id;
41                 id = pci_read_config32(sm_dev, PCI_VENDOR_ID);
42                 if ((id !=
43                      (PCI_VENDOR_ID_ATI | (PCI_DEVICE_ID_ATI_SB700_SM << 16))))
44                 {
45                         sm_dev = 0;
46                 }
47         }
48
49         return sm_dev;
50 }
51
52 void set_sm_enable_bits(device_t sm_dev, u32 reg_pos, u32 mask, u32 val)
53 {
54         u32 reg_old, reg;
55         reg = reg_old = pci_read_config32(sm_dev, reg_pos);
56         reg &= ~mask;
57         reg |= val;
58         if (reg != reg_old) {
59                 pci_write_config32(sm_dev, reg_pos, reg);
60         }
61 }
62
63 static void pmio_write_index(u16 port_base, u8 reg, u8 value)
64 {
65         outb(reg, port_base);
66         outb(value, port_base + 1);
67 }
68
69 static u8 pmio_read_index(u16 port_base, u8 reg)
70 {
71         outb(reg, port_base);
72         return inb(port_base + 1);
73 }
74
75 void pm_iowrite(u8 reg, u8 value)
76 {
77         pmio_write_index(PM_INDEX, reg, value);
78 }
79
80 u8 pm_ioread(u8 reg)
81 {
82         return pmio_read_index(PM_INDEX, reg);
83 }
84
85 void pm2_iowrite(u8 reg, u8 value)
86 {
87         pmio_write_index(PM2_INDEX, reg, value);
88 }
89
90 u8 pm2_ioread(u8 reg)
91 {
92         return pmio_read_index(PM2_INDEX, reg);
93 }
94
95 static void set_pmio_enable_bits(device_t sm_dev, u32 reg_pos,
96                                  u32 mask, u32 val)
97 {
98         u8 reg_old, reg;
99         reg = reg_old = pm_ioread(reg_pos);
100         reg &= ~mask;
101         reg |= val;
102         if (reg != reg_old) {
103                 pm_iowrite(reg_pos, reg);
104         }
105 }
106
107 void sb700_enable(device_t dev)
108 {
109         device_t sm_dev = 0;
110         device_t bus_dev = 0;
111         int index = -1;
112         u32 deviceid;
113         u32 vendorid;
114
115         /* struct southbridge_ati_sb700_config *conf; */
116         /* conf = dev->chip_info; */
117         int i;
118
119         u32 devfn;
120
121         printk(BIOS_DEBUG, "sb700_enable()\n");
122
123 /*
124 *       0:11.0  SATA    bit 8 of sm_dev 0xac : 1 - enable, default         + 32 * 3
125 *       0:12.0  OHCI0-USB1      bit 0 of sm_dev 0x68
126 *       0:12.1  OHCI1-USB1      bit 1 of sm_dev 0x68
127 *       0:12.2  EHCI-USB1       bit 2 of sm_dev 0x68
128 *       0:13.0  OHCI0-USB2      bit 4 of sm_dev 0x68
129 *       0:13.1  OHCI1-USB2      bit 5 of sm_dev 0x68
130 *       0:13.2  EHCI-USB2       bit 6 of sm_dev 0x68
131 *       0:14.5  OHCI0-USB3      bit 7 of sm_dev 0x68
132 *       0:14.0  SMBUS                                                   0
133 *       0:14.1  IDE                                                     1
134 *       0:14.2  HDA     bit 3 of pm_io 0x59 : 1 - enable, default           + 32 * 4
135 *       0:14.3  LPC     bit 20 of sm_dev 0x64 : 0 - disable, default  + 32 * 1
136 *       0:14.4  PCI                                                     4
137 */
138         if (dev->device == 0x0000) {
139                 vendorid = pci_read_config32(dev, PCI_VENDOR_ID);
140                 deviceid = (vendorid >> 16) & 0xffff;
141                 vendorid &= 0xffff;
142         } else {
143                 vendorid = dev->vendor;
144                 deviceid = dev->device;
145         }
146         bus_dev = dev->bus->dev;
147         if ((bus_dev->vendor == PCI_VENDOR_ID_ATI) &&
148             (bus_dev->device == PCI_DEVICE_ID_ATI_SB700_PCI)) {
149                 devfn = (bus_dev->path.pci.devfn) & ~7;
150                 sm_dev = find_sm_dev(bus_dev, devfn);
151                 if (!sm_dev)
152                         return;
153
154                 /* something under 00:01.0 */
155                 switch (dev->path.pci.devfn) {
156                 case 5 << 3:
157                         ;
158                 }
159
160                 return;
161         }
162
163         i = (dev->path.pci.devfn) & ~7;
164         i += (2 << 3);
165         for (devfn = (0x14 << 3); devfn <= i; devfn += (1 << 3)) {
166                 sm_dev = find_sm_dev(dev, devfn);
167                 if (sm_dev)
168                         break;
169         }
170         if (!sm_dev)
171                 return;
172
173         switch (dev->path.pci.devfn - (devfn - (0x14 << 3))) {
174         case (0x11 << 3) | 0:
175                 index = 8;
176                 set_sm_enable_bits(sm_dev, 0xac, 1 << index,
177                                    (dev->enabled ? 1 : 0) << index);
178                 index += 32 * 3;
179                 break;
180         case (0x12 << 3) | 0:
181         case (0x12 << 3) | 1:
182         case (0x12 << 3) | 2:
183                 index = dev->path.pci.devfn & 3;
184                 set_sm_enable_bits(sm_dev, 0x68, 1 << index,
185                                    (dev->enabled ? 1 : 0) << index);
186                 index += 32 * 2;
187                 break;
188         case (0x13 << 3) | 0:
189         case (0x13 << 3) | 1:
190         case (0x13 << 3) | 2:
191                 index = (dev->path.pci.devfn & 3) + 4;
192                 set_sm_enable_bits(sm_dev, 0x68, 1 << index,
193                                    (dev->enabled ? 1 : 0) << index);
194                 index += 32 * 2;
195                 break;
196         case (0x14 << 3) | 5:
197                 index = 7;
198                 set_sm_enable_bits(sm_dev, 0x68, 1 << index,
199                                    (dev->enabled ? 1 : 0) << index);
200                 index += 32 * 2;
201                 break;
202         case (0x14 << 3) | 0:
203                 index = 0;
204                 break;
205         case (0x14 << 3) | 1:
206                 index = 1;
207                 break;
208         case (0x14 << 3) | 2:
209                 index = 3;
210                 set_pmio_enable_bits(sm_dev, 0x59, 1 << index,
211                                      (dev->enabled ? 1 : 0) << index);
212                 index += 32 * 4;
213                 break;
214         case (0x14 << 3) | 3:
215                 index = 20;
216                 set_sm_enable_bits(sm_dev, 0x64, 1 << index,
217                                    (dev->enabled ? 1 : 0) << index);
218                 index += 32 * 1;
219                 break;
220         case (0x14 << 3) | 4:
221                 index = 4;
222                 break;
223         default:
224                 printk(BIOS_DEBUG, "unknown dev: %s deviceid=%4x\n", dev_path(dev),
225                              deviceid);
226         }
227 }
228
229 struct chip_operations southbridge_amd_sb700_ops = {
230         CHIP_NAME("ATI SB700")
231         .enable_dev = sb700_enable,
232 };