mirror of https://gitee.com/openkylin/linux.git
drm: SiS 315 Awareness.
Add support for the SiS 315 to the DRM. Signed-off-by: Dave Airlie <airlied@linux.ie>
This commit is contained in:
parent
8d153f7107
commit
7981bf7d49
|
@ -209,6 +209,7 @@
|
||||||
{0x1039, 0x0300, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
|
{0x1039, 0x0300, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
|
||||||
{0x1039, 0x5300, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
|
{0x1039, 0x5300, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
|
||||||
{0x1039, 0x6300, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
|
{0x1039, 0x6300, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
|
||||||
|
{0x1039, 0x6330, PCI_ANY_ID, PCI_ANY_ID, 0, 0, SIS_CHIP_315}, \
|
||||||
{0x1039, 0x7300, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
|
{0x1039, 0x7300, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
|
||||||
{0, 0, 0}
|
{0, 0, 0}
|
||||||
|
|
||||||
|
|
|
@ -69,6 +69,7 @@ static struct drm_driver driver = {
|
||||||
.load = sis_driver_load,
|
.load = sis_driver_load,
|
||||||
.unload = sis_driver_unload,
|
.unload = sis_driver_unload,
|
||||||
.context_dtor = NULL,
|
.context_dtor = NULL,
|
||||||
|
.dma_quiescent = sis_idle,
|
||||||
.reclaim_buffers = NULL,
|
.reclaim_buffers = NULL,
|
||||||
.reclaim_buffers_locked = sis_reclaim_buffers_locked,
|
.reclaim_buffers_locked = sis_reclaim_buffers_locked,
|
||||||
.lastclose = sis_lastclose,
|
.lastclose = sis_lastclose,
|
||||||
|
|
|
@ -34,13 +34,22 @@
|
||||||
#define DRIVER_AUTHOR "SIS, Tungsten Graphics"
|
#define DRIVER_AUTHOR "SIS, Tungsten Graphics"
|
||||||
#define DRIVER_NAME "sis"
|
#define DRIVER_NAME "sis"
|
||||||
#define DRIVER_DESC "SIS 300/630/540"
|
#define DRIVER_DESC "SIS 300/630/540"
|
||||||
#define DRIVER_DATE "20060529"
|
#define DRIVER_DATE "20060704"
|
||||||
#define DRIVER_MAJOR 1
|
#define DRIVER_MAJOR 1
|
||||||
#define DRIVER_MINOR 2
|
#define DRIVER_MINOR 2
|
||||||
#define DRIVER_PATCHLEVEL 1
|
#define DRIVER_PATCHLEVEL 1
|
||||||
|
|
||||||
|
enum sis_family {
|
||||||
|
SIS_OTHER = 0,
|
||||||
|
SIS_CHIP_315 = 1,
|
||||||
|
};
|
||||||
|
|
||||||
#include "drm_sman.h"
|
#include "drm_sman.h"
|
||||||
|
|
||||||
|
#define SIS_BASE (dev_priv->mmio)
|
||||||
|
#define SIS_READ(reg) DRM_READ32(SIS_BASE, reg);
|
||||||
|
#define SIS_WRITE(reg, val) DRM_WRITE32(SIS_BASE, reg, val);
|
||||||
|
|
||||||
typedef struct drm_sis_private {
|
typedef struct drm_sis_private {
|
||||||
drm_local_map_t *mmio;
|
drm_local_map_t *mmio;
|
||||||
unsigned int idle_fault;
|
unsigned int idle_fault;
|
||||||
|
@ -52,6 +61,7 @@ typedef struct drm_sis_private {
|
||||||
unsigned long agp_offset;
|
unsigned long agp_offset;
|
||||||
} drm_sis_private_t;
|
} drm_sis_private_t;
|
||||||
|
|
||||||
|
extern int sis_idle(drm_device_t *dev);
|
||||||
extern void sis_reclaim_buffers_locked(drm_device_t *dev, struct file *filp);
|
extern void sis_reclaim_buffers_locked(drm_device_t *dev, struct file *filp);
|
||||||
extern void sis_lastclose(drm_device_t *dev);
|
extern void sis_lastclose(drm_device_t *dev);
|
||||||
|
|
||||||
|
|
|
@ -226,6 +226,76 @@ static int sis_ioctl_agp_alloc(DRM_IOCTL_ARGS)
|
||||||
return sis_drm_alloc(dev, priv, data, AGP_TYPE);
|
return sis_drm_alloc(dev, priv, data, AGP_TYPE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static drm_local_map_t *sis_reg_init(drm_device_t *dev)
|
||||||
|
{
|
||||||
|
drm_map_list_t *entry;
|
||||||
|
drm_local_map_t *map;
|
||||||
|
|
||||||
|
list_for_each_entry(entry, &dev->maplist->head, head) {
|
||||||
|
map = entry->map;
|
||||||
|
if (!map)
|
||||||
|
continue;
|
||||||
|
if (map->type == _DRM_REGISTERS) {
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
int sis_idle(drm_device_t *dev)
|
||||||
|
{
|
||||||
|
drm_sis_private_t *dev_priv = dev->dev_private;
|
||||||
|
uint32_t idle_reg;
|
||||||
|
unsigned long end;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (dev_priv->idle_fault)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (dev_priv->mmio == NULL) {
|
||||||
|
dev_priv->mmio = sis_reg_init(dev);
|
||||||
|
if (dev_priv->mmio == NULL) {
|
||||||
|
DRM_ERROR("Could not find register map.\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Implement a device switch here if needed
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (dev_priv->chipset != SIS_CHIP_315)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Timeout after 3 seconds. We cannot use DRM_WAIT_ON here
|
||||||
|
* because its polling frequency is too low.
|
||||||
|
*/
|
||||||
|
|
||||||
|
end = jiffies + (DRM_HZ * 3);
|
||||||
|
|
||||||
|
for (i=0; i<4; ++i) {
|
||||||
|
do {
|
||||||
|
idle_reg = SIS_READ(0x85cc);
|
||||||
|
} while ( !time_after_eq(jiffies, end) &&
|
||||||
|
((idle_reg & 0x80000000) != 0x80000000));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (time_after_eq(jiffies, end)) {
|
||||||
|
DRM_ERROR("Graphics engine idle timeout. "
|
||||||
|
"Disabling idle check\n");
|
||||||
|
dev_priv->idle_fault = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The caller never sees an error code. It gets trapped
|
||||||
|
* in libdrm.
|
||||||
|
*/
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void sis_lastclose(struct drm_device *dev)
|
void sis_lastclose(struct drm_device *dev)
|
||||||
{
|
{
|
||||||
drm_sis_private_t *dev_priv = dev->dev_private;
|
drm_sis_private_t *dev_priv = dev->dev_private;
|
||||||
|
@ -237,6 +307,7 @@ void sis_lastclose(struct drm_device *dev)
|
||||||
drm_sman_cleanup(&dev_priv->sman);
|
drm_sman_cleanup(&dev_priv->sman);
|
||||||
dev_priv->vram_initialized = FALSE;
|
dev_priv->vram_initialized = FALSE;
|
||||||
dev_priv->agp_initialized = FALSE;
|
dev_priv->agp_initialized = FALSE;
|
||||||
|
dev_priv->mmio = NULL;
|
||||||
mutex_unlock(&dev->struct_mutex);
|
mutex_unlock(&dev->struct_mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue