added AGP support for AMD K8
git-svn-id: svn://svn.coreboot.org/coreboot/trunk@1568 2b7e53f0-3cfb-0310-b3e9-8179ed1497e1
This commit is contained in:
@@ -30,7 +30,7 @@ static void early_mtrr_init(void)
|
|||||||
/* Enable the access to AMD RdDram and WrDram extension bits */
|
/* Enable the access to AMD RdDram and WrDram extension bits */
|
||||||
msr = rdmsr(SYSCFG_MSR);
|
msr = rdmsr(SYSCFG_MSR);
|
||||||
msr.lo |= SYSCFG_MSR_MtrrFixDramModEn;
|
msr.lo |= SYSCFG_MSR_MtrrFixDramModEn;
|
||||||
wrmsr(msr);
|
wrmsr(SYSCFG_MSR, msr);
|
||||||
|
|
||||||
/* Inialize all of the relevant msrs to 0 */
|
/* Inialize all of the relevant msrs to 0 */
|
||||||
msr.lo = 0;
|
msr.lo = 0;
|
||||||
@@ -43,7 +43,7 @@ static void early_mtrr_init(void)
|
|||||||
/* Disable the access to AMD RdDram and WrDram extension bits */
|
/* Disable the access to AMD RdDram and WrDram extension bits */
|
||||||
msr = rdmsr(SYSCFG_MSR);
|
msr = rdmsr(SYSCFG_MSR);
|
||||||
msr.lo &= ~SYSCFG_MSR_MtrrFixDramModEn;
|
msr.lo &= ~SYSCFG_MSR_MtrrFixDramModEn;
|
||||||
wrmsr(msr);
|
wrmsr(SYSCFG_MSR, msr);
|
||||||
|
|
||||||
/* Enable memory access for 0 - 1MB using top_mem */
|
/* Enable memory access for 0 - 1MB using top_mem */
|
||||||
msr.hi = 0;
|
msr.hi = 0;
|
||||||
@@ -87,7 +87,7 @@ static void early_mtrr_init(void)
|
|||||||
|
|
||||||
/* Enale the MTRRs in SYSCFG */
|
/* Enale the MTRRs in SYSCFG */
|
||||||
msr = rdmsr(SYSCFG_MSR);
|
msr = rdmsr(SYSCFG_MSR);
|
||||||
msr.lo |= SYSCFG_MSR_MtrrrVarDramEn;
|
msr.lo |= SYSCFG_MSR_MtrrVarDramEn;
|
||||||
wrmsr(SYSCFG_MSR, msr);
|
wrmsr(SYSCFG_MSR, msr);
|
||||||
|
|
||||||
/* Enable the cache */
|
/* Enable the cache */
|
||||||
|
@@ -89,7 +89,7 @@ enable_mtrr:
|
|||||||
/* Enable the MTRRs and IORRs in SYSCFG */
|
/* Enable the MTRRs and IORRs in SYSCFG */
|
||||||
movl $SYSCFG_MSR, %ecx
|
movl $SYSCFG_MSR, %ecx
|
||||||
rdmsr
|
rdmsr
|
||||||
/* Don't enable SYSCFG_MSR_MtrrFixDramEn) untill we have done with VGA BIOS */
|
/* Don't enable SYSCFG_MSR_MtrrFixDramEn untill we have done with VGA BIOS */
|
||||||
orl $(SYSCFG_MSR_MtrrVarDramEn), %eax
|
orl $(SYSCFG_MSR_MtrrVarDramEn), %eax
|
||||||
wrmsr
|
wrmsr
|
||||||
|
|
||||||
|
@@ -300,6 +300,14 @@ void setup_mtrrs(struct mem_range *mem)
|
|||||||
struct mem_range *memp;
|
struct mem_range *memp;
|
||||||
unsigned long range_startk, range_sizek;
|
unsigned long range_startk, range_sizek;
|
||||||
unsigned int reg;
|
unsigned int reg;
|
||||||
|
msr_t msr;
|
||||||
|
|
||||||
|
#if defined(k7) || defined(k8)
|
||||||
|
/* Enable the access to AMD RdDram and WrDram extension bits */
|
||||||
|
msr = rdmsr(SYSCFG_MSR);
|
||||||
|
msr.lo |= SYSCFG_MSR_MtrrFixDramModEn;
|
||||||
|
wrmsr(SYSCFG_MSR, msr);
|
||||||
|
#endif
|
||||||
|
|
||||||
printk_debug("\n");
|
printk_debug("\n");
|
||||||
/* Initialized the fixed_mtrrs to uncached */
|
/* Initialized the fixed_mtrrs to uncached */
|
||||||
@@ -318,16 +326,31 @@ void setup_mtrrs(struct mem_range *mem)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(k7) || defined(k8)
|
|
||||||
#warning "FIXME: dealing with RdMEM/WrMEM for Athlon/Opteron"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
printk_debug("Setting fixed MTRRs(%d-%d) type: WB\n",
|
printk_debug("Setting fixed MTRRs(%d-%d) type: WB\n",
|
||||||
start_mtrr, last_mtrr);
|
start_mtrr, last_mtrr);
|
||||||
set_fixed_mtrrs(start_mtrr, last_mtrr, MTRR_TYPE_WRBACK);
|
|
||||||
|
|
||||||
|
#if defined(k7) || defined(k8)
|
||||||
|
set_fixed_mtrrs(start_mtrr, last_mtrr,
|
||||||
|
MTRR_TYPE_WRBACK | MTRR_READ_MEM| MTRR_WRITE_MEM);
|
||||||
|
#else
|
||||||
|
set_fixed_mtrrs(start_mtrr, last_mtrr,
|
||||||
|
MTRR_TYPE_WRBACK);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
printk_debug("DONE fixed MTRRs\n");
|
printk_debug("DONE fixed MTRRs\n");
|
||||||
|
|
||||||
|
#if defined(k7) || defined(k8)
|
||||||
|
/* Disable the access to AMD RdDram and WrDram extension bits */
|
||||||
|
msr = rdmsr(SYSCFG_MSR);
|
||||||
|
msr.lo &= ~SYSCFG_MSR_MtrrFixDramModEn;
|
||||||
|
wrmsr(SYSCFG_MSR, msr);
|
||||||
|
/* Enale the RdMEM and WrMEM bits in SYSCFG */
|
||||||
|
msr = rdmsr(SYSCFG_MSR);
|
||||||
|
msr.lo |= SYSCFG_MSR_MtrrFixDramEn;
|
||||||
|
wrmsr(SYSCFG_MSR, msr);
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Cache as many memory areas as possible */
|
/* Cache as many memory areas as possible */
|
||||||
/* FIXME is there an algorithm for computing the optimal set of mtrrs?
|
/* FIXME is there an algorithm for computing the optimal set of mtrrs?
|
||||||
* In some cases it is definitely possible to do better.
|
* In some cases it is definitely possible to do better.
|
||||||
|
@@ -456,6 +456,17 @@ static void set_pci_ops(struct device *dev)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
extern struct pci_driver generic_vga_driver;
|
||||||
|
/* TODO: Install generic VGA driver for VGA devices, base on the
|
||||||
|
* class ID */
|
||||||
|
if ((dev->class >> 8) == PCI_CLASS_DISPLAY_VGA) {
|
||||||
|
printk_debug("setting up generic VGA driver\n");
|
||||||
|
dev->ops = generic_vga_driver.ops;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/* If I don't have a specific driver use the default operations */
|
/* If I don't have a specific driver use the default operations */
|
||||||
switch(dev->hdr_type & 0x7f) { /* header type */
|
switch(dev->hdr_type & 0x7f) { /* header type */
|
||||||
case PCI_HEADER_TYPE_NORMAL: /* standard header */
|
case PCI_HEADER_TYPE_NORMAL: /* standard header */
|
||||||
|
@@ -39,6 +39,7 @@ driver mainboard.o
|
|||||||
#dir /drivers/si/3114
|
#dir /drivers/si/3114
|
||||||
#dir /drivers/intel/82551
|
#dir /drivers/intel/82551
|
||||||
driver ti_firewire.o
|
driver ti_firewire.o
|
||||||
|
#dir /drivers/vga
|
||||||
|
|
||||||
if HAVE_MP_TABLE object mptable.o end
|
if HAVE_MP_TABLE object mptable.o end
|
||||||
if HAVE_PIRQ_TABLE object irq_tables.o end
|
if HAVE_PIRQ_TABLE object irq_tables.o end
|
||||||
|
@@ -168,9 +168,7 @@ static unsigned int amdk8_scan_chains(device_t dev, unsigned int max)
|
|||||||
|
|
||||||
nodeid = amdk8_nodeid(dev);
|
nodeid = amdk8_nodeid(dev);
|
||||||
|
|
||||||
#if 1
|
printk_spew("amdk8_scan_chains max: %d starting...\n", max);
|
||||||
printk_debug("amdk8_scan_chains max: %d starting...\n", max);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
for (link = 0; link < dev->links; link++) {
|
for (link = 0; link < dev->links; link++) {
|
||||||
uint32_t link_type;
|
uint32_t link_type;
|
||||||
@@ -246,19 +244,15 @@ static unsigned int amdk8_scan_chains(device_t dev, unsigned int max)
|
|||||||
((dev->link[link].subordinate) << 24);
|
((dev->link[link].subordinate) << 24);
|
||||||
f1_write_config32(config_reg, config_busses);
|
f1_write_config32(config_reg, config_busses);
|
||||||
|
|
||||||
#if 1
|
printk_spew("Hyper transport scan link: %d max: %d\n",
|
||||||
printk_debug("Hyper transport scan link: %d max: %d\n",
|
|
||||||
link, max);
|
link, max);
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Now we can scan all of the subordinate busses i.e. the
|
/* Now we can scan all of the subordinate busses i.e. the
|
||||||
* chain on the hypertranport link */
|
* chain on the hypertranport link */
|
||||||
max = hypertransport_scan_chain(&dev->link[link], max);
|
max = hypertransport_scan_chain(&dev->link[link], max);
|
||||||
|
|
||||||
#if 1
|
printk_spew("Hyper transport scan link: %d new max: %d\n",
|
||||||
printk_debug("Hyper transport scan link: %d new max: %d\n",
|
|
||||||
link, max);
|
link, max);
|
||||||
#endif
|
|
||||||
|
|
||||||
/* We know the number of busses behind this bridge. Set the
|
/* We know the number of busses behind this bridge. Set the
|
||||||
* subordinate bus number to it's real value
|
* subordinate bus number to it's real value
|
||||||
@@ -271,13 +265,10 @@ static unsigned int amdk8_scan_chains(device_t dev, unsigned int max)
|
|||||||
config_busses = (config_busses & 0x00ffffff) |
|
config_busses = (config_busses & 0x00ffffff) |
|
||||||
(dev->link[link].subordinate << 24);
|
(dev->link[link].subordinate << 24);
|
||||||
f1_write_config32(config_reg, config_busses);
|
f1_write_config32(config_reg, config_busses);
|
||||||
#if 1
|
printk_spew("Hypertransport scan link done\n");
|
||||||
printk_debug("Hypertransport scan link done\n");
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
#if 1
|
|
||||||
printk_debug("amdk8_scan_chains max: %d done\n", max);
|
printk_spew("amdk8_scan_chains max: %d done\n", max);
|
||||||
#endif
|
|
||||||
return max;
|
return max;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -324,8 +315,8 @@ static unsigned amdk8_find_mempair(unsigned nodeid, unsigned link)
|
|||||||
}
|
}
|
||||||
/* Do I have a match for this node and link? */
|
/* Do I have a match for this node and link? */
|
||||||
if (((base & 3) == 3) &&
|
if (((base & 3) == 3) &&
|
||||||
((limit & 7) == nodeid) &&
|
((limit & 7) == nodeid) &&
|
||||||
(((limit >> 4) & 3) == link)) {
|
(((limit >> 4) & 3) == link)) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -438,7 +429,6 @@ static void amdk8_set_resource(device_t dev, struct resource *resource,
|
|||||||
if (dev->link[link].bridge_ctrl & PCI_BRIDGE_CTL_NO_ISA) {
|
if (dev->link[link].bridge_ctrl & PCI_BRIDGE_CTL_NO_ISA) {
|
||||||
base |= PCI_IO_BASE_NO_ISA;
|
base |= PCI_IO_BASE_NO_ISA;
|
||||||
}
|
}
|
||||||
|
|
||||||
f1_write_config32(reg + 0x4, limit);
|
f1_write_config32(reg + 0x4, limit);
|
||||||
f1_write_config32(reg, base);
|
f1_write_config32(reg, base);
|
||||||
} else if (resource->flags & IORESOURCE_MEM) {
|
} else if (resource->flags & IORESOURCE_MEM) {
|
||||||
@@ -494,7 +484,7 @@ static void amdk8_set_resources(device_t dev)
|
|||||||
* The root device in a AMD K8 system is not at Bus 0, Device 0, Fun 0
|
* The root device in a AMD K8 system is not at Bus 0, Device 0, Fun 0
|
||||||
* as other PCI based systems. The northbridge is at Bus 0, Device 0x18,
|
* as other PCI based systems. The northbridge is at Bus 0, Device 0x18,
|
||||||
* Fun 0. We have to call the pci_scan_bus() with PCI_DEVFN(0x18,0) as
|
* Fun 0. We have to call the pci_scan_bus() with PCI_DEVFN(0x18,0) as
|
||||||
* the starting device instead of PCI_DEVFN(0x0, 0) as in the default
|
* the starting device instead of PCI_DEVFN(0x00, 0) as in the default
|
||||||
* root_dev_scan_pci_bus().
|
* root_dev_scan_pci_bus().
|
||||||
*
|
*
|
||||||
* This function is set up as the default scan_bus() method for mainboards'
|
* This function is set up as the default scan_bus() method for mainboards'
|
||||||
@@ -507,17 +497,17 @@ unsigned int amdk8_scan_root_bus(device_t root, unsigned int max)
|
|||||||
{
|
{
|
||||||
unsigned reg;
|
unsigned reg;
|
||||||
|
|
||||||
printk_debug("amdk8_scan_root_bus\n");
|
printk_spew("amdk8_scan_root_bus\n");
|
||||||
|
|
||||||
/* Unmap all of the HT chains */
|
/* Unmap all of the HT chains by clearing the Configuration
|
||||||
|
* Map registers */
|
||||||
for (reg = 0xe0; reg <= 0xec; reg += 4) {
|
for (reg = 0xe0; reg <= 0xec; reg += 4) {
|
||||||
f1_write_config32(reg, 0);
|
f1_write_config32(reg, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
printk_debug("amdk8_scan_root_bus: start scaning pci bus\n");
|
|
||||||
max = pci_scan_bus(&root->link[0], PCI_DEVFN(0x18, 0), 0xff, max);
|
max = pci_scan_bus(&root->link[0], PCI_DEVFN(0x18, 0), 0xff, max);
|
||||||
|
|
||||||
printk_debug("amdk8_scan_root_bus: done\n");
|
printk_spew("amdk8_scan_root_bus: done\n");
|
||||||
return max;
|
return max;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -526,7 +516,7 @@ static void mcf0_control_init(struct device *dev)
|
|||||||
uint32_t cmd;
|
uint32_t cmd;
|
||||||
|
|
||||||
#if 1
|
#if 1
|
||||||
printk_debug("NB: Function 0 Misc Control.. ");
|
printk_spew("NB: Function 0 Misc Control.. ");
|
||||||
/* improve latency and bandwith on HT */
|
/* improve latency and bandwith on HT */
|
||||||
cmd = pci_read_config32(dev, 0x68);
|
cmd = pci_read_config32(dev, 0x68);
|
||||||
cmd &= 0xffff80ff;
|
cmd &= 0xffff80ff;
|
||||||
@@ -540,8 +530,9 @@ static void mcf0_control_init(struct device *dev)
|
|||||||
cmd &= 0xfffff0ff;
|
cmd &= 0xfffff0ff;
|
||||||
cmd |= 0x00000600;
|
cmd |= 0x00000600;
|
||||||
pci_write_config32(dev, 0xdc, cmd );
|
pci_write_config32(dev, 0xdc, cmd );
|
||||||
#endif
|
#endif
|
||||||
printk_debug("done.\n");
|
|
||||||
|
printk_spew("done.\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -556,7 +547,15 @@ static void amdk8_enable_resources(struct device *dev)
|
|||||||
printk_debug("%s bridge ctrl <- %04x\n", dev_path(dev), ctrl);
|
printk_debug("%s bridge ctrl <- %04x\n", dev_path(dev), ctrl);
|
||||||
pci_write_config16(dev, PCI_BRIDGE_CONTROL, ctrl);
|
pci_write_config16(dev, PCI_BRIDGE_CONTROL, ctrl);
|
||||||
|
|
||||||
#if 0
|
#if 1
|
||||||
|
/* No, don;t do it here, we should create phantom PCI resource
|
||||||
|
* for leagcy VGA resources in VGA device driver and use the
|
||||||
|
* generic resource allocation/assignment code to do it
|
||||||
|
*
|
||||||
|
* TOO BAD, the generic resource allcation code refuses to do
|
||||||
|
* abything with VGA and the AMDK8 resource code does want
|
||||||
|
* more than one discontinous IO/MEM regions */
|
||||||
|
|
||||||
/* let's see what link VGA is on */
|
/* let's see what link VGA is on */
|
||||||
for (link = 0; link < dev->links; link++) {
|
for (link = 0; link < dev->links; link++) {
|
||||||
device_t child;
|
device_t child;
|
||||||
@@ -566,22 +565,32 @@ static void amdk8_enable_resources(struct device *dev)
|
|||||||
vgalink = link;
|
vgalink = link;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (vgalink != 1) {
|
if (vgalink != -1) {
|
||||||
/* now find the IOPAIR that goes to vgalink and set the vga
|
uint32_t base, limit;
|
||||||
* enable in the base part (0x30) */
|
unsigned reg;
|
||||||
/* now allocate an MMIOPAIR and point it to the CPU0,
|
/* now allocate an MMPAIR and point it to the CPU0,
|
||||||
* LINK=vgalink */
|
* LINK=vgalink */
|
||||||
/* now set IORR1 so it has a hole for the 0xa0000-0xcffff
|
/* Set up mem pair
|
||||||
* region */
|
* FIXME: add amdk8_find_free_mempair() */
|
||||||
|
//reg = amdk8_find_mempair(0, vgalink);
|
||||||
|
reg = 0x90;
|
||||||
|
/* Set base of 0xa0000 */
|
||||||
|
base = 0xa03;
|
||||||
|
limit = 0xd00 | (vgalink << 4);
|
||||||
|
printk_debug("setting MMIO routing for VGA reg:0x%x, base: 0x%x, limit 0x%x\n",
|
||||||
|
reg, base, limit);
|
||||||
|
f1_write_config32(reg, base);
|
||||||
|
f1_write_config32(reg + 4, limit);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
pci_dev_enable_resources(dev);
|
pci_dev_enable_resources(dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct device_operations northbridge_operations = {
|
static struct device_operations northbridge_operations = {
|
||||||
.read_resources = amdk8_read_resources,
|
.read_resources = amdk8_read_resources,
|
||||||
.set_resources = amdk8_set_resources,
|
.set_resources = amdk8_set_resources,
|
||||||
.enable_resources = pci_dev_enable_resources,
|
.enable_resources = amdk8_enable_resources,
|
||||||
.init = mcf0_control_init,
|
.init = mcf0_control_init,
|
||||||
.scan_bus = amdk8_scan_chains,
|
.scan_bus = amdk8_scan_chains,
|
||||||
.enable = 0,
|
.enable = 0,
|
||||||
|
Reference in New Issue
Block a user