Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 7981bf7d authored by Thomas Hellstrom's avatar Thomas Hellstrom Committed by Dave Airlie
Browse files

drm: SiS 315 Awareness.



Add support for the SiS 315 to the DRM.

Signed-off-by: default avatarDave Airlie <airlied@linux.ie>
parent 8d153f71
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -209,6 +209,7 @@
	{0x1039, 0x0300, 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, 0x6330, PCI_ANY_ID, PCI_ANY_ID, 0, 0, SIS_CHIP_315}, \
	{0x1039, 0x7300, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
	{0, 0, 0}

+1 −0
Original line number Diff line number Diff line
@@ -69,6 +69,7 @@ static struct drm_driver driver = {
	.load = sis_driver_load,
	.unload = sis_driver_unload,
	.context_dtor = NULL,
	.dma_quiescent = sis_idle,
	.reclaim_buffers = NULL,
	.reclaim_buffers_locked = sis_reclaim_buffers_locked,
	.lastclose = sis_lastclose,
+11 −1
Original line number Diff line number Diff line
@@ -34,13 +34,22 @@
#define DRIVER_AUTHOR		"SIS, Tungsten Graphics"
#define DRIVER_NAME		"sis"
#define DRIVER_DESC		"SIS 300/630/540"
#define DRIVER_DATE		"20060529"
#define DRIVER_DATE		"20060704"
#define DRIVER_MAJOR		1
#define DRIVER_MINOR		2
#define DRIVER_PATCHLEVEL	1

enum sis_family {
	SIS_OTHER = 0,
	SIS_CHIP_315 = 1,
};

#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 {
	drm_local_map_t *mmio;
	unsigned int idle_fault;
@@ -52,6 +61,7 @@ typedef struct drm_sis_private {
	unsigned long agp_offset;
} 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_lastclose(drm_device_t *dev);

+71 −0
Original line number Diff line number Diff line
@@ -226,6 +226,76 @@ static int sis_ioctl_agp_alloc(DRM_IOCTL_ARGS)
	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)
{
	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);
	dev_priv->vram_initialized = FALSE;
	dev_priv->agp_initialized = FALSE;
	dev_priv->mmio = NULL;
	mutex_unlock(&dev->struct_mutex);
}