AMD Tilapia board support as a demonstration of an AMD Fam10 DDR3 board.
[coreboot.git] / src / mainboard / amd / tilapia_fam10 / mainboard.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 #include <device/device.h>
22 #include <device/pci.h>
23 #include <arch/io.h>
24 #include <boot/tables.h>
25 #include <cpu/x86/msr.h>
26 #include <cpu/amd/mtrr.h>
27 #include <device/pci_def.h>
28 #include <southbridge/amd/sb700/sb700.h>
29 #include "chip.h"
30
31 #define ADT7461_ADDRESS 0x4C
32 #define ARA_ADDRESS     0x0C /* Alert Response Address */
33
34 extern int do_smbus_read_byte(u32 smbus_io_base, u32 device, u32 address);
35 extern int do_smbus_write_byte(u32 smbus_io_base, u32 device, u32 address,
36                                u8 val);
37
38 #define ADT7461_read_byte(address) \
39         do_smbus_read_byte(SMBUS_IO_BASE, ADT7461_ADDRESS, address)
40 #define ARA_read_byte(address) \
41         do_smbus_read_byte(SMBUS_IO_BASE, ARA_ADDRESS, address)
42 #define ADT7461_write_byte(address, val) \
43         do_smbus_write_byte(SMBUS_IO_BASE, ADT7461_ADDRESS, address, val)
44
45 #define SMBUS_IO_BASE 0x6000
46
47 uint64_t uma_memory_base, uma_memory_size;
48
49 void set_pcie_dereset(void);
50 void set_pcie_reset(void);
51
52 void set_pcie_dereset()
53 {
54         u8 byte;
55         u16 word;
56         device_t sm_dev;
57         /* set 0 to bit1 :disable GPM9 as SLP_S2 output */
58         /* set 0 to bit2 :disable GPM8 as AZ_RST output */
59         byte = pm_ioread(0x8d);
60         byte &= ~((1 << 1) | (1 << 2));
61         pm_iowrite(0x8d, byte);
62
63         /* set the GPM8 and GPM9 output enable and the value to 1 */
64         byte = pm_ioread(0x94);
65         byte &= ~((1 << 2) | (1 << 3));
66         byte |=  ((1 << 0) | (1 << 1));
67         pm_iowrite(0x94, byte);
68
69         /* set the GPIO65 output enable and the value is 1 */
70         sm_dev = dev_find_slot(0, PCI_DEVFN(0x14, 0));
71         word = pci_read_config16(sm_dev, 0x7e);
72         word |= (1 << 0);
73         word &= ~(1 << 4);
74         pci_write_config16(sm_dev, 0x7e, word);
75 }
76
77 void set_pcie_reset()
78 {
79         u8 byte;
80         u16 word;
81         device_t sm_dev;
82
83         /* set 0 to bit1 :disable GPM9 as SLP_S2 output */
84         /* set 0 to bit2 :disable GPM8 as AZ_RST output */
85         byte = pm_ioread(0x8d);
86         byte &= ~((1 << 1) | (1 << 2));
87         pm_iowrite(0x8d, byte);
88
89         /* set the GPM8 and GPM9 output enable and the value to 0 */
90         byte = pm_ioread(0x94);
91         byte &= ~((1 << 2) | (1 << 3));
92         byte &= ~((1 << 0) | (1 << 1));
93         pm_iowrite(0x94, byte);
94
95         /* set the GPIO65 output enable and the value is 0 */
96         sm_dev = dev_find_slot(0, PCI_DEVFN(0x14, 0));
97         word = pci_read_config16(sm_dev, 0x7e);
98         word &= ~(1 << 0);
99         word &= ~(1 << 4);
100         pci_write_config16(sm_dev, 0x7e, word);
101 }
102
103 #if 0        /* TODO: */
104 /********************************************************
105 * tilapia uses SB700 GPIO8 to detect IDE_DMA66.
106 * IDE_DMA66 is routed to GPIO 8. So we read Gpio 8 to
107 * get the cable type, 40 pin or 80 pin?
108 ********************************************************/
109 static void get_ide_dma66(void)
110 {
111         u8 byte;
112         /*u32 sm_dev, ide_dev; */
113         device_t sm_dev, ide_dev;
114
115         sm_dev = dev_find_slot(0, PCI_DEVFN(0x14, 0));
116
117         byte = pci_read_config8(sm_dev, 0xA9);
118         byte |= (1 << 4);       /* Set Gpio8 as input */
119         pci_write_config8(sm_dev, 0xA9, byte);
120
121         ide_dev = dev_find_slot(0, PCI_DEVFN(0x14, 1));
122         byte = pci_read_config8(ide_dev, 0x56);
123         byte &= ~(7 << 0);
124         if ((1 << 4) & pci_read_config8(sm_dev, 0xAA))
125                 byte |= 2 << 0; /* mode 2 */
126         else
127                 byte |= 5 << 0; /* mode 5 */
128         pci_write_config8(ide_dev, 0x56, byte);
129 }
130 #endif
131
132 /*
133  * set thermal config
134  */
135 static void set_thermal_config(void)
136 {
137         u8 byte;
138         u16 word;
139         device_t sm_dev;
140
141         /* set ADT 7461 */
142         ADT7461_write_byte(0x0B, 0x50); /* Local Temperature Hight limit */
143         ADT7461_write_byte(0x0C, 0x00); /* Local Temperature Low limit */
144         ADT7461_write_byte(0x0D, 0x50); /* External Temperature Hight limit  High Byte */
145         ADT7461_write_byte(0x0E, 0x00); /* External Temperature Low limit High Byte */
146
147         ADT7461_write_byte(0x19, 0x55); /* External THERM limit */
148         ADT7461_write_byte(0x20, 0x55); /* Local THERM limit */
149
150         byte = ADT7461_read_byte(0x02); /* read status register to clear it */
151         ARA_read_byte(0x05); /* A hardware alert can only be cleared by the master sending an ARA as a read command */
152         printk(BIOS_INFO, "Init adt7461 end , status 0x02 %02x\n", byte);
153
154         /* sb700 settings for thermal config */
155         /* set SB700 GPIO 64 to GPIO with pull-up */
156         byte = pm2_ioread(0x42);
157         byte &= 0x3f;
158         pm2_iowrite(0x42, byte);
159
160         /* set GPIO 64 to input */
161         sm_dev = dev_find_slot(0, PCI_DEVFN(0x14, 0));
162         word = pci_read_config16(sm_dev, 0x56);
163         word |= 1 << 7;
164         pci_write_config16(sm_dev, 0x56, word);
165
166         /* set GPIO 64 internal pull-up */
167         byte = pm2_ioread(0xf0);
168         byte &= 0xee;
169         pm2_iowrite(0xf0, byte);
170
171         /* set Talert to be active low */
172         byte = pm_ioread(0x67);
173         byte &= ~(1 << 5);
174         pm_iowrite(0x67, byte);
175
176         /* set Talert to generate ACPI event */
177         byte = pm_ioread(0x3c);
178         byte &= 0xf3;
179         pm_iowrite(0x3c, byte);
180
181         /* THERMTRIP pin */
182         /* byte = pm_ioread(0x68);
183          * byte |= 1 << 3;
184          * pm_iowrite(0x68, byte);
185          *
186          * byte = pm_ioread(0x55);
187          * byte |= 1 << 0;
188          * pm_iowrite(0x55, byte);
189          *
190          * byte = pm_ioread(0x67);
191          * byte &= ~( 1 << 6);
192          * pm_iowrite(0x67, byte);
193          */
194 }
195
196 /*************************************************
197 * enable the dedicated function in tilapia board.
198 * This function called early than rs780_enable.
199 *************************************************/
200 static void tilapia_enable(device_t dev)
201 {
202         /* Leave it for furture use. */
203         /* struct mainboard_config *mainboard =
204            (struct mainboard_config *)dev->chip_info; */
205
206         printk(BIOS_INFO, "Mainboard TILAPIA Enable. dev=0x%p\n", dev);
207
208 #if (CONFIG_GFXUMA == 1)
209         msr_t msr, msr2;
210
211         /* TOP_MEM: the top of DRAM below 4G */
212         msr = rdmsr(TOP_MEM);
213         printk(BIOS_INFO,
214             "%s, TOP MEM: msr.lo = 0x%08x, msr.hi = 0x%08x\n",
215              __func__, msr.lo, msr.hi);
216
217         /* TOP_MEM2: the top of DRAM above 4G */
218         msr2 = rdmsr(TOP_MEM2);
219         printk(BIOS_INFO,
220             "%s, TOP MEM2: msr2.lo = 0x%08x, msr2.hi = 0x%08x\n",
221              __func__, msr2.lo, msr2.hi);
222
223         switch (msr.lo) {
224         case 0x10000000:        /* 256M system memory */
225                 uma_memory_size = 0x4000000;    /* 64M recommended UMA */
226                 break;
227
228         case 0x20000000:        /* 512M system memory */
229                 uma_memory_size = 0x8000000;    /* 128M recommended UMA */
230                 break;
231
232         default:                /* 1GB and above system memory */
233                 uma_memory_size = 0x10000000;   /* 256M recommended UMA */
234                 break;
235         }
236
237         uma_memory_base = msr.lo - uma_memory_size;     /* TOP_MEM1 */
238         printk(BIOS_INFO, "%s: uma size 0x%08llx, memory start 0x%08llx\n",
239                     __func__, uma_memory_size, uma_memory_base);
240
241         /* TODO: TOP_MEM2 */
242 #else
243         uma_memory_size = 0x8000000;    /* 128M recommended UMA */
244         uma_memory_base = 0x38000000;   /* 1GB  system memory supposed */
245 #endif
246
247         set_pcie_dereset();
248         /* get_ide_dma66(); */
249         set_thermal_config();
250 }
251
252 int add_mainboard_resources(struct lb_memory *mem)
253 {
254         /* UMA is removed from system memory in the northbridge code, but
255          * in some circumstances we want the memory mentioned as reserved.
256          */
257 #if (CONFIG_GFXUMA == 1)
258         printk(BIOS_INFO, "uma_memory_start=0x%llx, uma_memory_size=0x%llx \n",
259                     uma_memory_base, uma_memory_size);
260         lb_add_memory_range(mem, LB_MEM_RESERVED, uma_memory_base,
261                             uma_memory_size);
262 #endif
263         return 0;
264 }
265
266 struct chip_operations mainboard_ops = {
267         CHIP_NAME("AMD TILAPIA   Mainboard")
268         .enable_dev = tilapia_enable,
269 };