aboutsummaryrefslogtreecommitdiff
path: root/shared-core
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2008-01-25 15:27:53 +1000
committerDave Airlie <airlied@redhat.com>2008-01-25 15:27:53 +1000
commite7a41d7f5be49241480a20eb733262712e0f8dcb (patch)
tree801c7eadf769db981dfb8a900a24ef48542958a6 /shared-core
parentfb9ea12438de95a6ac085879e079055eaea3daf8 (diff)
parentbfdddd218ec3e7ce3f8e765b93af35661a7bf0fd (diff)
Merge remote branch 'origin/master' into modesetting-101
Conflicts: linux-core/drm_bo.c linux-core/drm_drv.c shared-core/drm.h shared-core/i915_dma.c shared-core/i915_drv.h shared-core/i915_irq.c shared-core/radeon_irq.c
Diffstat (limited to 'shared-core')
-rw-r--r--shared-core/drm.h76
-rw-r--r--shared-core/drm_pciids.txt98
-rw-r--r--shared-core/i915_dma.c152
-rw-r--r--shared-core/i915_drm.h10
-rw-r--r--shared-core/i915_drv.h72
-rw-r--r--shared-core/i915_irq.c326
-rw-r--r--shared-core/i915_mem.c8
-rw-r--r--shared-core/mach64_dma.c167
-rw-r--r--shared-core/mach64_drv.h210
-rw-r--r--shared-core/mach64_irq.c88
-rw-r--r--shared-core/mach64_state.c43
-rw-r--r--shared-core/mga_dma.c4
-rw-r--r--shared-core/mga_drv.h21
-rw-r--r--shared-core/mga_irq.c69
-rw-r--r--shared-core/mga_state.c14
-rw-r--r--shared-core/nouveau_drv.h2
-rw-r--r--shared-core/nouveau_irq.c4
-rw-r--r--shared-core/nouveau_mem.c2
-rw-r--r--shared-core/nouveau_reg.h3
-rw-r--r--shared-core/nouveau_state.c95
-rw-r--r--shared-core/nv04_graph.c2
-rw-r--r--shared-core/nv04_mc.c13
-rw-r--r--shared-core/nv20_graph.c18
-rw-r--r--shared-core/nv50_fifo.c92
-rw-r--r--shared-core/nv50_graph.c102
-rw-r--r--shared-core/nv50_instmem.c4
-rw-r--r--shared-core/r128_cce.c4
-rw-r--r--shared-core/r128_drv.h12
-rw-r--r--shared-core/r128_irq.c55
-rw-r--r--shared-core/r128_state.c43
-rw-r--r--shared-core/r300_cmdbuf.c39
-rw-r--r--shared-core/radeon_cp.c117
-rw-r--r--shared-core/radeon_drv.h48
-rw-r--r--shared-core/radeon_irq.c175
-rw-r--r--shared-core/radeon_mem.c6
-rw-r--r--shared-core/radeon_ms.h2
-rw-r--r--shared-core/radeon_ms_bo.c6
-rw-r--r--shared-core/radeon_ms_drm.c2
-rw-r--r--shared-core/radeon_state.c33
-rw-r--r--shared-core/via_dma.c20
-rw-r--r--shared-core/via_drv.c8
-rw-r--r--shared-core/via_drv.h9
-rw-r--r--shared-core/via_irq.c89
-rw-r--r--shared-core/via_map.c4
-rw-r--r--shared-core/via_video.c4
45 files changed, 1417 insertions, 954 deletions
diff --git a/shared-core/drm.h b/shared-core/drm.h
index f8d44048..7aea3033 100644
--- a/shared-core/drm.h
+++ b/shared-core/drm.h
@@ -555,6 +555,21 @@ union drm_wait_vblank {
struct drm_wait_vblank_reply reply;
};
+enum drm_modeset_ctl_cmd {
+ _DRM_PRE_MODESET = 1,
+ _DRM_POST_MODESET = 2,
+};
+
+/**
+ * DRM_IOCTL_MODESET_CTL ioctl argument type
+ *
+ * \sa drmModesetCtl().
+ */
+struct drm_modeset_ctl {
+ unsigned long arg;
+ enum drm_modeset_ctl_cmd cmd;
+};
+
/**
* DRM_IOCTL_AGP_ENABLE ioctl argument type.
*
@@ -662,6 +677,10 @@ struct drm_fence_arg {
#define DRM_BO_FLAG_EXE (1ULL << 2)
/*
+ * All of the bits related to access mode
+ */
+#define DRM_BO_MASK_ACCESS (DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE | DRM_BO_FLAG_EXE)
+/*
* Status flags. Can be read to determine the actual state of a buffer.
* Can also be set in the buffer mask before validation.
*/
@@ -701,7 +720,14 @@ struct drm_fence_arg {
*/
#define DRM_BO_FLAG_NO_MOVE (1ULL << 8)
-/* Mask: Make sure the buffer is in cached memory when mapped
+/* Mask: Make sure the buffer is in cached memory when mapped. In conjunction
+ * with DRM_BO_FLAG_CACHED it also allows the buffer to be bound into the GART
+ * with unsnooped PTEs instead of snooped, by using chipset-specific cache
+ * flushing at bind time. A better name might be DRM_BO_FLAG_TT_UNSNOOPED,
+ * as the eviction to local memory (TTM unbind) on map is just a side effect
+ * to prevent aggressive cache prefetch from the GPU disturbing the cache
+ * management that the DRM is doing.
+ *
* Flags: Acknowledge.
* Buffers allocated with this flag should not be used for suballocators
* This type may have issues on CPUs with over-aggressive caching
@@ -741,18 +767,49 @@ struct drm_fence_arg {
#define DRM_BO_FLAG_MEM_PRIV4 (1ULL << 31)
/* We can add more of these now with a 64-bit flag type */
-/* Memory flag mask */
+/*
+ * This is a mask covering all of the memory type flags; easier to just
+ * use a single constant than a bunch of | values. It covers
+ * DRM_BO_FLAG_MEM_LOCAL through DRM_BO_FLAG_MEM_PRIV4
+ */
#define DRM_BO_MASK_MEM 0x00000000FF000000ULL
-#define DRM_BO_MASK_MEMTYPE 0x00000000FF0800A0ULL
-
+/*
+ * This adds all of the CPU-mapping options in with the memory
+ * type to label all bits which change how the page gets mapped
+ */
+#define DRM_BO_MASK_MEMTYPE (DRM_BO_MASK_MEM | \
+ DRM_BO_FLAG_CACHED_MAPPED | \
+ DRM_BO_FLAG_CACHED | \
+ DRM_BO_FLAG_MAPPABLE)
+
/* Driver-private flags */
#define DRM_BO_MASK_DRIVER 0xFFFF000000000000ULL
-/* Don't block on validate and map */
+/*
+ * Don't block on validate and map. Instead, return EBUSY.
+ */
#define DRM_BO_HINT_DONT_BLOCK 0x00000002
-/* Don't place this buffer on the unfenced list.*/
+/*
+ * Don't place this buffer on the unfenced list. This means
+ * that the buffer will not end up having a fence associated
+ * with it as a result of this operation
+ */
#define DRM_BO_HINT_DONT_FENCE 0x00000004
+/*
+ * Sleep while waiting for the operation to complete.
+ * Without this flag, the kernel will, instead, spin
+ * until this operation has completed. I'm not sure
+ * why you would ever want this, so please always
+ * provide DRM_BO_HINT_WAIT_LAZY to any operation
+ * which may block
+ */
#define DRM_BO_HINT_WAIT_LAZY 0x00000008
+/*
+ * The client has compute relocations refering to this buffer using the
+ * offset in the presumed_offset field. If that offset ends up matching
+ * where this buffer lands, the kernel is free to skip executing those
+ * relocations
+ */
#define DRM_BO_HINT_PRESUMED_OFFSET 0x00000010
#define DRM_BO_INIT_MAGIC 0xfe769812
@@ -774,7 +831,7 @@ struct drm_bo_info_req {
};
struct drm_bo_create_req {
- uint64_t mask;
+ uint64_t flags;
uint64_t size;
uint64_t buffer_start;
unsigned int hint;
@@ -790,7 +847,7 @@ struct drm_bo_create_req {
struct drm_bo_info_rep {
uint64_t flags;
- uint64_t mask;
+ uint64_t proposed_flags;
uint64_t size;
uint64_t offset;
uint64_t arg_handle;
@@ -1046,6 +1103,7 @@ struct drm_mode_mode_cmd {
#define DRM_IOCTL_GET_CLIENT DRM_IOWR(0x05, struct drm_client)
#define DRM_IOCTL_GET_STATS DRM_IOR( 0x06, struct drm_stats)
#define DRM_IOCTL_SET_VERSION DRM_IOWR(0x07, struct drm_set_version)
+#define DRM_IOCTL_MODESET_CTL DRM_IOW(0x08, struct drm_modeset_ctl)
#define DRM_IOCTL_SET_UNIQUE DRM_IOW( 0x10, struct drm_unique)
#define DRM_IOCTL_AUTH_MAGIC DRM_IOW( 0x11, struct drm_auth)
@@ -1118,7 +1176,6 @@ struct drm_mode_mode_cmd {
#define DRM_IOCTL_BO_WAIT_IDLE DRM_IOWR(0xd5, struct drm_bo_map_wait_idle_arg)
#define DRM_IOCTL_BO_VERSION DRM_IOR(0xd6, struct drm_bo_version_arg)
-
#define DRM_IOCTL_MODE_GETRESOURCES DRM_IOWR(0xA0, struct drm_mode_card_res)
#define DRM_IOCTL_MODE_GETCRTC DRM_IOWR(0xA1, struct drm_mode_crtc)
#define DRM_IOCTL_MODE_GETOUTPUT DRM_IOWR(0xA2, struct drm_mode_get_output)
@@ -1133,6 +1190,7 @@ struct drm_mode_mode_cmd {
#define DRM_IOCTL_MODE_DETACHMODE DRM_IOWR(0xAA, struct drm_mode_mode_cmd)
#define DRM_IOCTL_MODE_GETPROPERTY DRM_IOWR(0xAB, struct drm_mode_get_property)
+
/*@}*/
/**
diff --git a/shared-core/drm_pciids.txt b/shared-core/drm_pciids.txt
index a76413d4..7ef34dfd 100644
--- a/shared-core/drm_pciids.txt
+++ b/shared-core/drm_pciids.txt
@@ -139,6 +139,101 @@
0x1002 0x5e4c CHIP_RV410|RADEON_NEW_MEMMAP "ATI Radeon RV410 X700 SE"
0x1002 0x5e4d CHIP_RV410|RADEON_NEW_MEMMAP "ATI Radeon RV410 X700"
0x1002 0x5e4f CHIP_RV410|RADEON_NEW_MEMMAP "ATI Radeon RV410 X700 SE"
+0x1002 0x7100 CHIP_R520|RADEON_NEW_MEMMAP "ATI Radeon X1800"
+0x1002 0x7101 CHIP_R520|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP "ATI Mobility Radeon X1800 XT"
+0x1002 0x7102 CHIP_R520|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP "ATI Mobility Radeon X1800"
+0x1002 0x7103 CHIP_R520|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP "ATI Mobility FireGL V7200"
+0x1002 0x7104 CHIP_R520|RADEON_NEW_MEMMAP "ATI FireGL V7200"
+0x1002 0x7105 CHIP_R520|RADEON_NEW_MEMMAP "ATI FireGL V5300"
+0x1002 0x7106 CHIP_R520|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP "ATI Mobility FireGL V7100"
+0x1002 0x7108 CHIP_R520|RADEON_NEW_MEMMAP "ATI Radeon X1800"
+0x1002 0x7109 CHIP_R520|RADEON_NEW_MEMMAP "ATI Radeon X1800"
+0x1002 0x710A CHIP_R520|RADEON_NEW_MEMMAP "ATI Radeon X1800"
+0x1002 0x710B CHIP_R520|RADEON_NEW_MEMMAP "ATI Radeon X1800"
+0x1002 0x710C CHIP_R520|RADEON_NEW_MEMMAP "ATI Radeon X1800"
+0x1002 0x710E CHIP_R520|RADEON_NEW_MEMMAP "ATI FireGL V7300"
+0x1002 0x710F CHIP_R520|RADEON_NEW_MEMMAP "ATI FireGL V7350"
+0x1002 0x7140 CHIP_RV515|RADEON_NEW_MEMMAP "ATI Radeon X1600"
+0x1002 0x7141 CHIP_RV515|RADEON_NEW_MEMMAP "ATI RV505"
+0x1002 0x7142 CHIP_RV515|RADEON_NEW_MEMMAP "ATI Radeon X1300/X1550"
+0x1002 0x7143 CHIP_RV515|RADEON_NEW_MEMMAP "ATI Radeon X1550"
+0x1002 0x7144 CHIP_RV515|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP "ATI M54-GL"
+0x1002 0x7145 CHIP_RV515|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP "ATI Mobility Radeon X1400"
+0x1002 0x7146 CHIP_RV515|RADEON_NEW_MEMMAP "ATI Radeon X1300/X1550"
+0x1002 0x7147 CHIP_RV515|RADEON_NEW_MEMMAP "ATI Radeon X1550 64-bit"
+0x1002 0x7149 CHIP_RV515|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP "ATI Mobility Radeon X1300"
+0x1002 0x714A CHIP_RV515|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP "ATI Mobility Radeon X1300"
+0x1002 0x714B CHIP_RV515|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP "ATI Mobility Radeon X1300"
+0x1002 0x714C CHIP_RV515|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP "ATI Mobility Radeon X1300"
+0x1002 0x714D CHIP_RV515|RADEON_NEW_MEMMAP "ATI Radeon X1300"
+0x1002 0x714E CHIP_RV515|RADEON_NEW_MEMMAP "ATI Radeon X1300"
+0x1002 0x714F CHIP_RV515|RADEON_NEW_MEMMAP "ATI RV505"
+0x1002 0x7151 CHIP_RV515|RADEON_NEW_MEMMAP "ATI RV505"
+0x1002 0x7152 CHIP_RV515|RADEON_NEW_MEMMAP "ATI FireGL V3300"
+0x1002 0x7153 CHIP_RV515|RADEON_NEW_MEMMAP "ATI FireGL V3350"
+0x1002 0x715E CHIP_RV515|RADEON_NEW_MEMMAP "ATI Radeon X1300"
+0x1002 0x715F CHIP_RV515|RADEON_NEW_MEMMAP "ATI Radeon X1550 64-bit"
+0x1002 0x7180 CHIP_RV515|RADEON_NEW_MEMMAP "ATI Radeon X1300/X1550"
+0x1002 0x7181 CHIP_RV515|RADEON_NEW_MEMMAP "ATI Radeon X1600"
+0x1002 0x7183 CHIP_RV515|RADEON_NEW_MEMMAP "ATI Radeon X1300/X1550"
+0x1002 0x7186 CHIP_RV515|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP "ATI Mobility Radeon X1450"
+0x1002 0x7187 CHIP_RV515|RADEON_NEW_MEMMAP "ATI Radeon X1300/X1550"
+0x1002 0x7188 CHIP_RV515|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP "ATI Mobility Radeon X2300"
+0x1002 0x718A CHIP_RV515|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP "ATI Mobility Radeon X2300"
+0x1002 0x718B CHIP_RV515|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP "ATI Mobility Radeon X1350"
+0x1002 0x718C CHIP_RV515|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP "ATI Mobility Radeon X1350"
+0x1002 0x718D CHIP_RV515|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP "ATI Mobility Radeon X1450"
+0x1002 0x718F CHIP_RV515|RADEON_NEW_MEMMAP "ATI Radeon X1300"
+0x1002 0x7193 CHIP_RV515|RADEON_NEW_MEMMAP "ATI Radeon X1550"
+0x1002 0x7196 CHIP_RV515|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP "ATI Mobility Radeon X1350"
+0x1002 0x719B CHIP_RV515|RADEON_NEW_MEMMAP "ATI FireMV 2250"
+0x1002 0x719F CHIP_RV515|RADEON_NEW_MEMMAP "ATI Radeon X1550 64-bit"
+0x1002 0x71C0 CHIP_RV530|RADEON_NEW_MEMMAP "ATI Radeon X1600"
+0x1002 0x71C1 CHIP_RV530|RADEON_NEW_MEMMAP "ATI Radeon X1650"
+0x1002 0x71C2 CHIP_RV530|RADEON_NEW_MEMMAP "ATI Radeon X1600"
+0x1002 0x71C3 CHIP_RV530|RADEON_NEW_MEMMAP "ATI Radeon X1600"
+0x1002 0x71C4 CHIP_RV530|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP "ATI Mobility FireGL V5200"
+0x1002 0x71C5 CHIP_RV530|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP "ATI Mobility Radeon X1600"
+0x1002 0x71C6 CHIP_RV530|RADEON_NEW_MEMMAP "ATI Radeon X1650"
+0x1002 0x71C7 CHIP_RV530|RADEON_NEW_MEMMAP "ATI Radeon X1650"
+0x1002 0x71CD CHIP_RV530|RADEON_NEW_MEMMAP "ATI Radeon X1600"
+0x1002 0x71CE CHIP_RV530|RADEON_NEW_MEMMAP "ATI Radeon X1300 XT/X1600 Pro"
+0x1002 0x71D2 CHIP_RV530|RADEON_NEW_MEMMAP "ATI FireGL V3400"
+0x1002 0x71D4 CHIP_RV530|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP "ATI Mobility FireGL V5250"
+0x1002 0x71D5 CHIP_RV530|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP "ATI Mobility Radeon X1700"
+0x1002 0x71D6 CHIP_RV530|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP "ATI Mobility Radeon X1700 XT"
+0x1002 0x71DA CHIP_RV530|RADEON_NEW_MEMMAP "ATI FireGL V5200"
+0x1002 0x71DE CHIP_RV530|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP "ATI Mobility Radeon X1700"
+0x1002 0x7200 CHIP_RV530|RADEON_NEW_MEMMAP "ATI Radeon X2300HD"
+0x1002 0x7210 CHIP_RV530|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP "ATI Mobility Radeon HD 2300"
+0x1002 0x7211 CHIP_RV530|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP "ATI Mobility Radeon HD 2300"
+0x1002 0x7240 CHIP_R580|RADEON_NEW_MEMMAP "ATI Radeon X1950"
+0x1002 0x7243 CHIP_R580|RADEON_NEW_MEMMAP "ATI Radeon X1900"
+0x1002 0x7244 CHIP_R580|RADEON_NEW_MEMMAP "ATI Radeon X1950"
+0x1002 0x7245 CHIP_R580|RADEON_NEW_MEMMAP "ATI Radeon X1900"
+0x1002 0x7246 CHIP_R580|RADEON_NEW_MEMMAP "ATI Radeon X1900"
+0x1002 0x7247 CHIP_R580|RADEON_NEW_MEMMAP "ATI Radeon X1900"
+0x1002 0x7248 CHIP_R580|RADEON_NEW_MEMMAP "ATI Radeon X1900"
+0x1002 0x7249 CHIP_R580|RADEON_NEW_MEMMAP "ATI Radeon X1900"
+0x1002 0x724A CHIP_R580|RADEON_NEW_MEMMAP "ATI Radeon X1900"
+0x1002 0x724B CHIP_R580|RADEON_NEW_MEMMAP "ATI Radeon X1900"
+0x1002 0x724C CHIP_R580|RADEON_NEW_MEMMAP "ATI Radeon X1900"
+0x1002 0x724D CHIP_R580|RADEON_NEW_MEMMAP "ATI Radeon X1900"
+0x1002 0x724E CHIP_R580|RADEON_NEW_MEMMAP "ATI AMD Stream Processor"
+0x1002 0x724F CHIP_R580|RADEON_NEW_MEMMAP "ATI Radeon X1900"
+0x1002 0x7280 CHIP_RV570|RADEON_NEW_MEMMAP "ATI Radeon X1950"
+0x1002 0x7281 CHIP_RV560|RADEON_NEW_MEMMAP "ATI RV560"
+0x1002 0x7283 CHIP_RV560|RADEON_NEW_MEMMAP "ATI RV560"
+0x1002 0x7284 CHIP_R580|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP "ATI Mobility Radeon X1900"
+0x1002 0x7287 CHIP_RV560|RADEON_NEW_MEMMAP "ATI RV560"
+0x1002 0x7288 CHIP_RV570|RADEON_NEW_MEMMAP "ATI Radeon X1950 GT"
+0x1002 0x7289 CHIP_RV570|RADEON_NEW_MEMMAP "ATI RV570"
+0x1002 0x728B CHIP_RV570|RADEON_NEW_MEMMAP "ATI RV570"
+0x1002 0x728C CHIP_RV570|RADEON_NEW_MEMMAP "ATI ATI FireGL V7400"
+0x1002 0x7290 CHIP_RV560|RADEON_NEW_MEMMAP "ATI RV560"
+0x1002 0x7291 CHIP_RV560|RADEON_NEW_MEMMAP "ATI Radeon X1650"
+0x1002 0x7293 CHIP_RV560|RADEON_NEW_MEMMAP "ATI Radeon X1650"
+0x1002 0x7297 CHIP_RV560|RADEON_NEW_MEMMAP "ATI RV560"
0x1002 0x7834 CHIP_RS300|RADEON_IS_IGP|RADEON_NEW_MEMMAP "ATI Radeon RS350 9000/9100 IGP"
0x1002 0x7835 CHIP_RS300|RADEON_IS_IGP|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP "ATI Radeon RS350 Mobility IGP"
@@ -236,6 +331,7 @@
0x1106 0x3343 0 "VIA P4M890"
0x1106 0x3230 VIA_DX9_0 "VIA K8M890"
0x1106 0x3157 VIA_PRO_GROUP_A "VIA CX700"
+0x1106 0x3371 VIA_DX9_0 "VIA P4M900 / VN896"
[i810]
0x8086 0x7121 0 "Intel i810 GMCH"
@@ -285,6 +381,7 @@
0x8086 0x3582 CHIP_I8XX "Intel i852GM/i855GM GMCH"
0x8086 0x2572 CHIP_I8XX "Intel i865G GMCH"
0x8086 0x2582 CHIP_I9XX|CHIP_I915 "Intel i915G"
+0x8086 0x258a CHIP_I9XX|CHIP_I915 "Intel E7221 (i915)"
0x8086 0x2592 CHIP_I9XX|CHIP_I915 "Intel i915GM"
0x8086 0x2772 CHIP_I9XX|CHIP_I915 "Intel i945G"
0x8086 0x27A2 CHIP_I9XX|CHIP_I915 "Intel i945GM"
@@ -298,6 +395,7 @@
0x8086 0x29C2 CHIP_I9XX|CHIP_I915 "Intel G33"
0x8086 0x29B2 CHIP_I9XX|CHIP_I915 "Intel Q35"
0x8086 0x29D2 CHIP_I9XX|CHIP_I915 "Intel Q33"
+0x8086 0x2A42 CHIP_I9XX|CHIP_I965 "Intel Integrated Graphics Device"
[imagine]
0x105d 0x2309 IMAGINE_128 "Imagine 128"
diff --git a/shared-core/i915_dma.c b/shared-core/i915_dma.c
index 4c1a07ac..66d1b13d 100644
--- a/shared-core/i915_dma.c
+++ b/shared-core/i915_dma.c
@@ -718,9 +718,15 @@ int i915_apply_reloc(struct drm_file *file_priv, int num_buffers,
unsigned index;
unsigned long new_cmd_offset;
u32 val;
- int ret;
+ int ret, i;
+ int buf_index = -1;
+
+ for (i = 0; i <= num_buffers; i++)
+ if (buffers[i].buffer)
+ if (reloc[2] == buffers[i].buffer->base.hash.key)
+ buf_index = i;
- if (reloc[2] >= num_buffers) {
+ if (buf_index == -1) {
DRM_ERROR("Illegal relocation buffer %08X\n", reloc[2]);
return -EINVAL;
}
@@ -729,7 +735,7 @@ int i915_apply_reloc(struct drm_file *file_priv, int num_buffers,
* Short-circuit relocations that were correctly
* guessed by the client
*/
- if (buffers[reloc[2]].presumed_offset_correct && !DRM_DEBUG_RELOCATION)
+ if (buffers[buf_index].presumed_offset_correct && !DRM_DEBUG_RELOCATION)
return 0;
new_cmd_offset = reloc[0];
@@ -756,17 +762,17 @@ int i915_apply_reloc(struct drm_file *file_priv, int num_buffers,
relocatee->page_offset = (relocatee->offset & PAGE_MASK);
}
- val = buffers[reloc[2]].buffer->offset;
+ val = buffers[buf_index].buffer->offset;
index = (reloc[0] - relocatee->page_offset) >> 2;
/* add in validate */
val = val + reloc[1];
if (DRM_DEBUG_RELOCATION) {
- if (buffers[reloc[2]].presumed_offset_correct &&
+ if (buffers[buf_index].presumed_offset_correct &&
relocatee->data_page[index] != val) {
DRM_DEBUG ("Relocation mismatch source %d target %d buffer %d user %08x kernel %08x\n",
- reloc[0], reloc[1], reloc[2], relocatee->data_page[index], val);
+ reloc[0], reloc[1], buf_index, relocatee->data_page[index], val);
}
}
relocatee->data_page[index] = val;
@@ -775,94 +781,79 @@ int i915_apply_reloc(struct drm_file *file_priv, int num_buffers,
int i915_process_relocs(struct drm_file *file_priv,
uint32_t buf_handle,
- uint32_t *reloc_buf_handle,
+ uint32_t __user **reloc_user_ptr,
struct i915_relocatee_info *relocatee,
struct drm_i915_validate_buffer *buffers,
uint32_t num_buffers)
{
- struct drm_device *dev = file_priv->minor->dev;
- struct drm_buffer_object *reloc_list_object;
- uint32_t cur_handle = *reloc_buf_handle;
- uint32_t *reloc_page;
- int ret, reloc_is_iomem, reloc_stride;
- uint32_t num_relocs, reloc_offset, reloc_end, reloc_page_offset, next_offset, cur_offset;
- struct drm_bo_kmap_obj reloc_kmap;
-
- memset(&reloc_kmap, 0, sizeof(reloc_kmap));
-
- mutex_lock(&dev->struct_mutex);
- reloc_list_object = drm_lookup_buffer_object(file_priv, cur_handle, 1);
- mutex_unlock(&dev->struct_mutex);
- if (!reloc_list_object)
- return -EINVAL;
+ int ret, reloc_stride;
+ uint32_t cur_offset;
+ uint32_t reloc_count;
+ uint32_t reloc_type;
+ uint32_t reloc_buf_size;
+ uint32_t *reloc_buf = NULL;
+ int i;
- ret = drm_bo_kmap(reloc_list_object, 0, 1, &reloc_kmap);
+ /* do a copy from user from the user ptr */
+ ret = get_user(reloc_count, *reloc_user_ptr);
if (ret) {
DRM_ERROR("Could not map relocation buffer.\n");
goto out;
}
- reloc_page = drm_bmo_virtual(&reloc_kmap, &reloc_is_iomem);
- num_relocs = reloc_page[0] & 0xffff;
+ ret = get_user(reloc_type, (*reloc_user_ptr)+1);
+ if (ret) {
+ DRM_ERROR("Could not map relocation buffer.\n");
+ goto out;
+ }
- if ((reloc_page[0] >> 16) & 0xffff) {
+ if (reloc_type != 0) {
DRM_ERROR("Unsupported relocation type requested\n");
+ ret = -EINVAL;
goto out;
}
- /* get next relocate buffer handle */
- *reloc_buf_handle = reloc_page[1];
- reloc_stride = I915_RELOC0_STRIDE * sizeof(uint32_t); /* may be different for other types of relocs */
-
- DRM_DEBUG("num relocs is %d, next is %08X\n", num_relocs, reloc_page[1]);
-
- reloc_page_offset = 0;
- reloc_offset = I915_RELOC_HEADER * sizeof(uint32_t);
- reloc_end = reloc_offset + (num_relocs * reloc_stride);
-
- do {
- next_offset = drm_bo_offset_end(reloc_offset, reloc_end);
+ reloc_buf_size = (I915_RELOC_HEADER + (reloc_count * I915_RELOC0_STRIDE)) * sizeof(uint32_t);
+ reloc_buf = kmalloc(reloc_buf_size, GFP_KERNEL);
+ if (!reloc_buf) {
+ DRM_ERROR("Out of memory for reloc buffer\n");
+ ret = -ENOMEM;
+ goto out;
+ }
- do {
- cur_offset = ((reloc_offset + reloc_page_offset) & ~PAGE_MASK) / sizeof(uint32_t);
- ret = i915_apply_reloc(file_priv, num_buffers,
- buffers, relocatee, &reloc_page[cur_offset]);
- if (ret)
- goto out;
+ if (copy_from_user(reloc_buf, *reloc_user_ptr, reloc_buf_size)) {
+ ret = -EFAULT;
+ goto out;
+ }
- reloc_offset += reloc_stride;
- } while (reloc_offset < next_offset);
+ /* get next relocate buffer handle */
+ *reloc_user_ptr = (uint32_t *)*(unsigned long *)&reloc_buf[2];
- drm_bo_kunmap(&reloc_kmap);
+ reloc_stride = I915_RELOC0_STRIDE * sizeof(uint32_t); /* may be different for other types of relocs */
- reloc_offset = next_offset;
- if (reloc_offset != reloc_end) {
- ret = drm_bo_kmap(reloc_list_object, reloc_offset >> PAGE_SHIFT, 1, &reloc_kmap);
- if (ret) {
- DRM_ERROR("Could not map relocation buffer.\n");
- goto out;
- }
+ DRM_DEBUG("num relocs is %d, next is %p\n", reloc_count, *reloc_user_ptr);
- reloc_page = drm_bmo_virtual(&reloc_kmap, &reloc_is_iomem);
- reloc_page_offset = reloc_offset & ~PAGE_MASK;
- }
+ for (i = 0; i < reloc_count; i++) {
+ cur_offset = I915_RELOC_HEADER + (i * I915_RELOC0_STRIDE);
+
+ ret = i915_apply_reloc(file_priv, num_buffers, buffers,
+ relocatee, reloc_buf + cur_offset);
+ if (ret)
+ goto out;
+ }
- } while (reloc_offset != reloc_end);
out:
+
+ if (reloc_buf)
+ kfree(reloc_buf);
drm_bo_kunmap(&relocatee->kmap);
relocatee->data_page = NULL;
- drm_bo_kunmap(&reloc_kmap);
-
- mutex_lock(&dev->struct_mutex);
- drm_bo_usage_deref_locked(&reloc_list_object);
- mutex_unlock(&dev->struct_mutex);
-
return ret;
}
static int i915_exec_reloc(struct drm_file *file_priv, drm_handle_t buf_handle,
- drm_handle_t buf_reloc_handle,
+ uint32_t __user *reloc_user_ptr,
struct drm_i915_validate_buffer *buffers,
uint32_t buf_count)
{
@@ -896,8 +887,8 @@ static int i915_exec_reloc(struct drm_file *file_priv, drm_handle_t buf_handle,
goto out_err;
}
- while (buf_reloc_handle) {
- ret = i915_process_relocs(file_priv, buf_handle, &buf_reloc_handle, &relocatee, buffers, buf_count);
+ while (reloc_user_ptr) {
+ ret = i915_process_relocs(file_priv, buf_handle, &reloc_user_ptr, &relocatee, buffers, buf_count);
if (ret) {
DRM_ERROR("process relocs failed\n");
break;
@@ -927,8 +918,8 @@ int i915_validate_buffer_list(struct drm_file *file_priv,
int ret = 0;
unsigned buf_count = 0;
struct drm_device *dev = file_priv->minor->dev;
- uint32_t buf_reloc_handle, buf_handle;
-
+ uint32_t buf_handle;
+ uint32_t __user *reloc_user_ptr;
do {
if (buf_count >= *num_buffers) {
@@ -963,21 +954,19 @@ int i915_validate_buffer_list(struct drm_file *file_priv,
}
buf_handle = req->bo_req.handle;
- buf_reloc_handle = arg.reloc_handle;
+ reloc_user_ptr = (uint32_t *)(unsigned long)arg.reloc_ptr;
- if (buf_reloc_handle) {
- ret = i915_exec_reloc(file_priv, buf_handle, buf_reloc_handle, buffers, buf_count);
+ if (reloc_user_ptr) {
+ ret = i915_exec_reloc(file_priv, buf_handle, reloc_user_ptr, buffers, buf_count);
if (ret)
goto out_err;
DRM_MEMORYBARRIER();
}
rep.ret = drm_bo_handle_validate(file_priv, req->bo_req.handle,
- req->bo_req.fence_class,
- req->bo_req.flags,
- req->bo_req.mask,
+ req->bo_req.flags, req->bo_req.mask,
req->bo_req.hint,
- 0,
+ req->bo_req.fence_class, 0,
&rep.bo_info,
&buffers[buf_count].buffer);
@@ -1092,7 +1081,8 @@ static int i915_execbuffer(struct drm_device *dev, void *data,
sarea_priv->last_dispatch = READ_BREADCRUMB(dev_priv);
/* fence */
- ret = drm_fence_buffer_objects(dev, NULL, 0, NULL, &fence);
+ ret = drm_fence_buffer_objects(dev, NULL, fence_arg->flags,
+ NULL, &fence);
if (ret)
goto out_err0;
@@ -1174,7 +1164,7 @@ static int i915_getparam(struct drm_device *dev, void *data,
int value;
if (!dev_priv) {
- DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
+ DRM_ERROR("called with no initialization\n");
return -EINVAL;
}
@@ -1208,7 +1198,7 @@ static int i915_setparam(struct drm_device *dev, void *data,
drm_i915_setparam_t *param = data;
if (!dev_priv) {
- DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
+ DRM_ERROR("called with no initialization\n");
return -EINVAL;
}
@@ -1252,7 +1242,7 @@ static int i915_mmio(struct drm_device *dev, void *data,
int i;
if (!dev_priv) {
- DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
+ DRM_ERROR("called with no initialization\n");
return -EINVAL;
}
@@ -1295,7 +1285,7 @@ static int i915_set_status_page(struct drm_device *dev, void *data,
drm_i915_hws_addr_t *hws = data;
if (!dev_priv) {
- DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
+ DRM_ERROR("called with no initialization\n");
return -EINVAL;
}
DRM_DEBUG("set status page addr 0x%08x\n", (u32)hws->addr);
diff --git a/shared-core/i915_drm.h b/shared-core/i915_drm.h
index c5819953..d48d7665 100644
--- a/shared-core/i915_drm.h
+++ b/shared-core/i915_drm.h
@@ -329,9 +329,9 @@ typedef struct drm_i915_hws_addr {
/*
* Relocation header is 4 uint32_ts
- * 0 - (16-bit relocation type << 16)| 16 bit reloc count
- * 1 - buffer handle for another list of relocs
- * 2-3 - spare.
+ * 0 - 32 bit reloc count
+ * 1 - 32-bit relocation type
+ * 2-3 - 64-bit user buffer handle ptr for another list of relocs.
*/
#define I915_RELOC_HEADER 4
@@ -339,7 +339,7 @@ typedef struct drm_i915_hws_addr {
* type 0 relocation has 4-uint32_t stride
* 0 - offset into buffer
* 1 - delta to add in
- * 2 - index into buffer list
+ * 2 - buffer handle
* 3 - reserved (for optimisations later).
*/
#define I915_RELOC_TYPE_0 0
@@ -347,7 +347,7 @@ typedef struct drm_i915_hws_addr {
struct drm_i915_op_arg {
uint64_t next;
- uint32_t reloc_handle;
+ uint64_t reloc_ptr;
int handled;
union {
struct drm_bo_op_req req;
diff --git a/shared-core/i915_drv.h b/shared-core/i915_drv.h
index 45b7786a..49e23ac3 100644
--- a/shared-core/i915_drv.h
+++ b/shared-core/i915_drv.h
@@ -271,23 +271,23 @@ extern int i915_irq_emit(struct drm_device *dev, void *data,
extern int i915_irq_wait(struct drm_device *dev, void *data,
struct drm_file *file_priv);
-extern void i915_driver_wait_next_vblank(struct drm_device *dev, int pipe);
-extern int i915_driver_vblank_wait(struct drm_device *dev, unsigned int *sequence);
-extern int i915_driver_vblank_wait2(struct drm_device *dev, unsigned int *sequence);
extern irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS);
extern void i915_driver_irq_preinstall(struct drm_device * dev);
-extern void i915_driver_irq_postinstall(struct drm_device * dev);
+extern int i915_driver_irq_postinstall(struct drm_device * dev);
extern void i915_driver_irq_uninstall(struct drm_device * dev);
extern int i915_vblank_pipe_set(struct drm_device *dev, void *data,
struct drm_file *file_priv);
extern int i915_vblank_pipe_get(struct drm_device *dev, void *data,
struct drm_file *file_priv);
extern int i915_emit_irq(struct drm_device * dev);
-extern void i915_user_irq_on(struct drm_i915_private *dev_priv);
-extern void i915_user_irq_off(struct drm_i915_private *dev_priv);
extern void i915_enable_interrupt (struct drm_device *dev);
+extern int i915_enable_vblank(struct drm_device *dev, int crtc);
+extern void i915_disable_vblank(struct drm_device *dev, int crtc);
+extern u32 i915_get_vblank_counter(struct drm_device *dev, int crtc);
extern int i915_vblank_swap(struct drm_device *dev, void *data,
struct drm_file *file_priv);
+extern void i915_user_irq_on(struct drm_i915_private *dev_priv);
+extern void i915_user_irq_off(struct drm_i915_private *dev_priv);
/* i915_mem.c */
extern int i915_mem_alloc(struct drm_device *dev, void *data,
@@ -318,12 +318,12 @@ extern int i915_fence_has_irq(struct drm_device *dev, uint32_t class, uint32_t f
#ifdef I915_HAVE_BUFFER
/* i915_buffer.c */
extern struct drm_ttm_backend *i915_create_ttm_backend_entry(struct drm_device *dev);
-extern int i915_fence_types(struct drm_buffer_object *bo, uint32_t *fclass,
- uint32_t *type);
+extern int i915_fence_type(struct drm_buffer_object *bo, uint32_t *fclass,
+ uint32_t *type);
extern int i915_invalidate_caches(struct drm_device *dev, uint64_t buffer_flags);
extern int i915_init_mem_type(struct drm_device *dev, uint32_t type,
struct drm_mem_type_manager *man);
-extern uint32_t i915_evict_mask(struct drm_buffer_object *bo);
+extern uint64_t i915_evict_flags(struct drm_buffer_object *bo);
extern int i915_move(struct drm_buffer_object *bo, int evict,
int no_wait, struct drm_bo_mem_reg *new_mem);
void i915_flush_ttm(struct drm_ttm *ttm);
@@ -354,8 +354,8 @@ extern void intel_modeset_cleanup(struct drm_device *dev);
#define BEGIN_LP_RING(n) do { \
if (I915_VERBOSE) \
- DRM_DEBUG("BEGIN_LP_RING(%d) in %s\n", \
- (n), __FUNCTION__); \
+ DRM_DEBUG("BEGIN_LP_RING(%d)\n", \
+ (n)); \
if (dev_priv->ring.space < (n)*4) \
i915_wait_ring(dev, (n)*4, __FUNCTION__); \
outcount = 0; \
@@ -516,8 +516,41 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller);
#define I915REG_INT_ENABLE_R 0x020a0
#define I915REG_INSTPM 0x020c0
+#define PIPEADSL 0x70000
+#define PIPEBDSL 0x71000
+
#define I915REG_PIPEASTAT 0x70024
#define I915REG_PIPEBSTAT 0x71024
+/*
+ * The two pipe frame counter registers are not synchronized, so
+ * reading a stable value is somewhat tricky. The following code
+ * should work:
+ *
+ * do {
+ * high1 = ((INREG(PIPEAFRAMEHIGH) & PIPE_FRAME_HIGH_MASK) >>
+ * PIPE_FRAME_HIGH_SHIFT;
+ * low1 = ((INREG(PIPEAFRAMEPIXEL) & PIPE_FRAME_LOW_MASK) >>
+ * PIPE_FRAME_LOW_SHIFT);
+ * high2 = ((INREG(PIPEAFRAMEHIGH) & PIPE_FRAME_HIGH_MASK) >>
+ * PIPE_FRAME_HIGH_SHIFT);
+ * } while (high1 != high2);
+ * frame = (high1 << 8) | low1;
+ */
+#define PIPEAFRAMEHIGH 0x70040
+#define PIPEBFRAMEHIGH 0x71040
+#define PIPE_FRAME_HIGH_MASK 0x0000ffff
+#define PIPE_FRAME_HIGH_SHIFT 0
+#define PIPEAFRAMEPIXEL 0x70044
+#define PIPEBFRAMEPIXEL 0x71044
+
+#define PIPE_FRAME_LOW_MASK 0xff000000
+#define PIPE_FRAME_LOW_SHIFT 24
+/*
+ * Pixel within the current frame is counted in the PIPEAFRAMEPIXEL register
+ * and is 24 bits wide.
+ */
+#define PIPE_PIXEL_MASK 0x00ffffff
+#define PIPE_PIXEL_SHIFT 0
#define I915_VBLANK_INTERRUPT_ENABLE (1UL<<17)
#define I915_VBLANK_CLEAR (1UL<<1)
@@ -871,6 +904,14 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller);
#define BCLRPAT_B 0x61020
#define VSYNCSHIFT_B 0x61028
+#define HACTIVE_MASK 0x00000fff
+#define VTOTAL_MASK 0x00001fff
+#define VTOTAL_SHIFT 16
+#define VACTIVE_MASK 0x00000fff
+#define VBLANK_END_MASK 0x00001fff
+#define VBLANK_END_SHIFT 16
+#define VBLANK_START_MASK 0x00001fff
+
#define PP_STATUS 0x61200
# define PP_ON (1 << 31)
/**
@@ -1274,7 +1315,7 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller);
#define IS_I855(dev) ((dev)->pci_device == 0x3582)
#define IS_I865G(dev) ((dev)->pci_device == 0x2572)
-#define IS_I915G(dev) (dev->pci_device == 0x2582)/* || dev->pci_device == PCI_DEVICE_ID_INTELPCI_CHIP_E7221_G)*/
+#define IS_I915G(dev) ((dev)->pci_device == 0x2582 || (dev)->pci_device == 0x258a)
#define IS_I915GM(dev) ((dev)->pci_device == 0x2592)
#define IS_I945G(dev) ((dev)->pci_device == 0x2772)
#define IS_I945GM(dev) ((dev)->pci_device == 0x27A2)
@@ -1284,10 +1325,13 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller);
(dev)->pci_device == 0x2992 || \
(dev)->pci_device == 0x29A2 || \
(dev)->pci_device == 0x2A02 || \
- (dev)->pci_device == 0x2A12)
+ (dev)->pci_device == 0x2A12 || \
+ (dev)->pci_device == 0x2A42)
#define IS_I965GM(dev) ((dev)->pci_device == 0x2A02)
+#define IS_IGD_GM(dev) ((dev)->pci_device == 0x2A42)
+
#define IS_G33(dev) ((dev)->pci_device == 0x29C2 || \
(dev)->pci_device == 0x29B2 || \
(dev)->pci_device == 0x29D2)
@@ -1296,7 +1340,7 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller);
IS_I945GM(dev) || IS_I965G(dev) || IS_G33(dev))
#define IS_MOBILE(dev) (IS_I830(dev) || IS_I85X(dev) || IS_I915GM(dev) || \
- IS_I945GM(dev) || IS_I965GM(dev))
+ IS_I945GM(dev) || IS_I965GM(dev) || IS_IGD_GM(dev))
#define PRIMARY_RINGBUFFER_SIZE (128*1024)
diff --git a/shared-core/i915_irq.c b/shared-core/i915_irq.c
index ac5361f2..9b391b75 100644
--- a/shared-core/i915_irq.c
+++ b/shared-core/i915_irq.c
@@ -45,9 +45,9 @@
* @dev: DRM device
* @plane: plane to look for
*
- * We need to get the pipe associated with a given plane to correctly perform
- * vblank driven swapping, and they may not always be equal. So look up the
- * pipe associated with @plane here.
+ * The Intel Mesa & 2D drivers call the vblank routines with a plane number
+ * rather than a pipe number, since they may not always be equal. This routine
+ * maps the given @plane back to a pipe number.
*/
static int
i915_get_pipe(struct drm_device *dev, int plane)
@@ -61,6 +61,44 @@ i915_get_pipe(struct drm_device *dev, int plane)
}
/**
+ * i915_get_plane - return the the plane associated with a given pipe
+ * @dev: DRM device
+ * @pipe: pipe to look for
+ *
+ * The Intel Mesa & 2D drivers call the vblank routines with a plane number
+ * rather than a plane number, since they may not always be equal. This routine
+ * maps the given @pipe back to a plane number.
+ */
+static int
+i915_get_plane(struct drm_device *dev, int pipe)
+{
+ if (i915_get_pipe(dev, 0) == pipe)
+ return 0;
+ return 1;
+}
+
+/**
+ * i915_pipe_enabled - check if a pipe is enabled
+ * @dev: DRM device
+ * @pipe: pipe to check
+ *
+ * Reading certain registers when the pipe is disabled can hang the chip.
+ * Use this routine to make sure the PLL is running and the pipe is active
+ * before reading such registers if unsure.
+ */
+static int
+i915_pipe_enabled(struct drm_device *dev, int pipe)
+{
+ struct drm_i915_private *dev_priv = (struct drm_i915_private *) dev->dev_private;
+ unsigned long pipeconf = pipe ? PIPEBCONF : PIPEACONF;
+
+ if (I915_READ(pipeconf) & PIPEACONF_ENABLE)
+ return 1;
+
+ return 0;
+}
+
+/**
* Emit a synchronous flip.
*
* This function must be called with the drawable spinlock held.
@@ -117,8 +155,7 @@ static void i915_vblank_tasklet(struct drm_device *dev)
struct drm_i915_private *dev_priv = (struct drm_i915_private *) dev->dev_private;
struct list_head *list, *tmp, hits, *hit;
int nhits, nrects, slice[2], upper[2], lower[2], i, num_pages;
- unsigned counter[2] = { atomic_read(&dev->vbl_received),
- atomic_read(&dev->vbl_received2) };
+ unsigned counter[2];
struct drm_drawable_info *drw;
struct drm_i915_sarea *sarea_priv = dev_priv->sarea_priv;
u32 cpp = dev_priv->cpp, offsets[3];
@@ -130,6 +167,9 @@ static void i915_vblank_tasklet(struct drm_device *dev)
(cpp << 23) | (1 << 24);
RING_LOCALS;
+ counter[0] = drm_vblank_count(dev, 0);
+ counter[1] = drm_vblank_count(dev, 1);
+
DRM_DEBUG("\n");
INIT_LIST_HEAD(&hits);
@@ -154,6 +194,7 @@ static void i915_vblank_tasklet(struct drm_device *dev)
list_del(list);
dev_priv->swaps_pending--;
+ drm_vblank_put(dev, pipe);
DRM_SPINUNLOCK(&dev_priv->swaps_lock);
DRM_SPINLOCK(&dev->drw_lock);
@@ -303,6 +344,73 @@ static void i915_vblank_tasklet(struct drm_device *dev)
drm_free(swap_hit, sizeof(*swap_hit), DRM_MEM_DRIVER);
}
}
+#if 0
+static int i915_in_vblank(struct drm_device *dev, int pipe)
+{
+ struct drm_i915_private *dev_priv = (struct drm_i915_private *) dev->dev_private;
+ unsigned long pipedsl, vblank, vtotal;
+ unsigned long vbl_start, vbl_end, cur_line;
+
+ pipedsl = pipe ? PIPEBDSL : PIPEADSL;
+ vblank = pipe ? VBLANK_B : VBLANK_A;
+ vtotal = pipe ? VTOTAL_B : VTOTAL_A;
+
+ vbl_start = I915_READ(vblank) & VBLANK_START_MASK;
+ vbl_end = (I915_READ(vblank) >> VBLANK_END_SHIFT) & VBLANK_END_MASK;
+
+ cur_line = I915_READ(pipedsl);
+
+ if (cur_line >= vbl_start)
+ return 1;
+
+ return 0;
+}
+#endif
+u32 i915_get_vblank_counter(struct drm_device *dev, int plane)
+{
+ struct drm_i915_private *dev_priv = (struct drm_i915_private *) dev->dev_private;
+ unsigned long high_frame;
+ unsigned long low_frame;
+ u32 high1, high2, low, count;
+ int pipe;
+
+ pipe = i915_get_pipe(dev, plane);
+ high_frame = pipe ? PIPEBFRAMEHIGH : PIPEAFRAMEHIGH;
+ low_frame = pipe ? PIPEBFRAMEPIXEL : PIPEAFRAMEPIXEL;
+
+ if (!i915_pipe_enabled(dev, pipe)) {
+ printk(KERN_ERR "trying to get vblank count for disabled "
+ "pipe %d\n", pipe);
+ return 0;
+ }
+
+ /*
+ * High & low register fields aren't synchronized, so make sure
+ * we get a low value that's stable across two reads of the high
+ * register.
+ */
+ do {
+ high1 = ((I915_READ(high_frame) & PIPE_FRAME_HIGH_MASK) >>
+ PIPE_FRAME_HIGH_SHIFT);
+ low = ((I915_READ(low_frame) & PIPE_FRAME_LOW_MASK) >>
+ PIPE_FRAME_LOW_SHIFT);
+ high2 = ((I915_READ(high_frame) & PIPE_FRAME_HIGH_MASK) >>
+ PIPE_FRAME_HIGH_SHIFT);
+ } while (high1 != high2);
+
+ count = (high1 << 8) | low;
+
+ /*
+ * If we're in the middle of the vblank period, the
+ * above regs won't have been updated yet, so return
+ * an incremented count to stay accurate
+ */
+#if 0
+ if (i915_in_vblank(dev, pipe))
+ count++;
+#endif
+ return count;
+}
#define HOTPLUG_CMD_CRT 1
#define HOTPLUG_CMD_SDVOB 4
@@ -445,11 +553,10 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)
pipeb_stats = I915_READ(I915REG_PIPEBSTAT);
/* On i8xx hw the IIR and IER are 16bit on i9xx its 32bit */
- if (IS_I9XX(dev)) {
+ if (IS_I9XX(dev))
temp = I915_READ(I915REG_INT_IDENTITY_R);
- } else {
+ else
temp = I915_READ16(I915REG_INT_IDENTITY_R);
- }
temp2 = temp;
temp &= (dev_priv->irq_enable_reg | USER_INT_FLAG);
@@ -464,7 +571,7 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)
}
#else
#if 0
- DRM_DEBUG("%s flag=%08x\n", __FUNCTION__, temp);
+ DRM_DEBUG("flag=%08x\n", temp);
#endif
#endif
@@ -479,8 +586,32 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)
(void) I915_READ16(I915REG_INT_IDENTITY_R);
}
+ /*
+ * Clear the PIPE(A|B)STAT regs before the IIR otherwise
+ * we may get extra interrupts.
+ */
+ if (temp & VSYNC_PIPEA_FLAG) {
+ drm_handle_vblank(dev, i915_get_plane(dev, 0));
+ I915_WRITE(I915REG_PIPEASTAT,
+ pipea_stats | I915_VBLANK_INTERRUPT_ENABLE |
+ I915_VBLANK_CLEAR);
+ }
+
+ if (temp & VSYNC_PIPEB_FLAG) {
+ drm_handle_vblank(dev, i915_get_plane(dev, 1));
+ I915_WRITE(I915REG_PIPEBSTAT,
+ pipeb_stats | I915_VBLANK_INTERRUPT_ENABLE |
+ I915_VBLANK_CLEAR);
+ }
+
+ I915_WRITE16(I915REG_INT_IDENTITY_R, temp);
+ (void) I915_READ16(I915REG_INT_IDENTITY_R); /* Flush posted write */
+
DRM_READMEMORYBARRIER();
+ temp &= (dev_priv->irq_enable_reg | USER_INT_FLAG | VSYNC_PIPEA_FLAG |
+ VSYNC_PIPEB_FLAG);
+
dev_priv->sarea_priv->last_dispatch = READ_BREADCRUMB(dev_priv);
if (temp & USER_INT_FLAG) {
@@ -491,32 +622,8 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)
}
if (temp & (VSYNC_PIPEA_FLAG | VSYNC_PIPEB_FLAG)) {
- int vblank_pipe = dev_priv->vblank_pipe;
-
- if ((vblank_pipe &
- (DRM_I915_VBLANK_PIPE_A | DRM_I915_VBLANK_PIPE_B))
- == (DRM_I915_VBLANK_PIPE_A | DRM_I915_VBLANK_PIPE_B)) {
- if (temp & VSYNC_PIPEA_FLAG)
- atomic_inc(&dev->vbl_received);
- if (temp & VSYNC_PIPEB_FLAG)
- atomic_inc(&dev->vbl_received2);
- } else if (((temp & VSYNC_PIPEA_FLAG) &&
- (vblank_pipe & DRM_I915_VBLANK_PIPE_A)) ||
- ((temp & VSYNC_PIPEB_FLAG) &&
- (vblank_pipe & DRM_I915_VBLANK_PIPE_B)))
- atomic_inc(&dev->vbl_received);
-
- DRM_WAKEUP(&dev->vbl_queue);
- drm_vbl_send_signals(dev);
-
if (dev_priv->swaps_pending > 0)
drm_locked_tasklet(dev, i915_vblank_tasklet);
- I915_WRITE(I915REG_PIPEASTAT,
- pipea_stats|I915_VBLANK_INTERRUPT_ENABLE|
- I915_VBLANK_CLEAR);
- I915_WRITE(I915REG_PIPEBSTAT,
- pipeb_stats|I915_VBLANK_INTERRUPT_ENABLE|
- I915_VBLANK_CLEAR);
}
/* for now lest just ack it */
@@ -535,13 +642,12 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)
int i915_emit_irq(struct drm_device *dev)
{
-
struct drm_i915_private *dev_priv = dev->dev_private;
RING_LOCALS;
i915_kernel_lost_context(dev);
- DRM_DEBUG("%s\n", __FUNCTION__);
+ DRM_DEBUG("\n");
i915_emit_breadcrumb(dev);
@@ -580,7 +686,7 @@ static int i915_wait_irq(struct drm_device * dev, int irq_nr)
struct drm_i915_private *dev_priv = (struct drm_i915_private *) dev->dev_private;
int ret = 0;
- DRM_DEBUG("%s irq_nr=%d breadcrumb=%d\n", __FUNCTION__, irq_nr,
+ DRM_DEBUG("irq_nr=%d breadcrumb=%d\n", irq_nr,
READ_BREADCRUMB(dev_priv));
if (READ_BREADCRUMB(dev_priv) >= irq_nr)
@@ -592,8 +698,7 @@ static int i915_wait_irq(struct drm_device * dev, int irq_nr)
i915_user_irq_off(dev_priv);
if (ret == -EBUSY) {
- DRM_ERROR("%s: EBUSY -- rec: %d emitted: %d\n",
- __FUNCTION__,
+ DRM_ERROR("EBUSY -- rec: %d emitted: %d\n",
READ_BREADCRUMB(dev_priv), (int)dev_priv->counter);
}
@@ -601,64 +706,6 @@ static int i915_wait_irq(struct drm_device * dev, int irq_nr)
return ret;
}
-static int i915_driver_vblank_do_wait(struct drm_device *dev,
- unsigned int *sequence,
- atomic_t *counter)
-{
- struct drm_i915_private *dev_priv = dev->dev_private;
- unsigned int cur_vblank;
- int ret = 0;
-
- if (!dev_priv) {
- DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
- return -EINVAL;
- }
-
- DRM_WAIT_ON(ret, dev->vbl_queue, 3 * DRM_HZ,
- (((cur_vblank = atomic_read(counter))
- - *sequence) <= (1<<23)));
-
- *sequence = cur_vblank;
-
- return ret;
-}
-
-void i915_driver_wait_next_vblank(struct drm_device *dev, int pipe)
-{
- unsigned int seq;
-
- seq = pipe ? atomic_read(&dev->vbl_received2) + 1 :
- atomic_read(&dev->vbl_received) + 1;
-
- if (!pipe)
- i915_driver_vblank_do_wait(dev, &seq, &dev->vbl_received);
- else
- i915_driver_vblank_do_wait(dev, &seq, &dev->vbl_received2);
-}
-
-int i915_driver_vblank_wait(struct drm_device *dev, unsigned int *sequence)
-{
- atomic_t *counter;
-
- if (i915_get_pipe(dev, 0) == 0)
- counter = &dev->vbl_received;
- else
- counter = &dev->vbl_received2;
- return i915_driver_vblank_do_wait(dev, sequence, counter);
-}
-
-int i915_driver_vblank_wait2(struct drm_device *dev, unsigned int *sequence)
-{
- atomic_t *counter;
-
- if (i915_get_pipe(dev, 1) == 0)
- counter = &dev->vbl_received;
- else
- counter = &dev->vbl_received2;
-
- return i915_driver_vblank_do_wait(dev, sequence, counter);
-}
-
/* Needs the lock as it touches the ring.
*/
int i915_irq_emit(struct drm_device *dev, void *data,
@@ -671,7 +718,7 @@ int i915_irq_emit(struct drm_device *dev, void *data,
LOCK_TEST_WITH_RETURN(dev, file_priv);
if (!dev_priv) {
- DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
+ DRM_ERROR("called with no initialization\n");
return -EINVAL;
}
@@ -694,24 +741,63 @@ int i915_irq_wait(struct drm_device *dev, void *data,
struct drm_i915_irq_wait *irqwait = data;
if (!dev_priv) {
- DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
+ DRM_ERROR("called with no initialization\n");
return -EINVAL;
}
return i915_wait_irq(dev, irqwait->irq_seq);
}
-void i915_enable_interrupt (struct drm_device *dev)
+int i915_enable_vblank(struct drm_device *dev, int plane)
{
struct drm_i915_private *dev_priv = (struct drm_i915_private *) dev->dev_private;
- struct drm_output *o;
+ int pipe = i915_get_pipe(dev, plane);
- dev_priv->irq_enable_reg = USER_INT_FLAG;
-
- if (dev_priv->vblank_pipe & DRM_I915_VBLANK_PIPE_A)
+ switch (pipe) {
+ case 0:
dev_priv->irq_enable_reg |= VSYNC_PIPEA_FLAG;
- if (dev_priv->vblank_pipe & DRM_I915_VBLANK_PIPE_B)
+ break;
+ case 1:
dev_priv->irq_enable_reg |= VSYNC_PIPEB_FLAG;
+ break;
+ default:
+ DRM_ERROR("tried to enable vblank on non-existent pipe %d\n",
+ pipe);
+ break;
+ }
+
+ I915_WRITE16(I915REG_INT_ENABLE_R, dev_priv->irq_enable_reg);
+
+ return 0;
+}
+
+void i915_disable_vblank(struct drm_device *dev, int plane)
+{
+ struct drm_i915_private *dev_priv = (struct drm_i915_private *) dev->dev_private;
+ int pipe = i915_get_pipe(dev, plane);
+
+ switch (pipe) {
+ case 0:
+ dev_priv->irq_enable_reg &= ~VSYNC_PIPEA_FLAG;
+ break;
+ case 1:
+ dev_priv->irq_enable_reg &= ~VSYNC_PIPEB_FLAG;
+ break;
+ default:
+ DRM_ERROR("tried to disable vblank on non-existent pipe %d\n",
+ pipe);
+ break;
+ }
+
+ I915_WRITE16(I915REG_INT_ENABLE_R, dev_priv->irq_enable_reg);
+}
+
+void i915_enable_interrupt (struct drm_device *dev)
+{
+ struct drm_i915_private *dev_priv = (struct drm_i915_private *) dev->dev_private;
+ struct drm_output *o;
+
+ dev_priv->irq_enable_reg |= USER_INT_FLAG;
if (IS_I9XX(dev) && dev->mode_config.num_output) {
dev_priv->irq_enable_reg |= HOTPLUG_FLAG;
@@ -760,20 +846,17 @@ int i915_vblank_pipe_set(struct drm_device *dev, void *data,
struct drm_i915_vblank_pipe *pipe = data;
if (!dev_priv) {
- DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
+ DRM_ERROR("called with no initialization\n");
return -EINVAL;
}
if (pipe->pipe & ~(DRM_I915_VBLANK_PIPE_A|DRM_I915_VBLANK_PIPE_B)) {
- DRM_ERROR("%s called with invalid pipe 0x%x\n",
- __FUNCTION__, pipe->pipe);
+ DRM_ERROR("called with invalid pipe 0x%x\n", pipe->pipe);
return -EINVAL;
}
dev_priv->vblank_pipe = pipe->pipe;
- i915_enable_interrupt (dev);
-
return 0;
}
@@ -785,7 +868,7 @@ int i915_vblank_pipe_get(struct drm_device *dev, void *data,
u16 flag;
if (!dev_priv) {
- DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
+ DRM_ERROR("called with no initialization\n");
return -EINVAL;
}
@@ -811,6 +894,7 @@ int i915_vblank_swap(struct drm_device *dev, void *data,
unsigned int pipe, seqtype, curseq, plane;
unsigned long irqflags;
struct list_head *list;
+ int ret;
if (!dev_priv) {
DRM_ERROR("%s called with no initialization\n", __func__);
@@ -854,7 +938,8 @@ int i915_vblank_swap(struct drm_device *dev, void *data,
DRM_SPINUNLOCK_IRQRESTORE(&dev->drw_lock, irqflags);
- curseq = atomic_read(pipe ? &dev->vbl_received2 : &dev->vbl_received);
+ drm_update_vblank_count(dev, pipe);
+ curseq = drm_vblank_count(dev, pipe);
if (seqtype == _DRM_VBLANK_RELATIVE)
swap->sequence += curseq;
@@ -927,6 +1012,12 @@ int i915_vblank_swap(struct drm_device *dev, void *data,
DRM_DEBUG("\n");
+ ret = drm_vblank_get(dev, pipe);
+ if (ret) {
+ drm_free(vbl_swap, sizeof(*vbl_swap), DRM_MEM_DRIVER);
+ return ret;
+ }
+
vbl_swap->drw_id = swap->drawable;
vbl_swap->plane = plane;
vbl_swap->sequence = swap->sequence;
@@ -937,7 +1028,7 @@ int i915_vblank_swap(struct drm_device *dev, void *data,
DRM_SPINLOCK_IRQSAVE(&dev_priv->swaps_lock, irqflags);
- list_add_tail((struct list_head *)vbl_swap, &dev_priv->vbl_swaps.head);
+ list_add_tail(&vbl_swap->head, &dev_priv->vbl_swaps.head);
dev_priv->swaps_pending++;
DRM_SPINUNLOCK_IRQRESTORE(&dev_priv->swaps_lock, irqflags);
@@ -962,9 +1053,10 @@ void i915_driver_irq_preinstall(struct drm_device * dev)
}
-void i915_driver_irq_postinstall(struct drm_device * dev)
+int i915_driver_irq_postinstall(struct drm_device * dev)
{
struct drm_i915_private *dev_priv = (struct drm_i915_private *) dev->dev_private;
+ int ret, num_pipes = 2;
DRM_SPININIT(&dev_priv->swaps_lock, "swap");
INIT_LIST_HEAD(&dev_priv->vbl_swaps.head);
@@ -972,6 +1064,13 @@ void i915_driver_irq_postinstall(struct drm_device * dev)
DRM_SPININIT(&dev_priv->user_irq_lock, "userirq");
dev_priv->user_irq_refcount = 0;
+ dev_priv->irq_enable_reg = 0;
+
+ ret = drm_vblank_init(dev, num_pipes);
+ if (ret)
+ return ret;
+
+ dev->max_vblank_count = 0xffffff; /* only 24 bits of frame count */
i915_enable_interrupt(dev);
DRM_INIT_WAITQUEUE(&dev_priv->irq_queue);
@@ -981,6 +1080,7 @@ void i915_driver_irq_postinstall(struct drm_device * dev)
*/
I915_WRITE(I915REG_INSTPM, (1 << 5) | (1 << 21));
+ return 0;
}
void i915_driver_irq_uninstall(struct drm_device * dev)
diff --git a/shared-core/i915_mem.c b/shared-core/i915_mem.c
index 4c7ced24..f24547c7 100644
--- a/shared-core/i915_mem.c
+++ b/shared-core/i915_mem.c
@@ -276,7 +276,7 @@ int i915_mem_alloc(struct drm_device *dev, void *data,
struct mem_block *block, **heap;
if (!dev_priv) {
- DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
+ DRM_ERROR("called with no initialization\n");
return -EINVAL;
}
@@ -314,7 +314,7 @@ int i915_mem_free(struct drm_device *dev, void *data,
struct mem_block *block, **heap;
if (!dev_priv) {
- DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
+ DRM_ERROR("called with no initialization\n");
return -EINVAL;
}
@@ -342,7 +342,7 @@ int i915_mem_init_heap(struct drm_device *dev, void *data,
struct mem_block **heap;
if (!dev_priv) {
- DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
+ DRM_ERROR("called with no initialization\n");
return -EINVAL;
}
@@ -366,7 +366,7 @@ int i915_mem_destroy_heap( struct drm_device *dev, void *data,
struct mem_block **heap;
if ( !dev_priv ) {
- DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ );
+ DRM_ERROR( "called with no initialization\n" );
return -EINVAL;
}
diff --git a/shared-core/mach64_dma.c b/shared-core/mach64_dma.c
index 411b98d5..339234fa 100644
--- a/shared-core/mach64_dma.c
+++ b/shared-core/mach64_dma.c
@@ -57,7 +57,7 @@
* \returns zero on success, or -EBUSY if the timeout (specificed by
* drm_mach64_private::usec_timeout) occurs.
*/
-int mach64_do_wait_for_fifo(drm_mach64_private_t * dev_priv, int entries)
+int mach64_do_wait_for_fifo(drm_mach64_private_t *dev_priv, int entries)
{
int slots = 0, i;
@@ -68,15 +68,14 @@ int mach64_do_wait_for_fifo(drm_mach64_private_t * dev_priv, int entries)
DRM_UDELAY(1);
}
- DRM_INFO("%s failed! slots=%d entries=%d\n", __FUNCTION__, slots,
- entries);
+ DRM_INFO("failed! slots=%d entries=%d\n", slots, entries);
return -EBUSY;
}
/**
* Wait for the draw engine to be idle.
*/
-int mach64_do_wait_for_idle(drm_mach64_private_t * dev_priv)
+int mach64_do_wait_for_idle(drm_mach64_private_t *dev_priv)
{
int i, ret;
@@ -85,14 +84,12 @@ int mach64_do_wait_for_idle(drm_mach64_private_t * dev_priv)
return ret;
for (i = 0; i < dev_priv->usec_timeout; i++) {
- if (!(MACH64_READ(MACH64_GUI_STAT) & MACH64_GUI_ACTIVE)) {
+ if (!(MACH64_READ(MACH64_GUI_STAT) & MACH64_GUI_ACTIVE))
return 0;
- }
DRM_UDELAY(1);
}
- DRM_INFO("%s failed! GUI_STAT=0x%08x\n", __FUNCTION__,
- MACH64_READ(MACH64_GUI_STAT));
+ DRM_INFO("failed! GUI_STAT=0x%08x\n", MACH64_READ(MACH64_GUI_STAT));
mach64_dump_ring_info(dev_priv);
return -EBUSY;
}
@@ -116,7 +113,7 @@ int mach64_do_wait_for_idle(drm_mach64_private_t * dev_priv)
*
* \sa mach64_dump_ring_info()
*/
-int mach64_wait_ring(drm_mach64_private_t * dev_priv, int n)
+int mach64_wait_ring(drm_mach64_private_t *dev_priv, int n)
{
drm_mach64_descriptor_ring_t *ring = &dev_priv->ring;
int i;
@@ -124,9 +121,8 @@ int mach64_wait_ring(drm_mach64_private_t * dev_priv, int n)
for (i = 0; i < dev_priv->usec_timeout; i++) {
mach64_update_ring_snapshot(dev_priv);
if (ring->space >= n) {
- if (i > 0) {
- DRM_DEBUG("%s: %d usecs\n", __FUNCTION__, i);
- }
+ if (i > 0)
+ DRM_DEBUG("%d usecs\n", i);
return 0;
}
DRM_UDELAY(1);
@@ -143,7 +139,7 @@ int mach64_wait_ring(drm_mach64_private_t * dev_priv, int n)
*
* \sa mach64_wait_ring()
*/
-static int mach64_ring_idle(drm_mach64_private_t * dev_priv)
+static int mach64_ring_idle(drm_mach64_private_t *dev_priv)
{
drm_mach64_descriptor_ring_t *ring = &dev_priv->ring;
u32 head;
@@ -155,9 +151,8 @@ static int mach64_ring_idle(drm_mach64_private_t * dev_priv)
mach64_update_ring_snapshot(dev_priv);
if (ring->head == ring->tail &&
!(MACH64_READ(MACH64_GUI_STAT) & MACH64_GUI_ACTIVE)) {
- if (i > 0) {
- DRM_DEBUG("%s: %d usecs\n", __FUNCTION__, i);
- }
+ if (i > 0)
+ DRM_DEBUG("%d usecs\n", i);
return 0;
}
if (ring->head == head) {
@@ -169,8 +164,7 @@ static int mach64_ring_idle(drm_mach64_private_t * dev_priv)
DRM_UDELAY(1);
}
- DRM_INFO("%s failed! GUI_STAT=0x%08x\n", __FUNCTION__,
- MACH64_READ(MACH64_GUI_STAT));
+ DRM_INFO("failed! GUI_STAT=0x%08x\n", MACH64_READ(MACH64_GUI_STAT));
mach64_dump_ring_info(dev_priv);
return -EBUSY;
}
@@ -180,7 +174,7 @@ static int mach64_ring_idle(drm_mach64_private_t * dev_priv)
*
* \sa mach64_do_engine_reset()
*/
-static void mach64_ring_reset(drm_mach64_private_t * dev_priv)
+static void mach64_ring_reset(drm_mach64_private_t *dev_priv)
{
drm_mach64_descriptor_ring_t *ring = &dev_priv->ring;
@@ -198,7 +192,7 @@ static void mach64_ring_reset(drm_mach64_private_t * dev_priv)
/**
* Ensure the all the queued commands will be processed.
*/
-int mach64_do_dma_flush(drm_mach64_private_t * dev_priv)
+int mach64_do_dma_flush(drm_mach64_private_t *dev_priv)
{
/* FIXME: It's not necessary to wait for idle when flushing
* we just need to ensure the ring will be completely processed
@@ -210,14 +204,14 @@ int mach64_do_dma_flush(drm_mach64_private_t * dev_priv)
/**
* Stop all DMA activity.
*/
-int mach64_do_dma_idle(drm_mach64_private_t * dev_priv)
+int mach64_do_dma_idle(drm_mach64_private_t *dev_priv)
{
int ret;
/* wait for completion */
if ((ret = mach64_ring_idle(dev_priv)) < 0) {
- DRM_ERROR("%s failed BM_GUI_TABLE=0x%08x tail: %u\n",
- __FUNCTION__, MACH64_READ(MACH64_BM_GUI_TABLE),
+ DRM_ERROR("failed BM_GUI_TABLE=0x%08x tail: %u\n",
+ MACH64_READ(MACH64_BM_GUI_TABLE),
dev_priv->ring.tail);
return ret;
}
@@ -232,11 +226,11 @@ int mach64_do_dma_idle(drm_mach64_private_t * dev_priv)
/**
* Reset the engine. This will stop the DMA if it is running.
*/
-int mach64_do_engine_reset(drm_mach64_private_t * dev_priv)
+int mach64_do_engine_reset(drm_mach64_private_t *dev_priv)
{
u32 tmp;
- DRM_DEBUG("%s\n", __FUNCTION__);
+ DRM_DEBUG("\n");
/* Kill off any outstanding DMA transfers.
*/
@@ -276,7 +270,7 @@ int mach64_do_engine_reset(drm_mach64_private_t * dev_priv)
/**
* Dump engine registers values.
*/
-void mach64_dump_engine_info(drm_mach64_private_t * dev_priv)
+void mach64_dump_engine_info(drm_mach64_private_t *dev_priv)
{
DRM_INFO("\n");
if (!dev_priv->is_pci) {
@@ -417,8 +411,8 @@ void mach64_dump_engine_info(drm_mach64_private_t * dev_priv)
* Used by mach64_dump_ring_info() to dump the contents of the current buffer
* pointed by the ring head.
*/
-static void mach64_dump_buf_info(drm_mach64_private_t * dev_priv,
- struct drm_buf * buf)
+static void mach64_dump_buf_info(drm_mach64_private_t *dev_priv,
+ struct drm_buf *buf)
{
u32 addr = GETBUFADDR(buf);
u32 used = buf->used >> 2;
@@ -477,7 +471,7 @@ static void mach64_dump_buf_info(drm_mach64_private_t * dev_priv,
* Dump the ring state and contents, including the contents of the buffer being
* processed by the graphics engine.
*/
-void mach64_dump_ring_info(drm_mach64_private_t * dev_priv)
+void mach64_dump_ring_info(drm_mach64_private_t *dev_priv)
{
drm_mach64_descriptor_ring_t *ring = &dev_priv->ring;
int i, skipped;
@@ -526,9 +520,8 @@ void mach64_dump_ring_info(drm_mach64_private_t * dev_priv)
u32 buf_addr = GETBUFADDR(buf);
- if (buf_addr <= addr && addr < buf_addr + buf->used) {
+ if (buf_addr <= addr && addr < buf_addr + buf->used)
mach64_dump_buf_info(dev_priv, buf);
- }
}
}
@@ -564,13 +557,13 @@ void mach64_dump_ring_info(drm_mach64_private_t * dev_priv)
/**
* Add the end mark to the ring's new tail position.
- *
+ *
* The bus master engine will keep processing the DMA buffers listed in the ring
* until it finds this mark, making it stop.
- *
+ *
* \sa mach64_clear_dma_eol
*/
-static __inline__ void mach64_set_dma_eol(volatile u32 * addr)
+static __inline__ void mach64_set_dma_eol(volatile u32 *addr)
{
#if defined(__i386__)
int nr = 31;
@@ -611,17 +604,17 @@ static __inline__ void mach64_set_dma_eol(volatile u32 * addr)
}
/**
- * Remove the end mark from the ring's old tail position.
- *
+ * Remove the end mark from the ring's old tail position.
+ *
* It should be called after calling mach64_set_dma_eol to mark the ring's new
* tail position.
- *
- * We update the end marks while the bus master engine is in operation. Since
+ *
+ * We update the end marks while the bus master engine is in operation. Since
* the bus master engine may potentially be reading from the same position
- * that we write, we must change atomically to avoid having intermediary bad
+ * that we write, we must change atomically to avoid having intermediary bad
* data.
*/
-static __inline__ void mach64_clear_dma_eol(volatile u32 * addr)
+static __inline__ void mach64_clear_dma_eol(volatile u32 *addr)
{
#if defined(__i386__)
int nr = 31;
@@ -661,35 +654,35 @@ static __inline__ void mach64_clear_dma_eol(volatile u32 * addr)
#endif
}
-#define RING_LOCALS \
+#define RING_LOCALS \
int _ring_tail, _ring_write; unsigned int _ring_mask; volatile u32 *_ring
#define RING_WRITE_OFS _ring_write
-#define BEGIN_RING( n ) \
-do { \
- if ( MACH64_VERBOSE ) { \
- DRM_INFO( "BEGIN_RING( %d ) in %s\n", \
- (n), __FUNCTION__ ); \
- } \
- if ( dev_priv->ring.space <= (n) * sizeof(u32) ) { \
- int ret; \
- if ((ret=mach64_wait_ring( dev_priv, (n) * sizeof(u32))) < 0 ) { \
- DRM_ERROR( "wait_ring failed, resetting engine\n"); \
- mach64_dump_engine_info( dev_priv ); \
- mach64_do_engine_reset( dev_priv ); \
- return ret; \
- } \
- } \
- dev_priv->ring.space -= (n) * sizeof(u32); \
- _ring = (u32 *) dev_priv->ring.start; \
- _ring_tail = _ring_write = dev_priv->ring.tail; \
- _ring_mask = dev_priv->ring.tail_mask; \
-} while (0)
+#define BEGIN_RING(n) \
+ do { \
+ if (MACH64_VERBOSE) { \
+ DRM_INFO( "BEGIN_RING( %d ) \n", \
+ (n) ); \
+ } \
+ if (dev_priv->ring.space <= (n) * sizeof(u32)) { \
+ int ret; \
+ if ((ret = mach64_wait_ring( dev_priv, (n) * sizeof(u32))) < 0 ) { \
+ DRM_ERROR( "wait_ring failed, resetting engine\n"); \
+ mach64_dump_engine_info( dev_priv ); \
+ mach64_do_engine_reset( dev_priv ); \
+ return ret; \
+ } \
+ } \
+ dev_priv->ring.space -= (n) * sizeof(u32); \
+ _ring = (u32 *) dev_priv->ring.start; \
+ _ring_tail = _ring_write = dev_priv->ring.tail; \
+ _ring_mask = dev_priv->ring.tail_mask; \
+ } while (0)
#define OUT_RING( x ) \
do { \
- if ( MACH64_VERBOSE ) { \
+ if (MACH64_VERBOSE) { \
DRM_INFO( " OUT_RING( 0x%08x ) at 0x%x\n", \
(unsigned int)(x), _ring_write ); \
} \
@@ -699,7 +692,7 @@ do { \
#define ADVANCE_RING() \
do { \
- if ( MACH64_VERBOSE ) { \
+ if (MACH64_VERBOSE) { \
DRM_INFO( "ADVANCE_RING() wr=0x%06x tail=0x%06x\n", \
_ring_write, _ring_tail ); \
} \
@@ -835,7 +828,7 @@ static int mach64_bm_dma_test(struct drm_device * dev)
u32 src_cntl, pat_reg0, pat_reg1;
int i, count, failed;
- DRM_DEBUG("%s\n", __FUNCTION__);
+ DRM_DEBUG("\n");
table = (u32 *) dev_priv->ring.start;
@@ -1011,7 +1004,7 @@ static int mach64_do_dma_init(struct drm_device * dev, drm_mach64_init_t * init)
u32 tmp;
int i, ret;
- DRM_DEBUG("%s\n", __FUNCTION__);
+ DRM_DEBUG("\n");
dev_priv = drm_alloc(sizeof(drm_mach64_private_t), DRM_MEM_DRIVER);
if (dev_priv == NULL)
@@ -1221,7 +1214,7 @@ static int mach64_do_dma_init(struct drm_device * dev, drm_mach64_init_t * init)
/** MMIO Pseudo-DMA (intended primarily for debugging, not performance)
*/
-int mach64_do_dispatch_pseudo_dma(drm_mach64_private_t * dev_priv)
+int mach64_do_dispatch_pseudo_dma(drm_mach64_private_t *dev_priv)
{
drm_mach64_descriptor_ring_t *ring = &dev_priv->ring;
volatile u32 *ring_read;
@@ -1236,9 +1229,7 @@ int mach64_do_dispatch_pseudo_dma(drm_mach64_private_t * dev_priv)
target = MACH64_BM_ADDR;
if ((ret = mach64_do_wait_for_idle(dev_priv)) < 0) {
- DRM_INFO
- ("%s: idle failed before pseudo-dma dispatch, resetting engine\n",
- __FUNCTION__);
+ DRM_INFO("idle failed before pseudo-dma dispatch, resetting engine\n");
mach64_dump_engine_info(dev_priv);
mach64_do_engine_reset(dev_priv);
return ret;
@@ -1359,7 +1350,7 @@ int mach64_do_dispatch_pseudo_dma(drm_mach64_private_t * dev_priv)
MACH64_WRITE(MACH64_BM_GUI_TABLE_CMD,
ring->head_addr | MACH64_CIRCULAR_BUF_SIZE_16KB);
- DRM_DEBUG("%s completed\n", __FUNCTION__);
+ DRM_DEBUG("completed\n");
return 0;
}
@@ -1372,7 +1363,7 @@ int mach64_do_dispatch_pseudo_dma(drm_mach64_private_t * dev_priv)
int mach64_do_cleanup_dma(struct drm_device * dev)
{
- DRM_DEBUG("%s\n", __FUNCTION__);
+ DRM_DEBUG("\n");
/* Make sure interrupts are disabled here because the uninstall ioctl
* may not have been called from userspace and after dev_private
@@ -1416,7 +1407,7 @@ int mach64_dma_init(struct drm_device *dev, void *data,
{
drm_mach64_init_t *init = data;
- DRM_DEBUG("%s\n", __FUNCTION__);
+ DRM_DEBUG("\n");
LOCK_TEST_WITH_RETURN(dev, file_priv);
@@ -1435,7 +1426,7 @@ int mach64_dma_idle(struct drm_device *dev, void *data,
{
drm_mach64_private_t *dev_priv = dev->dev_private;
- DRM_DEBUG("%s\n", __FUNCTION__);
+ DRM_DEBUG("\n");
LOCK_TEST_WITH_RETURN(dev, file_priv);
@@ -1447,7 +1438,7 @@ int mach64_dma_flush(struct drm_device *dev, void *data,
{
drm_mach64_private_t *dev_priv = dev->dev_private;
- DRM_DEBUG("%s\n", __FUNCTION__);
+ DRM_DEBUG("\n");
LOCK_TEST_WITH_RETURN(dev, file_priv);
@@ -1459,7 +1450,7 @@ int mach64_engine_reset(struct drm_device *dev, void *data,
{
drm_mach64_private_t *dev_priv = dev->dev_private;
- DRM_DEBUG("%s\n", __FUNCTION__);
+ DRM_DEBUG("\n");
LOCK_TEST_WITH_RETURN(dev, file_priv);
@@ -1481,8 +1472,7 @@ int mach64_init_freelist(struct drm_device * dev)
struct list_head *ptr;
int i;
- DRM_DEBUG("%s: adding %d buffers to freelist\n", __FUNCTION__,
- dma->buf_count);
+ DRM_DEBUG("adding %d buffers to freelist\n", dma->buf_count);
for (i = 0; i < dma->buf_count; i++) {
if ((entry =
@@ -1506,7 +1496,7 @@ void mach64_destroy_freelist(struct drm_device * dev)
struct list_head *ptr;
struct list_head *tmp;
- DRM_DEBUG("%s\n", __FUNCTION__);
+ DRM_DEBUG("\n");
list_for_each_safe(ptr, tmp, &dev_priv->pending) {
list_del(ptr);
@@ -1529,7 +1519,7 @@ void mach64_destroy_freelist(struct drm_device * dev)
/* IMPORTANT: This function should only be called when the engine is idle or locked up,
* as it assumes all buffers in the pending list have been completed by the hardware.
*/
-int mach64_do_release_used_buffers(drm_mach64_private_t * dev_priv)
+int mach64_do_release_used_buffers(drm_mach64_private_t *dev_priv)
{
struct list_head *ptr;
struct list_head *tmp;
@@ -1551,13 +1541,12 @@ int mach64_do_release_used_buffers(drm_mach64_private_t * dev_priv)
}
}
- DRM_DEBUG("%s: released %d buffers from pending list\n", __FUNCTION__,
- i);
+ DRM_DEBUG("released %d buffers from pending list\n", i);
return 0;
}
-static int mach64_do_reclaim_completed(drm_mach64_private_t * dev_priv)
+static int mach64_do_reclaim_completed(drm_mach64_private_t *dev_priv)
{
drm_mach64_descriptor_ring_t *ring = &dev_priv->ring;
struct list_head *ptr;
@@ -1579,8 +1568,7 @@ static int mach64_do_reclaim_completed(drm_mach64_private_t * dev_priv)
#endif
/* last pass is complete, so release everything */
mach64_do_release_used_buffers(dev_priv);
- DRM_DEBUG("%s: idle engine, freed all buffers.\n",
- __FUNCTION__);
+ DRM_DEBUG("idle engine, freed all buffers.\n");
if (list_empty(&dev_priv->free_list)) {
DRM_ERROR("Freelist empty with idle engine\n");
return -1;
@@ -1621,9 +1609,9 @@ static int mach64_do_reclaim_completed(drm_mach64_private_t * dev_priv)
list_del(ptr);
list_add_tail(ptr, &dev_priv->free_list);
DRM_DEBUG
- ("%s: freed processed buffer (head=%d tail=%d "
+ ("freed processed buffer (head=%d tail=%d "
"buf ring ofs=%d).\n",
- __FUNCTION__, head, tail, ofs);
+ head, tail, ofs);
return 0;
}
}
@@ -1631,7 +1619,7 @@ static int mach64_do_reclaim_completed(drm_mach64_private_t * dev_priv)
return 1;
}
-struct drm_buf *mach64_freelist_get(drm_mach64_private_t * dev_priv)
+struct drm_buf *mach64_freelist_get(drm_mach64_private_t *dev_priv)
{
drm_mach64_descriptor_ring_t *ring = &dev_priv->ring;
drm_mach64_freelist_t *entry;
@@ -1677,7 +1665,7 @@ struct drm_buf *mach64_freelist_get(drm_mach64_private_t * dev_priv)
return entry->buf;
}
-int mach64_freelist_put(drm_mach64_private_t * dev_priv, struct drm_buf * copy_buf)
+int mach64_freelist_put(drm_mach64_private_t *dev_priv, struct drm_buf *copy_buf)
{
struct list_head *ptr;
drm_mach64_freelist_t *entry;
@@ -1686,8 +1674,7 @@ int mach64_freelist_put(drm_mach64_private_t * dev_priv, struct drm_buf * copy_b
list_for_each(ptr, &dev_priv->pending) {
entry = list_entry(ptr, drm_mach64_freelist_t, list);
if (copy_buf == entry->buf) {
- DRM_ERROR("%s: Trying to release a pending buf\n",
- __FUNCTION__);
+ DRM_ERROR("Trying to release a pending buf\n");
return -EFAULT;
}
}
diff --git a/shared-core/mach64_drv.h b/shared-core/mach64_drv.h
index 1768a2a4..fb8a7724 100644
--- a/shared-core/mach64_drv.h
+++ b/shared-core/mach64_drv.h
@@ -96,6 +96,8 @@ typedef struct drm_mach64_private {
unsigned int depth_bpp;
unsigned int depth_offset, depth_pitch;
+ atomic_t vbl_received; /**< Number of vblanks received. */
+
u32 front_offset_pitch;
u32 back_offset_pitch;
u32 depth_offset_pitch;
@@ -160,13 +162,14 @@ extern int mach64_dma_blit(struct drm_device *dev, void *data,
struct drm_file *file_priv);
extern int mach64_get_param(struct drm_device *dev, void *data,
struct drm_file *file_priv);
-extern int mach64_driver_vblank_wait(struct drm_device * dev,
- unsigned int *sequence);
+extern u32 mach64_get_vblank_counter(struct drm_device *dev, int crtc);
+extern int mach64_enable_vblank(struct drm_device *dev, int crtc);
+extern void mach64_disable_vblank(struct drm_device *dev, int crtc);
extern irqreturn_t mach64_driver_irq_handler(DRM_IRQ_ARGS);
-extern void mach64_driver_irq_preinstall(struct drm_device * dev);
-extern void mach64_driver_irq_postinstall(struct drm_device * dev);
-extern void mach64_driver_irq_uninstall(struct drm_device * dev);
+extern void mach64_driver_irq_preinstall(struct drm_device *dev);
+extern int mach64_driver_irq_postinstall(struct drm_device *dev);
+extern void mach64_driver_irq_uninstall(struct drm_device *dev);
/* ================================================================
* Registers
@@ -536,8 +539,7 @@ static __inline__ void mach64_ring_start(drm_mach64_private_t * dev_priv)
{
drm_mach64_descriptor_ring_t *ring = &dev_priv->ring;
- DRM_DEBUG("%s: head_addr: 0x%08x head: %d tail: %d space: %d\n",
- __FUNCTION__,
+ DRM_DEBUG("head_addr: 0x%08x head: %d tail: %d space: %d\n",
ring->head_addr, ring->head, ring->tail, ring->space);
if (mach64_do_wait_for_idle(dev_priv) < 0) {
@@ -563,8 +565,7 @@ static __inline__ void mach64_ring_start(drm_mach64_private_t * dev_priv)
static __inline__ void mach64_ring_resume(drm_mach64_private_t * dev_priv,
drm_mach64_descriptor_ring_t * ring)
{
- DRM_DEBUG("%s: head_addr: 0x%08x head: %d tail: %d space: %d\n",
- __FUNCTION__,
+ DRM_DEBUG("head_addr: 0x%08x head: %d tail: %d space: %d\n",
ring->head_addr, ring->head, ring->tail, ring->space);
/* reset descriptor table ring head */
@@ -583,8 +584,7 @@ static __inline__ void mach64_ring_resume(drm_mach64_private_t * dev_priv,
MACH64_WRITE(MACH64_DST_HEIGHT_WIDTH, 0);
if (dev_priv->driver_mode == MACH64_MODE_DMA_SYNC) {
if ((mach64_do_wait_for_idle(dev_priv)) < 0) {
- DRM_ERROR("%s: idle failed, resetting engine\n",
- __FUNCTION__);
+ DRM_ERROR("idle failed, resetting engine\n");
mach64_dump_engine_info(dev_priv);
mach64_do_engine_reset(dev_priv);
return;
@@ -609,8 +609,7 @@ static __inline__ void mach64_ring_resume(drm_mach64_private_t * dev_priv,
static __inline__ void mach64_ring_tick(drm_mach64_private_t * dev_priv,
drm_mach64_descriptor_ring_t * ring)
{
- DRM_DEBUG("%s: head_addr: 0x%08x head: %d tail: %d space: %d\n",
- __FUNCTION__,
+ DRM_DEBUG("head_addr: 0x%08x head: %d tail: %d space: %d\n",
ring->head_addr, ring->head, ring->tail, ring->space);
if (!dev_priv->ring_running) {
@@ -657,8 +656,7 @@ static __inline__ void mach64_ring_tick(drm_mach64_private_t * dev_priv,
static __inline__ void mach64_ring_stop(drm_mach64_private_t * dev_priv)
{
- DRM_DEBUG("%s: head_addr: 0x%08x head: %d tail: %d space: %d\n",
- __FUNCTION__,
+ DRM_DEBUG("head_addr: 0x%08x head: %d tail: %d space: %d\n",
dev_priv->ring.head_addr, dev_priv->ring.head,
dev_priv->ring.tail, dev_priv->ring.space);
@@ -679,7 +677,7 @@ mach64_update_ring_snapshot(drm_mach64_private_t * dev_priv)
{
drm_mach64_descriptor_ring_t *ring = &dev_priv->ring;
- DRM_DEBUG("%s\n", __FUNCTION__);
+ DRM_DEBUG("\n");
mach64_ring_tick(dev_priv, ring);
@@ -720,7 +718,7 @@ static __inline__ int mach64_find_pending_buf_entry(drm_mach64_private_t *
struct list_head *ptr;
#if MACH64_EXTRA_CHECKING
if (list_empty(&dev_priv->pending)) {
- DRM_ERROR("Empty pending list in %s\n", __FUNCTION__);
+ DRM_ERROR("Empty pending list in \n");
return -EINVAL;
}
#endif
@@ -747,18 +745,15 @@ do { \
#define DMAGETPTR( file_priv, dev_priv, n ) \
do { \
if ( MACH64_VERBOSE ) { \
- DRM_INFO( "DMAGETPTR( %d ) in %s\n", \
- n, __FUNCTION__ ); \
+ DRM_INFO( "DMAGETPTR( %d )\n", (n) ); \
} \
_buf = mach64_freelist_get( dev_priv ); \
if (_buf == NULL) { \
- DRM_ERROR("%s: couldn't get buffer in DMAGETPTR\n", \
- __FUNCTION__ ); \
+ DRM_ERROR("couldn't get buffer in DMAGETPTR\n"); \
return -EAGAIN; \
} \
if (_buf->pending) { \
- DRM_ERROR("%s: pending buf in DMAGETPTR\n", \
- __FUNCTION__ ); \
+ DRM_ERROR("pending buf in DMAGETPTR\n"); \
return -EFAULT; \
} \
_buf->file_priv = file_priv; \
@@ -778,92 +773,87 @@ do { \
_buf->used += 8; \
} while (0)
-#define DMAADVANCE( dev_priv, _discard ) \
-do { \
- struct list_head *ptr; \
- int ret; \
- \
- if ( MACH64_VERBOSE ) { \
- DRM_INFO( "DMAADVANCE() in %s\n", __FUNCTION__ ); \
- } \
- \
- if (_buf->used <= 0) { \
- DRM_ERROR( "DMAADVANCE() in %s: sending empty buf %d\n", \
- __FUNCTION__, _buf->idx ); \
- return -EFAULT; \
- } \
- if (_buf->pending) { \
- /* This is a resued buffer, so we need to find it in the pending list */ \
- if ( (ret=mach64_find_pending_buf_entry(dev_priv, &_entry, _buf)) ) { \
- DRM_ERROR( "DMAADVANCE() in %s: couldn't find pending buf %d\n", \
- __FUNCTION__, _buf->idx ); \
- return ret; \
- } \
- if (_entry->discard) { \
- DRM_ERROR( "DMAADVANCE() in %s: sending discarded pending buf %d\n", \
- __FUNCTION__, _buf->idx ); \
- return -EFAULT; \
- } \
- } else { \
- if (list_empty(&dev_priv->placeholders)) { \
- DRM_ERROR( "DMAADVANCE() in %s: empty placeholder list\n", \
- __FUNCTION__ ); \
- return -EFAULT; \
- } \
- ptr = dev_priv->placeholders.next; \
- list_del(ptr); \
- _entry = list_entry(ptr, drm_mach64_freelist_t, list); \
- _buf->pending = 1; \
- _entry->buf = _buf; \
- list_add_tail(ptr, &dev_priv->pending); \
- } \
- _entry->discard = (_discard); \
- if ( (ret = mach64_add_buf_to_ring( dev_priv, _entry )) ) \
- return ret; \
-} while (0)
-
-#define DMADISCARDBUF() \
-do { \
- if (_entry == NULL) { \
- int ret; \
- if ( (ret=mach64_find_pending_buf_entry(dev_priv, &_entry, _buf)) ) { \
- DRM_ERROR( "%s: couldn't find pending buf %d\n", \
- __FUNCTION__, _buf->idx ); \
- return ret; \
- } \
- } \
- _entry->discard = 1; \
-} while(0)
-
-#define DMAADVANCEHOSTDATA( dev_priv ) \
-do { \
- struct list_head *ptr; \
- int ret; \
- \
- if ( MACH64_VERBOSE ) { \
- DRM_INFO( "DMAADVANCEHOSTDATA() in %s\n", __FUNCTION__ ); \
- } \
- \
- if (_buf->used <= 0) { \
- DRM_ERROR( "DMAADVANCEHOSTDATA() in %s: sending empty buf %d\n", \
- __FUNCTION__, _buf->idx ); \
- return -EFAULT; \
- } \
- if (list_empty(&dev_priv->placeholders)) { \
- DRM_ERROR( "%s: empty placeholder list in DMAADVANCEHOSTDATA()\n", \
- __FUNCTION__ ); \
- return -EFAULT; \
- } \
- \
- ptr = dev_priv->placeholders.next; \
- list_del(ptr); \
- _entry = list_entry(ptr, drm_mach64_freelist_t, list); \
- _entry->buf = _buf; \
- _entry->buf->pending = 1; \
- list_add_tail(ptr, &dev_priv->pending); \
- _entry->discard = 1; \
- if ( (ret = mach64_add_hostdata_buf_to_ring( dev_priv, _entry )) ) \
- return ret; \
-} while (0)
+#define DMAADVANCE( dev_priv, _discard ) \
+ do { \
+ struct list_head *ptr; \
+ int ret; \
+ \
+ if ( MACH64_VERBOSE ) { \
+ DRM_INFO( "DMAADVANCE() in \n" ); \
+ } \
+ \
+ if (_buf->used <= 0) { \
+ DRM_ERROR( "DMAADVANCE(): sending empty buf %d\n", \
+ _buf->idx ); \
+ return -EFAULT; \
+ } \
+ if (_buf->pending) { \
+ /* This is a resued buffer, so we need to find it in the pending list */ \
+ if ((ret = mach64_find_pending_buf_entry(dev_priv, &_entry, _buf))) { \
+ DRM_ERROR( "DMAADVANCE(): couldn't find pending buf %d\n", _buf->idx ); \
+ return ret; \
+ } \
+ if (_entry->discard) { \
+ DRM_ERROR( "DMAADVANCE(): sending discarded pending buf %d\n", _buf->idx ); \
+ return -EFAULT; \
+ } \
+ } else { \
+ if (list_empty(&dev_priv->placeholders)) { \
+ DRM_ERROR( "DMAADVANCE(): empty placeholder list\n"); \
+ return -EFAULT; \
+ } \
+ ptr = dev_priv->placeholders.next; \
+ list_del(ptr); \
+ _entry = list_entry(ptr, drm_mach64_freelist_t, list); \
+ _buf->pending = 1; \
+ _entry->buf = _buf; \
+ list_add_tail(ptr, &dev_priv->pending); \
+ } \
+ _entry->discard = (_discard); \
+ if ((ret = mach64_add_buf_to_ring( dev_priv, _entry ))) \
+ return ret; \
+ } while (0)
+
+#define DMADISCARDBUF() \
+ do { \
+ if (_entry == NULL) { \
+ int ret; \
+ if ((ret = mach64_find_pending_buf_entry(dev_priv, &_entry, _buf))) { \
+ DRM_ERROR( "couldn't find pending buf %d\n", \
+ _buf->idx ); \
+ return ret; \
+ } \
+ } \
+ _entry->discard = 1; \
+ } while(0)
+
+#define DMAADVANCEHOSTDATA( dev_priv ) \
+ do { \
+ struct list_head *ptr; \
+ int ret; \
+ \
+ if ( MACH64_VERBOSE ) { \
+ DRM_INFO( "DMAADVANCEHOSTDATA() in \n" ); \
+ } \
+ \
+ if (_buf->used <= 0) { \
+ DRM_ERROR( "DMAADVANCEHOSTDATA(): sending empty buf %d\n", _buf->idx ); \
+ return -EFAULT; \
+ } \
+ if (list_empty(&dev_priv->placeholders)) { \
+ DRM_ERROR( "empty placeholder list in DMAADVANCEHOSTDATA()\n" ); \
+ return -EFAULT; \
+ } \
+ \
+ ptr = dev_priv->placeholders.next; \
+ list_del(ptr); \
+ _entry = list_entry(ptr, drm_mach64_freelist_t, list); \
+ _entry->buf = _buf; \
+ _entry->buf->pending = 1; \
+ list_add_tail(ptr, &dev_priv->pending); \
+ _entry->discard = 1; \
+ if ((ret = mach64_add_hostdata_buf_to_ring( dev_priv, _entry ))) \
+ return ret; \
+ } while (0)
#endif /* __MACH64_DRV_H__ */
diff --git a/shared-core/mach64_irq.c b/shared-core/mach64_irq.c
index 4122dd91..2d522a6c 100644
--- a/shared-core/mach64_irq.c
+++ b/shared-core/mach64_irq.c
@@ -42,9 +42,8 @@
irqreturn_t mach64_driver_irq_handler(DRM_IRQ_ARGS)
{
- struct drm_device *dev = (struct drm_device *) arg;
- drm_mach64_private_t *dev_priv =
- (drm_mach64_private_t *) dev->dev_private;
+ struct drm_device *dev = arg;
+ drm_mach64_private_t *dev_priv = dev->dev_private;
int status;
status = MACH64_READ(MACH64_CRTC_INT_CNTL);
@@ -62,74 +61,81 @@ irqreturn_t mach64_driver_irq_handler(DRM_IRQ_ARGS)
(status & ~MACH64_CRTC_INT_ACKS)
| MACH64_CRTC_VBLANK_INT);
- atomic_inc(&dev->vbl_received);
- DRM_WAKEUP(&dev->vbl_queue);
- drm_vbl_send_signals(dev);
+ atomic_inc(&dev_priv->vbl_received);
+ drm_handle_vblank(dev, 0);
return IRQ_HANDLED;
}
return IRQ_NONE;
}
-int mach64_driver_vblank_wait(struct drm_device * dev, unsigned int *sequence)
+u32 mach64_get_vblank_counter(struct drm_device * dev, int crtc)
{
- unsigned int cur_vblank;
- int ret = 0;
-
- /* Assume that the user has missed the current sequence number
- * by about a day rather than she wants to wait for years
- * using vertical blanks...
- */
- DRM_WAIT_ON(ret, dev->vbl_queue, 3 * DRM_HZ,
- (((cur_vblank = atomic_read(&dev->vbl_received))
- - *sequence) <= (1 << 23)));
+ const drm_mach64_private_t *const dev_priv = dev->dev_private;
+
+ if (crtc != 0) {
+ return 0;
+ }
+
+ return atomic_read(&dev_priv->vbl_received);
+}
- *sequence = cur_vblank;
+int mach64_enable_vblank(struct drm_device * dev, int crtc)
+{
+ drm_mach64_private_t *dev_priv = dev->dev_private;
+ u32 status = MACH64_READ(MACH64_CRTC_INT_CNTL);
+
+ if (crtc != 0) {
+ DRM_ERROR("tried to enable vblank on non-existent crtc %d\n", crtc);
+ return 0;
+ }
+
+ DRM_DEBUG("before enable vblank CRTC_INT_CTNL: 0x%08x\n", status);
+
+ /* Turn on VBLANK interrupt */
+ MACH64_WRITE(MACH64_CRTC_INT_CNTL, MACH64_READ(MACH64_CRTC_INT_CNTL)
+ | MACH64_CRTC_VBLANK_INT_EN);
- return ret;
+ return 0;
}
-/* drm_dma.h hooks
-*/
-void mach64_driver_irq_preinstall(struct drm_device * dev)
-{
- drm_mach64_private_t *dev_priv =
- (drm_mach64_private_t *) dev->dev_private;
+void mach64_disable_vblank(struct drm_device * dev, int crtc)
+{
+ drm_mach64_private_t *dev_priv = dev->dev_private;
u32 status = MACH64_READ(MACH64_CRTC_INT_CNTL);
- DRM_DEBUG("before install CRTC_INT_CTNL: 0x%08x\n", status);
+ DRM_DEBUG("before disable vblank CRTC_INT_CTNL: 0x%08x\n", status);
/* Disable and clear VBLANK interrupt */
MACH64_WRITE(MACH64_CRTC_INT_CNTL, (status & ~MACH64_CRTC_VBLANK_INT_EN)
| MACH64_CRTC_VBLANK_INT);
}
-void mach64_driver_irq_postinstall(struct drm_device * dev)
+/* drm_dma.h hooks
+*/
+void mach64_driver_irq_preinstall(struct drm_device * dev)
{
- drm_mach64_private_t *dev_priv =
- (drm_mach64_private_t *) dev->dev_private;
+ drm_mach64_private_t *dev_priv = dev->dev_private;
- /* Turn on VBLANK interrupt */
- MACH64_WRITE(MACH64_CRTC_INT_CNTL, MACH64_READ(MACH64_CRTC_INT_CNTL)
- | MACH64_CRTC_VBLANK_INT_EN);
+ u32 status = MACH64_READ(MACH64_CRTC_INT_CNTL);
- DRM_DEBUG("after install CRTC_INT_CTNL: 0x%08x\n",
- MACH64_READ(MACH64_CRTC_INT_CNTL));
+ DRM_DEBUG("before install CRTC_INT_CTNL: 0x%08x\n", status);
+ mach64_disable_vblank(dev,0);
+}
+
+int mach64_driver_irq_postinstall(struct drm_device * dev)
+{
+ return drm_vblank_init(dev, 1);
}
void mach64_driver_irq_uninstall(struct drm_device * dev)
{
- drm_mach64_private_t *dev_priv =
- (drm_mach64_private_t *) dev->dev_private;
+ drm_mach64_private_t *dev_priv = dev->dev_private;
if (!dev_priv)
return;
- /* Disable and clear VBLANK interrupt */
- MACH64_WRITE(MACH64_CRTC_INT_CNTL,
- (MACH64_READ(MACH64_CRTC_INT_CNTL) &
- ~MACH64_CRTC_VBLANK_INT_EN)
- | MACH64_CRTC_VBLANK_INT);
+ mach64_disable_vblank(dev, 0);
DRM_DEBUG("after uninstall CRTC_INT_CTNL: 0x%08x\n",
MACH64_READ(MACH64_CRTC_INT_CNTL));
diff --git a/shared-core/mach64_state.c b/shared-core/mach64_state.c
index 88ff4843..c82f38bb 100644
--- a/shared-core/mach64_state.c
+++ b/shared-core/mach64_state.c
@@ -95,7 +95,7 @@ static int mach64_emit_cliprect(struct drm_file *file_priv,
drm_mach64_context_regs_t *regs = &sarea_priv->context_state;
DMALOCALS;
- DRM_DEBUG("%s: box=%p\n", __FUNCTION__, box);
+ DRM_DEBUG("box=%p\n", box);
/* Get GL scissor */
/* FIXME: store scissor in SAREA as a cliprect instead of in
@@ -146,7 +146,7 @@ static __inline__ int mach64_emit_state(struct drm_file *file_priv,
if (MACH64_VERBOSE) {
mach64_print_dirty(__FUNCTION__, dirty);
} else {
- DRM_DEBUG("%s: dirty=0x%08x\n", __FUNCTION__, dirty);
+ DRM_DEBUG("dirty=0x%08x\n", dirty);
}
DMAGETPTR(file_priv, dev_priv, 17); /* returns on failure to get buffer */
@@ -229,7 +229,7 @@ static int mach64_dma_dispatch_clear(struct drm_device * dev,
int i;
DMALOCALS;
- DRM_DEBUG("%s\n", __FUNCTION__);
+ DRM_DEBUG("\n");
switch (dev_priv->fb_bpp) {
case 16:
@@ -368,7 +368,7 @@ static int mach64_dma_dispatch_swap(struct drm_device * dev,
int i;
DMALOCALS;
- DRM_DEBUG("%s\n", __FUNCTION__);
+ DRM_DEBUG("\n");
switch (dev_priv->fb_bpp) {
case 16:
@@ -445,7 +445,7 @@ static int mach64_do_get_frames_queued(drm_mach64_private_t * dev_priv)
int i, start;
u32 head, tail, ofs;
- DRM_DEBUG("%s\n", __FUNCTION__);
+ DRM_DEBUG("\n");
if (sarea_priv->frames_queued == 0)
return 0;
@@ -525,15 +525,14 @@ static __inline__ int copy_from_user_vertex(u32 *to,
from += count;
to += count;
} else {
- DRM_ERROR("%s: Got bad command: 0x%04x\n",
- __FUNCTION__, reg);
+ DRM_ERROR("Got bad command: 0x%04x\n", reg);
drm_free(orig_from, bytes, DRM_MEM_DRIVER);
return -EACCES;
}
} else {
DRM_ERROR
- ("%s: Got bad command count(=%u) dwords remaining=%lu\n",
- __FUNCTION__, count, n);
+ ("Got bad command count(=%u) dwords remaining=%lu\n",
+ count, n);
drm_free(orig_from, bytes, DRM_MEM_DRIVER);
return -EINVAL;
}
@@ -543,7 +542,7 @@ static __inline__ int copy_from_user_vertex(u32 *to,
if (n == 0)
return 0;
else {
- DRM_ERROR("%s: Bad buf->used(=%lu)\n", __FUNCTION__, bytes);
+ DRM_ERROR("Bad buf->used(=%lu)\n", bytes);
return -EINVAL;
}
}
@@ -563,15 +562,15 @@ static int mach64_dma_dispatch_vertex(struct drm_device * dev,
int verify_ret = 0;
DMALOCALS;
- DRM_DEBUG("%s: buf=%p used=%lu nbox=%d\n",
- __FUNCTION__, buf, used, sarea_priv->nbox);
+ DRM_DEBUG("buf=%p used=%lu nbox=%d\n",
+ buf, used, sarea_priv->nbox);
if (!used)
goto _vertex_done;
copy_buf = mach64_freelist_get(dev_priv);
if (copy_buf == NULL) {
- DRM_ERROR("%s: couldn't get buffer\n", __FUNCTION__);
+ DRM_ERROR("couldn't get buffer\n");
return -EAGAIN;
}
@@ -698,7 +697,7 @@ static int mach64_dma_dispatch_blit(struct drm_device * dev,
copy_buf = mach64_freelist_get(dev_priv);
if (copy_buf == NULL) {
- DRM_ERROR("%s: couldn't get buffer\n", __FUNCTION__);
+ DRM_ERROR("couldn't get buffer\n");
return -EAGAIN;
}
@@ -759,7 +758,7 @@ static int mach64_dma_dispatch_blit(struct drm_device * dev,
DMAOUTREG(MACH64_DST_X_Y, (blit->y << 16) | blit->x);
DMAOUTREG(MACH64_DST_WIDTH_HEIGHT, (blit->height << 16) | blit->width);
- DRM_DEBUG("%s: %lu bytes\n", __FUNCTION__, used);
+ DRM_DEBUG("%lu bytes\n", used);
/* Add the buffer to the queue */
DMAADVANCEHOSTDATA(dev_priv);
@@ -780,7 +779,7 @@ int mach64_dma_clear(struct drm_device *dev, void *data,
drm_mach64_clear_t *clear = data;
int ret;
- DRM_DEBUG("%s: pid=%d\n", __FUNCTION__, DRM_CURRENTPID);
+ DRM_DEBUG("pid=%d\n", DRM_CURRENTPID);
LOCK_TEST_WITH_RETURN(dev, file_priv);
@@ -805,7 +804,7 @@ int mach64_dma_swap(struct drm_device *dev, void *data,
drm_mach64_sarea_t *sarea_priv = dev_priv->sarea_priv;
int ret;
- DRM_DEBUG("%s: pid=%d\n", __FUNCTION__, DRM_CURRENTPID);
+ DRM_DEBUG("pid=%d\n", DRM_CURRENTPID);
LOCK_TEST_WITH_RETURN(dev, file_priv);
@@ -830,12 +829,12 @@ int mach64_dma_vertex(struct drm_device *dev, void *data,
LOCK_TEST_WITH_RETURN(dev, file_priv);
if (!dev_priv) {
- DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
+ DRM_ERROR("called with no initialization\n");
return -EINVAL;
}
- DRM_DEBUG("%s: pid=%d buf=%p used=%lu discard=%d\n",
- __FUNCTION__, DRM_CURRENTPID,
+ DRM_DEBUG("pid=%d buf=%p used=%lu discard=%d\n",
+ DRM_CURRENTPID,
vertex->buf, vertex->used, vertex->discard);
if (vertex->prim < 0 || vertex->prim > MACH64_PRIM_POLYGON) {
@@ -882,10 +881,10 @@ int mach64_get_param(struct drm_device *dev, void *data,
drm_mach64_getparam_t *param = data;
int value;
- DRM_DEBUG("%s\n", __FUNCTION__);
+ DRM_DEBUG("\n");
if (!dev_priv) {
- DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
+ DRM_ERROR("called with no initialization\n");
return -EINVAL;
}
diff --git a/shared-core/mga_dma.c b/shared-core/mga_dma.c
index 67236b2d..d56f4d7a 100644
--- a/shared-core/mga_dma.c
+++ b/shared-core/mga_dma.c
@@ -997,7 +997,7 @@ static int mga_do_cleanup_dma(struct drm_device *dev, int full_cleanup)
}
}
- return 0;
+ return err;
}
int mga_dma_init(struct drm_device *dev, void *data,
@@ -1049,7 +1049,7 @@ int mga_dma_flush(struct drm_device *dev, void *data,
#if MGA_DMA_DEBUG
int ret = mga_do_wait_for_idle(dev_priv);
if (ret < 0)
- DRM_INFO("%s: -EBUSY\n", __FUNCTION__);
+ DRM_INFO("-EBUSY\n");
return ret;
#else
return mga_do_wait_for_idle(dev_priv);
diff --git a/shared-core/mga_drv.h b/shared-core/mga_drv.h
index 0c7fab5b..bf3be808 100644
--- a/shared-core/mga_drv.h
+++ b/shared-core/mga_drv.h
@@ -113,13 +113,14 @@ typedef struct drm_mga_private {
* \sa drm_mga_private_t::mmio
*/
/*@{*/
- u32 mmio_base; /**< Bus address of base of MMIO. */
- u32 mmio_size; /**< Size of the MMIO region. */
+ u32 mmio_base; /**< Bus address of base of MMIO. */
+ u32 mmio_size; /**< Size of the MMIO region. */
/*@}*/
u32 clear_cmd;
u32 maccess;
+ atomic_t vbl_received; /**< Number of vblanks received. */
wait_queue_head_t fence_queue;
atomic_t last_fence_retired;
u32 next_fence_to_post;
@@ -181,11 +182,14 @@ extern int mga_warp_install_microcode(drm_mga_private_t * dev_priv);
extern int mga_warp_init(drm_mga_private_t * dev_priv);
/* mga_irq.c */
+extern int mga_enable_vblank(struct drm_device *dev, int crtc);
+extern void mga_disable_vblank(struct drm_device *dev, int crtc);
+extern u32 mga_get_vblank_counter(struct drm_device *dev, int crtc);
extern int mga_driver_fence_wait(struct drm_device * dev, unsigned int *sequence);
extern int mga_driver_vblank_wait(struct drm_device * dev, unsigned int *sequence);
extern irqreturn_t mga_driver_irq_handler(DRM_IRQ_ARGS);
extern void mga_driver_irq_preinstall(struct drm_device * dev);
-extern void mga_driver_irq_postinstall(struct drm_device * dev);
+extern int mga_driver_irq_postinstall(struct drm_device * dev);
extern void mga_driver_irq_uninstall(struct drm_device * dev);
extern long mga_compat_ioctl(struct file *filp, unsigned int cmd,
unsigned long arg);
@@ -249,7 +253,7 @@ do { \
} else if ( dev_priv->prim.space < \
dev_priv->prim.high_mark ) { \
if ( MGA_DMA_DEBUG ) \
- DRM_INFO( "%s: wrap...\n", __FUNCTION__ ); \
+ DRM_INFO( "wrap...\n"); \
return -EBUSY; \
} \
} \
@@ -260,7 +264,7 @@ do { \
if ( test_bit( 0, &dev_priv->prim.wrapped ) ) { \
if ( mga_do_wait_for_idle( dev_priv ) < 0 ) { \
if ( MGA_DMA_DEBUG ) \
- DRM_INFO( "%s: wrap...\n", __FUNCTION__ ); \
+ DRM_INFO( "wrap...\n"); \
return -EBUSY; \
} \
mga_do_dma_wrap_end( dev_priv ); \
@@ -280,8 +284,7 @@ do { \
#define BEGIN_DMA( n ) \
do { \
if ( MGA_VERBOSE ) { \
- DRM_INFO( "BEGIN_DMA( %d ) in %s\n", \
- (n), __FUNCTION__ ); \
+ DRM_INFO( "BEGIN_DMA( %d )\n", (n) ); \
DRM_INFO( " space=0x%x req=0x%Zx\n", \
dev_priv->prim.space, (n) * DMA_BLOCK_SIZE ); \
} \
@@ -292,7 +295,7 @@ do { \
#define BEGIN_DMA_WRAP() \
do { \
if ( MGA_VERBOSE ) { \
- DRM_INFO( "BEGIN_DMA() in %s\n", __FUNCTION__ ); \
+ DRM_INFO( "BEGIN_DMA()\n" ); \
DRM_INFO( " space=0x%x\n", dev_priv->prim.space ); \
} \
prim = dev_priv->prim.start; \
@@ -311,7 +314,7 @@ do { \
#define FLUSH_DMA() \
do { \
if ( 0 ) { \
- DRM_INFO( "%s:\n", __FUNCTION__ ); \
+ DRM_INFO( "\n" ); \
DRM_INFO( " tail=0x%06x head=0x%06lx\n", \
dev_priv->prim.tail, \
MGA_READ( MGA_PRIMADDRESS ) - \
diff --git a/shared-core/mga_irq.c b/shared-core/mga_irq.c
index 0f83577f..4fe86322 100644
--- a/shared-core/mga_irq.c
+++ b/shared-core/mga_irq.c
@@ -36,6 +36,20 @@
#include "mga_drm.h"
#include "mga_drv.h"
+u32 mga_get_vblank_counter(struct drm_device *dev, int crtc)
+{
+ const drm_mga_private_t *const dev_priv =
+ (drm_mga_private_t *) dev->dev_private;
+
+ if (crtc != 0) {
+ return 0;
+ }
+
+
+ return atomic_read(&dev_priv->vbl_received);
+}
+
+
irqreturn_t mga_driver_irq_handler(DRM_IRQ_ARGS)
{
struct drm_device *dev = (struct drm_device *) arg;
@@ -48,9 +62,8 @@ irqreturn_t mga_driver_irq_handler(DRM_IRQ_ARGS)
/* VBLANK interrupt */
if (status & MGA_VLINEPEN) {
MGA_WRITE(MGA_ICLEAR, MGA_VLINEICLR);
- atomic_inc(&dev->vbl_received);
- DRM_WAKEUP(&dev->vbl_queue);
- drm_vbl_send_signals(dev);
+ atomic_inc(&dev_priv->vbl_received);
+ drm_handle_vblank(dev, 0);
handled = 1;
}
@@ -79,22 +92,34 @@ irqreturn_t mga_driver_irq_handler(DRM_IRQ_ARGS)
return IRQ_NONE;
}
-int mga_driver_vblank_wait(struct drm_device * dev, unsigned int *sequence)
+int mga_enable_vblank(struct drm_device *dev, int crtc)
{
- unsigned int cur_vblank;
- int ret = 0;
+ drm_mga_private_t *dev_priv = (drm_mga_private_t *) dev->dev_private;
- /* Assume that the user has missed the current sequence number
- * by about a day rather than she wants to wait for years
- * using vertical blanks...
- */
- DRM_WAIT_ON(ret, dev->vbl_queue, 3 * DRM_HZ,
- (((cur_vblank = atomic_read(&dev->vbl_received))
- - *sequence) <= (1 << 23)));
+ if (crtc != 0) {
+ DRM_ERROR("tried to enable vblank on non-existent crtc %d\n",
+ crtc);
+ return 0;
+ }
- *sequence = cur_vblank;
+ MGA_WRITE(MGA_IEN, MGA_VLINEIEN | MGA_SOFTRAPEN);
+ return 0;
+}
- return ret;
+
+void mga_disable_vblank(struct drm_device *dev, int crtc)
+{
+ if (crtc != 0) {
+ DRM_ERROR("tried to disable vblank on non-existent crtc %d\n",
+ crtc);
+ }
+
+ /* Do *NOT* disable the vertical refresh interrupt. MGA doesn't have
+ * a nice hardware counter that tracks the number of refreshes when
+ * the interrupt is disabled, and the kernel doesn't know the refresh
+ * rate to calculate an estimate.
+ */
+ /* MGA_WRITE(MGA_IEN, MGA_VLINEIEN | MGA_SOFTRAPEN); */
}
int mga_driver_fence_wait(struct drm_device * dev, unsigned int *sequence)
@@ -126,14 +151,22 @@ void mga_driver_irq_preinstall(struct drm_device * dev)
MGA_WRITE(MGA_ICLEAR, ~0);
}
-void mga_driver_irq_postinstall(struct drm_device * dev)
+int mga_driver_irq_postinstall(struct drm_device * dev)
{
drm_mga_private_t *dev_priv = (drm_mga_private_t *) dev->dev_private;
+ int ret;
+
+ ret = drm_vblank_init(dev, 1);
+ if (ret)
+ return ret;
DRM_INIT_WAITQUEUE(&dev_priv->fence_queue);
- /* Turn on vertical blank interrupt and soft trap interrupt. */
- MGA_WRITE(MGA_IEN, MGA_VLINEIEN | MGA_SOFTRAPEN);
+ /* Turn on soft trap interrupt. Vertical blank interrupts are enabled
+ * in mga_enable_vblank.
+ */
+ MGA_WRITE(MGA_IEN, MGA_SOFTRAPEN);
+ return 0;
}
void mga_driver_irq_uninstall(struct drm_device * dev)
diff --git a/shared-core/mga_state.c b/shared-core/mga_state.c
index d9cc9d7e..2da108be 100644
--- a/shared-core/mga_state.c
+++ b/shared-core/mga_state.c
@@ -644,7 +644,7 @@ static void mga_dma_dispatch_swap(struct drm_device * dev)
FLUSH_DMA();
- DRM_DEBUG("%s... done.\n", __FUNCTION__);
+ DRM_DEBUG("... done.\n");
}
static void mga_dma_dispatch_vertex(struct drm_device * dev, struct drm_buf * buf)
@@ -656,7 +656,7 @@ static void mga_dma_dispatch_vertex(struct drm_device * dev, struct drm_buf * bu
u32 length = (u32) buf->used;
int i = 0;
DMA_LOCALS;
- DRM_DEBUG("vertex: buf=%d used=%d\n", buf->idx, buf->used);
+ DRM_DEBUG("buf=%d used=%d\n", buf->idx, buf->used);
if (buf->used) {
buf_priv->dispatched = 1;
@@ -703,7 +703,7 @@ static void mga_dma_dispatch_indices(struct drm_device * dev, struct drm_buf * b
u32 address = (u32) buf->bus_address;
int i = 0;
DMA_LOCALS;
- DRM_DEBUG("indices: buf=%d start=%d end=%d\n", buf->idx, start, end);
+ DRM_DEBUG("buf=%d start=%d end=%d\n", buf->idx, start, end);
if (start != end) {
buf_priv->dispatched = 1;
@@ -988,7 +988,7 @@ static int mga_dma_iload(struct drm_device *dev, void *data, struct drm_file *fi
#if 0
if (mga_do_wait_for_idle(dev_priv) < 0) {
if (MGA_DMA_DEBUG)
- DRM_INFO("%s: -EBUSY\n", __FUNCTION__);
+ DRM_INFO("-EBUSY\n");
return -EBUSY;
}
#endif
@@ -1047,7 +1047,7 @@ static int mga_getparam(struct drm_device *dev, void *data, struct drm_file *fil
int value;
if (!dev_priv) {
- DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
+ DRM_ERROR("called with no initialization\n");
return -EINVAL;
}
@@ -1079,7 +1079,7 @@ static int mga_set_fence(struct drm_device *dev, void *data, struct drm_file *fi
DMA_LOCALS;
if (!dev_priv) {
- DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
+ DRM_ERROR("called with no initialization\n");
return -EINVAL;
}
@@ -1108,7 +1108,7 @@ static int mga_wait_fence(struct drm_device *dev, void *data, struct drm_file *f
u32 *fence = data;
if (!dev_priv) {
- DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
+ DRM_ERROR("called with no initialization\n");
return -EINVAL;
}
diff --git a/shared-core/nouveau_drv.h b/shared-core/nouveau_drv.h
index 85a0d0b5..4184aa5b 100644
--- a/shared-core/nouveau_drv.h
+++ b/shared-core/nouveau_drv.h
@@ -432,7 +432,7 @@ extern int nouveau_ioctl_gpuobj_free(struct drm_device *, void *data,
/* nouveau_irq.c */
extern irqreturn_t nouveau_irq_handler(DRM_IRQ_ARGS);
extern void nouveau_irq_preinstall(struct drm_device *);
-extern void nouveau_irq_postinstall(struct drm_device *);
+extern int nouveau_irq_postinstall(struct drm_device *);
extern void nouveau_irq_uninstall(struct drm_device *);
/* nouveau_sgdma.c */
diff --git a/shared-core/nouveau_irq.c b/shared-core/nouveau_irq.c
index 500fda2f..bceb81ab 100644
--- a/shared-core/nouveau_irq.c
+++ b/shared-core/nouveau_irq.c
@@ -46,13 +46,15 @@ nouveau_irq_preinstall(struct drm_device *dev)
NV_WRITE(NV03_PMC_INTR_EN_0, 0);
}
-void
+int
nouveau_irq_postinstall(struct drm_device *dev)
{
struct drm_nouveau_private *dev_priv = dev->dev_private;
/* Master enable */
NV_WRITE(NV03_PMC_INTR_EN_0, NV_PMC_INTR_EN_0_MASTER_ENABLE);
+
+ return 0;
}
void
diff --git a/shared-core/nouveau_mem.c b/shared-core/nouveau_mem.c
index 5259ea27..f4e641b9 100644
--- a/shared-core/nouveau_mem.c
+++ b/shared-core/nouveau_mem.c
@@ -619,7 +619,7 @@ alloc_ok:
block->map_handle = entry->user_token;
}
- DRM_DEBUG("allocated 0x%llx type=0x%08x\n", block->start, block->flags);
+ DRM_DEBUG("allocated %lld bytes at 0x%llx type=0x%08x\n", block->size, block->start, block->flags);
return block;
}
diff --git a/shared-core/nouveau_reg.h b/shared-core/nouveau_reg.h
index 7ac02f4a..a2506146 100644
--- a/shared-core/nouveau_reg.h
+++ b/shared-core/nouveau_reg.h
@@ -112,6 +112,9 @@
#define NV50_PUNK_BAR3_CTXDMA_VALID (1<<31)
#define NV50_PUNK_UNK1710 0x00001710
+#define NV04_PBUS_PCI_NV_1 0x00001804
+#define NV04_PBUS_PCI_NV_19 0x0000184C
+
#define NV04_PTIMER_INTR_0 0x00009100
#define NV04_PTIMER_INTR_EN_0 0x00009140
#define NV04_PTIMER_NUMERATOR 0x00009200
diff --git a/shared-core/nouveau_state.c b/shared-core/nouveau_state.c
index 16c86494..7086a0ab 100644
--- a/shared-core/nouveau_state.c
+++ b/shared-core/nouveau_state.c
@@ -88,7 +88,6 @@ static int nouveau_init_card_mappings(struct drm_device *dev)
static int nouveau_stub_init(struct drm_device *dev) { return 0; }
static void nouveau_stub_takedown(struct drm_device *dev) {}
-static uint64_t nouveau_stub_timer_read(struct drm_device *dev) { return 0; }
static int nouveau_init_engine_ptrs(struct drm_device *dev)
{
@@ -251,9 +250,9 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev)
engine->instmem.unbind = nv50_instmem_unbind;
engine->mc.init = nv50_mc_init;
engine->mc.takedown = nv50_mc_takedown;
- engine->timer.init = nouveau_stub_init;
- engine->timer.read = nouveau_stub_timer_read;
- engine->timer.takedown = nouveau_stub_takedown;
+ engine->timer.init = nv04_timer_init;
+ engine->timer.read = nv04_timer_read;
+ engine->timer.takedown = nv04_timer_takedown;
engine->fb.init = nouveau_stub_init;
engine->fb.takedown = nouveau_stub_takedown;
engine->graph.init = nv50_graph_init;
@@ -285,9 +284,6 @@ nouveau_card_init(struct drm_device *dev)
struct drm_nouveau_private *dev_priv = dev->dev_private;
struct nouveau_engine *engine;
int ret;
-#if defined(__powerpc__)
- struct device_node *dn;
-#endif
DRM_DEBUG("prev state = %d\n", dev_priv->init_state);
@@ -295,43 +291,6 @@ nouveau_card_init(struct drm_device *dev)
return 0;
dev_priv->ttm = 0;
- /* Map any PCI resources we need on the card */
- ret = nouveau_init_card_mappings(dev);
- if (ret) return ret;
-
-#if defined(__powerpc__)
- /* Put the card in BE mode if it's not */
- if (NV_READ(NV03_PMC_BOOT_1))
- NV_WRITE(NV03_PMC_BOOT_1,0x00000001);
-
- DRM_MEMORYBARRIER();
-#endif
-
-#if defined(__linux__) && defined(__powerpc__)
- /* if we have an OF card, copy vbios to RAMIN */
- dn = pci_device_to_OF_node(dev->pdev);
- if (dn)
- {
- int size;
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22))
- const uint32_t *bios = of_get_property(dn, "NVDA,BMP", &size);
-#else
- const uint32_t *bios = get_property(dn, "NVDA,BMP", &size);
-#endif
- if (bios)
- {
- int i;
- for(i=0;i<size;i+=4)
- NV_WI32(i, bios[i/4]);
- DRM_INFO("OF bios successfully copied (%d bytes)\n",size);
- }
- else
- DRM_INFO("Unable to get the OF bios\n");
- }
- else
- DRM_INFO("Unable to get the OF node\n");
-#endif
-
/* Determine exact chipset we're running on */
if (dev_priv->card_type < NV_10)
dev_priv->chipset = dev_priv->card_type;
@@ -451,6 +410,47 @@ void nouveau_preclose(struct drm_device *dev, struct drm_file *file_priv)
/* first module load, setup the mmio/fb mapping */
int nouveau_firstopen(struct drm_device *dev)
{
+#if defined(__powerpc__)
+ struct drm_nouveau_private *dev_priv = dev->dev_private;
+ struct device_node *dn;
+#endif
+ int ret;
+ /* Map any PCI resources we need on the card */
+ ret = nouveau_init_card_mappings(dev);
+ if (ret) return ret;
+
+#if defined(__powerpc__)
+ /* Put the card in BE mode if it's not */
+ if (NV_READ(NV03_PMC_BOOT_1))
+ NV_WRITE(NV03_PMC_BOOT_1,0x00000001);
+
+ DRM_MEMORYBARRIER();
+#endif
+
+#if defined(__linux__) && defined(__powerpc__)
+ /* if we have an OF card, copy vbios to RAMIN */
+ dn = pci_device_to_OF_node(dev->pdev);
+ if (dn)
+ {
+ int size;
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,22))
+ const uint32_t *bios = of_get_property(dn, "NVDA,BMP", &size);
+#else
+ const uint32_t *bios = get_property(dn, "NVDA,BMP", &size);
+#endif
+ if (bios)
+ {
+ int i;
+ for(i=0;i<size;i+=4)
+ NV_WI32(i, bios[i/4]);
+ DRM_INFO("OF bios successfully copied (%d bytes)\n",size);
+ }
+ else
+ DRM_INFO("Unable to get the OF bios\n");
+ }
+ else
+ DRM_INFO("Unable to get the OF node\n");
+#endif
return 0;
}
@@ -498,7 +498,12 @@ int nouveau_load(struct drm_device *dev, unsigned long flags)
iounmap(regs);
- if (architecture >= 0x50) {
+ if (architecture >= 0x80) {
+ dev_priv->card_type = NV_50;
+ } else if (architecture >= 0x60) {
+ /* FIXME we need to figure out who's who for NV6x */
+ dev_priv->card_type = NV_44;
+ } else if (architecture >= 0x50) {
dev_priv->card_type = NV_50;
} else if (architecture >= 0x40) {
uint8_t subarch = architecture & 0xf;
diff --git a/shared-core/nv04_graph.c b/shared-core/nv04_graph.c
index 81a6d5c8..6caae257 100644
--- a/shared-core/nv04_graph.c
+++ b/shared-core/nv04_graph.c
@@ -497,7 +497,7 @@ int nv04_graph_init(struct drm_device *dev) {
/*haiku same*/
/*NV_WRITE(NV04_PGRAPH_DEBUG_3, 0xfad4ff31);*/
- NV_WRITE(NV04_PGRAPH_DEBUG_3, 0x10d4ff31);
+ NV_WRITE(NV04_PGRAPH_DEBUG_3, 0xf0d4ff31);
/*haiku and blob 10d4*/
NV_WRITE(NV04_PGRAPH_STATE , 0xFFFFFFFF);
diff --git a/shared-core/nv04_mc.c b/shared-core/nv04_mc.c
index 24c1f7b3..766f3a33 100644
--- a/shared-core/nv04_mc.c
+++ b/shared-core/nv04_mc.c
@@ -7,12 +7,25 @@ int
nv04_mc_init(struct drm_device *dev)
{
struct drm_nouveau_private *dev_priv = dev->dev_private;
+ uint32_t saved_pci_nv_1, saved_pci_nv_19;
+
+ saved_pci_nv_1 = NV_READ(NV04_PBUS_PCI_NV_1);
+ saved_pci_nv_19 = NV_READ(NV04_PBUS_PCI_NV_19);
+
+ /* clear busmaster bit */
+ NV_WRITE(NV04_PBUS_PCI_NV_1, saved_pci_nv_1 & ~(0x00000001 << 2));
+ /* clear SBA and AGP bits */
+ NV_WRITE(NV04_PBUS_PCI_NV_19, saved_pci_nv_19 & 0xfffff0ff);
/* Power up everything, resetting each individual unit will
* be done later if needed.
*/
NV_WRITE(NV03_PMC_ENABLE, 0xFFFFFFFF);
+ /* and restore (gives effect of resetting AGP) */
+ NV_WRITE(NV04_PBUS_PCI_NV_19, saved_pci_nv_19);
+ NV_WRITE(NV04_PBUS_PCI_NV_1, saved_pci_nv_1);
+
return 0;
}
diff --git a/shared-core/nv20_graph.c b/shared-core/nv20_graph.c
index 81501ed7..37a147b5 100644
--- a/shared-core/nv20_graph.c
+++ b/shared-core/nv20_graph.c
@@ -432,19 +432,6 @@ static void nv30_31_graph_context_init(struct drm_device *dev,
INSTANCE_WR(ctx, 0x385c/4, 0x3f800000);
INSTANCE_WR(ctx, 0x3864/4, 0xbf800000);
INSTANCE_WR(ctx, 0x386c/4, 0xbf800000);
-
- /* nv30gl stuff */
- for (i=0; i<8; i++) {
- INSTANCE_WR(ctx, (0x4dfc/4)+i, 0x001c527d);
- }
- INSTANCE_WR(ctx, 0x4e3c/4, 0x001c527c);
-/* these ones make dma fifo hang
- INSTANCE_WR(ctx, 0x567c/4, 0x000a0000);
- INSTANCE_WR(ctx, 0x0878/4, 0x01000000);
- INSTANCE_WR(ctx, 0x02f4/4, 0x0001ffff);
-
- INSTANCE_WR(ctx, 0x0028/4, INSTANCE_RD(ctx, 0x0028/4) | 1);
-*/
}
static void nv34_graph_context_init(struct drm_device *dev,
@@ -655,6 +642,7 @@ int nv20_graph_load_context(struct nouveau_channel *chan)
NV_WRITE(NV20_PGRAPH_CHANNEL_CTX_POINTER, inst);
NV_WRITE(NV20_PGRAPH_CHANNEL_CTX_XFER,
NV20_PGRAPH_CHANNEL_CTX_XFER_LOAD);
+ NV_WRITE(NV10_PGRAPH_CTX_CONTROL, 0x10010100);
nouveau_wait_for_idle(dev);
return 0;
@@ -772,7 +760,7 @@ int nv20_graph_init(struct drm_device *dev) {
NV_WRITE(NV10_PGRAPH_RDI_INDEX, 0x00EA000C);
NV_WRITE(NV10_PGRAPH_RDI_DATA, NV_READ(0x100324));
- NV_WRITE(NV10_PGRAPH_CTX_CONTROL, 0x10010100);
+ NV_WRITE(NV10_PGRAPH_CTX_CONTROL, 0x10000100);
NV_WRITE(NV10_PGRAPH_STATE , 0xFFFFFFFF);
NV_WRITE(NV04_PGRAPH_FIFO , 0x00000001);
@@ -867,7 +855,7 @@ int nv30_graph_init(struct drm_device *dev)
NV_WRITE(NV10_PGRAPH_TSTATUS(i), NV_READ(NV10_PFB_TSTATUS(i)));
}
- NV_WRITE(NV10_PGRAPH_CTX_CONTROL, 0x10010100);
+ NV_WRITE(NV10_PGRAPH_CTX_CONTROL, 0x10000100);
NV_WRITE(NV10_PGRAPH_STATE , 0xFFFFFFFF);
NV_WRITE(NV04_PGRAPH_FIFO , 0x00000001);
diff --git a/shared-core/nv50_fifo.c b/shared-core/nv50_fifo.c
index c5cde913..edf4edbf 100644
--- a/shared-core/nv50_fifo.c
+++ b/shared-core/nv50_fifo.c
@@ -28,9 +28,10 @@
#include "drm.h"
#include "nouveau_drv.h"
-typedef struct {
- struct nouveau_gpuobj_ref *thingo;
-} nv50_fifo_priv;
+struct nv50_fifo_priv {
+ struct nouveau_gpuobj_ref *thingo[2];
+ int cur_thingo;
+};
#define IS_G80 ((dev_priv->chipset & 0xf0) == 0x50)
@@ -38,23 +39,23 @@ static void
nv50_fifo_init_thingo(struct drm_device *dev)
{
struct drm_nouveau_private *dev_priv = dev->dev_private;
- nv50_fifo_priv *priv = dev_priv->Engine.fifo.priv;
- struct nouveau_gpuobj_ref *thingo = priv->thingo;
- int i, fi=2;
+ struct nv50_fifo_priv *priv = dev_priv->Engine.fifo.priv;
+ struct nouveau_gpuobj_ref *cur;
+ int i, nr;
DRM_DEBUG("\n");
- INSTANCE_WR(thingo->gpuobj, 0, 0x7e);
- INSTANCE_WR(thingo->gpuobj, 1, 0x7e);
- for (i = 1; i < 127; i++, fi) {
+ cur = priv->thingo[priv->cur_thingo];
+ priv->cur_thingo = !priv->cur_thingo;
+
+ /* We never schedule channel 0 or 127 */
+ for (i = 1, nr = 0; i < 127; i++) {
if (dev_priv->fifos[i]) {
- INSTANCE_WR(thingo->gpuobj, fi, i);
- fi++;
+ INSTANCE_WR(cur->gpuobj, nr++, i);
}
}
-
- NV_WRITE(0x32f4, thingo->instance >> 12);
- NV_WRITE(0x32ec, fi);
+ NV_WRITE(0x32f4, cur->instance >> 12);
+ NV_WRITE(0x32ec, nr);
NV_WRITE(0x2500, 0x101);
}
@@ -98,14 +99,12 @@ static void
nv50_fifo_init_reset(struct drm_device *dev)
{
struct drm_nouveau_private *dev_priv = dev->dev_private;
- uint32_t pmc_e;
+ uint32_t pmc_e = NV_PMC_ENABLE_PFIFO;
DRM_DEBUG("\n");
- pmc_e = NV_READ(NV03_PMC_ENABLE);
- NV_WRITE(NV03_PMC_ENABLE, pmc_e & ~NV_PMC_ENABLE_PFIFO);
- pmc_e = NV_READ(NV03_PMC_ENABLE);
- NV_WRITE(NV03_PMC_ENABLE, pmc_e | NV_PMC_ENABLE_PFIFO);
+ NV_WRITE(NV03_PMC_ENABLE, NV_READ(NV03_PMC_ENABLE) & ~pmc_e);
+ NV_WRITE(NV03_PMC_ENABLE, NV_READ(NV03_PMC_ENABLE) | pmc_e);
}
static void
@@ -141,7 +140,7 @@ nv50_fifo_init_regs__nv(struct drm_device *dev)
NV_WRITE(0x250c, 0x6f3cfc34);
}
-static int
+static void
nv50_fifo_init_regs(struct drm_device *dev)
{
struct drm_nouveau_private *dev_priv = dev->dev_private;
@@ -158,15 +157,13 @@ nv50_fifo_init_regs(struct drm_device *dev)
/* Enable dummy channels setup by nv50_instmem.c */
nv50_fifo_channel_enable(dev, 0, 1);
nv50_fifo_channel_enable(dev, 127, 1);
-
- return 0;
}
int
nv50_fifo_init(struct drm_device *dev)
{
struct drm_nouveau_private *dev_priv = dev->dev_private;
- nv50_fifo_priv *priv;
+ struct nv50_fifo_priv *priv;
int ret;
DRM_DEBUG("\n");
@@ -179,18 +176,23 @@ nv50_fifo_init(struct drm_device *dev)
nv50_fifo_init_reset(dev);
nv50_fifo_init_intr(dev);
- if ((ret = nouveau_gpuobj_new_ref(dev, NULL, NULL, 0, (128+2)*4, 0x1000,
- NVOBJ_FLAG_ZERO_ALLOC,
- &priv->thingo))) {
- DRM_ERROR("error creating thingo: %d\n", ret);
+ ret = nouveau_gpuobj_new_ref(dev, NULL, NULL, 0, 128*4, 0x1000,
+ NVOBJ_FLAG_ZERO_ALLOC, &priv->thingo[0]);
+ if (ret) {
+ DRM_ERROR("error creating thingo0: %d\n", ret);
return ret;
}
- nv50_fifo_init_context_table(dev);
+ ret = nouveau_gpuobj_new_ref(dev, NULL, NULL, 0, 128*4, 0x1000,
+ NVOBJ_FLAG_ZERO_ALLOC, &priv->thingo[1]);
+ if (ret) {
+ DRM_ERROR("error creating thingo1: %d\n", ret);
+ return ret;
+ }
+ nv50_fifo_init_context_table(dev);
nv50_fifo_init_regs__nv(dev);
- if ((ret = nv50_fifo_init_regs(dev)))
- return ret;
+ nv50_fifo_init_regs(dev);
return 0;
}
@@ -199,14 +201,15 @@ void
nv50_fifo_takedown(struct drm_device *dev)
{
struct drm_nouveau_private *dev_priv = dev->dev_private;
- nv50_fifo_priv *priv = dev_priv->Engine.fifo.priv;
+ struct nv50_fifo_priv *priv = dev_priv->Engine.fifo.priv;
DRM_DEBUG("\n");
if (!priv)
return;
- nouveau_gpuobj_ref_del(dev, &priv->thingo);
+ nouveau_gpuobj_ref_del(dev, &priv->thingo[0]);
+ nouveau_gpuobj_ref_del(dev, &priv->thingo[1]);
dev_priv->Engine.fifo.priv = NULL;
drm_free(priv, sizeof(*priv), DRM_MEM_DRIVER);
@@ -234,18 +237,18 @@ nv50_fifo_create_context(struct nouveau_channel *chan)
if (IS_G80) {
uint32_t ramfc_offset = chan->ramin->gpuobj->im_pramin->start;
uint32_t vram_offset = chan->ramin->gpuobj->im_backing->start;
- if ((ret = nouveau_gpuobj_new_fake(dev, ramfc_offset,
- vram_offset, 0x100,
- NVOBJ_FLAG_ZERO_ALLOC |
- NVOBJ_FLAG_ZERO_FREE,
- &ramfc, &chan->ramfc)))
- return ret;
+ ret = nouveau_gpuobj_new_fake(dev, ramfc_offset, vram_offset,
+ 0x100, NVOBJ_FLAG_ZERO_ALLOC |
+ NVOBJ_FLAG_ZERO_FREE, &ramfc,
+ &chan->ramfc);
+ if (ret)
+ return ret;
} else {
- if ((ret = nouveau_gpuobj_new_ref(dev, chan, NULL, 0, 0x100,
- 256,
- NVOBJ_FLAG_ZERO_ALLOC |
- NVOBJ_FLAG_ZERO_FREE,
- &chan->ramfc)))
+ ret = nouveau_gpuobj_new_ref(dev, chan, NULL, 0, 0x100, 256,
+ NVOBJ_FLAG_ZERO_ALLOC |
+ NVOBJ_FLAG_ZERO_FREE,
+ &chan->ramfc);
+ if (ret)
return ret;
ramfc = chan->ramfc->gpuobj;
}
@@ -272,7 +275,8 @@ nv50_fifo_create_context(struct nouveau_channel *chan)
INSTANCE_WR(ramfc, 0x98/4, chan->ramin->instance >> 12);
}
- if ((ret = nv50_fifo_channel_enable(dev, chan->id, 0))) {
+ ret = nv50_fifo_channel_enable(dev, chan->id, 0);
+ if (ret) {
DRM_ERROR("error enabling ch%d: %d\n", chan->id, ret);
nouveau_gpuobj_ref_del(dev, &chan->ramfc);
return ret;
diff --git a/shared-core/nv50_graph.c b/shared-core/nv50_graph.c
index 5814abd4..503f45dd 100644
--- a/shared-core/nv50_graph.c
+++ b/shared-core/nv50_graph.c
@@ -34,14 +34,12 @@ static void
nv50_graph_init_reset(struct drm_device *dev)
{
struct drm_nouveau_private *dev_priv = dev->dev_private;
- uint32_t pmc_e;
+ uint32_t pmc_e = NV_PMC_ENABLE_PGRAPH | (1 << 21);
DRM_DEBUG("\n");
- pmc_e = NV_READ(NV03_PMC_ENABLE);
- NV_WRITE(NV03_PMC_ENABLE, pmc_e & ~NV_PMC_ENABLE_PGRAPH);
- pmc_e = NV_READ(NV03_PMC_ENABLE);
- NV_WRITE(NV03_PMC_ENABLE, pmc_e | NV_PMC_ENABLE_PGRAPH);
+ NV_WRITE(NV03_PMC_ENABLE, NV_READ(NV03_PMC_ENABLE) & ~pmc_e);
+ NV_WRITE(NV03_PMC_ENABLE, NV_READ(NV03_PMC_ENABLE) | pmc_e);
}
static void
@@ -51,6 +49,7 @@ nv50_graph_init_intr(struct drm_device *dev)
DRM_DEBUG("\n");
NV_WRITE(NV03_PGRAPH_INTR, 0xffffffff);
+ NV_WRITE(0x400138, 0xffffffff);
NV_WRITE(NV40_PGRAPH_INTR_EN, 0xffffffff);
}
@@ -146,12 +145,53 @@ static uint32_t nv84_ctx_voodoo[] = {
0x00415e06, 0x00415f05, 0x0060000d, 0x00700005, 0x0070000d, 0x00700006,
0x0070000b, 0x0070000e, 0x0070001c, 0x0060000c, ~0
};
+
+static uint32_t nv86_ctx_voodoo[] = {
+ 0x0070008e, 0x0070009c, 0x00200020, 0x00600008, 0x0050004c, 0x00400e89,
+ 0x00200000, 0x00600007, 0x00300000, 0x00c000ff, 0x00200000, 0x008000ff,
+ 0x00700009, 0x0040dd4d, 0x00402944, 0x00402905, 0x0040290d, 0x0040b906,
+ 0x00600005, 0x004015c5, 0x00600011, 0x0040270b, 0x004021c5, 0x00700000,
+ 0x00700081, 0x00600004, 0x0050004a, 0x00216d80, 0x00600007, 0x00c02801,
+ 0x0020002e, 0x00800001, 0x005000cb, 0x0090ffff, 0x0091ffff, 0x00200020,
+ 0x00600008, 0x0050004c, 0x00600009, 0x0040b945, 0x0040d44d, 0x0070009d,
+ 0x00402dcf, 0x0070009f, 0x0050009f, 0x00402ac0, 0x00200200, 0x00600008,
+ 0x00402a4f, 0x00402ac0, 0x004030cc, 0x00700081, 0x00200000, 0x00600006,
+ 0x00700000, 0x00111bfc, 0x00700083, 0x00300000, 0x00216d80, 0x00600007,
+ 0x00c00b01, 0x0020001e, 0x00800001, 0x005000cb, 0x00c000ff, 0x00700080,
+ 0x00700083, 0x00200047, 0x00600006, 0x0011020a, 0x00200280, 0x00600007,
+ 0x00300000, 0x00c000ff, 0x00c800ff, 0x0040c407, 0x00202916, 0x008000ff,
+ 0x0040508c, 0x005000cb, 0x00a0023f, 0x00200040, 0x00600006, 0x0070000f,
+ 0x00170202, 0x0011020a, 0x00200032, 0x0010020d, 0x001c0242, 0x00120302,
+ 0x00140402, 0x00180500, 0x00130509, 0x00150550, 0x00110605, 0x0020000f,
+ 0x00100607, 0x00110700, 0x00110900, 0x00120902, 0x00110a00, 0x00160b02,
+ 0x00120b28, 0x00140b2b, 0x00110c01, 0x00111400, 0x00111405, 0x00111407,
+ 0x00111409, 0x0011140b, 0x002000cb, 0x00101500, 0x0040790f, 0x0040794b,
+ 0x00214b40, 0x00600007, 0x00200442, 0x008800ff, 0x0070008f, 0x0040798c,
+ 0x005000cb, 0x00000000, 0x0020002b, 0x00101a05, 0x00131c00, 0x00121c04,
+ 0x00141c20, 0x00111c25, 0x00131c40, 0x00121c44, 0x00141c60, 0x00111c65,
+ 0x00131f00, 0x00191f40, 0x004099e0, 0x002001d9, 0x00600006, 0x00200044,
+ 0x00102080, 0x001120c6, 0x001520c9, 0x001920d0, 0x00122100, 0x00122103,
+ 0x00162200, 0x00122207, 0x00112280, 0x00112300, 0x00112302, 0x00122380,
+ 0x0011238b, 0x00112394, 0x0011239c, 0x00000000, 0x0040a00f, 0x005000cb,
+ 0x00214b40, 0x00600007, 0x00200442, 0x008800ff, 0x005000cb, 0x0040a387,
+ 0x0060000a, 0x00000000, 0x0040b200, 0x007000a0, 0x00700080, 0x00200280,
+ 0x00600007, 0x00200004, 0x00c000ff, 0x008000ff, 0x005000cb, 0x00700000,
+ 0x00200000, 0x00600006, 0x00111bfe, 0x0040d44d, 0x00700000, 0x00200000,
+ 0x00600006, 0x00111bfe, 0x00700080, 0x0070001d, 0x0040114d, 0x00700081,
+ 0x00600004, 0x0050004a, 0x0040be88, 0x0060000b, 0x00200000, 0x00600006,
+ 0x00700000, 0x0040d40b, 0x00111bfd, 0x0040424d, 0x00202916, 0x008000fd,
+ 0x005000cb, 0x00c00002, 0x00200280, 0x00600007, 0x00200160, 0x00800002,
+ 0x005000cb, 0x00c01802, 0x002027b6, 0x00800002, 0x005000cb, 0x00404e4d,
+ 0x0060000b, 0x0040d24d, 0x00700001, 0x00700003, 0x0040d806, 0x0040d905,
+ 0x0060000d, 0x00700005, 0x0070000d, 0x00700006, 0x0070000b, 0x0070000e,
+ 0x0070001c, 0x0060000c, ~0
+};
-static void
+static int
nv50_graph_init_ctxctl(struct drm_device *dev)
{
struct drm_nouveau_private *dev_priv = dev->dev_private;
- uint32_t *voodoo;
+ uint32_t *voodoo = NULL;
DRM_DEBUG("\n");
@@ -159,34 +199,42 @@ nv50_graph_init_ctxctl(struct drm_device *dev)
case 0x84:
voodoo = nv84_ctx_voodoo;
break;
+ case 0x86:
+ voodoo = nv86_ctx_voodoo;
+ break;
default:
DRM_ERROR("no voodoo for chipset NV%02x\n", dev_priv->chipset);
- break;
+ return -EINVAL;
}
- if (voodoo) {
- NV_WRITE(NV40_PGRAPH_CTXCTL_UCODE_INDEX, 0);
- while (*voodoo != ~0) {
- NV_WRITE(NV40_PGRAPH_CTXCTL_UCODE_DATA, *voodoo);
- voodoo++;
- }
+ NV_WRITE(NV40_PGRAPH_CTXCTL_UCODE_INDEX, 0);
+ while (*voodoo != ~0) {
+ NV_WRITE(NV40_PGRAPH_CTXCTL_UCODE_DATA, *voodoo);
+ voodoo++;
}
NV_WRITE(0x400320, 4);
NV_WRITE(NV40_PGRAPH_CTXCTL_CUR, 0);
NV_WRITE(NV20_PGRAPH_CHANNEL_CTX_POINTER, 0);
+
+ return 0;
}
int
nv50_graph_init(struct drm_device *dev)
{
+ int ret;
+
DRM_DEBUG("\n");
nv50_graph_init_reset(dev);
nv50_graph_init_intr(dev);
nv50_graph_init_regs__nv(dev);
nv50_graph_init_regs(dev);
- nv50_graph_init_ctxctl(dev);
+
+ ret = nv50_graph_init_ctxctl(dev);
+ if (ret)
+ return ret;
return 0;
}
@@ -209,11 +257,10 @@ nv50_graph_create_context(struct nouveau_channel *chan)
DRM_DEBUG("ch%d\n", chan->id);
- if ((ret = nouveau_gpuobj_new_ref(dev, chan, NULL, 0,
- grctx_size, 0x1000,
- NVOBJ_FLAG_ZERO_ALLOC |
- NVOBJ_FLAG_ZERO_FREE,
- &chan->ramin_grctx)))
+ ret = nouveau_gpuobj_new_ref(dev, chan, NULL, 0, grctx_size, 0x1000,
+ NVOBJ_FLAG_ZERO_ALLOC |
+ NVOBJ_FLAG_ZERO_FREE, &chan->ramin_grctx);
+ if (ret)
return ret;
hdr = IS_G80 ? 0x200 : 0x20;
@@ -225,11 +272,16 @@ nv50_graph_create_context(struct nouveau_channel *chan)
INSTANCE_WR(ramin, (hdr + 0x10)/4, 0);
INSTANCE_WR(ramin, (hdr + 0x14)/4, 0x00010000);
- if ((ret = engine->graph.load_context(chan))) {
+ ret = engine->graph.load_context(chan);
+ if (ret) {
DRM_ERROR("Error hacking up initial context: %d\n", ret);
return ret;
}
+ INSTANCE_WR(chan->ramin_grctx->gpuobj, 0x00000/4,
+ chan->ramin->instance >> 12);
+ INSTANCE_WR(chan->ramin_grctx->gpuobj, 0x0011c/4, 0x00000002);
+
return 0;
}
@@ -259,7 +311,7 @@ nv50_graph_transfer_context(struct drm_device *dev, uint32_t inst, int save)
DRM_DEBUG("inst=0x%08x, save=%d\n", inst, save);
old_cp = NV_READ(NV20_PGRAPH_CHANNEL_CTX_POINTER);
- NV_WRITE(NV20_PGRAPH_CHANNEL_CTX_POINTER, inst | (1<<31));
+ NV_WRITE(NV20_PGRAPH_CHANNEL_CTX_POINTER, inst);
NV_WRITE(0x400824, NV_READ(0x400824) |
(save ? NV40_PGRAPH_CTXCTL_0310_XFER_SAVE :
NV40_PGRAPH_CTXCTL_0310_XFER_LOAD));
@@ -286,7 +338,7 @@ nv50_graph_load_context(struct nouveau_channel *chan)
{
struct drm_device *dev = chan->dev;
struct drm_nouveau_private *dev_priv = dev->dev_private;
- uint32_t inst = ((chan->ramin->instance >> 12) | (1<<31));
+ uint32_t inst = chan->ramin->instance >> 12;
int ret; (void)ret;
DRM_DEBUG("ch%d\n", chan->id);
@@ -298,7 +350,7 @@ nv50_graph_load_context(struct nouveau_channel *chan)
NV_WRITE(NV20_PGRAPH_CHANNEL_CTX_POINTER, inst);
NV_WRITE(0x400320, 4);
- NV_WRITE(NV40_PGRAPH_CTXCTL_CUR, inst);
+ NV_WRITE(NV40_PGRAPH_CTXCTL_CUR, inst | (1<<31));
return 0;
}
@@ -307,7 +359,7 @@ int
nv50_graph_save_context(struct nouveau_channel *chan)
{
struct drm_device *dev = chan->dev;
- uint32_t inst = ((chan->ramin->instance >> 12) | (1<<31));
+ uint32_t inst = chan->ramin->instance >> 12;
DRM_DEBUG("ch%d\n", chan->id);
diff --git a/shared-core/nv50_instmem.c b/shared-core/nv50_instmem.c
index c80574a9..9687ecbb 100644
--- a/shared-core/nv50_instmem.c
+++ b/shared-core/nv50_instmem.c
@@ -69,6 +69,10 @@ nv50_instmem_init(struct drm_device *dev)
return -ENOMEM;
dev_priv->Engine.instmem.priv = priv;
+ /* Save state, will restore at takedown. */
+ for (i = 0x1700; i <= 0x1710; i+=4)
+ priv->save1700[(i-0x1700)/4] = NV_READ(i);
+
/* Reserve the last MiB of VRAM, we should probably try to avoid
* setting up the below tables over the top of the VBIOS image at
* some point.
diff --git a/shared-core/r128_cce.c b/shared-core/r128_cce.c
index 8ce128bd..204ea37d 100644
--- a/shared-core/r128_cce.c
+++ b/shared-core/r128_cce.c
@@ -649,7 +649,7 @@ int r128_cce_start(struct drm_device *dev, void *data, struct drm_file *file_pri
LOCK_TEST_WITH_RETURN(dev, file_priv);
if (dev_priv->cce_running || dev_priv->cce_mode == R128_PM4_NONPM4) {
- DRM_DEBUG("%s while CCE running\n", __FUNCTION__);
+ DRM_DEBUG("while CCE running\n");
return 0;
}
@@ -708,7 +708,7 @@ int r128_cce_reset(struct drm_device *dev, void *data, struct drm_file *file_pri
LOCK_TEST_WITH_RETURN(dev, file_priv);
if (!dev_priv) {
- DRM_DEBUG("%s called before init done\n", __FUNCTION__);
+ DRM_DEBUG("called before init done\n");
return -EINVAL;
}
diff --git a/shared-core/r128_drv.h b/shared-core/r128_drv.h
index b0558389..ab8b6297 100644
--- a/shared-core/r128_drv.h
+++ b/shared-core/r128_drv.h
@@ -97,6 +97,8 @@ typedef struct drm_r128_private {
u32 crtc_offset;
u32 crtc_offset_cntl;
+ atomic_t vbl_received;
+
u32 color_fmt;
unsigned int front_offset;
unsigned int front_pitch;
@@ -149,11 +151,12 @@ extern int r128_wait_ring(drm_r128_private_t * dev_priv, int n);
extern int r128_do_cce_idle(drm_r128_private_t * dev_priv);
extern int r128_do_cleanup_cce(struct drm_device * dev);
-extern int r128_driver_vblank_wait(struct drm_device * dev, unsigned int *sequence);
-
+extern int r128_enable_vblank(struct drm_device *dev, int crtc);
+extern void r128_disable_vblank(struct drm_device *dev, int crtc);
+extern u32 r128_get_vblank_counter(struct drm_device *dev, int crtc);
extern irqreturn_t r128_driver_irq_handler(DRM_IRQ_ARGS);
extern void r128_driver_irq_preinstall(struct drm_device * dev);
-extern void r128_driver_irq_postinstall(struct drm_device * dev);
+extern int r128_driver_irq_postinstall(struct drm_device * dev);
extern void r128_driver_irq_uninstall(struct drm_device * dev);
extern void r128_driver_lastclose(struct drm_device * dev);
extern void r128_driver_preclose(struct drm_device * dev,
@@ -462,8 +465,7 @@ do { \
#define BEGIN_RING( n ) do { \
if ( R128_VERBOSE ) { \
- DRM_INFO( "BEGIN_RING( %d ) in %s\n", \
- (n), __FUNCTION__ ); \
+ DRM_INFO( "BEGIN_RING( %d )\n", (n)); \
} \
if ( dev_priv->ring.space <= (n) * sizeof(u32) ) { \
COMMIT_RING(); \
diff --git a/shared-core/r128_irq.c b/shared-core/r128_irq.c
index c76fdca7..5b95bd89 100644
--- a/shared-core/r128_irq.c
+++ b/shared-core/r128_irq.c
@@ -35,6 +35,16 @@
#include "r128_drm.h"
#include "r128_drv.h"
+u32 r128_get_vblank_counter(struct drm_device *dev, int crtc)
+{
+ const drm_r128_private_t *dev_priv = dev->dev_private;
+
+ if (crtc != 0)
+ return 0;
+
+ return atomic_read(&dev_priv->vbl_received);
+}
+
irqreturn_t r128_driver_irq_handler(DRM_IRQ_ARGS)
{
struct drm_device *dev = (struct drm_device *) arg;
@@ -46,30 +56,38 @@ irqreturn_t r128_driver_irq_handler(DRM_IRQ_ARGS)
/* VBLANK interrupt */
if (status & R128_CRTC_VBLANK_INT) {
R128_WRITE(R128_GEN_INT_STATUS, R128_CRTC_VBLANK_INT_AK);
- atomic_inc(&dev->vbl_received);
- DRM_WAKEUP(&dev->vbl_queue);
- drm_vbl_send_signals(dev);
+ atomic_inc(&dev_priv->vbl_received);
+ drm_handle_vblank(dev, 0);
return IRQ_HANDLED;
}
return IRQ_NONE;
}
-int r128_driver_vblank_wait(struct drm_device * dev, unsigned int *sequence)
+int r128_enable_vblank(struct drm_device *dev, int crtc)
{
- unsigned int cur_vblank;
- int ret = 0;
+ drm_r128_private_t *dev_priv = dev->dev_private;
- /* Assume that the user has missed the current sequence number
- * by about a day rather than she wants to wait for years
- * using vertical blanks...
- */
- DRM_WAIT_ON(ret, dev->vbl_queue, 3 * DRM_HZ,
- (((cur_vblank = atomic_read(&dev->vbl_received))
- - *sequence) <= (1 << 23)));
+ if (crtc != 0) {
+ DRM_ERROR("%s: bad crtc %d\n", __FUNCTION__, crtc);
+ return -EINVAL;
+ }
- *sequence = cur_vblank;
+ R128_WRITE(R128_GEN_INT_CNTL, R128_CRTC_VBLANK_INT_EN);
+ return 0;
+}
+
+void r128_disable_vblank(struct drm_device *dev, int crtc)
+{
+ if (crtc != 0)
+ DRM_ERROR("%s: bad crtc %d\n", __FUNCTION__, crtc);
- return ret;
+ /*
+ * FIXME: implement proper interrupt disable by using the vblank
+ * counter register (if available)
+ *
+ * R128_WRITE(R128_GEN_INT_CNTL,
+ * R128_READ(R128_GEN_INT_CNTL) & ~R128_CRTC_VBLANK_INT_EN);
+ */
}
void r128_driver_irq_preinstall(struct drm_device * dev)
@@ -82,12 +100,9 @@ void r128_driver_irq_preinstall(struct drm_device * dev)
R128_WRITE(R128_GEN_INT_STATUS, R128_CRTC_VBLANK_INT_AK);
}
-void r128_driver_irq_postinstall(struct drm_device * dev)
+int r128_driver_irq_postinstall(struct drm_device * dev)
{
- drm_r128_private_t *dev_priv = (drm_r128_private_t *) dev->dev_private;
-
- /* Turn on VBL interrupt */
- R128_WRITE(R128_GEN_INT_CNTL, R128_CRTC_VBLANK_INT_EN);
+ return drm_vblank_init(dev, 1);
}
void r128_driver_irq_uninstall(struct drm_device * dev)
diff --git a/shared-core/r128_state.c b/shared-core/r128_state.c
index b7f483ca..51a9afce 100644
--- a/shared-core/r128_state.c
+++ b/shared-core/r128_state.c
@@ -42,7 +42,7 @@ static void r128_emit_clip_rects(drm_r128_private_t * dev_priv,
{
u32 aux_sc_cntl = 0x00000000;
RING_LOCALS;
- DRM_DEBUG(" %s\n", __FUNCTION__);
+ DRM_DEBUG("\n");
BEGIN_RING((count < 3 ? count : 3) * 5 + 2);
@@ -85,7 +85,7 @@ static __inline__ void r128_emit_core(drm_r128_private_t * dev_priv)
drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv;
drm_r128_context_regs_t *ctx = &sarea_priv->context_state;
RING_LOCALS;
- DRM_DEBUG(" %s\n", __FUNCTION__);
+ DRM_DEBUG("\n");
BEGIN_RING(2);
@@ -100,7 +100,7 @@ static __inline__ void r128_emit_context(drm_r128_private_t * dev_priv)
drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv;
drm_r128_context_regs_t *ctx = &sarea_priv->context_state;
RING_LOCALS;
- DRM_DEBUG(" %s\n", __FUNCTION__);
+ DRM_DEBUG("\n");
BEGIN_RING(13);
@@ -126,7 +126,7 @@ static __inline__ void r128_emit_setup(drm_r128_private_t * dev_priv)
drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv;
drm_r128_context_regs_t *ctx = &sarea_priv->context_state;
RING_LOCALS;
- DRM_DEBUG(" %s\n", __FUNCTION__);
+ DRM_DEBUG("\n");
BEGIN_RING(3);
@@ -142,7 +142,7 @@ static __inline__ void r128_emit_masks(drm_r128_private_t * dev_priv)
drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv;
drm_r128_context_regs_t *ctx = &sarea_priv->context_state;
RING_LOCALS;
- DRM_DEBUG(" %s\n", __FUNCTION__);
+ DRM_DEBUG("\n");
BEGIN_RING(5);
@@ -161,7 +161,7 @@ static __inline__ void r128_emit_window(drm_r128_private_t * dev_priv)
drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv;
drm_r128_context_regs_t *ctx = &sarea_priv->context_state;
RING_LOCALS;
- DRM_DEBUG(" %s\n", __FUNCTION__);
+ DRM_DEBUG("\n");
BEGIN_RING(2);
@@ -178,7 +178,7 @@ static __inline__ void r128_emit_tex0(drm_r128_private_t * dev_priv)
drm_r128_texture_regs_t *tex = &sarea_priv->tex_state[0];
int i;
RING_LOCALS;
- DRM_DEBUG(" %s\n", __FUNCTION__);
+ DRM_DEBUG("\n");
BEGIN_RING(7 + R128_MAX_TEXTURE_LEVELS);
@@ -204,7 +204,7 @@ static __inline__ void r128_emit_tex1(drm_r128_private_t * dev_priv)
drm_r128_texture_regs_t *tex = &sarea_priv->tex_state[1];
int i;
RING_LOCALS;
- DRM_DEBUG(" %s\n", __FUNCTION__);
+ DRM_DEBUG("\n");
BEGIN_RING(5 + R128_MAX_TEXTURE_LEVELS);
@@ -226,7 +226,7 @@ static void r128_emit_state(drm_r128_private_t * dev_priv)
drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv;
unsigned int dirty = sarea_priv->dirty;
- DRM_DEBUG("%s: dirty=0x%08x\n", __FUNCTION__, dirty);
+ DRM_DEBUG("dirty=0x%08x\n", dirty);
if (dirty & R128_UPLOAD_CORE) {
r128_emit_core(dev_priv);
@@ -362,7 +362,7 @@ static void r128_cce_dispatch_clear(struct drm_device * dev,
unsigned int flags = clear->flags;
int i;
RING_LOCALS;
- DRM_DEBUG("%s\n", __FUNCTION__);
+ DRM_DEBUG("\n");
if (dev_priv->page_flipping && dev_priv->current_page == 1) {
unsigned int tmp = flags;
@@ -466,7 +466,7 @@ static void r128_cce_dispatch_swap(struct drm_device * dev)
struct drm_clip_rect *pbox = sarea_priv->boxes;
int i;
RING_LOCALS;
- DRM_DEBUG("%s\n", __FUNCTION__);
+ DRM_DEBUG("\n");
#if R128_PERFORMANCE_BOXES
/* Do some trivial performance monitoring...
@@ -528,8 +528,7 @@ static void r128_cce_dispatch_flip(struct drm_device * dev)
{
drm_r128_private_t *dev_priv = dev->dev_private;
RING_LOCALS;
- DRM_DEBUG("%s: page=%d pfCurrentPage=%d\n",
- __FUNCTION__,
+ DRM_DEBUG("page=%d pfCurrentPage=%d\n",
dev_priv->current_page, dev_priv->sarea_priv->pfCurrentPage);
#if R128_PERFORMANCE_BOXES
@@ -1156,7 +1155,7 @@ static int r128_cce_dispatch_read_pixels(struct drm_device * dev,
int count, *x, *y;
int i, xbuf_size, ybuf_size;
RING_LOCALS;
- DRM_DEBUG("%s\n", __FUNCTION__);
+ DRM_DEBUG("\n");
count = depth->n;
if (count > 4096 || count <= 0)
@@ -1226,7 +1225,7 @@ static void r128_cce_dispatch_stipple(struct drm_device * dev, u32 * stipple)
drm_r128_private_t *dev_priv = dev->dev_private;
int i;
RING_LOCALS;
- DRM_DEBUG("%s\n", __FUNCTION__);
+ DRM_DEBUG("\n");
BEGIN_RING(33);
@@ -1309,7 +1308,7 @@ static int r128_do_cleanup_pageflip(struct drm_device * dev)
static int r128_cce_flip(struct drm_device *dev, void *data, struct drm_file *file_priv)
{
drm_r128_private_t *dev_priv = dev->dev_private;
- DRM_DEBUG("%s\n", __FUNCTION__);
+ DRM_DEBUG("\n");
LOCK_TEST_WITH_RETURN(dev, file_priv);
@@ -1328,7 +1327,7 @@ static int r128_cce_swap(struct drm_device *dev, void *data, struct drm_file *fi
{
drm_r128_private_t *dev_priv = dev->dev_private;
drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv;
- DRM_DEBUG("%s\n", __FUNCTION__);
+ DRM_DEBUG("\n");
LOCK_TEST_WITH_RETURN(dev, file_priv);
@@ -1356,7 +1355,7 @@ static int r128_cce_vertex(struct drm_device *dev, void *data, struct drm_file *
LOCK_TEST_WITH_RETURN(dev, file_priv);
if (!dev_priv) {
- DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
+ DRM_ERROR("called with no initialization\n");
return -EINVAL;
}
@@ -1412,7 +1411,7 @@ static int r128_cce_indices(struct drm_device *dev, void *data, struct drm_file
LOCK_TEST_WITH_RETURN(dev, file_priv);
if (!dev_priv) {
- DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
+ DRM_ERROR("called with no initialization\n");
return -EINVAL;
}
@@ -1557,11 +1556,11 @@ static int r128_cce_indirect(struct drm_device *dev, void *data, struct drm_file
LOCK_TEST_WITH_RETURN(dev, file_priv);
if (!dev_priv) {
- DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
+ DRM_ERROR("called with no initialization\n");
return -EINVAL;
}
- DRM_DEBUG("indirect: idx=%d s=%d e=%d d=%d\n",
+ DRM_DEBUG("idx=%d s=%d e=%d d=%d\n",
indirect->idx, indirect->start, indirect->end,
indirect->discard);
@@ -1622,7 +1621,7 @@ static int r128_getparam(struct drm_device *dev, void *data, struct drm_file *fi
int value;
if (!dev_priv) {
- DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
+ DRM_ERROR("called with no initialization\n");
return -EINVAL;
}
diff --git a/shared-core/r300_cmdbuf.c b/shared-core/r300_cmdbuf.c
index 6ab907c6..a26a71d5 100644
--- a/shared-core/r300_cmdbuf.c
+++ b/shared-core/r300_cmdbuf.c
@@ -77,23 +77,31 @@ static int r300_emit_cliprects(drm_radeon_private_t *dev_priv,
return -EFAULT;
}
- box.x1 =
- (box.x1 +
- R300_CLIPRECT_OFFSET) & R300_CLIPRECT_MASK;
- box.y1 =
- (box.y1 +
- R300_CLIPRECT_OFFSET) & R300_CLIPRECT_MASK;
- box.x2 =
- (box.x2 +
- R300_CLIPRECT_OFFSET) & R300_CLIPRECT_MASK;
- box.y2 =
- (box.y2 +
- R300_CLIPRECT_OFFSET) & R300_CLIPRECT_MASK;
+ if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RV515) {
+ box.x1 = (box.x1) &
+ R300_CLIPRECT_MASK;
+ box.y1 = (box.y1) &
+ R300_CLIPRECT_MASK;
+ box.x2 = (box.x2) &
+ R300_CLIPRECT_MASK;
+ box.y2 = (box.y2) &
+ R300_CLIPRECT_MASK;
+ } else {
+ box.x1 = (box.x1 + R300_CLIPRECT_OFFSET) &
+ R300_CLIPRECT_MASK;
+ box.y1 = (box.y1 + R300_CLIPRECT_OFFSET) &
+ R300_CLIPRECT_MASK;
+ box.x2 = (box.x2 + R300_CLIPRECT_OFFSET) &
+ R300_CLIPRECT_MASK;
+ box.y2 = (box.y2 + R300_CLIPRECT_OFFSET) &
+ R300_CLIPRECT_MASK;
+ }
OUT_RING((box.x1 << R300_CLIPRECT_X_SHIFT) |
(box.y1 << R300_CLIPRECT_Y_SHIFT));
OUT_RING((box.x2 << R300_CLIPRECT_X_SHIFT) |
(box.y2 << R300_CLIPRECT_Y_SHIFT));
+
}
OUT_RING_REG(R300_RE_CLIPRECT_CNTL, r300_cliprect_cntl[nr - 1]);
@@ -133,9 +141,11 @@ static int r300_emit_cliprects(drm_radeon_private_t *dev_priv,
static u8 r300_reg_flags[0x10000 >> 2];
-void r300_init_reg_flags(void)
+void r300_init_reg_flags(struct drm_device *dev)
{
int i;
+ drm_radeon_private_t *dev_priv = dev->dev_private;
+
memset(r300_reg_flags, 0, 0x10000 >> 2);
#define ADD_RANGE_MARK(reg, count,mark) \
for(i=((reg)>>2);i<((reg)>>2)+(count);i++)\
@@ -230,6 +240,9 @@ void r300_init_reg_flags(void)
ADD_RANGE(R300_VAP_INPUT_ROUTE_0_0, 8);
ADD_RANGE(R300_VAP_INPUT_ROUTE_1_0, 8);
+ if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RV515) {
+ ADD_RANGE(0x4074, 16);
+ }
}
static __inline__ int r300_check_range(unsigned reg, int count)
diff --git a/shared-core/radeon_cp.c b/shared-core/radeon_cp.c
index c2863346..f0e55105 100644
--- a/shared-core/radeon_cp.c
+++ b/shared-core/radeon_cp.c
@@ -816,19 +816,44 @@ static const u32 R300_cp_microcode[][2] = {
{ 0000000000, 0000000000 },
};
+static u32 RADEON_READ_MCIND(drm_radeon_private_t *dev_priv, int addr)
+{
+ u32 ret;
+ RADEON_WRITE(R520_MC_IND_INDEX, 0x7f0000 | (addr & 0xff));
+ ret = RADEON_READ(R520_MC_IND_DATA);
+ RADEON_WRITE(R520_MC_IND_INDEX, 0);
+ return ret;
+}
+
u32 radeon_read_fb_location(drm_radeon_private_t *dev_priv)
{
- return RADEON_READ(RADEON_MC_FB_LOCATION);
+
+ if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV515)
+ return RADEON_READ_MCIND(dev_priv, RV515_MC_FB_LOCATION);
+ else if ((dev_priv->flags & RADEON_FAMILY_MASK) > CHIP_RV515)
+ return RADEON_READ_MCIND(dev_priv, R520_MC_FB_LOCATION);
+ else
+ return RADEON_READ(RADEON_MC_FB_LOCATION);
}
static void radeon_write_fb_location(drm_radeon_private_t *dev_priv, u32 fb_loc)
{
- RADEON_WRITE(RADEON_MC_FB_LOCATION, fb_loc);
+ if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV515)
+ RADEON_WRITE_MCIND(RV515_MC_FB_LOCATION, fb_loc);
+ else if ((dev_priv->flags & RADEON_FAMILY_MASK) > CHIP_RV515)
+ RADEON_WRITE_MCIND(R520_MC_FB_LOCATION, fb_loc);
+ else
+ RADEON_WRITE(RADEON_MC_FB_LOCATION, fb_loc);
}
static void radeon_write_agp_location(drm_radeon_private_t *dev_priv, u32 agp_loc)
{
- RADEON_WRITE(RADEON_MC_AGP_LOCATION, agp_loc);
+ if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV515)
+ RADEON_WRITE_MCIND(RV515_MC_AGP_LOCATION, agp_loc);
+ else if ((dev_priv->flags & RADEON_FAMILY_MASK) > CHIP_RV515)
+ RADEON_WRITE_MCIND(R520_MC_AGP_LOCATION, agp_loc);
+ else
+ RADEON_WRITE(RADEON_MC_AGP_LOCATION, agp_loc);
}
static int RADEON_READ_PLL(struct drm_device * dev, int addr)
@@ -1089,41 +1114,43 @@ static int radeon_do_engine_reset(struct drm_device * dev)
radeon_do_pixcache_flush(dev_priv);
- clock_cntl_index = RADEON_READ(RADEON_CLOCK_CNTL_INDEX);
- mclk_cntl = RADEON_READ_PLL(dev, RADEON_MCLK_CNTL);
-
- RADEON_WRITE_PLL(RADEON_MCLK_CNTL, (mclk_cntl |
- RADEON_FORCEON_MCLKA |
- RADEON_FORCEON_MCLKB |
- RADEON_FORCEON_YCLKA |
- RADEON_FORCEON_YCLKB |
- RADEON_FORCEON_MC |
- RADEON_FORCEON_AIC));
-
- rbbm_soft_reset = RADEON_READ(RADEON_RBBM_SOFT_RESET);
-
- RADEON_WRITE(RADEON_RBBM_SOFT_RESET, (rbbm_soft_reset |
- RADEON_SOFT_RESET_CP |
- RADEON_SOFT_RESET_HI |
- RADEON_SOFT_RESET_SE |
- RADEON_SOFT_RESET_RE |
- RADEON_SOFT_RESET_PP |
- RADEON_SOFT_RESET_E2 |
- RADEON_SOFT_RESET_RB));
- RADEON_READ(RADEON_RBBM_SOFT_RESET);
- RADEON_WRITE(RADEON_RBBM_SOFT_RESET, (rbbm_soft_reset &
- ~(RADEON_SOFT_RESET_CP |
- RADEON_SOFT_RESET_HI |
- RADEON_SOFT_RESET_SE |
- RADEON_SOFT_RESET_RE |
- RADEON_SOFT_RESET_PP |
- RADEON_SOFT_RESET_E2 |
- RADEON_SOFT_RESET_RB)));
- RADEON_READ(RADEON_RBBM_SOFT_RESET);
-
- RADEON_WRITE_PLL(RADEON_MCLK_CNTL, mclk_cntl);
- RADEON_WRITE(RADEON_CLOCK_CNTL_INDEX, clock_cntl_index);
- RADEON_WRITE(RADEON_RBBM_SOFT_RESET, rbbm_soft_reset);
+ if ((dev_priv->flags & RADEON_FAMILY_MASK) < CHIP_RV515) {
+ clock_cntl_index = RADEON_READ(RADEON_CLOCK_CNTL_INDEX);
+ mclk_cntl = RADEON_READ_PLL(dev, RADEON_MCLK_CNTL);
+
+ RADEON_WRITE_PLL(RADEON_MCLK_CNTL, (mclk_cntl |
+ RADEON_FORCEON_MCLKA |
+ RADEON_FORCEON_MCLKB |
+ RADEON_FORCEON_YCLKA |
+ RADEON_FORCEON_YCLKB |
+ RADEON_FORCEON_MC |
+ RADEON_FORCEON_AIC));
+
+ rbbm_soft_reset = RADEON_READ(RADEON_RBBM_SOFT_RESET);
+
+ RADEON_WRITE(RADEON_RBBM_SOFT_RESET, (rbbm_soft_reset |
+ RADEON_SOFT_RESET_CP |
+ RADEON_SOFT_RESET_HI |
+ RADEON_SOFT_RESET_SE |
+ RADEON_SOFT_RESET_RE |
+ RADEON_SOFT_RESET_PP |
+ RADEON_SOFT_RESET_E2 |
+ RADEON_SOFT_RESET_RB));
+ RADEON_READ(RADEON_RBBM_SOFT_RESET);
+ RADEON_WRITE(RADEON_RBBM_SOFT_RESET, (rbbm_soft_reset &
+ ~(RADEON_SOFT_RESET_CP |
+ RADEON_SOFT_RESET_HI |
+ RADEON_SOFT_RESET_SE |
+ RADEON_SOFT_RESET_RE |
+ RADEON_SOFT_RESET_PP |
+ RADEON_SOFT_RESET_E2 |
+ RADEON_SOFT_RESET_RB)));
+ RADEON_READ(RADEON_RBBM_SOFT_RESET);
+
+ RADEON_WRITE_PLL(RADEON_MCLK_CNTL, mclk_cntl);
+ RADEON_WRITE(RADEON_CLOCK_CNTL_INDEX, clock_cntl_index);
+ RADEON_WRITE(RADEON_RBBM_SOFT_RESET, rbbm_soft_reset);
+ }
/* Reset the CP ring */
radeon_do_cp_reset(dev_priv);
@@ -1881,7 +1908,7 @@ int radeon_cp_init(struct drm_device *dev, void *data, struct drm_file *file_pri
LOCK_TEST_WITH_RETURN(dev, file_priv);
if (init->func == RADEON_INIT_R300_CP)
- r300_init_reg_flags();
+ r300_init_reg_flags(dev);
switch (init->func) {
case RADEON_INIT_CP:
@@ -1903,12 +1930,12 @@ int radeon_cp_start(struct drm_device *dev, void *data, struct drm_file *file_pr
LOCK_TEST_WITH_RETURN(dev, file_priv);
if (dev_priv->cp_running) {
- DRM_DEBUG("%s while CP running\n", __FUNCTION__);
+ DRM_DEBUG("while CP running\n");
return 0;
}
if (dev_priv->cp_mode == RADEON_CSQ_PRIDIS_INDDIS) {
- DRM_DEBUG("%s called with bogus CP mode (%d)\n",
- __FUNCTION__, dev_priv->cp_mode);
+ DRM_DEBUG("called with bogus CP mode (%d)\n",
+ dev_priv->cp_mode);
return 0;
}
@@ -2018,7 +2045,7 @@ int radeon_cp_reset(struct drm_device *dev, void *data, struct drm_file *file_pr
LOCK_TEST_WITH_RETURN(dev, file_priv);
if (!dev_priv) {
- DRM_DEBUG("%s called before init done\n", __FUNCTION__);
+ DRM_DEBUG("called before init done\n");
return -EINVAL;
}
@@ -2295,6 +2322,10 @@ int radeon_driver_load(struct drm_device *dev, unsigned long flags)
case CHIP_R350:
case CHIP_R420:
case CHIP_RV410:
+ case CHIP_RV515:
+ case CHIP_R520:
+ case CHIP_RV570:
+ case CHIP_R580:
dev_priv->flags |= RADEON_HAS_HIERZ;
break;
default:
diff --git a/shared-core/radeon_drv.h b/shared-core/radeon_drv.h
index 37b9c43f..63877008 100644
--- a/shared-core/radeon_drv.h
+++ b/shared-core/radeon_drv.h
@@ -129,6 +129,12 @@ enum radeon_family {
CHIP_R420,
CHIP_RV410,
CHIP_RS400,
+ CHIP_RV515,
+ CHIP_R520,
+ CHIP_RV530,
+ CHIP_RV560,
+ CHIP_RV570,
+ CHIP_R580,
CHIP_LAST,
};
@@ -305,6 +311,9 @@ typedef struct drm_radeon_private {
u32 scratch_ages[5];
+ unsigned int crtc_last_cnt;
+ unsigned int crtc2_last_cnt;
+
/* starting from here on, data is preserved accross an open */
uint32_t flags; /* see radeon_chip_flags */
unsigned long fb_aper_offset;
@@ -374,13 +383,13 @@ extern int radeon_irq_wait(struct drm_device *dev, void *data, struct drm_file *
extern int radeon_emit_irq(struct drm_device * dev);
extern void radeon_do_release(struct drm_device * dev);
-extern int radeon_driver_vblank_wait(struct drm_device * dev,
- unsigned int *sequence);
-extern int radeon_driver_vblank_wait2(struct drm_device * dev,
- unsigned int *sequence);
+extern u32 radeon_get_vblank_counter(struct drm_device *dev, int crtc);
+extern int radeon_enable_vblank(struct drm_device *dev, int crtc);
+extern void radeon_disable_vblank(struct drm_device *dev, int crtc);
+extern void radeon_do_release(struct drm_device * dev);
extern irqreturn_t radeon_driver_irq_handler(DRM_IRQ_ARGS);
extern void radeon_driver_irq_preinstall(struct drm_device * dev);
-extern void radeon_driver_irq_postinstall(struct drm_device * dev);
+extern int radeon_driver_irq_postinstall(struct drm_device * dev);
extern void radeon_driver_irq_uninstall(struct drm_device * dev);
extern int radeon_vblank_crtc_get(struct drm_device *dev);
extern int radeon_vblank_crtc_set(struct drm_device *dev, int64_t value);
@@ -399,7 +408,7 @@ extern long radeon_compat_ioctl(struct file *filp, unsigned int cmd,
unsigned long arg);
/* r300_cmdbuf.c */
-extern void r300_init_reg_flags(void);
+extern void r300_init_reg_flags(struct drm_device *dev);
extern int r300_do_cp_cmdbuf(struct drm_device *dev,
struct drm_file *file_priv,
@@ -423,7 +432,7 @@ extern int radeon_fence_has_irq(struct drm_device *dev, uint32_t class, uint32_t
extern struct drm_ttm_backend *radeon_create_ttm_backend_entry(struct drm_device *dev);
extern int radeon_fence_types(struct drm_buffer_object *bo, uint32_t *class, uint32_t *type);
extern int radeon_invalidate_caches(struct drm_device *dev, uint64_t buffer_flags);
-extern uint32_t radeon_evict_mask(struct drm_buffer_object *bo);
+extern uint64_t radeon_evict_flags(struct drm_buffer_object *bo);
extern int radeon_init_mem_type(struct drm_device * dev, uint32_t type,
struct drm_mem_type_manager * man);
extern int radeon_move(struct drm_buffer_object * bo,
@@ -494,6 +503,15 @@ extern int radeon_move(struct drm_buffer_object * bo,
#define RADEON_IGPGART_ENABLE 0x38
#define RADEON_IGPGART_UNK_39 0x39
+#define R520_MC_IND_INDEX 0x70
+#define R520_MC_IND_WR_EN (1<<24)
+#define R520_MC_IND_DATA 0x74
+
+#define RV515_MC_FB_LOCATION 0x01
+#define RV515_MC_AGP_LOCATION 0x02
+
+#define R520_MC_FB_LOCATION 0x04
+#define R520_MC_AGP_LOCATION 0x05
#define RADEON_MPP_TB_CONFIG 0x01c0
#define RADEON_MEM_CNTL 0x0140
@@ -545,6 +563,12 @@ extern int radeon_move(struct drm_buffer_object * bo,
? DRM_READ32( dev_priv->ring_rptr, RADEON_SCRATCHOFF(x) ) \
: RADEON_READ( RADEON_SCRATCH_REG0 + 4*(x) ) )
+#define RADEON_CRTC_CRNT_FRAME 0x0214
+#define RADEON_CRTC2_CRNT_FRAME 0x0314
+
+#define RADEON_CRTC_STATUS 0x005c
+#define RADEON_CRTC2_STATUS 0x03fc
+
#define RADEON_GEN_INT_CNTL 0x0040
# define RADEON_CRTC_VBLANK_MASK (1 << 0)
# define RADEON_CRTC2_VBLANK_MASK (1 << 9)
@@ -1117,6 +1141,13 @@ do { \
RADEON_WRITE( RADEON_PCIE_DATA, (val) ); \
} while (0)
+#define RADEON_WRITE_MCIND( addr, val ) \
+ do { \
+ RADEON_WRITE(R520_MC_IND_INDEX, 0xff0000 | ((addr) & 0xff)); \
+ RADEON_WRITE(R520_MC_IND_DATA, (val)); \
+ RADEON_WRITE(R520_MC_IND_INDEX, 0); \
+ } while (0)
+
#define CP_PACKET0( reg, n ) \
(RADEON_CP_PACKET0 | ((n) << 16) | ((reg) >> 2))
#define CP_PACKET0_TABLE( reg, n ) \
@@ -1227,8 +1258,7 @@ do { \
#define BEGIN_RING( n ) do { \
if ( RADEON_VERBOSE ) { \
- DRM_INFO( "BEGIN_RING( %d ) in %s\n", \
- n, __FUNCTION__ ); \
+ DRM_INFO( "BEGIN_RING( %d )\n", (n)); \
} \
if ( dev_priv->ring.space <= (n) * sizeof(u32) ) { \
COMMIT_RING(); \
diff --git a/shared-core/radeon_irq.c b/shared-core/radeon_irq.c
index 544e3a0f..3f6ace88 100644
--- a/shared-core/radeon_irq.c
+++ b/shared-core/radeon_irq.c
@@ -35,12 +35,61 @@
#include "radeon_drm.h"
#include "radeon_drv.h"
-static __inline__ u32 radeon_acknowledge_irqs(drm_radeon_private_t * dev_priv,
- u32 mask)
+static void radeon_irq_set_state(struct drm_device *dev, u32 mask, int state)
{
- u32 irqs = RADEON_READ(RADEON_GEN_INT_STATUS) & mask;
+ drm_radeon_private_t *dev_priv = dev->dev_private;
+
+ if (state)
+ dev_priv->irq_enable_reg |= mask;
+ else
+ dev_priv->irq_enable_reg &= ~mask;
+
+ RADEON_WRITE(RADEON_GEN_INT_CNTL, dev_priv->irq_enable_reg);
+}
+
+int radeon_enable_vblank(struct drm_device *dev, int crtc)
+{
+ switch (crtc) {
+ case 0:
+ radeon_irq_set_state(dev, RADEON_CRTC_VBLANK_MASK, 1);
+ break;
+ case 1:
+ radeon_irq_set_state(dev, RADEON_CRTC2_VBLANK_MASK, 1);
+ break;
+ default:
+ DRM_ERROR("tried to enable vblank on non-existent crtc %d\n",
+ crtc);
+ return EINVAL;
+ }
+
+ return 0;
+}
+
+void radeon_disable_vblank(struct drm_device *dev, int crtc)
+{
+ switch (crtc) {
+ case 0:
+ radeon_irq_set_state(dev, RADEON_CRTC_VBLANK_MASK, 0);
+ break;
+ case 1:
+ radeon_irq_set_state(dev, RADEON_CRTC2_VBLANK_MASK, 0);
+ break;
+ default:
+ DRM_ERROR("tried to enable vblank on non-existent crtc %d\n",
+ crtc);
+ break;
+ }
+}
+
+static __inline__ u32 radeon_acknowledge_irqs(drm_radeon_private_t * dev_priv)
+{
+ u32 irqs = RADEON_READ(RADEON_GEN_INT_STATUS) &
+ (RADEON_SW_INT_TEST | RADEON_CRTC_VBLANK_STAT |
+ RADEON_CRTC2_VBLANK_STAT);
+
if (irqs)
RADEON_WRITE(RADEON_GEN_INT_STATUS, irqs);
+
return irqs;
}
@@ -72,9 +121,7 @@ irqreturn_t radeon_driver_irq_handler(DRM_IRQ_ARGS)
/* Only consider the bits we're interested in - others could be used
* outside the DRM
*/
- stat = radeon_acknowledge_irqs(dev_priv, (RADEON_SW_INT_TEST_ACK |
- RADEON_CRTC_VBLANK_STAT |
- RADEON_CRTC2_VBLANK_STAT));
+ stat = radeon_acknowledge_irqs(dev_priv);
if (!stat)
return IRQ_NONE;
@@ -87,27 +134,11 @@ irqreturn_t radeon_driver_irq_handler(DRM_IRQ_ARGS)
radeon_fence_handler(dev);
#endif
}
-
/* VBLANK interrupt */
- if (stat & (RADEON_CRTC_VBLANK_STAT|RADEON_CRTC2_VBLANK_STAT)) {
- int vblank_crtc = dev_priv->vblank_crtc;
-
- if ((vblank_crtc &
- (DRM_RADEON_VBLANK_CRTC1 | DRM_RADEON_VBLANK_CRTC2)) ==
- (DRM_RADEON_VBLANK_CRTC1 | DRM_RADEON_VBLANK_CRTC2)) {
- if (stat & RADEON_CRTC_VBLANK_STAT)
- atomic_inc(&dev->vbl_received);
- if (stat & RADEON_CRTC2_VBLANK_STAT)
- atomic_inc(&dev->vbl_received2);
- } else if (((stat & RADEON_CRTC_VBLANK_STAT) &&
- (vblank_crtc & DRM_RADEON_VBLANK_CRTC1)) ||
- ((stat & RADEON_CRTC2_VBLANK_STAT) &&
- (vblank_crtc & DRM_RADEON_VBLANK_CRTC2)))
- atomic_inc(&dev->vbl_received);
-
- DRM_WAKEUP(&dev->vbl_queue);
- drm_vbl_send_signals(dev);
- }
+ if (stat & RADEON_CRTC_VBLANK_STAT)
+ drm_handle_vblank(dev, 0);
+ if (stat & RADEON_CRTC2_VBLANK_STAT)
+ drm_handle_vblank(dev, 1);
return IRQ_HANDLED;
}
@@ -146,54 +177,27 @@ static int radeon_wait_irq(struct drm_device * dev, int swi_nr)
return ret;
}
-static int radeon_driver_vblank_do_wait(struct drm_device * dev,
- unsigned int *sequence, int crtc)
+u32 radeon_get_vblank_counter(struct drm_device *dev, int crtc)
{
- drm_radeon_private_t *dev_priv =
- (drm_radeon_private_t *) dev->dev_private;
- unsigned int cur_vblank;
- int ret = 0;
- int ack = 0;
- atomic_t *counter;
+ drm_radeon_private_t *dev_priv = dev->dev_private;
+ u32 crtc_cnt_reg, crtc_status_reg;
+
if (!dev_priv) {
- DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
+ DRM_ERROR("called with no initialization\n");
return -EINVAL;
}
- if (crtc == DRM_RADEON_VBLANK_CRTC1) {
- counter = &dev->vbl_received;
- ack |= RADEON_CRTC_VBLANK_STAT;
- } else if (crtc == DRM_RADEON_VBLANK_CRTC2) {
- counter = &dev->vbl_received2;
- ack |= RADEON_CRTC2_VBLANK_STAT;
- } else
+ if (crtc == 0) {
+ crtc_cnt_reg = RADEON_CRTC_CRNT_FRAME;
+ crtc_status_reg = RADEON_CRTC_STATUS;
+ } else if (crtc == 1) {
+ crtc_cnt_reg = RADEON_CRTC2_CRNT_FRAME;
+ crtc_status_reg = RADEON_CRTC2_STATUS;
+ } else {
return -EINVAL;
+ }
- radeon_acknowledge_irqs(dev_priv, ack);
-
- dev_priv->stats.boxes |= RADEON_BOX_WAIT_IDLE;
-
- /* Assume that the user has missed the current sequence number
- * by about a day rather than she wants to wait for years
- * using vertical blanks...
- */
- DRM_WAIT_ON(ret, dev->vbl_queue, 3 * DRM_HZ,
- (((cur_vblank = atomic_read(counter))
- - *sequence) <= (1 << 23)));
-
- *sequence = cur_vblank;
-
- return ret;
-}
-
-int radeon_driver_vblank_wait(struct drm_device *dev, unsigned int *sequence)
-{
- return radeon_driver_vblank_do_wait(dev, sequence, DRM_RADEON_VBLANK_CRTC1);
-}
-
-int radeon_driver_vblank_wait2(struct drm_device *dev, unsigned int *sequence)
-{
- return radeon_driver_vblank_do_wait(dev, sequence, DRM_RADEON_VBLANK_CRTC2);
+ return RADEON_READ(crtc_cnt_reg) + (RADEON_READ(crtc_status_reg) & 1);
}
/* Needs the lock as it touches the ring.
@@ -207,7 +211,7 @@ int radeon_irq_emit(struct drm_device *dev, void *data, struct drm_file *file_pr
LOCK_TEST_WITH_RETURN(dev, file_priv);
if (!dev_priv) {
- DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
+ DRM_ERROR("called with no initialization\n");
return -EINVAL;
}
@@ -229,28 +233,13 @@ int radeon_irq_wait(struct drm_device *dev, void *data, struct drm_file *file_pr
drm_radeon_irq_wait_t *irqwait = data;
if (!dev_priv) {
- DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
+ DRM_ERROR("called with no initialization\n");
return -EINVAL;
}
return radeon_wait_irq(dev, irqwait->irq_seq);
}
-static void radeon_enable_interrupt(struct drm_device *dev)
-{
- drm_radeon_private_t *dev_priv = (drm_radeon_private_t *) dev->dev_private;
-
- dev_priv->irq_enable_reg = RADEON_SW_INT_ENABLE;
- if (dev_priv->vblank_crtc & DRM_RADEON_VBLANK_CRTC1)
- dev_priv->irq_enable_reg |= RADEON_CRTC_VBLANK_MASK;
-
- if (dev_priv->vblank_crtc & DRM_RADEON_VBLANK_CRTC2)
- dev_priv->irq_enable_reg |= RADEON_CRTC2_VBLANK_MASK;
-
- RADEON_WRITE(RADEON_GEN_INT_CNTL, dev_priv->irq_enable_reg);
- dev_priv->irq_enabled = 1;
-}
-
/* drm_dma.h hooks
*/
void radeon_driver_irq_preinstall(struct drm_device * dev)
@@ -262,20 +251,27 @@ void radeon_driver_irq_preinstall(struct drm_device * dev)
RADEON_WRITE(RADEON_GEN_INT_CNTL, 0);
/* Clear bits if they're already high */
- radeon_acknowledge_irqs(dev_priv, (RADEON_SW_INT_TEST_ACK |
- RADEON_CRTC_VBLANK_STAT |
- RADEON_CRTC2_VBLANK_STAT));
+ radeon_acknowledge_irqs(dev_priv);
}
-void radeon_driver_irq_postinstall(struct drm_device * dev)
+int radeon_driver_irq_postinstall(struct drm_device * dev)
{
drm_radeon_private_t *dev_priv =
(drm_radeon_private_t *) dev->dev_private;
+ int ret;
dev_priv->counter = 0;
DRM_INIT_WAITQUEUE(&dev_priv->irq_queue);
- radeon_enable_interrupt(dev);
+ ret = drm_vblank_init(dev, 2);
+ if (ret)
+ return ret;
+
+ dev->max_vblank_count = 0x001fffff;
+
+ radeon_irq_set_state(dev, RADEON_SW_INT_ENABLE, 1);
+
+ return 0;
}
void radeon_driver_irq_uninstall(struct drm_device * dev)
@@ -317,6 +313,5 @@ int radeon_vblank_crtc_set(struct drm_device *dev, int64_t value)
return -EINVAL;
}
dev_priv->vblank_crtc = (unsigned int)value;
- radeon_enable_interrupt(dev);
return 0;
}
diff --git a/shared-core/radeon_mem.c b/shared-core/radeon_mem.c
index 9947e940..1e582ee0 100644
--- a/shared-core/radeon_mem.c
+++ b/shared-core/radeon_mem.c
@@ -224,7 +224,7 @@ int radeon_mem_alloc(struct drm_device *dev, void *data, struct drm_file *file_p
struct mem_block *block, **heap;
if (!dev_priv) {
- DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
+ DRM_ERROR("called with no initialization\n");
return -EINVAL;
}
@@ -259,7 +259,7 @@ int radeon_mem_free(struct drm_device *dev, void *data, struct drm_file *file_pr
struct mem_block *block, **heap;
if (!dev_priv) {
- DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
+ DRM_ERROR("called with no initialization\n");
return -EINVAL;
}
@@ -285,7 +285,7 @@ int radeon_mem_init_heap(struct drm_device *dev, void *data, struct drm_file *fi
struct mem_block **heap;
if (!dev_priv) {
- DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
+ DRM_ERROR("called with no initialization\n");
return -EINVAL;
}
diff --git a/shared-core/radeon_ms.h b/shared-core/radeon_ms.h
index a784882b..66533837 100644
--- a/shared-core/radeon_ms.h
+++ b/shared-core/radeon_ms.h
@@ -338,7 +338,7 @@ int radeon_ms_bo_get_gpu_addr(struct drm_device *dev,
int radeon_ms_bo_move(struct drm_buffer_object * bo, int evict,
int no_wait, struct drm_bo_mem_reg * new_mem);
struct drm_ttm_backend *radeon_ms_create_ttm_backend(struct drm_device * dev);
-uint32_t radeon_ms_evict_mask(struct drm_buffer_object *bo);
+uint64_t radeon_ms_evict_flags(struct drm_buffer_object *bo);
int radeon_ms_init_mem_type(struct drm_device * dev, uint32_t type,
struct drm_mem_type_manager * man);
int radeon_ms_invalidate_caches(struct drm_device * dev, uint64_t flags);
diff --git a/shared-core/radeon_ms_bo.c b/shared-core/radeon_ms_bo.c
index cedad689..6d9a97c1 100644
--- a/shared-core/radeon_ms_bo.c
+++ b/shared-core/radeon_ms_bo.c
@@ -141,7 +141,7 @@ static int radeon_ms_bo_move_flip(struct drm_buffer_object *bo,
tmp_mem = *new_mem;
tmp_mem.mm_node = NULL;
- tmp_mem.mask = DRM_BO_FLAG_MEM_TT |
+ tmp_mem.flags = DRM_BO_FLAG_MEM_TT |
DRM_BO_FLAG_CACHED |
DRM_BO_FLAG_FORCE_CACHING;
ret = drm_bo_mem_space(bo, &tmp_mem, no_wait);
@@ -149,7 +149,7 @@ static int radeon_ms_bo_move_flip(struct drm_buffer_object *bo,
return ret;
}
- ret = drm_bind_ttm(bo->ttm, &tmp_mem);
+ ret = drm_ttm_bind(bo->ttm, &tmp_mem);
if (ret) {
goto out_cleanup;
}
@@ -217,7 +217,7 @@ struct drm_ttm_backend *radeon_ms_create_ttm_backend(struct drm_device * dev)
return NULL;
}
-uint32_t radeon_ms_evict_mask(struct drm_buffer_object *bo)
+uint64_t radeon_ms_evict_flags(struct drm_buffer_object *bo)
{
switch (bo->mem.mem_type) {
case DRM_BO_MEM_LOCAL:
diff --git a/shared-core/radeon_ms_drm.c b/shared-core/radeon_ms_drm.c
index 91ca4a32..bf76b45d 100644
--- a/shared-core/radeon_ms_drm.c
+++ b/shared-core/radeon_ms_drm.c
@@ -63,7 +63,7 @@ struct drm_bo_driver radeon_ms_bo_driver = {
.fence_type = radeon_ms_fence_types,
.invalidate_caches = radeon_ms_invalidate_caches,
.init_mem_type = radeon_ms_init_mem_type,
- .evict_mask = radeon_ms_evict_mask,
+ .evict_flags = radeon_ms_evict_flags,
.move = radeon_ms_bo_move,
.ttm_cache_flush = radeon_ms_ttm_flush,
};
diff --git a/shared-core/radeon_state.c b/shared-core/radeon_state.c
index 623576ad..6f2e05b3 100644
--- a/shared-core/radeon_state.c
+++ b/shared-core/radeon_state.c
@@ -898,7 +898,7 @@ static void radeon_cp_dispatch_clear(struct drm_device * dev,
int w = pbox[i].x2 - x;
int h = pbox[i].y2 - y;
- DRM_DEBUG("dispatch clear %d,%d-%d,%d flags 0x%x\n",
+ DRM_DEBUG("%d,%d-%d,%d flags 0x%x\n",
x, y, w, h, flags);
if (flags & RADEON_FRONT) {
@@ -1368,7 +1368,7 @@ static void radeon_cp_dispatch_swap(struct drm_device * dev)
int w = pbox[i].x2 - x;
int h = pbox[i].y2 - y;
- DRM_DEBUG("dispatch swap %d,%d-%d,%d\n", x, y, w, h);
+ DRM_DEBUG("%d,%d-%d,%d\n", x, y, w, h);
BEGIN_RING(9);
@@ -1422,8 +1422,7 @@ static void radeon_cp_dispatch_flip(struct drm_device * dev)
int offset = (dev_priv->sarea_priv->pfCurrentPage == 1)
? dev_priv->front_offset : dev_priv->back_offset;
RING_LOCALS;
- DRM_DEBUG("%s: pfCurrentPage=%d\n",
- __FUNCTION__,
+ DRM_DEBUG("pfCurrentPage=%d\n",
dev_priv->sarea_priv->pfCurrentPage);
/* Do some trivial performance monitoring...
@@ -1562,7 +1561,7 @@ static void radeon_cp_dispatch_indirect(struct drm_device * dev,
{
drm_radeon_private_t *dev_priv = dev->dev_private;
RING_LOCALS;
- DRM_DEBUG("indirect: buf=%d s=0x%x e=0x%x\n", buf->idx, start, end);
+ DRM_DEBUG("buf=%d s=0x%x e=0x%x\n", buf->idx, start, end);
if (start != end) {
int offset = (dev_priv->gart_buffers_offset
@@ -1758,7 +1757,7 @@ static int radeon_cp_dispatch_texture(struct drm_device * dev,
buf = radeon_freelist_get(dev);
}
if (!buf) {
- DRM_DEBUG("radeon_cp_dispatch_texture: EAGAIN\n");
+ DRM_DEBUG("EAGAIN\n");
if (DRM_COPY_TO_USER(tex->image, image, sizeof(*image)))
return -EFAULT;
return -EAGAIN;
@@ -2084,7 +2083,7 @@ static int radeon_surface_alloc(struct drm_device *dev, void *data, struct drm_f
drm_radeon_surface_alloc_t *alloc = data;
if (!dev_priv) {
- DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
+ DRM_ERROR("called with no initialization\n");
return -EINVAL;
}
@@ -2100,7 +2099,7 @@ static int radeon_surface_free(struct drm_device *dev, void *data, struct drm_fi
drm_radeon_surface_free_t *memfree = data;
if (!dev_priv) {
- DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
+ DRM_ERROR("called with no initialization\n");
return -EINVAL;
}
@@ -2215,7 +2214,7 @@ static int radeon_cp_vertex(struct drm_device *dev, void *data, struct drm_file
LOCK_TEST_WITH_RETURN(dev, file_priv);
if (!dev_priv) {
- DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
+ DRM_ERROR("called with no initialization\n");
return -EINVAL;
}
@@ -2299,7 +2298,7 @@ static int radeon_cp_indices(struct drm_device *dev, void *data, struct drm_file
LOCK_TEST_WITH_RETURN(dev, file_priv);
if (!dev_priv) {
- DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
+ DRM_ERROR("called with no initialization\n");
return -EINVAL;
}
sarea_priv = dev_priv->sarea_priv;
@@ -2437,11 +2436,11 @@ static int radeon_cp_indirect(struct drm_device *dev, void *data, struct drm_fil
LOCK_TEST_WITH_RETURN(dev, file_priv);
if (!dev_priv) {
- DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
+ DRM_ERROR("called with no initialization\n");
return -EINVAL;
}
- DRM_DEBUG("indirect: idx=%d s=%d e=%d d=%d\n",
+ DRM_DEBUG("idx=%d s=%d e=%d d=%d\n",
indirect->idx, indirect->start, indirect->end,
indirect->discard);
@@ -2509,7 +2508,7 @@ static int radeon_cp_vertex2(struct drm_device *dev, void *data, struct drm_file
LOCK_TEST_WITH_RETURN(dev, file_priv);
if (!dev_priv) {
- DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
+ DRM_ERROR("called with no initialization\n");
return -EINVAL;
}
@@ -2814,7 +2813,7 @@ static int radeon_emit_wait(struct drm_device * dev, int flags)
drm_radeon_private_t *dev_priv = dev->dev_private;
RING_LOCALS;
- DRM_DEBUG("%s: %x\n", __FUNCTION__, flags);
+ DRM_DEBUG("%x\n", flags);
switch (flags) {
case RADEON_WAIT_2D:
BEGIN_RING(2);
@@ -2852,7 +2851,7 @@ static int radeon_cp_cmdbuf(struct drm_device *dev, void *data, struct drm_file
LOCK_TEST_WITH_RETURN(dev, file_priv);
if (!dev_priv) {
- DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
+ DRM_ERROR("called with no initialization\n");
return -EINVAL;
}
@@ -3013,7 +3012,7 @@ static int radeon_cp_getparam(struct drm_device *dev, void *data, struct drm_fil
int value;
if (!dev_priv) {
- DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
+ DRM_ERROR("called with no initialization\n");
return -EINVAL;
}
@@ -3104,7 +3103,7 @@ static int radeon_cp_setparam(struct drm_device *dev, void *data, struct drm_fil
struct drm_radeon_driver_file_fields *radeon_priv;
if (!dev_priv) {
- DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
+ DRM_ERROR("called with no initialization\n");
return -EINVAL;
}
diff --git a/shared-core/via_dma.c b/shared-core/via_dma.c
index ab39f53c..431738a9 100644
--- a/shared-core/via_dma.c
+++ b/shared-core/via_dma.c
@@ -167,14 +167,12 @@ static int via_initialize(struct drm_device * dev,
}
if (dev_priv->ring.virtual_start != NULL) {
- DRM_ERROR("%s called again without calling cleanup\n",
- __FUNCTION__);
+ DRM_ERROR("called again without calling cleanup\n");
return -EFAULT;
}
if (!dev->agp || !dev->agp->base) {
- DRM_ERROR("%s called with no agp memory available\n",
- __FUNCTION__);
+ DRM_ERROR("called with no agp memory available\n");
return -EFAULT;
}
@@ -257,8 +255,7 @@ static int via_dispatch_cmdbuffer(struct drm_device * dev, drm_via_cmdbuffer_t *
dev_priv = (drm_via_private_t *) dev->dev_private;
if (dev_priv->ring.virtual_start == NULL) {
- DRM_ERROR("%s called without initializing AGP ring buffer.\n",
- __FUNCTION__);
+ DRM_ERROR("called without initializing AGP ring buffer.\n");
return -EFAULT;
}
@@ -327,8 +324,7 @@ static int via_cmdbuffer(struct drm_device *dev, void *data, struct drm_file *fi
LOCK_TEST_WITH_RETURN(dev, file_priv);
- DRM_DEBUG("via cmdbuffer, buf %p size %lu\n", cmdbuf->buf,
- cmdbuf->size);
+ DRM_DEBUG("buf %p size %lu\n", cmdbuf->buf, cmdbuf->size);
ret = via_dispatch_cmdbuffer(dev, cmdbuf);
if (ret) {
@@ -369,8 +365,7 @@ static int via_pci_cmdbuffer(struct drm_device *dev, void *data, struct drm_file
LOCK_TEST_WITH_RETURN(dev, file_priv);
- DRM_DEBUG("via_pci_cmdbuffer, buf %p size %lu\n", cmdbuf->buf,
- cmdbuf->size);
+ DRM_DEBUG("buf %p size %lu\n", cmdbuf->buf, cmdbuf->size);
ret = via_dispatch_pci_cmdbuffer(dev, cmdbuf);
if (ret) {
@@ -640,14 +635,13 @@ static int via_cmdbuf_size(struct drm_device *dev, void *data, struct drm_file *
uint32_t tmp_size, count;
drm_via_private_t *dev_priv;
- DRM_DEBUG("via cmdbuf_size\n");
+ DRM_DEBUG("\n");
LOCK_TEST_WITH_RETURN(dev, file_priv);
dev_priv = (drm_via_private_t *) dev->dev_private;
if (dev_priv->ring.virtual_start == NULL) {
- DRM_ERROR("%s called without initializing AGP ring buffer.\n",
- __FUNCTION__);
+ DRM_ERROR("called without initializing AGP ring buffer.\n");
return -EFAULT;
}
diff --git a/shared-core/via_drv.c b/shared-core/via_drv.c
index 9f099555..a802e4ae 100644
--- a/shared-core/via_drv.c
+++ b/shared-core/via_drv.c
@@ -74,7 +74,7 @@ static struct drm_bo_driver via_bo_driver = {
.fence_type = via_fence_types,
.invalidate_caches = via_invalidate_caches,
.init_mem_type = via_init_mem_type,
- .evict_mask = via_evict_mask,
+ .evict_flags = via_evict_flags,
.move = NULL,
};
#endif
@@ -83,14 +83,16 @@ static int probe(struct pci_dev *pdev, const struct pci_device_id *ent);
static struct drm_driver driver = {
.driver_features =
DRIVER_USE_AGP | DRIVER_USE_MTRR | DRIVER_HAVE_IRQ |
- DRIVER_IRQ_SHARED | DRIVER_IRQ_VBL,
+ DRIVER_IRQ_SHARED,
.load = via_driver_load,
.unload = via_driver_unload,
#ifndef VIA_HAVE_CORE_MM
.context_ctor = via_init_context,
#endif
.context_dtor = via_final_context,
- .vblank_wait = via_driver_vblank_wait,
+ .get_vblank_counter = via_get_vblank_counter,
+ .enable_vblank = via_enable_vblank,
+ .disable_vblank = via_disable_vblank,
.irq_preinstall = via_driver_irq_preinstall,
.irq_postinstall = via_driver_irq_postinstall,
.irq_uninstall = via_driver_irq_uninstall,
diff --git a/shared-core/via_drv.h b/shared-core/via_drv.h
index d6da8bd9..8dd4a727 100644
--- a/shared-core/via_drv.h
+++ b/shared-core/via_drv.h
@@ -102,6 +102,7 @@ typedef struct drm_via_private {
struct timeval last_vblank;
int last_vblank_valid;
unsigned usec_per_vblank;
+ atomic_t vbl_received;
drm_via_state_t hc_state;
char pci_buf[VIA_PCI_BUF_SIZE];
const uint32_t *fire_offsets[VIA_FIRE_BUF_SIZE];
@@ -166,11 +167,13 @@ extern int via_driver_unload(struct drm_device *dev);
extern int via_final_context(struct drm_device * dev, int context);
extern int via_do_cleanup_map(struct drm_device * dev);
-extern int via_driver_vblank_wait(struct drm_device * dev, unsigned int *sequence);
+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);
extern irqreturn_t via_driver_irq_handler(DRM_IRQ_ARGS);
extern void via_driver_irq_preinstall(struct drm_device * dev);
-extern void via_driver_irq_postinstall(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);
@@ -211,7 +214,7 @@ extern int via_fence_types(struct drm_buffer_object *bo, uint32_t *fclass,
extern int via_invalidate_caches(struct drm_device *dev, uint64_t buffer_flags);
extern int via_init_mem_type(struct drm_device *dev, uint32_t type,
struct drm_mem_type_manager *man);
-extern uint32_t via_evict_mask(struct drm_buffer_object *bo);
+extern uint64_t via_evict_flags(struct drm_buffer_object *bo);
extern int via_move(struct drm_buffer_object *bo, int evict,
int no_wait, struct drm_bo_mem_reg *new_mem);
#endif
diff --git a/shared-core/via_irq.c b/shared-core/via_irq.c
index ec3f50bd..b8e652e6 100644
--- a/shared-core/via_irq.c
+++ b/shared-core/via_irq.c
@@ -96,6 +96,15 @@ static unsigned time_diff(struct timeval *now,struct timeval *then)
1000000 - (then->tv_usec - now->tv_usec);
}
+u32 via_get_vblank_counter(struct drm_device *dev, int crtc)
+{
+ drm_via_private_t *dev_priv = dev->dev_private;
+ if (crtc != 0)
+ return 0;
+
+ return atomic_read(&dev_priv->vbl_received);
+}
+
irqreturn_t via_driver_irq_handler(DRM_IRQ_ARGS)
{
struct drm_device *dev = (struct drm_device *) arg;
@@ -108,8 +117,8 @@ irqreturn_t via_driver_irq_handler(DRM_IRQ_ARGS)
status = VIA_READ(VIA_REG_INTERRUPT);
if (status & VIA_IRQ_VBLANK_PENDING) {
- atomic_inc(&dev->vbl_received);
- if (!(atomic_read(&dev->vbl_received) & 0x0F)) {
+ atomic_inc(&dev_priv->vbl_received);
+ if (!(atomic_read(&dev_priv->vbl_received) & 0x0F)) {
#ifdef __linux__
do_gettimeofday(&cur_vblank);
#else
@@ -123,12 +132,11 @@ irqreturn_t via_driver_irq_handler(DRM_IRQ_ARGS)
dev_priv->last_vblank = cur_vblank;
dev_priv->last_vblank_valid = 1;
}
- if (!(atomic_read(&dev->vbl_received) & 0xFF)) {
+ if (!(atomic_read(&dev_priv->vbl_received) & 0xFF)) {
DRM_DEBUG("US per vblank is: %u\n",
dev_priv->usec_per_vblank);
}
- DRM_WAKEUP(&dev->vbl_queue);
- drm_vbl_send_signals(dev);
+ drm_handle_vblank(dev, 0);
handled = 1;
}
@@ -170,31 +178,25 @@ static __inline__ void viadrv_acknowledge_irqs(drm_via_private_t * dev_priv)
}
}
-int via_driver_vblank_wait(struct drm_device * dev, unsigned int *sequence)
+int via_enable_vblank(struct drm_device *dev, int crtc)
{
- drm_via_private_t *dev_priv = (drm_via_private_t *) dev->dev_private;
- unsigned int cur_vblank;
- int ret = 0;
+ drm_via_private_t *dev_priv = dev->dev_private;
+ u32 status;
- DRM_DEBUG("viadrv_vblank_wait\n");
- if (!dev_priv) {
- DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
+ if (crtc != 0) {
+ DRM_ERROR("%s: bad crtc %d\n", __FUNCTION__, crtc);
return -EINVAL;
}
- viadrv_acknowledge_irqs(dev_priv);
-
- /* Assume that the user has missed the current sequence number
- * by about a day rather than she wants to wait for years
- * using vertical blanks...
- */
-
- DRM_WAIT_ON(ret, dev->vbl_queue, 3 * DRM_HZ,
- (((cur_vblank = atomic_read(&dev->vbl_received)) -
- *sequence) <= (1 << 23)));
+ status = VIA_READ(VIA_REG_INTERRUPT);
+ VIA_WRITE(VIA_REG_INTERRUPT, status & VIA_IRQ_VBLANK_ENABLE);
+ return 0;
+}
- *sequence = cur_vblank;
- return ret;
+void via_disable_vblank(struct drm_device *dev, int crtc)
+{
+ if (crtc != 0)
+ DRM_ERROR("%s: bad crtc %d\n", __FUNCTION__, crtc);
}
static int
@@ -208,24 +210,23 @@ via_driver_irq_wait(struct drm_device * dev, unsigned int irq, int force_sequenc
maskarray_t *masks;
int real_irq;
- DRM_DEBUG("%s\n", __FUNCTION__);
+ DRM_DEBUG("\n");
if (!dev_priv) {
- DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
+ DRM_ERROR("called with no initialization\n");
return -EINVAL;
}
if (irq >= drm_via_irq_num) {
- DRM_ERROR("%s Trying to wait on unknown irq %d\n", __FUNCTION__,
- irq);
+ DRM_ERROR("Trying to wait on unknown irq %d\n", irq);
return -EINVAL;
}
real_irq = dev_priv->irq_map[irq];
if (real_irq < 0) {
- DRM_ERROR("%s Video IRQ %d not available on this hardware.\n",
- __FUNCTION__, irq);
+ DRM_ERROR("Video IRQ %d not available on this hardware.\n",
+ irq);
return -EINVAL;
}
@@ -259,7 +260,7 @@ void via_driver_irq_preinstall(struct drm_device * dev)
drm_via_irq_t *cur_irq;
int i;
- DRM_DEBUG("driver_irq_preinstall: dev_priv: %p\n", dev_priv);
+ DRM_DEBUG("dev_priv: %p\n", dev_priv);
if (dev_priv) {
cur_irq = dev_priv->via_irqs;
@@ -301,23 +302,24 @@ void via_driver_irq_preinstall(struct drm_device * dev)
}
}
-void via_driver_irq_postinstall(struct drm_device * dev)
+int via_driver_irq_postinstall(struct drm_device * dev)
{
drm_via_private_t *dev_priv = (drm_via_private_t *) dev->dev_private;
u32 status;
DRM_DEBUG("via_driver_irq_postinstall\n");
- if (dev_priv) {
- status = VIA_READ(VIA_REG_INTERRUPT);
- VIA_WRITE(VIA_REG_INTERRUPT, status | VIA_IRQ_GLOBAL
- | dev_priv->irq_enable_mask);
+ if (!dev_priv)
+ return -EINVAL;
- /* Some magic, oh for some data sheets ! */
+ status = VIA_READ(VIA_REG_INTERRUPT);
+ VIA_WRITE(VIA_REG_INTERRUPT, status | VIA_IRQ_GLOBAL
+ | dev_priv->irq_enable_mask);
- VIA_WRITE8(0x83d4, 0x11);
- VIA_WRITE8(0x83d5, VIA_READ8(0x83d5) | 0x30);
+ /* Some magic, oh for some data sheets ! */
+ VIA_WRITE8(0x83d4, 0x11);
+ VIA_WRITE8(0x83d5, VIA_READ8(0x83d5) | 0x30);
- }
+ return 0;
}
void via_driver_irq_uninstall(struct drm_device * dev)
@@ -325,7 +327,7 @@ void via_driver_irq_uninstall(struct drm_device * dev)
drm_via_private_t *dev_priv = (drm_via_private_t *) dev->dev_private;
u32 status;
- DRM_DEBUG("driver_irq_uninstall)\n");
+ DRM_DEBUG("\n");
if (dev_priv) {
/* Some more magic, oh for some data sheets ! */
@@ -352,7 +354,7 @@ int via_wait_irq(struct drm_device *dev, void *data, struct drm_file *file_priv)
return -EINVAL;
if (irqwait->request.irq >= dev_priv->num_irqs) {
- DRM_ERROR("%s Trying to wait on unknown irq %d\n", __FUNCTION__,
+ DRM_ERROR("Trying to wait on unknown irq %d\n",
irqwait->request.irq);
return -EINVAL;
}
@@ -371,8 +373,7 @@ int via_wait_irq(struct drm_device *dev, void *data, struct drm_file *file_priv)
}
if (irqwait->request.type & VIA_IRQ_SIGNAL) {
- DRM_ERROR("%s Signals on Via IRQs not implemented yet.\n",
- __FUNCTION__);
+ DRM_ERROR("Signals on Via IRQs not implemented yet.\n");
return -EINVAL;
}
diff --git a/shared-core/via_map.c b/shared-core/via_map.c
index b8f61673..11bfa551 100644
--- a/shared-core/via_map.c
+++ b/shared-core/via_map.c
@@ -30,7 +30,7 @@ static int via_do_init_map(struct drm_device * dev, drm_via_init_t * init)
drm_via_private_t *dev_priv = dev->dev_private;
int ret = 0;
- DRM_DEBUG("%s\n", __FUNCTION__);
+ DRM_DEBUG("\n");
dev_priv->sarea = drm_getsarea(dev);
if (!dev_priv->sarea) {
@@ -95,7 +95,7 @@ int via_map_init(struct drm_device *dev, void *data, struct drm_file *file_priv)
{
drm_via_init_t *init = data;
- DRM_DEBUG("%s\n", __FUNCTION__);
+ DRM_DEBUG("\n");
switch (init->func) {
case VIA_INIT_MAP:
diff --git a/shared-core/via_video.c b/shared-core/via_video.c
index c15e75b5..6ec04ac1 100644
--- a/shared-core/via_video.c
+++ b/shared-core/via_video.c
@@ -33,7 +33,7 @@ void via_init_futex(drm_via_private_t * dev_priv)
{
unsigned int i;
- DRM_DEBUG("%s\n", __FUNCTION__);
+ DRM_DEBUG("\n");
for (i = 0; i < VIA_NR_XVMC_LOCKS; ++i) {
DRM_INIT_WAITQUEUE(&(dev_priv->decoder_queue[i]));
@@ -73,7 +73,7 @@ int via_decoder_futex(struct drm_device *dev, void *data, struct drm_file *file_
drm_via_sarea_t *sAPriv = dev_priv->sarea_priv;
int ret = 0;
- DRM_DEBUG("%s\n", __FUNCTION__);
+ DRM_DEBUG("\n");
if (fx->lock > VIA_NR_XVMC_LOCKS)
return -EFAULT;