[RFC 21/21] DRM: Add VIA drm driver
James Simmons
jsimmons at infradead.org
Sat Jun 8 09:57:24 PDT 2013
commit f4101ca539b83c824747d657bbdc28834276fea8
Author: James Simmons <jsimmons at infradead.org>
Date: Sat Jun 8 12:28:13 2013 -0400
via: Piece all the TTM/KMS changes together.
This updates the core VIA drm driver to support KMS/TTM/GEM. This includes
setting up the graphics cards resources and enabling the dumb scanout api.
Signed-Off-by: James Simmons <jsimmons at infradead.org>
diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig
index b16c50e..b773b42 100644
--- a/drivers/gpu/drm/Kconfig
+++ b/drivers/gpu/drm/Kconfig
@@ -188,6 +188,11 @@ config DRM_SIS
config DRM_VIA
tristate "Via unichrome video cards"
depends on DRM && PCI
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ select DRM_KMS_HELPER
+ select DRM_TTM
help
Choose this option if you have a Via unichrome or compatible video
chipset. If M is selected the module will be called via.
diff --git a/drivers/gpu/drm/via/Makefile b/drivers/gpu/drm/via/Makefile
index b537e4b..a0479bb 100644
--- a/drivers/gpu/drm/via/Makefile
+++ b/drivers/gpu/drm/via/Makefile
@@ -3,6 +3,10 @@
# Direct Rendering Infrastructure (DRI) in XFree86 4.1.0 and higher.
ccflags-y := -Iinclude/drm
-via-y := via_irq.o via_drv.o via_map.o via_mm.o via_h1_cmdbuf.o via_verifier.o via_video.o via_h1_dma.o
+via-y := via_drv.o via_pm.o via_i2c.o via_irq.o via_verifier.o via_ioc32.o \
+ init_ttm.o ttm_gem.o via_ttm.o via_fence.o via_sgdma.o \
+ via_h1_dma.o via_h1_cmdbuf.o \
+ via_display.o via_crtc.o via_fb.o crtc_hw.o via_clocks.o \
+ via_analog.o via_lvds.o via_tmds.o via_hdmi.o
-obj-$(CONFIG_DRM_VIA) +=via.o
+obj-$(CONFIG_DRM_VIA) += via.o
diff --git a/drivers/gpu/drm/via/via_drv.c b/drivers/gpu/drm/via/via_drv.c
index f4ae203..2a8592b 100644
--- a/drivers/gpu/drm/via/via_drv.c
+++ b/drivers/gpu/drm/via/via_drv.c
@@ -16,72 +16,436 @@
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
- * VIA, S3 GRAPHICS, AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * THE AUTHOR(S) OR COPYRIGHT HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
-
#include <linux/module.h>
#include <drm/drmP.h>
#include <drm/via_drm.h>
+#include <drm/drm_pciids.h>
+
#include "via_drv.h"
-#include <drm/drm_pciids.h>
+int via_modeset = 0;
+
+MODULE_PARM_DESC(modeset, "Disable/Enable modesetting");
+module_param_named(modeset, via_modeset, int, 0400);
+
+int via_hdmi_audio = 0;
+
+MODULE_PARM_DESC(audio, "HDMI Audio enable (1 = enable)");
+module_param_named(audio, via_hdmi_audio, int, 0444);
-static int via_driver_open(struct drm_device *dev, struct drm_file *file)
+static struct pci_device_id via_pci_table[] = {
+ viadrv_PCI_IDS,
+};
+MODULE_DEVICE_TABLE(pci, via_pci_table);
+
+#define SGDMA_MEMORY (256*1024)
+#define VQ_MEMORY (256*1024)
+
+#if __OS_HAS_AGP
+
+#define VIA_AGP_MODE_MASK 0x17
+#define VIA_AGPV3_MODE 0x08
+#define VIA_AGPV3_8X_MODE 0x02
+#define VIA_AGPV3_4X_MODE 0x01
+#define VIA_AGP_4X_MODE 0x04
+#define VIA_AGP_2X_MODE 0x02
+#define VIA_AGP_1X_MODE 0x01
+#define VIA_AGP_FW_MODE 0x10
+
+static int
+via_detect_agp(struct drm_device *dev)
{
- struct via_file_private *file_priv;
+ struct drm_via_private *dev_priv = dev->dev_private;
+ struct drm_agp_info agp_info;
+ struct drm_agp_mode mode;
+ int ret = 0;
- DRM_DEBUG_DRIVER("\n");
- file_priv = kmalloc(sizeof(*file_priv), GFP_KERNEL);
- if (!file_priv)
- return -ENOMEM;
+ ret = drm_agp_acquire(dev);
+ if (ret) {
+ DRM_ERROR("Failed acquiring AGP device.\n");
+ return ret;
+ }
+
+ ret = drm_agp_info(dev, &agp_info);
+ if (ret) {
+ DRM_ERROR("Failed detecting AGP aperture size.\n");
+ goto out_err0;
+ }
+
+ mode.mode = agp_info.mode & ~VIA_AGP_MODE_MASK;
+ if (mode.mode & VIA_AGPV3_MODE)
+ mode.mode |= VIA_AGPV3_8X_MODE;
+ else
+ mode.mode |= VIA_AGP_4X_MODE;
+
+ mode.mode |= VIA_AGP_FW_MODE;
+ ret = drm_agp_enable(dev, mode);
+ if (ret) {
+ DRM_ERROR("Failed to enable the AGP bus.\n");
+ goto out_err0;
+ }
+
+ ret = ttm_bo_init_mm(&dev_priv->bdev, TTM_PL_TT, agp_info.aperture_size >> PAGE_SHIFT);
+ if (!ret) {
+ DRM_INFO("Detected %lu MB of AGP Aperture at "
+ "physical address 0x%08lx.\n",
+ agp_info.aperture_size >> 20,
+ agp_info.aperture_base);
+ } else {
+out_err0:
+ drm_agp_release(dev);
+ }
+ return ret;
+}
+
+static void via_agp_engine_init(struct drm_via_private *dev_priv)
+{
+ VIA_WRITE(VIA_REG_TRANSET, 0x00100000);
+ VIA_WRITE(VIA_REG_TRANSPACE, 0x00000000);
+ VIA_WRITE(VIA_REG_TRANSPACE, 0x00333004);
+ VIA_WRITE(VIA_REG_TRANSPACE, 0x60000000);
+ VIA_WRITE(VIA_REG_TRANSPACE, 0x61000000);
+ VIA_WRITE(VIA_REG_TRANSPACE, 0x62000000);
+ VIA_WRITE(VIA_REG_TRANSPACE, 0x63000000);
+ VIA_WRITE(VIA_REG_TRANSPACE, 0x64000000);
+ VIA_WRITE(VIA_REG_TRANSPACE, 0x7D000000);
+
+ VIA_WRITE(VIA_REG_TRANSET, 0xfe020000);
+ VIA_WRITE(VIA_REG_TRANSPACE, 0x00000000);
+}
+#endif
+
+static int
+via_mmio_setup(struct drm_device *dev)
+{
+ struct drm_via_private *dev_priv = dev->dev_private;
+ int ret, len = pci_resource_len(dev->pdev, 1);
+ void __iomem *regs = ioport_map(0x3c0, 100);
+ struct ttm_buffer_object *bo;
+ u8 val;
+
+ val = ioread8(regs + 0x03);
+ iowrite8(val | 0x1, regs + 0x03);
+ val = ioread8(regs + 0x0C);
+ iowrite8(val | 0x1, regs + 0x02);
+
+ /* Unlock Extended IO Space */
+ iowrite8(0x10, regs + 0x04);
+ iowrite8(0x01, regs + 0x05);
+ /* Unlock CRTC register protect */
+ iowrite8(0x47, regs + 0x14);
- file->driver_priv = file_priv;
+ /* Enable MMIO */
+ iowrite8(0x1a, regs + 0x04);
+ val = ioread8(regs + 0x05);
+ iowrite8(val | 0x38, regs + 0x05);
- INIT_LIST_HEAD(&file_priv->obj_list);
+ ret = ttm_bo_init_mm(&dev_priv->bdev, TTM_PL_PRIV0,
+ len >> PAGE_SHIFT);
+ if (ret)
+ return ret;
+ ret = ttm_bo_allocate(&dev_priv->bdev, VIA_MMIO_REGSIZE, ttm_bo_type_kernel,
+ TTM_PL_FLAG_PRIV0, 1, PAGE_SIZE, false, NULL,
+ NULL, &bo);
+ if (ret)
+ goto err;
+
+ ret = ttm_bo_pin(bo, &dev_priv->mmio);
+err:
+ if (!ret)
+ DRM_INFO("Detected MMIO at physical address 0x%08llx.\n",
+ (unsigned long long) pci_resource_start(dev->pdev, 1));
+ else
+ ttm_bo_clean_mm(&dev_priv->bdev, TTM_PL_PRIV0);
+ return ret;
+}
+
+static void
+chip_revision_info(struct drm_device *dev)
+{
+ struct drm_via_private *dev_priv = dev->dev_private;
+ u8 tmp;
+
+ switch (dev->pci_device) {
+ /* Check revision of CLE266 Chip */
+ case PCI_DEVICE_ID_VIA_CLE266:
+ /* CR4F only define in CLE266.CX chip */
+ tmp = vga_rcrt(VGABASE, 0x4F);
+ vga_wcrt(VGABASE, 0x4F, 0x55);
+ if (vga_rcrt(VGABASE, 0x4F) != 0x55)
+ dev_priv->revision = CLE266_REVISION_AX;
+ else
+ dev_priv->revision = CLE266_REVISION_CX;
+ /* restore orignal CR4F value */
+ vga_wcrt(VGABASE, 0x4F, tmp);
+ break;
+
+ case PCI_DEVICE_ID_VIA_VT3157:
+ tmp = vga_rseq(VGABASE, 0x43);
+ if (tmp & 0x02) {
+ dev_priv->revision = CX700_REVISION_700M2;
+ } else if (tmp & 0x40) {
+ dev_priv->revision = CX700_REVISION_700M;
+ } else {
+ dev_priv->revision = CX700_REVISION_700;
+ }
+ break;
+
+ case PCI_DEVICE_ID_VIA_VT1122:
+ case PCI_DEVICE_ID_VIA_VX875:
+ case PCI_DEVICE_ID_VIA_VX900:
+ dev_priv->revision = vga_rseq(VGABASE, 0x3B);
+ break;
+
+ default:
+ break;
+ }
+}
+
+static int via_dumb_create(struct drm_file *filp, struct drm_device *dev,
+ struct drm_mode_create_dumb *args)
+{
+ struct drm_via_private *dev_priv = dev->dev_private;
+ struct drm_gem_object *obj;
+ int ret;
+
+ args->pitch = round_up(args->width * (args->bpp >> 3), 16);
+ args->size = args->pitch * args->height;
+ obj = ttm_gem_create(dev, &dev_priv->bdev, TTM_PL_FLAG_VRAM,
+ false, 16, PAGE_SIZE, args->size);
+ if (IS_ERR(obj))
+ return PTR_ERR(obj);
+
+ ret = drm_gem_handle_create(filp, obj, &args->handle);
+ /* drop reference from allocate - handle holds it now */
+ drm_gem_object_unreference_unlocked(obj);
+ return ret;
+}
+
+static int via_dumb_mmap(struct drm_file *filp, struct drm_device *dev,
+ uint32_t handle, uint64_t *offset_p)
+{
+ struct ttm_buffer_object *bo;
+ struct drm_gem_object *obj;
+
+ obj = drm_gem_object_lookup(dev, filp, handle);
+ if (!obj || !obj->driver_private)
+ return -ENOENT;
+
+ bo = obj->driver_private;
+ *offset_p = bo->addr_space_offset;
+ drm_gem_object_unreference_unlocked(obj);
return 0;
}
-void via_driver_postclose(struct drm_device *dev, struct drm_file *file)
+static int gem_dumb_destroy(struct drm_file *filp, struct drm_device *dev,
+ uint32_t handle)
+{
+ return drm_gem_handle_delete(filp, handle);
+}
+
+static int via_driver_unload(struct drm_device *dev)
{
- struct via_file_private *file_priv = file->driver_priv;
+ struct drm_via_private *dev_priv = dev->dev_private;
+ struct ttm_buffer_object *bo;
+ int ret = 0;
+
+ ret = via_dma_cleanup(dev);
+ if (ret)
+ return ret;
+
+ drm_irq_uninstall(dev);
+
+ if (drm_core_check_feature(dev, DRIVER_MODESET))
+ via_modeset_fini(dev);
+
+ via_fence_pool_fini(dev_priv->dma_fences);
+
+ drm_vblank_cleanup(dev);
+
+ /* destroy work queue. */
+ if (dev_priv->wq)
+ destroy_workqueue(dev_priv->wq);
- kfree(file_priv);
+ bo = dev_priv->vq.bo;
+ if (bo) {
+ ttm_bo_unpin(bo, &dev_priv->vq);
+ ttm_bo_unref(&bo);
+ }
+
+ bo = dev_priv->gart.bo;
+ if (bo) {
+ /* enable gtt write */
+ if (pci_is_pcie(dev->pdev))
+ svga_wseq_mask(VGABASE, 0x6C, 0, BIT(7));
+ ttm_bo_unpin(bo, &dev_priv->gart);
+ ttm_bo_unref(&bo);
+ }
+
+ bo = dev_priv->mmio.bo;
+ if (bo) {
+ ttm_bo_unpin(bo, &dev_priv->mmio);
+ ttm_bo_unref(&bo);
+ }
+
+ /* mtrr delete the vram */
+ if (drm_core_has_MTRR(dev) && (dev_priv->vram_mtrr >= 0))
+ arch_phys_wc_del(dev_priv->vram_mtrr);
+
+ ttm_global_fini(&dev_priv->mem_global_ref,
+ &dev_priv->bo_global_ref,
+ &dev_priv->bdev);
+
+#if __OS_HAS_AGP
+ if (dev->agp && dev->agp->acquired)
+ drm_agp_release(dev);
+#endif
+ kfree(dev_priv);
+ return ret;
}
-static struct pci_device_id pciidlist[] = {
- viadrv_PCI_IDS
-};
+static int
+via_driver_load(struct drm_device *dev, unsigned long chipset)
+{
+ struct drm_via_private *dev_priv;
+ int ret = 0;
+
+ dev_priv = kzalloc(sizeof(struct drm_via_private), GFP_KERNEL);
+ if (dev_priv == NULL)
+ return -ENOMEM;
+
+ dev->dev_private = (void *)dev_priv;
+ dev_priv->engine_type = chipset;
+ dev_priv->vram_mtrr = -ENXIO;
+ dev_priv->dev = dev;
+
+ via_init_command_verifier();
+
+ ret = via_ttm_init(dev_priv);
+ if (ret)
+ goto out_err;
+
+ ret = via_detect_vram(dev);
+ if (ret)
+ goto out_err;
+
+ ret = via_mmio_setup(dev);
+ if (ret) {
+ DRM_INFO("VIA MMIO region failed to map\n");
+ goto out_err;
+ }
+
+ chip_revision_info(dev);
+
+#if __OS_HAS_AGP
+ if ((dev_priv->engine_type > VIA_ENG_H2) ||
+ (dev->agp && drm_pci_device_is_agp(dev))) {
+ ret = via_detect_agp(dev);
+ if (!ret)
+ via_agp_engine_init(dev_priv);
+ else
+ DRM_ERROR("Failed to allocate AGP\n");
+ }
+#endif
+ if (pci_is_pcie(dev->pdev)) {
+ /* allocate the gart table */
+ ret = ttm_allocate_kernel_buffer(&dev_priv->bdev, SGDMA_MEMORY,
+ 16, TTM_PL_FLAG_VRAM,
+ &dev_priv->gart);
+ if (likely(!ret)) {
+ DRM_INFO("Allocated %u KB of DMA memory\n",
+ SGDMA_MEMORY >> 10);
+ } else
+ DRM_ERROR("Failed to allocate DMA memory\n");
+ }
+
+ /* allocate vq bo */
+ ret = ttm_allocate_kernel_buffer(&dev_priv->bdev, VQ_MEMORY, 16,
+ TTM_PL_FLAG_VRAM, &dev_priv->vq);
+ if (likely(!ret))
+ DRM_INFO("Allocated %u KB of memory for VQ\n", VQ_MEMORY >> 10);
+ else
+ DRM_ERROR("Failed to allocate VQ memory\n");
+
+ via_engine_init(dev);
+
+ /* setup workqueue */
+ dev_priv->wq = create_workqueue("viadrm");
+ if (dev_priv->wq == NULL) {
+ DRM_ERROR("create_workqueue failed !\n");
+ ret = -EINVAL;
+ goto out_err;
+ }
+
+ ret = drm_vblank_init(dev, 2);
+ if (ret)
+ goto out_err;
+
+ ret = via_dmablit_init(dev);
+ if (ret)
+ goto out_err;
+
+ if (drm_core_check_feature(dev, DRIVER_MODESET)) {
+ ret = via_modeset_init(dev);
+ if (ret)
+ goto out_err;
+ }
+
+ ret = drm_irq_install(dev);
+out_err:
+ if (ret)
+ via_driver_unload(dev);
+ return ret;
+}
+
+static int via_final_context(struct drm_device *dev, int context)
+{
+ /* Linux specific until context tracking code gets ported to BSD */
+ /* Last context, perform cleanup */
+ if (dev->ctx_count == 1 && dev->dev_private) {
+ DRM_DEBUG("Last Context\n");
+ drm_irq_uninstall(dev);
+ via_dma_cleanup(dev);
+ }
+ return 1;
+}
+
+static void via_reclaim_buffers_locked(struct drm_device *dev,
+ struct drm_file *filp)
+{
+ mutex_lock(&dev->struct_mutex);
+ via_driver_dma_quiescent(dev);
+ mutex_unlock(&dev->struct_mutex);
+ return;
+}
static const struct file_operations via_driver_fops = {
- .owner = THIS_MODULE,
- .open = drm_open,
- .release = drm_release,
+ .owner = THIS_MODULE,
+ .open = drm_open,
+ .release = drm_release,
.unlocked_ioctl = drm_ioctl,
- .mmap = drm_mmap,
- .poll = drm_poll,
- .fasync = drm_fasync,
-#ifdef CONFIG_COMPAT
- .compat_ioctl = drm_compat_ioctl,
-#endif
- .llseek = noop_llseek,
+ .mmap = ttm_mmap,
+ .poll = drm_poll,
+ .fasync = drm_fasync,
+ .llseek = noop_llseek,
};
-static struct drm_driver driver = {
+static struct drm_driver via_driver = {
.driver_features =
- DRIVER_USE_AGP | DRIVER_USE_MTRR | DRIVER_HAVE_IRQ |
- DRIVER_IRQ_SHARED,
+ DRIVER_USE_AGP | DRIVER_USE_MTRR | DRIVER_HAVE_IRQ |
+ DRIVER_GEM | DRIVER_IRQ_SHARED,
.load = via_driver_load,
.unload = via_driver_unload,
- .open = via_driver_open,
.preclose = via_reclaim_buffers_locked,
- .postclose = via_driver_postclose,
.context_dtor = via_final_context,
- .get_vblank_counter = via_get_vblank_counter,
+ .get_vblank_counter = drm_vblank_count,
.enable_vblank = via_enable_vblank,
.disable_vblank = via_disable_vblank,
.irq_preinstall = via_driver_irq_preinstall,
@@ -89,7 +453,11 @@ static struct drm_driver driver = {
.irq_uninstall = via_driver_irq_uninstall,
.irq_handler = via_driver_irq_handler,
.dma_quiescent = via_driver_dma_quiescent,
- .lastclose = via_lastclose,
+ .gem_init_object = ttm_gem_init_object,
+ .gem_free_object = ttm_gem_free_object,
+ .dumb_create = via_dumb_create,
+ .dumb_map_offset = via_dumb_mmap,
+ .dumb_destroy = gem_dumb_destroy,
.ioctls = via_ioctls,
.fops = &via_driver_fops,
.name = DRIVER_NAME,
@@ -100,21 +468,60 @@ static struct drm_driver driver = {
.patchlevel = DRIVER_PATCHLEVEL,
};
+static int
+via_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
+{
+ return drm_get_pci_dev(pdev, ent, &via_driver);
+}
+
+static void
+via_pci_remove(struct pci_dev *pdev)
+{
+ struct drm_device *dev = pci_get_drvdata(pdev);
+
+ drm_put_dev(dev);
+}
+
+#ifdef CONFIG_PM
+static int
+via_pci_suspend(struct pci_dev *pdev, pm_message_t state)
+{
+ return 0;
+}
+
+static int
+via_pci_resume(struct pci_dev *pdev)
+{
+ return 0;
+}
+#endif /* CONFIG_PM */
+
static struct pci_driver via_pci_driver = {
- .name = DRIVER_NAME,
- .id_table = pciidlist,
+ .name = DRIVER_NAME,
+ .id_table = via_pci_table,
};
static int __init via_init(void)
{
- driver.num_ioctls = via_max_ioctl;
- via_init_command_verifier();
- return drm_pci_init(&driver, &via_pci_driver);
+ via_driver.num_ioctls = via_max_ioctl;
+
+ if (via_modeset) {
+ via_pci_driver.probe = via_pci_probe;
+ via_pci_driver.remove = via_pci_remove;
+#ifdef CONFIG_PM
+ via_pci_driver.suspend = via_pci_suspend;
+ via_pci_driver.resume = via_pci_resume;
+#endif
+ via_driver.driver_features |= DRIVER_MODESET;
+ via_driver.major = 3;
+ via_driver.minor = 0;
+ }
+ return drm_pci_init(&via_driver, &via_pci_driver);
}
static void __exit via_exit(void)
{
- drm_pci_exit(&driver, &via_pci_driver);
+ drm_pci_exit(&via_driver, &via_pci_driver);
}
module_init(via_init);
diff --git a/drivers/gpu/drm/via/via_drv.h b/drivers/gpu/drm/via/via_drv.h
index 893a650..56c2237 100644
--- a/drivers/gpu/drm/via/via_drv.h
+++ b/drivers/gpu/drm/via/via_drv.h
@@ -16,7 +16,7 @@
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
- * VIA, S3 GRAPHICS, AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * THE AUTHOR(S) OR COPYRIGHT HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
@@ -24,29 +24,63 @@
#ifndef _VIA_DRV_H_
#define _VIA_DRV_H_
-#include <drm/drm_mm.h>
-#define DRIVER_AUTHOR "Various"
-
+#define DRIVER_AUTHOR "Various"
#define DRIVER_NAME "via"
#define DRIVER_DESC "VIA Unichrome / Pro"
-#define DRIVER_DATE "20070202"
+#define DRIVER_DATE "20110221"
+
+#define DRIVER_MAJOR 3
+#define DRIVER_MINOR 0
+#define DRIVER_PATCHLEVEL 0
+
+#include <linux/module.h>
-#define DRIVER_MAJOR 2
-#define DRIVER_MINOR 11
-#define DRIVER_PATCHLEVEL 1
+#include "ttm/ttm_bo_api.h"
+#include "ttm/ttm_bo_driver.h"
+#include "ttm/ttm_placement.h"
+#include "ttm/ttm_memory.h"
+#include "ttm/ttm_module.h"
+#include "ttm/ttm_page_alloc.h"
+#include <drm/drmP.h>
+#include <drm/via_drm.h>
+
+#include "via_regs.h"
+#include "via_fence.h"
+#include "via_dma.h"
#include "via_verifier.h"
+#include "via_display.h"
-#include "via_dmablit.h"
+#define VIA_MM_ALIGN_SIZE 16
#define VIA_PCI_BUF_SIZE 60000
#define VIA_FIRE_BUF_SIZE 1024
#define VIA_NUM_IRQS 4
-typedef struct drm_via_ring_buffer {
- drm_local_map_t map;
- char *virtual_start;
-} drm_via_ring_buffer_t;
+#define DRM_FILE_PAGE_OFFSET (0x100000000ULL >> PAGE_SHIFT)
+
+#define CLE266_REVISION_AX 0x0A
+#define CLE266_REVISION_CX 0x0C
+#define CX700_REVISION_700 0x0
+#define CX700_REVISION_700M 0x1
+#define CX700_REVISION_700M2 0x2
+
+/* For VT3353 */
+#define VX800_REVISION_A 0x0f
+#define VX800_REVISION_B0 0x10
+#define VX800_REVISION_B1 0x11
+#define VX800_REVISION_B2 0x12
+
+/* For VT3409 */
+#define VX855_REVISION_A0 0x00
+#define VX855_REVISION_A1 0x01
+#define VX855_REVISION_A2 0x02
+
+/* For VT3410 */
+#define VX900_REVISION_A0 0x00
+#define VX900_REVISION_A1 0x01
+#define VX900_REVISION_A2 0x02
+#define VX900_REVISION_A3 0x03
typedef uint32_t maskarray_t[5];
@@ -57,84 +91,162 @@ typedef struct drm_via_irq {
wait_queue_head_t irq_queue;
} drm_via_irq_t;
-typedef struct drm_via_private {
- drm_via_sarea_t *sarea_priv;
- drm_local_map_t *sarea;
- drm_local_map_t *fb;
- drm_local_map_t *mmio;
- unsigned long agpAddr;
- wait_queue_head_t decoder_queue[VIA_NR_XVMC_LOCKS];
- char *dma_ptr;
+struct sgdma_tt {
+ struct ttm_dma_tt sgdma;
+ unsigned long offset;
+};
+
+struct via_state {
+ struct vga_regset crt_regs[256];
+ struct vga_regset seq_regs[256];
+};
+
+enum via_engine {
+ VIA_ENG_H1 = 0,
+ VIA_ENG_H2,
+ VIA_ENG_H5S1,
+ VIA_ENG_H5S2VP1,
+ VIA_ENG_H6S2
+};
+
+struct drm_via_private {
+ struct drm_global_reference mem_global_ref;
+ struct ttm_bo_global_ref bo_global_ref;
+ struct ttm_bo_device bdev;
+ struct drm_device *dev;
+ int revision;
+
+ struct ttm_bo_kmap_obj dmabuf;
+ struct ttm_bo_kmap_obj mmio;
+ struct ttm_bo_kmap_obj gart;
+ struct ttm_bo_kmap_obj vq;
+
+ struct drm_fb_helper *helper;
+ int vram_mtrr;
+ u8 vram_type;
+
+ struct via_state pm_cache;
+
+ enum via_engine engine_type;
+ struct drm_via_state hc_state;
unsigned int dma_low;
unsigned int dma_high;
unsigned int dma_offset;
+ uint32_t dma_diff;
uint32_t dma_wrap;
- volatile uint32_t *last_pause_ptr;
- volatile uint32_t *hw_addr_ptr;
- drm_via_ring_buffer_t ring;
- struct timeval last_vblank;
- int last_vblank_valid;
- unsigned usec_per_vblank;
- atomic_t vbl_received;
- drm_via_state_t hc_state;
+ void __iomem *last_pause_ptr;
+ void __iomem *hw_addr_ptr;
+
char pci_buf[VIA_PCI_BUF_SIZE];
const uint32_t *fire_offsets[VIA_FIRE_BUF_SIZE];
uint32_t num_fire_offsets;
- int chipset;
+
drm_via_irq_t via_irqs[VIA_NUM_IRQS];
+ struct work_struct hotplug_work;
+ struct workqueue_struct *wq;
unsigned num_irqs;
maskarray_t *irq_masks;
uint32_t irq_enable_mask;
uint32_t irq_pending_mask;
int *irq_map;
- unsigned int idle_fault;
- int vram_initialized;
- struct drm_mm vram_mm;
- int agp_initialized;
- struct drm_mm agp_mm;
- /** Mapping of userspace keys to mm objects */
- struct idr object_idr;
- unsigned long vram_offset;
- unsigned long agp_offset;
- drm_via_blitq_t blit_queues[VIA_NUM_BLIT_ENGINES];
- uint32_t dma_diff;
-} drm_via_private_t;
-enum via_family {
- VIA_OTHER = 0, /* Baseline */
- VIA_PRO_GROUP_A, /* Another video engine and DMA commands */
- VIA_DX9_0 /* Same video as pro_group_a, but 3D is unsupported */
+ /* fence handling */
+ struct via_fence_pool *dma_fences;
+ int desc_size;
+
+ struct via_crtc iga[2];
+ bool spread_spectrum;
};
+#define VIA_MEM_NONE 0x00
+#define VIA_MEM_SDR66 0x01
+#define VIA_MEM_SDR100 0x02
+#define VIA_MEM_SDR133 0x03
+#define VIA_MEM_DDR_200 0x04
+#define VIA_MEM_DDR_266 0x05
+#define VIA_MEM_DDR_333 0x06
+#define VIA_MEM_DDR_400 0x07
+#define VIA_MEM_DDR2_400 0x08
+#define VIA_MEM_DDR2_533 0x09
+#define VIA_MEM_DDR2_667 0x0A
+#define VIA_MEM_DDR2_800 0x0B
+#define VIA_MEM_DDR2_1066 0x0C
+#define VIA_MEM_DDR3_533 0x0D
+#define VIA_MEM_DDR3_667 0x0E
+#define VIA_MEM_DDR3_800 0x0F
+#define VIA_MEM_DDR3_1066 0x10
+#define VIA_MEM_DDR3_1333 0x11
+#define VIA_MEM_DDR3_1600 0x12
+
/* VIA MMIO register access */
-#define VIA_BASE ((dev_priv->mmio))
+#define VIA_BASE ((dev_priv->mmio.virtual))
+
+#define VIA_READ(reg) ioread32(VIA_BASE + reg)
+#define VIA_WRITE(reg, val) iowrite32(val, VIA_BASE + reg)
+#define VIA_READ8(reg) ioread8(VIA_BASE + reg)
+#define VIA_WRITE8(reg, val) iowrite8(val, VIA_BASE + reg)
-#define VIA_READ(reg) DRM_READ32(VIA_BASE, reg)
-#define VIA_WRITE(reg, val) DRM_WRITE32(VIA_BASE, reg, val)
-#define VIA_READ8(reg) DRM_READ8(VIA_BASE, reg)
-#define VIA_WRITE8(reg, val) DRM_WRITE8(VIA_BASE, reg, val)
+#define VIA_WRITE_MASK(reg, data, mask) \
+ VIA_WRITE(reg, (data & mask) | (VIA_READ(reg) & ~mask)) \
+
+#define VGABASE (VIA_BASE+VIA_MMIO_VGABASE)
extern struct drm_ioctl_desc via_ioctls[];
extern int via_max_ioctl;
-extern int via_fb_init(struct drm_device *dev, void *data, struct drm_file *file_priv);
-extern int via_mem_alloc(struct drm_device *dev, void *data, struct drm_file *file_priv);
-extern int via_mem_free(struct drm_device *dev, void *data, struct drm_file *file_priv);
-extern int via_agp_init(struct drm_device *dev, void *data, struct drm_file *file_priv);
-extern int via_map_init(struct drm_device *dev, void *data, struct drm_file *file_priv);
-extern int via_decoder_futex(struct drm_device *dev, void *data, struct drm_file *file_priv);
+extern int via_hdmi_audio;
+
+extern void via_engine_init(struct drm_device *dev);
+
+extern int via_dma_init(struct drm_device *dev, void *data, struct drm_file *file_priv);
+extern int via_flush_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv);
+extern int via_dispatch_cmdbuffer(struct drm_device *dev, drm_via_cmdbuffer_t *cmd);
+extern int via_cmdbuffer(struct drm_device *dev, void *data, struct drm_file *file_priv);
+extern int via_cmdbuf_size(struct drm_device *dev, void *data, struct drm_file *file_priv);
+extern int via_pci_cmdbuffer(struct drm_device *dev, void *data, struct drm_file *file_priv);
extern int via_wait_irq(struct drm_device *dev, void *data, struct drm_file *file_priv);
-extern int via_dma_blit_sync(struct drm_device *dev, void *data, struct drm_file *file_priv);
-extern int via_dma_blit(struct drm_device *dev, void *data, struct drm_file *file_priv);
+extern int via_wait_idle(struct drm_via_private *dev_priv);
+
+extern int via_detect_vram(struct drm_device *dev);
+
+extern int via_ttm_init(struct drm_via_private *dev_priv);
+extern struct ttm_tt *via_sgdma_backend_init(struct ttm_bo_device *bdev, unsigned long size,
+ uint32_t page_flags, struct page *dummy_read_page);
+
+extern int ttm_global_init(struct drm_global_reference *global_ref,
+ struct ttm_bo_global_ref *global_bo,
+ struct ttm_bo_driver *driver,
+ struct ttm_bo_device *bdev,
+ bool dma32);
+extern void ttm_global_fini(struct drm_global_reference *global_ref,
+ struct ttm_bo_global_ref *global_bo,
+ struct ttm_bo_device *bdev);
-extern int via_driver_load(struct drm_device *dev, unsigned long chipset);
-extern int via_driver_unload(struct drm_device *dev);
+extern int ttm_bo_allocate(struct ttm_bo_device *bdev, unsigned long size,
+ enum ttm_bo_type origin, int types,
+ uint32_t byte_align, uint32_t page_align,
+ bool interruptible, struct sg_table *sg,
+ struct file *persistant_swap_storage,
+ struct ttm_buffer_object **p_bo);
+extern void ttm_placement_from_domain(struct ttm_buffer_object *bo,
+ struct ttm_placement *placement, u32 domains,
+ struct ttm_bo_device *bdev);
+extern int ttm_bo_unpin(struct ttm_buffer_object *bo, struct ttm_bo_kmap_obj *kmap);
+extern int ttm_bo_pin(struct ttm_buffer_object *bo, struct ttm_bo_kmap_obj *kmap);
+extern int ttm_allocate_kernel_buffer(struct ttm_bo_device *bdev, unsigned long size,
+ uint32_t alignment, uint32_t domain,
+ struct ttm_bo_kmap_obj *kmap);
-extern int via_init_context(struct drm_device *dev, int context);
-extern int via_final_context(struct drm_device *dev, int context);
+extern int ttm_mmap(struct file *filp, struct vm_area_struct *vma);
+
+extern int ttm_gem_init_object(struct drm_gem_object *obj);
+extern void ttm_gem_free_object(struct drm_gem_object *obj);
+extern struct drm_gem_object *ttm_gem_create(struct drm_device *dev,
+ struct ttm_bo_device *bdev, int type,
+ bool interruptible,
+ int byte_align, int page_align,
+ unsigned long size);
-extern int via_do_cleanup_map(struct drm_device *dev);
-extern u32 via_get_vblank_counter(struct drm_device *dev, int crtc);
extern int via_enable_vblank(struct drm_device *dev, int crtc);
extern void via_disable_vblank(struct drm_device *dev, int crtc);
@@ -143,18 +255,11 @@ extern void via_driver_irq_preinstall(struct drm_device *dev);
extern int via_driver_irq_postinstall(struct drm_device *dev);
extern void via_driver_irq_uninstall(struct drm_device *dev);
-extern int via_dma_cleanup(struct drm_device *dev);
extern void via_init_command_verifier(void);
extern int via_driver_dma_quiescent(struct drm_device *dev);
-extern void via_init_futex(drm_via_private_t *dev_priv);
-extern void via_cleanup_futex(drm_via_private_t *dev_priv);
-extern void via_release_futex(drm_via_private_t *dev_priv, int context);
-
-extern void via_reclaim_buffers_locked(struct drm_device *dev,
- struct drm_file *file_priv);
-extern void via_lastclose(struct drm_device *dev);
+extern int via_dma_cleanup(struct drm_device *dev);
extern void via_dmablit_handler(struct drm_device *dev, int engine, int from_irq);
-extern void via_init_dmablit(struct drm_device *dev);
+extern int via_dmablit_init(struct drm_device *dev);
#endif
More information about the dri-devel
mailing list