Merge remote-tracking branch 'anholt/modesetting-dri2-no-pageflip'

This commit is contained in:
Keith Packard 2014-10-27 14:48:55 -07:00
commit 59b12c454d
18 changed files with 2405 additions and 8 deletions

View File

@ -1410,6 +1410,59 @@ get_prime_id(void)
return -1;
}
#include "pci_ids/pci_id_driver_map.h"
static char *
dri2_probe_driver_name(ScreenPtr pScreen, DRI2InfoPtr info)
{
ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
EntityInfoPtr pEnt = xf86GetEntityInfo(pScrn->entityList[0]);
struct pci_device *pdev = NULL;
int i, j;
if (pEnt)
pdev = xf86GetPciInfoForEntity(pEnt->index);
/* For non-PCI devices, just assume that the 3D driver is named
* the same as the kernel driver. This is currently true for vc4
* and msm (freedreno).
*/
if (!pdev) {
drmVersionPtr version = drmGetVersion(info->fd);
char *kernel_driver;
if (!version) {
xf86DrvMsg(pScreen->myNum, X_ERROR,
"[DRI2] Couldn't drmGetVersion() on non-PCI device, "
"no driver name found.\n");
return NULL;
}
kernel_driver = strndup(version->name, version->name_len);
drmFreeVersion(version);
return kernel_driver;
}
for (i = 0; driver_map[i].driver; i++) {
if (pdev->vendor_id != driver_map[i].vendor_id)
continue;
if (driver_map[i].num_chips_ids == -1)
return strdup(driver_map[i].driver);
for (j = 0; j < driver_map[i].num_chips_ids; j++) {
if (driver_map[i].chip_ids[j] == pdev->device_id)
return strdup(driver_map[i].driver);
}
}
xf86DrvMsg(pScreen->myNum, X_ERROR,
"[DRI2] No driver mapping found for PCI device "
"0x%04x / 0x%04x\n",
pdev->vendor_id, pdev->device_id);
return NULL;
}
Bool
DRI2ScreenInit(ScreenPtr pScreen, DRI2InfoPtr info)
{
@ -1524,7 +1577,14 @@ DRI2ScreenInit(ScreenPtr pScreen, DRI2InfoPtr info)
ds->driverNames = malloc(sizeof(*ds->driverNames));
if (!ds->driverNames)
goto err_out;
ds->driverNames[0] = info->driverName;
if (info->driverName) {
ds->driverNames[0] = info->driverName;
} else {
ds->driverNames[0] = dri2_probe_driver_name(pScreen, info);
if (!ds->driverNames[0])
return FALSE;
}
}
else {
ds->numDrivers = info->numDrivers;

View File

@ -0,0 +1,4 @@
CHIPSET(0x7121, I810, i8xx)
CHIPSET(0x7123, I810_DC100, i8xx)
CHIPSET(0x7125, I810_E, i8xx)
CHIPSET(0x1132, I815, i8xx)

View File

@ -0,0 +1,15 @@
CHIPSET(0x3577, I830_M, "Intel(R) 830M")
CHIPSET(0x2562, 845_G, "Intel(R) 845G")
CHIPSET(0x3582, I855_GM, "Intel(R) 852GM/855GM")
CHIPSET(0x2572, I865_G, "Intel(R) 865G")
CHIPSET(0x2582, I915_G, "Intel(R) 915G")
CHIPSET(0x258A, E7221_G, "Intel(R) E7221G (i915)")
CHIPSET(0x2592, I915_GM, "Intel(R) 915GM")
CHIPSET(0x2772, I945_G, "Intel(R) 945G")
CHIPSET(0x27A2, I945_GM, "Intel(R) 945GM")
CHIPSET(0x27AE, I945_GME, "Intel(R) 945GME")
CHIPSET(0x29B2, Q35_G, "Intel(R) Q35")
CHIPSET(0x29C2, G33_G, "Intel(R) G33")
CHIPSET(0x29D2, Q33_G, "Intel(R) Q33")
CHIPSET(0xA011, IGD_GM, "Intel(R) IGD")
CHIPSET(0xA001, IGD_G, "Intel(R) IGD")

View File

@ -0,0 +1,115 @@
CHIPSET(0x29A2, i965, "Intel(R) 965G")
CHIPSET(0x2992, i965, "Intel(R) 965Q")
CHIPSET(0x2982, i965, "Intel(R) 965G")
CHIPSET(0x2972, i965, "Intel(R) 946GZ")
CHIPSET(0x2A02, i965, "Intel(R) 965GM")
CHIPSET(0x2A12, i965, "Intel(R) 965GME/GLE")
CHIPSET(0x2A42, g4x, "Mobile Intel® GM45 Express Chipset")
CHIPSET(0x2E02, g4x, "Intel(R) Integrated Graphics Device")
CHIPSET(0x2E12, g4x, "Intel(R) Q45/Q43")
CHIPSET(0x2E22, g4x, "Intel(R) G45/G43")
CHIPSET(0x2E32, g4x, "Intel(R) G41")
CHIPSET(0x2E42, g4x, "Intel(R) B43")
CHIPSET(0x2E92, g4x, "Intel(R) B43")
CHIPSET(0x0042, ilk, "Intel(R) Ironlake Desktop")
CHIPSET(0x0046, ilk, "Intel(R) Ironlake Mobile")
CHIPSET(0x0102, snb_gt1, "Intel(R) Sandybridge Desktop")
CHIPSET(0x0112, snb_gt2, "Intel(R) Sandybridge Desktop")
CHIPSET(0x0122, snb_gt2, "Intel(R) Sandybridge Desktop")
CHIPSET(0x0106, snb_gt1, "Intel(R) Sandybridge Mobile")
CHIPSET(0x0116, snb_gt2, "Intel(R) Sandybridge Mobile")
CHIPSET(0x0126, snb_gt2, "Intel(R) Sandybridge Mobile")
CHIPSET(0x010A, snb_gt1, "Intel(R) Sandybridge Server")
CHIPSET(0x0152, ivb_gt1, "Intel(R) Ivybridge Desktop")
CHIPSET(0x0162, ivb_gt2, "Intel(R) Ivybridge Desktop")
CHIPSET(0x0156, ivb_gt1, "Intel(R) Ivybridge Mobile")
CHIPSET(0x0166, ivb_gt2, "Intel(R) Ivybridge Mobile")
CHIPSET(0x015a, ivb_gt1, "Intel(R) Ivybridge Server")
CHIPSET(0x016a, ivb_gt2, "Intel(R) Ivybridge Server")
CHIPSET(0x0402, hsw_gt1, "Intel(R) Haswell Desktop")
CHIPSET(0x0412, hsw_gt2, "Intel(R) Haswell Desktop")
CHIPSET(0x0422, hsw_gt3, "Intel(R) Haswell Desktop")
CHIPSET(0x0406, hsw_gt1, "Intel(R) Haswell Mobile")
CHIPSET(0x0416, hsw_gt2, "Intel(R) Haswell Mobile")
CHIPSET(0x0426, hsw_gt3, "Intel(R) Haswell Mobile")
CHIPSET(0x040A, hsw_gt1, "Intel(R) Haswell Server")
CHIPSET(0x041A, hsw_gt2, "Intel(R) Haswell Server")
CHIPSET(0x042A, hsw_gt3, "Intel(R) Haswell Server")
CHIPSET(0x040B, hsw_gt1, "Intel(R) Haswell")
CHIPSET(0x041B, hsw_gt2, "Intel(R) Haswell")
CHIPSET(0x042B, hsw_gt3, "Intel(R) Haswell")
CHIPSET(0x040E, hsw_gt1, "Intel(R) Haswell")
CHIPSET(0x041E, hsw_gt2, "Intel(R) Haswell")
CHIPSET(0x042E, hsw_gt3, "Intel(R) Haswell")
CHIPSET(0x0C02, hsw_gt1, "Intel(R) Haswell Desktop")
CHIPSET(0x0C12, hsw_gt2, "Intel(R) Haswell Desktop")
CHIPSET(0x0C22, hsw_gt3, "Intel(R) Haswell Desktop")
CHIPSET(0x0C06, hsw_gt1, "Intel(R) Haswell Mobile")
CHIPSET(0x0C16, hsw_gt2, "Intel(R) Haswell Mobile")
CHIPSET(0x0C26, hsw_gt3, "Intel(R) Haswell Mobile")
CHIPSET(0x0C0A, hsw_gt1, "Intel(R) Haswell Server")
CHIPSET(0x0C1A, hsw_gt2, "Intel(R) Haswell Server")
CHIPSET(0x0C2A, hsw_gt3, "Intel(R) Haswell Server")
CHIPSET(0x0C0B, hsw_gt1, "Intel(R) Haswell")
CHIPSET(0x0C1B, hsw_gt2, "Intel(R) Haswell")
CHIPSET(0x0C2B, hsw_gt3, "Intel(R) Haswell")
CHIPSET(0x0C0E, hsw_gt1, "Intel(R) Haswell")
CHIPSET(0x0C1E, hsw_gt2, "Intel(R) Haswell")
CHIPSET(0x0C2E, hsw_gt3, "Intel(R) Haswell")
CHIPSET(0x0A02, hsw_gt1, "Intel(R) Haswell Desktop")
CHIPSET(0x0A12, hsw_gt2, "Intel(R) Haswell Desktop")
CHIPSET(0x0A22, hsw_gt3, "Intel(R) Haswell Desktop")
CHIPSET(0x0A06, hsw_gt1, "Intel(R) Haswell Mobile")
CHIPSET(0x0A16, hsw_gt2, "Intel(R) Haswell Mobile")
CHIPSET(0x0A26, hsw_gt3, "Intel(R) Haswell Mobile")
CHIPSET(0x0A0A, hsw_gt1, "Intel(R) Haswell Server")
CHIPSET(0x0A1A, hsw_gt2, "Intel(R) Haswell Server")
CHIPSET(0x0A2A, hsw_gt3, "Intel(R) Haswell Server")
CHIPSET(0x0A0B, hsw_gt1, "Intel(R) Haswell")
CHIPSET(0x0A1B, hsw_gt2, "Intel(R) Haswell")
CHIPSET(0x0A2B, hsw_gt3, "Intel(R) Haswell")
CHIPSET(0x0A0E, hsw_gt1, "Intel(R) Haswell")
CHIPSET(0x0A1E, hsw_gt2, "Intel(R) Haswell")
CHIPSET(0x0A2E, hsw_gt3, "Intel(R) Haswell")
CHIPSET(0x0D02, hsw_gt1, "Intel(R) Haswell Desktop")
CHIPSET(0x0D12, hsw_gt2, "Intel(R) Haswell Desktop")
CHIPSET(0x0D22, hsw_gt3, "Intel(R) Haswell Desktop")
CHIPSET(0x0D06, hsw_gt1, "Intel(R) Haswell Mobile")
CHIPSET(0x0D16, hsw_gt2, "Intel(R) Haswell Mobile")
CHIPSET(0x0D26, hsw_gt3, "Intel(R) Haswell Mobile")
CHIPSET(0x0D0A, hsw_gt1, "Intel(R) Haswell Server")
CHIPSET(0x0D1A, hsw_gt2, "Intel(R) Haswell Server")
CHIPSET(0x0D2A, hsw_gt3, "Intel(R) Haswell")
CHIPSET(0x0D0B, hsw_gt1, "Intel(R) Haswell")
CHIPSET(0x0D1B, hsw_gt2, "Intel(R) Haswell")
CHIPSET(0x0D2B, hsw_gt3, "Intel(R) Haswell")
CHIPSET(0x0D0E, hsw_gt1, "Intel(R) Haswell")
CHIPSET(0x0D1E, hsw_gt2, "Intel(R) Haswell")
CHIPSET(0x0D2E, hsw_gt3, "Intel(R) Haswell")
CHIPSET(0x0F31, byt, "Intel(R) Bay Trail")
CHIPSET(0x0F32, byt, "Intel(R) Bay Trail")
CHIPSET(0x0F33, byt, "Intel(R) Bay Trail")
CHIPSET(0x0157, byt, "Intel(R) Bay Trail")
CHIPSET(0x0155, byt, "Intel(R) Bay Trail")
CHIPSET(0x1602, bdw_gt1, "Intel(R) Broadwell GT1")
CHIPSET(0x1606, bdw_gt1, "Intel(R) Broadwell GT1")
CHIPSET(0x160A, bdw_gt1, "Intel(R) Broadwell GT1")
CHIPSET(0x160B, bdw_gt1, "Intel(R) Broadwell GT1")
CHIPSET(0x160D, bdw_gt1, "Intel(R) Broadwell GT1")
CHIPSET(0x160E, bdw_gt1, "Intel(R) Broadwell GT1")
CHIPSET(0x1612, bdw_gt2, "Intel(R) HD Graphics 5600 (Broadwell GT2)")
CHIPSET(0x1616, bdw_gt2, "Intel(R) HD Graphics 5500 (Broadwell GT2)")
CHIPSET(0x161A, bdw_gt2, "Intel(R) Broadwell GT2")
CHIPSET(0x161B, bdw_gt2, "Intel(R) Broadwell GT2")
CHIPSET(0x161D, bdw_gt2, "Intel(R) Broadwell GT2")
CHIPSET(0x161E, bdw_gt2, "Intel(R) HD Graphics 5300 (Broadwell GT2)")
CHIPSET(0x1622, bdw_gt3, "Intel(R) Iris Pro 6200 (Broadwell GT3e)")
CHIPSET(0x1626, bdw_gt3, "Intel(R) HD Graphics 6000 (Broadwell GT3)")
CHIPSET(0x162A, bdw_gt3, "Intel(R) Iris Pro P6300 (Broadwell GT3e)")
CHIPSET(0x162B, bdw_gt3, "Intel(R) Iris 6100 (Broadwell GT3)")
CHIPSET(0x162D, bdw_gt3, "Intel(R) Broadwell GT3")
CHIPSET(0x162E, bdw_gt3, "Intel(R) Broadwell GT3")
CHIPSET(0x22B0, chv, "Intel(R) Cherryview")
CHIPSET(0x22B1, chv, "Intel(R) Cherryview")
CHIPSET(0x22B2, chv, "Intel(R) Cherryview")
CHIPSET(0x22B3, chv, "Intel(R) Cherryview")

View File

@ -0,0 +1,80 @@
#ifndef _PCI_ID_DRIVER_MAP_H_
#define _PCI_ID_DRIVER_MAP_H_
#include <stddef.h>
#ifndef ARRAY_SIZE
#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
#endif
static const int i915_chip_ids[] = {
#define CHIPSET(chip, desc, name) chip,
#include "pci_ids/i915_pci_ids.h"
#undef CHIPSET
};
static const int i965_chip_ids[] = {
#define CHIPSET(chip, family, name) chip,
#include "pci_ids/i965_pci_ids.h"
#undef CHIPSET
};
#ifndef DRIVER_MAP_GALLIUM_ONLY
static const int r100_chip_ids[] = {
#define CHIPSET(chip, name, family) chip,
#include "pci_ids/radeon_pci_ids.h"
#undef CHIPSET
};
static const int r200_chip_ids[] = {
#define CHIPSET(chip, name, family) chip,
#include "pci_ids/r200_pci_ids.h"
#undef CHIPSET
};
#endif
static const int r300_chip_ids[] = {
#define CHIPSET(chip, name, family) chip,
#include "pci_ids/r300_pci_ids.h"
#undef CHIPSET
};
static const int r600_chip_ids[] = {
#define CHIPSET(chip, name, family) chip,
#include "pci_ids/r600_pci_ids.h"
#undef CHIPSET
};
static const int radeonsi_chip_ids[] = {
#define CHIPSET(chip, name, family) chip,
#include "pci_ids/radeonsi_pci_ids.h"
#undef CHIPSET
};
static const int vmwgfx_chip_ids[] = {
#define CHIPSET(chip, name, family) chip,
#include "pci_ids/vmwgfx_pci_ids.h"
#undef CHIPSET
};
static const struct {
int vendor_id;
const char *driver;
const int *chip_ids;
int num_chips_ids;
} driver_map[] = {
{ 0x8086, "i915", i915_chip_ids, ARRAY_SIZE(i915_chip_ids) },
{ 0x8086, "i965", i965_chip_ids, ARRAY_SIZE(i965_chip_ids) },
#ifndef DRIVER_MAP_GALLIUM_ONLY
{ 0x1002, "radeon", r100_chip_ids, ARRAY_SIZE(r100_chip_ids) },
{ 0x1002, "r200", r200_chip_ids, ARRAY_SIZE(r200_chip_ids) },
#endif
{ 0x1002, "r300", r300_chip_ids, ARRAY_SIZE(r300_chip_ids) },
{ 0x1002, "r600", r600_chip_ids, ARRAY_SIZE(r600_chip_ids) },
{ 0x1002, "radeonsi", radeonsi_chip_ids, ARRAY_SIZE(radeonsi_chip_ids) },
{ 0x10de, "nouveau", NULL, -1 },
{ 0x15ad, "vmwgfx", vmwgfx_chip_ids, ARRAY_SIZE(vmwgfx_chip_ids) },
{ 0x0000, NULL, NULL, 0 },
};
#endif /* _PCI_ID_DRIVER_MAP_H_ */

View File

@ -0,0 +1,24 @@
CHIPSET(0x5148, R200_QH, R200)
CHIPSET(0x514C, R200_QL, R200)
CHIPSET(0x514D, R200_QM, R200)
CHIPSET(0x4242, R200_BB, R200)
CHIPSET(0x4966, RV250_If, RV250)
CHIPSET(0x4967, RV250_Ig, RV250)
CHIPSET(0x4C64, RV250_Ld, RV250)
CHIPSET(0x4C66, RV250_Lf, RV250)
CHIPSET(0x4C67, RV250_Lg, RV250)
CHIPSET(0x4C6E, RV280_4C6E, RV280)
CHIPSET(0x5960, RV280_5960, RV280)
CHIPSET(0x5961, RV280_5961, RV280)
CHIPSET(0x5962, RV280_5962, RV280)
CHIPSET(0x5964, RV280_5964, RV280)
CHIPSET(0x5965, RV280_5965, RV280)
CHIPSET(0x5C61, RV280_5C61, RV280)
CHIPSET(0x5C63, RV280_5C63, RV280)
CHIPSET(0x5834, RS300_5834, RS300)
CHIPSET(0x5835, RS300_5835, RS300)
CHIPSET(0x7834, RS350_7834, RS300)
CHIPSET(0x7835, RS350_7835, RS300)

View File

@ -0,0 +1,227 @@
CHIPSET(0x4144, R300_AD, R300)
CHIPSET(0x4145, R300_AE, R300)
CHIPSET(0x4146, R300_AF, R300)
CHIPSET(0x4147, R300_AG, R300)
CHIPSET(0x4E44, R300_ND, R300)
CHIPSET(0x4E45, R300_NE, R300)
CHIPSET(0x4E46, R300_NF, R300)
CHIPSET(0x4E47, R300_NG, R300)
CHIPSET(0x4E48, R350_NH, R350)
CHIPSET(0x4E49, R350_NI, R350)
CHIPSET(0x4E4B, R350_NK, R350)
CHIPSET(0x4148, R350_AH, R350)
CHIPSET(0x4149, R350_AI, R350)
CHIPSET(0x414A, R350_AJ, R350)
CHIPSET(0x414B, R350_AK, R350)
CHIPSET(0x4E4A, R360_NJ, R350)
CHIPSET(0x4150, RV350_AP, RV350)
CHIPSET(0x4151, RV350_AQ, RV350)
CHIPSET(0x4152, RV350_AR, RV350)
CHIPSET(0x4153, RV350_AS, RV350)
CHIPSET(0x4154, RV350_AT, RV350)
CHIPSET(0x4155, RV350_AU, RV350)
CHIPSET(0x4156, RV350_AV, RV350)
CHIPSET(0x4E50, RV350_NP, RV350)
CHIPSET(0x4E51, RV350_NQ, RV350)
CHIPSET(0x4E52, RV350_NR, RV350)
CHIPSET(0x4E53, RV350_NS, RV350)
CHIPSET(0x4E54, RV350_NT, RV350)
CHIPSET(0x4E56, RV350_NV, RV350)
CHIPSET(0x5460, RV370_5460, RV370)
CHIPSET(0x5462, RV370_5462, RV370)
CHIPSET(0x5464, RV370_5464, RV370)
CHIPSET(0x5B60, RV370_5B60, RV370)
CHIPSET(0x5B62, RV370_5B62, RV370)
CHIPSET(0x5B63, RV370_5B63, RV370)
CHIPSET(0x5B64, RV370_5B64, RV370)
CHIPSET(0x5B65, RV370_5B65, RV370)
CHIPSET(0x3150, RV380_3150, RV380)
CHIPSET(0x3151, RV380_3151, RV380)
CHIPSET(0x3152, RV380_3152, RV380)
CHIPSET(0x3154, RV380_3154, RV380)
CHIPSET(0x3155, RV380_3155, RV380)
CHIPSET(0x3E50, RV380_3E50, RV380)
CHIPSET(0x3E54, RV380_3E54, RV380)
CHIPSET(0x4A48, R420_JH, R420)
CHIPSET(0x4A49, R420_JI, R420)
CHIPSET(0x4A4A, R420_JJ, R420)
CHIPSET(0x4A4B, R420_JK, R420)
CHIPSET(0x4A4C, R420_JL, R420)
CHIPSET(0x4A4D, R420_JM, R420)
CHIPSET(0x4A4E, R420_JN, R420)
CHIPSET(0x4A4F, R420_JO, R420)
CHIPSET(0x4A50, R420_JP, R420)
CHIPSET(0x4A54, R420_JT, R420)
CHIPSET(0x5548, R423_UH, R423)
CHIPSET(0x5549, R423_UI, R423)
CHIPSET(0x554A, R423_UJ, R423)
CHIPSET(0x554B, R423_UK, R423)
CHIPSET(0x5550, R423_5550, R423)
CHIPSET(0x5551, R423_UQ, R423)
CHIPSET(0x5552, R423_UR, R423)
CHIPSET(0x5554, R423_UT, R423)
CHIPSET(0x5D57, R423_5D57, R423)
CHIPSET(0x554C, R430_554C, R430)
CHIPSET(0x554D, R430_554D, R430)
CHIPSET(0x554E, R430_554E, R430)
CHIPSET(0x554F, R430_554F, R430)
CHIPSET(0x5D48, R430_5D48, R430)
CHIPSET(0x5D49, R430_5D49, R430)
CHIPSET(0x5D4A, R430_5D4A, R430)
CHIPSET(0x5D4C, R480_5D4C, R480)
CHIPSET(0x5D4D, R480_5D4D, R480)
CHIPSET(0x5D4E, R480_5D4E, R480)
CHIPSET(0x5D4F, R480_5D4F, R480)
CHIPSET(0x5D50, R480_5D50, R480)
CHIPSET(0x5D52, R480_5D52, R480)
CHIPSET(0x4B48, R481_4B48, R481)
CHIPSET(0x4B49, R481_4B49, R481)
CHIPSET(0x4B4A, R481_4B4A, R481)
CHIPSET(0x4B4B, R481_4B4B, R481)
CHIPSET(0x4B4C, R481_4B4C, R481)
CHIPSET(0x564A, RV410_564A, RV410)
CHIPSET(0x564B, RV410_564B, RV410)
CHIPSET(0x564F, RV410_564F, RV410)
CHIPSET(0x5652, RV410_5652, RV410)
CHIPSET(0x5653, RV410_5653, RV410)
CHIPSET(0x5657, RV410_5657, RV410)
CHIPSET(0x5E48, RV410_5E48, RV410)
CHIPSET(0x5E4A, RV410_5E4A, RV410)
CHIPSET(0x5E4B, RV410_5E4B, RV410)
CHIPSET(0x5E4C, RV410_5E4C, RV410)
CHIPSET(0x5E4D, RV410_5E4D, RV410)
CHIPSET(0x5E4F, RV410_5E4F, RV410)
CHIPSET(0x5A41, RS400_5A41, RS400)
CHIPSET(0x5A42, RS400_5A42, RS400)
CHIPSET(0x5A61, RC410_5A61, RC410)
CHIPSET(0x5A62, RC410_5A62, RC410)
CHIPSET(0x5954, RS480_5954, RS480)
CHIPSET(0x5955, RS480_5955, RS480)
CHIPSET(0x5974, RS482_5974, RS480)
CHIPSET(0x5975, RS482_5975, RS480)
CHIPSET(0x7100, R520_7100, R520)
CHIPSET(0x7101, R520_7101, R520)
CHIPSET(0x7102, R520_7102, R520)
CHIPSET(0x7103, R520_7103, R520)
CHIPSET(0x7104, R520_7104, R520)
CHIPSET(0x7105, R520_7105, R520)
CHIPSET(0x7106, R520_7106, R520)
CHIPSET(0x7108, R520_7108, R520)
CHIPSET(0x7109, R520_7109, R520)
CHIPSET(0x710A, R520_710A, R520)
CHIPSET(0x710B, R520_710B, R520)
CHIPSET(0x710C, R520_710C, R520)
CHIPSET(0x710E, R520_710E, R520)
CHIPSET(0x710F, R520_710F, R520)
CHIPSET(0x7140, RV515_7140, RV515)
CHIPSET(0x7141, RV515_7141, RV515)
CHIPSET(0x7142, RV515_7142, RV515)
CHIPSET(0x7143, RV515_7143, RV515)
CHIPSET(0x7144, RV515_7144, RV515)
CHIPSET(0x7145, RV515_7145, RV515)
CHIPSET(0x7146, RV515_7146, RV515)
CHIPSET(0x7147, RV515_7147, RV515)
CHIPSET(0x7149, RV515_7149, RV515)
CHIPSET(0x714A, RV515_714A, RV515)
CHIPSET(0x714B, RV515_714B, RV515)
CHIPSET(0x714C, RV515_714C, RV515)
CHIPSET(0x714D, RV515_714D, RV515)
CHIPSET(0x714E, RV515_714E, RV515)
CHIPSET(0x714F, RV515_714F, RV515)
CHIPSET(0x7151, RV515_7151, RV515)
CHIPSET(0x7152, RV515_7152, RV515)
CHIPSET(0x7153, RV515_7153, RV515)
CHIPSET(0x715E, RV515_715E, RV515)
CHIPSET(0x715F, RV515_715F, RV515)
CHIPSET(0x7180, RV515_7180, RV515)
CHIPSET(0x7181, RV515_7181, RV515)
CHIPSET(0x7183, RV515_7183, RV515)
CHIPSET(0x7186, RV515_7186, RV515)
CHIPSET(0x7187, RV515_7187, RV515)
CHIPSET(0x7188, RV515_7188, RV515)
CHIPSET(0x718A, RV515_718A, RV515)
CHIPSET(0x718B, RV515_718B, RV515)
CHIPSET(0x718C, RV515_718C, RV515)
CHIPSET(0x718D, RV515_718D, RV515)
CHIPSET(0x718F, RV515_718F, RV515)
CHIPSET(0x7193, RV515_7193, RV515)
CHIPSET(0x7196, RV515_7196, RV515)
CHIPSET(0x719B, RV515_719B, RV515)
CHIPSET(0x719F, RV515_719F, RV515)
CHIPSET(0x7200, RV515_7200, RV515)
CHIPSET(0x7210, RV515_7210, RV515)
CHIPSET(0x7211, RV515_7211, RV515)
CHIPSET(0x71C0, RV530_71C0, RV530)
CHIPSET(0x71C1, RV530_71C1, RV530)
CHIPSET(0x71C2, RV530_71C2, RV530)
CHIPSET(0x71C3, RV530_71C3, RV530)
CHIPSET(0x71C4, RV530_71C4, RV530)
CHIPSET(0x71C5, RV530_71C5, RV530)
CHIPSET(0x71C6, RV530_71C6, RV530)
CHIPSET(0x71C7, RV530_71C7, RV530)
CHIPSET(0x71CD, RV530_71CD, RV530)
CHIPSET(0x71CE, RV530_71CE, RV530)
CHIPSET(0x71D2, RV530_71D2, RV530)
CHIPSET(0x71D4, RV530_71D4, RV530)
CHIPSET(0x71D5, RV530_71D5, RV530)
CHIPSET(0x71D6, RV530_71D6, RV530)
CHIPSET(0x71DA, RV530_71DA, RV530)
CHIPSET(0x71DE, RV530_71DE, RV530)
CHIPSET(0x7281, RV560_7281, RV560)
CHIPSET(0x7283, RV560_7283, RV560)
CHIPSET(0x7287, RV560_7287, RV560)
CHIPSET(0x7290, RV560_7290, RV560)
CHIPSET(0x7291, RV560_7291, RV560)
CHIPSET(0x7293, RV560_7293, RV560)
CHIPSET(0x7297, RV560_7297, RV560)
CHIPSET(0x7280, RV570_7280, RV570)
CHIPSET(0x7288, RV570_7288, RV570)
CHIPSET(0x7289, RV570_7289, RV570)
CHIPSET(0x728B, RV570_728B, RV570)
CHIPSET(0x728C, RV570_728C, RV570)
CHIPSET(0x7240, R580_7240, R580)
CHIPSET(0x7243, R580_7243, R580)
CHIPSET(0x7244, R580_7244, R580)
CHIPSET(0x7245, R580_7245, R580)
CHIPSET(0x7246, R580_7246, R580)
CHIPSET(0x7247, R580_7247, R580)
CHIPSET(0x7248, R580_7248, R580)
CHIPSET(0x7249, R580_7249, R580)
CHIPSET(0x724A, R580_724A, R580)
CHIPSET(0x724B, R580_724B, R580)
CHIPSET(0x724C, R580_724C, R580)
CHIPSET(0x724D, R580_724D, R580)
CHIPSET(0x724E, R580_724E, R580)
CHIPSET(0x724F, R580_724F, R580)
CHIPSET(0x7284, R580_7284, R580)
CHIPSET(0x793F, RS600_793F, RS600)
CHIPSET(0x7941, RS600_7941, RS600)
CHIPSET(0x7942, RS600_7942, RS600)
CHIPSET(0x791E, RS690_791E, RS690)
CHIPSET(0x791F, RS690_791F, RS690)
CHIPSET(0x796C, RS740_796C, RS740)
CHIPSET(0x796D, RS740_796D, RS740)
CHIPSET(0x796E, RS740_796E, RS740)
CHIPSET(0x796F, RS740_796F, RS740)

View File

@ -0,0 +1,327 @@
CHIPSET(0x9400, R600_9400, R600)
CHIPSET(0x9401, R600_9401, R600)
CHIPSET(0x9402, R600_9402, R600)
CHIPSET(0x9403, R600_9403, R600)
CHIPSET(0x9405, R600_9405, R600)
CHIPSET(0x940A, R600_940A, R600)
CHIPSET(0x940B, R600_940B, R600)
CHIPSET(0x940F, R600_940F, R600)
CHIPSET(0x94C0, RV610_94C0, RV610)
CHIPSET(0x94C1, RV610_94C1, RV610)
CHIPSET(0x94C3, RV610_94C3, RV610)
CHIPSET(0x94C4, RV610_94C4, RV610)
CHIPSET(0x94C5, RV610_94C5, RV610)
CHIPSET(0x94C6, RV610_94C6, RV610)
CHIPSET(0x94C7, RV610_94C7, RV610)
CHIPSET(0x94C8, RV610_94C8, RV610)
CHIPSET(0x94C9, RV610_94C9, RV610)
CHIPSET(0x94CB, RV610_94CB, RV610)
CHIPSET(0x94CC, RV610_94CC, RV610)
CHIPSET(0x94CD, RV610_94CD, RV610)
CHIPSET(0x9580, RV630_9580, RV630)
CHIPSET(0x9581, RV630_9581, RV630)
CHIPSET(0x9583, RV630_9583, RV630)
CHIPSET(0x9586, RV630_9586, RV630)
CHIPSET(0x9587, RV630_9587, RV630)
CHIPSET(0x9588, RV630_9588, RV630)
CHIPSET(0x9589, RV630_9589, RV630)
CHIPSET(0x958A, RV630_958A, RV630)
CHIPSET(0x958B, RV630_958B, RV630)
CHIPSET(0x958C, RV630_958C, RV630)
CHIPSET(0x958D, RV630_958D, RV630)
CHIPSET(0x958E, RV630_958E, RV630)
CHIPSET(0x958F, RV630_958F, RV630)
CHIPSET(0x9500, RV670_9500, RV670)
CHIPSET(0x9501, RV670_9501, RV670)
CHIPSET(0x9504, RV670_9504, RV670)
CHIPSET(0x9505, RV670_9505, RV670)
CHIPSET(0x9506, RV670_9506, RV670)
CHIPSET(0x9507, RV670_9507, RV670)
CHIPSET(0x9508, RV670_9508, RV670)
CHIPSET(0x9509, RV670_9509, RV670)
CHIPSET(0x950F, RV670_950F, RV670)
CHIPSET(0x9511, RV670_9511, RV670)
CHIPSET(0x9515, RV670_9515, RV670)
CHIPSET(0x9517, RV670_9517, RV670)
CHIPSET(0x9519, RV670_9519, RV670)
CHIPSET(0x95C0, RV620_95C0, RV620)
CHIPSET(0x95C2, RV620_95C2, RV620)
CHIPSET(0x95C4, RV620_95C4, RV620)
CHIPSET(0x95C5, RV620_95C5, RV620)
CHIPSET(0x95C6, RV620_95C6, RV620)
CHIPSET(0x95C7, RV620_95C7, RV620)
CHIPSET(0x95C9, RV620_95C9, RV620)
CHIPSET(0x95CC, RV620_95CC, RV620)
CHIPSET(0x95CD, RV620_95CD, RV620)
CHIPSET(0x95CE, RV620_95CE, RV620)
CHIPSET(0x95CF, RV620_95CF, RV620)
CHIPSET(0x9590, RV635_9590, RV635)
CHIPSET(0x9591, RV635_9591, RV635)
CHIPSET(0x9593, RV635_9593, RV635)
CHIPSET(0x9595, RV635_9595, RV635)
CHIPSET(0x9596, RV635_9596, RV635)
CHIPSET(0x9597, RV635_9597, RV635)
CHIPSET(0x9598, RV635_9598, RV635)
CHIPSET(0x9599, RV635_9599, RV635)
CHIPSET(0x959B, RV635_959B, RV635)
CHIPSET(0x9610, RS780_9610, RS780)
CHIPSET(0x9611, RS780_9611, RS780)
CHIPSET(0x9612, RS780_9612, RS780)
CHIPSET(0x9613, RS780_9613, RS780)
CHIPSET(0x9614, RS780_9614, RS780)
CHIPSET(0x9615, RS780_9615, RS780)
CHIPSET(0x9616, RS780_9616, RS780)
CHIPSET(0x9710, RS880_9710, RS880)
CHIPSET(0x9711, RS880_9711, RS880)
CHIPSET(0x9712, RS880_9712, RS880)
CHIPSET(0x9713, RS880_9713, RS880)
CHIPSET(0x9714, RS880_9714, RS880)
CHIPSET(0x9715, RS880_9715, RS880)
CHIPSET(0x9440, RV770_9440, RV770)
CHIPSET(0x9441, RV770_9441, RV770)
CHIPSET(0x9442, RV770_9442, RV770)
CHIPSET(0x9443, RV770_9443, RV770)
CHIPSET(0x9444, RV770_9444, RV770)
CHIPSET(0x9446, RV770_9446, RV770)
CHIPSET(0x944A, RV770_944A, RV770)
CHIPSET(0x944B, RV770_944B, RV770)
CHIPSET(0x944C, RV770_944C, RV770)
CHIPSET(0x944E, RV770_944E, RV770)
CHIPSET(0x9450, RV770_9450, RV770)
CHIPSET(0x9452, RV770_9452, RV770)
CHIPSET(0x9456, RV770_9456, RV770)
CHIPSET(0x945A, RV770_945A, RV770)
CHIPSET(0x945B, RV770_945B, RV770)
CHIPSET(0x945E, RV770_945E, RV770)
CHIPSET(0x9460, RV790_9460, RV770)
CHIPSET(0x9462, RV790_9462, RV770)
CHIPSET(0x946A, RV770_946A, RV770)
CHIPSET(0x946B, RV770_946B, RV770)
CHIPSET(0x947A, RV770_947A, RV770)
CHIPSET(0x947B, RV770_947B, RV770)
CHIPSET(0x9480, RV730_9480, RV730)
CHIPSET(0x9487, RV730_9487, RV730)
CHIPSET(0x9488, RV730_9488, RV730)
CHIPSET(0x9489, RV730_9489, RV730)
CHIPSET(0x948A, RV730_948A, RV730)
CHIPSET(0x948F, RV730_948F, RV730)
CHIPSET(0x9490, RV730_9490, RV730)
CHIPSET(0x9491, RV730_9491, RV730)
CHIPSET(0x9495, RV730_9495, RV730)
CHIPSET(0x9498, RV730_9498, RV730)
CHIPSET(0x949C, RV730_949C, RV730)
CHIPSET(0x949E, RV730_949E, RV730)
CHIPSET(0x949F, RV730_949F, RV730)
CHIPSET(0x9540, RV710_9540, RV710)
CHIPSET(0x9541, RV710_9541, RV710)
CHIPSET(0x9542, RV710_9542, RV710)
CHIPSET(0x954E, RV710_954E, RV710)
CHIPSET(0x954F, RV710_954F, RV710)
CHIPSET(0x9552, RV710_9552, RV710)
CHIPSET(0x9553, RV710_9553, RV710)
CHIPSET(0x9555, RV710_9555, RV710)
CHIPSET(0x9557, RV710_9557, RV710)
CHIPSET(0x955F, RV710_955F, RV710)
CHIPSET(0x94A0, RV740_94A0, RV740)
CHIPSET(0x94A1, RV740_94A1, RV740)
CHIPSET(0x94A3, RV740_94A3, RV740)
CHIPSET(0x94B1, RV740_94B1, RV740)
CHIPSET(0x94B3, RV740_94B3, RV740)
CHIPSET(0x94B4, RV740_94B4, RV740)
CHIPSET(0x94B5, RV740_94B5, RV740)
CHIPSET(0x94B9, RV740_94B9, RV740)
CHIPSET(0x68E0, CEDAR_68E0, CEDAR)
CHIPSET(0x68E1, CEDAR_68E1, CEDAR)
CHIPSET(0x68E4, CEDAR_68E4, CEDAR)
CHIPSET(0x68E5, CEDAR_68E5, CEDAR)
CHIPSET(0x68E8, CEDAR_68E8, CEDAR)
CHIPSET(0x68E9, CEDAR_68E9, CEDAR)
CHIPSET(0x68F1, CEDAR_68F1, CEDAR)
CHIPSET(0x68F2, CEDAR_68F2, CEDAR)
CHIPSET(0x68F8, CEDAR_68F8, CEDAR)
CHIPSET(0x68F9, CEDAR_68F9, CEDAR)
CHIPSET(0x68FA, CEDAR_68FA, CEDAR)
CHIPSET(0x68FE, CEDAR_68FE, CEDAR)
CHIPSET(0x68C0, REDWOOD_68C0, REDWOOD)
CHIPSET(0x68C1, REDWOOD_68C1, REDWOOD)
CHIPSET(0x68C7, REDWOOD_68C7, REDWOOD)
CHIPSET(0x68C8, REDWOOD_68C8, REDWOOD)
CHIPSET(0x68C9, REDWOOD_68C9, REDWOOD)
CHIPSET(0x68D8, REDWOOD_68D8, REDWOOD)
CHIPSET(0x68D9, REDWOOD_68D9, REDWOOD)
CHIPSET(0x68DA, REDWOOD_68DA, REDWOOD)
CHIPSET(0x68DE, REDWOOD_68DE, REDWOOD)
CHIPSET(0x68A0, JUNIPER_68A0, JUNIPER)
CHIPSET(0x68A1, JUNIPER_68A1, JUNIPER)
CHIPSET(0x68A8, JUNIPER_68A8, JUNIPER)
CHIPSET(0x68A9, JUNIPER_68A9, JUNIPER)
CHIPSET(0x68B0, JUNIPER_68B0, JUNIPER)
CHIPSET(0x68B8, JUNIPER_68B8, JUNIPER)
CHIPSET(0x68B9, JUNIPER_68B9, JUNIPER)
CHIPSET(0x68BA, JUNIPER_68BA, JUNIPER)
CHIPSET(0x68BE, JUNIPER_68BE, JUNIPER)
CHIPSET(0x68BF, JUNIPER_68BF, JUNIPER)
CHIPSET(0x6880, CYPRESS_6880, CYPRESS)
CHIPSET(0x6888, CYPRESS_6888, CYPRESS)
CHIPSET(0x6889, CYPRESS_6889, CYPRESS)
CHIPSET(0x688A, CYPRESS_688A, CYPRESS)
CHIPSET(0x688C, CYPRESS_688C, CYPRESS)
CHIPSET(0x688D, CYPRESS_688D, CYPRESS)
CHIPSET(0x6898, CYPRESS_6898, CYPRESS)
CHIPSET(0x6899, CYPRESS_6899, CYPRESS)
CHIPSET(0x689B, CYPRESS_689B, CYPRESS)
CHIPSET(0x689E, CYPRESS_689E, CYPRESS)
CHIPSET(0x689C, HEMLOCK_689C, HEMLOCK)
CHIPSET(0x689D, HEMLOCK_689D, HEMLOCK)
CHIPSET(0x9802, PALM_9802, PALM)
CHIPSET(0x9803, PALM_9803, PALM)
CHIPSET(0x9804, PALM_9804, PALM)
CHIPSET(0x9805, PALM_9805, PALM)
CHIPSET(0x9806, PALM_9806, PALM)
CHIPSET(0x9807, PALM_9807, PALM)
CHIPSET(0x9808, PALM_9808, PALM)
CHIPSET(0x9809, PALM_9809, PALM)
CHIPSET(0x980A, PALM_980A, PALM)
CHIPSET(0x9640, SUMO_9640, SUMO)
CHIPSET(0x9641, SUMO_9641, SUMO)
CHIPSET(0x9642, SUMO2_9642, SUMO2)
CHIPSET(0x9643, SUMO2_9643, SUMO2)
CHIPSET(0x9644, SUMO2_9644, SUMO2)
CHIPSET(0x9645, SUMO2_9645, SUMO2)
CHIPSET(0x9647, SUMO_9647, SUMO)
CHIPSET(0x9648, SUMO_9648, SUMO)
CHIPSET(0x9649, SUMO2_9649, SUMO2)
CHIPSET(0x964a, SUMO_964A, SUMO)
CHIPSET(0x964b, SUMO_964B, SUMO)
CHIPSET(0x964c, SUMO_964C, SUMO)
CHIPSET(0x964e, SUMO_964E, SUMO)
CHIPSET(0x964f, SUMO_964F, SUMO)
CHIPSET(0x6700, CAYMAN_6700, CAYMAN)
CHIPSET(0x6701, CAYMAN_6701, CAYMAN)
CHIPSET(0x6702, CAYMAN_6702, CAYMAN)
CHIPSET(0x6703, CAYMAN_6703, CAYMAN)
CHIPSET(0x6704, CAYMAN_6704, CAYMAN)
CHIPSET(0x6705, CAYMAN_6705, CAYMAN)
CHIPSET(0x6706, CAYMAN_6706, CAYMAN)
CHIPSET(0x6707, CAYMAN_6707, CAYMAN)
CHIPSET(0x6708, CAYMAN_6708, CAYMAN)
CHIPSET(0x6709, CAYMAN_6709, CAYMAN)
CHIPSET(0x6718, CAYMAN_6718, CAYMAN)
CHIPSET(0x6719, CAYMAN_6719, CAYMAN)
CHIPSET(0x671C, CAYMAN_671C, CAYMAN)
CHIPSET(0x671D, CAYMAN_671D, CAYMAN)
CHIPSET(0x671F, CAYMAN_671F, CAYMAN)
CHIPSET(0x6720, BARTS_6720, BARTS)
CHIPSET(0x6721, BARTS_6721, BARTS)
CHIPSET(0x6722, BARTS_6722, BARTS)
CHIPSET(0x6723, BARTS_6723, BARTS)
CHIPSET(0x6724, BARTS_6724, BARTS)
CHIPSET(0x6725, BARTS_6725, BARTS)
CHIPSET(0x6726, BARTS_6726, BARTS)
CHIPSET(0x6727, BARTS_6727, BARTS)
CHIPSET(0x6728, BARTS_6728, BARTS)
CHIPSET(0x6729, BARTS_6729, BARTS)
CHIPSET(0x6738, BARTS_6738, BARTS)
CHIPSET(0x6739, BARTS_6739, BARTS)
CHIPSET(0x673E, BARTS_673E, BARTS)
CHIPSET(0x6740, TURKS_6740, TURKS)
CHIPSET(0x6741, TURKS_6741, TURKS)
CHIPSET(0x6742, TURKS_6742, TURKS)
CHIPSET(0x6743, TURKS_6743, TURKS)
CHIPSET(0x6744, TURKS_6744, TURKS)
CHIPSET(0x6745, TURKS_6745, TURKS)
CHIPSET(0x6746, TURKS_6746, TURKS)
CHIPSET(0x6747, TURKS_6747, TURKS)
CHIPSET(0x6748, TURKS_6748, TURKS)
CHIPSET(0x6749, TURKS_6749, TURKS)
CHIPSET(0x674A, TURKS_674A, TURKS)
CHIPSET(0x6750, TURKS_6750, TURKS)
CHIPSET(0x6751, TURKS_6751, TURKS)
CHIPSET(0x6758, TURKS_6758, TURKS)
CHIPSET(0x6759, TURKS_6759, TURKS)
CHIPSET(0x675B, TURKS_675B, TURKS)
CHIPSET(0x675D, TURKS_675D, TURKS)
CHIPSET(0x675F, TURKS_675F, TURKS)
CHIPSET(0x6840, TURKS_6840, TURKS)
CHIPSET(0x6841, TURKS_6841, TURKS)
CHIPSET(0x6842, TURKS_6842, TURKS)
CHIPSET(0x6843, TURKS_6843, TURKS)
CHIPSET(0x6849, TURKS_6849, TURKS)
CHIPSET(0x6850, TURKS_6850, TURKS)
CHIPSET(0x6858, TURKS_6858, TURKS)
CHIPSET(0x6859, TURKS_6859, TURKS)
CHIPSET(0x6760, CAICOS_6760, CAICOS)
CHIPSET(0x6761, CAICOS_6761, CAICOS)
CHIPSET(0x6762, CAICOS_6762, CAICOS)
CHIPSET(0x6763, CAICOS_6763, CAICOS)
CHIPSET(0x6764, CAICOS_6764, CAICOS)
CHIPSET(0x6765, CAICOS_6765, CAICOS)
CHIPSET(0x6766, CAICOS_6766, CAICOS)
CHIPSET(0x6767, CAICOS_6767, CAICOS)
CHIPSET(0x6768, CAICOS_6768, CAICOS)
CHIPSET(0x6770, CAICOS_6770, CAICOS)
CHIPSET(0x6771, CAICOS_6771, CAICOS)
CHIPSET(0x6772, CAICOS_6772, CAICOS)
CHIPSET(0x6778, CAICOS_6778, CAICOS)
CHIPSET(0x6779, CAICOS_6779, CAICOS)
CHIPSET(0x677B, CAICOS_677B, CAICOS)
CHIPSET(0x9900, ARUBA_9900, ARUBA)
CHIPSET(0x9901, ARUBA_9901, ARUBA)
CHIPSET(0x9903, ARUBA_9903, ARUBA)
CHIPSET(0x9904, ARUBA_9904, ARUBA)
CHIPSET(0x9905, ARUBA_9905, ARUBA)
CHIPSET(0x9906, ARUBA_9906, ARUBA)
CHIPSET(0x9907, ARUBA_9907, ARUBA)
CHIPSET(0x9908, ARUBA_9908, ARUBA)
CHIPSET(0x9909, ARUBA_9909, ARUBA)
CHIPSET(0x990A, ARUBA_990A, ARUBA)
CHIPSET(0x990B, ARUBA_990B, ARUBA)
CHIPSET(0x990C, ARUBA_990C, ARUBA)
CHIPSET(0x990D, ARUBA_990D, ARUBA)
CHIPSET(0x990E, ARUBA_990E, ARUBA)
CHIPSET(0x990F, ARUBA_990F, ARUBA)
CHIPSET(0x9910, ARUBA_9910, ARUBA)
CHIPSET(0x9913, ARUBA_9913, ARUBA)
CHIPSET(0x9917, ARUBA_9917, ARUBA)
CHIPSET(0x9918, ARUBA_9918, ARUBA)
CHIPSET(0x9919, ARUBA_9919, ARUBA)
CHIPSET(0x9990, ARUBA_9990, ARUBA)
CHIPSET(0x9991, ARUBA_9991, ARUBA)
CHIPSET(0x9992, ARUBA_9992, ARUBA)
CHIPSET(0x9993, ARUBA_9993, ARUBA)
CHIPSET(0x9994, ARUBA_9994, ARUBA)
CHIPSET(0x9995, ARUBA_9995, ARUBA)
CHIPSET(0x9996, ARUBA_9996, ARUBA)
CHIPSET(0x9997, ARUBA_9997, ARUBA)
CHIPSET(0x9998, ARUBA_9998, ARUBA)
CHIPSET(0x9999, ARUBA_9999, ARUBA)
CHIPSET(0x999A, ARUBA_999A, ARUBA)
CHIPSET(0x999B, ARUBA_999B, ARUBA)
CHIPSET(0x999C, ARUBA_999C, ARUBA)
CHIPSET(0x999D, ARUBA_999D, ARUBA)
CHIPSET(0x99A0, ARUBA_99A0, ARUBA)
CHIPSET(0x99A2, ARUBA_99A2, ARUBA)
CHIPSET(0x99A4, ARUBA_99A4, ARUBA)

View File

@ -0,0 +1,23 @@
CHIPSET(0x4C57, RADEON_LW, RV200)
CHIPSET(0x4C58, RADEON_LX, RV200)
CHIPSET(0x4C59, RADEON_LY, RV100)
CHIPSET(0x4C5A, RADEON_LZ, RV100)
CHIPSET(0x5144, RADEON_QD, R100)
CHIPSET(0x5145, RADEON_QE, R100)
CHIPSET(0x5146, RADEON_QF, R100)
CHIPSET(0x5147, RADEON_QG, R100)
CHIPSET(0x5159, RADEON_QY, RV100)
CHIPSET(0x515A, RADEON_QZ, RV100)
CHIPSET(0x5157, RV200_QW, RV200)
CHIPSET(0x5158, RV200_QX, RV200)
CHIPSET(0x515E, RN50_515E, UNKNOWN)
CHIPSET(0x5969, RN50_5969, UNKNOWN)
CHIPSET(0x4136, RS100_4136, RS100)
CHIPSET(0x4336, RS100_4336, RS100)
CHIPSET(0x4137, RS200_4137, RS200)
CHIPSET(0x4337, RS200_4337, RS200)
CHIPSET(0x4237, RS250_4237, RS200)
CHIPSET(0x4437, RS250_4437, RS200)

View File

@ -0,0 +1,157 @@
CHIPSET(0x6780, TAHITI_6780, TAHITI)
CHIPSET(0x6784, TAHITI_6784, TAHITI)
CHIPSET(0x6788, TAHITI_6788, TAHITI)
CHIPSET(0x678A, TAHITI_678A, TAHITI)
CHIPSET(0x6790, TAHITI_6790, TAHITI)
CHIPSET(0x6791, TAHITI_6791, TAHITI)
CHIPSET(0x6792, TAHITI_6792, TAHITI)
CHIPSET(0x6798, TAHITI_6798, TAHITI)
CHIPSET(0x6799, TAHITI_6799, TAHITI)
CHIPSET(0x679A, TAHITI_679A, TAHITI)
CHIPSET(0x679B, TAHITI_679B, TAHITI)
CHIPSET(0x679E, TAHITI_679E, TAHITI)
CHIPSET(0x679F, TAHITI_679F, TAHITI)
CHIPSET(0x6800, PITCAIRN_6800, PITCAIRN)
CHIPSET(0x6801, PITCAIRN_6801, PITCAIRN)
CHIPSET(0x6802, PITCAIRN_6802, PITCAIRN)
CHIPSET(0x6806, PITCAIRN_6806, PITCAIRN)
CHIPSET(0x6808, PITCAIRN_6808, PITCAIRN)
CHIPSET(0x6809, PITCAIRN_6809, PITCAIRN)
CHIPSET(0x6810, PITCAIRN_6810, PITCAIRN)
CHIPSET(0x6811, PITCAIRN_6811, PITCAIRN)
CHIPSET(0x6816, PITCAIRN_6816, PITCAIRN)
CHIPSET(0x6817, PITCAIRN_6817, PITCAIRN)
CHIPSET(0x6818, PITCAIRN_6818, PITCAIRN)
CHIPSET(0x6819, PITCAIRN_6819, PITCAIRN)
CHIPSET(0x684C, PITCAIRN_684C, PITCAIRN)
CHIPSET(0x6820, VERDE_6820, VERDE)
CHIPSET(0x6821, VERDE_6821, VERDE)
CHIPSET(0x6822, VERDE_6822, VERDE)
CHIPSET(0x6823, VERDE_6823, VERDE)
CHIPSET(0x6824, VERDE_6824, VERDE)
CHIPSET(0x6825, VERDE_6825, VERDE)
CHIPSET(0x6826, VERDE_6826, VERDE)
CHIPSET(0x6827, VERDE_6827, VERDE)
CHIPSET(0x6828, VERDE_6828, VERDE)
CHIPSET(0x6829, VERDE_6829, VERDE)
CHIPSET(0x682A, VERDE_682A, VERDE)
CHIPSET(0x682B, VERDE_682B, VERDE)
CHIPSET(0x682C, VERDE_682C, VERDE)
CHIPSET(0x682D, VERDE_682D, VERDE)
CHIPSET(0x682F, VERDE_682F, VERDE)
CHIPSET(0x6830, VERDE_6830, VERDE)
CHIPSET(0x6831, VERDE_6831, VERDE)
CHIPSET(0x6835, VERDE_6835, VERDE)
CHIPSET(0x6837, VERDE_6837, VERDE)
CHIPSET(0x6838, VERDE_6838, VERDE)
CHIPSET(0x6839, VERDE_6839, VERDE)
CHIPSET(0x683B, VERDE_683B, VERDE)
CHIPSET(0x683D, VERDE_683D, VERDE)
CHIPSET(0x683F, VERDE_683F, VERDE)
CHIPSET(0x6600, OLAND_6600, OLAND)
CHIPSET(0x6601, OLAND_6601, OLAND)
CHIPSET(0x6602, OLAND_6602, OLAND)
CHIPSET(0x6603, OLAND_6603, OLAND)
CHIPSET(0x6604, OLAND_6604, OLAND)
CHIPSET(0x6605, OLAND_6605, OLAND)
CHIPSET(0x6606, OLAND_6606, OLAND)
CHIPSET(0x6607, OLAND_6607, OLAND)
CHIPSET(0x6608, OLAND_6608, OLAND)
CHIPSET(0x6610, OLAND_6610, OLAND)
CHIPSET(0x6611, OLAND_6611, OLAND)
CHIPSET(0x6613, OLAND_6613, OLAND)
CHIPSET(0x6620, OLAND_6620, OLAND)
CHIPSET(0x6621, OLAND_6621, OLAND)
CHIPSET(0x6623, OLAND_6623, OLAND)
CHIPSET(0x6631, OLAND_6631, OLAND)
CHIPSET(0x6660, HAINAN_6660, HAINAN)
CHIPSET(0x6663, HAINAN_6663, HAINAN)
CHIPSET(0x6664, HAINAN_6664, HAINAN)
CHIPSET(0x6665, HAINAN_6665, HAINAN)
CHIPSET(0x6667, HAINAN_6667, HAINAN)
CHIPSET(0x666F, HAINAN_666F, HAINAN)
CHIPSET(0x6640, BONAIRE_6640, BONAIRE)
CHIPSET(0x6641, BONAIRE_6641, BONAIRE)
CHIPSET(0x6646, BONAIRE_6646, BONAIRE)
CHIPSET(0x6647, BONAIRE_6647, BONAIRE)
CHIPSET(0x6649, BONAIRE_6649, BONAIRE)
CHIPSET(0x6650, BONAIRE_6650, BONAIRE)
CHIPSET(0x6651, BONAIRE_6651, BONAIRE)
CHIPSET(0x6658, BONAIRE_6658, BONAIRE)
CHIPSET(0x665C, BONAIRE_665C, BONAIRE)
CHIPSET(0x665D, BONAIRE_665D, BONAIRE)
CHIPSET(0x9830, KABINI_9830, KABINI)
CHIPSET(0x9831, KABINI_9831, KABINI)
CHIPSET(0x9832, KABINI_9832, KABINI)
CHIPSET(0x9833, KABINI_9833, KABINI)
CHIPSET(0x9834, KABINI_9834, KABINI)
CHIPSET(0x9835, KABINI_9835, KABINI)
CHIPSET(0x9836, KABINI_9836, KABINI)
CHIPSET(0x9837, KABINI_9837, KABINI)
CHIPSET(0x9838, KABINI_9838, KABINI)
CHIPSET(0x9839, KABINI_9839, KABINI)
CHIPSET(0x983A, KABINI_983A, KABINI)
CHIPSET(0x983B, KABINI_983B, KABINI)
CHIPSET(0x983C, KABINI_983C, KABINI)
CHIPSET(0x983D, KABINI_983D, KABINI)
CHIPSET(0x983E, KABINI_983E, KABINI)
CHIPSET(0x983F, KABINI_983F, KABINI)
CHIPSET(0x9850, MULLINS_9850, MULLINS)
CHIPSET(0x9851, MULLINS_9851, MULLINS)
CHIPSET(0x9852, MULLINS_9852, MULLINS)
CHIPSET(0x9853, MULLINS_9853, MULLINS)
CHIPSET(0x9854, MULLINS_9854, MULLINS)
CHIPSET(0x9855, MULLINS_9855, MULLINS)
CHIPSET(0x9856, MULLINS_9856, MULLINS)
CHIPSET(0x9857, MULLINS_9857, MULLINS)
CHIPSET(0x9858, MULLINS_9858, MULLINS)
CHIPSET(0x9859, MULLINS_9859, MULLINS)
CHIPSET(0x985A, MULLINS_985A, MULLINS)
CHIPSET(0x985B, MULLINS_985B, MULLINS)
CHIPSET(0x985C, MULLINS_985C, MULLINS)
CHIPSET(0x985D, MULLINS_985D, MULLINS)
CHIPSET(0x985E, MULLINS_985E, MULLINS)
CHIPSET(0x985F, MULLINS_985F, MULLINS)
CHIPSET(0x1304, KAVERI_1304, KAVERI)
CHIPSET(0x1305, KAVERI_1305, KAVERI)
CHIPSET(0x1306, KAVERI_1306, KAVERI)
CHIPSET(0x1307, KAVERI_1307, KAVERI)
CHIPSET(0x1309, KAVERI_1309, KAVERI)
CHIPSET(0x130A, KAVERI_130A, KAVERI)
CHIPSET(0x130B, KAVERI_130B, KAVERI)
CHIPSET(0x130C, KAVERI_130C, KAVERI)
CHIPSET(0x130D, KAVERI_130D, KAVERI)
CHIPSET(0x130E, KAVERI_130E, KAVERI)
CHIPSET(0x130F, KAVERI_130F, KAVERI)
CHIPSET(0x1310, KAVERI_1310, KAVERI)
CHIPSET(0x1311, KAVERI_1311, KAVERI)
CHIPSET(0x1312, KAVERI_1312, KAVERI)
CHIPSET(0x1313, KAVERI_1313, KAVERI)
CHIPSET(0x1315, KAVERI_1315, KAVERI)
CHIPSET(0x1316, KAVERI_1316, KAVERI)
CHIPSET(0x1317, KAVERI_1317, KAVERI)
CHIPSET(0x1318, KAVERI_1318, KAVERI)
CHIPSET(0x131B, KAVERI_131B, KAVERI)
CHIPSET(0x131C, KAVERI_131C, KAVERI)
CHIPSET(0x131D, KAVERI_131D, KAVERI)
CHIPSET(0x67A0, HAWAII_67A0, HAWAII)
CHIPSET(0x67A1, HAWAII_67A1, HAWAII)
CHIPSET(0x67A2, HAWAII_67A2, HAWAII)
CHIPSET(0x67A8, HAWAII_67A8, HAWAII)
CHIPSET(0x67A9, HAWAII_67A9, HAWAII)
CHIPSET(0x67AA, HAWAII_67AA, HAWAII)
CHIPSET(0x67B0, HAWAII_67B0, HAWAII)
CHIPSET(0x67B1, HAWAII_67B1, HAWAII)
CHIPSET(0x67B8, HAWAII_67B8, HAWAII)
CHIPSET(0x67B9, HAWAII_67B9, HAWAII)
CHIPSET(0x67BA, HAWAII_67BA, HAWAII)
CHIPSET(0x67BE, HAWAII_67BE, HAWAII)

View File

@ -0,0 +1 @@
CHIPSET(0x0405, SVGAII, SVGAII)

View File

@ -30,6 +30,7 @@ AM_CPPFLAGS = \
$(XORG_INCS) \
-I$(top_srcdir)/glamor \
-I$(srcdir)/../../ddc \
-I$(srcdir)/../../dri2 \
-I$(srcdir)/../../i2c \
-I$(srcdir)/../../modes \
-I$(srcdir)/../../parser \
@ -42,10 +43,13 @@ modesetting_drv_la_LIBADD = $(UDEV_LIBS) $(DRM_LIBS)
modesetting_drv_ladir = @moduledir@/drivers
modesetting_drv_la_SOURCES = \
dri2.c \
driver.c \
driver.h \
drmmode_display.c \
drmmode_display.h
drmmode_display.h \
vblank.c \
$(NULL)
drivermandir = $(DRIVER_MAN_DIR)
driverman_PRE = modesetting.man

View File

@ -0,0 +1,863 @@
/*
* Copyright © 2013 Intel Corporation
* Copyright © 2014 Broadcom
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*/
/**
* @file dri2.c
*
* Implements generic support for DRI2 on KMS, using glamor pixmaps
* for color buffer management (no support for other aux buffers), and
* the DRM vblank ioctls.
*
* This doesn't implement pageflipping yet.
*/
#ifdef HAVE_DIX_CONFIG_H
#include "dix-config.h"
#endif
#include <time.h>
#include "list.h"
#include "xf86.h"
#include "driver.h"
#include "dri2.h"
#ifdef GLAMOR
#define GLAMOR_FOR_XORG 1
#include "glamor.h"
enum ms_dri2_frame_event_type {
MS_DRI2_QUEUE_SWAP,
MS_DRI2_WAIT_MSC,
};
typedef struct ms_dri2_frame_event {
ScreenPtr screen;
DrawablePtr drawable;
ClientPtr client;
enum ms_dri2_frame_event_type type;
int frame;
xf86CrtcPtr crtc;
struct xorg_list drawable_resource, client_resource;
/* for swaps & flips only */
DRI2SwapEventPtr event_complete;
void *event_data;
DRI2BufferPtr front;
DRI2BufferPtr back;
} ms_dri2_frame_event_rec, *ms_dri2_frame_event_ptr;
typedef struct {
int refcnt;
PixmapPtr pixmap;
} ms_dri2_buffer_private_rec, *ms_dri2_buffer_private_ptr;
static DevPrivateKeyRec ms_dri2_client_key;
static RESTYPE frame_event_client_type, frame_event_drawable_type;
static int ms_dri2_server_generation;
struct ms_dri2_resource {
XID id;
RESTYPE type;
struct xorg_list list;
};
static struct ms_dri2_resource *
ms_get_resource(XID id, RESTYPE type)
{
struct ms_dri2_resource *resource;
void *ptr;
ptr = NULL;
dixLookupResourceByType(&ptr, id, type, NULL, DixWriteAccess);
if (ptr)
return ptr;
resource = malloc(sizeof(*resource));
if (resource == NULL)
return NULL;
if (!AddResource(id, type, resource)) {
free(resource);
return NULL;
}
resource->id = id;
resource->type = type;
xorg_list_init(&resource->list);
return resource;
}
static inline PixmapPtr
get_drawable_pixmap(DrawablePtr drawable)
{
ScreenPtr screen = drawable->pScreen;
if (drawable->type == DRAWABLE_PIXMAP)
return (PixmapPtr) drawable;
else
return screen->GetWindowPixmap((WindowPtr) drawable);
}
static PixmapPtr
get_front_buffer(DrawablePtr drawable)
{
PixmapPtr pixmap;
pixmap = get_drawable_pixmap(drawable);
pixmap->refcnt++;
return pixmap;
}
static DRI2Buffer2Ptr
ms_dri2_create_buffer(DrawablePtr drawable, unsigned int attachment,
unsigned int format)
{
ScreenPtr screen = drawable->pScreen;
ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
DRI2Buffer2Ptr buffer;
PixmapPtr pixmap;
uint32_t size;
uint16_t pitch;
ms_dri2_buffer_private_ptr private;
buffer = calloc(1, sizeof *buffer);
if (buffer == NULL)
return NULL;
private = calloc(1, sizeof(*private));
if (private == NULL) {
free(buffer);
return NULL;
}
pixmap = NULL;
if (attachment == DRI2BufferFrontLeft)
pixmap = get_front_buffer(drawable);
if (pixmap == NULL) {
int pixmap_width = drawable->width;
int pixmap_height = drawable->height;
int pixmap_cpp = (format != 0) ? format : drawable->depth;
/* Assume that non-color-buffers require special
* device-specific handling. Mesa currently makes no requests
* for non-color aux buffers.
*/
switch (attachment) {
case DRI2BufferAccum:
case DRI2BufferBackLeft:
case DRI2BufferBackRight:
case DRI2BufferFakeFrontLeft:
case DRI2BufferFakeFrontRight:
case DRI2BufferFrontLeft:
case DRI2BufferFrontRight:
break;
case DRI2BufferStencil:
case DRI2BufferDepth:
case DRI2BufferDepthStencil:
case DRI2BufferHiz:
default:
xf86DrvMsg(scrn->scrnIndex, X_WARNING,
"Request for DRI2 buffer attachment %d unsupported\n",
attachment);
free(private);
free(buffer);
return NULL;
}
pixmap = screen->CreatePixmap(screen,
pixmap_width,
pixmap_height,
pixmap_cpp,
0);
if (pixmap == NULL) {
if (pixmap)
screen->DestroyPixmap(pixmap);
free(private);
free(buffer);
return NULL;
}
}
buffer->attachment = attachment;
buffer->cpp = pixmap->drawable.bitsPerPixel / 8;
buffer->format = format;
/* The buffer's flags field is unused by the client drivers in
* Mesa currently.
*/
buffer->flags = 0;
buffer->name = glamor_name_from_pixmap(pixmap, &pitch, &size);
buffer->pitch = pitch;
if (buffer->name == -1) {
xf86DrvMsg(scrn->scrnIndex, X_ERROR,
"Failed to get DRI2 name for pixmap\n");
screen->DestroyPixmap(pixmap);
free(private);
free(buffer);
return NULL;
}
buffer->driverPrivate = private;
private->refcnt = 1;
private->pixmap = pixmap;
return buffer;
}
static void
ms_dri2_reference_buffer(DRI2Buffer2Ptr buffer)
{
if (buffer) {
ms_dri2_buffer_private_ptr private = buffer->driverPrivate;
private->refcnt++;
}
}
static void ms_dri2_destroy_buffer(DrawablePtr drawable, DRI2Buffer2Ptr buffer)
{
if (!buffer)
return;
if (buffer->driverPrivate) {
ms_dri2_buffer_private_ptr private = buffer->driverPrivate;
if (--private->refcnt == 0) {
ScreenPtr screen = private->pixmap->drawable.pScreen;
screen->DestroyPixmap(private->pixmap);
free(private);
free(buffer);
}
} else {
free(buffer);
}
}
static void
ms_dri2_copy_region(DrawablePtr drawable, RegionPtr pRegion,
DRI2BufferPtr destBuffer, DRI2BufferPtr sourceBuffer)
{
ms_dri2_buffer_private_ptr src_priv = sourceBuffer->driverPrivate;
ms_dri2_buffer_private_ptr dst_priv = destBuffer->driverPrivate;
PixmapPtr src_pixmap = src_priv->pixmap;
PixmapPtr dst_pixmap = dst_priv->pixmap;
ScreenPtr screen = drawable->pScreen;
DrawablePtr src = (sourceBuffer->attachment == DRI2BufferFrontLeft)
? drawable : &src_pixmap->drawable;
DrawablePtr dst = (destBuffer->attachment == DRI2BufferFrontLeft)
? drawable : &dst_pixmap->drawable;
RegionPtr pCopyClip;
GCPtr gc;
gc = GetScratchGC(dst->depth, screen);
if (!gc)
return;
pCopyClip = REGION_CREATE(screen, NULL, 0);
REGION_COPY(screen, pCopyClip, pRegion);
(*gc->funcs->ChangeClip) (gc, CT_REGION, pCopyClip, 0);
ValidateGC(dst, gc);
/* It's important that this copy gets submitted before the direct
* rendering client submits rendering for the next frame, but we
* don't actually need to submit right now. The client will wait
* for the DRI2CopyRegion reply or the swap buffer event before
* rendering, and we'll hit the flush callback chain before those
* messages are sent. We submit our batch buffers from the flush
* callback chain so we know that will happen before the client
* tries to render again.
*/
gc->ops->CopyArea(src, dst, gc,
0, 0,
drawable->width, drawable->height,
0, 0);
FreeScratchGC(gc);
}
static uint64_t
gettime_us(void)
{
struct timespec tv;
if (clock_gettime(CLOCK_MONOTONIC, &tv))
return 0;
return (uint64_t)tv.tv_sec * 1000000 + tv.tv_nsec / 1000;
}
/**
* Get current frame count and frame count timestamp, based on drawable's
* crtc.
*/
static int
ms_dri2_get_msc(DrawablePtr draw, CARD64 *ust, CARD64 *msc)
{
int ret;
xf86CrtcPtr crtc = ms_dri2_crtc_covering_drawable(draw);
/* Drawable not displayed, make up a *monotonic* value */
if (crtc == NULL) {
*ust = gettime_us();
*msc = 0;
return TRUE;
}
ret = ms_get_crtc_ust_msc(crtc, ust, msc);
if (ret)
return FALSE;
return TRUE;
}
static XID
get_client_id(ClientPtr client)
{
XID *ptr = dixGetPrivateAddr(&client->devPrivates, &ms_dri2_client_key);
if (*ptr == 0)
*ptr = FakeClientID(client->index);
return *ptr;
}
/*
* Hook this frame event into the server resource
* database so we can clean it up if the drawable or
* client exits while the swap is pending
*/
static Bool
ms_dri2_add_frame_event(ms_dri2_frame_event_ptr info)
{
struct ms_dri2_resource *resource;
resource = ms_get_resource(get_client_id(info->client),
frame_event_client_type);
if (resource == NULL)
return FALSE;
xorg_list_add(&info->client_resource, &resource->list);
resource = ms_get_resource(info->drawable->id, frame_event_drawable_type);
if (resource == NULL) {
xorg_list_del(&info->client_resource);
return FALSE;
}
xorg_list_add(&info->drawable_resource, &resource->list);
return TRUE;
}
static void
ms_dri2_del_frame_event(ms_dri2_frame_event_rec *info)
{
xorg_list_del(&info->client_resource);
xorg_list_del(&info->drawable_resource);
if (info->front)
ms_dri2_destroy_buffer(NULL, info->front);
if (info->back)
ms_dri2_destroy_buffer(NULL, info->back);
free(info);
}
static void
ms_dri2_blit_swap(DrawablePtr drawable,
DRI2BufferPtr dst,
DRI2BufferPtr src)
{
BoxRec box;
RegionRec region;
box.x1 = 0;
box.y1 = 0;
box.x2 = drawable->width;
box.y2 = drawable->height;
REGION_INIT(pScreen, &region, &box, 0);
ms_dri2_copy_region(drawable, &region, dst, src);
}
static void
ms_dri2_frame_event_handler(uint64_t msc,
uint64_t usec,
void *data)
{
ms_dri2_frame_event_ptr frame_info = data;
DrawablePtr drawable = frame_info->drawable;
ScreenPtr screen = frame_info->screen;
ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
uint32_t tv_sec = usec / 1000000;
uint32_t tv_usec = usec % 1000000;
if (!drawable) {
ms_dri2_del_frame_event(frame_info);
return;
}
switch (frame_info->type) {
case MS_DRI2_QUEUE_SWAP:
ms_dri2_blit_swap(drawable, frame_info->front, frame_info->back);
DRI2SwapComplete(frame_info->client, drawable, msc, tv_sec, tv_usec,
DRI2_BLIT_COMPLETE,
frame_info->client ? frame_info->event_complete : NULL,
frame_info->event_data);
break;
case MS_DRI2_WAIT_MSC:
if (frame_info->client)
DRI2WaitMSCComplete(frame_info->client, drawable,
msc, tv_sec, tv_usec);
break;
default:
xf86DrvMsg(scrn->scrnIndex, X_WARNING,
"%s: unknown vblank event (type %d) received\n", __func__,
frame_info->type);
break;
}
ms_dri2_del_frame_event(frame_info);
}
static void
ms_dri2_frame_event_abort(void *data)
{
ms_dri2_frame_event_ptr frame_info = data;
ms_dri2_del_frame_event(frame_info);
}
/**
* Request a DRM event when the requested conditions will be satisfied.
*
* We need to handle the event and ask the server to wake up the client when
* we receive it.
*/
static int
ms_dri2_schedule_wait_msc(ClientPtr client, DrawablePtr draw, CARD64 target_msc,
CARD64 divisor, CARD64 remainder)
{
ScreenPtr screen = draw->pScreen;
ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
modesettingPtr ms = modesettingPTR(scrn);
ms_dri2_frame_event_ptr wait_info;
drmVBlank vbl;
int ret;
xf86CrtcPtr crtc = ms_dri2_crtc_covering_drawable(draw);
drmmode_crtc_private_ptr drmmode_crtc;
CARD64 current_msc, current_ust, request_msc;
uint32_t seq;
/* Drawable not visible, return immediately */
if (!crtc)
goto out_complete;
drmmode_crtc = crtc->driver_private;
wait_info = calloc(1, sizeof(*wait_info));
if (!wait_info)
goto out_complete;
wait_info->screen = screen;
wait_info->drawable = draw;
wait_info->client = client;
wait_info->type = MS_DRI2_WAIT_MSC;
if (!ms_dri2_add_frame_event(wait_info)) {
free(wait_info);
wait_info = NULL;
goto out_complete;
}
/* Get current count */
ret = ms_get_crtc_ust_msc(crtc, &current_ust, &current_msc);
/*
* If divisor is zero, or current_msc is smaller than target_msc,
* we just need to make sure target_msc passes before waking up the
* client.
*/
if (divisor == 0 || current_msc < target_msc) {
/* If target_msc already reached or passed, set it to
* current_msc to ensure we return a reasonable value back
* to the caller. This keeps the client from continually
* sending us MSC targets from the past by forcibly updating
* their count on this call.
*/
seq = ms_drm_queue_alloc(crtc, wait_info,
ms_dri2_frame_event_handler,
ms_dri2_frame_event_abort);
if (!seq)
goto out_free;
if (current_msc >= target_msc)
target_msc = current_msc;
vbl.request.type = (DRM_VBLANK_ABSOLUTE |
DRM_VBLANK_EVENT |
drmmode_crtc->vblank_pipe);
vbl.request.sequence = ms_crtc_msc_to_kernel_msc(crtc, target_msc);
vbl.request.signal = (unsigned long)seq;
ret = drmWaitVBlank(ms->fd, &vbl);
if (ret) {
static int limit = 5;
if (limit) {
xf86DrvMsg(scrn->scrnIndex, X_WARNING,
"%s:%d get vblank counter failed: %s\n",
__FUNCTION__, __LINE__,
strerror(errno));
limit--;
}
goto out_free;
}
wait_info->frame = ms_kernel_msc_to_crtc_msc(crtc, vbl.reply.sequence);
DRI2BlockClient(client, draw);
return TRUE;
}
/*
* If we get here, target_msc has already passed or we don't have one,
* so we queue an event that will satisfy the divisor/remainder equation.
*/
vbl.request.type =
DRM_VBLANK_ABSOLUTE | DRM_VBLANK_EVENT | drmmode_crtc->vblank_pipe;
request_msc = current_msc - (current_msc % divisor) +
remainder;
/*
* If calculated remainder is larger than requested remainder,
* it means we've passed the last point where
* seq % divisor == remainder, so we need to wait for the next time
* that will happen.
*/
if ((current_msc % divisor) >= remainder)
request_msc += divisor;
seq = ms_drm_queue_alloc(crtc, wait_info,
ms_dri2_frame_event_handler,
ms_dri2_frame_event_abort);
if (!seq)
goto out_free;
vbl.request.sequence = ms_crtc_msc_to_kernel_msc(crtc, request_msc);
vbl.request.signal = (unsigned long)seq;
ret = drmWaitVBlank(ms->fd, &vbl);
if (ret) {
static int limit = 5;
if (limit) {
xf86DrvMsg(scrn->scrnIndex, X_WARNING,
"%s:%d get vblank counter failed: %s\n",
__FUNCTION__, __LINE__,
strerror(errno));
limit--;
}
goto out_free;
}
wait_info->frame = ms_kernel_msc_to_crtc_msc(crtc, vbl.reply.sequence);
DRI2BlockClient(client, draw);
return TRUE;
out_free:
ms_dri2_del_frame_event(wait_info);
out_complete:
DRI2WaitMSCComplete(client, draw, target_msc, 0, 0);
return TRUE;
}
/**
* ScheduleSwap is responsible for requesting a DRM vblank event for
* the appropriate frame, or executing the swap immediately if it
* doesn't need to wait.
*
* When the swap is complete, the driver should call into the server so it
* can send any swap complete events that have been requested.
*/
static int
ms_dri2_schedule_swap(ClientPtr client, DrawablePtr draw,
DRI2BufferPtr front, DRI2BufferPtr back,
CARD64 *target_msc, CARD64 divisor,
CARD64 remainder, DRI2SwapEventPtr func, void *data)
{
ScreenPtr screen = draw->pScreen;
ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
modesettingPtr ms = modesettingPTR(scrn);
drmVBlank vbl;
int ret;
xf86CrtcPtr crtc = ms_dri2_crtc_covering_drawable(draw);
drmmode_crtc_private_ptr drmmode_crtc;
ms_dri2_frame_event_ptr frame_info = NULL;
uint64_t current_msc, current_ust;
uint64_t request_msc;
uint32_t seq;
/* Drawable not displayed... just complete the swap */
if (!crtc)
goto blit_fallback;
drmmode_crtc = crtc->driver_private;
frame_info = calloc(1, sizeof(*frame_info));
if (!frame_info)
goto blit_fallback;
frame_info->screen = screen;
frame_info->drawable = draw;
frame_info->client = client;
frame_info->event_complete = func;
frame_info->event_data = data;
frame_info->front = front;
frame_info->back = back;
frame_info->crtc = crtc;
frame_info->type = MS_DRI2_QUEUE_SWAP;
if (!ms_dri2_add_frame_event(frame_info)) {
free(frame_info);
frame_info = NULL;
goto blit_fallback;
}
ms_dri2_reference_buffer(front);
ms_dri2_reference_buffer(back);
ret = ms_get_crtc_ust_msc(crtc, &current_ust, &current_msc);
/*
* If divisor is zero, or current_msc is smaller than target_msc
* we just need to make sure target_msc passes before initiating
* the swap.
*/
if (divisor == 0 || current_msc < *target_msc) {
/* We need to use DRM_VBLANK_NEXTONMISS to avoid unreliable
* timestamping later on.
*/
vbl.request.type = (DRM_VBLANK_ABSOLUTE |
DRM_VBLANK_NEXTONMISS |
DRM_VBLANK_EVENT |
drmmode_crtc->vblank_pipe);
/* If target_msc already reached or passed, set it to
* current_msc to ensure we return a reasonable value back
* to the caller. This makes swap_interval logic more robust.
*/
if (current_msc >= *target_msc)
*target_msc = current_msc;
seq = ms_drm_queue_alloc(crtc, frame_info,
ms_dri2_frame_event_handler,
ms_dri2_frame_event_abort);
if (!seq)
goto blit_fallback;
vbl.request.sequence = ms_crtc_msc_to_kernel_msc(crtc, *target_msc);
vbl.request.signal = (unsigned long)seq;
ret = drmWaitVBlank(ms->fd, &vbl);
if (ret) {
xf86DrvMsg(scrn->scrnIndex, X_WARNING,
"divisor 0 get vblank counter failed: %s\n",
strerror(errno));
goto blit_fallback;
}
*target_msc = ms_kernel_msc_to_crtc_msc(crtc, vbl.reply.sequence);
frame_info->frame = *target_msc;
return TRUE;
}
/*
* If we get here, target_msc has already passed or we don't have one,
* and we need to queue an event that will satisfy the divisor/remainder
* equation.
*/
vbl.request.type = (DRM_VBLANK_ABSOLUTE |
DRM_VBLANK_NEXTONMISS |
DRM_VBLANK_EVENT |
drmmode_crtc->vblank_pipe);
request_msc = current_msc - (current_msc % divisor) +
remainder;
/*
* If the calculated deadline vbl.request.sequence is smaller than
* or equal to current_msc, it means we've passed the last point
* when effective onset frame seq could satisfy
* seq % divisor == remainder, so we need to wait for the next time
* this will happen.
* This comparison takes the DRM_VBLANK_NEXTONMISS delay into account.
*/
if (request_msc <= current_msc)
request_msc += divisor;
seq = ms_drm_queue_alloc(crtc, frame_info,
ms_dri2_frame_event_handler,
ms_dri2_frame_event_abort);
if (!seq)
goto blit_fallback;
vbl.request.sequence = ms_crtc_msc_to_kernel_msc(crtc, request_msc);
vbl.request.signal = (unsigned long)seq;
ret = drmWaitVBlank(ms->fd, &vbl);
if (ret) {
xf86DrvMsg(scrn->scrnIndex, X_WARNING,
"final get vblank counter failed: %s\n",
strerror(errno));
goto blit_fallback;
}
*target_msc = ms_kernel_msc_to_crtc_msc(crtc, vbl.reply.sequence);
frame_info->frame = *target_msc;
return TRUE;
blit_fallback:
ms_dri2_blit_swap(draw, front, back);
DRI2SwapComplete(client, draw, 0, 0, 0, DRI2_BLIT_COMPLETE, func, data);
if (frame_info)
ms_dri2_del_frame_event(frame_info);
*target_msc = 0; /* offscreen, so zero out target vblank count */
return TRUE;
}
static int
ms_dri2_frame_event_client_gone(void *data, XID id)
{
struct ms_dri2_resource *resource = data;
while (!xorg_list_is_empty(&resource->list)) {
ms_dri2_frame_event_ptr info =
xorg_list_first_entry(&resource->list,
ms_dri2_frame_event_rec,
client_resource);
xorg_list_del(&info->client_resource);
info->client = NULL;
}
free(resource);
return Success;
}
static int
ms_dri2_frame_event_drawable_gone(void *data, XID id)
{
struct ms_dri2_resource *resource = data;
while (!xorg_list_is_empty(&resource->list)) {
ms_dri2_frame_event_ptr info =
xorg_list_first_entry(&resource->list,
ms_dri2_frame_event_rec,
drawable_resource);
xorg_list_del(&info->drawable_resource);
info->drawable = NULL;
}
free(resource);
return Success;
}
static Bool
ms_dri2_register_frame_event_resource_types(void)
{
frame_event_client_type =
CreateNewResourceType(ms_dri2_frame_event_client_gone,
"Frame Event Client");
if (!frame_event_client_type)
return FALSE;
frame_event_drawable_type =
CreateNewResourceType(ms_dri2_frame_event_drawable_gone,
"Frame Event Drawable");
if (!frame_event_drawable_type)
return FALSE;
return TRUE;
}
Bool
ms_dri2_screen_init(ScreenPtr screen)
{
ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
modesettingPtr ms = modesettingPTR(scrn);
DRI2InfoRec info;
if (!glamor_supports_pixmap_import_export(screen)) {
xf86DrvMsg(scrn->scrnIndex, X_WARNING,
"DRI2: glamor lacks support for pixmap import/export\n");
}
if (!xf86LoaderCheckSymbol("DRI2Version"))
return FALSE;
if (!dixRegisterPrivateKey(&ms_dri2_client_key,
PRIVATE_CLIENT, sizeof(XID)))
return FALSE;
if (serverGeneration != ms_dri2_server_generation) {
ms_dri2_server_generation = serverGeneration;
if (!ms_dri2_register_frame_event_resource_types()) {
xf86DrvMsg(scrn->scrnIndex, X_WARNING,
"Cannot register DRI2 frame event resources\n");
return FALSE;
}
}
memset(&info, '\0', sizeof(info));
info.fd = ms->fd;
info.driverName = NULL; /* Compat field, unused. */
info.deviceName = drmGetDeviceNameFromFd(ms->fd);
info.version = 4;
info.CreateBuffer = ms_dri2_create_buffer;
info.DestroyBuffer = ms_dri2_destroy_buffer;
info.CopyRegion = ms_dri2_copy_region;
info.ScheduleSwap = ms_dri2_schedule_swap;
info.GetMSC = ms_dri2_get_msc;
info.ScheduleWaitMSC = ms_dri2_schedule_wait_msc;
/* These two will be filled in by dri2.c */
info.numDrivers = 0;
info.driverNames = NULL;
return DRI2ScreenInit(screen, &info);
}
void
ms_dri2_close_screen(ScreenPtr screen)
{
DRI2CloseScreen(screen);
}
#endif /* GLAMOR */

View File

@ -788,7 +788,9 @@ PreInit(ScrnInfoPtr pScrn, int flags)
try_enable_glamor(pScrn);
if (!ms->glamor) {
if (ms->glamor) {
xf86LoadSubModule(pScrn, "dri2");
} else {
Bool prefer_shadow = TRUE;
ret = drmGetCap(ms->fd, DRM_CAP_DUMB_PREFER_SHADOW, &value);
@ -1107,6 +1109,21 @@ ScreenInit(ScreenPtr pScreen, int argc, char **argv)
if (serverGeneration == 1)
xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options);
if (!ms_vblank_screen_init(pScreen)) {
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
"Failed to initialize vblank support.\n");
return FALSE;
}
#ifdef GLAMOR
if (ms->glamor) {
if (!ms_dri2_screen_init(pScreen)) {
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
"Failed to initialize the DRI2 extension.\n");
}
}
#endif
return EnterVT(pScrn);
}
@ -1172,6 +1189,14 @@ CloseScreen(ScreenPtr pScreen)
ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
modesettingPtr ms = modesettingPTR(pScrn);
#ifdef GLAMOR
if (ms->glamor) {
ms_dri2_close_screen(pScreen);
}
#endif
ms_vblank_close_screen(pScreen);
if (ms->damage) {
DamageUnregister(ms->damage);
DamageDestroy(ms->damage);

View File

@ -30,6 +30,7 @@
#include <errno.h>
#include <drm.h>
#include <xf86drm.h>
#include <xf86Crtc.h>
#include <damage.h>
#include "drmmode_display.h"
@ -42,6 +43,26 @@ typedef struct {
ScrnInfoPtr pScrn_2;
} EntRec, *EntPtr;
typedef void (*ms_drm_handler_proc)(uint64_t frame,
uint64_t usec,
void *data);
typedef void (*ms_drm_abort_proc)(void *data);
/**
* A tracked handler for an event that will hopefully be generated by
* the kernel, and what to do when it is encountered.
*/
struct ms_drm_queue {
struct xorg_list list;
xf86CrtcPtr crtc;
uint32_t seq;
void *data;
ScrnInfoPtr scrn;
ms_drm_handler_proc handler;
ms_drm_abort_proc abort;
};
typedef struct _modesettingRec {
int fd;
@ -70,6 +91,8 @@ typedef struct _modesettingRec {
drmmode_rec drmmode;
drmEventContext event_context;
DamagePtr damage;
Bool dirty_enabled;
@ -78,3 +101,24 @@ typedef struct _modesettingRec {
} modesettingRec, *modesettingPtr;
#define modesettingPTR(p) ((modesettingPtr)((p)->driverPrivate))
uint32_t ms_drm_queue_alloc(xf86CrtcPtr crtc,
void *data,
ms_drm_handler_proc handler,
ms_drm_abort_proc abort);
xf86CrtcPtr ms_dri2_crtc_covering_drawable(DrawablePtr pDraw);
xf86CrtcPtr ms_covering_crtc(ScrnInfoPtr scrn, BoxPtr box,
xf86CrtcPtr desired, BoxPtr crtc_box_ret);
int ms_get_crtc_ust_msc(xf86CrtcPtr crtc, CARD64 *ust, CARD64 *msc);
uint32_t ms_crtc_msc_to_kernel_msc(xf86CrtcPtr crtc, uint64_t expect);
uint64_t ms_kernel_msc_to_crtc_msc(xf86CrtcPtr crtc, uint32_t sequence);
Bool ms_dri2_screen_init(ScreenPtr screen);
void ms_dri2_close_screen(ScreenPtr screen);
Bool ms_vblank_screen_init(ScreenPtr screen);
void ms_vblank_close_screen(ScreenPtr screen);

View File

@ -116,7 +116,7 @@ dumb_bo_unmap(int fd, struct dumb_bo *bo)
}
#endif
static int
int
dumb_bo_destroy(int fd, struct dumb_bo *bo)
{
struct drm_mode_destroy_dumb arg;
@ -137,8 +137,8 @@ dumb_bo_destroy(int fd, struct dumb_bo *bo)
return 0;
}
static struct dumb_bo *
dumb_get_bo_from_handle(int fd, int handle, int pitch, int size)
struct dumb_bo *
dumb_get_bo_from_fd(int fd, int handle, int pitch, int size)
{
struct dumb_bo *bo;
int ret;
@ -164,7 +164,7 @@ drmmode_SetSlaveBO(PixmapPtr ppix,
msPixmapPrivPtr ppriv = msGetPixmapPriv(drmmode, ppix);
ppriv->backing_bo =
dumb_get_bo_from_handle(drmmode->fd, fd_handle, pitch, size);
dumb_get_bo_from_fd(drmmode->fd, fd_handle, pitch, size);
if (!ppriv->backing_bo)
return FALSE;
@ -582,6 +582,17 @@ static const xf86CrtcFuncsRec drmmode_crtc_funcs = {
.shadow_create = drmmode_shadow_create,
};
static uint32_t
drmmode_crtc_vblank_pipe(int crtc_id)
{
if (crtc_id > 1)
return crtc_id << DRM_VBLANK_HIGH_CRTC_SHIFT;
else if (crtc_id > 0)
return DRM_VBLANK_SECONDARY;
else
return 0;
}
static void
drmmode_crtc_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int num)
{
@ -596,6 +607,7 @@ drmmode_crtc_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int num)
drmmode_crtc->mode_crtc =
drmModeGetCrtc(drmmode->fd, drmmode->mode_res->crtcs[num]);
drmmode_crtc->drmmode = drmmode;
drmmode_crtc->vblank_pipe = drmmode_crtc_vblank_pipe(num);
crtc->driver_private = drmmode_crtc;
}
@ -1183,6 +1195,11 @@ drmmode_xf86crtc_resize(ScrnInfoPtr scrn, int width, int height)
xf86DrvMsg(scrn->scrnIndex, X_INFO,
"Allocate new frame buffer %dx%d stride\n", width, height);
if (drmmode->triple_buffer_pixmap) {
screen->DestroyPixmap(drmmode->triple_buffer_pixmap);
drmmode->triple_buffer_pixmap = NULL;
}
old_width = scrn->virtualX;
old_height = scrn->virtualY;
old_pitch = drmmode->front_bo->pitch;

View File

@ -43,6 +43,7 @@ struct dumb_bo {
typedef struct {
int fd;
unsigned fb_id;
unsigned old_fb_id;
drmModeResPtr mode_res;
drmModeFBPtr mode_fb;
int cpp;
@ -58,17 +59,42 @@ typedef struct {
Bool shadow_enable;
void *shadow_fb;
/**
* A screen-sized pixmap when we're doing triple-buffered DRI2
* pageflipping.
*
* One is shared between all drawables that flip to the front
* buffer, and it only gets reallocated when root pixmap size
* changes.
*/
PixmapPtr triple_buffer_pixmap;
/** The GEM name for triple_buffer_pixmap */
uint32_t triple_buffer_name;
DevPrivateKeyRec pixmapPrivateKeyRec;
} drmmode_rec, *drmmode_ptr;
typedef struct {
drmmode_ptr drmmode;
drmModeCrtcPtr mode_crtc;
int hw_id;
uint32_t vblank_pipe;
struct dumb_bo *cursor_bo;
unsigned rotate_fb_id;
uint16_t lut_r[256], lut_g[256], lut_b[256];
DamagePtr slave_damage;
/**
* @{ MSC (vblank count) handling for the PRESENT extension.
*
* The kernel's vblank counters are 32 bits and apparently full of
* lies, and we need to give a reliable 64-bit msc for GL, so we
* have to track and convert to a userland-tracked 64-bit msc.
*/
int32_t vblank_offset;
uint32_t msc_prev;
uint64_t msc_high;
/** @} */
} drmmode_crtc_private_rec, *drmmode_crtc_private_ptr;
typedef struct {
@ -121,6 +147,9 @@ Bool drmmode_map_cursor_bos(ScrnInfoPtr pScrn, drmmode_ptr drmmode);
void drmmode_free_bos(ScrnInfoPtr pScrn, drmmode_ptr drmmode);
void drmmode_get_default_bpp(ScrnInfoPtr pScrn, drmmode_ptr drmmmode,
int *depth, int *bpp);
struct dumb_bo *dumb_get_bo_from_fd(int drm_fd, int fd, int pitch, int size);
int dumb_bo_destroy(int fd, struct dumb_bo *bo);
#ifndef DRM_CAP_DUMB_PREFERRED_DEPTH
#define DRM_CAP_DUMB_PREFERRED_DEPTH 3

View File

@ -0,0 +1,382 @@
/*
* Copyright © 2013 Keith Packard
*
* Permission to use, copy, modify, distribute, and sell this software and its
* documentation for any purpose is hereby granted without fee, provided that
* the above copyright notice appear in all copies and that both that copyright
* notice and this permission notice appear in supporting documentation, and
* that the name of the copyright holders not be used in advertising or
* publicity pertaining to distribution of the software without specific,
* written prior permission. The copyright holders make no representations
* about the suitability of this software for any purpose. It is provided "as
* is" without express or implied warranty.
*
* THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
* EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
* OF THIS SOFTWARE.
*/
/** @file vblank.c
*
* Support for tracking the DRM's vblank events.
*/
#ifdef HAVE_DIX_CONFIG_H
#include "dix-config.h"
#endif
#include <unistd.h>
#include <xf86.h>
#include <xf86Crtc.h>
#include <poll.h>
#include "driver.h"
#include "drmmode_display.h"
/**
* Tracking for outstanding events queued to the kernel.
*
* Each list entry is a struct ms_drm_queue, which has a uint32_t
* value generated from drm_seq that identifies the event and a
* reference back to the crtc/screen associated with the event. It's
* done this way rather than in the screen because we want to be able
* to drain the list of event handlers that should be called at server
* regen time, even though we don't close the drm fd and have no way
* to actually drain the kernel events.
*/
static struct xorg_list ms_drm_queue;
static uint32_t ms_drm_seq;
struct ms_pageflip {
ScreenPtr screen;
Bool crtc_for_msc_ust;
};
static void ms_box_intersect(BoxPtr dest, BoxPtr a, BoxPtr b)
{
dest->x1 = a->x1 > b->x1 ? a->x1 : b->x1;
dest->x2 = a->x2 < b->x2 ? a->x2 : b->x2;
if (dest->x1 >= dest->x2) {
dest->x1 = dest->x2 = dest->y1 = dest->y2 = 0;
return;
}
dest->y1 = a->y1 > b->y1 ? a->y1 : b->y1;
dest->y2 = a->y2 < b->y2 ? a->y2 : b->y2;
if (dest->y1 >= dest->y2)
dest->x1 = dest->x2 = dest->y1 = dest->y2 = 0;
}
static void ms_crtc_box(xf86CrtcPtr crtc, BoxPtr crtc_box)
{
if (crtc->enabled) {
crtc_box->x1 = crtc->x;
crtc_box->x2 =
crtc->x + xf86ModeWidth(&crtc->mode, crtc->rotation);
crtc_box->y1 = crtc->y;
crtc_box->y2 =
crtc->y + xf86ModeHeight(&crtc->mode, crtc->rotation);
} else
crtc_box->x1 = crtc_box->x2 = crtc_box->y1 = crtc_box->y2 = 0;
}
static int ms_box_area(BoxPtr box)
{
return (int)(box->x2 - box->x1) * (int)(box->y2 - box->y1);
}
/*
* Return the crtc covering 'box'. If two crtcs cover a portion of
* 'box', then prefer 'desired'. If 'desired' is NULL, then prefer the crtc
* with greater coverage
*/
xf86CrtcPtr
ms_covering_crtc(ScrnInfoPtr scrn,
BoxPtr box, xf86CrtcPtr desired, BoxPtr crtc_box_ret)
{
xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
xf86CrtcPtr crtc, best_crtc;
int coverage, best_coverage;
int c;
BoxRec crtc_box, cover_box;
best_crtc = NULL;
best_coverage = 0;
crtc_box_ret->x1 = 0;
crtc_box_ret->x2 = 0;
crtc_box_ret->y1 = 0;
crtc_box_ret->y2 = 0;
for (c = 0; c < xf86_config->num_crtc; c++) {
crtc = xf86_config->crtc[c];
/* If the CRTC is off, treat it as not covering */
if (!crtc->enabled)
continue;
ms_crtc_box(crtc, &crtc_box);
ms_box_intersect(&cover_box, &crtc_box, box);
coverage = ms_box_area(&cover_box);
if (coverage && crtc == desired) {
*crtc_box_ret = crtc_box;
return crtc;
}
if (coverage > best_coverage) {
*crtc_box_ret = crtc_box;
best_crtc = crtc;
best_coverage = coverage;
}
}
return best_crtc;
}
xf86CrtcPtr
ms_dri2_crtc_covering_drawable(DrawablePtr pDraw)
{
ScreenPtr pScreen = pDraw->pScreen;
ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
BoxRec box, crtcbox;
xf86CrtcPtr crtc;
box.x1 = pDraw->x;
box.y1 = pDraw->y;
box.x2 = box.x1 + pDraw->width;
box.y2 = box.y1 + pDraw->height;
crtc = ms_covering_crtc(pScrn, &box, NULL, &crtcbox);
/* Make sure the CRTC is valid and this is the real front buffer */
if (crtc != NULL && !crtc->rotatedData)
return crtc;
return NULL;
}
static Bool
ms_get_kernel_ust_msc(xf86CrtcPtr crtc,
uint32_t *msc, uint64_t *ust)
{
ScreenPtr screen = crtc->randr_crtc->pScreen;
ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
modesettingPtr ms = modesettingPTR(scrn);
drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
drmVBlank vbl;
int ret;
/* Get current count */
vbl.request.type = DRM_VBLANK_RELATIVE | drmmode_crtc->vblank_pipe;
vbl.request.sequence = 0;
vbl.request.signal = 0;
ret = drmWaitVBlank(ms->fd, &vbl);
if (ret) {
*msc = 0;
*ust = 0;
return FALSE;
} else {
*msc = vbl.reply.sequence;
*ust = (CARD64) vbl.reply.tval_sec * 1000000 + vbl.reply.tval_usec;
return TRUE;
}
}
/**
* Convert a 32-bit kernel MSC sequence number to a 64-bit local sequence
* number, adding in the vblank_offset and high 32 bits, and dealing
* with 64-bit wrapping
*/
uint64_t
ms_kernel_msc_to_crtc_msc(xf86CrtcPtr crtc, uint32_t sequence)
{
drmmode_crtc_private_rec *drmmode_crtc = crtc->driver_private;
sequence += drmmode_crtc->vblank_offset;
if ((int32_t) (sequence - drmmode_crtc->msc_prev) < -0x40000000)
drmmode_crtc->msc_high += 0x100000000L;
drmmode_crtc->msc_prev = sequence;
return drmmode_crtc->msc_high + sequence;
}
int
ms_get_crtc_ust_msc(xf86CrtcPtr crtc, CARD64 *ust, CARD64 *msc)
{
uint32_t kernel_msc;
if (!ms_get_kernel_ust_msc(crtc, &kernel_msc, ust))
return BadMatch;
*msc = ms_kernel_msc_to_crtc_msc(crtc, kernel_msc);
return Success;
}
#define MAX_VBLANK_OFFSET 1000
/**
* Convert a 64-bit adjusted MSC value into a 32-bit kernel sequence number,
* removing the high 32 bits and subtracting out the vblank_offset term.
*
* This also updates the vblank_offset when it notices that the value should
* change.
*/
uint32_t
ms_crtc_msc_to_kernel_msc(xf86CrtcPtr crtc, uint64_t expect)
{
drmmode_crtc_private_rec *drmmode_crtc = crtc->driver_private;
uint64_t msc;
uint64_t ust;
int64_t diff;
ms_get_crtc_ust_msc(crtc, &ust, &msc);
diff = expect - msc;
/* We're way off here, assume that the kernel has lost its mind
* and smack the vblank back to something sensible
*/
if (diff < -MAX_VBLANK_OFFSET || MAX_VBLANK_OFFSET < diff) {
drmmode_crtc->vblank_offset += (int32_t) diff;
if (drmmode_crtc->vblank_offset > -MAX_VBLANK_OFFSET &&
drmmode_crtc->vblank_offset < MAX_VBLANK_OFFSET)
drmmode_crtc->vblank_offset = 0;
}
return (uint32_t) (expect - drmmode_crtc->vblank_offset);
}
/**
* Check for pending DRM events and process them.
*/
static void
ms_drm_wakeup_handler(void *data, int err, void *mask)
{
ScreenPtr screen = data;
ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
modesettingPtr ms = modesettingPTR(scrn);
fd_set *read_mask = mask;
if (data == NULL || err < 0)
return;
if (FD_ISSET(ms->fd, read_mask))
drmHandleEvent(ms->fd, &ms->event_context);
}
/*
* Enqueue a potential drm response; when the associated response
* appears, we've got data to pass to the handler from here
*/
uint32_t
ms_drm_queue_alloc(xf86CrtcPtr crtc,
void *data,
ms_drm_handler_proc handler,
ms_drm_abort_proc abort)
{
ScreenPtr screen = crtc->randr_crtc->pScreen;
ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
struct ms_drm_queue *q;
q = calloc(1, sizeof(struct ms_drm_queue));
if (!q)
return 0;
if (!ms_drm_seq)
++ms_drm_seq;
q->seq = ms_drm_seq++;
q->scrn = scrn;
q->crtc = crtc;
q->data = data;
q->handler = handler;
q->abort = abort;
xorg_list_add(&q->list, &ms_drm_queue);
return q->seq;
}
/**
* Abort one queued DRM entry, removing it
* from the list, calling the abort function and
* freeing the memory
*/
static void
ms_drm_abort_one(struct ms_drm_queue *q)
{
xorg_list_del(&q->list);
q->abort(q->data);
free(q);
}
/**
* Abort all queued entries on a specific scrn, used
* when resetting the X server
*/
static void
ms_drm_abort_scrn(ScrnInfoPtr scrn)
{
struct ms_drm_queue *q, *tmp;
xorg_list_for_each_entry_safe(q, tmp, &ms_drm_queue, list) {
if (q->scrn == scrn)
ms_drm_abort_one(q);
}
}
/*
* General DRM kernel handler. Looks for the matching sequence number in the
* drm event queue and calls the handler for it.
*/
static void
ms_drm_handler(int fd, uint32_t frame, uint32_t sec, uint32_t usec,
void *user_ptr)
{
struct ms_drm_queue *q, *tmp;
uint32_t user_data = (uint32_t) (intptr_t) user_ptr;
xorg_list_for_each_entry_safe(q, tmp, &ms_drm_queue, list) {
if (q->seq == user_data) {
uint64_t msc;
msc = ms_kernel_msc_to_crtc_msc(q->crtc, frame);
xorg_list_del(&q->list);
q->handler(msc, (uint64_t) sec * 1000000 + usec, q->data);
free(q);
break;
}
}
}
Bool
ms_vblank_screen_init(ScreenPtr screen)
{
ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
modesettingPtr ms = modesettingPTR(scrn);
xorg_list_init(&ms_drm_queue);
ms->event_context.version = DRM_EVENT_CONTEXT_VERSION;
ms->event_context.vblank_handler = ms_drm_handler;
ms->event_context.page_flip_handler = ms_drm_handler;
/* We need to re-register the DRM fd for the synchronisation
* feedback on every server generation, so perform the
* registration within ScreenInit and not PreInit.
*/
AddGeneralSocket(ms->fd);
RegisterBlockAndWakeupHandlers((BlockHandlerProcPtr)NoopDDA,
ms_drm_wakeup_handler, screen);
return TRUE;
}
void
ms_vblank_close_screen(ScreenPtr screen)
{
ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
modesettingPtr ms = modesettingPTR(scrn);
ms_drm_abort_scrn(scrn);
RemoveBlockAndWakeupHandlers((BlockHandlerProcPtr)NoopDDA,
ms_drm_wakeup_handler, screen);
RemoveGeneralSocket(ms->fd);
}