diff options
Diffstat (limited to 'src/southbridge/amd/sr5650/pcie.c')
-rw-r--r-- | src/southbridge/amd/sr5650/pcie.c | 940 |
1 files changed, 0 insertions, 940 deletions
diff --git a/src/southbridge/amd/sr5650/pcie.c b/src/southbridge/amd/sr5650/pcie.c deleted file mode 100644 index 5c3aee7995..0000000000 --- a/src/southbridge/amd/sr5650/pcie.c +++ /dev/null @@ -1,940 +0,0 @@ -/* - * This file is part of the coreboot project. - * - * Copyright (C) 2010 Advanced Micro Devices, Inc. - * Copyright (C) 2015 Timothy Pearson <tpearson@raptorengineeringinc.com>, Raptor Engineering - * - * 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. - */ - -#include <console/console.h> -#include <device/device.h> -#include <device/pci.h> -#include <device/pci_ops.h> -#include <delay.h> -#include "sr5650.h" -#include "cmn.h" - -/*------------------------------------------------ -* Global variable -------------------------------------------------*/ -PCIE_CFG AtiPcieCfg = { - PCIE_ENABLE_STATIC_DEV_REMAP, /* Config */ - 0, /* ResetReleaseDelay */ - 0, /* Gfx0Width */ - 0, /* Gfx1Width */ - 0, /* GfxPayload */ - 0, /* GppPayload */ - 0, /* PortDetect, filled by GppSbInit */ - 0, /* PortHp */ - 0, /* DbgConfig */ - 0, /* DbgConfig2 */ - 0, /* GfxLx */ - 0, /* GppLx */ - 0, /* NBSBLx */ - 0, /* PortSlotInit */ - 0, /* Gfx0Pwr */ - 0, /* Gfx1Pwr */ - 0 /* GppPwr */ -}; - -static void ValidatePortEn(struct device *nb_dev); - -static void ValidatePortEn(struct device *nb_dev) -{ -} - -/***************************************************************** -* Compliant with CIM_33's PCIEPowerOffGppPorts -* Power off unused GPP lines -*****************************************************************/ -static void PciePowerOffGppPorts(struct device *nb_dev, struct device *dev, u32 port) -{ - printk(BIOS_DEBUG, "PciePowerOffGppPorts() port %d\n", port); - u32 reg; - u32 state_save; - uint8_t i; - struct southbridge_amd_sr5650_config *cfg = - (struct southbridge_amd_sr5650_config *)nb_dev->chip_info; - u32 state = cfg->port_enable; - - if (!(AtiPcieCfg.Config & PCIE_DISABLE_HIDE_UNUSED_PORTS)) - state &= AtiPcieCfg.PortDetect; - state = ~state; - state &= (1 << 4) + (1 << 5) + (1 << 6) + (1 << 7); - state_save = state << 17; - /* Disable ports any that failed training */ - for (i = 9; i <= 13; i++) { - if (!(AtiPcieCfg.PortDetect & 1 << i)) { - if ((port >= 9) && (port <= 13)) { - state |= (1 << (port + 7)); - } - if (port == 9) - state_save |= 1 << 25; - if (port == 10) - state_save |= 1 << 26; - if (port == 11) - state_save |= 1 << 6; - if (port == 12) - state_save |= 1 << 7; - - if (port == 13) { - reg = nbmisc_read_index(nb_dev, 0x2a); - reg |= 1 << 4; - nbmisc_write_index(nb_dev, 0x2a, reg); - } - } - } - state &= !(AtiPcieCfg.PortHp); - reg = nbmisc_read_index(nb_dev, 0x0c); - reg |= state; - nbmisc_write_index(nb_dev, 0x0c, reg); - - reg = nbmisc_read_index(nb_dev, 0x08); - reg |= state_save; - nbmisc_write_index(nb_dev, 0x08, reg); - - if ((AtiPcieCfg.Config & PCIE_OFF_UNUSED_GPP_LANES) - && !(AtiPcieCfg. - Config & (PCIE_DISABLE_HIDE_UNUSED_PORTS + - PCIE_GFX_COMPLIANCE))) { - } - /* step 3 Power Down Control for Southbridge */ - reg = nbpcie_p_read_index(dev, 0xa2); - - switch ((reg >> 4) & 0x7) { /* get bit 4-6, LC_LINK_WIDTH_RD */ - case 1: - nbpcie_ind_write_index(nb_dev, 0x65, 0x0e0e); - break; - case 2: - nbpcie_ind_write_index(nb_dev, 0x65, 0x0c0c); - break; - default: - break; - } -} - -/********************************************************************** -**********************************************************************/ -static void switching_gpp1_configurations(struct device *nb_dev, struct device *sb_dev) -{ - u32 reg; - struct southbridge_amd_sr5650_config *cfg = - (struct southbridge_amd_sr5650_config *)nb_dev->chip_info; - - /* 4.3.3.1.1.1.step1. Asserts PCIE-GPP1 global reset */ - reg = nbmisc_read_index(nb_dev, 0x8); - reg |= 1 << 15; - nbmisc_write_index(nb_dev, 0x8, reg); - - /* 4.3.3.1.1.1.step2. De-asserts STRAP_BIF_all_valid for PCIE-GPP1 core */ - reg = nbmisc_read_index(nb_dev, 0x26); - reg |= 1 << 28; - nbmisc_write_index(nb_dev, 0x26, reg); - - /* 4.3.3.1.1.1.step3. Programs PCIE-GPP1 to be desired port configuration 8:8 or 16:0. */ - reg = nbmisc_read_index(nb_dev, 0x8); - reg &= ~(1 << 8); /* clean */ - reg |= cfg->gpp1_configuration << 8; - nbmisc_write_index(nb_dev, 0x8, reg); - - /* 4.3.3.1.1.1.step4. Wait for 2ms */ - mdelay(1); - - /* 4.3.3.1.1.1.step5. Asserts STRAP_BIF_all_valid for PCIE-GPP1 core */ - reg = nbmisc_read_index(nb_dev, 0x26); - reg &= ~(1 << 28); - nbmisc_write_index(nb_dev, 0x26, reg); - - /* 4.3.3.1.1.1.step6. De-asserts PCIE-GPP1 global reset */ - reg = nbmisc_read_index(nb_dev, 0x8); - reg &= ~(1 << 15); - nbmisc_write_index(nb_dev, 0x8, reg); - - /* Follow the procedure for PCIE-GPP1 common initialization and - * link training sequence. */ -} - -/********************************************************************** -**********************************************************************/ -static void switching_gpp2_configurations(struct device *nb_dev, struct device *sb_dev) -{ - u32 reg; - struct southbridge_amd_sr5650_config *cfg = - (struct southbridge_amd_sr5650_config *)nb_dev->chip_info; - - /* 4.3.3.1.1.2.step1. Asserts PCIE-GPP2 global reset */ - reg = nbmisc_read_index(nb_dev, 0x8); - reg |= 1 << 13; - nbmisc_write_index(nb_dev, 0x8, reg); - - /* 4.3.3.1.1.2.step2. De-asserts STRAP_BIF_all_valid for PCIE-GPP2 core */ - reg = nbmisc_read_index(nb_dev, 0x26); - reg |= 1 << 29; - nbmisc_write_index(nb_dev, 0x26, reg); - - /* 4.3.3.1.1.2.step3. Programs PCIE-GPP2 to be desired port configuration 8:8 or 16:0. */ - reg = nbmisc_read_index(nb_dev, 0x8); - reg &= ~(1 << 9); /* clean */ - reg |= (cfg->gpp2_configuration & 1) << 9; - nbmisc_write_index(nb_dev, 0x8, reg); - - /* 4.3.3.1.1.2.step4. Wait for 2ms */ - mdelay(2); - - /* 4.3.3.1.1.2.step5. Asserts STRAP_BIF_all_valid for PCIE-GPP2 core */ - reg = nbmisc_read_index(nb_dev, 0x26); - reg &= ~(1 << 29); - nbmisc_write_index(nb_dev, 0x26, reg); - - /* 4.3.3.1.1.2.step6. De-asserts PCIE-GPP2 global reset */ - reg = nbmisc_read_index(nb_dev, 0x8); - reg &= ~(1 << 13); - nbmisc_write_index(nb_dev, 0x8, reg); - - /* Follow the procedure for PCIE-GPP2 common initialization and - * link training sequence. */ -} -static void switching_gpp3a_configurations(struct device *nb_dev, struct device *sb_dev) -{ - u32 reg; - struct southbridge_amd_sr5650_config *cfg = - (struct southbridge_amd_sr5650_config *)nb_dev->chip_info; - - /* 4.3.3.2.3.2.step1. Asserts PCIE-GPP3a global reset. */ - reg = nbmisc_read_index(nb_dev, 0x8); - reg |= 1 << 31; - nbmisc_write_index(nb_dev, 0x8, reg); - /* 4.3.3.2.3.2.step2. De-asserts STRAP_BIF_all_valid for PCIE-GPP3a core */ - reg = nbmisc_read_index(nb_dev, 0x26); - reg |= 1 << 30; - nbmisc_write_index(nb_dev, 0x26, reg); - /* 4.3.3.2.3.2.step3. Programs the desired PCIE-GPP3a configuration. */ - reg = nbmisc_read_index(nb_dev, 0x67); - reg &= ~0x1F; /* clean */ - reg |= cfg->gpp3a_configuration; - nbmisc_write_index(nb_dev, 0x67, reg); - /* 4.3.3.2.3.2.step4. Programs PCIE-GPP3a Line Director. */ - reg = nbmisc_read_index(nb_dev, 0x26); - reg &= 0xF0000000; /* TODO:Lane reversed. */ - switch (cfg->gpp3a_configuration) { - case 0xB: /* 1:1:1:1:1:1 */ - reg |= 0x2AA3554; - break; - case 0x1: /* 4:2:0:0:0:0 */ - reg |= 0x055B000; - break; - case 0x2: /* 4:1:1:0:0:0 */ - reg |= 0x215B400; - break; - case 0xC: /* 2:2:2:0:0:0 */ - reg |= 0xFF0BAA0; - break; - case 0xA: /* 2:2:1:1:0:0 */ - reg |= 0x215B400; - break; - case 0x4: /* 2:1:1:1:1:0 */ - reg |= 0xFF0BAA0; - break; - default: /* shouldn't be here. */ - printk(BIOS_DEBUG, "Warning:gpp3a_configuration is not correct. Check your devicetree.cb\n"); - break; - } - nbmisc_write_index(nb_dev, 0x26, reg); - /* 4.3.3.2.3.2.step5. De-asserts STRAP_BIF_all_valid for PCIE-GPP3a core */ - reg = nbmisc_read_index(nb_dev, 0x26); - reg &= ~(1 << 30); - nbmisc_write_index(nb_dev, 0x26, reg); - /* 4.3.3.2.3.2.step6. De-asserts PCIE-GPP3a global reset. */ - reg = nbmisc_read_index(nb_dev, 0x8); - reg &= ~(1 << 31); - nbmisc_write_index(nb_dev, 0x8, reg); -} - -/***************************************************************** -* The sr5650 uses NBCONFIG:0x1c (BAR3) to map the PCIE Extended Configuration -* Space to a 256MB range within the first 4GB of addressable memory. -*****************************************************************/ -void enable_pcie_bar3(struct device *nb_dev) -{ - printk(BIOS_DEBUG, "%s\n", __func__); - set_nbcfg_enable_bits(nb_dev, 0x7C, 1 << 30, 1 << 30); /* Enables writes to the BAR3 register. */ - set_nbcfg_enable_bits(nb_dev, 0x84, 7 << 16, 0 << 16); - - pci_write_config32(nb_dev, 0x1C, EXT_CONF_BASE_ADDRESS); /* PCIEMiscInit */ - pci_write_config32(nb_dev, 0x20, 0x00000000); - set_htiu_enable_bits(nb_dev, 0x32, 1 << 28, 1 << 28); /* PCIEMiscInit */ - ProgK8TempMmioBase(1, EXT_CONF_BASE_ADDRESS, TEMP_MMIO_BASE_ADDRESS); -} - -/***************************************************************** -* We should disable bar3 when we want to exit sr5650_enable, because bar3 will be -* remapped in set_resource later. -*****************************************************************/ -void disable_pcie_bar3(struct device *nb_dev) -{ - printk(BIOS_DEBUG, "%s\n", __func__); - pci_write_config32(nb_dev, 0x1C, 0); /* clear BAR3 address */ - set_nbcfg_enable_bits(nb_dev, 0x7C, 1 << 30, 0 << 30); /* Disable writes to the BAR3. */ - ProgK8TempMmioBase(0, EXT_CONF_BASE_ADDRESS, TEMP_MMIO_BASE_ADDRESS); -} - -/* - * GEN2 Software Compliance - */ -void init_gen2(struct device *nb_dev, struct device *dev, u8 port) -{ - u32 reg, val; - - /* for A11 (0x89 == 0) */ - reg = 0x34; - if (port <= 3) { - val = 1<<5; - } else { - val = 1<<31; - if (port >= 9) - reg = 0x39; - } - - /* TODO: check for rev > a11 */ - switch (port) { - case 2: - reg = 0x34; - val = 1<<5; - break; - case 3: - reg = 0x22; - val = 1<<6; - break; - case 4: - reg = 0x34; - val = 1<<31; - break; - case 5: - case 6: - reg = 0x39; - val = 1<<31; - break; - case 7: - case 8: - case 9: - reg = 0x37; - val = 1<<port; - break; - case 10: - reg = 0x22; - val = 1<<5; - break; - default: - reg = 0; - break; - } - - /* Enables GEN2 capability of the device */ - set_pcie_enable_bits(dev, 0xA4, 0x1, 0x1); - /* Advertise the link speed to be Gen2 */ - pci_ext_write_config32(nb_dev, dev, 0x88, 0xF0, 1<<2); /* LINK_CRTL2 */ - set_nbmisc_enable_bits(nb_dev, reg, val, val); -} - - -/* Alternative to default CPL buffer count */ -const u8 pGpp420000[] = {0x38, 0x1C}; -const u8 pGpp411000[] = {0x38, 0x0E, 0x0E}; -const u8 pGpp222000[] = {0x1C, 0x1C, 0x1C}; -const u8 pGpp221100[] = {0x1C, 0x1C, 0x0E, 0x0E}; -const u8 pGpp211110[] = {0x1C, 0x0E, 0x0E, 0x0E, 0, 0x0E, 0x0E}; -const u8 pGpp111111[] = {0x0E, 0x0E, 0x0E, 0x0E, 0, 0x0E, 0x0E}; - -/* - * Enabling Dynamic Slave CPL Buffer Allocation Feature for PCIE-GPP3a Ports - * PcieLibCplBufferAllocation - */ -static void gpp3a_cpl_buf_alloc(struct device *nb_dev, struct device *dev) -{ - u8 dev_index; - u8 value; - struct southbridge_amd_sr5650_config *cfg = - (struct southbridge_amd_sr5650_config *)nb_dev->chip_info; - - dev_index = dev->path.pci.devfn >> 3; - - if (dev_index < 4) - return; - - dev_index -= 4; - - switch (cfg->gpp3a_configuration) { - case 0x1: /* 4:2:0:0:0:0 */ - if (dev_index >= ARRAY_SIZE(pGpp420000)) - return; - value = pGpp420000[dev_index]; - break; - case 0x2: /* 4:1:1:0:0:0 */ - if (dev_index >= ARRAY_SIZE(pGpp411000)) - return; - value = pGpp411000[dev_index]; - break; - case 0xC: /* 2:2:2:0:0:0 */ - if (dev_index >= ARRAY_SIZE(pGpp222000)) - return; - value = pGpp222000[dev_index]; - break; - case 0xA: /* 2:2:1:1:0:0 */ - if (dev_index >= ARRAY_SIZE(pGpp221100)) - return; - value = pGpp221100[dev_index]; - break; - case 0x4: /* 2:1:1:1:1:0 */ - if (dev_index >= ARRAY_SIZE(pGpp211110)) - return; - value = pGpp211110[dev_index]; - break; - case 0xB: /* 1:1:1:1:1:1 */ - if (dev_index >= ARRAY_SIZE(pGpp111111)) - return; - value = pGpp111111[dev_index]; - break; - default: /* shouldn't be here. */ - printk(BIOS_WARNING, "buggy gpp3a_configuration\n"); - return; - } - - if (value != 0) { - set_pcie_enable_bits(dev, 0x10, 0x3f << 8, value << 8); - set_pcie_enable_bits(dev, 0x20, 1 << 11, 1 << 11); - } -} - -/* - * Enabling Dynamic Slave CPL Buffer Allocation Feature for PCIE-GPP1/PCIE-GPP2 Ports - * PcieLibCplBufferAllocation - */ -static void gpp12_cpl_buf_alloc(struct device *nb_dev, struct device *dev) -{ - u8 gpp_cfg; - u8 value; - u8 dev_index; - - dev_index = dev->path.pci.devfn >> 3; - struct southbridge_amd_sr5650_config *cfg = - (struct southbridge_amd_sr5650_config *)nb_dev->chip_info; - - if (dev_index < 4) { - gpp_cfg = cfg->gpp1_configuration; - } else if (dev_index > 0xa) { - gpp_cfg = cfg->gpp2_configuration; - } else { - return; - } - - if (gpp_cfg == 0) { - /* Configuration 16:0, leave the default value */ - } else if (gpp_cfg == 1) { - /* Configuration 8:8 */ - value = 0x60; - set_pcie_enable_bits(dev, 0x10, 0x3f << 8, value << 8); - set_pcie_enable_bits(dev, 0x20, 1 << 11, 1 << 11); - } else { - printk(BIOS_DEBUG, "buggy gpp configuration\n"); - } -} - -#if 1 /* BTS report error without this function. But some board - * fail to boot. Leave it here for future debug. */ - -/* - * Enable LCLK clock gating - */ -static void EnableLclkGating(struct device *dev) -{ - u8 port; - u32 reg = 0; - u32 mask = 0; - u32 value = 0; - struct device *nb_dev = pcidev_on_root(0x0, 0); - struct device *clk_f1 = pcidev_on_root(0x0, 1); - - reg = 0xE8; - port = dev->path.pci.devfn >> 3; - switch (port) { - //PCIE_CORE_INDEX_GPP1 - case 2: - case 3: - reg = 0x94; - mask = 1 << 16; - break; - - //PCIE_CORE_INDEX_GPP2 - case 11: - case 12: - value = 1 << 28; - break; - - //PCIE_CORE_INDEX_GPP3a - case 4 ... 7: - case 9: - case 10: - value = 1 << 31; - break; - - //PCIE_CORE_INDEX_GPP3b; - case 13: - value = 1 << 25; - break; - - //PCIE_CORE_INDEX_SB; - case 8: - reg = 0x94; - mask = 1 << 24; - break; - default: - break; - } - /* enable access func1 */ - set_nbcfg_enable_bits(nb_dev, 0x4C, 1 << 0, 1 << 0); - set_nbcfg_enable_bits(clk_f1, reg, mask, value); -} -#endif - -/***************************************** -* Compliant with CIM_33's PCIEGPPInit -* nb_dev: -* root bridge struct -* dev: -* p2p bridge struct -* port: -* p2p bridge number, 4-10 -*****************************************/ -void sr5650_gpp_sb_init(struct device *nb_dev, struct device *dev, u32 port) -{ - uint8_t training_ok = 1; - - u32 gpp_sb_sel = 0; - struct southbridge_amd_sr5650_config *cfg = - (struct southbridge_amd_sr5650_config *)nb_dev->chip_info; - - printk(BIOS_DEBUG, "%s: nb_dev=0x%p, dev=0x%p, port=0x%x\n", __func__, nb_dev, dev, port); - switch (port) { - case 2: - case 3: - gpp_sb_sel = PCIE_CORE_INDEX_GPP1; - break; - case 4 ... 7: - case 9: - case 10: - gpp_sb_sel = PCIE_CORE_INDEX_GPP3a; - break; - case 8: - gpp_sb_sel = PCIE_CORE_INDEX_SB; - break; - case 11: - case 12: - gpp_sb_sel = PCIE_CORE_INDEX_GPP2; - break; - case 13: - gpp_sb_sel = PCIE_CORE_INDEX_GPP3b; - break; - } - - /* Init common Core registers */ - set_pcie_enable_bits(dev, 0xB1, 1 << 28 | 1 << 23 | 1 << 20 | 1 << 19, - 1 << 28 | 1 << 23 | 1 << 20 | 1 << 19); - if (gpp_sb_sel == PCIE_CORE_INDEX_GPP3a) { - set_pcie_enable_bits(dev, 0xB1, 1 << 22, 1 << 22); - /* 4.3.3.2.3 Step 10: Dynamic Slave CPL Buffer Allocation */ - gpp3a_cpl_buf_alloc(nb_dev, dev); - } - if (gpp_sb_sel == PCIE_CORE_INDEX_GPP1 || gpp_sb_sel == PCIE_CORE_INDEX_GPP2) { - gpp12_cpl_buf_alloc(nb_dev, dev); - } - set_pcie_enable_bits(dev, 0xA1, (1 << 26) | (1 << 24) | (1 << 11), 1 << 11); - set_pcie_enable_bits(dev, 0xA0, 0x0000FFF0, 0x6830); - // PCIE should not ignore malformed packet error or ATS request - set_pcie_enable_bits(dev, 0x70, 1 << 12, 0); - //Step 14.1: Advertising Hot Plug Capabilities - set_pcie_enable_bits(dev, 0x10, 1 << 4, 1 << 4); //Enable power fault - - set_pcie_enable_bits(nb_dev, 0xC1 | gpp_sb_sel, 1 << 0, 1 << 0); - - /* init GPP core */ - /* 4.4.2.step13.1. Sets RCB completion timeout to be 200ms */ - pci_ext_write_config32(nb_dev, dev, 0x80, 0xF << 0, 0x6 << 0); - /* 4.4.2.step13.2. RCB completion timeout on link down to shorten enumeration time. */ - set_pcie_enable_bits(dev, 0x70, 1 << 19, 1 << 19); - /* 4.4.2.step13.3. Enable slave ordering rules */ - set_pcie_enable_bits(nb_dev, 0x20 | gpp_sb_sel, 1 << 8, 0 << 8); - /* 4.4.2.step13.4. Sets DMA payload size to 64 bytes. */ - set_pcie_enable_bits(nb_dev, 0x10 | gpp_sb_sel, 7 << 10, 4 << 10); - /* 4.4.2.step13.5. Set REGS_DLP_IGNORE_IN_L1_EN to ignore DLLPs - during L1 so that Tx Clk can be turned off. */ - set_pcie_enable_bits(nb_dev, 0x02 | gpp_sb_sel, 1 << 0 | 1 << 8, 1 << 0 | 1 << 8); // add bit 8 from CIMx - /* 4.4.2.step13.6. Set REGS_LC_ALLOW_TX_L1_CONTROL to allow TX to - prevent LC from going to L1 when there are outstanding completions.*/ - set_pcie_enable_bits(dev, 0x02, 1 << 15, 1 << 15); - - /* Enables the PLL power down when all lanes are inactive. - * It should be on in GPP. - */ - if (gpp_sb_sel == PCIE_CORE_INDEX_GPP3a || gpp_sb_sel == PCIE_CORE_INDEX_GPP3b || gpp_sb_sel == PCIE_CORE_INDEX_SB) { - set_pcie_enable_bits(nb_dev, 0x02 | gpp_sb_sel, 1 << 3, 1 << 3); - } - - /* 4.4.2.step13.7. Set REGS_LC_DONT_GO_TO_L0S_IF_L1_ARMED to prevent - lc to go to from L0 to Rcv_L0s if L1 is armed. */ - set_pcie_enable_bits(dev, 0xA1, 1 << 11, 1 << 11); - /* 4.4.2.step13.8. CMGOOD_OVERRIDE for all five PCIe cores. */ - set_nbmisc_enable_bits(nb_dev, 0x22, 1 << 27, 1 << 27); - /* 4.4.2.step13.9. Prevents Electrical Idle from causing a - transition from Rcv_L0 to Rcv_L0s. */ - set_pcie_enable_bits(dev, 0xB1, 1 << 20, 1 << 20); - /* 4.4.2.step13.10. Prevents the LTSSM from going to Rcv_L0s if - it has already acknowledged a request to go - to L1 but it has not transitioned there yet. */ - /* seems the same as step13.7 */ - set_pcie_enable_bits(dev, 0xA1, 1 << 11, 1 << 11); - /* 4.4.2.step13.11. Transmits FTS before Recovery. */ - set_pcie_enable_bits(dev, 0xA3, 1 << 9, 1 << 9); - /* 4.4.2.step13.12. Sets TX arbitration algorithm to round robin - for PCIE-GPP1, PCIE-GPP2, PCIE-GPP3a and PCIE-GPP3b cores only. */ - //if (gpp_sb_sel != PCIE_CORE_INDEX_SB) /* RPR NOT set SB_CORE, BTS set SB_CORE, we comply with BTS */ - set_pcie_enable_bits(nb_dev, 0x1C | gpp_sb_sel, 0x7FF, 0x109); - /* 4.4.2.step13.13. Sets number of TX Clocks to drain TX Pipe to 0x3.*/ - set_pcie_enable_bits(dev, 0xA0, 0xF << 4, 0x3 << 4); - /* 4.4.2.step13.14. Lets PI use Electrical Idle from PHY when - turning off PLL in L1 at Gen 2 speed instead of Inferred Electrical - Idle. - NOTE: LC still uses Inferred Electrical Idle. */ - set_pcie_enable_bits(nb_dev, 0x40 | gpp_sb_sel, 3 << 14, 2 << 14); - /* 4.4.2.step13.15. Turn on rx_fronten_en for all active lanes upon - exit from Electrical Idle, rather than being tied to PLL_PDNB. */ - set_pcie_enable_bits(nb_dev, 0xC2 | gpp_sb_sel, 1 << 25, 1 << 25); - - /* 4.4.2.step13.16. Advertises TX L0s and L1 exit latency. - TX L0s exit latency to be 100b: 512ns to less than 1us; - L1 exit latency to be 011b: 4us to less than 8us. - For Hot-Plug Slots: Advertise TX L0s and L1 exit latency. - TX L0s exit latency to be 110b: 2us to 4us. - L1 exit latency to be 111b: more than 64us.*/ - //set_pcie_enable_bits(dev, 0xC1, 0xF << 0, 0xC << 0); /* 0xF for hotplug. */ - set_pcie_enable_bits(dev, 0xC1, 0xF << 0, 0xF << 0); /* 0xF for hotplug. */ - /* 4.4.2.step13.17. Always ACK an ASPM L1 entry DLLP to - workaround credit control issue on PM_NAK - message of SB700 and SB800. */ - /* 4.4.4.step13.18. To allow advertising Gen 2 capabilities to Southbridge. */ - if (port == 8) { - set_pcie_enable_bits(dev, 0xA0, 1 << 23, 1 << 23); - set_pcie_enable_bits(nb_dev, 0xC1 | gpp_sb_sel, 1 << 1, 1 << 1); - } - /* 4.4.2.step13.19. CMOS Option (Gen 2 AUTO-Part 1 - Enabled by Default) */ - /* 4.4.2.step13.20. CMOS Option (RC Advertised Gen 2-Part1 - Disabled by Default)*/ - set_nbcfg_enable_bits(dev, 0x88, 0xF << 0, 0x2 << 0); - /* Disables GEN2 capability of the device. - * RPR typo- it says enable but the bit setting says disable. - * Disable it here and we enable it later. */ - set_pcie_enable_bits(dev, 0xA4, 1 << 0, 1 << 0); - - /* 4.4.2.step13.21. Legacy Hot Plug -CMOS Option */ - /* NOTE: This feature can be enabled only for Hot-Plug slots implemented on SR5690 platform. */ - - /* 4.4.2.step13.22. Native PCIe Mode -CMOS Option */ - /* Enable native PME. */ - set_pcie_enable_bits(dev, 0x10, 1 << 3, 1 < 3); - /* This bit when set indicates that the PCIe Link associated with this port - is connected to a slot. */ - pci_ext_write_config32(nb_dev, dev, 0x5a, 1 << 8, 1 << 8); - /* This bit when set indicates that this slot is capable of supporting - Hot-Plug operations. */ - set_nbcfg_enable_bits(dev, 0x6C, 1 << 6, 1 << 6); - /* Enables flushing of TLPs when Data Link is down. */ - set_pcie_enable_bits(dev, 0x20, 1 << 19, 0 << 19); - - /* 4.4.2.step14. Server Class Hot Plug Feature. NOTE: This feature is not supported on SR5670 and SR5650 */ - /* 4.4.2 step14.1: Advertising Hot Plug Capabilities */ - /* 4.4.2.step14.2: Firmware Upload */ - /* 4.4.2.Step14.3: SBIOS Acknowledgment to Firmware of Successful Firmware Upload */ - /* step14.4 */ - /* step14.5 */ - /* skip */ - - /* CIMx LPC Deadlock workaround - Enable Memory Write Map*/ - if (gpp_sb_sel == PCIE_CORE_INDEX_SB) { - set_pcie_enable_bits(nb_dev, 0x10 | gpp_sb_sel, 1 << 9, 1 << 9); - set_htiu_enable_bits(nb_dev, 0x06, 1 << 26, 1 << 26); - } - - /* This CPL setup requires more than this one register and should be done in gpp_core. - * The additional setup is for the different revisions. */ - - /* CIMx CommonPortInit settings that are not set above. */ - pci_ext_write_config32(nb_dev, dev, 0x88, 0xF0, 1 << 0); /* LINK_CRTL2 */ - - if (port == 8) - set_pcie_enable_bits(dev, 0xA0, 0, 1 << 23); - -#if 0 //SR56x0 pcie Gen2 code is not tested yet, we should enable it again when test finished. - /* set automatic Gen2 support, needs mainboard config option as Gen2 can cause issues on some platforms. */ - init_gen2(nb_dev, dev, port); - set_pcie_enable_bits(dev, 0xA4, 1 << 29, 1 << 29); - set_pcie_enable_bits(dev, 0xC0, 1 << 15, 0); - set_pcie_enable_bits(dev, 0xA2, 1 << 13, 0); -#endif - - /* Hotplug Support - bit5 + bit6 capable and surprise */ - pci_ext_write_config32(nb_dev, dev, 0x6c, 0x60, 0x60); - - /* Set interrupt pin info 0x3d */ - pci_ext_write_config32(nb_dev, dev, 0x3c, 1 << 8, 1 << 8); - - /* 5.12.9.3 Hotplug step 1 - NB_PCIE_ROOT_CTRL - enable pm irq - The RPR is wrong - this is not a PCIEND_P register */ - pci_ext_write_config32(nb_dev, dev, 0x74, 1 << 3, 1 << 3); - - /* 5.12.9.3 step 2 - PCIEP_PORT_CNTL - enable hotplug messages */ - if (port != 8) - set_pcie_enable_bits(dev, 0x10, 1 << 2, 1 << 2); - - /* Not sure about this PME setup */ - /* Native PME */ - set_pcie_enable_bits(dev, 0x10, 1 << 3, 1 << 3); /* Not set in CIMx */ - - /* PME Enable */ - pci_ext_write_config32(nb_dev, dev, 0x54, 1 << 8, 1 << 8); /* Not in CIMx */ - - /* 4.4.3 Training for GPP devices */ - /* init GPP */ - switch (port) { - case 2: - case 3: - case 4: /* GPP_SB */ - case 5: - case 6: - case 7: - case 9: /*GPP*/ - case 10: - case 11: - case 12: - case 13: - /* 4.4.2.step13.5. Blocks DMA traffic during C3 state */ - set_pcie_enable_bits(dev, 0x10, 1 << 0, 0 << 0); - /* Enables TLP flushing */ - set_pcie_enable_bits(dev, 0x20, 1 << 19, 0 << 19); - - /* check port enable */ - if (cfg->port_enable & (1 << port)) { - uint32_t hw_port = port; - switch (cfg->gpp3a_configuration) { - case 0x1: /* 4:2:0:0:0:0 */ - if (hw_port == 9) - hw_port = 4 + 1; - break; - case 0x2: /* 4:1:1:0:0:0 */ - if (hw_port == 9) - hw_port = 4 + 1; - else if (hw_port == 10) - hw_port = 4 + 2; - break; - case 0xc: /* 2:2:2:0:0:0 */ - if (hw_port == 6) - hw_port = 4 + 1; - else if (hw_port == 9) - hw_port = 4 + 2; - break; - case 0xa: /* 2:2:1:1:0:0 */ - if (hw_port == 6) - hw_port = 4 + 1; - else if (hw_port == 9) - hw_port = 4 + 2; - else if (hw_port == 10) - hw_port = 4 + 3; - break; - case 0x4: /* 2:1:1:1:1:0 */ - if (hw_port == 6) - hw_port = 4 + 1; - else if (hw_port == 7) - hw_port = 4 + 2; - else if (hw_port == 9) - hw_port = 4 + 3; - else if (hw_port == 10) - hw_port = 4 + 4; - break; - case 0xb: /* 1:1:1:1:1:1 */ - break; - default: /* shouldn't be here. */ - printk(BIOS_WARNING, "invalid gpp3a_configuration\n"); - return; - } - PcieReleasePortTraining(nb_dev, dev, hw_port); - if (!(AtiPcieCfg.Config & PCIE_GPP_COMPLIANCE)) { - u8 res = PcieTrainPort(nb_dev, dev, hw_port); - printk(BIOS_DEBUG, "%s: port=0x%x hw_port=0x%x result=%d\n", - __func__, port, hw_port, res); - if (res) { - AtiPcieCfg.PortDetect |= 1 << port; - } else { - /* Even though nothing is attached to this port - * the port needs to be "enabled" to obtain - * a bus number from the PCI resource allocator - */ - training_ok = 0; - dev->enabled = 1; - } - } - } - break; - case 8: /* SB */ - break; - default: - break; - } - - /* Re-enable RC ordering logic after training (from CIMx)*/ - set_pcie_enable_bits(nb_dev, 0x20 | gpp_sb_sel, 1 << 9, 0); - - /* Advertising Hot Plug Capabilities */ - pci_ext_write_config32(nb_dev, dev, 0x6c, 0x04001B, 0x00001B); - - /* PCIE Late Init (CIMx late init - Maybe move somewhere else? Later in the coreboot PCI device enum?) */ - /* Set Slot Number */ - pci_ext_write_config32(nb_dev, dev, 0x6c, 0x1FFF << 19, port << 19); - - /* Set Slot present 0x5A*/ - pci_ext_write_config32(nb_dev, dev, 0x58, 1 << 24, 1 << 24); - - //PCIE-GPP1 TXCLK Clock Gating In L1 Late Core setting - Maybe move somewhere else? */ - set_pcie_enable_bits(nb_dev, 0x11 | gpp_sb_sel, 0xF << 0, 0x0C << 0); - /* Enable powering down PLLs in L1 or L23 Ready states. - * Turns off PHY`s RX FRONTEND during L1 when PLL power down is enabled */ - set_pcie_enable_bits(nb_dev, 0x40 | gpp_sb_sel, 0x1219, 0x1009); - /* 4.4..7.1 TXCLK Gating in L1, Enables powering down TXCLK clock pads on the receive side. */ - set_pcie_enable_bits(nb_dev, 0x40 | gpp_sb_sel, 1 << 6, 1 << 6); - - /* Step 20: Disables immediate RCB timeout on link down */ - if (!((pci_read_config32(dev, 0x6C) >> 6) & 0x01)) { - set_pcie_enable_bits(dev, 0x70, 1 << 19, 0 << 19); - } - - /* Step 27: LCLK Gating */ - EnableLclkGating(dev); - - /* Set Common Clock */ - /* If dev present, set PcieCapPtr+0x10, BIT6); - * set dev 0x68,bit 6 - * retrain link, set dev, 0x68 bit 5; - * wait dev 0x6B bit3 clear - */ - - if ((port == 8) || (!training_ok)) { - PciePowerOffGppPorts(nb_dev, dev, port); /* This is run for all ports that are not hotplug and don't detect devices */ - } -} - -/** - * Step 21: Register Locking - * Lock HWInit Register of each pcie core - */ -static void lock_hwinitreg(struct device *nb_dev) -{ - /* Step 21: Register Locking, Lock HWInit Register */ - set_pcie_enable_bits(nb_dev, 0x10 | PCIE_CORE_INDEX_GPP1, 1 << 0, 1 << 0); - set_pcie_enable_bits(nb_dev, 0x10 | PCIE_CORE_INDEX_SB, 1 << 0, 1 << 0); - set_pcie_enable_bits(nb_dev, 0x10 | PCIE_CORE_INDEX_GPP2, 1 << 0, 1 << 0); - set_pcie_enable_bits(nb_dev, 0x10 | PCIE_CORE_INDEX_GPP3a, 1 << 0, 1 << 0); - set_pcie_enable_bits(nb_dev, 0x10 | PCIE_CORE_INDEX_GPP3b, 1 << 0, 1 << 0); -} - -/** - * Lock HWInit Register - */ -void sr56x0_lock_hwinitreg(void) -{ - struct device *nb_dev = pcidev_on_root(0, 0); - - /* Lock HWInit Register */ - lock_hwinitreg(nb_dev); - - /* Lock HWInit Register NBMISCIND:0x0 NBCNTL[7] HWINIT_WR_LOCK */ - set_nbmisc_enable_bits(nb_dev, 0x00, 1 << 7, 1 << 7); - - /* Hide clock configuration PCI device HIDE_CLKCFG_HEADER */ - set_nbmisc_enable_bits(nb_dev, 0x00, 0x00000100, 1 << 8); -} - -/***************************************** -* Compliant with CIM_33's PCIEConfigureGPPCore -*****************************************/ -void config_gpp_core(struct device *nb_dev, struct device *sb_dev) -{ - u32 reg; - - reg = nbmisc_read_index(nb_dev, 0x20); - if (AtiPcieCfg.Config & PCIE_ENABLE_STATIC_DEV_REMAP) - reg &= 0xfffffffd; /* set bit1 = 0 */ - else - reg |= 0x2; /* set bit1 = 1 */ - nbmisc_write_index(nb_dev, 0x20, reg); - - /* Must perform PCIE-GPP1, GPP2, GPP3a global reset anyway */ - reg = nbmisc_read_index(nb_dev, 0x8); - reg |= (1 << 31) | (1 << 15) | (1 << 13); //asserts - nbmisc_write_index(nb_dev, 0x8, reg); - reg &= ~((1 << 31) | (1 << 15) | (1 << 13)); //De-asserts - nbmisc_write_index(nb_dev, 0x8, reg); - - switching_gpp3a_configurations(nb_dev, sb_dev); - switching_gpp1_configurations(nb_dev, sb_dev); - switching_gpp2_configurations(nb_dev, sb_dev); - ValidatePortEn(nb_dev); -} - -/***************************************** -* Compliant with CIM_33's PCIEMiscClkProg -*****************************************/ -void pcie_config_misc_clk(struct device *nb_dev) -{ - u32 reg; - - reg = pci_read_config32(nb_dev, 0x4c); - reg |= 1 << 0; - pci_write_config32(nb_dev, 0x4c, reg); - -#if 0 - /* TODO: Check the mics clock later. */ - pci_devfn_t d0f1 = PCI_DEV(0, 0, 1); - - if (AtiPcieCfg.Config & PCIE_GFX_CLK_GATING) { - /* TXCLK Clock Gating */ - set_nbmisc_enable_bits(nb_dev, 0x07, 3 << 0, 3 << 0); - set_nbmisc_enable_bits(nb_dev, 0x07, 1 << 22, 1 << 22); - set_pcie_enable_bits(nb_dev, 0x11 | PCIE_CORE_INDEX_GFX, (3 << 6) | (~0xf), 3 << 6); - - /* LCLK Clock Gating */ - reg = pci_io_read_config32(d0f1, 0x94); - reg &= ~(1 << 16); - pci_io_write_config32(d0f1, 0x94, reg); - } - - if (AtiPcieCfg.Config & PCIE_GPP_CLK_GATING) { - /* TXCLK Clock Gating */ - set_nbmisc_enable_bits(nb_dev, 0x07, 3 << 4, 3 << 4); - set_nbmisc_enable_bits(nb_dev, 0x07, 1 << 22, 1 << 22); - set_pcie_enable_bits(nb_dev, 0x11 | PCIE_CORE_INDEX_SB, (3 << 6) | (~0xf), 3 << 6); - - /* LCLK Clock Gating */ - reg = pci_io_read_config32(d0f1, 0x94); - reg &= ~(1 << 24); - pci_io_write_config32(d0f1, 0x94, reg); - } -#endif - - reg = pci_read_config32(nb_dev, 0x4c); - reg &= ~(1 << 0); - pci_write_config32(nb_dev, 0x4c, reg); -} |