/***************************************** * Compliant with CIM_33's PCIEConfigureGPPCore *****************************************/ void config_gpp_core(device_t nb_dev, device_t sb_dev) { u32 reg; struct southbridge_amd_sr5650_config *cfg = (struct southbridge_amd_sr5650_config *)nb_dev->chip_info; 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-aserts nbmisc_write_index(nb_dev, 0x8, reg); reg = nbmisc_read_index(nb_dev, 0x67); /* get STRAP_BIF_LINK_CONFIG at bit 0-4 */ if (cfg->gpp3a_configuration != (reg & 0x1F)) switching_gpp3a_configurations(nb_dev, sb_dev); reg = nbmisc_read_index(nb_dev, 0x8); /* get MULTIPORT_CONFIG_GPP1 MULTIPORT_CONFIG_CONFIG_GPP2 at bit 8,9 */ if ((cfg->gpp1_configuration << 8) != (reg & (1 << 8))) switching_gpp1_configurations(nb_dev, sb_dev); if ((cfg->gpp2_configuration << 9) != (reg & (1 << 9))) switching_gpp2_configurations(nb_dev, sb_dev); ValidatePortEn(nb_dev); }
/***************************************************************** * Compliant with CIM_33's PCIEPowerOffGppPorts * Power off unused GPP lines *****************************************************************/ static void PciePowerOffGppPorts(device_t nb_dev, device_t dev, u32 port) { u32 reg; u16 state_save; struct southbridge_amd_rs690_config *cfg = (struct southbridge_amd_rs690_config *)nb_dev->chip_info; u8 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; 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))) { } if (!cfg->gfx_tmds){ /* 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; } }
void set_nbmisc_enable_bits(device_t nb_dev, u32 reg_pos, u32 mask, u32 val) { u32 reg_old, reg; reg = reg_old = nbmisc_read_index(nb_dev, reg_pos); reg &= ~mask; reg |= val; if (reg != reg_old) { nbmisc_write_index(nb_dev, reg_pos, reg); } }
static void switching_gpp2_configurations(device_t nb_dev, device_t 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(device_t nb_dev, device_t 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 you 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); }