+static void
+cap_evendor(struct device *d, int where)
+{
+ u32 hdr;
+
+ printf("Vendor Specific Information: ");
+ if (!config_fetch(d, where + PCI_EVNDR_HEADER, 4))
+ {
+ printf("<unreadable>\n");
+ return;
+ }
+
+ hdr = get_conf_long(d, where + PCI_EVNDR_HEADER);
+ printf("ID=%04x Rev=%d Len=%03x <?>\n",
+ BITS(hdr, 0, 16),
+ BITS(hdr, 16, 4),
+ BITS(hdr, 20, 12));
+}
+
+static int l1pm_calc_pwron(int scale, int value)
+{
+ switch (scale)
+ {
+ case 0:
+ return 2 * value;
+ case 1:
+ return 10 * value;
+ case 2:
+ return 100 * value;
+ }
+ return -1;
+}
+
+static void
+cap_l1pm(struct device *d, int where)
+{
+ u32 l1_cap, val, scale;
+ int time;
+
+ printf("L1 PM Substates\n");
+
+ if (verbose < 2)
+ return;
+
+ if (!config_fetch(d, where + PCI_L1PM_SUBSTAT_CAP, 12))
+ {
+ printf("\t\t<unreadable>\n");
+ return;
+ }
+
+ l1_cap = get_conf_long(d, where + PCI_L1PM_SUBSTAT_CAP);
+ printf("\t\tL1SubCap: ");
+ printf("PCI-PM_L1.2%c PCI-PM_L1.1%c ASPM_L1.2%c ASPM_L1.1%c L1_PM_Substates%c\n",
+ FLAG(l1_cap, PCI_L1PM_SUBSTAT_CAP_PM_L12),
+ FLAG(l1_cap, PCI_L1PM_SUBSTAT_CAP_PM_L11),
+ FLAG(l1_cap, PCI_L1PM_SUBSTAT_CAP_ASPM_L12),
+ FLAG(l1_cap, PCI_L1PM_SUBSTAT_CAP_ASPM_L11),
+ FLAG(l1_cap, PCI_L1PM_SUBSTAT_CAP_L1PM_SUPP));
+
+ if (l1_cap & PCI_L1PM_SUBSTAT_CAP_PM_L12 || l1_cap & PCI_L1PM_SUBSTAT_CAP_ASPM_L12)
+ {
+ printf("\t\t\t PortCommonModeRestoreTime=%dus ", BITS(l1_cap, 8, 8));
+ time = l1pm_calc_pwron(BITS(l1_cap, 16, 2), BITS(l1_cap, 19, 5));
+ if (time != -1)
+ printf("PortTPowerOnTime=%dus\n", time);
+ else
+ printf("PortTPowerOnTime=<error>\n");
+ }
+
+ val = get_conf_long(d, where + PCI_L1PM_SUBSTAT_CTL1);
+ printf("\t\tL1SubCtl1: PCI-PM_L1.2%c PCI-PM_L1.1%c ASPM_L1.2%c ASPM_L1.1%c\n",
+ FLAG(val, PCI_L1PM_SUBSTAT_CTL1_PM_L12),
+ FLAG(val, PCI_L1PM_SUBSTAT_CTL1_PM_L11),
+ FLAG(val, PCI_L1PM_SUBSTAT_CTL1_ASPM_L12),
+ FLAG(val, PCI_L1PM_SUBSTAT_CTL1_ASPM_L11));
+
+ if (l1_cap & PCI_L1PM_SUBSTAT_CAP_PM_L12 || l1_cap & PCI_L1PM_SUBSTAT_CAP_ASPM_L12)
+ printf("\t\t\t T_CommonMode=%dus", BITS(val, 8, 8));
+
+ if (l1_cap & PCI_L1PM_SUBSTAT_CAP_ASPM_L12)
+ {
+ scale = BITS(val, 29, 3);
+ if (scale > 5)
+ printf(" LTR1.2_Threshold=<error>");
+ else
+ printf(" LTR1.2_Threshold=%lldns", BITS(val, 16, 10) * (unsigned long long) cap_ltr_scale(scale));
+ }
+ printf("\n");
+
+ val = get_conf_long(d, where + PCI_L1PM_SUBSTAT_CTL2);
+ printf("\t\tL1SubCtl2:");
+ if (l1_cap & PCI_L1PM_SUBSTAT_CAP_PM_L12 || l1_cap & PCI_L1PM_SUBSTAT_CAP_ASPM_L12)
+ {
+ time = l1pm_calc_pwron(BITS(val, 0, 2), BITS(val, 3, 5));
+ if (time != -1)
+ printf(" T_PwrOn=%dus", time);
+ else
+ printf(" T_PwrOn=<error>");
+ }
+ printf("\n");
+}
+
+static void
+cap_ptm(struct device *d, int where)
+{
+ u32 buff;
+ u16 clock;
+
+ printf("Precision Time Measurement\n");
+
+ if (verbose < 2)
+ return;
+
+ if (!config_fetch(d, where + 4, 8))
+ {
+ printf("\t\t<unreadable>\n");
+ return;
+ }
+
+ buff = get_conf_long(d, where + 4);
+ printf("\t\tPTMCap: ");
+ printf("Requester:%c Responder:%c Root:%c\n",
+ FLAG(buff, 0x1),
+ FLAG(buff, 0x2),
+ FLAG(buff, 0x4));
+
+ clock = BITS(buff, 8, 8);
+ printf("\t\tPTMClockGranularity: ");
+ switch (clock)
+ {
+ case 0x00:
+ printf("Unimplemented\n");
+ break;
+ case 0xff:
+ printf("Greater than 254ns\n");
+ break;
+ default:
+ printf("%huns\n", clock);
+ }
+
+ buff = get_conf_long(d, where + 8);
+ printf("\t\tPTMControl: ");
+ printf("Enabled:%c RootSelected:%c\n",
+ FLAG(buff, 0x1),
+ FLAG(buff, 0x2));
+
+ clock = BITS(buff, 8, 8);
+ printf("\t\tPTMEffectiveGranularity: ");
+ switch (clock)
+ {
+ case 0x00:
+ printf("Unknown\n");
+ break;
+ case 0xff:
+ printf("Greater than 254ns\n");
+ break;
+ default:
+ printf("%huns\n", clock);
+ }
+}
+