===================================================================
@@ -208,6 +208,7 @@
void config_gpp_core(device_t nb_dev, device_t sb_dev);
void PcieReleasePortTraining(device_t nb_dev, device_t dev, u32 port);
u8 PcieTrainPort(device_t nb_dev, device_t dev, u32 port);
+void init_gen2(device_t nb_dev, device_t dev, u8 port);
u32 extractbit(u32 data, int bit_number);
u32 extractbits(u32 source, int lsb, int msb);
int cpuidFamily(void);
===================================================================
@@ -225,6 +225,64 @@
ProgK8TempMmioBase(0, EXT_CONF_BASE_ADDRESS, TEMP_MMIO_BASE_ADDRESS);
}
+/*
+ * GEN2 Software Compliance
+ */
+void init_gen2(device_t nb_dev, device_t 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);
+}
+
/*****************************************
* Compliant with CIM_33's PCIEGPPInit
* nb_dev:
@@ -334,6 +392,12 @@
/* step 5: dynamic slave CPL buffer allocation. Disable it, otherwise linux hangs. Why? */
/* set_pcie_enable_bits(nb_dev, 0x20 | gfx_gpp_sb_sel, 1 << 11, 1 << 11); */
+ /* 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);
+
/* step 5a: Training for GPP devices */
/* init GPP */
switch (port) {
===================================================================
@@ -259,6 +259,7 @@
{
u16 count = 5000;
u32 lc_state, reg, current_link_width, lane_mask;
+ u32 lc_speed;
int8_t current, res = 0;
u32 gfx_gpp_sb_sel;
void set_pcie_dereset(void);
@@ -347,6 +348,25 @@
break;
}
}
+
+ lc_speed = nbpcie_p_read_index(dev, 0xA4); /* lc_speed_cntl */
+ printk(BIOS_DEBUG, "port=%x: lc_speed_cntl=%x\n", port, lc_speed);
+ if (lc_speed & (1 << 27)) {
+ printk(BIOS_DEBUG, "Gen2 support advertised, ");
+ } else {
+ printk(BIOS_DEBUG, "Only Gen1 support advertised, ");
+ }
+ if (lc_speed & (1 << 24)) {
+ printk(BIOS_DEBUG, "Device currently support Gen2\n");
+ } else {
+ printk(BIOS_DEBUG, "Device currently not support Gen2\n");
+ }
+ if (lc_speed & (1 << 11)) {
+ printk(BIOS_DEBUG, "Current Data Rate is Gen2\n");
+ } else {
+ printk(BIOS_DEBUG, "Current Data Rate is Gen1\n");
+ }
+
return res;
}