blob: 8b5b428f31f9cc4ea100a90ae9ee91fa6542658a [file] [log] [blame]
Oskar Enokssonadc0a632014-02-11 22:19:35 +01001/*
2 * Copyright (c) 2011,2014 Oskar Enoksson <enok@lysator.liu.se>
3 * Subject to the GNU GPL v2, or (at your option) any later version.
4 */
Oskar Enoksson37106a72010-08-20 20:37:27 +00005#include <stdint.h>
6#include <string.h>
7#include <device/pci_def.h>
Oskar Enokssondf073cb2011-10-04 22:15:51 +02008#include <device/pci_ids.h>
Oskar Enoksson37106a72010-08-20 20:37:27 +00009#include <arch/io.h>
10#include <device/pnp_def.h>
Oskar Enoksson37106a72010-08-20 20:37:27 +000011#include <pc80/mc146818rtc.h>
12#include <console/console.h>
Oskar Enoksson37106a72010-08-20 20:37:27 +000013#include <cpu/amd/model_fxx_rev.h>
Patrick Georgie135ac52012-11-20 11:53:47 +010014#include <delay.h>
Edward O'Callaghan77757c22015-01-04 21:33:39 +110015#include <northbridge/amd/amdk8/amdk8.h>
stepan836ae292010-12-08 05:42:47 +000016#include "southbridge/amd/amd8111/early_smbus.c"
Edward O'Callaghan77757c22015-01-04 21:33:39 +110017#include <northbridge/amd/amdk8/raminit.h>
Oskar Enoksson37106a72010-08-20 20:37:27 +000018#include "northbridge/amd/amdk8/reset_test.c"
19#include "northbridge/amd/amdk8/debug.c"
Edward O'Callaghan81998092014-04-28 18:07:33 +100020#include <superio/winbond/common/winbond.h>
21#include <superio/winbond/w83627hf/w83627hf.h>
Edward O'Callaghan77757c22015-01-04 21:33:39 +110022#include <cpu/x86/bist.h>
stepan836ae292010-12-08 05:42:47 +000023#include "southbridge/amd/amd8111/early_ctrl.c"
Oskar Enoksson37106a72010-08-20 20:37:27 +000024
25#define SERIAL_DEV PNP_DEV(0x2e, W83627HF_SP1)
26
Oskar Enoksson37106a72010-08-20 20:37:27 +000027static void memreset_setup(void)
28{
Oskar Enokssonf5e102d2011-11-07 18:31:33 +010029 if (is_cpu_pre_c0()) {
30 /* Set the memreset low. */
31 outb((1<<2)|(0<<0), SMBUS_IO_BASE + 0xc0 + 16);
32 /* Ensure the BIOS has control of the memory lines. */
33 outb((1<<2)|(0<<0), SMBUS_IO_BASE + 0xc0 + 17);
34 } else {
35 /* Ensure the CPU has control of the memory lines. */
36 outb((1<<2)|(1<<0), SMBUS_IO_BASE + 0xc0 + 17);
37 }
Oskar Enoksson37106a72010-08-20 20:37:27 +000038}
39
40static void memreset(int controllers, const struct mem_controller *ctrl)
41{
Oskar Enokssonf5e102d2011-11-07 18:31:33 +010042 if (is_cpu_pre_c0()) {
43 udelay(800);
44 /* Set memreset high. */
45 outb((1<<2)|(1<<0), SMBUS_IO_BASE + 0xc0 + 16);
46 udelay(90);
47 }
Oskar Enoksson37106a72010-08-20 20:37:27 +000048}
49
50#define SMBUS_HUB 0x18
51
52static inline void activate_spd_rom(const struct mem_controller *ctrl)
53{
Oskar Enokssonf5e102d2011-11-07 18:31:33 +010054 int ret,i;
55 unsigned device=(ctrl->channel0[0])>>8;
56 /* the very first write always get COL_STS=1 and ABRT_STS=1, so try another time*/
57 i=2;
58 do {
59 ret = smbus_write_byte(SMBUS_HUB, 0x01, device);
60 } while ((ret!=0) && (i-->0));
61 smbus_write_byte(SMBUS_HUB, 0x03, 0);
Oskar Enoksson37106a72010-08-20 20:37:27 +000062}
63
64static inline void change_i2c_mux(unsigned device)
65{
Oskar Enokssonf5e102d2011-11-07 18:31:33 +010066 int ret, i;
Stefan Reinauer069f4762015-01-05 13:02:32 -080067 printk(BIOS_DEBUG, "change_i2c_mux i=%02x\n", device);
Oskar Enokssonf5e102d2011-11-07 18:31:33 +010068 i=2;
69 do {
70 ret = smbus_write_byte(SMBUS_HUB, 0x01, device);
Stefan Reinauer069f4762015-01-05 13:02:32 -080071 printk(BIOS_DEBUG, "change_i2c_mux 1 ret=%08x\n", ret);
Oskar Enokssonf5e102d2011-11-07 18:31:33 +010072 } while ((ret!=0) && (i-->0));
73 ret = smbus_write_byte(SMBUS_HUB, 0x03, 0);
Stefan Reinauer069f4762015-01-05 13:02:32 -080074 printk(BIOS_DEBUG, "change_i2c_mux 2 ret=%08x\n", ret);
Oskar Enoksson37106a72010-08-20 20:37:27 +000075}
76
77static inline int spd_read_byte(unsigned device, unsigned address)
78{
79 return smbus_read_byte(device, address);
80}
81
Oskar Enokssondf073cb2011-10-04 22:15:51 +020082#include "northbridge/amd/amdk8/incoherent_ht.c"
Oskar Enoksson37106a72010-08-20 20:37:27 +000083#include "northbridge/amd/amdk8/raminit.c"
84#include "resourcemap.c"
Oskar Enoksson37106a72010-08-20 20:37:27 +000085#include "northbridge/amd/amdk8/coherent_ht.c"
86#include "lib/generic_sdram.c"
Oskar Enoksson37106a72010-08-20 20:37:27 +000087#include "cpu/amd/dualcore/dualcore.c"
Patrick Georgi9bd9a902010-11-20 10:31:00 +000088#include <spd.h>
Oskar Enoksson37106a72010-08-20 20:37:27 +000089#include "cpu/amd/model_fxx/init_cpus.c"
Oskar Enokssonaaedeca2014-02-11 22:51:03 +010090#if CONFIG_SET_FIDVID
91#include "cpu/amd/model_fxx/fidvid.c"
92#endif
Oskar Enoksson37106a72010-08-20 20:37:27 +000093
Oskar Enokssondf073cb2011-10-04 22:15:51 +020094#define RC0 ((1<<1)<<8)
95#define RC1 ((1<<2)<<8)
Oskar Enoksson37106a72010-08-20 20:37:27 +000096
97void cache_as_ram_main(unsigned long bist, unsigned long cpu_init_detectedx)
98{
99 static const uint16_t spd_addr [] = {
Uwe Hermann7b997052010-11-21 22:47:22 +0000100 //first node
101 RC0|DIMM0, RC0|DIMM2, 0, 0,
102 RC0|DIMM1, RC0|DIMM3, 0, 0,
Oskar Enoksson37106a72010-08-20 20:37:27 +0000103#if CONFIG_MAX_PHYSICAL_CPUS > 1
Uwe Hermann7b997052010-11-21 22:47:22 +0000104 //second node
105 RC1|DIMM0, RC1|DIMM2, 0, 0,
106 RC1|DIMM1, RC1|DIMM3, 0, 0,
Oskar Enoksson37106a72010-08-20 20:37:27 +0000107#endif
108 };
Patrick Georgibbc880e2012-11-20 18:20:56 +0100109 struct sys_info *sysinfo = &sysinfo_car;
Oskar Enoksson37106a72010-08-20 20:37:27 +0000110
Oskar Enokssondf073cb2011-10-04 22:15:51 +0200111 int needs_reset = 0;
112 unsigned bsp_apicid = 0;
Oskar Enoksson37106a72010-08-20 20:37:27 +0000113
Oskar Enokssonf5e102d2011-11-07 18:31:33 +0100114 if (bist == 0)
115 bsp_apicid = init_cpus(cpu_init_detectedx,sysinfo);
Oskar Enoksson37106a72010-08-20 20:37:27 +0000116
Edward O'Callaghan81998092014-04-28 18:07:33 +1000117 winbond_enable_serial(SERIAL_DEV, CONFIG_TTYS0_BASE);
Oskar Enokssonf5e102d2011-11-07 18:31:33 +0100118 console_init();
Oskar Enoksson37106a72010-08-20 20:37:27 +0000119
120 /* Halt if there was a built in self test failure */
121 report_bist_failure(bist);
122
Oskar Enokssonf5e102d2011-11-07 18:31:33 +0100123 printk(BIOS_DEBUG, "*sysinfo range: [%p,%p]\n",sysinfo,sysinfo+1);
Oskar Enokssondf073cb2011-10-04 22:15:51 +0200124
Oskar Enoksson37106a72010-08-20 20:37:27 +0000125 setup_dl145g1_resource_map();
126 //setup_default_resource_map();
127
Oskar Enokssondf073cb2011-10-04 22:15:51 +0200128 setup_coherent_ht_domain();
129 wait_all_core0_started();
Patrick Georgie1667822012-05-05 15:29:32 +0200130#if CONFIG_LOGICAL_CPUS
Oskar Enokssonf5e102d2011-11-07 18:31:33 +0100131 // It is said that we should start core1 after all core0 launched
132 start_other_cores();
133 wait_all_other_cores_started(bsp_apicid);
Oskar Enoksson37106a72010-08-20 20:37:27 +0000134#endif
135
Oskar Enokssonf5e102d2011-11-07 18:31:33 +0100136 ht_setup_chains_x(sysinfo);
Oskar Enokssonaaedeca2014-02-11 22:51:03 +0100137#if CONFIG_SET_FIDVID
138 /* Check to see if processor is capable of changing FIDVID */
139 /* otherwise it will throw a GP# when reading FIDVID_STATUS */
140 struct cpuid_result cpuid1 = cpuid(0x80000007);
141 if ((cpuid1.edx & 0x6) == 0x6) {
142 {
143 /* Read FIDVID_STATUS */
144 msr_t msr;
145 msr=rdmsr(0xc0010042);
Stefan Reinauer069f4762015-01-05 13:02:32 -0800146 printk(BIOS_DEBUG, "begin msr fid, vid %08x%08x\n", msr.hi, msr.lo);
Oskar Enokssonaaedeca2014-02-11 22:51:03 +0100147 }
148
149 enable_fid_change();
150 enable_fid_change_on_sb(sysinfo->sbbusn, sysinfo->sbdn);
151 init_fidvid_bsp(bsp_apicid);
152
153 // show final fid and vid
154 {
155 msr_t msr;
156 msr=rdmsr(0xc0010042);
Stefan Reinauer069f4762015-01-05 13:02:32 -0800157 printk(BIOS_DEBUG, "end msr fid, vid %08x%08x\n", msr.hi, msr.lo);
Oskar Enokssonaaedeca2014-02-11 22:51:03 +0100158 }
159
160 } else {
Stefan Reinauer069f4762015-01-05 13:02:32 -0800161 printk(BIOS_DEBUG, "Changing FIDVID not supported\n");
Oskar Enokssonaaedeca2014-02-11 22:51:03 +0100162 }
163#endif
Oskar Enoksson37106a72010-08-20 20:37:27 +0000164
Oskar Enokssondf073cb2011-10-04 22:15:51 +0200165 needs_reset |= optimize_link_coherent_ht();
166 needs_reset |= optimize_link_incoherent_ht(sysinfo);
167
168 if (needs_reset) {
Stefan Reinauer069f4762015-01-05 13:02:32 -0800169 printk(BIOS_INFO, "ht reset -\n");
Oskar Enokssondf073cb2011-10-04 22:15:51 +0200170 soft_reset_x(sysinfo->sbbusn, sysinfo->sbdn);
171 }
Oskar Enoksson37106a72010-08-20 20:37:27 +0000172
173 enable_smbus();
174
175 int i;
176 for(i=0;i<2;i++) {
Oskar Enokssondf073cb2011-10-04 22:15:51 +0200177 activate_spd_rom(&sysinfo->ctrl[i]);
Oskar Enoksson37106a72010-08-20 20:37:27 +0000178 }
Oskar Enokssondf073cb2011-10-04 22:15:51 +0200179 for(i=RC0;i<=RC1;i<<=1) {
Oskar Enoksson37106a72010-08-20 20:37:27 +0000180 change_i2c_mux(i);
181 }
182
Oskar Enokssondf073cb2011-10-04 22:15:51 +0200183 //dump_spd_registers(&sysinfo->ctrl[0]);
184 //dump_spd_registers(&sysinfo->ctrl[1]);
Oskar Enoksson37106a72010-08-20 20:37:27 +0000185 //dump_smbus_registers();
186
Oskar Enokssonf5e102d2011-11-07 18:31:33 +0100187 allow_all_aps_stop(bsp_apicid);
Oskar Enoksson37106a72010-08-20 20:37:27 +0000188
Oskar Enokssonf5e102d2011-11-07 18:31:33 +0100189 //It's the time to set ctrl now;
190 fill_mem_ctrl(sysinfo->nodes, sysinfo->ctrl, spd_addr);
Oskar Enoksson37106a72010-08-20 20:37:27 +0000191
Oskar Enokssonf5e102d2011-11-07 18:31:33 +0100192 memreset_setup();
Oskar Enokssonaaedeca2014-02-11 22:51:03 +0100193#if CONFIG_SET_FIDVID
194 init_timer(); // Need to use TMICT to synchronize FID/VID
195#endif
Oskar Enokssonf5e102d2011-11-07 18:31:33 +0100196 sdram_initialize(sysinfo->nodes, sysinfo->ctrl, sysinfo);
Oskar Enoksson37106a72010-08-20 20:37:27 +0000197
198 //dump_pci_devices();
199
200 post_cache_as_ram();
201}