From 0c6fb0fbe1fff43af60634b785cd5b7196c8dd03 Mon Sep 17 00:00:00 2001
From: Jon Smirl <jonsmirl@yahoo.com>
Date: Fri, 17 Sep 2004 04:02:28 +0000
Subject: Add linux sysfs i2c support to radeon driver. This patch adds GPL
 licensed     files to the linux build but not to the BSD directories.

---
 linux-core/Makefile.kernel |  2 +-
 linux/Makefile.kernel      |  2 +-
 shared-core/radeon_cp.c    | 40 +++++++++++++++++++++++++++++++---------
 shared-core/radeon_drv.h   | 11 +++++++++--
 shared/radeon_cp.c         | 40 +++++++++++++++++++++++++++++++---------
 shared/radeon_drv.h        | 11 +++++++++--
 6 files changed, 82 insertions(+), 24 deletions(-)

diff --git a/linux-core/Makefile.kernel b/linux-core/Makefile.kernel
index 92e3f73e..5ff3d399 100644
--- a/linux-core/Makefile.kernel
+++ b/linux-core/Makefile.kernel
@@ -13,7 +13,7 @@ mga-objs    := mga_drv.o mga_dma.o mga_state.o mga_warp.o mga_irq.o
 i810-objs   := i810_drv.o i810_dma.o
 i830-objs   := i830_drv.o i830_dma.o i830_irq.o
 i915-objs   := i915_drv.o i915_dma.o i915_irq.o i915_mem.o
-radeon-objs := radeon_drv.o radeon_cp.o radeon_state.o radeon_mem.o radeon_irq.o
+radeon-objs := radeon_drv.o radeon_cp.o radeon_state.o radeon_mem.o radeon_irq.o radeon_i2c.o
 sis-objs    := sis_drv.o sis_ds.o sis_mm.o
 ffb-objs    := ffb_drv.o ffb_context.o
 savage-objs := savage_drv.o savage_dma.o
diff --git a/linux/Makefile.kernel b/linux/Makefile.kernel
index 92e3f73e..5ff3d399 100644
--- a/linux/Makefile.kernel
+++ b/linux/Makefile.kernel
@@ -13,7 +13,7 @@ mga-objs    := mga_drv.o mga_dma.o mga_state.o mga_warp.o mga_irq.o
 i810-objs   := i810_drv.o i810_dma.o
 i830-objs   := i830_drv.o i830_dma.o i830_irq.o
 i915-objs   := i915_drv.o i915_dma.o i915_irq.o i915_mem.o
-radeon-objs := radeon_drv.o radeon_cp.o radeon_state.o radeon_mem.o radeon_irq.o
+radeon-objs := radeon_drv.o radeon_cp.o radeon_state.o radeon_mem.o radeon_irq.o radeon_i2c.o
 sis-objs    := sis_drv.o sis_ds.o sis_mm.o
 ffb-objs    := ffb_drv.o ffb_context.o
 savage-objs := savage_drv.o savage_dma.o
diff --git a/shared-core/radeon_cp.c b/shared-core/radeon_cp.c
index c5ff768a..27a1beb0 100644
--- a/shared-core/radeon_cp.c
+++ b/shared-core/radeon_cp.c
@@ -36,7 +36,6 @@
 
 #define RADEON_FIFO_DEBUG	0
 
-
 /* CP microcode (from ATI) */
 static u32 R200_cp_microcode[][2] = {
 	{ 0x21007000, 0000000000 },        
@@ -1285,12 +1284,8 @@ int radeon_do_cleanup_cp( drm_device_t *dev )
 					       dev_priv->bus_pci_gart ))
 			DRM_ERROR( "failed to cleanup PCI GART!\n" );
 	}
-	
-	{
-		int flags = dev_priv->flags;
-		memset(dev_priv, 0, sizeof(*dev_priv));
-		dev_priv->flags = flags;
-	}
+	/* only clear to the start of flags */
+	memset(dev_priv, 0, offsetof(drm_radeon_private_t, flags));
 
 	return 0;
 }
@@ -1735,8 +1730,9 @@ int radeon_cp_buffers( DRM_IOCTL_ARGS )
 /* Always create a map record for MMIO and FB memory, done from DRIVER_POSTINIT */
 int radeon_preinit( struct drm_device *dev, unsigned long flags )
 {
-	u32 save, temp;
+	u32 save, temp, memmode;
 	drm_radeon_private_t *dev_priv;
+	int ret = 0;
 
 	dev_priv = DRM(alloc)( sizeof(drm_radeon_private_t), DRM_MEM_DRIVER );
 	if ( dev_priv == NULL )
@@ -1746,6 +1742,17 @@ int radeon_preinit( struct drm_device *dev, unsigned long flags )
 	dev->dev_private = (void *)dev_priv;
 	dev_priv->flags = flags;
 
+	/* registers */
+	/* PCI space is twice the real size, so that you can have a RW and RO mapping */
+	if( (ret = DRM(initmap)( dev, pci_resource_start( dev->pdev, 2 ),
+			pci_resource_len( dev->pdev, 2 ) / 2, _DRM_REGISTERS, 0 )))
+		return ret;
+
+	/* framebuffer */
+	if( (ret = DRM(initmap)( dev, pci_resource_start( dev->pdev, 0 ),
+			pci_resource_len( dev->pdev, 0 ), _DRM_FRAME_BUFFER, _DRM_WRITE_COMBINING )))
+		return ret;
+
 	/* There are signatures in BIOS and PCI-SSID for a PCI card, but they are not very reliable.
 		Following detection method works for all cards tested so far.
 		Note, checking AGP_ENABLE bit after drmAgpEnable call can also give the correct result.
@@ -1759,8 +1766,19 @@ int radeon_preinit( struct drm_device *dev, unsigned long flags )
 		dev_priv->flags |= CHIP_IS_AGP;
 	DRM_DEBUG("%s card detected\n", ((dev_priv->flags & CHIP_IS_AGP) ? "AGP" : "PCI"));
 	pci_write_config_dword(dev->pdev, RADEON_AGP_COMMAND_PCI_CONFIG, save);
+	
+	/* Check if we need a reset */
+	if (!(dev_priv->mmio = drm_core_findmap(dev , pci_resource_start( dev->pdev, 2 ))))
+		return DRM_ERR(ENOMEM);
 
-        return 0;
+	memmode = RADEON_READ(RADEON_MEM_SDRAM_MODE_REG);
+	DRM_DEBUG("Memmode is %x, if zero needs reset\n", memmode);
+	dev->need_reset = (memmode == 0);
+	
+#if defined(__linux__)
+	ret = radeon_create_i2c_busses(dev);
+#endif
+        return ret;
 }
 
 int radeon_postinit( struct drm_device *dev, unsigned long flags )
@@ -1772,6 +1790,10 @@ int radeon_postcleanup( struct drm_device *dev )
 {
 	drm_radeon_private_t *dev_priv = dev->dev_private;
 	
+	DRM_DEBUG("\n");
+#if defined(__linux__)
+	radeon_delete_i2c_busses(dev);
+#endif
 	DRM(free)( dev_priv, sizeof(*dev_priv), DRM_MEM_DRIVER );
 
 	dev->dev_private = NULL;
diff --git a/shared-core/radeon_drv.h b/shared-core/radeon_drv.h
index d3c65a00..ec3560aa 100644
--- a/shared-core/radeon_drv.h
+++ b/shared-core/radeon_drv.h
@@ -47,6 +47,10 @@ enum radeon_family {
 	CHIP_LAST,
 };
 
+#if defined(__linux__)
+#include "radeon_gpl.h"
+#endif
+
 /*
  * Chip flags
  */
@@ -102,8 +106,6 @@ struct mem_block {
 
 typedef struct drm_radeon_private {
 
-	uint32_t flags;		/* see radeon_chip_flags */
-
 	drm_radeon_ring_buffer_t ring;
 	drm_radeon_sarea_t *sarea_priv;
 
@@ -180,6 +182,11 @@ typedef struct drm_radeon_private {
    	wait_queue_head_t swi_queue;
    	atomic_t swi_emitted;
 
+	/* starting from here on, data is preserved accross an open */
+	uint32_t flags;		/* see radeon_chip_flags */
+#if defined(__linux__)
+	struct radeon_i2c_chan 	i2c[4];
+#endif
 } drm_radeon_private_t;
 
 typedef struct drm_radeon_buf_priv {
diff --git a/shared/radeon_cp.c b/shared/radeon_cp.c
index c5ff768a..27a1beb0 100644
--- a/shared/radeon_cp.c
+++ b/shared/radeon_cp.c
@@ -36,7 +36,6 @@
 
 #define RADEON_FIFO_DEBUG	0
 
-
 /* CP microcode (from ATI) */
 static u32 R200_cp_microcode[][2] = {
 	{ 0x21007000, 0000000000 },        
@@ -1285,12 +1284,8 @@ int radeon_do_cleanup_cp( drm_device_t *dev )
 					       dev_priv->bus_pci_gart ))
 			DRM_ERROR( "failed to cleanup PCI GART!\n" );
 	}
-	
-	{
-		int flags = dev_priv->flags;
-		memset(dev_priv, 0, sizeof(*dev_priv));
-		dev_priv->flags = flags;
-	}
+	/* only clear to the start of flags */
+	memset(dev_priv, 0, offsetof(drm_radeon_private_t, flags));
 
 	return 0;
 }
@@ -1735,8 +1730,9 @@ int radeon_cp_buffers( DRM_IOCTL_ARGS )
 /* Always create a map record for MMIO and FB memory, done from DRIVER_POSTINIT */
 int radeon_preinit( struct drm_device *dev, unsigned long flags )
 {
-	u32 save, temp;
+	u32 save, temp, memmode;
 	drm_radeon_private_t *dev_priv;
+	int ret = 0;
 
 	dev_priv = DRM(alloc)( sizeof(drm_radeon_private_t), DRM_MEM_DRIVER );
 	if ( dev_priv == NULL )
@@ -1746,6 +1742,17 @@ int radeon_preinit( struct drm_device *dev, unsigned long flags )
 	dev->dev_private = (void *)dev_priv;
 	dev_priv->flags = flags;
 
+	/* registers */
+	/* PCI space is twice the real size, so that you can have a RW and RO mapping */
+	if( (ret = DRM(initmap)( dev, pci_resource_start( dev->pdev, 2 ),
+			pci_resource_len( dev->pdev, 2 ) / 2, _DRM_REGISTERS, 0 )))
+		return ret;
+
+	/* framebuffer */
+	if( (ret = DRM(initmap)( dev, pci_resource_start( dev->pdev, 0 ),
+			pci_resource_len( dev->pdev, 0 ), _DRM_FRAME_BUFFER, _DRM_WRITE_COMBINING )))
+		return ret;
+
 	/* There are signatures in BIOS and PCI-SSID for a PCI card, but they are not very reliable.
 		Following detection method works for all cards tested so far.
 		Note, checking AGP_ENABLE bit after drmAgpEnable call can also give the correct result.
@@ -1759,8 +1766,19 @@ int radeon_preinit( struct drm_device *dev, unsigned long flags )
 		dev_priv->flags |= CHIP_IS_AGP;
 	DRM_DEBUG("%s card detected\n", ((dev_priv->flags & CHIP_IS_AGP) ? "AGP" : "PCI"));
 	pci_write_config_dword(dev->pdev, RADEON_AGP_COMMAND_PCI_CONFIG, save);
+	
+	/* Check if we need a reset */
+	if (!(dev_priv->mmio = drm_core_findmap(dev , pci_resource_start( dev->pdev, 2 ))))
+		return DRM_ERR(ENOMEM);
 
-        return 0;
+	memmode = RADEON_READ(RADEON_MEM_SDRAM_MODE_REG);
+	DRM_DEBUG("Memmode is %x, if zero needs reset\n", memmode);
+	dev->need_reset = (memmode == 0);
+	
+#if defined(__linux__)
+	ret = radeon_create_i2c_busses(dev);
+#endif
+        return ret;
 }
 
 int radeon_postinit( struct drm_device *dev, unsigned long flags )
@@ -1772,6 +1790,10 @@ int radeon_postcleanup( struct drm_device *dev )
 {
 	drm_radeon_private_t *dev_priv = dev->dev_private;
 	
+	DRM_DEBUG("\n");
+#if defined(__linux__)
+	radeon_delete_i2c_busses(dev);
+#endif
 	DRM(free)( dev_priv, sizeof(*dev_priv), DRM_MEM_DRIVER );
 
 	dev->dev_private = NULL;
diff --git a/shared/radeon_drv.h b/shared/radeon_drv.h
index d3c65a00..ec3560aa 100644
--- a/shared/radeon_drv.h
+++ b/shared/radeon_drv.h
@@ -47,6 +47,10 @@ enum radeon_family {
 	CHIP_LAST,
 };
 
+#if defined(__linux__)
+#include "radeon_gpl.h"
+#endif
+
 /*
  * Chip flags
  */
@@ -102,8 +106,6 @@ struct mem_block {
 
 typedef struct drm_radeon_private {
 
-	uint32_t flags;		/* see radeon_chip_flags */
-
 	drm_radeon_ring_buffer_t ring;
 	drm_radeon_sarea_t *sarea_priv;
 
@@ -180,6 +182,11 @@ typedef struct drm_radeon_private {
    	wait_queue_head_t swi_queue;
    	atomic_t swi_emitted;
 
+	/* starting from here on, data is preserved accross an open */
+	uint32_t flags;		/* see radeon_chip_flags */
+#if defined(__linux__)
+	struct radeon_i2c_chan 	i2c[4];
+#endif
 } drm_radeon_private_t;
 
 typedef struct drm_radeon_buf_priv {
-- 
cgit v1.2.3