Index: src/southbridge/amd/rs690/early_setup.c
===================================================================
--- src/southbridge/amd/rs690/early_setup.c	(revision 6275)
+++ src/southbridge/amd/rs690/early_setup.c	(working copy)
@@ -3,6 +3,8 @@
  *
  * Copyright (C) 2008 Advanced Micro Devices, Inc.
  * Copyright (C) 2008 Carl-Daniel Hailfinger
+ * Copyright (C) 2010 Advanced Micro Devices, Inc.
+ * Copyright (C) 2011 Ivaylo Valkov <ivaylo@e-valkov.org>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -18,6 +20,9 @@
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
  */
 
+#ifndef CONFIG_NORTHBRIDGE_AMD_AMDFAM10
+#define CONFIG_NORTHBRIDGE_AMD_AMDFAM10 0
+#endif
 
 #define NBHTIU_INDEX		0xA8
 #define NBMISC_INDEX		0x60
@@ -89,6 +94,7 @@
 	}
 }
 
+#if CONFIG_NORTHBRIDGE_AMD_AMDFAM10 != 1		/* Used only in k8_optimization. Otherwise build fails. */
 static void set_nbcfg_enable_bits(device_t nb_dev, u32 reg_pos, u32 mask,
 				  u32 val)
 {
@@ -100,6 +106,9 @@
 		pci_write_config32(nb_dev, reg_pos, reg);
 	}
 }
+#else
+#define set_nbcfg_enable_bits() do{}while(0)
+#endif
 
 static void set_nbcfg_enable_bits_8(device_t nb_dev, u32 reg_pos, u8 mask,
 				    u8 val)
@@ -148,10 +157,29 @@
 		printk(BIOS_INFO, "CPU Rev is K8_G0.\n");
 	else if (eax <= 0x100000)
 		printk(BIOS_INFO, "CPU Rev is K8_G1.\n");
+	else if (eax <= 0x100f00)
+		printk(BIOS_INFO, "CPU Rev is Fam 10.\n");
 	else
 		printk(BIOS_INFO, "CPU Rev is K8_10.\n");
 }
 
+static u8 is_famly10(void)
+{
+	return (cpuid_eax(1) & 0xff00000) != 0;
+}
+
+#if CONFIG_NORTHBRIDGE_AMD_AMDFAM10 == 1		/* save some spaces */
+static u8 l3_cache(void)
+{
+	return (cpuid_edx(0x80000006) & (0x3FFF << 18)) != 0;
+}
+
+static u8 cpu_core_number(void)
+{
+	return (cpuid_ecx(0x80000008) & 0xFF) + 1;
+}
+#endif
+
 static u8 get_nb_rev(device_t nb_dev)
 {
 	u32 reg;
@@ -215,6 +243,7 @@
 	}
 }
 
+#if CONFIG_NORTHBRIDGE_AMD_AMDFAM10 != 1		/* save some spaces */
 /*******************************************************
 * Optimize k8 with UMA.
 * See BKDG_NPT_0F guide for details.
@@ -266,7 +295,75 @@
 	msr.hi &= ~(1 << 4);
 	wrmsr(0xC001001F, msr);
 }
+#else
+#define k8_optimization() do{}while(0)
+#endif	/* #if CONFIG_NORTHBRIDGE_AMD_AMDFAM10 != 1 */
 
+#if CONFIG_NORTHBRIDGE_AMD_AMDFAM10 == 1		/* save some spaces */
+static void fam10_optimization(void)
+{
+	device_t cpu_f0, cpu_f2, cpu_f3;
+	u32 val;
+
+	printk(BIOS_INFO, "fam10_optimization()\n");
+
+	cpu_f0 = PCI_DEV(0, 0x18, 0);
+	cpu_f2 = PCI_DEV(0, 0x18, 2);
+	cpu_f3 = PCI_DEV(0, 0x18, 3);
+
+	/* 8.6.4.1 */
+	/* Table 8-13 */
+	pci_write_config32(cpu_f0, 0x90, 0x808502D0);
+	/* Table 8-14 */
+	pci_write_config32(cpu_f0, 0x94, 0x00000000);
+
+	/* Table 8-15 */
+	val = pci_read_config32(cpu_f0, 0x68);
+	val |= 1 << 24;
+	pci_write_config32(cpu_f0, 0x68, val);
+
+	/* Table 8-16 */
+	val = pci_read_config32(cpu_f0, 0x84);
+	val &= ~(1 << 12);
+	pci_write_config32(cpu_f0, 0x84, val);
+
+	/* Table 8-17 */
+	val = pci_read_config32(cpu_f2, 0x90);
+	val &= ~(1 << 10);
+	pci_write_config32(cpu_f2, 0x90, val);
+
+	/* Table 8-18 */
+	pci_write_config32(cpu_f3, 0x6C, 0x60018051);
+	/* Table 8-19 */
+	pci_write_config32(cpu_f3, 0x70, 0x60321151);
+	/* Table 8-20 */
+	pci_write_config32(cpu_f3, 0x74, 0x00980101);
+	/* Table 8-21 */
+	pci_write_config32(cpu_f3, 0x78, 0x00200C14);
+	/* Table 8-22 */
+	pci_write_config32(cpu_f3, 0x7C, 0x00070811); /* TODO: Check if L3 Cache is enabled. */
+
+	/* Table 8-23 */
+	Set_NB32(cpu_f3, 0x140, 0x00D33656);
+	/* Table 8-24 */
+	Set_NB32(cpu_f3, 0x144, 0x00000036);
+	/* Table 8-25 */
+	Set_NB32(cpu_f3, 0x148, 0x8000832A);
+	/* Table 8-26 */
+	Set_NB32(cpu_f3, 0x158, 0);
+	/*          L3 Disabled:  L3 Enabled: */
+	/* cores:    2   3    4    2   3    4  */
+	/* bit8:4   28  26   24   24  20   16 */
+	if (!l3_cache()) {
+		Set_NB32(cpu_f3, 0x1A0, 4 << 12 | (24 + 2*(4-cpu_core_number())) << 4 | 2);
+	} else {
+		Set_NB32(cpu_f3, 0x1A0, 4 << 12 | (16 + 4*(4-cpu_core_number())) << 4 | 4);
+	}
+}
+#else
+#define fam10_optimization() do{}while(0)
+#endif	/* #if CONFIG_NORTHBRIDGE_AMD_AMDFAM10 == 1 */
+
 /*****************************************
 * Compliant with CIM_33's ATINB_PCICFG_POR_TABLE
 *****************************************/
@@ -479,6 +576,10 @@
 		break;
 	}
 
-	k8_optimization();
+	if (is_famly10())
+		fam10_optimization();
+	else
+		k8_optimization();
+
 	rs690_por_init(nb_dev);
 }
