forcewake: Add mmio code to do proper forcewake stuff for gen6

This commit is contained in:
Ben Widawsky 2011-07-28 13:40:19 -07:00
parent 294927c601
commit cac8f8b526
2 changed files with 130 additions and 1 deletions

View File

@ -37,6 +37,12 @@
extern void *mmio; extern void *mmio;
void intel_get_mmio(struct pci_device *pci_dev); void intel_get_mmio(struct pci_device *pci_dev);
/* New style register access API */
int intel_register_access_init(struct pci_device *pci_dev);
void intel_register_access_fini(void);
uint32_t intel_register_read(uint32_t reg);
void intel_register_write(uint32_t reg, uint32_t val);
static inline uint32_t static inline uint32_t
INREG(uint32_t reg) INREG(uint32_t reg)
{ {

View File

@ -22,12 +22,16 @@
* *
* Authors: * Authors:
* Eric Anholt <eric@anholt.net> * Eric Anholt <eric@anholt.net>
* Ben Widawsky <ben@bwidawsk.net>
* *
*/ */
#include <unistd.h> #include <unistd.h>
#include <stdlib.h>
#include <stdio.h> #include <stdio.h>
#include <stdarg.h>
#include <stdlib.h>
#include <stdint.h>
#include <stdbool.h>
#include <string.h> #include <string.h>
#include <errno.h> #include <errno.h>
#include <err.h> #include <err.h>
@ -41,6 +45,15 @@
void *mmio; void *mmio;
static struct _mmio_data {
int inited;
bool safe;
char debugfs_path[FILENAME_MAX];
char debugfs_forcewake_path[FILENAME_MAX];
uint32_t i915_devid;
int key;
} mmio_data;
void void
intel_map_file(char *file) intel_map_file(char *file)
{ {
@ -89,3 +102,113 @@ intel_get_mmio(struct pci_device *pci_dev)
} }
} }
/*
* If successful, i915_debugfs_path and i915_debugfs_forcewake_path are both
* updated with the correct path.
*/
static int
find_debugfs_path(char *dri_base)
{
char buf[FILENAME_MAX];
struct stat sb;
int i, ret;
for (i = 0; i < 16; i++) {
snprintf(buf, FILENAME_MAX, "%s/%i/name", dri_base, i);
snprintf(mmio_data.debugfs_path, FILENAME_MAX,
"%s/%i/", dri_base, i);
snprintf(mmio_data.debugfs_forcewake_path, FILENAME_MAX,
"%s/%i/i915_forcewake_user", dri_base, i);
ret = stat(mmio_data.debugfs_forcewake_path, &sb);
if (ret) {
mmio_data.debugfs_path[0] = 0;
mmio_data.debugfs_forcewake_path[0] = 0;
} else
return 0;
}
return -1;
}
static int
get_forcewake_lock(void)
{
return open(mmio_data.debugfs_forcewake_path, 0);
}
static void
release_forcewake_lock(int fd)
{
close(fd);
}
/*
* Initialize register access library.
*
* @pci_dev: pci device we're mucking with
* @safe: use safe register access tables
*/
int
intel_register_access_init(struct pci_device *pci_dev)
{
int ret;
/* after old API is deprecated, remove this */
if (mmio == NULL)
intel_get_mmio(pci_dev);
assert(mmio != NULL);
if (mmio_data.inited)
return -1;
/* Find where the forcewake lock is */
ret = find_debugfs_path("/sys/kernel/debug/dri");
if (ret) {
ret = find_debugfs_path("/debug/dri");
if (ret) {
fprintf(stderr, "Couldn't find path to dri/debugfs entry\n");
return ret;
}
}
mmio_data.i915_devid = pci_dev->device_id;
mmio_data.key = get_forcewake_lock();
mmio_data.inited++;
return 0;
}
void
intel_register_access_fini(void)
{
release_forcewake_lock(mmio_data.key);
mmio_data.inited--;
}
uint32_t
intel_register_read(uint32_t reg)
{
struct intel_register_range *range;
uint32_t ret;
assert(mmio_data.inited);
if (IS_GEN6(mmio_data.i915_devid))
assert(mmio_data.key != -1);
}
void
intel_register_write(uint32_t reg, uint32_t val)
{
struct intel_register_range *range;
assert(mmio_data.inited);
if (IS_GEN6(mmio_data.i915_devid))
assert(mmio_data.key != -1);
*(volatile uint32_t *)((volatile char *)mmio + reg) = val;
}