blob: 5773ae272ac21c6d43befdfd4b1aceb146c9aa7b [file] [log] [blame]
Michael Xie7586cef2008-09-22 13:11:39 +00001/*
2 * This file is part of the coreboot project.
3 *
4 * Copyright (C) 2008 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.
Michael Xie7586cef2008-09-22 13:11:39 +000014 */
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>
Michael Xie7586cef2008-09-22 13:11:39 +000023#include <arch/io.h>
24#include <cpu/x86/lapic.h>
Stefan Reinauer0401bd82010-01-16 18:31:34 +000025#include <arch/ioapic.h>
Carl-Daniel Hailfinger2ee67792008-10-01 12:52:52 +000026#include <stdlib.h>
Michael Xie7586cef2008-09-22 13:11:39 +000027#include "sb600.h"
stepan836ae292010-12-08 05:42:47 +000028#include "smbus.c"
Michael Xie7586cef2008-09-22 13:11:39 +000029
30#define NMI_OFF 0
31
32#define MAINBOARD_POWER_OFF 0
33#define MAINBOARD_POWER_ON 1
34
Stefan Reinauer08670622009-06-30 15:17:49 +000035#ifndef CONFIG_MAINBOARD_POWER_ON_AFTER_POWER_FAIL
36#define CONFIG_MAINBOARD_POWER_ON_AFTER_POWER_FAIL MAINBOARD_POWER_ON
Michael Xie7586cef2008-09-22 13:11:39 +000037#endif
38
Michael Xie7586cef2008-09-22 13:11:39 +000039/*
40* SB600 enables all USB controllers by default in SMBUS Control.
41* SB600 enables SATA by default in SMBUS Control.
42*/
43static void sm_init(device_t dev)
44{
45 u8 byte;
46 u8 byte_old;
47 u32 dword;
Joe Bao164463c2008-12-01 19:37:21 +000048 u32 ioapic_base;
49 u32 on;
50 u32 nmi_option;
Michael Xie7586cef2008-09-22 13:11:39 +000051
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +000052 printk(BIOS_INFO, "sm_init().\n");
Michael Xie7586cef2008-09-22 13:11:39 +000053
54 ioapic_base = pci_read_config32(dev, 0x74) & (0xffffffe0); /* some like mem resource, but does not have enable bit */
Stefan Reinauer0401bd82010-01-16 18:31:34 +000055 /* Don't rename APIC ID */
Kevin Paul Herbertbde6d302014-12-24 18:43:20 -080056 clear_ioapic((void *)ioapic_base);
Michael Xie7586cef2008-09-22 13:11:39 +000057
58 dword = pci_read_config8(dev, 0x62);
59 dword |= 1 << 2;
60 pci_write_config8(dev, 0x62, dword);
61
62 dword = pci_read_config32(dev, 0x78);
63 dword |= 1 << 9;
64 pci_write_config32(dev, 0x78, dword); /* enable 0xCD6 0xCD7 */
65
Joe Bao164463c2008-12-01 19:37:21 +000066 /* bit 10: MultiMediaTimerIrqEn */
67 dword = pci_read_config8(dev, 0x64);
68 dword |= 1 << 10;
69 pci_write_config8(dev, 0x64, dword);
Michael Xie7586cef2008-09-22 13:11:39 +000070 /* enable serial irq */
71 byte = pci_read_config8(dev, 0x69);
72 byte |= 1 << 7; /* enable serial irq function */
73 byte &= ~(0xF << 2);
74 byte |= 4 << 2; /* set NumSerIrqBits=4 */
75 pci_write_config8(dev, 0x69, byte);
76
77 byte = pm_ioread(0x61);
78 byte |= 1 << 1; /* Set to enable NB/SB handshake during IOAPIC interrupt for AMD K8/K7 */
79 pm_iowrite(0x61, byte);
80
81 /* disable SMI */
82 byte = pm_ioread(0x53);
83 byte |= 1 << 3;
84 pm_iowrite(0x53, byte);
85
86 /* power after power fail */
Stefan Reinauer08670622009-06-30 15:17:49 +000087 on = CONFIG_MAINBOARD_POWER_ON_AFTER_POWER_FAIL;
Luc Verhaegena9c5ea02009-06-03 14:19:33 +000088 get_option(&on, "power_on_after_fail");
Michael Xie7586cef2008-09-22 13:11:39 +000089 byte = pm_ioread(0x74);
90 byte &= ~0x03;
91 if (on) {
Josef Kellermannea1c0a72011-03-17 12:34:15 +000092 byte |= 1 << 0;
Michael Xie7586cef2008-09-22 13:11:39 +000093 }
94 byte |= 1 << 2;
95 pm_iowrite(0x74, byte);
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +000096 printk(BIOS_INFO, "set power %s after power fail\n", on ? "on" : "off");
Michael Xie7586cef2008-09-22 13:11:39 +000097
98 /* sb600 rpr:2.3.3: */
99 byte = pm_ioread(0x9A);
100 byte |= 1 << 5 | 1 << 4 | 1 << 2;
101 pm_iowrite(0x9A, byte);
102
103 byte = pm_ioread(0x8F);
104 byte |= 1 << 5;
105 byte &= ~(1 << 4);
106 pm_iowrite(0x8F, byte);
107
108 pm_iowrite(0x8B, 0x01);
109 pm_iowrite(0x8A, 0x90);
110 pm_iowrite(0x88, 0x10); /* A21 */
111
112 byte = pm_ioread(0x7C);
113 byte |= 1 << 0;
114 pm_iowrite(0x7C, byte);
115
116 byte = pm_ioread(0x68);
117 byte &= ~(1 << 1);
Joe Bao164463c2008-12-01 19:37:21 +0000118 /* 2.6 */
119 byte |= 1 << 2;
Michael Xie7586cef2008-09-22 13:11:39 +0000120 pm_iowrite(0x68, byte);
121
Joe Bao164463c2008-12-01 19:37:21 +0000122 /* 2.6 */
123 byte = pm_ioread(0x65);
124 byte &= ~(1 << 7);
125 pm_iowrite(0x65, byte);
126
127 /* 2.3.4 */
128 byte = pm_ioread(0x52);
129 byte &= ~0x2F;
130 byte |= 0x8;
131 pm_iowrite(0x52, byte);
132
Michael Xie7586cef2008-09-22 13:11:39 +0000133 byte = pm_ioread(0x8D);
134 byte &= ~(1 << 6);
135 pm_iowrite(0x8D, byte);
136
137 byte = pm_ioread(0x61);
138 byte &= ~(1 << 2);
139 pm_iowrite(0x61, byte);
140
141 byte = pm_ioread(0x42);
142 byte &= ~(1 << 2);
143 pm_iowrite(0x42, byte);
144
145 /* Set up NMI on errors */
146 byte = inb(0x70); /* RTC70 */
147 byte_old = byte;
148 nmi_option = NMI_OFF;
Luc Verhaegena9c5ea02009-06-03 14:19:33 +0000149 get_option(&nmi_option, "nmi");
Michael Xie7586cef2008-09-22 13:11:39 +0000150 if (nmi_option) {
151 byte &= ~(1 << 7); /* set NMI */
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +0000152 printk(BIOS_INFO, "++++++++++set NMI+++++\n");
Michael Xie7586cef2008-09-22 13:11:39 +0000153 } else {
154 byte |= (1 << 7); /* Can not mask NMI from PCI-E and NMI_NOW */
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +0000155 printk(BIOS_INFO, "++++++++++no set NMI+++++\n");
Michael Xie7586cef2008-09-22 13:11:39 +0000156 }
157 byte &= ~(1 << 7);
158 if (byte != byte_old) {
159 outb(byte, 0x70);
160 }
161
162 /* 2.10 IO Trap Settings */
163 abcfg_reg(0x10090, 1 << 16, 1 << 16);
164
165 /* ab index */
166 pci_write_config32(dev, 0xF0, AB_INDX);
167 /* Initialize the real time clock */
Gabe Blackb3f08c62014-04-30 17:12:25 -0700168 cmos_init(0);
Michael Xie7586cef2008-09-22 13:11:39 +0000169
170 /*3.4 Enabling IDE/PCIB Prefetch for Performance Enhancement */
171 abcfg_reg(0x10060, 9 << 17, 9 << 17);
172 abcfg_reg(0x10064, 9 << 17, 9 << 17);
173
174 /* 3.5 Enabling OHCI Prefetch for Performance Enhancement */
175 abcfg_reg(0x80, 1 << 0, 1<< 0);
176
177 /* 3.6 B-Link Client's Credit Variable Settings for the Downstream Arbitration Equation */
178 /* 3.7 Enabling Additional Address Bits Checking in Downstream */
179 abcfg_reg(0x9c, 3 << 0, 3 << 0);
180
181 /* 3.8 Set B-Link Prefetch Mode */
182 abcfg_reg(0x80, 3 << 17, 3 << 17);
183
184 /* 3.9 Enabling Detection of Upstream Interrupts */
185 abcfg_reg(0x94, 1 << 20,1 << 20);
186
187 /* 3.10: Enabling Downstream Posted Transactions to Pass Non-Posted
188 * Transactions for the K8 Platform (for All Revisions) */
189 abcfg_reg(0x10090, 1 << 8, 1 << 8);
190
191 /* 3.11:Programming Cycle Delay for AB and BIF Clock Gating */
192 /* 3.12: Enabling AB and BIF Clock Gating */
193 abcfg_reg(0x10054, 0xFFFF0000, 0x1040000);
194 abcfg_reg(0x54, 0xFF << 16, 4 << 16);
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +0000195 printk(BIOS_INFO, "3.11, ABCFG:0x54\n");
Michael Xie7586cef2008-09-22 13:11:39 +0000196 abcfg_reg(0x54, 1 << 24, 1 << 24);
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +0000197 printk(BIOS_INFO, "3.12, ABCFG:0x54\n");
Michael Xie7586cef2008-09-22 13:11:39 +0000198 abcfg_reg(0x98, 0x0000FF00, 0x00004700);
199
200 /* 3.13:Enabling AB Int_Arbiter Enhancement (for All Revisions) */
201 abcfg_reg(0x10054, 0x0000FFFF, 0x07FF);
202
203 /* 3.14:Enabling L1 on A-link Express */
204 axcfg_reg(0x68, 0x00000003, 0x2);
205 axindxp_reg(0xa0, 0x0000F000, 0x6000);
206
207 abcfg_reg(0x10098, 0xFFFFFFFF, 0x4000);
208 abcfg_reg(0x04, 0xFFFFFFFF, 0x6);
Stefan Reinauerc02b4fc2010-03-22 11:42:32 +0000209 printk(BIOS_INFO, "sm_init() end\n");
Michael Xie7586cef2008-09-22 13:11:39 +0000210
211 /* Enable NbSb virtual channel */
212 axcfg_reg(0x114, 0x3f << 1, 0 << 1);
213 axcfg_reg(0x120, 0x7f << 1, 0x7f << 1);
214 axcfg_reg(0x120, 7 << 24, 1 << 24);
215 axcfg_reg(0x120, 1 << 31, 1 << 31);
216 abcfg_reg(0x50, 1 << 3, 1 << 3);
217}
218
219static int lsmbus_recv_byte(device_t dev)
220{
221 u32 device;
222 struct resource *res;
223 struct bus *pbus;
224
Stefan Reinauer2b34db82009-02-28 20:10:20 +0000225 device = dev->path.i2c.device;
Michael Xie7586cef2008-09-22 13:11:39 +0000226 pbus = get_pbus_smbus(dev);
227
228 res = find_resource(pbus->dev, 0x10);
229
230 return do_smbus_recv_byte(res->base, device);
231}
232
233static int lsmbus_send_byte(device_t dev, u8 val)
234{
235 u32 device;
236 struct resource *res;
237 struct bus *pbus;
238
Stefan Reinauer2b34db82009-02-28 20:10:20 +0000239 device = dev->path.i2c.device;
Michael Xie7586cef2008-09-22 13:11:39 +0000240 pbus = get_pbus_smbus(dev);
241
242 res = find_resource(pbus->dev, 0x10);
243
244 return do_smbus_send_byte(res->base, device, val);
245}
246
247static int lsmbus_read_byte(device_t dev, u8 address)
248{
249 u32 device;
250 struct resource *res;
251 struct bus *pbus;
252
Stefan Reinauer2b34db82009-02-28 20:10:20 +0000253 device = dev->path.i2c.device;
Michael Xie7586cef2008-09-22 13:11:39 +0000254 pbus = get_pbus_smbus(dev);
255
256 res = find_resource(pbus->dev, 0x10);
257
258 return do_smbus_read_byte(res->base, device, address);
259}
260
261static int lsmbus_write_byte(device_t dev, u8 address, u8 val)
262{
263 u32 device;
264 struct resource *res;
265 struct bus *pbus;
266
Stefan Reinauer2b34db82009-02-28 20:10:20 +0000267 device = dev->path.i2c.device;
Michael Xie7586cef2008-09-22 13:11:39 +0000268 pbus = get_pbus_smbus(dev);
269
270 res = find_resource(pbus->dev, 0x10);
271
272 return do_smbus_write_byte(res->base, device, address, val);
273}
274static struct smbus_bus_operations lops_smbus_bus = {
275 .recv_byte = lsmbus_recv_byte,
276 .send_byte = lsmbus_send_byte,
277 .read_byte = lsmbus_read_byte,
278 .write_byte = lsmbus_write_byte,
279};
280
281static void sb600_sm_read_resources(device_t dev)
282{
283 struct resource *res;
Joe Bao164463c2008-12-01 19:37:21 +0000284 u8 byte;
285
286 /* rpr2.14: Hides SM bus controller Bar1 where stores HPET MMIO base address */
287 byte = pm_ioread(0x55);
288 byte |= 1 << 7;
289 pm_iowrite(0x55, byte);
Michael Xie7586cef2008-09-22 13:11:39 +0000290
291 /* Get the normal pci resources of this device */
Joe Bao164463c2008-12-01 19:37:21 +0000292 /* pci_dev_read_resources(dev); */
293
294 byte = pm_ioread(0x55);
295 byte &= ~(1 << 7);
296 pm_iowrite(0x55, byte);
Michael Xie7586cef2008-09-22 13:11:39 +0000297
298 /* apic */
299 res = new_resource(dev, 0x74);
Uwe Hermann74d1a6e2010-10-12 17:34:08 +0000300 res->base = IO_APIC_ADDR;
Michael Xie7586cef2008-09-22 13:11:39 +0000301 res->size = 256 * 0x10;
302 res->limit = 0xFFFFFFFFUL; /* res->base + res->size -1; */
303 res->align = 8;
304 res->gran = 8;
305 res->flags = IORESOURCE_MEM | IORESOURCE_FIXED;
306
Joe Bao164463c2008-12-01 19:37:21 +0000307 res = new_resource(dev, 0x14); /* hpet */
Martin Roth1e1c7ac2015-12-10 08:19:27 -0700308 res->base = HPET_BASE_ADDRESS; /* reset hpet to widely accepted address */
Joe Bao164463c2008-12-01 19:37:21 +0000309 res->size = 0x400;
310 res->limit = 0xFFFFFFFFUL; /* res->base + res->size -1; */
311 res->align = 8;
312 res->gran = 8;
313 res->flags = IORESOURCE_MEM | IORESOURCE_FIXED;
Michael Xie7586cef2008-09-22 13:11:39 +0000314 /* dev->command |= PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER; */
315
Joe Bao164463c2008-12-01 19:37:21 +0000316 /* smbus */
317 res = new_resource(dev, 0x10);
318 res->base = 0xB00;
319 res->size = 0x10;
320 res->limit = 0xFFFFUL; /* res->base + res->size -1; */
321 res->align = 8;
322 res->gran = 8;
323 res->flags = IORESOURCE_IO | IORESOURCE_FIXED;
324
Michael Xie7586cef2008-09-22 13:11:39 +0000325 compact_resources(dev);
326
327}
Uwe Hermannff492b12010-09-24 23:37:25 +0000328
Michael Xie7586cef2008-09-22 13:11:39 +0000329static void sb600_sm_set_resources(struct device *dev)
330{
331 struct resource *res;
Joe Bao164463c2008-12-01 19:37:21 +0000332 u8 byte;
Michael Xie7586cef2008-09-22 13:11:39 +0000333
334 pci_dev_set_resources(dev);
335
Zheng Bao2a5101a2010-10-10 15:18:53 +0000336 /* rpr2.14: Make HPET MMIO decoding controlled by the memory enable bit in command register of LPC ISA bridge */
Joe Bao164463c2008-12-01 19:37:21 +0000337 byte = pm_ioread(0x52);
338 byte |= 1 << 6;
339 pm_iowrite(0x52, byte);
340
Michael Xie7586cef2008-09-22 13:11:39 +0000341 res = find_resource(dev, 0x74);
342 pci_write_config32(dev, 0x74, res->base | 1 << 3);
Joe Bao164463c2008-12-01 19:37:21 +0000343
344 res = find_resource(dev, 0x14);
345 pci_write_config32(dev, 0x14, res->base);
346
347 res = find_resource(dev, 0x10);
348 pci_write_config32(dev, 0x10, res->base | 1);
Michael Xie7586cef2008-09-22 13:11:39 +0000349}
350
351static struct pci_operations lops_pci = {
352 .set_subsystem = pci_dev_set_subsystem,
353};
Uwe Hermannff492b12010-09-24 23:37:25 +0000354
Michael Xie7586cef2008-09-22 13:11:39 +0000355static struct device_operations smbus_ops = {
356 .read_resources = sb600_sm_read_resources,
357 .set_resources = sb600_sm_set_resources,
358 .enable_resources = pci_dev_enable_resources,
359 .init = sm_init,
Kyösti Mälkkid0e212c2015-02-26 20:47:47 +0200360 .scan_bus = scan_smbus,
Michael Xie7586cef2008-09-22 13:11:39 +0000361 /* .enable = sb600_enable, */
362 .ops_pci = &lops_pci,
363 .ops_smbus_bus = &lops_smbus_bus,
364};
Uwe Hermannff492b12010-09-24 23:37:25 +0000365
Stefan Reinauer8e96ba22010-03-16 23:33:29 +0000366static const struct pci_driver smbus_driver __pci_driver = {
Michael Xie7586cef2008-09-22 13:11:39 +0000367 .ops = &smbus_ops,
368 .vendor = PCI_VENDOR_ID_ATI,
369 .device = PCI_DEVICE_ID_ATI_SB600_SM,
370};