/* * This file is part of the coreboot project. * * Copyright (C) 2003 by Eric Biederman * Copyright (C) Stefan Reinauer * Copyright (C) 2007 Advanced Micro Devices, Inc. * Copyright (C) 2015 Timothy Pearson , Raptor Engineering * Copyright (C) 2016 Damien Zammit * * 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 * the Free Software Foundation; version 2 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. */ /* Turn off machine check triggers when reading * pci space where there are no devices. * This is necessary when scanning the bus for * devices which is done by the kernel */ #include #include #include #include #include #include #include #include #include #include "amdfam10.h" /** * @brief Read resources for AGP aperture * * @param dev * * There is only one AGP aperture resource needed. The resource is added to * the northbridge of BSP. * * The same trick can be used to augment legacy VGA resources which can * be detect by generic pci reousrce allocator for VGA devices. * BAD: it is more tricky than I think, the resource allocation code is * implemented in a way to NOT DOING legacy VGA resource allocation on * purpose :-(. */ static void mcf3_read_resources(struct device *dev) { struct resource *resource; unsigned char gart; /* Read the generic PCI resources */ pci_dev_read_resources(dev); /* If we are not the first processor don't allocate the gart apeture */ if (dev->path.pci.devfn != PCI_DEVFN(CONFIG_CDB, 3)) { return; } gart = 1; get_option(&gart, "gart"); if (gart) { /* Add a Gart apeture resource */ resource = new_resource(dev, 0x94); resource->size = CONFIG_AGP_APERTURE_SIZE; resource->align = log2(resource->size); resource->gran = log2(resource->size); resource->limit = 0xffffffff; /* 4G */ resource->flags = IORESOURCE_MEM; } } static void set_agp_aperture(struct device *dev, uint32_t pci_id) { uint32_t dword; struct resource *resource; resource = probe_resource(dev, 0x94); if (resource) { struct device *pdev; u32 gart_base, gart_acr; /* Remember this resource has been stored */ resource->flags |= IORESOURCE_STORED; /* Find the size of the GART aperture */ gart_acr = (0<<6)|(0<<5)|(0<<4)|((resource->gran - 25) << 1)|(0<<0); /* Get the base address */ gart_base = ((resource->base) >> 25) & 0x00007fff; /* Update the other northbriges */ pdev = 0; while ((pdev = dev_find_device(PCI_VENDOR_ID_AMD, pci_id, pdev))) { /* Store the GART size but don't enable it */ pci_write_config32(pdev, 0x90, gart_acr); /* Store the GART base address */ pci_write_config32(pdev, 0x94, gart_base); /* Don't set the GART Table base address */ pci_write_config32(pdev, 0x98, 0); /* Report the resource has been stored... */ report_resource_stored(pdev, resource, " "); /* Errata 540 workaround */ dword = pci_read_config32(pdev, 0x90); dword |= 0x1 << 6; /* DisGartTblWlkPrb = 0x1 */ pci_write_config32(pdev, 0x90, dword); } } } static void mcf3_set_resources_fam10h(struct device *dev) { /* Set the gart aperture */ set_agp_aperture(dev, 0x1203); /* Set the generic PCI resources */ pci_dev_set_resources(dev); } static void mcf3_set_resources_fam15h_model10(struct device *dev) { /* Set the gart aperture */ set_agp_aperture(dev, 0x1403); /* Set the generic PCI resources */ pci_dev_set_resources(dev); } static void mcf3_set_resources_fam15h(struct device *dev) { /* Set the gart aperture */ set_agp_aperture(dev, 0x1603); /* Set the generic PCI resources */ pci_dev_set_resources(dev); } static void misc_control_init(struct device *dev) { uint32_t dword; uint8_t nvram; uint8_t boost_limit; uint8_t current_boost; printk(BIOS_DEBUG, "NB: Function 3 Misc Control.. "); #if IS_ENABLED(CONFIG_DIMM_DDR3) && !IS_ENABLED(CONFIG_NORTHBRIDGE_AMD_AGESA) uint8_t node; uint8_t slot; uint8_t dimm_present; /* Restore DRAM MCA registers */ struct amdmct_memory_info *mem_info; mem_info = cbmem_find(CBMEM_ID_AMDMCT_MEMINFO); if (mem_info) { node = PCI_SLOT(dev->path.pci.devfn) - 0x18; /* Check node for installed DIMMs */ dimm_present = 0; /* Check all slots for installed DIMMs */ for (slot = 0; slot < MAX_DIMMS_SUPPORTED; slot++) { if (mem_info->dct_stat[node].DIMMPresent & (1 << slot)) { dimm_present = 1; break; } } if (dimm_present) { uint32_t mc4_status_high = pci_read_config32(dev, 0x4c); uint32_t mc4_status_low = pci_read_config32(dev, 0x48); if ((mc4_status_high & (0x1 << 31)) && (mc4_status_high != 0xffffffff)) { printk(BIOS_WARNING, "\nWARNING: MC4 Machine Check Exception detected on node %d!\n" "Signature: %08x%08x\n", node, mc4_status_high, mc4_status_low); } /* Clear MC4 error status */ pci_write_config32(dev, 0x48, 0x0); pci_write_config32(dev, 0x4c, 0x0); } } #endif /* Disable Machine checks from Invalid Locations. * This is needed for PC backwards compatibility. */ dword = pci_read_config32(dev, 0x44); dword |= (1<<6) | (1<<25); pci_write_config32(dev, 0x44, dword); boost_limit = 0xf; if (get_option(&nvram, "maximum_p_state_limit") == CB_SUCCESS) boost_limit = nvram & 0xf; /* Set P-state maximum value */ dword = pci_read_config32(dev, 0xdc); current_boost = (dword >> 8) & 0x7; if (boost_limit > current_boost) boost_limit = current_boost; dword &= ~(0x7 << 8); dword |= (boost_limit & 0x7) << 8; pci_write_config32(dev, 0xdc, dword); printk(BIOS_DEBUG, "done.\n"); } static struct device_operations mcf3_ops_fam10h = { .read_resources = mcf3_read_resources, .set_resources = mcf3_set_resources_fam10h, .enable_resources = pci_dev_enable_resources, .init = misc_control_init, .scan_bus = 0, .ops_pci = 0, }; static struct device_operations mcf3_ops_fam15h_model10 = { .read_resources = mcf3_read_resources, .set_resources = mcf3_set_resources_fam15h_model10, .enable_resources = pci_dev_enable_resources, .init = misc_control_init, .scan_bus = 0, .ops_pci = 0, }; static struct device_operations mcf3_ops_fam15h = { .read_resources = mcf3_read_resources, .set_resources = mcf3_set_resources_fam15h, .enable_resources = pci_dev_enable_resources, .init = misc_control_init, .scan_bus = 0, .ops_pci = 0, }; static const struct pci_driver mcf3_driver __pci_driver = { .ops = &mcf3_ops_fam10h, .vendor = PCI_VENDOR_ID_AMD, .device = 0x1203, }; static const struct pci_driver mcf3_driver_fam15_model10 __pci_driver = { .ops = &mcf3_ops_fam15h_model10, .vendor = PCI_VENDOR_ID_AMD, .device = 0x1403, }; static const struct pci_driver mcf3_driver_fam15 __pci_driver = { .ops = &mcf3_ops_fam15h, .vendor = PCI_VENDOR_ID_AMD, .device = 0x1603, };