diff options
| -rw-r--r-- | drivers/gpu/drm/ttm/ttm_bo_util.c | 63 |
1 files changed, 52 insertions, 11 deletions
diff --git a/drivers/gpu/drm/ttm/ttm_bo_util.c b/drivers/gpu/drm/ttm/ttm_bo_util.c index 3e5d0c4ad85c..ce2e6f38ea01 100644 --- a/drivers/gpu/drm/ttm/ttm_bo_util.c +++ b/drivers/gpu/drm/ttm/ttm_bo_util.c | |||
| @@ -136,7 +136,8 @@ static int ttm_copy_io_page(void *dst, void *src, unsigned long page) | |||
| 136 | } | 136 | } |
| 137 | 137 | ||
| 138 | static int ttm_copy_io_ttm_page(struct ttm_tt *ttm, void *src, | 138 | static int ttm_copy_io_ttm_page(struct ttm_tt *ttm, void *src, |
| 139 | unsigned long page) | 139 | unsigned long page, |
| 140 | pgprot_t prot) | ||
| 140 | { | 141 | { |
| 141 | struct page *d = ttm_tt_get_page(ttm, page); | 142 | struct page *d = ttm_tt_get_page(ttm, page); |
| 142 | void *dst; | 143 | void *dst; |
| @@ -145,17 +146,35 @@ static int ttm_copy_io_ttm_page(struct ttm_tt *ttm, void *src, | |||
| 145 | return -ENOMEM; | 146 | return -ENOMEM; |
| 146 | 147 | ||
| 147 | src = (void *)((unsigned long)src + (page << PAGE_SHIFT)); | 148 | src = (void *)((unsigned long)src + (page << PAGE_SHIFT)); |
| 148 | dst = kmap(d); | 149 | |
| 150 | #ifdef CONFIG_X86 | ||
| 151 | dst = kmap_atomic_prot(d, KM_USER0, prot); | ||
| 152 | #else | ||
| 153 | if (prot != PAGE_KERNEL) | ||
| 154 | dst = vmap(&d, 1, 0, prot); | ||
| 155 | else | ||
| 156 | dst = kmap(d); | ||
| 157 | #endif | ||
| 149 | if (!dst) | 158 | if (!dst) |
| 150 | return -ENOMEM; | 159 | return -ENOMEM; |
| 151 | 160 | ||
| 152 | memcpy_fromio(dst, src, PAGE_SIZE); | 161 | memcpy_fromio(dst, src, PAGE_SIZE); |
| 153 | kunmap(d); | 162 | |
| 163 | #ifdef CONFIG_X86 | ||
| 164 | kunmap_atomic(dst, KM_USER0); | ||
| 165 | #else | ||
| 166 | if (prot != PAGE_KERNEL) | ||
| 167 | vunmap(dst); | ||
| 168 | else | ||
| 169 | kunmap(d); | ||
| 170 | #endif | ||
| 171 | |||
| 154 | return 0; | 172 | return 0; |
| 155 | } | 173 | } |
| 156 | 174 | ||
| 157 | static int ttm_copy_ttm_io_page(struct ttm_tt *ttm, void *dst, | 175 | static int ttm_copy_ttm_io_page(struct ttm_tt *ttm, void *dst, |
| 158 | unsigned long page) | 176 | unsigned long page, |
| 177 | pgprot_t prot) | ||
| 159 | { | 178 | { |
| 160 | struct page *s = ttm_tt_get_page(ttm, page); | 179 | struct page *s = ttm_tt_get_page(ttm, page); |
| 161 | void *src; | 180 | void *src; |
| @@ -164,12 +183,28 @@ static int ttm_copy_ttm_io_page(struct ttm_tt *ttm, void *dst, | |||
| 164 | return -ENOMEM; | 183 | return -ENOMEM; |
| 165 | 184 | ||
| 166 | dst = (void *)((unsigned long)dst + (page << PAGE_SHIFT)); | 185 | dst = (void *)((unsigned long)dst + (page << PAGE_SHIFT)); |
| 167 | src = kmap(s); | 186 | #ifdef CONFIG_X86 |
| 187 | src = kmap_atomic_prot(s, KM_USER0, prot); | ||
| 188 | #else | ||
| 189 | if (prot != PAGE_KERNEL) | ||
| 190 | src = vmap(&s, 1, 0, prot); | ||
| 191 | else | ||
| 192 | src = kmap(s); | ||
| 193 | #endif | ||
| 168 | if (!src) | 194 | if (!src) |
| 169 | return -ENOMEM; | 195 | return -ENOMEM; |
| 170 | 196 | ||
| 171 | memcpy_toio(dst, src, PAGE_SIZE); | 197 | memcpy_toio(dst, src, PAGE_SIZE); |
| 172 | kunmap(s); | 198 | |
| 199 | #ifdef CONFIG_X86 | ||
| 200 | kunmap_atomic(src, KM_USER0); | ||
| 201 | #else | ||
| 202 | if (prot != PAGE_KERNEL) | ||
| 203 | vunmap(src); | ||
| 204 | else | ||
| 205 | kunmap(s); | ||
| 206 | #endif | ||
| 207 | |||
| 173 | return 0; | 208 | return 0; |
| 174 | } | 209 | } |
| 175 | 210 | ||
| @@ -214,11 +249,17 @@ int ttm_bo_move_memcpy(struct ttm_buffer_object *bo, | |||
| 214 | 249 | ||
| 215 | for (i = 0; i < new_mem->num_pages; ++i) { | 250 | for (i = 0; i < new_mem->num_pages; ++i) { |
| 216 | page = i * dir + add; | 251 | page = i * dir + add; |
| 217 | if (old_iomap == NULL) | 252 | if (old_iomap == NULL) { |
| 218 | ret = ttm_copy_ttm_io_page(ttm, new_iomap, page); | 253 | pgprot_t prot = ttm_io_prot(old_mem->placement, |
| 219 | else if (new_iomap == NULL) | 254 | PAGE_KERNEL); |
| 220 | ret = ttm_copy_io_ttm_page(ttm, old_iomap, page); | 255 | ret = ttm_copy_ttm_io_page(ttm, new_iomap, page, |
| 221 | else | 256 | prot); |
| 257 | } else if (new_iomap == NULL) { | ||
| 258 | pgprot_t prot = ttm_io_prot(new_mem->placement, | ||
| 259 | PAGE_KERNEL); | ||
| 260 | ret = ttm_copy_io_ttm_page(ttm, old_iomap, page, | ||
| 261 | prot); | ||
| 262 | } else | ||
| 222 | ret = ttm_copy_io_page(new_iomap, old_iomap, page); | 263 | ret = ttm_copy_io_page(new_iomap, old_iomap, page); |
| 223 | if (ret) | 264 | if (ret) |
| 224 | goto out1; | 265 | goto out1; |
