aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/vmwgfx
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2013-09-01 19:31:40 -0400
committerDave Airlie <airlied@redhat.com>2013-09-01 19:31:40 -0400
commit9c725e5bcdae59d5383d4aec33a34c822582dda5 (patch)
tree3d55827f5f44f16cb0aada2713029f7490f557d4 /drivers/gpu/drm/vmwgfx
parentefa27f9cec09518c9b574e3ab4a0a41717237429 (diff)
parent679fe80fbe964ea7f9f71781c2ca65b630949da3 (diff)
Merge branch 'drm-next-3.12' of git://people.freedesktop.org/~agd5f/linux into drm-next
Alex writes: This is the radeon drm-next request. Big changes include: - support for dpm on CIK parts - support for ASPM on CIK parts - support for berlin GPUs - major ring handling cleanup - remove the old 3D blit code for bo moves in favor of CP DMA or sDMA - lots of bug fixes [airlied: fix up a bunch of conflicts from drm_order removal] * 'drm-next-3.12' of git://people.freedesktop.org/~agd5f/linux: (898 commits) drm/radeon/dpm: make sure dc performance level limits are valid (CI) drm/radeon/dpm: make sure dc performance level limits are valid (BTC-SI) (v2) drm/radeon: gcc fixes for extended dpm tables drm/radeon: gcc fixes for kb/kv dpm drm/radeon: gcc fixes for ci dpm drm/radeon: gcc fixes for si dpm drm/radeon: gcc fixes for ni dpm drm/radeon: gcc fixes for trinity dpm drm/radeon: gcc fixes for sumo dpm drm/radeonn: gcc fixes for rv7xx/eg/btc dpm drm/radeon: gcc fixes for rv6xx dpm drm/radeon: gcc fixes for radeon_atombios.c drm/radeon: enable UVD interrupts on CIK drm/radeon: fix init ordering for r600+ drm/radeon/dpm: only need to reprogram uvd if uvd pg is enabled drm/radeon: check the return value of uvd_v1_0_start in uvd_v1_0_init drm/radeon: split out radeon_uvd_resume from uvd_v4_2_resume radeon kms: fix uninitialised hotplug work usage in r100_irq_process() drm/radeon/audio: set up the sads on DCE3.2 asics drm/radeon: fix handling of variable sized arrays for router objects ... Conflicts: drivers/gpu/drm/i915/i915_dma.c drivers/gpu/drm/i915/i915_gem_dmabuf.c drivers/gpu/drm/i915/intel_pm.c drivers/gpu/drm/radeon/cik.c drivers/gpu/drm/radeon/ni.c drivers/gpu/drm/radeon/r600.c
Diffstat (limited to 'drivers/gpu/drm/vmwgfx')
-rw-r--r--drivers/gpu/drm/vmwgfx/vmwgfx_gmr.c58
1 files changed, 39 insertions, 19 deletions
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_gmr.c b/drivers/gpu/drm/vmwgfx/vmwgfx_gmr.c
index 3751730764a5..1a0bf07fe54b 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_gmr.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_gmr.c
@@ -29,7 +29,9 @@
29#include <drm/drmP.h> 29#include <drm/drmP.h>
30#include <drm/ttm/ttm_bo_driver.h> 30#include <drm/ttm/ttm_bo_driver.h>
31 31
32#define VMW_PPN_SIZE sizeof(unsigned long) 32#define VMW_PPN_SIZE (sizeof(unsigned long))
33/* A future safe maximum remap size. */
34#define VMW_PPN_PER_REMAP ((31 * 1024) / VMW_PPN_SIZE)
33 35
34static int vmw_gmr2_bind(struct vmw_private *dev_priv, 36static int vmw_gmr2_bind(struct vmw_private *dev_priv,
35 struct page *pages[], 37 struct page *pages[],
@@ -38,43 +40,61 @@ static int vmw_gmr2_bind(struct vmw_private *dev_priv,
38{ 40{
39 SVGAFifoCmdDefineGMR2 define_cmd; 41 SVGAFifoCmdDefineGMR2 define_cmd;
40 SVGAFifoCmdRemapGMR2 remap_cmd; 42 SVGAFifoCmdRemapGMR2 remap_cmd;
41 uint32_t define_size = sizeof(define_cmd) + 4;
42 uint32_t remap_size = VMW_PPN_SIZE * num_pages + sizeof(remap_cmd) + 4;
43 uint32_t *cmd; 43 uint32_t *cmd;
44 uint32_t *cmd_orig; 44 uint32_t *cmd_orig;
45 uint32_t define_size = sizeof(define_cmd) + sizeof(*cmd);
46 uint32_t remap_num = num_pages / VMW_PPN_PER_REMAP + ((num_pages % VMW_PPN_PER_REMAP) > 0);
47 uint32_t remap_size = VMW_PPN_SIZE * num_pages + (sizeof(remap_cmd) + sizeof(*cmd)) * remap_num;
48 uint32_t remap_pos = 0;
49 uint32_t cmd_size = define_size + remap_size;
45 uint32_t i; 50 uint32_t i;
46 51
47 cmd_orig = cmd = vmw_fifo_reserve(dev_priv, define_size + remap_size); 52 cmd_orig = cmd = vmw_fifo_reserve(dev_priv, cmd_size);
48 if (unlikely(cmd == NULL)) 53 if (unlikely(cmd == NULL))
49 return -ENOMEM; 54 return -ENOMEM;
50 55
51 define_cmd.gmrId = gmr_id; 56 define_cmd.gmrId = gmr_id;
52 define_cmd.numPages = num_pages; 57 define_cmd.numPages = num_pages;
53 58
59 *cmd++ = SVGA_CMD_DEFINE_GMR2;
60 memcpy(cmd, &define_cmd, sizeof(define_cmd));
61 cmd += sizeof(define_cmd) / sizeof(*cmd);
62
63 /*
64 * Need to split the command if there are too many
65 * pages that goes into the gmr.
66 */
67
54 remap_cmd.gmrId = gmr_id; 68 remap_cmd.gmrId = gmr_id;
55 remap_cmd.flags = (VMW_PPN_SIZE > sizeof(*cmd)) ? 69 remap_cmd.flags = (VMW_PPN_SIZE > sizeof(*cmd)) ?
56 SVGA_REMAP_GMR2_PPN64 : SVGA_REMAP_GMR2_PPN32; 70 SVGA_REMAP_GMR2_PPN64 : SVGA_REMAP_GMR2_PPN32;
57 remap_cmd.offsetPages = 0;
58 remap_cmd.numPages = num_pages;
59 71
60 *cmd++ = SVGA_CMD_DEFINE_GMR2; 72 while (num_pages > 0) {
61 memcpy(cmd, &define_cmd, sizeof(define_cmd)); 73 unsigned long nr = min(num_pages, (unsigned long)VMW_PPN_PER_REMAP);
62 cmd += sizeof(define_cmd) / sizeof(uint32); 74
75 remap_cmd.offsetPages = remap_pos;
76 remap_cmd.numPages = nr;
63 77
64 *cmd++ = SVGA_CMD_REMAP_GMR2; 78 *cmd++ = SVGA_CMD_REMAP_GMR2;
65 memcpy(cmd, &remap_cmd, sizeof(remap_cmd)); 79 memcpy(cmd, &remap_cmd, sizeof(remap_cmd));
66 cmd += sizeof(remap_cmd) / sizeof(uint32); 80 cmd += sizeof(remap_cmd) / sizeof(*cmd);
67 81
68 for (i = 0; i < num_pages; ++i) { 82 for (i = 0; i < nr; ++i) {
69 if (VMW_PPN_SIZE <= 4) 83 if (VMW_PPN_SIZE <= 4)
70 *cmd = page_to_pfn(*pages++); 84 *cmd = page_to_pfn(*pages++);
71 else 85 else
72 *((uint64_t *)cmd) = page_to_pfn(*pages++); 86 *((uint64_t *)cmd) = page_to_pfn(*pages++);
73 87
74 cmd += VMW_PPN_SIZE / sizeof(*cmd); 88 cmd += VMW_PPN_SIZE / sizeof(*cmd);
89 }
90
91 num_pages -= nr;
92 remap_pos += nr;
75 } 93 }
76 94
77 vmw_fifo_commit(dev_priv, define_size + remap_size); 95 BUG_ON(cmd != cmd_orig + cmd_size / sizeof(*cmd));
96
97 vmw_fifo_commit(dev_priv, cmd_size);
78 98
79 return 0; 99 return 0;
80} 100}