Nils Jacobs | d0ac789 | 2011-12-30 23:00:11 +0100 | [diff] [blame] | 1 | /* |
| 2 | * This file is part of the coreboot project. |
| 3 | * |
| 4 | * Copyright (C) 2007 Advanced Micro Devices, Inc. |
| 5 | * Copyright (C) 2010 Nils Jacobs |
| 6 | * |
| 7 | * This program is free software; you can redistribute it and/or modify |
| 8 | * it under the terms of the GNU General Public License version 2 as |
| 9 | * published by the Free Software Foundation. |
| 10 | * |
| 11 | * This program is distributed in the hope that it will be useful, |
| 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
Paul Menzel | a8ae1c6 | 2013-02-20 13:21:20 +0100 | [diff] [blame] | 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
Nils Jacobs | d0ac789 | 2011-12-30 23:00:11 +0100 | [diff] [blame] | 14 | * GNU General Public License for more details. |
| 15 | * |
| 16 | * You should have received a copy of the GNU General Public License |
| 17 | * along with this program; if not, write to the Free Software |
| 18 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
| 19 | */ |
| 20 | |
Ronald G. Minnich | 40fedaf | 2006-04-06 23:35:52 +0000 | [diff] [blame] | 21 | #include <console/console.h> |
| 22 | #include <arch/io.h> |
| 23 | #include <stdint.h> |
| 24 | #include <device/device.h> |
| 25 | #include <device/pci.h> |
| 26 | #include <device/pci_ids.h> |
| 27 | #include <stdlib.h> |
| 28 | #include <string.h> |
Ronald G. Minnich | 40fedaf | 2006-04-06 23:35:52 +0000 | [diff] [blame] | 29 | #include "northbridge.h" |
| 30 | #include <cpu/amd/gx2def.h> |
| 31 | #include <cpu/x86/msr.h> |
| 32 | #include <cpu/x86/cache.h> |
| 33 | |
Nils Jacobs | 1c6d4e6 | 2010-12-26 05:12:49 +0000 | [diff] [blame] | 34 | struct gliutable |
| 35 | { |
Ronald G. Minnich | 40fedaf | 2006-04-06 23:35:52 +0000 | [diff] [blame] | 36 | unsigned long desc_name; |
| 37 | unsigned short desc_type; |
| 38 | unsigned long hi, lo; |
| 39 | }; |
| 40 | |
| 41 | struct gliutable gliu0table[] = { |
Nils Jacobs | a4f06f1 | 2011-12-30 22:30:27 +0100 | [diff] [blame] | 42 | {.desc_name=GLIU0_P2D_BM_0, .desc_type= BM,.hi= MSR_MC + 0x0,.lo= 0x0FFF80}, /* 0-7FFFF to MC */ |
| 43 | {.desc_name=GLIU0_P2D_BM_1, .desc_type= BM,.hi= MSR_MC + 0x0,.lo=(0x80 << 20) + 0x0FFFE0}, /* 80000-9ffff to Mc */ |
| 44 | {.desc_name=GLIU0_P2D_SC_0, .desc_type= SC_SHADOW,.hi= MSR_MC + 0x0,.lo= 0x03}, /* C0000-Fffff split to MC and PCI (sub decode) A0000-Bffff handled by SoftVideo */ |
| 45 | {.desc_name=GLIU0_P2D_R_0, .desc_type= R_SYSMEM,.hi= MSR_MC,.lo= 0x0}, /* Catch and fix dynamicly. */ |
| 46 | {.desc_name=GLIU0_P2D_BMO_0, .desc_type= BMO_SMM,.hi= MSR_MC,.lo= 0x0}, /* Catch and fix dynamicly. */ |
| 47 | {.desc_name=GLIU0_GLD_MSR_COH, .desc_type= OTHER,.hi= 0x0,.lo= GL0_CPU}, |
| 48 | {.desc_name=GL_END, .desc_type= GL_END,.hi= 0x0,.lo= 0x0}, |
Ronald G. Minnich | 40fedaf | 2006-04-06 23:35:52 +0000 | [diff] [blame] | 49 | }; |
| 50 | |
Ronald G. Minnich | 40fedaf | 2006-04-06 23:35:52 +0000 | [diff] [blame] | 51 | struct gliutable gliu1table[] = { |
Nils Jacobs | a4f06f1 | 2011-12-30 22:30:27 +0100 | [diff] [blame] | 52 | {.desc_name=GLIU1_P2D_BM_0, .desc_type= BM,.hi= MSR_GL0 + 0x0,.lo= 0x0FFF80}, /* 0-7FFFF to MC */ |
| 53 | {.desc_name=GLIU1_P2D_BM_1, .desc_type= BM,.hi= MSR_GL0 + 0x0,.lo= (0x80 << 20) + 0x0FFFE0},/* 80000-9ffff to Mc */ |
| 54 | {.desc_name=GLIU1_P2D_SC_0, .desc_type= SC_SHADOW,.hi= MSR_GL0 + 0x0,.lo= 0x03}, /* C0000-Fffff split to MC and PCI (sub decode) */ |
| 55 | {.desc_name=GLIU1_P2D_R_0, .desc_type= R_SYSMEM,.hi= MSR_GL0,.lo= 0x0}, /* Catch and fix dynamicly. */ |
| 56 | {.desc_name=GLIU1_P2D_BM_3, .desc_type= BM_SMM,.hi= MSR_GL0,.lo= 0x0}, /* Catch and fix dynamicly. */ |
| 57 | {.desc_name=GLIU1_GLD_MSR_COH, .desc_type= OTHER,.hi= 0x0,.lo= GL1_GLIU0}, |
| 58 | {.desc_name=GLIU1_IOD_SC_0, .desc_type= SCIO,.hi= (GL1_GLCP << 29) + 0x0,.lo= 0x033000F0}, /* FooGlue FPU 0xF0 */ |
| 59 | {.desc_name=GL_END, .desc_type= GL_END,.hi= 0x0,.lo= 0x0}, |
Ronald G. Minnich | 40fedaf | 2006-04-06 23:35:52 +0000 | [diff] [blame] | 60 | }; |
| 61 | |
Nils Jacobs | a4f06f1 | 2011-12-30 22:30:27 +0100 | [diff] [blame] | 62 | struct gliutable *gliutables[] = { gliu0table, gliu1table, 0 }; |
Ronald G. Minnich | 4223188 | 2006-04-07 16:55:20 +0000 | [diff] [blame] | 63 | |
Nils Jacobs | 1c6d4e6 | 2010-12-26 05:12:49 +0000 | [diff] [blame] | 64 | struct msrinit |
| 65 | { |
Ronald G. Minnich | 40fedaf | 2006-04-06 23:35:52 +0000 | [diff] [blame] | 66 | unsigned long msrnum; |
Li-Ta Lo | d8d8fff | 2006-04-13 17:00:38 +0000 | [diff] [blame] | 67 | msr_t msr; |
| 68 | }; |
Ronald G. Minnich | 40fedaf | 2006-04-06 23:35:52 +0000 | [diff] [blame] | 69 | |
Nils Jacobs | a4f06f1 | 2011-12-30 22:30:27 +0100 | [diff] [blame] | 70 | struct msrinit ClockGatingDefault[] = { |
Ronald G. Minnich | 40fedaf | 2006-04-06 23:35:52 +0000 | [diff] [blame] | 71 | {GLIU0_GLD_MSR_PM, {.hi=0x00,.lo=0x0005}}, |
Nils Jacobs | 5beac7f | 2010-11-03 13:19:50 +0000 | [diff] [blame] | 72 | /* MC must stay off in SDR mode. It is turned on in CPUBug??? lotus #77.142 */ |
Ronald G. Minnich | 40fedaf | 2006-04-06 23:35:52 +0000 | [diff] [blame] | 73 | {MC_GLD_MSR_PM, {.hi=0x00,.lo=0x0000}}, |
| 74 | {GLIU1_GLD_MSR_PM, {.hi=0x00,.lo=0x0005}}, |
Nils Jacobs | 1c6d4e6 | 2010-12-26 05:12:49 +0000 | [diff] [blame] | 75 | {VG_GLD_MSR_PM, {.hi=0x00,.lo=0x0000}}, /* lotus #77.163 */ |
Ronald G. Minnich | 40fedaf | 2006-04-06 23:35:52 +0000 | [diff] [blame] | 76 | {GP_GLD_MSR_PM, {.hi=0x00,.lo=0x0001}}, |
| 77 | {DF_GLD_MSR_PM, {.hi=0x00,.lo=0x0155}}, |
| 78 | {GLCP_GLD_MSR_PM, {.hi=0x00,.lo=0x0015}}, |
| 79 | {GLPCI_GLD_MSR_PM, {.hi=0x00,.lo=0x0015}}, |
Nils Jacobs | 1c6d4e6 | 2010-12-26 05:12:49 +0000 | [diff] [blame] | 80 | {FG_GLD_MSR_PM, {.hi=0x00,.lo=0x0000}}, /* Always on */ |
Ronald G. Minnich | 40fedaf | 2006-04-06 23:35:52 +0000 | [diff] [blame] | 81 | {0xffffffff, {0xffffffff, 0xffffffff}}, |
| 82 | }; |
Nils Jacobs | 1c6d4e6 | 2010-12-26 05:12:49 +0000 | [diff] [blame] | 83 | |
| 84 | /* All On */ |
Ronald G. Minnich | 40fedaf | 2006-04-06 23:35:52 +0000 | [diff] [blame] | 85 | struct msrinit ClockGatingAllOn[] = { |
| 86 | {GLIU0_GLD_MSR_PM, {.hi=0x00,.lo=0x0FFFFFFFF}}, |
| 87 | {MC_GLD_MSR_PM, {.hi=0x00,.lo=0x0FFFFFFFF}}, |
| 88 | {GLIU1_GLD_MSR_PM, {.hi=0x00,.lo=0x0FFFFFFFF}}, |
| 89 | {VG_GLD_MSR_PM, {.hi=0x00, .lo=0x00}}, |
| 90 | {GP_GLD_MSR_PM, {.hi=0x00,.lo=0x000000001}}, |
| 91 | {DF_GLD_MSR_PM, {.hi=0x00,.lo=0x0FFFFFFFF}}, |
| 92 | {GLCP_GLD_MSR_PM, {.hi=0x00,.lo=0x0FFFFFFFF}}, |
| 93 | {GLPCI_GLD_MSR_PM, {.hi=0x00,.lo=0x0FFFFFFFF}}, |
| 94 | {FG_GLD_MSR_PM, {.hi=0x00,.lo=0x0000}}, |
| 95 | {0xffffffff, {0xffffffff, 0xffffffff}}, |
| 96 | }; |
| 97 | |
Nils Jacobs | 1c6d4e6 | 2010-12-26 05:12:49 +0000 | [diff] [blame] | 98 | /* Performance */ |
Ronald G. Minnich | 40fedaf | 2006-04-06 23:35:52 +0000 | [diff] [blame] | 99 | struct msrinit ClockGatingPerformance[] = { |
Nils Jacobs | 1c6d4e6 | 2010-12-26 05:12:49 +0000 | [diff] [blame] | 100 | {VG_GLD_MSR_PM, {.hi=0x00,.lo=0x0000}}, /* lotus #77.163 */ |
Ronald G. Minnich | 40fedaf | 2006-04-06 23:35:52 +0000 | [diff] [blame] | 101 | {GP_GLD_MSR_PM, {.hi=0x00,.lo=0x0001}}, |
| 102 | {DF_GLD_MSR_PM, {.hi=0x00,.lo=0x0155}}, |
| 103 | {GLCP_GLD_MSR_PM, {.hi=0x00,.lo=0x0015}}, |
| 104 | {0xffffffff, {0xffffffff, 0xffffffff}}, |
| 105 | }; |
Nils Jacobs | 5beac7f | 2010-11-03 13:19:50 +0000 | [diff] [blame] | 106 | |
Nils Jacobs | 1c6d4e6 | 2010-12-26 05:12:49 +0000 | [diff] [blame] | 107 | /* SET GeodeLink PRIORITY */ |
Nils Jacobs | a4f06f1 | 2011-12-30 22:30:27 +0100 | [diff] [blame] | 108 | struct msrinit GeodeLinkPriorityTable[] = { |
Nils Jacobs | 5beac7f | 2010-11-03 13:19:50 +0000 | [diff] [blame] | 109 | {CPU_GLD_MSR_CONFIG, {.hi=0x00,.lo=0x0220}}, /* CPU Priority. */ |
| 110 | {DF_GLD_MSR_MASTER_CONF, {.hi=0x00,.lo=0x0000}}, /* DF Priority. */ |
| 111 | {VG_GLD_MSR_CONFIG, {.hi=0x00,.lo=0x0720}}, /* VG Primary and Secondary Priority. */ |
| 112 | {GP_GLD_MSR_CONFIG, {.hi=0x00,.lo=0x0010}}, /* Graphics Priority. */ |
| 113 | {GLPCI_GLD_MSR_CONFIG, {.hi=0x00,.lo=0x0027}}, /* GLPCI Priority + PID */ |
| 114 | {GLCP_GLD_MSR_CONF, {.hi=0x00,.lo=0x0001}}, /* GLCP Priority + PID */ |
Nils Jacobs | 84be0f5 | 2010-12-29 21:12:10 +0000 | [diff] [blame] | 115 | {FG_GLD_MSR_CONFIG, {.hi=0x00,.lo=0x0622}}, /* FG PID */ |
Nils Jacobs | 5beac7f | 2010-11-03 13:19:50 +0000 | [diff] [blame] | 116 | {0x0FFFFFFFF, {0x0FFFFFFFF, 0x0FFFFFFFF}}, /* END */ |
Ronald G. Minnich | 40fedaf | 2006-04-06 23:35:52 +0000 | [diff] [blame] | 117 | }; |
| 118 | |
Nils Jacobs | 1c6d4e6 | 2010-12-26 05:12:49 +0000 | [diff] [blame] | 119 | static void writeglmsr(struct gliutable *gl) |
| 120 | { |
Ronald G. Minnich | 4223188 | 2006-04-07 16:55:20 +0000 | [diff] [blame] | 121 | msr_t msr; |
Ronald G. Minnich | 40fedaf | 2006-04-06 23:35:52 +0000 | [diff] [blame] | 122 | |
Ronald G. Minnich | 4223188 | 2006-04-07 16:55:20 +0000 | [diff] [blame] | 123 | msr.lo = gl->lo; |
| 124 | msr.hi = gl->hi; |
Nils Jacobs | 5beac7f | 2010-11-03 13:19:50 +0000 | [diff] [blame] | 125 | wrmsr(gl->desc_name, msr); /* MSR - see table above */ |
Nils Jacobs | d0ac789 | 2011-12-30 23:00:11 +0100 | [diff] [blame] | 126 | printk(BIOS_DEBUG, "%s: MSR 0x%08lx, val 0x%08x:0x%08x\n", __func__, gl->desc_name, msr.hi, msr.lo); |
Ronald G. Minnich | 40fedaf | 2006-04-06 23:35:52 +0000 | [diff] [blame] | 127 | } |
| 128 | |
Nils Jacobs | 1c6d4e6 | 2010-12-26 05:12:49 +0000 | [diff] [blame] | 129 | static void ShadowInit(struct gliutable *gl) |
Li-Ta Lo | d8d8fff | 2006-04-13 17:00:38 +0000 | [diff] [blame] | 130 | { |
Ronald G. Minnich | 4223188 | 2006-04-07 16:55:20 +0000 | [diff] [blame] | 131 | msr_t msr; |
| 132 | |
| 133 | msr = rdmsr(gl->desc_name); |
| 134 | |
| 135 | if (msr.lo == 0) { |
Stefan Reinauer | 14e2277 | 2010-04-27 06:56:47 +0000 | [diff] [blame] | 136 | writeglmsr(gl); |
Ronald G. Minnich | 4223188 | 2006-04-07 16:55:20 +0000 | [diff] [blame] | 137 | } |
| 138 | } |
| 139 | |
Nils Jacobs | 1c6d4e6 | 2010-12-26 05:12:49 +0000 | [diff] [blame] | 140 | static void SysmemInit(struct gliutable *gl) |
Li-Ta Lo | d8d8fff | 2006-04-13 17:00:38 +0000 | [diff] [blame] | 141 | { |
Ronald G. Minnich | 4223188 | 2006-04-07 16:55:20 +0000 | [diff] [blame] | 142 | msr_t msr; |
| 143 | int sizembytes, sizebytes; |
| 144 | |
Nils Jacobs | 1c6d4e6 | 2010-12-26 05:12:49 +0000 | [diff] [blame] | 145 | /* Figure out how much RAM is in the machine and alocate all to the |
Nils Jacobs | d0ac789 | 2011-12-30 23:00:11 +0100 | [diff] [blame] | 146 | * system. We will adjust for SMM now and Frame Buffer later. |
Ronald G. Minnich | fb93749 | 2006-06-10 22:57:15 +0000 | [diff] [blame] | 147 | */ |
Ronald G. Minnich | 4223188 | 2006-04-07 16:55:20 +0000 | [diff] [blame] | 148 | sizembytes = sizeram(); |
Nils Jacobs | d0ac789 | 2011-12-30 23:00:11 +0100 | [diff] [blame] | 149 | printk(BIOS_DEBUG, "%s: enable for %dMBytes\n", __func__, sizembytes); |
Ronald G. Minnich | 4223188 | 2006-04-07 16:55:20 +0000 | [diff] [blame] | 150 | sizebytes = sizembytes << 20; |
| 151 | |
Nils Jacobs | d0ac789 | 2011-12-30 23:00:11 +0100 | [diff] [blame] | 152 | sizebytes -= ((SMM_SIZE * 1024) + 1); |
Ronald G. Minnich | 4223188 | 2006-04-07 16:55:20 +0000 | [diff] [blame] | 153 | |
Nils Jacobs | d0ac789 | 2011-12-30 23:00:11 +0100 | [diff] [blame] | 154 | /* 20 bit address The bottom 12 bits go into bits 20-31 in msr.lo |
| 155 | The top 8 bits go into 0-7 of msr.hi. */ |
| 156 | sizebytes --; |
Ronald G. Minnich | fb93749 | 2006-06-10 22:57:15 +0000 | [diff] [blame] | 157 | msr.hi = (gl->hi & 0xFFFFFF00) | (sizebytes >> 24); |
Nils Jacobs | d0ac789 | 2011-12-30 23:00:11 +0100 | [diff] [blame] | 158 | sizebytes <<= 8; /* move bits 23:12 in bits 31:20. */ |
Ronald G. Minnich | 4223188 | 2006-04-07 16:55:20 +0000 | [diff] [blame] | 159 | sizebytes &= 0xfff00000; |
Nils Jacobs | d0ac789 | 2011-12-30 23:00:11 +0100 | [diff] [blame] | 160 | sizebytes |= 0x100; /* start at 1MB */ |
Ronald G. Minnich | 4223188 | 2006-04-07 16:55:20 +0000 | [diff] [blame] | 161 | msr.lo = sizebytes; |
Nils Jacobs | 5beac7f | 2010-11-03 13:19:50 +0000 | [diff] [blame] | 162 | wrmsr(gl->desc_name, msr); /* MSR - see table above */ |
Nils Jacobs | d0ac789 | 2011-12-30 23:00:11 +0100 | [diff] [blame] | 163 | printk(BIOS_DEBUG, "%s: MSR 0x%08lx, val 0x%08x:0x%08x\n", __func__, |
Ronald G. Minnich | 4223188 | 2006-04-07 16:55:20 +0000 | [diff] [blame] | 164 | gl->desc_name, msr.hi, msr.lo); |
Ronald G. Minnich | 4223188 | 2006-04-07 16:55:20 +0000 | [diff] [blame] | 165 | } |
Nils Jacobs | 5beac7f | 2010-11-03 13:19:50 +0000 | [diff] [blame] | 166 | |
Nils Jacobs | 1c6d4e6 | 2010-12-26 05:12:49 +0000 | [diff] [blame] | 167 | static void SMMGL0Init(struct gliutable *gl) |
| 168 | { |
Ronald G. Minnich | 4223188 | 2006-04-07 16:55:20 +0000 | [diff] [blame] | 169 | msr_t msr; |
Nils Jacobs | a4f06f1 | 2011-12-30 22:30:27 +0100 | [diff] [blame] | 170 | int sizebytes = sizeram() << 20; |
Ronald G. Minnich | 4223188 | 2006-04-07 16:55:20 +0000 | [diff] [blame] | 171 | long offset; |
| 172 | |
Nils Jacobs | d0ac789 | 2011-12-30 23:00:11 +0100 | [diff] [blame] | 173 | sizebytes -= (SMM_SIZE * 1024); |
Ronald G. Minnich | 4223188 | 2006-04-07 16:55:20 +0000 | [diff] [blame] | 174 | |
Stefan Reinauer | c02b4fc | 2010-03-22 11:42:32 +0000 | [diff] [blame] | 175 | printk(BIOS_DEBUG, "%s: %d bytes\n", __func__, sizebytes); |
Ronald G. Minnich | 4223188 | 2006-04-07 16:55:20 +0000 | [diff] [blame] | 176 | |
| 177 | offset = sizebytes - SMM_OFFSET; |
Nils Jacobs | d0ac789 | 2011-12-30 23:00:11 +0100 | [diff] [blame] | 178 | offset = (offset >> 12) & 0x000fffff; |
| 179 | printk(BIOS_DEBUG, "%s: offset is 0x%08x\n", __func__, SMM_OFFSET); |
Ronald G. Minnich | 4223188 | 2006-04-07 16:55:20 +0000 | [diff] [blame] | 180 | |
Nils Jacobs | d0ac789 | 2011-12-30 23:00:11 +0100 | [diff] [blame] | 181 | msr.hi = offset << 8 | gl->hi; |
Nils Jacobs | a4f06f1 | 2011-12-30 22:30:27 +0100 | [diff] [blame] | 182 | msr.hi |= SMM_OFFSET >> 24; |
Ronald G. Minnich | 4223188 | 2006-04-07 16:55:20 +0000 | [diff] [blame] | 183 | |
| 184 | msr.lo = SMM_OFFSET << 8; |
Nils Jacobs | a4f06f1 | 2011-12-30 22:30:27 +0100 | [diff] [blame] | 185 | msr.lo |= ((~(SMM_SIZE * 1024) + 1) >> 12) & 0xfffff; |
Stefan Reinauer | 14e2277 | 2010-04-27 06:56:47 +0000 | [diff] [blame] | 186 | |
Nils Jacobs | 5beac7f | 2010-11-03 13:19:50 +0000 | [diff] [blame] | 187 | wrmsr(gl->desc_name, msr); /* MSR - See table above */ |
Nils Jacobs | d0ac789 | 2011-12-30 23:00:11 +0100 | [diff] [blame] | 188 | printk(BIOS_DEBUG, "%s: MSR 0x%08lx, val 0x%08x:0x%08x\n", __func__, gl->desc_name, msr.hi, msr.lo); |
Ronald G. Minnich | 4223188 | 2006-04-07 16:55:20 +0000 | [diff] [blame] | 189 | } |
Nils Jacobs | 5beac7f | 2010-11-03 13:19:50 +0000 | [diff] [blame] | 190 | |
Nils Jacobs | 1c6d4e6 | 2010-12-26 05:12:49 +0000 | [diff] [blame] | 191 | static void SMMGL1Init(struct gliutable *gl) |
| 192 | { |
Ronald G. Minnich | 4223188 | 2006-04-07 16:55:20 +0000 | [diff] [blame] | 193 | msr_t msr; |
Nils Jacobs | d0ac789 | 2011-12-30 23:00:11 +0100 | [diff] [blame] | 194 | printk(BIOS_DEBUG, "%s:\n", __func__); |
Ronald G. Minnich | 4223188 | 2006-04-07 16:55:20 +0000 | [diff] [blame] | 195 | |
| 196 | msr.hi = gl->hi; |
| 197 | /* I don't think this is needed */ |
| 198 | msr.hi &= 0xffffff00; |
| 199 | msr.hi |= (SMM_OFFSET >> 24); |
Nils Jacobs | d0ac789 | 2011-12-30 23:00:11 +0100 | [diff] [blame] | 200 | msr.lo = (SMM_OFFSET << 8) & 0xfff00000; |
Nils Jacobs | a4f06f1 | 2011-12-30 22:30:27 +0100 | [diff] [blame] | 201 | msr.lo |= ((~(SMM_SIZE * 1024) + 1) >> 12) & 0xfffff; |
Stefan Reinauer | 14e2277 | 2010-04-27 06:56:47 +0000 | [diff] [blame] | 202 | |
Nils Jacobs | 5beac7f | 2010-11-03 13:19:50 +0000 | [diff] [blame] | 203 | wrmsr(gl->desc_name, msr); /* MSR - See table above */ |
Nils Jacobs | d0ac789 | 2011-12-30 23:00:11 +0100 | [diff] [blame] | 204 | printk(BIOS_DEBUG, "%s: MSR 0x%08lx, val 0x%08x:0x%08x\n", __func__, gl->desc_name, msr.hi, msr.lo); |
Ronald G. Minnich | 4223188 | 2006-04-07 16:55:20 +0000 | [diff] [blame] | 205 | } |
| 206 | |
Nils Jacobs | 1c6d4e6 | 2010-12-26 05:12:49 +0000 | [diff] [blame] | 207 | static void GLIUInit(struct gliutable *gl) |
| 208 | { |
Nils Jacobs | a4f06f1 | 2011-12-30 22:30:27 +0100 | [diff] [blame] | 209 | while (gl->desc_type != GL_END) { |
| 210 | switch (gl->desc_type) { |
Stefan Reinauer | 14e2277 | 2010-04-27 06:56:47 +0000 | [diff] [blame] | 211 | default: |
Ronald G. Minnich | fb93749 | 2006-06-10 22:57:15 +0000 | [diff] [blame] | 212 | writeglmsr(gl); |
Nils Jacobs | 5beac7f | 2010-11-03 13:19:50 +0000 | [diff] [blame] | 213 | case SC_SHADOW: /* Check for a Shadow entry */ |
Ronald G. Minnich | 4223188 | 2006-04-07 16:55:20 +0000 | [diff] [blame] | 214 | ShadowInit(gl); |
| 215 | break; |
Stefan Reinauer | 14e2277 | 2010-04-27 06:56:47 +0000 | [diff] [blame] | 216 | |
Nils Jacobs | 5beac7f | 2010-11-03 13:19:50 +0000 | [diff] [blame] | 217 | case R_SYSMEM: /* check for a SYSMEM entry */ |
Ronald G. Minnich | 4223188 | 2006-04-07 16:55:20 +0000 | [diff] [blame] | 218 | SysmemInit(gl); |
| 219 | break; |
Stefan Reinauer | 14e2277 | 2010-04-27 06:56:47 +0000 | [diff] [blame] | 220 | |
Nils Jacobs | a4f06f1 | 2011-12-30 22:30:27 +0100 | [diff] [blame] | 221 | case BMO_SMM: /* check for a SMM entry */ |
Ronald G. Minnich | 4223188 | 2006-04-07 16:55:20 +0000 | [diff] [blame] | 222 | SMMGL0Init(gl); |
| 223 | break; |
Stefan Reinauer | 14e2277 | 2010-04-27 06:56:47 +0000 | [diff] [blame] | 224 | |
Nils Jacobs | a4f06f1 | 2011-12-30 22:30:27 +0100 | [diff] [blame] | 225 | case BM_SMM: /* check for a SMM entry */ |
Stefan Reinauer | 14e2277 | 2010-04-27 06:56:47 +0000 | [diff] [blame] | 226 | SMMGL1Init(gl); |
Ronald G. Minnich | 4223188 | 2006-04-07 16:55:20 +0000 | [diff] [blame] | 227 | break; |
| 228 | } |
| 229 | gl++; |
| 230 | } |
Ronald G. Minnich | 4223188 | 2006-04-07 16:55:20 +0000 | [diff] [blame] | 231 | } |
Nils Jacobs | 5beac7f | 2010-11-03 13:19:50 +0000 | [diff] [blame] | 232 | |
Nils Jacobs | 1c6d4e6 | 2010-12-26 05:12:49 +0000 | [diff] [blame] | 233 | /* Set up GLPCI settings for reads/write into memory. |
Nils Jacobs | 5beac7f | 2010-11-03 13:19:50 +0000 | [diff] [blame] | 234 | * |
| 235 | * R0: 0-640KB, |
| 236 | * R1: 1MB - Top of System Memory |
| 237 | * R2: SMM Memory |
| 238 | * R3: Framebuffer? - not set up yet |
| 239 | * R4: ?? |
| 240 | */ |
Nils Jacobs | 1c6d4e6 | 2010-12-26 05:12:49 +0000 | [diff] [blame] | 241 | static void GLPCIInit(void) |
| 242 | { |
Ronald G. Minnich | 40fedaf | 2006-04-06 23:35:52 +0000 | [diff] [blame] | 243 | struct gliutable *gl = 0; |
| 244 | int i; |
| 245 | msr_t msr; |
| 246 | int msrnum; |
Ronald G. Minnich | fb93749 | 2006-06-10 22:57:15 +0000 | [diff] [blame] | 247 | |
Nils Jacobs | 5beac7f | 2010-11-03 13:19:50 +0000 | [diff] [blame] | 248 | /* R0 - GLPCI settings for Conventional Memory space. */ |
| 249 | msr.hi = (0x09F000 >> 12) << GLPCI_RC_UPPER_TOP_SHIFT; /* 640 */ |
| 250 | msr.lo = 0; /* 0 */ |
Nils Jacobs | a4f06f1 | 2011-12-30 22:30:27 +0100 | [diff] [blame] | 251 | msr.lo |= GLPCI_RC_LOWER_EN_SET + GLPCI_RC_LOWER_PF_SET + GLPCI_RC_LOWER_WC_SET; |
Ronald G. Minnich | 40fedaf | 2006-04-06 23:35:52 +0000 | [diff] [blame] | 252 | msrnum = GLPCI_RC0; |
| 253 | wrmsr(msrnum, msr); |
| 254 | |
Nils Jacobs | 5beac7f | 2010-11-03 13:19:50 +0000 | [diff] [blame] | 255 | /* R1 - GLPCI settings for SysMem space. */ |
| 256 | /* Get systop from GLIU0 SYSTOP Descriptor */ |
Nils Jacobs | a4f06f1 | 2011-12-30 22:30:27 +0100 | [diff] [blame] | 257 | for (i = 0; gliu0table[i].desc_name != GL_END; i++) { |
Ronald G. Minnich | 40fedaf | 2006-04-06 23:35:52 +0000 | [diff] [blame] | 258 | if (gliu0table[i].desc_type == R_SYSMEM) { |
| 259 | gl = &gliu0table[i]; |
| 260 | break; |
| 261 | } |
| 262 | } |
Ronald G. Minnich | 40fedaf | 2006-04-06 23:35:52 +0000 | [diff] [blame] | 263 | if (gl) { |
Ronald G. Minnich | c01fe5d | 2006-05-03 03:30:23 +0000 | [diff] [blame] | 264 | unsigned long pah, pal; |
Ronald G. Minnich | 40fedaf | 2006-04-06 23:35:52 +0000 | [diff] [blame] | 265 | msrnum = gl->desc_name; |
| 266 | msr = rdmsr(msrnum); |
Ronald G. Minnich | c01fe5d | 2006-05-03 03:30:23 +0000 | [diff] [blame] | 267 | /* example R_SYSMEM value: 20:00:00:0f:fb:f0:01:00 |
Nils Jacobs | a4f06f1 | 2011-12-30 22:30:27 +0100 | [diff] [blame] | 268 | * translates to a base of 0x00100000 and top of 0xffbf0000 |
| 269 | * base of 1M and top of around 256M |
Ronald G. Minnich | c01fe5d | 2006-05-03 03:30:23 +0000 | [diff] [blame] | 270 | */ |
Nils Jacobs | 5beac7f | 2010-11-03 13:19:50 +0000 | [diff] [blame] | 271 | /* we have to create a page-aligned (4KB page) address for base and top |
Nils Jacobs | 1c6d4e6 | 2010-12-26 05:12:49 +0000 | [diff] [blame] | 272 | * so we need a high page aligned addresss (pah) and low page aligned address (pal) |
Ronald G. Minnich | c01fe5d | 2006-05-03 03:30:23 +0000 | [diff] [blame] | 273 | * pah is from msr.hi << 12 | msr.low >> 20. pal is msr.lo << 12 |
| 274 | */ |
Nils Jacobs | d0ac789 | 2011-12-30 23:00:11 +0100 | [diff] [blame] | 275 | pah = ((msr.hi & 0xff) << 12) | ((msr.lo >> 20) & 0xfff); |
Ronald G. Minnich | c01fe5d | 2006-05-03 03:30:23 +0000 | [diff] [blame] | 276 | /* we have the page address. Now make it a page-aligned address */ |
| 277 | pah <<= 12; |
Ronald G. Minnich | 40fedaf | 2006-04-06 23:35:52 +0000 | [diff] [blame] | 278 | |
Ronald G. Minnich | c01fe5d | 2006-05-03 03:30:23 +0000 | [diff] [blame] | 279 | pal = msr.lo << 12; |
Nils Jacobs | a4f06f1 | 2011-12-30 22:30:27 +0100 | [diff] [blame] | 280 | msr.hi = pah; |
| 281 | msr.lo = pal; |
Ronald G. Minnich | c01fe5d | 2006-05-03 03:30:23 +0000 | [diff] [blame] | 282 | msr.lo |= GLPCI_RC_LOWER_EN_SET | GLPCI_RC_LOWER_PF_SET | GLPCI_RC_LOWER_WC_SET; |
Nils Jacobs | d0ac789 | 2011-12-30 23:00:11 +0100 | [diff] [blame] | 283 | printk(BIOS_DEBUG, "GLPCI R1: system msr.lo 0x%08x msr.hi 0x%08x\n", msr.lo, msr.hi); |
Ronald G. Minnich | 40fedaf | 2006-04-06 23:35:52 +0000 | [diff] [blame] | 284 | msrnum = GLPCI_RC1; |
| 285 | wrmsr(msrnum, msr); |
| 286 | } |
| 287 | |
Nils Jacobs | 5beac7f | 2010-11-03 13:19:50 +0000 | [diff] [blame] | 288 | /* R2 - GLPCI settings for SMM space. */ |
Nils Jacobs | a4f06f1 | 2011-12-30 22:30:27 +0100 | [diff] [blame] | 289 | msr.hi = ((SMM_OFFSET + (SMM_SIZE * 1024 - 1)) >> 12) << GLPCI_RC_UPPER_TOP_SHIFT; |
| 290 | msr.lo = (SMM_OFFSET >> 12) << GLPCI_RC_LOWER_BASE_SHIFT; |
Ronald G. Minnich | 40fedaf | 2006-04-06 23:35:52 +0000 | [diff] [blame] | 291 | msr.lo |= GLPCI_RC_LOWER_EN_SET | GLPCI_RC_LOWER_PF_SET; |
Nils Jacobs | d0ac789 | 2011-12-30 23:00:11 +0100 | [diff] [blame] | 292 | printk(BIOS_DEBUG, "GLPCI R2: system msr.lo 0x%08x msr.hi 0x%08x\n", msr.lo, msr.hi); |
Ronald G. Minnich | 40fedaf | 2006-04-06 23:35:52 +0000 | [diff] [blame] | 293 | msrnum = GLPCI_RC2; |
| 294 | wrmsr(msrnum, msr); |
| 295 | |
| 296 | /* this is done elsewhere already, but it does no harm to do it more than once */ |
Nils Jacobs | a4f06f1 | 2011-12-30 22:30:27 +0100 | [diff] [blame] | 297 | /* write serialize memory hole to PCI. Need to unWS when something is shadowed regardless of cachablility. */ |
| 298 | msr.lo = 0x021212121; /* cache disabled and write serialized */ |
| 299 | msr.hi = 0x021212121; /* cache disabled and write serialized */ |
Ronald G. Minnich | 40fedaf | 2006-04-06 23:35:52 +0000 | [diff] [blame] | 300 | |
| 301 | msrnum = CPU_RCONF_A0_BF; |
| 302 | wrmsr(msrnum, msr); |
| 303 | |
Ronald G. Minnich | 40fedaf | 2006-04-06 23:35:52 +0000 | [diff] [blame] | 304 | msrnum = CPU_RCONF_C0_DF; |
| 305 | wrmsr(msrnum, msr); |
| 306 | |
Ronald G. Minnich | 40fedaf | 2006-04-06 23:35:52 +0000 | [diff] [blame] | 307 | msrnum = CPU_RCONF_E0_FF; |
| 308 | wrmsr(msrnum, msr); |
| 309 | |
Nils Jacobs | 5beac7f | 2010-11-03 13:19:50 +0000 | [diff] [blame] | 310 | /* Set Non-Cacheable Read Only for NorthBound Transactions to Memory. The Enable bit is handled in the Shadow setup. */ |
Ronald G. Minnich | 40fedaf | 2006-04-06 23:35:52 +0000 | [diff] [blame] | 311 | msrnum = GLPCI_A0_BF; |
Nils Jacobs | a4f06f1 | 2011-12-30 22:30:27 +0100 | [diff] [blame] | 312 | msr.hi = 0x35353535; |
| 313 | msr.lo = 0x35353535; |
Ronald G. Minnich | 40fedaf | 2006-04-06 23:35:52 +0000 | [diff] [blame] | 314 | wrmsr(msrnum, msr); |
| 315 | |
| 316 | msrnum = GLPCI_C0_DF; |
Nils Jacobs | a4f06f1 | 2011-12-30 22:30:27 +0100 | [diff] [blame] | 317 | msr.hi = 0x35353535; |
| 318 | msr.lo = 0x35353535; |
Ronald G. Minnich | 40fedaf | 2006-04-06 23:35:52 +0000 | [diff] [blame] | 319 | wrmsr(msrnum, msr); |
| 320 | |
| 321 | msrnum = GLPCI_E0_FF; |
Nils Jacobs | a4f06f1 | 2011-12-30 22:30:27 +0100 | [diff] [blame] | 322 | msr.hi = 0x35353535; |
| 323 | msr.lo = 0x35353535; |
Ronald G. Minnich | 40fedaf | 2006-04-06 23:35:52 +0000 | [diff] [blame] | 324 | wrmsr(msrnum, msr); |
| 325 | |
Nils Jacobs | 5beac7f | 2010-11-03 13:19:50 +0000 | [diff] [blame] | 326 | /* Set WSREQ */ |
Ronald G. Minnich | 40fedaf | 2006-04-06 23:35:52 +0000 | [diff] [blame] | 327 | msrnum = CPU_DM_CONFIG0; |
| 328 | msr = rdmsr(msrnum); |
Nils Jacobs | a4f06f1 | 2011-12-30 22:30:27 +0100 | [diff] [blame] | 329 | msr.hi &= ~(7 << DM_CONFIG0_UPPER_WSREQ_SHIFT); |
Nils Jacobs | 5beac7f | 2010-11-03 13:19:50 +0000 | [diff] [blame] | 330 | msr.hi |= 2 << DM_CONFIG0_UPPER_WSREQ_SHIFT ; /* reduce to 1 for safe mode. */ |
Ronald G. Minnich | 40fedaf | 2006-04-06 23:35:52 +0000 | [diff] [blame] | 331 | wrmsr(msrnum, msr); |
| 332 | |
| 333 | /* we are ignoring the 5530 case for now, and perhaps forever. */ |
| 334 | |
Nils Jacobs | d0ac789 | 2011-12-30 23:00:11 +0100 | [diff] [blame] | 335 | /* 553X NB Init */ |
Patrick Georgi | 472efa6 | 2012-02-16 20:44:20 +0100 | [diff] [blame] | 336 | |
Nils Jacobs | d0ac789 | 2011-12-30 23:00:11 +0100 | [diff] [blame] | 337 | /* Arbiter setup */ |
Ronald G. Minnich | 40fedaf | 2006-04-06 23:35:52 +0000 | [diff] [blame] | 338 | msrnum = GLPCI_ARB; |
| 339 | msr = rdmsr(msrnum); |
Nils Jacobs | a4f06f1 | 2011-12-30 22:30:27 +0100 | [diff] [blame] | 340 | msr.hi |= GLPCI_ARB_UPPER_PRE0_SET | GLPCI_ARB_UPPER_PRE1_SET; |
| 341 | msr.lo |= GLPCI_ARB_LOWER_IIE_SET; |
Ronald G. Minnich | 40fedaf | 2006-04-06 23:35:52 +0000 | [diff] [blame] | 342 | wrmsr(msrnum, msr); |
| 343 | |
Ronald G. Minnich | 40fedaf | 2006-04-06 23:35:52 +0000 | [diff] [blame] | 344 | msrnum = GLPCI_CTRL; |
| 345 | msr = rdmsr(msrnum); |
| 346 | |
Nils Jacobs | a4f06f1 | 2011-12-30 22:30:27 +0100 | [diff] [blame] | 347 | msr.lo |= GLPCI_CTRL_LOWER_ME_SET | GLPCI_CTRL_LOWER_OWC_SET | GLPCI_CTRL_LOWER_PCD_SET; /* (Out will be disabled in CPUBUG649 for < 2.0 parts .) */ |
| 348 | msr.lo |= GLPCI_CTRL_LOWER_LDE_SET; |
Ronald G. Minnich | 40fedaf | 2006-04-06 23:35:52 +0000 | [diff] [blame] | 349 | |
Nils Jacobs | a4f06f1 | 2011-12-30 22:30:27 +0100 | [diff] [blame] | 350 | msr.lo &= ~(0x03 << GLPCI_CTRL_LOWER_IRFC_SHIFT); |
| 351 | msr.lo |= 0x02 << GLPCI_CTRL_LOWER_IRFC_SHIFT; |
Ronald G. Minnich | 40fedaf | 2006-04-06 23:35:52 +0000 | [diff] [blame] | 352 | |
Nils Jacobs | a4f06f1 | 2011-12-30 22:30:27 +0100 | [diff] [blame] | 353 | msr.lo &= ~(0x07 << GLPCI_CTRL_LOWER_IRFT_SHIFT); |
| 354 | msr.lo |= 0x06 << GLPCI_CTRL_LOWER_IRFT_SHIFT; |
Stefan Reinauer | 14e2277 | 2010-04-27 06:56:47 +0000 | [diff] [blame] | 355 | |
Nils Jacobs | a4f06f1 | 2011-12-30 22:30:27 +0100 | [diff] [blame] | 356 | msr.hi &= ~(0x0f << GLPCI_CTRL_UPPER_FTH_SHIFT); |
| 357 | msr.hi |= 0x0F << GLPCI_CTRL_UPPER_FTH_SHIFT; |
Stefan Reinauer | 14e2277 | 2010-04-27 06:56:47 +0000 | [diff] [blame] | 358 | |
Nils Jacobs | a4f06f1 | 2011-12-30 22:30:27 +0100 | [diff] [blame] | 359 | msr.hi &= ~(0x0f << GLPCI_CTRL_UPPER_RTH_SHIFT); |
| 360 | msr.hi |= 0x0F << GLPCI_CTRL_UPPER_RTH_SHIFT; |
Stefan Reinauer | 14e2277 | 2010-04-27 06:56:47 +0000 | [diff] [blame] | 361 | |
Nils Jacobs | a4f06f1 | 2011-12-30 22:30:27 +0100 | [diff] [blame] | 362 | msr.hi &= ~(0x0f << GLPCI_CTRL_UPPER_SBRTH_SHIFT); |
| 363 | msr.hi |= 0x0F << GLPCI_CTRL_UPPER_SBRTH_SHIFT; |
Stefan Reinauer | 14e2277 | 2010-04-27 06:56:47 +0000 | [diff] [blame] | 364 | |
Nils Jacobs | a4f06f1 | 2011-12-30 22:30:27 +0100 | [diff] [blame] | 365 | msr.hi &= ~(0x03 << GLPCI_CTRL_UPPER_WTO_SHIFT); |
| 366 | msr.hi |= 0x06 << GLPCI_CTRL_UPPER_WTO_SHIFT; |
Stefan Reinauer | 14e2277 | 2010-04-27 06:56:47 +0000 | [diff] [blame] | 367 | |
Nils Jacobs | a4f06f1 | 2011-12-30 22:30:27 +0100 | [diff] [blame] | 368 | msr.hi &= ~(0x03 << GLPCI_CTRL_UPPER_ILTO_SHIFT); |
| 369 | msr.hi |= 0x00 << GLPCI_CTRL_UPPER_ILTO_SHIFT; |
Ronald G. Minnich | 40fedaf | 2006-04-06 23:35:52 +0000 | [diff] [blame] | 370 | wrmsr(msrnum, msr); |
| 371 | |
Nils Jacobs | 5beac7f | 2010-11-03 13:19:50 +0000 | [diff] [blame] | 372 | /* Set GLPCI Latency Timer. */ |
Ronald G. Minnich | 40fedaf | 2006-04-06 23:35:52 +0000 | [diff] [blame] | 373 | msrnum = GLPCI_CTRL; |
| 374 | msr = rdmsr(msrnum); |
Nils Jacobs | a4f06f1 | 2011-12-30 22:30:27 +0100 | [diff] [blame] | 375 | msr.hi |= 0x1F << GLPCI_CTRL_UPPER_LAT_SHIFT; /* Change once 1.x is gone. */ |
Ronald G. Minnich | 40fedaf | 2006-04-06 23:35:52 +0000 | [diff] [blame] | 376 | wrmsr(msrnum, msr); |
| 377 | |
Nils Jacobs | 5beac7f | 2010-11-03 13:19:50 +0000 | [diff] [blame] | 378 | /* GLPCI_SPARE */ |
Ronald G. Minnich | 40fedaf | 2006-04-06 23:35:52 +0000 | [diff] [blame] | 379 | msrnum = GLPCI_SPARE; |
| 380 | msr = rdmsr(msrnum); |
Nils Jacobs | a4f06f1 | 2011-12-30 22:30:27 +0100 | [diff] [blame] | 381 | msr.lo &= ~0x7; |
| 382 | msr.lo |= GLPCI_SPARE_LOWER_AILTO_SET | GLPCI_SPARE_LOWER_PPD_SET | GLPCI_SPARE_LOWER_PPC_SET | GLPCI_SPARE_LOWER_MPC_SET | GLPCI_SPARE_LOWER_NSE_SET | GLPCI_SPARE_LOWER_SUPO_SET; |
Ronald G. Minnich | 40fedaf | 2006-04-06 23:35:52 +0000 | [diff] [blame] | 383 | wrmsr(msrnum, msr); |
Ronald G. Minnich | 40fedaf | 2006-04-06 23:35:52 +0000 | [diff] [blame] | 384 | } |
| 385 | |
Nils Jacobs | 5beac7f | 2010-11-03 13:19:50 +0000 | [diff] [blame] | 386 | /* Enable Clock Gating. */ |
Nils Jacobs | a4f06f1 | 2011-12-30 22:30:27 +0100 | [diff] [blame] | 387 | static void ClockGatingInit(void) |
Nils Jacobs | 5beac7f | 2010-11-03 13:19:50 +0000 | [diff] [blame] | 388 | { |
Ronald G. Minnich | 40fedaf | 2006-04-06 23:35:52 +0000 | [diff] [blame] | 389 | msr_t msr; |
| 390 | struct msrinit *gating = ClockGatingDefault; |
| 391 | int i; |
| 392 | |
Nils Jacobs | d0ac789 | 2011-12-30 23:00:11 +0100 | [diff] [blame] | 393 | for (i = 0; gating->msrnum != 0xffffffff; i++) { |
Ronald G. Minnich | 40fedaf | 2006-04-06 23:35:52 +0000 | [diff] [blame] | 394 | msr = rdmsr(gating->msrnum); |
Ronald G. Minnich | 40fedaf | 2006-04-06 23:35:52 +0000 | [diff] [blame] | 395 | msr.hi |= gating->msr.hi; |
| 396 | msr.lo |= gating->msr.lo; |
Nils Jacobs | 5beac7f | 2010-11-03 13:19:50 +0000 | [diff] [blame] | 397 | wrmsr(gating->msrnum, msr); /* MSR - See the table above */ |
Nils Jacobs | a4f06f1 | 2011-12-30 22:30:27 +0100 | [diff] [blame] | 398 | gating += 1; |
Ronald G. Minnich | 40fedaf | 2006-04-06 23:35:52 +0000 | [diff] [blame] | 399 | } |
Ronald G. Minnich | 40fedaf | 2006-04-06 23:35:52 +0000 | [diff] [blame] | 400 | } |
Ronald G. Minnich | 4223188 | 2006-04-07 16:55:20 +0000 | [diff] [blame] | 401 | |
Nils Jacobs | 5beac7f | 2010-11-03 13:19:50 +0000 | [diff] [blame] | 402 | static void GeodeLinkPriority(void) |
| 403 | { |
Stefan Reinauer | 86fc984 | 2011-10-13 17:26:10 -0700 | [diff] [blame] | 404 | msr_t msr = { 0, 0 }; |
Patrick Georgi | 472efa6 | 2012-02-16 20:44:20 +0100 | [diff] [blame] | 405 | |
Ronald G. Minnich | 4223188 | 2006-04-07 16:55:20 +0000 | [diff] [blame] | 406 | struct msrinit *prio = GeodeLinkPriorityTable; |
| 407 | int i; |
| 408 | |
Nils Jacobs | a4f06f1 | 2011-12-30 22:30:27 +0100 | [diff] [blame] | 409 | for (i = 0; prio->msrnum != 0xffffffff; i++) { |
Ronald G. Minnich | 4223188 | 2006-04-07 16:55:20 +0000 | [diff] [blame] | 410 | msr = rdmsr(prio->msrnum); |
Ronald G. Minnich | 4223188 | 2006-04-07 16:55:20 +0000 | [diff] [blame] | 411 | msr.hi |= prio->msr.hi; |
| 412 | msr.lo &= ~0xfff; |
| 413 | msr.lo |= prio->msr.lo; |
Nils Jacobs | 5beac7f | 2010-11-03 13:19:50 +0000 | [diff] [blame] | 414 | wrmsr(prio->msrnum, msr); /* MSR - See the table above */ |
Nils Jacobs | a4f06f1 | 2011-12-30 22:30:27 +0100 | [diff] [blame] | 415 | prio += 1; |
Ronald G. Minnich | 4223188 | 2006-04-07 16:55:20 +0000 | [diff] [blame] | 416 | } |
| 417 | } |
Ronald G. Minnich | fb93749 | 2006-06-10 22:57:15 +0000 | [diff] [blame] | 418 | |
Nils Jacobs | 1c6d4e6 | 2010-12-26 05:12:49 +0000 | [diff] [blame] | 419 | /* Get the GLIU0 shadow register settings. |
Nils Jacobs | 5beac7f | 2010-11-03 13:19:50 +0000 | [diff] [blame] | 420 | * |
| 421 | * If the setShadow function is used then all shadow descriptors |
| 422 | * will stay sync'ed. |
Ronald G. Minnich | fb93749 | 2006-06-10 22:57:15 +0000 | [diff] [blame] | 423 | */ |
| 424 | static uint64_t getShadow(void) |
| 425 | { |
Nils Jacobs | d0ac789 | 2011-12-30 23:00:11 +0100 | [diff] [blame] | 426 | msr_t msr = { 0, 0 }; |
Patrick Georgi | 472efa6 | 2012-02-16 20:44:20 +0100 | [diff] [blame] | 427 | |
Nils Jacobs | 84be0f5 | 2010-12-29 21:12:10 +0000 | [diff] [blame] | 428 | msr = rdmsr(GLIU0_P2D_SC_0); |
Ronald G. Minnich | fb93749 | 2006-06-10 22:57:15 +0000 | [diff] [blame] | 429 | return ( ( (uint64_t) msr.hi ) << 32 ) | msr.lo; |
| 430 | } |
| 431 | |
Nils Jacobs | 1c6d4e6 | 2010-12-26 05:12:49 +0000 | [diff] [blame] | 432 | /* Set the cache RConf registers for the memory hole. |
Nils Jacobs | 5beac7f | 2010-11-03 13:19:50 +0000 | [diff] [blame] | 433 | * |
| 434 | * Keeps all cache shadow descriptors sync'ed. |
| 435 | * This is part of the PCI lockup solution. |
| 436 | * |
| 437 | * Entry: EDX:EAX is the shadow settings. |
Ronald G. Minnich | fb93749 | 2006-06-10 22:57:15 +0000 | [diff] [blame] | 438 | */ |
| 439 | static void setShadowRCONF(uint32_t shadowHi, uint32_t shadowLo) |
| 440 | { |
Nils Jacobs | 5beac7f | 2010-11-03 13:19:50 +0000 | [diff] [blame] | 441 | /* ok this is whacky bit translation time. */ |
Ronald G. Minnich | fb93749 | 2006-06-10 22:57:15 +0000 | [diff] [blame] | 442 | int bit; |
| 443 | uint8_t shadowByte; |
Stefan Reinauer | 86fc984 | 2011-10-13 17:26:10 -0700 | [diff] [blame] | 444 | msr_t msr = { 0, 0 }; |
Ronald G. Minnich | fb93749 | 2006-06-10 22:57:15 +0000 | [diff] [blame] | 445 | shadowByte = (uint8_t) (shadowLo >> 16); |
| 446 | |
Nils Jacobs | 5beac7f | 2010-11-03 13:19:50 +0000 | [diff] [blame] | 447 | /* load up D000 settings in edx. */ |
Ronald G. Minnich | fb93749 | 2006-06-10 22:57:15 +0000 | [diff] [blame] | 448 | for (bit = 8; (bit > 4); bit--) { |
| 449 | msr.hi <<= 8; |
Nils Jacobs | 1c6d4e6 | 2010-12-26 05:12:49 +0000 | [diff] [blame] | 450 | msr.hi |= 1; /* cache disable PCI/Shadow memory */ |
Ronald G. Minnich | fb93749 | 2006-06-10 22:57:15 +0000 | [diff] [blame] | 451 | if (shadowByte && (1 << bit)) |
Nils Jacobs | 1c6d4e6 | 2010-12-26 05:12:49 +0000 | [diff] [blame] | 452 | msr.hi |= 0x20; /* write serialize PCI memory */ |
Ronald G. Minnich | fb93749 | 2006-06-10 22:57:15 +0000 | [diff] [blame] | 453 | } |
| 454 | |
Nils Jacobs | 5beac7f | 2010-11-03 13:19:50 +0000 | [diff] [blame] | 455 | /* load up C000 settings in eax. */ |
Nils Jacobs | a4f06f1 | 2011-12-30 22:30:27 +0100 | [diff] [blame] | 456 | for (; bit; bit--) { |
Ronald G. Minnich | fb93749 | 2006-06-10 22:57:15 +0000 | [diff] [blame] | 457 | msr.lo <<= 8; |
Nils Jacobs | 1c6d4e6 | 2010-12-26 05:12:49 +0000 | [diff] [blame] | 458 | msr.lo |= 1; /* cache disable PCI/Shadow memory */ |
Ronald G. Minnich | fb93749 | 2006-06-10 22:57:15 +0000 | [diff] [blame] | 459 | if (shadowByte && (1 << bit)) |
Nils Jacobs | 1c6d4e6 | 2010-12-26 05:12:49 +0000 | [diff] [blame] | 460 | msr.lo |= 0x20; /* write serialize PCI memory */ |
Ronald G. Minnich | fb93749 | 2006-06-10 22:57:15 +0000 | [diff] [blame] | 461 | } |
| 462 | |
| 463 | wrmsr(CPU_RCONF_C0_DF, msr); |
| 464 | |
| 465 | shadowByte = (uint8_t) (shadowLo >> 24); |
| 466 | |
Nils Jacobs | 5beac7f | 2010-11-03 13:19:50 +0000 | [diff] [blame] | 467 | /* load up F000 settings in edx. */ |
Ronald G. Minnich | fb93749 | 2006-06-10 22:57:15 +0000 | [diff] [blame] | 468 | for (bit = 8; (bit > 4); bit--) { |
| 469 | msr.hi <<= 8; |
Nils Jacobs | 1c6d4e6 | 2010-12-26 05:12:49 +0000 | [diff] [blame] | 470 | msr.hi |= 1; /* cache disable PCI/Shadow memory */ |
Ronald G. Minnich | fb93749 | 2006-06-10 22:57:15 +0000 | [diff] [blame] | 471 | if (shadowByte && (1 << bit)) |
Nils Jacobs | 1c6d4e6 | 2010-12-26 05:12:49 +0000 | [diff] [blame] | 472 | msr.hi |= 0x20; /* write serialize PCI memory */ |
Ronald G. Minnich | fb93749 | 2006-06-10 22:57:15 +0000 | [diff] [blame] | 473 | } |
| 474 | |
Nils Jacobs | 5beac7f | 2010-11-03 13:19:50 +0000 | [diff] [blame] | 475 | /* load up E000 settings in eax. */ |
Nils Jacobs | a4f06f1 | 2011-12-30 22:30:27 +0100 | [diff] [blame] | 476 | for (; bit; bit--) { |
Ronald G. Minnich | fb93749 | 2006-06-10 22:57:15 +0000 | [diff] [blame] | 477 | msr.lo <<= 8; |
Nils Jacobs | 1c6d4e6 | 2010-12-26 05:12:49 +0000 | [diff] [blame] | 478 | msr.lo |= 1; /* cache disable PCI/Shadow memory */ |
Ronald G. Minnich | fb93749 | 2006-06-10 22:57:15 +0000 | [diff] [blame] | 479 | if (shadowByte && (1 << bit)) |
Nils Jacobs | 1c6d4e6 | 2010-12-26 05:12:49 +0000 | [diff] [blame] | 480 | msr.lo |= 0x20; /* write serialize PCI memory */ |
Ronald G. Minnich | fb93749 | 2006-06-10 22:57:15 +0000 | [diff] [blame] | 481 | } |
| 482 | |
| 483 | wrmsr(CPU_RCONF_E0_FF, msr); |
| 484 | } |
| 485 | |
Nils Jacobs | 1c6d4e6 | 2010-12-26 05:12:49 +0000 | [diff] [blame] | 486 | /* Set the GLPCI registers for the memory hole. |
Nils Jacobs | 5beac7f | 2010-11-03 13:19:50 +0000 | [diff] [blame] | 487 | * Keeps all cache shadow descriptors sync'ed. |
| 488 | * Entry: EDX:EAX is the shadow settings |
Ronald G. Minnich | fb93749 | 2006-06-10 22:57:15 +0000 | [diff] [blame] | 489 | */ |
| 490 | static void setShadowGLPCI(uint32_t shadowHi, uint32_t shadowLo) |
| 491 | { |
| 492 | msr_t msr; |
Stefan Reinauer | 14e2277 | 2010-04-27 06:56:47 +0000 | [diff] [blame] | 493 | |
Nils Jacobs | 5beac7f | 2010-11-03 13:19:50 +0000 | [diff] [blame] | 494 | /* Set the Enable Register. */ |
Ronald G. Minnich | fb93749 | 2006-06-10 22:57:15 +0000 | [diff] [blame] | 495 | msr = rdmsr(GLPCI_REN); |
| 496 | msr.lo &= 0xFFFF00FF; |
Nils Jacobs | a4f06f1 | 2011-12-30 22:30:27 +0100 | [diff] [blame] | 497 | msr.lo |= ((shadowLo & 0xFFFF0000) >> 8); |
Ronald G. Minnich | fb93749 | 2006-06-10 22:57:15 +0000 | [diff] [blame] | 498 | wrmsr(GLPCI_REN, msr); |
| 499 | } |
| 500 | |
Nils Jacobs | 1c6d4e6 | 2010-12-26 05:12:49 +0000 | [diff] [blame] | 501 | /* Set the GLIU SC register settings. Scans descriptor tables for SC_SHADOW. |
Nils Jacobs | 5beac7f | 2010-11-03 13:19:50 +0000 | [diff] [blame] | 502 | * Keeps all shadow descriptors sync'ed. |
| 503 | * Entry: EDX:EAX is the shadow settings |
Ronald G. Minnich | fb93749 | 2006-06-10 22:57:15 +0000 | [diff] [blame] | 504 | */ |
| 505 | static void setShadow(uint64_t shadowSettings) |
| 506 | { |
| 507 | int i; |
| 508 | msr_t msr; |
Nils Jacobs | a4f06f1 | 2011-12-30 22:30:27 +0100 | [diff] [blame] | 509 | struct gliutable *pTable; |
Ronald G. Minnich | fb93749 | 2006-06-10 22:57:15 +0000 | [diff] [blame] | 510 | uint32_t shadowLo, shadowHi; |
| 511 | |
| 512 | shadowLo = (uint32_t) shadowSettings; |
| 513 | shadowHi = (uint32_t) (shadowSettings >> 32); |
| 514 | |
| 515 | setShadowRCONF(shadowHi, shadowLo); |
| 516 | setShadowGLPCI(shadowHi, shadowLo); |
| 517 | |
Nils Jacobs | a4f06f1 | 2011-12-30 22:30:27 +0100 | [diff] [blame] | 518 | for (i = 0; gliutables[i]; i++) { |
Ronald G. Minnich | fb93749 | 2006-06-10 22:57:15 +0000 | [diff] [blame] | 519 | for (pTable = gliutables[i]; pTable->desc_type != GL_END; pTable++) { |
| 520 | if (pTable->desc_type == SC_SHADOW) { |
| 521 | |
| 522 | msr = rdmsr(pTable->desc_name); |
| 523 | msr.lo = (uint32_t) shadowSettings; |
Nils Jacobs | 5beac7f | 2010-11-03 13:19:50 +0000 | [diff] [blame] | 524 | msr.hi &= 0xFFFF0000; /* maintain PDID in upper EDX */ |
Ronald G. Minnich | fb93749 | 2006-06-10 22:57:15 +0000 | [diff] [blame] | 525 | msr.hi |= ((uint32_t) (shadowSettings >> 32)) & 0x0000FFFF; |
Nils Jacobs | 5beac7f | 2010-11-03 13:19:50 +0000 | [diff] [blame] | 526 | wrmsr(pTable->desc_name, msr); /* MSR - See the table above */ |
Ronald G. Minnich | fb93749 | 2006-06-10 22:57:15 +0000 | [diff] [blame] | 527 | |
| 528 | } |
| 529 | } |
| 530 | } |
| 531 | } |
| 532 | |
Nils Jacobs | d0ac789 | 2011-12-30 23:00:11 +0100 | [diff] [blame] | 533 | static void rom_shadow_settings(void) |
Ronald G. Minnich | fb93749 | 2006-06-10 22:57:15 +0000 | [diff] [blame] | 534 | { |
| 535 | uint64_t shadowSettings = getShadow(); |
Nils Jacobs | 5beac7f | 2010-11-03 13:19:50 +0000 | [diff] [blame] | 536 | shadowSettings &= (uint64_t) 0xFFFF00000000FFFFULL; /* Disable read & writes */ |
| 537 | shadowSettings |= (uint64_t) 0x0000FFFFFFFF0000ULL; /* Enable reads for C0000-FFFFF */ |
Ronald G. Minnich | fb93749 | 2006-06-10 22:57:15 +0000 | [diff] [blame] | 538 | setShadow(shadowSettings); |
| 539 | } |
| 540 | |
Nils Jacobs | 1c6d4e6 | 2010-12-26 05:12:49 +0000 | [diff] [blame] | 541 | /* Set up RCONF_DEFAULT and any other RCONF registers needed. |
Ronald G. Minnich | fb93749 | 2006-06-10 22:57:15 +0000 | [diff] [blame] | 542 | * |
Nils Jacobs | 5beac7f | 2010-11-03 13:19:50 +0000 | [diff] [blame] | 543 | * DEVRC_RCONF_DEFAULT: |
| 544 | * ROMRC(63:56) = 04h ; write protect ROMBASE |
| 545 | * ROMBASE(36:55) = 0FFFC0h ; Top of PCI/bottom of rom chipselect area |
| 546 | * DEVRC(35:28) = 39h ; cache disabled in PCI memory + WS bit on + Write Combine + write burst. |
| 547 | * SYSTOP(27:8) = top of system memory |
| 548 | * SYSRC(7:0) = 00h ; writeback, can set to 08h to make writethrough |
| 549 | */ |
Ronald G. Minnich | fb93749 | 2006-06-10 22:57:15 +0000 | [diff] [blame] | 550 | #define SYSMEM_RCONF_WRITETHROUGH 8 |
| 551 | #define DEVRC_RCONF_DEFAULT 0x21 |
| 552 | #define ROMBASE_RCONF_DEFAULT 0xFFFC0000 |
| 553 | #define ROMRC_RCONF_DEFAULT 0x25 |
| 554 | |
Nils Jacobs | d0ac789 | 2011-12-30 23:00:11 +0100 | [diff] [blame] | 555 | static void enable_L_cache(void) |
Ronald G. Minnich | fb93749 | 2006-06-10 22:57:15 +0000 | [diff] [blame] | 556 | { |
| 557 | struct gliutable *gl = 0; |
| 558 | int i; |
| 559 | msr_t msr; |
| 560 | uint8_t SysMemCacheProp; |
Ronald G. Minnich | fb93749 | 2006-06-10 22:57:15 +0000 | [diff] [blame] | 561 | |
| 562 | /* Locate SYSMEM entry in GLIU0table */ |
Nils Jacobs | a4f06f1 | 2011-12-30 22:30:27 +0100 | [diff] [blame] | 563 | for (i = 0; gliu0table[i].desc_name != GL_END; i++) { |
Ronald G. Minnich | fb93749 | 2006-06-10 22:57:15 +0000 | [diff] [blame] | 564 | if (gliu0table[i].desc_type == R_SYSMEM) { |
| 565 | gl = &gliu0table[i]; |
| 566 | break; |
| 567 | } |
| 568 | } |
| 569 | if (gl == 0) { |
Nils Jacobs | 5beac7f | 2010-11-03 13:19:50 +0000 | [diff] [blame] | 570 | post_code(0xCE); /* POST_RCONFInitError */ |
Ronald G. Minnich | fb93749 | 2006-06-10 22:57:15 +0000 | [diff] [blame] | 571 | while (1); |
| 572 | } |
| 573 | |
Nils Jacobs | 5beac7f | 2010-11-03 13:19:50 +0000 | [diff] [blame] | 574 | /* sysdescfound: */ |
Ronald G. Minnich | fb93749 | 2006-06-10 22:57:15 +0000 | [diff] [blame] | 575 | msr = rdmsr(gl->desc_name); |
| 576 | |
Stefan Reinauer | 14e2277 | 2010-04-27 06:56:47 +0000 | [diff] [blame] | 577 | /* 20 bit address - The bottom 12 bits go into bits 20-31 in eax, the |
| 578 | * top 8 bits go into 0-7 of edx. |
Ronald G. Minnich | fb93749 | 2006-06-10 22:57:15 +0000 | [diff] [blame] | 579 | */ |
| 580 | msr.lo = (msr.lo & 0xFFFFFF00) | (msr.hi & 0xFF); |
| 581 | msr.lo = ((msr.lo << 12) | (msr.lo >> 20)) & 0x000FFFFF; |
Nils Jacobs | 5beac7f | 2010-11-03 13:19:50 +0000 | [diff] [blame] | 582 | msr.lo <<= RCONF_DEFAULT_LOWER_SYSTOP_SHIFT; /* 8 */ |
Stefan Reinauer | 14e2277 | 2010-04-27 06:56:47 +0000 | [diff] [blame] | 583 | |
Nils Jacobs | 5beac7f | 2010-11-03 13:19:50 +0000 | [diff] [blame] | 584 | /* Set Default SYSMEM region properties */ |
Nils Jacobs | d0ac789 | 2011-12-30 23:00:11 +0100 | [diff] [blame] | 585 | msr.lo &= ~SYSMEM_RCONF_WRITETHROUGH; /* NOT writethrough == writeback 8 (or ~8) */ |
Ronald G. Minnich | fb93749 | 2006-06-10 22:57:15 +0000 | [diff] [blame] | 586 | |
Nils Jacobs | 5beac7f | 2010-11-03 13:19:50 +0000 | [diff] [blame] | 587 | /* Set PCI space cache properties */ |
Nils Jacobs | d0ac789 | 2011-12-30 23:00:11 +0100 | [diff] [blame] | 588 | msr.hi = (DEVRC_RCONF_DEFAULT >> 4); /* setting is split betwwen hi and lo... */ |
Ronald G. Minnich | fb93749 | 2006-06-10 22:57:15 +0000 | [diff] [blame] | 589 | msr.lo |= (DEVRC_RCONF_DEFAULT << 28); |
| 590 | |
Nils Jacobs | 5beac7f | 2010-11-03 13:19:50 +0000 | [diff] [blame] | 591 | /* Set the ROMBASE. This is usually FFFC0000h */ |
Ronald G. Minnich | fb93749 | 2006-06-10 22:57:15 +0000 | [diff] [blame] | 592 | msr.hi |= (ROMBASE_RCONF_DEFAULT >> 12) << RCONF_DEFAULT_UPPER_ROMBASE_SHIFT; |
| 593 | |
Nils Jacobs | 5beac7f | 2010-11-03 13:19:50 +0000 | [diff] [blame] | 594 | /* Set ROMBASE cache properties. */ |
Ronald G. Minnich | fb93749 | 2006-06-10 22:57:15 +0000 | [diff] [blame] | 595 | msr.hi |= ((ROMRC_RCONF_DEFAULT >> 8) | (ROMRC_RCONF_DEFAULT << 24)); |
Stefan Reinauer | 14e2277 | 2010-04-27 06:56:47 +0000 | [diff] [blame] | 596 | |
Nils Jacobs | 5beac7f | 2010-11-03 13:19:50 +0000 | [diff] [blame] | 597 | /* now program RCONF_DEFAULT */ |
Ronald G. Minnich | fb93749 | 2006-06-10 22:57:15 +0000 | [diff] [blame] | 598 | wrmsr(CPU_RCONF_DEFAULT, msr); |
Nils Jacobs | d0ac789 | 2011-12-30 23:00:11 +0100 | [diff] [blame] | 599 | printk(BIOS_DEBUG, "CPU_RCONF_DEFAULT (1808): 0x%08X:0x%08X\n", msr.hi, msr.lo); |
Ronald G. Minnich | fb93749 | 2006-06-10 22:57:15 +0000 | [diff] [blame] | 600 | |
Nils Jacobs | d0ac789 | 2011-12-30 23:00:11 +0100 | [diff] [blame] | 601 | /* RCONF_BYPASS: Cache tablewalk properties and SMM header access properties. */ |
Nils Jacobs | 5beac7f | 2010-11-03 13:19:50 +0000 | [diff] [blame] | 602 | /* Set to match system memory cache properties. */ |
Ronald G. Minnich | fb93749 | 2006-06-10 22:57:15 +0000 | [diff] [blame] | 603 | msr = rdmsr(CPU_RCONF_DEFAULT); |
| 604 | SysMemCacheProp = (uint8_t) (msr.lo & 0xFF); |
| 605 | msr = rdmsr(CPU_RCONF_BYPASS); |
| 606 | msr.lo = (msr.lo & 0xFFFF0000) | (SysMemCacheProp << 8) | SysMemCacheProp; |
| 607 | wrmsr(CPU_RCONF_BYPASS, msr); |
Nils Jacobs | d0ac789 | 2011-12-30 23:00:11 +0100 | [diff] [blame] | 608 | printk(BIOS_DEBUG, "CPU_RCONF_BYPASS (180A): 0x%08x : 0x%08x\n", msr.hi, msr.lo); |
| 609 | } |
| 610 | |
| 611 | static void setup_gx2_cache(void) |
| 612 | { |
| 613 | msr_t msr; |
| 614 | |
| 615 | enable_L_cache(); |
| 616 | |
| 617 | /* Make sure all INVD instructions are treated as WBINVD. We do this |
| 618 | * because we've found some programs which require this behavior. |
| 619 | */ |
| 620 | msr = rdmsr(CPU_DM_CONFIG0); |
| 621 | msr.lo |= DM_CONFIG0_LOWER_WBINVD_SET; |
| 622 | wrmsr(CPU_DM_CONFIG0, msr); |
| 623 | |
| 624 | x86_enable_cache(); |
| 625 | wbinvd(); |
Ronald G. Minnich | fb93749 | 2006-06-10 22:57:15 +0000 | [diff] [blame] | 626 | } |
| 627 | |
Nils Jacobs | 84be0f5 | 2010-12-29 21:12:10 +0000 | [diff] [blame] | 628 | uint32_t get_systop(void) |
| 629 | { |
| 630 | struct gliutable *gl = 0; |
| 631 | uint32_t systop; |
| 632 | msr_t msr; |
| 633 | int i; |
| 634 | |
| 635 | for (i = 0; gliu0table[i].desc_name != GL_END; i++) { |
| 636 | if (gliu0table[i].desc_type == R_SYSMEM) { |
| 637 | gl = &gliu0table[i]; |
| 638 | break; |
| 639 | } |
| 640 | } |
| 641 | if (gl) { |
| 642 | msr = rdmsr(gl->desc_name); |
| 643 | systop = ((msr.hi & 0xFF) << 24) | ((msr.lo & 0xFFF00000) >> 8); |
| 644 | systop += 0x1000; /* 4K */ |
| 645 | } else { |
| 646 | systop = |
| 647 | ((sizeram() - CONFIG_VIDEO_MB) * 1024) - SMM_SIZE - 1024; |
| 648 | } |
| 649 | return systop; |
| 650 | } |
| 651 | |
Nils Jacobs | 5beac7f | 2010-11-03 13:19:50 +0000 | [diff] [blame] | 652 | /* Core Logic initialization: Host bridge. */ |
Nils Jacobs | 84be0f5 | 2010-12-29 21:12:10 +0000 | [diff] [blame] | 653 | void northbridge_init_early(void) |
Li-Ta Lo | d8d8fff | 2006-04-13 17:00:38 +0000 | [diff] [blame] | 654 | { |
Ronald G. Minnich | 4223188 | 2006-04-07 16:55:20 +0000 | [diff] [blame] | 655 | int i; |
Stefan Reinauer | c02b4fc | 2010-03-22 11:42:32 +0000 | [diff] [blame] | 656 | printk(BIOS_DEBUG, "Enter %s\n", __func__); |
Li-Ta Lo | d8d8fff | 2006-04-13 17:00:38 +0000 | [diff] [blame] | 657 | |
Nils Jacobs | a4f06f1 | 2011-12-30 22:30:27 +0100 | [diff] [blame] | 658 | for (i = 0; gliutables[i]; i++) |
Ronald G. Minnich | 4223188 | 2006-04-07 16:55:20 +0000 | [diff] [blame] | 659 | GLIUInit(gliutables[i]); |
| 660 | |
Nils Jacobs | 5beac7f | 2010-11-03 13:19:50 +0000 | [diff] [blame] | 661 | /* Now that the descriptor to memory is set up. */ |
| 662 | /* The memory controller needs one read to synch its lines before it can be used. */ |
Ronald G. Minnich | 4223188 | 2006-04-07 16:55:20 +0000 | [diff] [blame] | 663 | i = *(int *) 0; |
| 664 | |
Nils Jacobs | d0ac789 | 2011-12-30 23:00:11 +0100 | [diff] [blame] | 665 | GeodeLinkPriority(); |
| 666 | |
| 667 | setup_gx2_cache(); |
| 668 | |
| 669 | rom_shadow_settings(); |
| 670 | |
Ronald G. Minnich | 4223188 | 2006-04-07 16:55:20 +0000 | [diff] [blame] | 671 | GLPCIInit(); |
Nils Jacobs | d0ac789 | 2011-12-30 23:00:11 +0100 | [diff] [blame] | 672 | |
Ronald G. Minnich | 4223188 | 2006-04-07 16:55:20 +0000 | [diff] [blame] | 673 | ClockGatingInit(); |
Nils Jacobs | d0ac789 | 2011-12-30 23:00:11 +0100 | [diff] [blame] | 674 | |
| 675 | __asm__ __volatile__("FINIT\n"); |
Stefan Reinauer | c02b4fc | 2010-03-22 11:42:32 +0000 | [diff] [blame] | 676 | printk(BIOS_DEBUG, "Exit %s\n", __func__); |
Ronald G. Minnich | 4223188 | 2006-04-07 16:55:20 +0000 | [diff] [blame] | 677 | } |
| 678 | |