| .. | .. |
|---|
| 53 | 53 | for (i = 0; i < pageCount; i++) { |
|---|
| 54 | 54 | vma = find_vma(current_mm, (Memory + i) << PAGE_SHIFT); |
|---|
| 55 | 55 | if (!vma) { |
|---|
| 56 | | - pr_err("failed to get vma\n"); |
|---|
| 56 | + pr_err("page[%d] failed to get vma\n", i); |
|---|
| 57 | 57 | ret = RGA_OUT_OF_RESOURCES; |
|---|
| 58 | 58 | break; |
|---|
| 59 | 59 | } |
|---|
| 60 | 60 | |
|---|
| 61 | 61 | pgd = pgd_offset(current_mm, (Memory + i) << PAGE_SHIFT); |
|---|
| 62 | 62 | if (pgd_none(*pgd) || unlikely(pgd_bad(*pgd))) { |
|---|
| 63 | | - pr_err("failed to get pgd\n"); |
|---|
| 63 | + pr_err("page[%d] failed to get pgd\n", i); |
|---|
| 64 | 64 | ret = RGA_OUT_OF_RESOURCES; |
|---|
| 65 | 65 | break; |
|---|
| 66 | 66 | } |
|---|
| .. | .. |
|---|
| 71 | 71 | */ |
|---|
| 72 | 72 | p4d = p4d_offset(pgd, (Memory + i) << PAGE_SHIFT); |
|---|
| 73 | 73 | if (p4d_none(*p4d) || unlikely(p4d_bad(*p4d))) { |
|---|
| 74 | | - pr_err("failed to get p4d\n"); |
|---|
| 74 | + pr_err("page[%d] failed to get p4d\n", i); |
|---|
| 75 | 75 | ret = RGA_OUT_OF_RESOURCES; |
|---|
| 76 | 76 | break; |
|---|
| 77 | 77 | } |
|---|
| .. | .. |
|---|
| 82 | 82 | #endif |
|---|
| 83 | 83 | |
|---|
| 84 | 84 | if (pud_none(*pud) || unlikely(pud_bad(*pud))) { |
|---|
| 85 | | - pr_err("failed to get pud\n"); |
|---|
| 85 | + pr_err("page[%d] failed to get pud\n", i); |
|---|
| 86 | 86 | ret = RGA_OUT_OF_RESOURCES; |
|---|
| 87 | 87 | break; |
|---|
| 88 | 88 | } |
|---|
| 89 | 89 | pmd = pmd_offset(pud, (Memory + i) << PAGE_SHIFT); |
|---|
| 90 | 90 | if (pmd_none(*pmd) || unlikely(pmd_bad(*pmd))) { |
|---|
| 91 | | - pr_err("failed to get pmd\n"); |
|---|
| 91 | + pr_err("page[%d] failed to get pmd\n", i); |
|---|
| 92 | 92 | ret = RGA_OUT_OF_RESOURCES; |
|---|
| 93 | 93 | break; |
|---|
| 94 | 94 | } |
|---|
| 95 | 95 | pte = pte_offset_map_lock(current_mm, pmd, |
|---|
| 96 | 96 | (Memory + i) << PAGE_SHIFT, &ptl); |
|---|
| 97 | 97 | if (pte_none(*pte)) { |
|---|
| 98 | | - pr_err("failed to get pte\n"); |
|---|
| 98 | + pr_err("page[%d] failed to get pte\n", i); |
|---|
| 99 | 99 | pte_unmap_unlock(pte, ptl); |
|---|
| 100 | 100 | ret = RGA_OUT_OF_RESOURCES; |
|---|
| 101 | 101 | break; |
|---|
| .. | .. |
|---|
| 105 | 105 | pages[i] = pfn_to_page(pfn); |
|---|
| 106 | 106 | pte_unmap_unlock(pte, ptl); |
|---|
| 107 | 107 | } |
|---|
| 108 | + |
|---|
| 109 | + if (ret == RGA_OUT_OF_RESOURCES && i > 0) |
|---|
| 110 | + pr_err("Only get buffer %d byte from vma, but current image required %d byte", |
|---|
| 111 | + (int)(i * PAGE_SIZE), (int)(pageCount * PAGE_SIZE)); |
|---|
| 108 | 112 | |
|---|
| 109 | 113 | return ret; |
|---|
| 110 | 114 | } |
|---|
| .. | .. |
|---|
| 144 | 148 | put_page(pages[i]); |
|---|
| 145 | 149 | |
|---|
| 146 | 150 | ret = rga_get_user_pages_from_vma(pages, Memory, pageCount, current_mm); |
|---|
| 147 | | - if (ret < 0) { |
|---|
| 148 | | - pr_err("Can not get user pages from vma, result = %d, pagecount = %d\n", |
|---|
| 149 | | - result, pageCount); |
|---|
| 151 | + if (ret < 0 && result > 0) { |
|---|
| 152 | + pr_err("Only get buffer %d byte from user pages, but current image required %d byte\n", |
|---|
| 153 | + (int)(result * PAGE_SIZE), (int)(pageCount * PAGE_SIZE)); |
|---|
| 150 | 154 | } |
|---|
| 151 | 155 | } |
|---|
| 152 | 156 | |
|---|
| .. | .. |
|---|
| 177 | 181 | } |
|---|
| 178 | 182 | |
|---|
| 179 | 183 | /* get sg form pages. */ |
|---|
| 180 | | - ret = sg_alloc_table_from_pages(sgt, virt_addr->pages, |
|---|
| 184 | + /* iova requires minimum page alignment, so sgt cannot have offset */ |
|---|
| 185 | + ret = sg_alloc_table_from_pages(sgt, |
|---|
| 186 | + virt_addr->pages, |
|---|
| 181 | 187 | virt_addr->page_count, |
|---|
| 182 | | - 0, virt_addr->size, |
|---|
| 188 | + 0, |
|---|
| 189 | + virt_addr->size, |
|---|
| 183 | 190 | GFP_KERNEL); |
|---|
| 184 | 191 | if (ret) { |
|---|
| 185 | 192 | pr_err("sg_alloc_table_from_pages failed"); |
|---|
| .. | .. |
|---|
| 245 | 252 | if (!size) { |
|---|
| 246 | 253 | pr_err("failed to calculating buffer size! size = %ld, count = %d, offset = %ld\n", |
|---|
| 247 | 254 | size, count, (unsigned long)offset); |
|---|
| 255 | + rga_dump_memory_parm(memory_parm); |
|---|
| 248 | 256 | return -EFAULT; |
|---|
| 249 | 257 | } |
|---|
| 250 | 258 | |
|---|
| 251 | 259 | /* alloc pages and page_table */ |
|---|
| 252 | 260 | order = get_order(count * sizeof(struct page *)); |
|---|
| 261 | + if (order >= MAX_ORDER) { |
|---|
| 262 | + pr_err("Can not alloc pages with order[%d] for viraddr pages, max_order = %d\n", |
|---|
| 263 | + order, MAX_ORDER); |
|---|
| 264 | + return -ENOMEM; |
|---|
| 265 | + } |
|---|
| 266 | + |
|---|
| 253 | 267 | pages = (struct page **)__get_free_pages(GFP_KERNEL, order); |
|---|
| 254 | 268 | if (pages == NULL) { |
|---|
| 255 | | - pr_err("%s can not alloc pages for pages\n", __func__); |
|---|
| 269 | + pr_err("%s can not alloc pages for viraddr pages\n", __func__); |
|---|
| 256 | 270 | return -ENOMEM; |
|---|
| 257 | 271 | } |
|---|
| 258 | 272 | |
|---|
| 259 | 273 | /* get pages from virtual address. */ |
|---|
| 260 | 274 | ret = rga_get_user_pages(pages, viraddr >> PAGE_SHIFT, count, writeFlag, mm); |
|---|
| 261 | 275 | if (ret < 0) { |
|---|
| 262 | | - pr_err("failed to get pages"); |
|---|
| 276 | + pr_err("failed to get pages from virtual adrees: 0x%lx\n", |
|---|
| 277 | + (unsigned long)viraddr); |
|---|
| 263 | 278 | ret = -EINVAL; |
|---|
| 264 | 279 | goto out_free_pages; |
|---|
| 265 | 280 | } else if (ret > 0) { |
|---|
| .. | .. |
|---|
| 301 | 316 | |
|---|
| 302 | 317 | if (scheduler->data->mmu == RGA_MMU && |
|---|
| 303 | 318 | !(mm_flag & RGA_MEM_UNDER_4G)) { |
|---|
| 304 | | - pr_err("%s unsupported Memory larger than 4G!\n", |
|---|
| 319 | + pr_err("%s unsupported memory larger than 4G!\n", |
|---|
| 305 | 320 | rga_get_mmu_type_str(scheduler->data->mmu)); |
|---|
| 306 | 321 | return false; |
|---|
| 307 | 322 | } |
|---|
| .. | .. |
|---|
| 358 | 373 | struct rga_job *job) |
|---|
| 359 | 374 | { |
|---|
| 360 | 375 | int ret; |
|---|
| 376 | + int ex_buffer_size; |
|---|
| 361 | 377 | uint32_t mm_flag = 0; |
|---|
| 362 | 378 | phys_addr_t phys_addr = 0; |
|---|
| 363 | 379 | struct rga_dma_buffer *buffer; |
|---|
| .. | .. |
|---|
| 369 | 385 | if (scheduler == NULL) { |
|---|
| 370 | 386 | pr_err("Invalid scheduler device!\n"); |
|---|
| 371 | 387 | return -EINVAL; |
|---|
| 388 | + } |
|---|
| 389 | + |
|---|
| 390 | + if (external_buffer->memory_parm.size) |
|---|
| 391 | + ex_buffer_size = external_buffer->memory_parm.size; |
|---|
| 392 | + else |
|---|
| 393 | + ex_buffer_size = rga_image_size_cal(external_buffer->memory_parm.width, |
|---|
| 394 | + external_buffer->memory_parm.height, |
|---|
| 395 | + external_buffer->memory_parm.format, |
|---|
| 396 | + NULL, NULL, NULL); |
|---|
| 397 | + if (ex_buffer_size <= 0) { |
|---|
| 398 | + pr_err("failed to calculating buffer size!\n"); |
|---|
| 399 | + rga_dump_memory_parm(&external_buffer->memory_parm); |
|---|
| 400 | + return ex_buffer_size == 0 ? -EINVAL : ex_buffer_size; |
|---|
| 372 | 401 | } |
|---|
| 373 | 402 | |
|---|
| 374 | 403 | /* |
|---|
| .. | .. |
|---|
| 402 | 431 | pr_err("%s core[%d] map dma buffer error!\n", |
|---|
| 403 | 432 | __func__, scheduler->core); |
|---|
| 404 | 433 | goto free_buffer; |
|---|
| 434 | + } |
|---|
| 435 | + |
|---|
| 436 | + if (buffer->size < ex_buffer_size) { |
|---|
| 437 | + pr_err("Only get buffer %ld byte from %s = 0x%lx, but current image required %d byte\n", |
|---|
| 438 | + buffer->size, rga_get_memory_type_str(external_buffer->type), |
|---|
| 439 | + (unsigned long)external_buffer->memory, ex_buffer_size); |
|---|
| 440 | + rga_dump_memory_parm(&external_buffer->memory_parm); |
|---|
| 441 | + ret = -EINVAL; |
|---|
| 442 | + goto unmap_buffer; |
|---|
| 405 | 443 | } |
|---|
| 406 | 444 | |
|---|
| 407 | 445 | buffer->scheduler = scheduler; |
|---|
| .. | .. |
|---|
| 539 | 577 | mm_flag |= RGA_MEM_PHYSICAL_CONTIGUOUS; |
|---|
| 540 | 578 | } |
|---|
| 541 | 579 | |
|---|
| 580 | + /* |
|---|
| 581 | + * Some userspace virtual addresses do not have an |
|---|
| 582 | + * interface for flushing the cache, so it is mandatory |
|---|
| 583 | + * to flush the cache when the virtual address is used. |
|---|
| 584 | + */ |
|---|
| 585 | + mm_flag |= RGA_MEM_FORCE_FLUSH_CACHE; |
|---|
| 586 | + |
|---|
| 542 | 587 | if (!rga_mm_check_memory_limit(scheduler, mm_flag)) { |
|---|
| 543 | 588 | pr_err("scheduler core[%d] unsupported mm_flag[0x%x]!\n", |
|---|
| 544 | 589 | scheduler->core, mm_flag); |
|---|
| .. | .. |
|---|
| 576 | 621 | if (mm_flag & RGA_MEM_PHYSICAL_CONTIGUOUS) |
|---|
| 577 | 622 | break; |
|---|
| 578 | 623 | |
|---|
| 579 | | - pr_err("Current RGA mmu[%d] cannot support virtual address!\n", |
|---|
| 580 | | - scheduler->data->mmu); |
|---|
| 624 | + pr_err("Current %s[%d] cannot support virtual address!\n", |
|---|
| 625 | + rga_get_mmu_type_str(scheduler->data->mmu), scheduler->data->mmu); |
|---|
| 581 | 626 | goto free_dma_buffer; |
|---|
| 582 | 627 | } |
|---|
| 583 | 628 | |
|---|
| .. | .. |
|---|
| 589 | 634 | internal_buffer->virt_addr = virt_addr; |
|---|
| 590 | 635 | internal_buffer->dma_buffer = buffer; |
|---|
| 591 | 636 | internal_buffer->mm_flag = mm_flag; |
|---|
| 592 | | - internal_buffer->phys_addr = phys_addr ? phys_addr : 0; |
|---|
| 637 | + internal_buffer->phys_addr = phys_addr ? phys_addr + virt_addr->offset : 0; |
|---|
| 593 | 638 | |
|---|
| 594 | 639 | return 0; |
|---|
| 595 | 640 | |
|---|
| .. | .. |
|---|
| 649 | 694 | internal_buffer->memory_parm.format, |
|---|
| 650 | 695 | NULL, NULL, NULL); |
|---|
| 651 | 696 | if (buffer_size <= 0) { |
|---|
| 652 | | - pr_err("Fault to get phys addr size!\n"); |
|---|
| 697 | + pr_err("Failed to get phys addr size!\n"); |
|---|
| 698 | + rga_dump_memory_parm(&internal_buffer->memory_parm); |
|---|
| 653 | 699 | return buffer_size == 0 ? -EINVAL : buffer_size; |
|---|
| 654 | 700 | } |
|---|
| 655 | 701 | |
|---|
| .. | .. |
|---|
| 674 | 720 | ret = rga_iommu_map(phys_addr, buffer_size, buffer, scheduler->dev); |
|---|
| 675 | 721 | if (ret < 0) { |
|---|
| 676 | 722 | pr_err("%s core[%d] map phys_addr error!\n", __func__, scheduler->core); |
|---|
| 677 | | - return ret; |
|---|
| 723 | + goto free_dma_buffer; |
|---|
| 678 | 724 | } |
|---|
| 679 | 725 | } |
|---|
| 680 | 726 | |
|---|
| .. | .. |
|---|
| 686 | 732 | internal_buffer->dma_buffer = buffer; |
|---|
| 687 | 733 | |
|---|
| 688 | 734 | return 0; |
|---|
| 735 | + |
|---|
| 736 | +free_dma_buffer: |
|---|
| 737 | + kfree(buffer); |
|---|
| 738 | + |
|---|
| 739 | + return ret; |
|---|
| 689 | 740 | } |
|---|
| 690 | 741 | |
|---|
| 691 | 742 | static int rga_mm_unmap_buffer(struct rga_internal_buffer *internal_buffer) |
|---|
| .. | .. |
|---|
| 738 | 789 | |
|---|
| 739 | 790 | ret = rga_mm_map_virt_addr(external_buffer, internal_buffer, job, write_flag); |
|---|
| 740 | 791 | if (ret < 0) { |
|---|
| 741 | | - pr_err("%s iommu_map virtual address error!\n", __func__); |
|---|
| 792 | + pr_err("%s map virtual address error!\n", __func__); |
|---|
| 742 | 793 | return ret; |
|---|
| 743 | 794 | } |
|---|
| 744 | 795 | |
|---|
| .. | .. |
|---|
| 751 | 802 | |
|---|
| 752 | 803 | ret = rga_mm_map_phys_addr(external_buffer, internal_buffer, job); |
|---|
| 753 | 804 | if (ret < 0) { |
|---|
| 754 | | - pr_err("%s iommu_map physical address error!\n", __func__); |
|---|
| 805 | + pr_err("%s map physical address error!\n", __func__); |
|---|
| 755 | 806 | return ret; |
|---|
| 756 | 807 | } |
|---|
| 757 | 808 | |
|---|
| .. | .. |
|---|
| 1130 | 1181 | |
|---|
| 1131 | 1182 | if (job->flags & RGA_JOB_USE_HANDLE) { |
|---|
| 1132 | 1183 | order = get_order(page_count * sizeof(uint32_t *)); |
|---|
| 1184 | + if (order >= MAX_ORDER) { |
|---|
| 1185 | + pr_err("Can not alloc pages with order[%d] for page_table, max_order = %d\n", |
|---|
| 1186 | + order, MAX_ORDER); |
|---|
| 1187 | + return -ENOMEM; |
|---|
| 1188 | + } |
|---|
| 1189 | + |
|---|
| 1133 | 1190 | page_table = (uint32_t *)__get_free_pages(GFP_KERNEL | GFP_DMA32, order); |
|---|
| 1134 | 1191 | if (page_table == NULL) { |
|---|
| 1135 | | - pr_err("%s can not alloc pages for pages, order = %d\n", |
|---|
| 1192 | + pr_err("%s can not alloc pages for page_table, order = %d\n", |
|---|
| 1136 | 1193 | __func__, order); |
|---|
| 1137 | 1194 | return -ENOMEM; |
|---|
| 1138 | 1195 | } |
|---|
| .. | .. |
|---|
| 1189 | 1246 | |
|---|
| 1190 | 1247 | if (job->flags & RGA_JOB_USE_HANDLE) { |
|---|
| 1191 | 1248 | order = get_order(page_count * sizeof(uint32_t *)); |
|---|
| 1249 | + if (order >= MAX_ORDER) { |
|---|
| 1250 | + pr_err("Can not alloc pages with order[%d] for page_table, max_order = %d\n", |
|---|
| 1251 | + order, MAX_ORDER); |
|---|
| 1252 | + return -ENOMEM; |
|---|
| 1253 | + } |
|---|
| 1254 | + |
|---|
| 1192 | 1255 | page_table = (uint32_t *)__get_free_pages(GFP_KERNEL | GFP_DMA32, order); |
|---|
| 1193 | 1256 | if (page_table == NULL) { |
|---|
| 1194 | | - pr_err("%s can not alloc pages for pages, order = %d\n", |
|---|
| 1257 | + pr_err("%s can not alloc pages for page_table, order = %d\n", |
|---|
| 1195 | 1258 | __func__, order); |
|---|
| 1196 | 1259 | return -ENOMEM; |
|---|
| 1197 | 1260 | } |
|---|
| .. | .. |
|---|
| 1239 | 1302 | struct sg_table *sgt; |
|---|
| 1240 | 1303 | struct rga_scheduler_t *scheduler; |
|---|
| 1241 | 1304 | |
|---|
| 1242 | | - sgt = rga_mm_lookup_sgt(buffer); |
|---|
| 1243 | | - if (sgt == NULL) { |
|---|
| 1244 | | - pr_err("%s(%d), failed to get sgt, core = 0x%x\n", |
|---|
| 1245 | | - __func__, __LINE__, job->core); |
|---|
| 1246 | | - return -EINVAL; |
|---|
| 1247 | | - } |
|---|
| 1248 | | - |
|---|
| 1249 | 1305 | scheduler = buffer->dma_buffer->scheduler; |
|---|
| 1250 | 1306 | if (scheduler == NULL) { |
|---|
| 1251 | 1307 | pr_err("%s(%d), failed to get scheduler, core = 0x%x\n", |
|---|
| .. | .. |
|---|
| 1253 | 1309 | return -EFAULT; |
|---|
| 1254 | 1310 | } |
|---|
| 1255 | 1311 | |
|---|
| 1256 | | - dma_sync_sg_for_device(scheduler->dev, sgt->sgl, sgt->orig_nents, dir); |
|---|
| 1312 | + if (buffer->mm_flag & RGA_MEM_PHYSICAL_CONTIGUOUS) { |
|---|
| 1313 | + dma_sync_single_for_device(scheduler->dev, buffer->phys_addr, buffer->size, dir); |
|---|
| 1314 | + } else { |
|---|
| 1315 | + sgt = rga_mm_lookup_sgt(buffer); |
|---|
| 1316 | + if (sgt == NULL) { |
|---|
| 1317 | + pr_err("%s(%d), failed to get sgt, core = 0x%x\n", |
|---|
| 1318 | + __func__, __LINE__, job->core); |
|---|
| 1319 | + return -EINVAL; |
|---|
| 1320 | + } |
|---|
| 1321 | + |
|---|
| 1322 | + dma_sync_sg_for_device(scheduler->dev, sgt->sgl, sgt->orig_nents, dir); |
|---|
| 1323 | + } |
|---|
| 1257 | 1324 | |
|---|
| 1258 | 1325 | return 0; |
|---|
| 1259 | 1326 | } |
|---|
| .. | .. |
|---|
| 1265 | 1332 | struct sg_table *sgt; |
|---|
| 1266 | 1333 | struct rga_scheduler_t *scheduler; |
|---|
| 1267 | 1334 | |
|---|
| 1268 | | - sgt = rga_mm_lookup_sgt(buffer); |
|---|
| 1269 | | - if (sgt == NULL) { |
|---|
| 1270 | | - pr_err("%s(%d), failed to get sgt, core = 0x%x\n", |
|---|
| 1271 | | - __func__, __LINE__, job->core); |
|---|
| 1272 | | - return -EINVAL; |
|---|
| 1273 | | - } |
|---|
| 1274 | | - |
|---|
| 1275 | 1335 | scheduler = buffer->dma_buffer->scheduler; |
|---|
| 1276 | 1336 | if (scheduler == NULL) { |
|---|
| 1277 | 1337 | pr_err("%s(%d), failed to get scheduler, core = 0x%x\n", |
|---|
| .. | .. |
|---|
| 1279 | 1339 | return -EFAULT; |
|---|
| 1280 | 1340 | } |
|---|
| 1281 | 1341 | |
|---|
| 1282 | | - dma_sync_sg_for_cpu(scheduler->dev, sgt->sgl, sgt->orig_nents, dir); |
|---|
| 1342 | + if (buffer->mm_flag & RGA_MEM_PHYSICAL_CONTIGUOUS) { |
|---|
| 1343 | + dma_sync_single_for_cpu(scheduler->dev, buffer->phys_addr, buffer->size, dir); |
|---|
| 1344 | + } else { |
|---|
| 1345 | + sgt = rga_mm_lookup_sgt(buffer); |
|---|
| 1346 | + if (sgt == NULL) { |
|---|
| 1347 | + pr_err("%s(%d), failed to get sgt, core = 0x%x\n", |
|---|
| 1348 | + __func__, __LINE__, job->core); |
|---|
| 1349 | + return -EINVAL; |
|---|
| 1350 | + } |
|---|
| 1351 | + |
|---|
| 1352 | + dma_sync_sg_for_cpu(scheduler->dev, sgt->sgl, sgt->orig_nents, dir); |
|---|
| 1353 | + } |
|---|
| 1283 | 1354 | |
|---|
| 1284 | 1355 | return 0; |
|---|
| 1285 | 1356 | } |
|---|
| .. | .. |
|---|
| 1334 | 1405 | uint64_t handle, |
|---|
| 1335 | 1406 | uint64_t *channel_addr, |
|---|
| 1336 | 1407 | struct rga_internal_buffer **buf, |
|---|
| 1408 | + int require_size, |
|---|
| 1337 | 1409 | enum dma_data_direction dir) |
|---|
| 1338 | 1410 | { |
|---|
| 1339 | 1411 | int ret = 0; |
|---|
| .. | .. |
|---|
| 1369 | 1441 | return ret; |
|---|
| 1370 | 1442 | } |
|---|
| 1371 | 1443 | |
|---|
| 1372 | | - if (internal_buffer->type == RGA_VIRTUAL_ADDRESS) { |
|---|
| 1444 | + if (internal_buffer->size < require_size) { |
|---|
| 1445 | + ret = -EINVAL; |
|---|
| 1446 | + pr_err("Only get buffer %ld byte from handle[%ld], but current required %d byte\n", |
|---|
| 1447 | + internal_buffer->size, (unsigned long)handle, require_size); |
|---|
| 1448 | + |
|---|
| 1449 | + goto put_internal_buffer; |
|---|
| 1450 | + } |
|---|
| 1451 | + |
|---|
| 1452 | + if (internal_buffer->mm_flag & RGA_MEM_FORCE_FLUSH_CACHE) { |
|---|
| 1373 | 1453 | /* |
|---|
| 1374 | 1454 | * Some userspace virtual addresses do not have an |
|---|
| 1375 | 1455 | * interface for flushing the cache, so it is mandatory |
|---|
| .. | .. |
|---|
| 1378 | 1458 | ret = rga_mm_sync_dma_sg_for_device(internal_buffer, job, dir); |
|---|
| 1379 | 1459 | if (ret < 0) { |
|---|
| 1380 | 1460 | pr_err("sync sgt for device error!\n"); |
|---|
| 1381 | | - return ret; |
|---|
| 1461 | + goto put_internal_buffer; |
|---|
| 1382 | 1462 | } |
|---|
| 1383 | 1463 | } |
|---|
| 1384 | 1464 | |
|---|
| 1385 | 1465 | return 0; |
|---|
| 1466 | + |
|---|
| 1467 | +put_internal_buffer: |
|---|
| 1468 | + mutex_lock(&mm->lock); |
|---|
| 1469 | + kref_put(&internal_buffer->refcount, rga_mm_kref_release_buffer); |
|---|
| 1470 | + mutex_unlock(&mm->lock); |
|---|
| 1471 | + |
|---|
| 1472 | + return ret; |
|---|
| 1473 | + |
|---|
| 1386 | 1474 | } |
|---|
| 1387 | 1475 | |
|---|
| 1388 | 1476 | static void rga_mm_put_buffer(struct rga_mm *mm, |
|---|
| .. | .. |
|---|
| 1390 | 1478 | struct rga_internal_buffer *internal_buffer, |
|---|
| 1391 | 1479 | enum dma_data_direction dir) |
|---|
| 1392 | 1480 | { |
|---|
| 1393 | | - if (internal_buffer->type == RGA_VIRTUAL_ADDRESS && dir != DMA_NONE) |
|---|
| 1481 | + if (internal_buffer->mm_flag & RGA_MEM_FORCE_FLUSH_CACHE && dir != DMA_NONE) |
|---|
| 1394 | 1482 | if (rga_mm_sync_dma_sg_for_cpu(internal_buffer, job, dir)) |
|---|
| 1395 | 1483 | pr_err("sync sgt for cpu error!\n"); |
|---|
| 1396 | 1484 | |
|---|
| 1397 | 1485 | mutex_lock(&mm->lock); |
|---|
| 1398 | 1486 | kref_put(&internal_buffer->refcount, rga_mm_kref_release_buffer); |
|---|
| 1399 | 1487 | mutex_unlock(&mm->lock); |
|---|
| 1400 | | -} |
|---|
| 1401 | | - |
|---|
| 1402 | | -static int rga_mm_get_channel_handle_info(struct rga_mm *mm, |
|---|
| 1403 | | - struct rga_job *job, |
|---|
| 1404 | | - struct rga_img_info_t *img, |
|---|
| 1405 | | - struct rga_job_buffer *job_buf, |
|---|
| 1406 | | - enum dma_data_direction dir) |
|---|
| 1407 | | -{ |
|---|
| 1408 | | - int ret = 0; |
|---|
| 1409 | | - int handle = 0; |
|---|
| 1410 | | - |
|---|
| 1411 | | - /* using third-address */ |
|---|
| 1412 | | - if (img->uv_addr > 0) { |
|---|
| 1413 | | - handle = img->yrgb_addr; |
|---|
| 1414 | | - if (handle > 0) { |
|---|
| 1415 | | - ret = rga_mm_get_buffer(mm, job, handle, &img->yrgb_addr, |
|---|
| 1416 | | - &job_buf->y_addr, dir); |
|---|
| 1417 | | - if (ret < 0) { |
|---|
| 1418 | | - pr_err("handle[%d] Can't get src y/rgb address info!\n", handle); |
|---|
| 1419 | | - return ret; |
|---|
| 1420 | | - } |
|---|
| 1421 | | - } |
|---|
| 1422 | | - |
|---|
| 1423 | | - handle = img->uv_addr; |
|---|
| 1424 | | - if (handle > 0) { |
|---|
| 1425 | | - ret = rga_mm_get_buffer(mm, job, handle, &img->uv_addr, |
|---|
| 1426 | | - &job_buf->uv_addr, dir); |
|---|
| 1427 | | - if (ret < 0) { |
|---|
| 1428 | | - pr_err("handle[%d] Can't get src uv address info!\n", handle); |
|---|
| 1429 | | - return ret; |
|---|
| 1430 | | - } |
|---|
| 1431 | | - } |
|---|
| 1432 | | - |
|---|
| 1433 | | - handle = img->v_addr; |
|---|
| 1434 | | - if (handle > 0) { |
|---|
| 1435 | | - ret = rga_mm_get_buffer(mm, job, handle, &img->v_addr, |
|---|
| 1436 | | - &job_buf->v_addr, dir); |
|---|
| 1437 | | - if (ret < 0) { |
|---|
| 1438 | | - pr_err("handle[%d] Can't get src uv address info!\n", handle); |
|---|
| 1439 | | - return ret; |
|---|
| 1440 | | - } |
|---|
| 1441 | | - } |
|---|
| 1442 | | - } else { |
|---|
| 1443 | | - handle = img->yrgb_addr; |
|---|
| 1444 | | - if (handle > 0) { |
|---|
| 1445 | | - ret = rga_mm_get_buffer(mm, job, handle, &img->yrgb_addr, |
|---|
| 1446 | | - &job_buf->addr, dir); |
|---|
| 1447 | | - if (ret < 0) { |
|---|
| 1448 | | - pr_err("handle[%d] Can't get src y/rgb address info!\n", handle); |
|---|
| 1449 | | - return ret; |
|---|
| 1450 | | - } |
|---|
| 1451 | | - } |
|---|
| 1452 | | - |
|---|
| 1453 | | - rga_convert_addr(img, false); |
|---|
| 1454 | | - } |
|---|
| 1455 | | - |
|---|
| 1456 | | - if (job->scheduler->data->mmu == RGA_MMU && |
|---|
| 1457 | | - rga_mm_is_need_mmu(job, job_buf->addr)) { |
|---|
| 1458 | | - ret = rga_mm_set_mmu_base(job, img, job_buf); |
|---|
| 1459 | | - if (ret < 0) { |
|---|
| 1460 | | - pr_err("Can't set RGA2 MMU_BASE from handle!\n"); |
|---|
| 1461 | | - return ret; |
|---|
| 1462 | | - } |
|---|
| 1463 | | - } |
|---|
| 1464 | | - |
|---|
| 1465 | | - return 0; |
|---|
| 1466 | 1488 | } |
|---|
| 1467 | 1489 | |
|---|
| 1468 | 1490 | static void rga_mm_put_channel_handle_info(struct rga_mm *mm, |
|---|
| .. | .. |
|---|
| 1481 | 1503 | free_pages((unsigned long)job_buf->page_table, job_buf->order); |
|---|
| 1482 | 1504 | } |
|---|
| 1483 | 1505 | |
|---|
| 1506 | +static int rga_mm_get_channel_handle_info(struct rga_mm *mm, |
|---|
| 1507 | + struct rga_job *job, |
|---|
| 1508 | + struct rga_img_info_t *img, |
|---|
| 1509 | + struct rga_job_buffer *job_buf, |
|---|
| 1510 | + enum dma_data_direction dir) |
|---|
| 1511 | +{ |
|---|
| 1512 | + int ret = 0; |
|---|
| 1513 | + int handle = 0; |
|---|
| 1514 | + int img_size, yrgb_size, uv_size, v_size; |
|---|
| 1515 | + |
|---|
| 1516 | + img_size = rga_image_size_cal(img->vir_w, img->vir_h, img->format, |
|---|
| 1517 | + &yrgb_size, &uv_size, &v_size); |
|---|
| 1518 | + if (img_size <= 0) { |
|---|
| 1519 | + pr_err("Image size cal error! width = %d, height = %d, format = %s\n", |
|---|
| 1520 | + img->vir_w, img->vir_h, rga_get_format_name(img->format)); |
|---|
| 1521 | + return -EINVAL; |
|---|
| 1522 | + } |
|---|
| 1523 | + |
|---|
| 1524 | + /* using third-address */ |
|---|
| 1525 | + if (img->uv_addr > 0) { |
|---|
| 1526 | + handle = img->yrgb_addr; |
|---|
| 1527 | + if (handle > 0) { |
|---|
| 1528 | + ret = rga_mm_get_buffer(mm, job, handle, &img->yrgb_addr, |
|---|
| 1529 | + &job_buf->y_addr, yrgb_size, dir); |
|---|
| 1530 | + if (ret < 0) { |
|---|
| 1531 | + pr_err("handle[%d] Can't get y/rgb address info!\n", handle); |
|---|
| 1532 | + return ret; |
|---|
| 1533 | + } |
|---|
| 1534 | + } |
|---|
| 1535 | + |
|---|
| 1536 | + handle = img->uv_addr; |
|---|
| 1537 | + if (handle > 0) { |
|---|
| 1538 | + ret = rga_mm_get_buffer(mm, job, handle, &img->uv_addr, |
|---|
| 1539 | + &job_buf->uv_addr, uv_size, dir); |
|---|
| 1540 | + if (ret < 0) { |
|---|
| 1541 | + pr_err("handle[%d] Can't get uv address info!\n", handle); |
|---|
| 1542 | + return ret; |
|---|
| 1543 | + } |
|---|
| 1544 | + } |
|---|
| 1545 | + |
|---|
| 1546 | + handle = img->v_addr; |
|---|
| 1547 | + if (handle > 0) { |
|---|
| 1548 | + ret = rga_mm_get_buffer(mm, job, handle, &img->v_addr, |
|---|
| 1549 | + &job_buf->v_addr, v_size, dir); |
|---|
| 1550 | + if (ret < 0) { |
|---|
| 1551 | + pr_err("handle[%d] Can't get uv address info!\n", handle); |
|---|
| 1552 | + return ret; |
|---|
| 1553 | + } |
|---|
| 1554 | + } |
|---|
| 1555 | + } else { |
|---|
| 1556 | + handle = img->yrgb_addr; |
|---|
| 1557 | + if (handle > 0) { |
|---|
| 1558 | + ret = rga_mm_get_buffer(mm, job, handle, &img->yrgb_addr, |
|---|
| 1559 | + &job_buf->addr, img_size, dir); |
|---|
| 1560 | + if (ret < 0) { |
|---|
| 1561 | + pr_err("handle[%d] Can't get y/rgb address info!\n", handle); |
|---|
| 1562 | + return ret; |
|---|
| 1563 | + } |
|---|
| 1564 | + } |
|---|
| 1565 | + |
|---|
| 1566 | + rga_convert_addr(img, false); |
|---|
| 1567 | + } |
|---|
| 1568 | + |
|---|
| 1569 | + if (job->scheduler->data->mmu == RGA_MMU && |
|---|
| 1570 | + rga_mm_is_need_mmu(job, job_buf->addr)) { |
|---|
| 1571 | + ret = rga_mm_set_mmu_base(job, img, job_buf); |
|---|
| 1572 | + if (ret < 0) { |
|---|
| 1573 | + pr_err("Can't set RGA2 MMU_BASE from handle!\n"); |
|---|
| 1574 | + |
|---|
| 1575 | + rga_mm_put_channel_handle_info(mm, job, job_buf, dir); |
|---|
| 1576 | + return ret; |
|---|
| 1577 | + } |
|---|
| 1578 | + } |
|---|
| 1579 | + |
|---|
| 1580 | + return 0; |
|---|
| 1581 | +} |
|---|
| 1582 | + |
|---|
| 1484 | 1583 | static int rga_mm_get_handle_info(struct rga_job *job) |
|---|
| 1485 | 1584 | { |
|---|
| 1486 | 1585 | int ret = 0; |
|---|
| .. | .. |
|---|
| 1491 | 1590 | req = &job->rga_command_base; |
|---|
| 1492 | 1591 | mm = rga_drvdata->mm; |
|---|
| 1493 | 1592 | |
|---|
| 1593 | + switch (req->render_mode) { |
|---|
| 1594 | + case BITBLT_MODE: |
|---|
| 1595 | + case COLOR_PALETTE_MODE: |
|---|
| 1596 | + if (unlikely(req->src.yrgb_addr <= 0)) { |
|---|
| 1597 | + pr_err("render_mode[0x%x] src0 channel handle[%ld] must is valid!", |
|---|
| 1598 | + req->render_mode, (unsigned long)req->src.yrgb_addr); |
|---|
| 1599 | + return -EINVAL; |
|---|
| 1600 | + } |
|---|
| 1601 | + |
|---|
| 1602 | + if (unlikely(req->dst.yrgb_addr <= 0)) { |
|---|
| 1603 | + pr_err("render_mode[0x%x] dst channel handle[%ld] must is valid!", |
|---|
| 1604 | + req->render_mode, (unsigned long)req->dst.yrgb_addr); |
|---|
| 1605 | + return -EINVAL; |
|---|
| 1606 | + } |
|---|
| 1607 | + |
|---|
| 1608 | + if (req->bsfilter_flag) { |
|---|
| 1609 | + if (unlikely(req->pat.yrgb_addr <= 0)) { |
|---|
| 1610 | + pr_err("render_mode[0x%x] src1/pat channel handle[%ld] must is valid!", |
|---|
| 1611 | + req->render_mode, (unsigned long)req->pat.yrgb_addr); |
|---|
| 1612 | + return -EINVAL; |
|---|
| 1613 | + } |
|---|
| 1614 | + } |
|---|
| 1615 | + |
|---|
| 1616 | + break; |
|---|
| 1617 | + case COLOR_FILL_MODE: |
|---|
| 1618 | + if (unlikely(req->dst.yrgb_addr <= 0)) { |
|---|
| 1619 | + pr_err("render_mode[0x%x] dst channel handle[%ld] must is valid!", |
|---|
| 1620 | + req->render_mode, (unsigned long)req->dst.yrgb_addr); |
|---|
| 1621 | + return -EINVAL; |
|---|
| 1622 | + } |
|---|
| 1623 | + |
|---|
| 1624 | + break; |
|---|
| 1625 | + |
|---|
| 1626 | + case UPDATE_PALETTE_TABLE_MODE: |
|---|
| 1627 | + case UPDATE_PATTEN_BUF_MODE: |
|---|
| 1628 | + if (unlikely(req->pat.yrgb_addr <= 0)) { |
|---|
| 1629 | + pr_err("render_mode[0x%x] lut/pat channel handle[%ld] must is valid!, req->render_mode", |
|---|
| 1630 | + req->render_mode, (unsigned long)req->pat.yrgb_addr); |
|---|
| 1631 | + return -EINVAL; |
|---|
| 1632 | + } |
|---|
| 1633 | + |
|---|
| 1634 | + break; |
|---|
| 1635 | + default: |
|---|
| 1636 | + pr_err("%s, unknown render mode!\n", __func__); |
|---|
| 1637 | + break; |
|---|
| 1638 | + } |
|---|
| 1639 | + |
|---|
| 1494 | 1640 | if (likely(req->src.yrgb_addr > 0)) { |
|---|
| 1495 | 1641 | ret = rga_mm_get_channel_handle_info(mm, job, &req->src, |
|---|
| 1496 | 1642 | &job->src_buffer, |
|---|
| 1497 | 1643 | DMA_TO_DEVICE); |
|---|
| 1498 | 1644 | if (ret < 0) { |
|---|
| 1499 | | - pr_err("Can't get src buffer third info!\n"); |
|---|
| 1645 | + pr_err("Can't get src buffer info from handle!\n"); |
|---|
| 1500 | 1646 | return ret; |
|---|
| 1501 | 1647 | } |
|---|
| 1502 | 1648 | } |
|---|
| .. | .. |
|---|
| 1506 | 1652 | &job->dst_buffer, |
|---|
| 1507 | 1653 | DMA_TO_DEVICE); |
|---|
| 1508 | 1654 | if (ret < 0) { |
|---|
| 1509 | | - pr_err("Can't get dst buffer third info!\n"); |
|---|
| 1655 | + pr_err("Can't get dst buffer info from handle!\n"); |
|---|
| 1510 | 1656 | return ret; |
|---|
| 1511 | 1657 | } |
|---|
| 1512 | 1658 | } |
|---|
| .. | .. |
|---|
| 1528 | 1674 | DMA_BIDIRECTIONAL); |
|---|
| 1529 | 1675 | } |
|---|
| 1530 | 1676 | if (ret < 0) { |
|---|
| 1531 | | - pr_err("Can't get pat buffer third info!\n"); |
|---|
| 1677 | + pr_err("Can't get pat buffer info from handle!\n"); |
|---|
| 1532 | 1678 | return ret; |
|---|
| 1533 | 1679 | } |
|---|
| 1534 | 1680 | } |
|---|
| .. | .. |
|---|
| 1681 | 1827 | struct rga_job_buffer *job_buffer, |
|---|
| 1682 | 1828 | enum dma_data_direction dir) |
|---|
| 1683 | 1829 | { |
|---|
| 1684 | | - if (job_buffer->addr->type == RGA_VIRTUAL_ADDRESS && dir != DMA_NONE) |
|---|
| 1830 | + if (job_buffer->addr->mm_flag & RGA_MEM_FORCE_FLUSH_CACHE && dir != DMA_NONE) |
|---|
| 1685 | 1831 | if (rga_mm_sync_dma_sg_for_cpu(job_buffer->addr, job, dir)) |
|---|
| 1686 | 1832 | pr_err("sync sgt for cpu error!\n"); |
|---|
| 1687 | 1833 | |
|---|
| .. | .. |
|---|
| 1718 | 1864 | goto error_unmap_buffer; |
|---|
| 1719 | 1865 | } |
|---|
| 1720 | 1866 | |
|---|
| 1721 | | - if (buffer->type == RGA_VIRTUAL_ADDRESS) { |
|---|
| 1722 | | - /* |
|---|
| 1723 | | - * Some userspace virtual addresses do not have an |
|---|
| 1724 | | - * interface for flushing the cache, so it is mandatory |
|---|
| 1725 | | - * to flush the cache when the virtual address is used. |
|---|
| 1726 | | - */ |
|---|
| 1867 | + if (buffer->mm_flag & RGA_MEM_FORCE_FLUSH_CACHE) { |
|---|
| 1727 | 1868 | ret = rga_mm_sync_dma_sg_for_device(buffer, job, dir); |
|---|
| 1728 | 1869 | if (ret < 0) { |
|---|
| 1729 | 1870 | pr_err("sync sgt for device error!\n"); |
|---|
| .. | .. |
|---|
| 1869 | 2010 | uint32_t rga_mm_import_buffer(struct rga_external_buffer *external_buffer, |
|---|
| 1870 | 2011 | struct rga_session *session) |
|---|
| 1871 | 2012 | { |
|---|
| 1872 | | - int ret = 0; |
|---|
| 2013 | + int ret = 0, new_id; |
|---|
| 1873 | 2014 | struct rga_mm *mm; |
|---|
| 1874 | 2015 | struct rga_internal_buffer *internal_buffer; |
|---|
| 1875 | 2016 | |
|---|
| .. | .. |
|---|
| 1911 | 2052 | * allocation under our spinlock. |
|---|
| 1912 | 2053 | */ |
|---|
| 1913 | 2054 | idr_preload(GFP_KERNEL); |
|---|
| 1914 | | - internal_buffer->handle = idr_alloc(&mm->memory_idr, internal_buffer, 1, 0, GFP_KERNEL); |
|---|
| 2055 | + new_id = idr_alloc_cyclic(&mm->memory_idr, internal_buffer, 1, 0, GFP_NOWAIT); |
|---|
| 1915 | 2056 | idr_preload_end(); |
|---|
| 2057 | + if (new_id < 0) { |
|---|
| 2058 | + pr_err("internal_buffer alloc id failed!\n"); |
|---|
| 2059 | + goto FREE_INTERNAL_BUFFER; |
|---|
| 2060 | + } |
|---|
| 1916 | 2061 | |
|---|
| 2062 | + internal_buffer->handle = new_id; |
|---|
| 1917 | 2063 | mm->buffer_count++; |
|---|
| 1918 | 2064 | |
|---|
| 1919 | 2065 | if (DEBUGGER_EN(MM)) { |
|---|