summaryrefslogtreecommitdiff
path: root/hw/xfree86/fbdevhw
diff options
context:
space:
mode:
authorIan Romanick <idr@localhost.localdomain>2006-06-07 14:09:02 -0700
committerIan Romanick <idr@localhost.localdomain>2006-06-07 14:09:02 -0700
commit46f55f5dead5d70cdff30531d80a72f6be042315 (patch)
tree8b06abaed2a9c3908299620dd3595393a1d2766d /hw/xfree86/fbdevhw
parentd00aa6b8559d3e5f70c6558ce0abd12f7d758491 (diff)
Initial batch of changes for PCI rework. All future changes will be
tracked individually.
Diffstat (limited to 'hw/xfree86/fbdevhw')
-rw-r--r--hw/xfree86/fbdevhw/fbdevhw.c136
-rw-r--r--hw/xfree86/fbdevhw/fbdevhw.h6
2 files changed, 95 insertions, 47 deletions
diff --git a/hw/xfree86/fbdevhw/fbdevhw.c b/hw/xfree86/fbdevhw/fbdevhw.c
index 70bed620b..277b5daea 100644
--- a/hw/xfree86/fbdevhw/fbdevhw.c
+++ b/hw/xfree86/fbdevhw/fbdevhw.c
@@ -268,53 +268,99 @@ fbdev2xfree_timing(struct fb_var_screeninfo *var, DisplayModePtr mode)
/* -------------------------------------------------------------------- */
/* open correct framebuffer device */
-/* try to find the framebuffer device for a given PCI device */
+/**
+ * Try to find the framebuffer device for a given PCI device
+ */
static int
-fbdev_open_pci(pciVideoPtr pPci, char **namep)
-{
- struct fb_fix_screeninfo fix;
- char filename[16];
- int fd,i,j;
- memType res_start, res_end;
-
- for (i = 0; i < 8; i++) {
- sprintf(filename,"/dev/fb%d",i);
- if (-1 == (fd = open(filename,O_RDWR,0))) {
- xf86DrvMsg(-1, X_WARNING,
- "open %s: %s\n", filename, strerror(errno));
- continue;
+fbdev_open_pci(struct pci_device * pPci, char **namep)
+{
+ struct fb_fix_screeninfo fix;
+ char filename[256];
+ int fd,i,j;
+
+
+ /* There are two ways to that we can determine which fb device is
+ * associated with this PCI device. The more modern way is to look in
+ * the sysfs directory for the PCI device for a file named
+ * "graphics:fb*"
+ */
+
+ for (i = 0; i < 8; i++) {
+ sprintf(filename,
+ "/sys/bus/pci/devices/%04x:%02x:%02x.%d/graphics:fb%d",
+ pPci->domain, pPci->bus, pPci->dev, pPci->func, i);
+
+ fd = open(filename, O_RDONLY, 0);
+ if (fd != -1) {
+ close(fd);
+ sprintf(filename, "/dev/fb%d", i);
+
+ fd = open(filename, O_RDWR, 0);
+ if (fd != -1) {
+ if (ioctl(fd, FBIOGET_FSCREENINFO, (void*) & fix) != -1) {
+ if (namep) {
+ *namep = xnfalloc(16);
+ strncpy(*namep,fix.id,16);
+ }
+
+ return fd;
}
- if (-1 == ioctl(fd,FBIOGET_FSCREENINFO,(void*)&fix)) {
- close(fd);
- continue;
- }
- for (j = 0; j < 6; j++) {
- res_start = pPci->memBase[j];
- res_end = res_start+pPci->size[j];
- if ((0 != fix.smem_len &&
- (memType) fix.smem_start >= res_start &&
- (memType) fix.smem_start < res_end) ||
- (0 != fix.mmio_len &&
- (memType) fix.mmio_start >= res_start &&
- (memType) fix.mmio_start < res_end))
- break;
- }
- if (j == 6) {
- close(fd);
- continue;
- }
- if (namep) {
- *namep = xnfalloc(16);
- strncpy(*namep,fix.id,16);
- }
- return fd;
+ }
}
- if (namep)
- *namep = NULL;
- xf86DrvMsg(-1, X_ERROR,
- "Unable to find a valid framebuffer device\n");
- return -1;
+ close(fd);
+ }
+
+
+ /* The other way is to examine the resources associated with each fb
+ * device and see if there is a match with the PCI device. This technique
+ * has some problems on certain mixed 64-bit / 32-bit architectures.
+ * There is a flaw in the fb_fix_screeninfo structure in that it only
+ * returns the low 32-bits of the address of the resources associated with
+ * a device. However, on a mixed architecture the base addresses of PCI
+ * devices, even for 32-bit applications, may be higher than 0x0f0000000.
+ */
+
+ for (i = 0; i < 8; i++) {
+ sprintf(filename,"/dev/fb%d",i);
+ if (-1 == (fd = open(filename,O_RDWR,0))) {
+ xf86DrvMsg(-1, X_WARNING,
+ "open %s: %s\n", filename, strerror(errno));
+ continue;
+ }
+ if (-1 == ioctl(fd,FBIOGET_FSCREENINFO,(void*)&fix)) {
+ close(fd);
+ continue;
+ }
+ for (j = 0; j < 6; j++) {
+ const pciaddr_t res_start = pPci->regions[j].base_addr;
+ const pciaddr_t res_end = res_start + pPci->regions[j].size;
+
+ if ((0 != fix.smem_len &&
+ (pciaddr_t) fix.smem_start >= res_start &&
+ (pciaddr_t) fix.smem_start < res_end) ||
+ (0 != fix.mmio_len &&
+ (pciaddr_t) fix.mmio_start >= res_start &&
+ (pciaddr_t) fix.mmio_start < res_end))
+ break;
+ }
+ if (j == 6) {
+ close(fd);
+ continue;
+ }
+ if (namep) {
+ *namep = xnfalloc(16);
+ strncpy(*namep,fix.id,16);
+ }
+ return fd;
+ }
+
+ if (namep)
+ *namep = NULL;
+
+ xf86DrvMsg(-1, X_ERROR,
+ "Unable to find a valid framebuffer device\n");
+ return -1;
}
static int
@@ -359,7 +405,7 @@ fbdev_open(int scrnIndex, char *dev, char** namep)
/* -------------------------------------------------------------------- */
Bool
-fbdevHWProbe(pciVideoPtr pPci, char *device,char **namep)
+fbdevHWProbe(struct pci_device * pPci, char *device,char **namep)
{
int fd;
@@ -375,7 +421,7 @@ fbdevHWProbe(pciVideoPtr pPci, char *device,char **namep)
}
Bool
-fbdevHWInit(ScrnInfoPtr pScrn, pciVideoPtr pPci, char *device)
+fbdevHWInit(ScrnInfoPtr pScrn, struct pci_device * pPci, char *device)
{
fbdevHWPtr fPtr;
diff --git a/hw/xfree86/fbdevhw/fbdevhw.h b/hw/xfree86/fbdevhw/fbdevhw.h
index cfc3fcdb6..3c482d709 100644
--- a/hw/xfree86/fbdevhw/fbdevhw.h
+++ b/hw/xfree86/fbdevhw/fbdevhw.h
@@ -6,6 +6,8 @@
#include "xf86str.h"
#include "colormapst.h"
+#include <pciaccess.h>
+
#define FBDEVHW_PACKED_PIXELS 0 /* Packed Pixels */
#define FBDEVHW_PLANES 1 /* Non interleaved planes */
#define FBDEVHW_INTERLEAVED_PLANES 2 /* Interleaved planes */
@@ -15,8 +17,8 @@
Bool fbdevHWGetRec(ScrnInfoPtr pScrn);
void fbdevHWFreeRec(ScrnInfoPtr pScrn);
-Bool fbdevHWProbe(pciVideoPtr pPci, char *device, char **namep);
-Bool fbdevHWInit(ScrnInfoPtr pScrn, pciVideoPtr pPci, char *device);
+Bool fbdevHWProbe(struct pci_device * pPci, char *device, char **namep);
+Bool fbdevHWInit(ScrnInfoPtr pScrn, struct pci_device * pPci, char *device);
char* fbdevHWGetName(ScrnInfoPtr pScrn);
int fbdevHWGetDepth(ScrnInfoPtr pScrn, int *fbbpp);