Rev 4080 | Rev 4569 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 4080 | Rev 4111 | ||
---|---|---|---|
Line 30... | Line 30... | ||
30 | 30 | ||
31 | #include "vmwgfx_drv.h" |
31 | #include "vmwgfx_drv.h" |
32 | #include |
32 | #include |
Line 33... | Line 33... | ||
33 | #include |
33 | #include |
- | 34 | ||
- | 35 | #define VMW_PPN_SIZE (sizeof(unsigned long)) |
|
Line 34... | Line 36... | ||
34 | 36 | /* A future safe maximum remap size. */ |
|
35 | #define VMW_PPN_SIZE sizeof(unsigned long) |
37 | #define VMW_PPN_PER_REMAP ((31 * 1024) / VMW_PPN_SIZE) |
36 | 38 | ||
37 | static int vmw_gmr2_bind(struct vmw_private *dev_priv, |
39 | static int vmw_gmr2_bind(struct vmw_private *dev_priv, |
38 | struct page *pages[], |
40 | struct page *pages[], |
39 | unsigned long num_pages, |
41 | unsigned long num_pages, |
40 | int gmr_id) |
42 | int gmr_id) |
41 | { |
- | |
42 | SVGAFifoCmdDefineGMR2 define_cmd; |
- | |
43 | SVGAFifoCmdRemapGMR2 remap_cmd; |
43 | { |
44 | uint32_t define_size = sizeof(define_cmd) + 4; |
44 | SVGAFifoCmdDefineGMR2 define_cmd; |
- | 45 | SVGAFifoCmdRemapGMR2 remap_cmd; |
|
- | 46 | uint32_t *cmd; |
|
- | 47 | uint32_t *cmd_orig; |
|
- | 48 | uint32_t define_size = sizeof(define_cmd) + sizeof(*cmd); |
|
- | 49 | uint32_t remap_num = num_pages / VMW_PPN_PER_REMAP + ((num_pages % VMW_PPN_PER_REMAP) > 0); |
|
45 | uint32_t remap_size = VMW_PPN_SIZE * num_pages + sizeof(remap_cmd) + 4; |
50 | uint32_t remap_size = VMW_PPN_SIZE * num_pages + (sizeof(remap_cmd) + sizeof(*cmd)) * remap_num; |
Line 46... | Line 51... | ||
46 | uint32_t *cmd; |
51 | uint32_t remap_pos = 0; |
47 | uint32_t *cmd_orig; |
52 | uint32_t cmd_size = define_size + remap_size; |
48 | uint32_t i; |
53 | uint32_t i; |
Line 49... | Line 54... | ||
49 | 54 | ||
50 | cmd_orig = cmd = vmw_fifo_reserve(dev_priv, define_size + remap_size); |
55 | cmd_orig = cmd = vmw_fifo_reserve(dev_priv, cmd_size); |
Line -... | Line 56... | ||
- | 56 | if (unlikely(cmd == NULL)) |
|
- | 57 | return -ENOMEM; |
|
- | 58 | ||
- | 59 | define_cmd.gmrId = gmr_id; |
|
- | 60 | define_cmd.numPages = num_pages; |
|
- | 61 | ||
- | 62 | *cmd++ = SVGA_CMD_DEFINE_GMR2; |
|
- | 63 | memcpy(cmd, &define_cmd, sizeof(define_cmd)); |
|
- | 64 | cmd += sizeof(define_cmd) / sizeof(*cmd); |
|
51 | if (unlikely(cmd == NULL)) |
65 | |
52 | return -ENOMEM; |
66 | /* |
53 | 67 | * Need to split the command if there are too many |
|
54 | define_cmd.gmrId = gmr_id; |
- | |
55 | define_cmd.numPages = num_pages; |
- | |
Line 56... | Line 68... | ||
56 | 68 | * pages that goes into the gmr. |
|
- | 69 | */ |
|
- | 70 | ||
57 | remap_cmd.gmrId = gmr_id; |
71 | remap_cmd.gmrId = gmr_id; |
58 | remap_cmd.flags = (VMW_PPN_SIZE > sizeof(*cmd)) ? |
72 | remap_cmd.flags = (VMW_PPN_SIZE > sizeof(*cmd)) ? |
Line 59... | Line 73... | ||
59 | SVGA_REMAP_GMR2_PPN64 : SVGA_REMAP_GMR2_PPN32; |
73 | SVGA_REMAP_GMR2_PPN64 : SVGA_REMAP_GMR2_PPN32; |
60 | remap_cmd.offsetPages = 0; |
74 | |
61 | remap_cmd.numPages = num_pages; |
75 | while (num_pages > 0) { |
Line 62... | Line 76... | ||
62 | 76 | unsigned long nr = min(num_pages, (unsigned long)VMW_PPN_PER_REMAP); |
|
63 | *cmd++ = SVGA_CMD_DEFINE_GMR2; |
77 | |
64 | memcpy(cmd, &define_cmd, sizeof(define_cmd)); |
78 | remap_cmd.offsetPages = remap_pos; |
65 | cmd += sizeof(define_cmd) / sizeof(uint32); |
79 | remap_cmd.numPages = nr; |
66 | 80 | ||
Line 67... | Line 81... | ||
67 | *cmd++ = SVGA_CMD_REMAP_GMR2; |
81 | *cmd++ = SVGA_CMD_REMAP_GMR2; |
68 | memcpy(cmd, &remap_cmd, sizeof(remap_cmd)); |
82 | memcpy(cmd, &remap_cmd, sizeof(remap_cmd)); |
Line -... | Line 83... | ||
- | 83 | cmd += sizeof(remap_cmd) / sizeof(*cmd); |
|
- | 84 | ||
- | 85 | for (i = 0; i < nr; ++i) { |
|
- | 86 | if (VMW_PPN_SIZE <= 4) |
|
- | 87 | *cmd = page_to_pfn(*pages++); |
|
- | 88 | else |
|
69 | cmd += sizeof(remap_cmd) / sizeof(uint32); |
89 | *((uint64_t *)cmd) = page_to_pfn(*pages++); |
Line 70... | Line 90... | ||
70 | 90 | ||
71 | for (i = 0; i < num_pages; ++i) { |
91 | cmd += VMW_PPN_SIZE / sizeof(*cmd); |
Line 72... | Line 92... | ||
72 | if (VMW_PPN_SIZE <= 4) |
92 | } |