aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/gpu/drm/i915/i915_drv.c2
-rw-r--r--drivers/gpu/drm/i915/i915_irq.c15
-rw-r--r--drivers/gpu/drm/i915/i915_reg.h26
-rw-r--r--drivers/gpu/drm/i915/intel_ringbuffer.c124
4 files changed, 159 insertions, 8 deletions
diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index 393696cee86d..2c87f9b97b6f 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -157,11 +157,13 @@ static const struct intel_device_info intel_ironlake_m_info = {
157static const struct intel_device_info intel_sandybridge_d_info = { 157static const struct intel_device_info intel_sandybridge_d_info = {
158 .gen = 6, 158 .gen = 6,
159 .need_gfx_hws = 1, .has_hotplug = 1, 159 .need_gfx_hws = 1, .has_hotplug = 1,
160 .has_bsd_ring = 1,
160}; 161};
161 162
162static const struct intel_device_info intel_sandybridge_m_info = { 163static const struct intel_device_info intel_sandybridge_m_info = {
163 .gen = 6, .is_mobile = 1, 164 .gen = 6, .is_mobile = 1,
164 .need_gfx_hws = 1, .has_hotplug = 1, 165 .need_gfx_hws = 1, .has_hotplug = 1,
166 .has_bsd_ring = 1,
165}; 167};
166 168
167static const struct pci_device_id pciidlist[] = { /* aka */ 169static const struct pci_device_id pciidlist[] = { /* aka */
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
index b1e7655288d8..d4c053e1c376 100644
--- a/drivers/gpu/drm/i915/i915_irq.c
+++ b/drivers/gpu/drm/i915/i915_irq.c
@@ -300,6 +300,10 @@ static irqreturn_t ironlake_irq_handler(struct drm_device *dev)
300 u32 de_iir, gt_iir, de_ier, pch_iir; 300 u32 de_iir, gt_iir, de_ier, pch_iir;
301 struct drm_i915_master_private *master_priv; 301 struct drm_i915_master_private *master_priv;
302 struct intel_ring_buffer *render_ring = &dev_priv->render_ring; 302 struct intel_ring_buffer *render_ring = &dev_priv->render_ring;
303 u32 bsd_usr_interrupt = GT_BSD_USER_INTERRUPT;
304
305 if (IS_GEN6(dev))
306 bsd_usr_interrupt = GT_GEN6_BSD_USER_INTERRUPT;
303 307
304 /* disable master interrupt before clearing iir */ 308 /* disable master interrupt before clearing iir */
305 de_ier = I915_READ(DEIER); 309 de_ier = I915_READ(DEIER);
@@ -331,10 +335,9 @@ static irqreturn_t ironlake_irq_handler(struct drm_device *dev)
331 mod_timer(&dev_priv->hangcheck_timer, 335 mod_timer(&dev_priv->hangcheck_timer,
332 jiffies + msecs_to_jiffies(DRM_I915_HANGCHECK_PERIOD)); 336 jiffies + msecs_to_jiffies(DRM_I915_HANGCHECK_PERIOD));
333 } 337 }
334 if (gt_iir & GT_BSD_USER_INTERRUPT) 338 if (gt_iir & bsd_usr_interrupt)
335 DRM_WAKEUP(&dev_priv->bsd_ring.irq_queue); 339 DRM_WAKEUP(&dev_priv->bsd_ring.irq_queue);
336 340
337
338 if (de_iir & DE_GSE) 341 if (de_iir & DE_GSE)
339 intel_opregion_gse_intr(dev); 342 intel_opregion_gse_intr(dev);
340 343
@@ -1436,17 +1439,19 @@ static int ironlake_irq_postinstall(struct drm_device *dev)
1436 I915_WRITE(DEIER, dev_priv->de_irq_enable_reg); 1439 I915_WRITE(DEIER, dev_priv->de_irq_enable_reg);
1437 (void) I915_READ(DEIER); 1440 (void) I915_READ(DEIER);
1438 1441
1439 /* Gen6 only needs render pipe_control now */
1440 if (IS_GEN6(dev)) 1442 if (IS_GEN6(dev))
1441 render_mask = GT_PIPE_NOTIFY; 1443 render_mask = GT_PIPE_NOTIFY | GT_GEN6_BSD_USER_INTERRUPT;
1442 1444
1443 dev_priv->gt_irq_mask_reg = ~render_mask; 1445 dev_priv->gt_irq_mask_reg = ~render_mask;
1444 dev_priv->gt_irq_enable_reg = render_mask; 1446 dev_priv->gt_irq_enable_reg = render_mask;
1445 1447
1446 I915_WRITE(GTIIR, I915_READ(GTIIR)); 1448 I915_WRITE(GTIIR, I915_READ(GTIIR));
1447 I915_WRITE(GTIMR, dev_priv->gt_irq_mask_reg); 1449 I915_WRITE(GTIMR, dev_priv->gt_irq_mask_reg);
1448 if (IS_GEN6(dev)) 1450 if (IS_GEN6(dev)) {
1449 I915_WRITE(GEN6_RENDER_IMR, ~GEN6_RENDER_PIPE_CONTROL_NOTIFY_INTERRUPT); 1451 I915_WRITE(GEN6_RENDER_IMR, ~GEN6_RENDER_PIPE_CONTROL_NOTIFY_INTERRUPT);
1452 I915_WRITE(GEN6_BSD_IMR, ~GEN6_BSD_IMR_USER_INTERRUPT);
1453 }
1454
1450 I915_WRITE(GTIER, dev_priv->gt_irq_enable_reg); 1455 I915_WRITE(GTIER, dev_priv->gt_irq_enable_reg);
1451 (void) I915_READ(GTIER); 1456 (void) I915_READ(GTIER);
1452 1457
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index b46e580421e1..8d51de0e01f2 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -197,11 +197,11 @@
197#define MI_STORE_DWORD_INDEX MI_INSTR(0x21, 1) 197#define MI_STORE_DWORD_INDEX MI_INSTR(0x21, 1)
198#define MI_STORE_DWORD_INDEX_SHIFT 2 198#define MI_STORE_DWORD_INDEX_SHIFT 2
199#define MI_LOAD_REGISTER_IMM MI_INSTR(0x22, 1) 199#define MI_LOAD_REGISTER_IMM MI_INSTR(0x22, 1)
200#define MI_FLUSH_DW MI_INSTR(0x26, 2) /* for GEN6 */
200#define MI_BATCH_BUFFER MI_INSTR(0x30, 1) 201#define MI_BATCH_BUFFER MI_INSTR(0x30, 1)
201#define MI_BATCH_NON_SECURE (1) 202#define MI_BATCH_NON_SECURE (1)
202#define MI_BATCH_NON_SECURE_I965 (1<<8) 203#define MI_BATCH_NON_SECURE_I965 (1<<8)
203#define MI_BATCH_BUFFER_START MI_INSTR(0x31, 0) 204#define MI_BATCH_BUFFER_START MI_INSTR(0x31, 0)
204
205/* 205/*
206 * 3D instructions used by the kernel 206 * 3D instructions used by the kernel
207 */ 207 */
@@ -484,6 +484,28 @@
484#define BSD_HWS_PGA 0x04080 484#define BSD_HWS_PGA 0x04080
485 485
486/* 486/*
487 * video command stream instruction and interrupt control register defines
488 * for GEN6
489 */
490#define GEN6_BSD_RING_TAIL 0x12030
491#define GEN6_BSD_RING_HEAD 0x12034
492#define GEN6_BSD_RING_START 0x12038
493#define GEN6_BSD_RING_CTL 0x1203c
494#define GEN6_BSD_RING_ACTHD 0x12074
495#define GEN6_BSD_HWS_PGA 0x14080
496
497#define GEN6_BSD_SLEEP_PSMI_CONTROL 0x12050
498#define GEN6_BSD_SLEEP_PSMI_CONTROL_RC_ILDL_MESSAGE_MODIFY_MASK (1 << 16)
499#define GEN6_BSD_SLEEP_PSMI_CONTROL_RC_ILDL_MESSAGE_DISABLE (1 << 0)
500#define GEN6_BSD_SLEEP_PSMI_CONTROL_RC_ILDL_MESSAGE_ENABLE 0
501#define GEN6_BSD_SLEEP_PSMI_CONTROL_IDLE_INDICATOR (1 << 3)
502
503#define GEN6_BSD_IMR 0x120a8
504#define GEN6_BSD_IMR_USER_INTERRUPT (1 << 12)
505
506#define GEN6_BSD_RNCID 0x12198
507
508/*
487 * Framebuffer compression (915+ only) 509 * Framebuffer compression (915+ only)
488 */ 510 */
489 511
@@ -2598,7 +2620,7 @@
2598#define GT_SYNC_STATUS (1 << 2) 2620#define GT_SYNC_STATUS (1 << 2)
2599#define GT_USER_INTERRUPT (1 << 0) 2621#define GT_USER_INTERRUPT (1 << 0)
2600#define GT_BSD_USER_INTERRUPT (1 << 5) 2622#define GT_BSD_USER_INTERRUPT (1 << 5)
2601 2623#define GT_GEN6_BSD_USER_INTERRUPT (1 << 12)
2602 2624
2603#define GTISR 0x44010 2625#define GTISR 0x44010
2604#define GTIMR 0x44014 2626#define GTIMR 0x44014
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c
index 3f80f18e2844..478406d1886c 100644
--- a/drivers/gpu/drm/i915/intel_ringbuffer.c
+++ b/drivers/gpu/drm/i915/intel_ringbuffer.c
@@ -32,6 +32,7 @@
32#include "i915_drv.h" 32#include "i915_drv.h"
33#include "i915_drm.h" 33#include "i915_drm.h"
34#include "i915_trace.h" 34#include "i915_trace.h"
35#include "intel_drv.h"
35 36
36static u32 i915_gem_get_seqno(struct drm_device *dev) 37static u32 i915_gem_get_seqno(struct drm_device *dev)
37{ 38{
@@ -865,6 +866,124 @@ static struct intel_ring_buffer bsd_ring = {
865 .map = {0,} 866 .map = {0,}
866}; 867};
867 868
869
870static void gen6_bsd_setup_status_page(struct drm_device *dev,
871 struct intel_ring_buffer *ring)
872{
873 drm_i915_private_t *dev_priv = dev->dev_private;
874 I915_WRITE(GEN6_BSD_HWS_PGA, ring->status_page.gfx_addr);
875 I915_READ(GEN6_BSD_HWS_PGA);
876}
877
878static inline unsigned int gen6_bsd_ring_get_head(struct drm_device *dev,
879 struct intel_ring_buffer *ring)
880{
881 drm_i915_private_t *dev_priv = dev->dev_private;
882 return I915_READ(GEN6_BSD_RING_HEAD) & HEAD_ADDR;
883}
884
885static inline unsigned int gen6_bsd_ring_get_tail(struct drm_device *dev,
886 struct intel_ring_buffer *ring)
887{
888 drm_i915_private_t *dev_priv = dev->dev_private;
889 return I915_READ(GEN6_BSD_RING_TAIL) & TAIL_ADDR;
890}
891
892static inline void gen6_bsd_ring_set_tail(struct drm_device *dev,
893 u32 value)
894{
895 drm_i915_private_t *dev_priv = dev->dev_private;
896
897 /* Every tail move must follow the sequence below */
898 I915_WRITE(GEN6_BSD_SLEEP_PSMI_CONTROL,
899 GEN6_BSD_SLEEP_PSMI_CONTROL_RC_ILDL_MESSAGE_MODIFY_MASK |
900 GEN6_BSD_SLEEP_PSMI_CONTROL_RC_ILDL_MESSAGE_DISABLE);
901 I915_WRITE(GEN6_BSD_RNCID, 0x0);
902
903 if (wait_for((I915_READ(GEN6_BSD_SLEEP_PSMI_CONTROL) &
904 GEN6_BSD_SLEEP_PSMI_CONTROL_IDLE_INDICATOR) == 0,
905 50))
906 DRM_ERROR("timed out waiting for IDLE Indicator\n");
907
908 I915_WRITE(GEN6_BSD_RING_TAIL, value);
909 I915_WRITE(GEN6_BSD_SLEEP_PSMI_CONTROL,
910 GEN6_BSD_SLEEP_PSMI_CONTROL_RC_ILDL_MESSAGE_MODIFY_MASK |
911 GEN6_BSD_SLEEP_PSMI_CONTROL_RC_ILDL_MESSAGE_ENABLE);
912}
913
914static inline unsigned int gen6_bsd_ring_get_active_head(struct drm_device *dev,
915 struct intel_ring_buffer *ring)
916{
917 drm_i915_private_t *dev_priv = dev->dev_private;
918 return I915_READ(GEN6_BSD_RING_ACTHD);
919}
920
921static void gen6_bsd_ring_flush(struct drm_device *dev,
922 struct intel_ring_buffer *ring,
923 u32 invalidate_domains,
924 u32 flush_domains)
925{
926 intel_ring_begin(dev, ring, 4);
927 intel_ring_emit(dev, ring, MI_FLUSH_DW);
928 intel_ring_emit(dev, ring, 0);
929 intel_ring_emit(dev, ring, 0);
930 intel_ring_emit(dev, ring, 0);
931 intel_ring_advance(dev, ring);
932}
933
934static int
935gen6_bsd_ring_dispatch_gem_execbuffer(struct drm_device *dev,
936 struct intel_ring_buffer *ring,
937 struct drm_i915_gem_execbuffer2 *exec,
938 struct drm_clip_rect *cliprects,
939 uint64_t exec_offset)
940{
941 uint32_t exec_start;
942 exec_start = (uint32_t) exec_offset + exec->batch_start_offset;
943 intel_ring_begin(dev, ring, 2);
944 intel_ring_emit(dev, ring, MI_BATCH_BUFFER_START | MI_BATCH_NON_SECURE_I965); /* bit0-7 is the length on GEN6+ */
945 intel_ring_emit(dev, ring, exec_start);
946 intel_ring_advance(dev, ring);
947 return 0;
948}
949
950/* ring buffer for Video Codec for Gen6+ */
951static struct intel_ring_buffer gen6_bsd_ring = {
952 .name = "gen6 bsd ring",
953 .id = RING_BSD,
954 .regs = {
955 .ctl = GEN6_BSD_RING_CTL,
956 .head = GEN6_BSD_RING_HEAD,
957 .tail = GEN6_BSD_RING_TAIL,
958 .start = GEN6_BSD_RING_START
959 },
960 .size = 32 * PAGE_SIZE,
961 .alignment = PAGE_SIZE,
962 .virtual_start = NULL,
963 .dev = NULL,
964 .gem_object = NULL,
965 .head = 0,
966 .tail = 0,
967 .space = 0,
968 .user_irq_refcount = 0,
969 .irq_gem_seqno = 0,
970 .waiting_gem_seqno = 0,
971 .setup_status_page = gen6_bsd_setup_status_page,
972 .init = init_bsd_ring,
973 .get_head = gen6_bsd_ring_get_head,
974 .get_tail = gen6_bsd_ring_get_tail,
975 .set_tail = gen6_bsd_ring_set_tail,
976 .get_active_head = gen6_bsd_ring_get_active_head,
977 .flush = gen6_bsd_ring_flush,
978 .add_request = bsd_ring_add_request,
979 .get_gem_seqno = bsd_ring_get_gem_seqno,
980 .user_irq_get = bsd_ring_get_user_irq,
981 .user_irq_put = bsd_ring_put_user_irq,
982 .dispatch_gem_execbuffer = gen6_bsd_ring_dispatch_gem_execbuffer,
983 .status_page = {NULL, 0, NULL},
984 .map = {0,}
985};
986
868int intel_init_render_ring_buffer(struct drm_device *dev) 987int intel_init_render_ring_buffer(struct drm_device *dev)
869{ 988{
870 drm_i915_private_t *dev_priv = dev->dev_private; 989 drm_i915_private_t *dev_priv = dev->dev_private;
@@ -885,7 +1004,10 @@ int intel_init_bsd_ring_buffer(struct drm_device *dev)
885{ 1004{
886 drm_i915_private_t *dev_priv = dev->dev_private; 1005 drm_i915_private_t *dev_priv = dev->dev_private;
887 1006
888 dev_priv->bsd_ring = bsd_ring; 1007 if (IS_GEN6(dev))
1008 dev_priv->bsd_ring = gen6_bsd_ring;
1009 else
1010 dev_priv->bsd_ring = bsd_ring;
889 1011
890 return intel_init_ring_buffer(dev, &dev_priv->bsd_ring); 1012 return intel_init_ring_buffer(dev, &dev_priv->bsd_ring);
891} 1013}