media_modules: remap the highmem addr to prevent crash on the kernel 32bit [2/2]

PD#SWPL-1909

Problem:
mem rw exception caused crashed.

Solution:
1. add mapping the highmem address by the func vmap().
2. remove the flag CODEC_MM_FLAGS_CPU if not necessary.

Verify:
p212, w400

Change-Id: Id2904331098eef7245e9949619840dcb20d16b4b
Signed-off-by: Nanxin Qin <nanxin.qin@amlogic.com>
This commit is contained in:
Nanxin Qin
2018-10-31 14:07:00 +08:00
committed by Dongjin Kim
parent bcd96d9ce9
commit eba9cc8b79
10 changed files with 463 additions and 151 deletions

View File

@@ -5943,20 +5943,37 @@ static unsigned char get_data_check_sum
{
int jj;
int sum = 0;
u8 *data = ((u8 *)dec->chunk->block->start_virt) +
dec->chunk->offset;
u8 *data = NULL;
if (!dec->chunk->block->is_mapped)
data = codec_mm_vmap(dec->chunk->block->start +
dec->chunk->offset, size);
else
data = ((u8 *)dec->chunk->block->start_virt) +
dec->chunk->offset;
for (jj = 0; jj < size; jj++)
sum += data[jj];
if (!dec->chunk->block->is_mapped)
codec_mm_unmap_phyaddr(data);
return sum;
}
static void dump_data(struct AVS2Decoder_s *dec, int size)
{
int jj;
u8 *data = ((u8 *)dec->chunk->block->start_virt) +
dec->chunk->offset;
u8 *data = NULL;
int padding_size = dec->chunk->offset &
(VDEC_FIFO_ALIGN - 1);
if (!dec->chunk->block->is_mapped)
data = codec_mm_vmap(dec->chunk->block->start +
dec->chunk->offset, size);
else
data = ((u8 *)dec->chunk->block->start_virt) +
dec->chunk->offset;
avs2_print(dec, 0, "padding: ");
for (jj = padding_size; jj > 0; jj--)
avs2_print_cont(dec,
@@ -5981,6 +5998,9 @@ static void dump_data(struct AVS2Decoder_s *dec, int size)
avs2_print(dec,
0,
"\n");
if (!dec->chunk->block->is_mapped)
codec_mm_unmap_phyaddr(data);
}
static void avs2_work(struct work_struct *work)
@@ -6249,13 +6269,21 @@ static void run(struct vdec_s *vdec, unsigned long mask,
READ_VREG(HEVC_STREAM_RD_PTR),
dec->start_shift_bytes);
if (vdec_frame_based(vdec) && dec->chunk) {
u8 *data = ((u8 *)dec->chunk->block->start_virt) +
dec->chunk->offset;
u8 *data = NULL;
if (!dec->chunk->block->is_mapped)
data = codec_mm_vmap(dec->chunk->block->start +
dec->chunk->offset, 8);
else
data = ((u8 *)dec->chunk->block->start_virt) +
dec->chunk->offset;
avs2_print_cont(dec, 0, "data adr %p:",
data);
for (ii = 0; ii < 8; ii++)
avs2_print_cont(dec, 0, "%02x ",
data[ii]);
if (!dec->chunk->block->is_mapped)
codec_mm_unmap_phyaddr(data);
}
avs2_print_cont(dec, 0, "\r\n");
}
@@ -6451,9 +6479,13 @@ static void avs2_dump_state(struct vdec_s *vdec)
int jj;
if (dec->chunk && dec->chunk->block &&
dec->chunk->size > 0) {
u8 *data =
((u8 *)dec->chunk->block->start_virt) +
dec->chunk->offset;
u8 *data = NULL;
if (!dec->chunk->block->is_mapped)
data = codec_mm_vmap(dec->chunk->block->start +
dec->chunk->offset, dec->chunk->size);
else
data = ((u8 *)dec->chunk->block->start_virt) +
dec->chunk->offset;
avs2_print(dec, 0,
"frame data size 0x%x\n",
dec->chunk->size);
@@ -6467,6 +6499,9 @@ static void avs2_dump_state(struct vdec_s *vdec)
avs2_print_cont(dec, 0,
"\n");
}
if (!dec->chunk->block->is_mapped)
codec_mm_unmap_phyaddr(data);
}
}

View File

@@ -59,6 +59,7 @@
#include "../utils/config_parser.h"
#include "../../../amvdec_ports/vdec_drv_base.h"
#include "../../../common/chips/decoder_cpu_ver_info.h"
#include <linux/crc32.h>
#undef pr_info
#define pr_info printk
@@ -5113,9 +5114,15 @@ static void vmh264_dump_state(struct vdec_s *vdec)
int jj;
if (hw->chunk && hw->chunk->block &&
hw->chunk->size > 0) {
u8 *data =
((u8 *)hw->chunk->block->start_virt) +
hw->chunk->offset;
u8 *data = NULL;
if (!hw->chunk->block->is_mapped)
data = codec_mm_vmap(hw->chunk->block->start +
hw->chunk->offset, hw->chunk->size);
else
data = ((u8 *)hw->chunk->block->start_virt)
+ hw->chunk->offset;
dpb_print(DECODE_ID(hw), 0,
"frame data size 0x%x\n",
hw->chunk->size);
@@ -5132,6 +5139,9 @@ static void vmh264_dump_state(struct vdec_s *vdec)
PRINT_FRAMEBASE_DATA,
"\n");
}
if (!hw->chunk->block->is_mapped)
codec_mm_unmap_phyaddr(data);
}
}
}
@@ -6540,9 +6550,17 @@ static void vh264_work(struct work_struct *work)
if (dpb_is_debug(DECODE_ID(hw),
PRINT_FRAMEBASE_DATA)) {
int jj;
u8 *data =
((u8 *)hw->chunk->block->start_virt) +
hw->chunk->offset;
u8 *data = NULL;
if (!hw->chunk->block->is_mapped)
data = codec_mm_vmap(
hw->chunk->block->start +
hw->chunk->offset, r);
else
data = ((u8 *)
hw->chunk->block->start_virt)
+ hw->chunk->offset;
for (jj = 0; jj < r; jj++) {
if ((jj & 0xf) == 0)
dpb_print(DECODE_ID(hw),
@@ -6556,6 +6574,9 @@ static void vh264_work(struct work_struct *work)
PRINT_FRAMEBASE_DATA,
"\n");
}
if (!hw->chunk->block->is_mapped)
codec_mm_unmap_phyaddr(data);
}
WRITE_VREG(POWER_CTL_VLD,
READ_VREG(POWER_CTL_VLD) |
@@ -6755,10 +6776,20 @@ static unsigned char get_data_check_sum
{
int jj;
int sum = 0;
u8 *data = ((u8 *)hw->chunk->block->start_virt) +
hw->chunk->offset;
u8 *data = NULL;
if (!hw->chunk->block->is_mapped)
data = codec_mm_vmap(hw->chunk->block->start +
hw->chunk->offset, size);
else
data = ((u8 *)hw->chunk->block->start_virt)
+ hw->chunk->offset;
for (jj = 0; jj < size; jj++)
sum += data[jj];
if (!hw->chunk->block->is_mapped)
codec_mm_unmap_phyaddr(data);
return sum;
}
@@ -6831,8 +6862,15 @@ static void run(struct vdec_s *vdec, unsigned long mask,
#endif
if (input_frame_based(vdec)) {
u8 *data = ((u8 *)hw->chunk->block->start_virt) +
hw->chunk->offset;
u8 *data = NULL;
if (!hw->chunk->block->is_mapped)
data = codec_mm_vmap(hw->chunk->block->start +
hw->chunk->offset, size);
else
data = ((u8 *)hw->chunk->block->start_virt)
+ hw->chunk->offset;
if (dpb_is_debug(DECODE_ID(hw),
PRINT_FLAG_VDEC_STATUS)
) {
@@ -6848,9 +6886,7 @@ static void run(struct vdec_s *vdec, unsigned long mask,
PRINT_FRAMEBASE_DATA)
) {
int jj;
u8 *data =
((u8 *)hw->chunk->block->start_virt) +
hw->chunk->offset;
for (jj = 0; jj < size; jj++) {
if ((jj & 0xf) == 0)
dpb_print(DECODE_ID(hw),
@@ -6866,6 +6902,8 @@ static void run(struct vdec_s *vdec, unsigned long mask,
}
}
if (!hw->chunk->block->is_mapped)
codec_mm_unmap_phyaddr(data);
} else
dpb_print(DECODE_ID(hw), PRINT_FLAG_VDEC_STATUS,
"%s: %x %x %x %x %x size 0x%x\n",
@@ -6923,7 +6961,9 @@ static void run(struct vdec_s *vdec, unsigned long mask,
return;
}
if (input_frame_based(vdec)) {
int decode_size = hw->chunk->size +
int decode_size = 0;
decode_size = hw->chunk->size +
(hw->chunk->offset & (VDEC_FIFO_ALIGN - 1));
WRITE_VREG(H264_DECODE_INFO, (1<<13));
WRITE_VREG(H264_DECODE_SIZE, decode_size);
@@ -7361,6 +7401,18 @@ static int ammvdec_h264_probe(struct platform_device *pdev)
dma_sync_single_for_device(amports_get_dma_device(),
hw->cma_alloc_addr,
V_BUF_ADDR_OFFSET, DMA_TO_DEVICE);
} else {
tmpbuf = codec_mm_vmap(hw->cma_alloc_addr,
V_BUF_ADDR_OFFSET);
if (tmpbuf) {
memset(tmpbuf, 0, V_BUF_ADDR_OFFSET);
dma_sync_single_for_device(
amports_get_dma_device(),
hw->cma_alloc_addr,
V_BUF_ADDR_OFFSET,
DMA_TO_DEVICE);
codec_mm_unmap_phyaddr(tmpbuf);
}
}
#else
/*init sps/pps internal buf 64k*/

View File

@@ -9720,10 +9720,20 @@ static unsigned char get_data_check_sum
{
int jj;
int sum = 0;
u8 *data = ((u8 *)hevc->chunk->block->start_virt) +
hevc->chunk->offset;
u8 *data = NULL;
if (!hevc->chunk->block->is_mapped)
data = codec_mm_vmap(hevc->chunk->block->start +
hevc->chunk->offset, size);
else
data = ((u8 *)hevc->chunk->block->start_virt) +
hevc->chunk->offset;
for (jj = 0; jj < size; jj++)
sum += data[jj];
if (!hevc->chunk->block->is_mapped)
codec_mm_unmap_phyaddr(data);
return sum;
}
@@ -9878,9 +9888,17 @@ static void vh265_work(struct work_struct *work)
if (get_dbg_flag(hevc) & PRINT_FRAMEBASE_DATA) {
int jj;
u8 *data =
((u8 *)hevc->chunk->block->start_virt) +
hevc->chunk->offset;
u8 *data = NULL;
if (!hevc->chunk->block->is_mapped)
data = codec_mm_vmap(
hevc->chunk->block->start +
hevc->chunk->offset, r);
else
data = ((u8 *)
hevc->chunk->block->start_virt)
+ hevc->chunk->offset;
for (jj = 0; jj < r; jj++) {
if ((jj & 0xf) == 0)
hevc_print(hevc,
@@ -9894,6 +9912,9 @@ static void vh265_work(struct work_struct *work)
PRINT_FRAMEBASE_DATA,
"\n");
}
if (!hevc->chunk->block->is_mapped)
codec_mm_unmap_phyaddr(data);
}
decode_size = hevc->chunk->size +
@@ -10243,8 +10264,15 @@ static void run(struct vdec_s *vdec, unsigned long mask,
if ((get_dbg_flag(hevc) & PRINT_FRAMEBASE_DATA) &&
input_frame_based(vdec)) {
int jj;
u8 *data = ((u8 *)hevc->chunk->block->start_virt) +
hevc->chunk->offset;
u8 *data = NULL;
if (!hevc->chunk->block->is_mapped)
data = codec_mm_vmap(hevc->chunk->block->start +
hevc->chunk->offset, r);
else
data = ((u8 *)hevc->chunk->block->start_virt)
+ hevc->chunk->offset;
for (jj = 0; jj < r; jj++) {
if ((jj & 0xf) == 0)
hevc_print(hevc, PRINT_FRAMEBASE_DATA,
@@ -10255,6 +10283,9 @@ static void run(struct vdec_s *vdec, unsigned long mask,
hevc_print_cont(hevc, PRINT_FRAMEBASE_DATA,
"\n");
}
if (!hevc->chunk->block->is_mapped)
codec_mm_unmap_phyaddr(data);
}
if (vdec->mc_loaded) {
/*firmware have load before,
@@ -10634,9 +10665,13 @@ static void vh265_dump_state(struct vdec_s *vdec)
int jj;
if (hevc->chunk && hevc->chunk->block &&
hevc->chunk->size > 0) {
u8 *data =
((u8 *)hevc->chunk->block->start_virt) +
hevc->chunk->offset;
u8 *data = NULL;
if (!hevc->chunk->block->is_mapped)
data = codec_mm_vmap(hevc->chunk->block->start +
hevc->chunk->offset, hevc->chunk->size);
else
data = ((u8 *)hevc->chunk->block->start_virt)
+ hevc->chunk->offset;
hevc_print(hevc, 0,
"frame data size 0x%x\n",
hevc->chunk->size);
@@ -10653,6 +10688,9 @@ static void vh265_dump_state(struct vdec_s *vdec)
PRINT_FRAMEBASE_DATA,
"\n");
}
if (!hevc->chunk->block->is_mapped)
codec_mm_unmap_phyaddr(data);
}
}

View File

@@ -637,9 +637,15 @@ static void vmjpeg_dump_state(struct vdec_s *vdec)
int jj;
if (hw->chunk && hw->chunk->block &&
hw->chunk->size > 0) {
u8 *data =
((u8 *)hw->chunk->block->start_virt) +
hw->chunk->offset;
u8 *data = NULL;
if (!hw->chunk->block->is_mapped)
data = codec_mm_vmap(hw->chunk->block->start +
hw->chunk->offset, hw->chunk->size);
else
data = ((u8 *)hw->chunk->block->start_virt) +
hw->chunk->offset;
mmjpeg_debug_print(DECODE_ID(hw), 0,
"frame data size 0x%x\n",
hw->chunk->size);
@@ -656,6 +662,9 @@ static void vmjpeg_dump_state(struct vdec_s *vdec)
PRINT_FRAMEBASE_DATA,
"\n");
}
if (!hw->chunk->block->is_mapped)
codec_mm_unmap_phyaddr(data);
}
}
}

View File

@@ -1738,12 +1738,13 @@ static int vmpeg12_canvas_init(void)
= (u32)buf_start;
ccbuf_phyAddress_virt
= codec_mm_phys_to_virt(ccbuf_phyAddress);
= codec_mm_phys_to_virt(
ccbuf_phyAddress);
if (!ccbuf_phyAddress_virt) {
ccbuf_phyAddress_virt
= ioremap_nocache(
ccbuf_phyAddress,
CCBUF_SIZE);
= codec_mm_vmap(
ccbuf_phyAddress,
CCBUF_SIZE);
ccbuf_phyAddress_is_remaped_nocache = 1;
}
}
@@ -1899,7 +1900,7 @@ static void vmpeg12_local_init(void)
p_userdata_mgr = NULL;
}
if (ccbuf_phyAddress_is_remaped_nocache)
iounmap(ccbuf_phyAddress_virt);
codec_mm_unmap_phyaddr(ccbuf_phyAddress_virt);
ccbuf_phyAddress_virt = NULL;
ccbuf_phyAddress = 0;
ccbuf_phyAddress_is_remaped_nocache = 0;
@@ -2112,7 +2113,7 @@ static int amvdec_mpeg12_remove(struct platform_device *pdev)
amvdec_disable();
if (ccbuf_phyAddress_is_remaped_nocache)
iounmap(ccbuf_phyAddress_virt);
codec_mm_unmap_phyaddr(ccbuf_phyAddress_virt);
ccbuf_phyAddress_virt = NULL;
ccbuf_phyAddress = 0;

View File

@@ -1265,9 +1265,15 @@ static void vmpeg2_dump_state(struct vdec_s *vdec)
int jj;
if (hw->chunk && hw->chunk->block &&
hw->chunk->size > 0) {
u8 *data =
((u8 *)hw->chunk->block->start_virt) +
hw->chunk->offset;
u8 *data = NULL;
if (!hw->chunk->block->is_mapped)
data = codec_mm_vmap(hw->chunk->block->start +
hw->chunk->offset, hw->chunk->size);
else
data = ((u8 *)hw->chunk->block->start_virt) +
hw->chunk->offset;
debug_print(DECODE_ID(hw), 0,
"frame data size 0x%x\n",
hw->chunk->size);
@@ -1284,6 +1290,9 @@ static void vmpeg2_dump_state(struct vdec_s *vdec)
PRINT_FRAMEBASE_DATA,
"\n");
}
if (!hw->chunk->block->is_mapped)
codec_mm_unmap_phyaddr(data);
}
}
}
@@ -1581,10 +1590,20 @@ static unsigned char get_data_check_sum
{
int jj;
int sum = 0;
u8 *data = ((u8 *)hw->chunk->block->start_virt) +
hw->chunk->offset;
u8 *data = NULL;
if (!hw->chunk->block->is_mapped)
data = codec_mm_vmap(hw->chunk->block->start +
hw->chunk->offset, size);
else
data = ((u8 *)hw->chunk->block->start_virt) +
hw->chunk->offset;
for (jj = 0; jj < size; jj++)
sum += data[jj];
if (!hw->chunk->block->is_mapped)
codec_mm_unmap_phyaddr(data);
return sum;
}
@@ -1613,8 +1632,15 @@ void (*callback)(struct vdec_s *, void *),
return;
}
if (input_frame_based(vdec)) {
u8 *data = ((u8 *)hw->chunk->block->start_virt) +
hw->chunk->offset;
u8 *data = NULL;
if (!hw->chunk->block->is_mapped)
data = codec_mm_vmap(hw->chunk->block->start +
hw->chunk->offset, size);
else
data = ((u8 *)hw->chunk->block->start_virt) +
hw->chunk->offset;
if (debug_enable & PRINT_FLAG_VDEC_STATUS
) {
debug_print(DECODE_ID(hw), 0,
@@ -1628,9 +1654,7 @@ void (*callback)(struct vdec_s *, void *),
if (debug_enable & PRINT_FRAMEBASE_DATA
) {
int jj;
u8 *data =
((u8 *)hw->chunk->block->start_virt) +
hw->chunk->offset;
for (jj = 0; jj < size; jj++) {
if ((jj & 0xf) == 0)
debug_print(DECODE_ID(hw),
@@ -1646,6 +1670,8 @@ void (*callback)(struct vdec_s *, void *),
}
}
if (!hw->chunk->block->is_mapped)
codec_mm_unmap_phyaddr(data);
} else
debug_print(DECODE_ID(hw), PRINT_FLAG_VDEC_STATUS,
"%s: %x %x %x %x %x size 0x%x\n",

View File

@@ -1240,9 +1240,15 @@ static void vmpeg4_dump_state(struct vdec_s *vdec)
int jj;
if (hw->chunk && hw->chunk->block &&
hw->chunk->size > 0) {
u8 *data =
((u8 *)hw->chunk->block->start_virt) +
hw->chunk->offset;
u8 *data = NULL;
if (!hw->chunk->block->is_mapped)
data = codec_mm_vmap(hw->chunk->block->start +
hw->chunk->offset, hw->chunk->size);
else
data = ((u8 *)hw->chunk->block->start_virt) +
hw->chunk->offset;
mmpeg4_debug_print(DECODE_ID(hw), 0,
"frame data size 0x%x\n",
hw->chunk->size);
@@ -1259,11 +1265,13 @@ static void vmpeg4_dump_state(struct vdec_s *vdec)
PRINT_FRAMEBASE_DATA,
"\n");
}
if (!hw->chunk->block->is_mapped)
codec_mm_unmap_phyaddr(data);
}
}
}
static void reset_process_time(struct vdec_mpeg4_hw_s *hw)
{
if (hw->start_process_time) {
@@ -1589,10 +1597,20 @@ static unsigned char get_data_check_sum
{
int jj;
int sum = 0;
u8 *data = ((u8 *)hw->chunk->block->start_virt) +
hw->chunk->offset;
u8 *data = NULL;
if (!hw->chunk->block->is_mapped)
data = codec_mm_vmap(hw->chunk->block->start +
hw->chunk->offset, size);
else
data = ((u8 *)hw->chunk->block->start_virt) +
hw->chunk->offset;
for (jj = 0; jj < size; jj++)
sum += data[jj];
if (!hw->chunk->block->is_mapped)
codec_mm_unmap_phyaddr(data);
return sum;
}
@@ -1621,8 +1639,15 @@ static void run(struct vdec_s *vdec, unsigned long mask,
}
if (input_frame_based(vdec)) {
u8 *data = ((u8 *)hw->chunk->block->start_virt) +
hw->chunk->offset;
u8 *data = NULL;
if (!hw->chunk->block->is_mapped)
data = codec_mm_vmap(hw->chunk->block->start +
hw->chunk->offset, size);
else
data = ((u8 *)hw->chunk->block->start_virt) +
hw->chunk->offset;
if (debug_enable & PRINT_FLAG_VDEC_STATUS
) {
mmpeg4_debug_print(DECODE_ID(hw), 0,
@@ -1636,9 +1661,7 @@ static void run(struct vdec_s *vdec, unsigned long mask,
if (debug_enable & PRINT_FRAMEBASE_DATA
) {
int jj;
u8 *data =
((u8 *)hw->chunk->block->start_virt) +
hw->chunk->offset;
for (jj = 0; jj < size; jj++) {
if ((jj & 0xf) == 0)
mmpeg4_debug_print(DECODE_ID(hw),
@@ -1654,6 +1677,8 @@ static void run(struct vdec_s *vdec, unsigned long mask,
}
}
if (!hw->chunk->block->is_mapped)
codec_mm_unmap_phyaddr(data);
} else
mmpeg4_debug_print(DECODE_ID(hw), PRINT_FLAG_VDEC_STATUS,
"%s: %x %x %x %x %x size 0x%x\n",

View File

@@ -25,6 +25,9 @@
#include "vdec.h"
#include "vdec_input.h"
#include <asm/cacheflush.h>
#include <linux/crc32.h>
#define VFRAME_BLOCK_SIZE (512 * SZ_1K)/*512 for 1080p default init.*/
#define VFRAME_BLOCK_SIZE_4K (2 * SZ_1M) /*2M for 4K default.*/
#define VFRAME_BLOCK_SIZE_MAX (4 * SZ_1M)
@@ -47,49 +50,101 @@
#define EXTRA_PADDING_SIZE (16 * SZ_1K) /*HEVC_PADDING_SIZE*/
#define MEM_NAME "VFRAME_INPUT"
//static int vdec_input_get_duration_u64(struct vdec_input_s *input);
static struct vframe_block_list_s *
vdec_input_alloc_new_block(struct vdec_input_s *input);
static int copy_from_user_to_phyaddr(void *virts, const char __user *buf,
u32 size, ulong phys, u32 pading, bool is_mapped)
{
u32 i, span = SZ_1M;
u32 count = size / PAGE_ALIGN(span);
u32 remain = size % PAGE_ALIGN(span);
ulong addr = phys;
u8 *p = virts;
if (is_mapped) {
if (copy_from_user(p, buf, size))
return -EFAULT;
if (pading) {
p += size;
memset(p, 0, pading);
}
dma_sync_single_for_device(get_vdec_device(),
addr, size + pading, DMA_TO_DEVICE);
return 0;
}
for (i = 0; i < count; i++) {
addr = phys + i * span;
p = codec_mm_vmap(addr, span);
if (!p)
return -1;
if (copy_from_user(p, buf + i * span, span)) {
codec_mm_unmap_phyaddr(p);
return -EFAULT;
}
codec_mm_unmap_phyaddr(p);
dma_sync_single_for_device(get_vdec_device(),
addr, span, DMA_TO_DEVICE);
}
if (!remain)
return 0;
span = size - remain;
addr = phys + span;
p = codec_mm_vmap(addr, remain + pading);
if (!p)
return -1;
if (copy_from_user(p, buf + span, remain)) {
codec_mm_unmap_phyaddr(p);
return -EFAULT;
}
if (pading)
memset(p + remain, 0, pading);
codec_mm_unmap_phyaddr(p);
dma_sync_single_for_device(get_vdec_device(),
addr, remain + pading, DMA_TO_DEVICE);
return 0;
}
static int vframe_chunk_fill(struct vdec_input_s *input,
struct vframe_chunk_s *chunk, const char *buf,
size_t count, struct vframe_block_list_s *block)
{
u8 *p = (u8 *)block->start_virt + block->wp;
int total_size = count + chunk->pading_size;
if (block->type == VDEC_TYPE_FRAME_BLOCK) {
if (copy_from_user(p, buf, count))
return -EFAULT;
p += count;
memset(p, 0, chunk->pading_size);
dma_sync_single_for_device(get_vdec_device(),
copy_from_user_to_phyaddr(p, buf, count,
block->start + block->wp,
total_size, DMA_TO_DEVICE);
chunk->pading_size,
block->is_mapped);
} else if (block->type == VDEC_TYPE_FRAME_CIRCULAR) {
size_t len = min((size_t)(block->size - block->wp), count);
u32 wp;
if (copy_from_user(p, buf, len))
return -EFAULT;
dma_sync_single_for_device(get_vdec_device(),
block->start + block->wp,
len, DMA_TO_DEVICE);
copy_from_user_to_phyaddr(p, buf, len,
block->start + block->wp, 0,
block->is_mapped);
p += len;
if (count > len) {
p = (u8 *)block->start_virt;
if (copy_from_user(p, buf, count - len))
return -EFAULT;
dma_sync_single_for_device(get_vdec_device(),
block->start,
count-len, DMA_TO_DEVICE);
copy_from_user_to_phyaddr(p, buf + len,
count - len,
block->start, 0,
block->is_mapped);
p += count - len;
}
@@ -100,7 +155,12 @@ static int vframe_chunk_fill(struct vdec_input_s *input,
len = min(block->size - wp, chunk->pading_size);
memset(p, 0, len);
if (!block->is_mapped) {
p = codec_mm_vmap(block->start + wp, len);
memset(p, 0, len);
codec_mm_unmap_phyaddr(p);
} else
memset(p, 0, len);
dma_sync_single_for_device(get_vdec_device(),
block->start + wp,
@@ -109,6 +169,11 @@ static int vframe_chunk_fill(struct vdec_input_s *input,
if (chunk->pading_size > len) {
p = (u8 *)block->start_virt;
if (!block->is_mapped) {
p = codec_mm_vmap(block->start, count - len);
memset(p, 0, count - len);
codec_mm_unmap_phyaddr(p);
} else
memset(p, 0, count - len);
dma_sync_single_for_device(get_vdec_device(),
@@ -182,6 +247,8 @@ static int vframe_block_init_alloc_storage(struct vdec_input_s *input,
}
block->start_virt = (void *)codec_mm_phys_to_virt(block->addr);
if (block->start_virt)
block->is_mapped = true;
block->start = block->addr;
block->size = alloc_size;
@@ -706,6 +773,7 @@ int vdec_input_add_frame(struct vdec_input_s *input, const char *buf,
#endif
if (input_stream_based(input))
return -EINVAL;
if (count < PAGE_SIZE) {
need_pading_size = PAGE_ALIGN(count + need_pading_size) -
count;

View File

@@ -28,6 +28,7 @@ struct vframe_block_list_s {
ulong start;
void *start_virt;
ulong addr;
bool is_mapped;
int type;
u32 size;
u32 wp;

View File

@@ -3232,70 +3232,87 @@ static void init_buff_spec(struct VP9Decoder_s *pbi,
buf_spec->lmem.buf_start +
buf_spec->lmem.buf_size;
if (pbi) {
if (!pbi)
return;
if (!vdec_secure(hw_to_vdec(pbi))) {
mem_start_virt =
codec_mm_phys_to_virt(buf_spec->dblk_para.buf_start);
if (mem_start_virt) {
memset(mem_start_virt, 0, buf_spec->dblk_para.buf_size);
memset(mem_start_virt, 0,
buf_spec->dblk_para.buf_size);
codec_mm_dma_flush(mem_start_virt,
buf_spec->dblk_para.buf_size,
DMA_TO_DEVICE);
} else {
/*not virt for tvp playing,
may need clear on ucode.*/
pr_err("mem_start_virt failed\n");
}
if (debug) {
pr_info("%s workspace (%x %x) size = %x\n", __func__,
buf_spec->start_adr, buf_spec->end_adr,
buf_spec->end_adr - buf_spec->start_adr);
}
if (debug) {
pr_info("ipp.buf_start :%x\n",
buf_spec->ipp.buf_start);
pr_info("sao_abv.buf_start :%x\n",
buf_spec->sao_abv.buf_start);
pr_info("sao_vb.buf_start :%x\n",
buf_spec->sao_vb.buf_start);
pr_info("short_term_rps.buf_start :%x\n",
buf_spec->short_term_rps.buf_start);
pr_info("vps.buf_start :%x\n",
buf_spec->vps.buf_start);
pr_info("sps.buf_start :%x\n",
buf_spec->sps.buf_start);
pr_info("pps.buf_start :%x\n",
buf_spec->pps.buf_start);
pr_info("sao_up.buf_start :%x\n",
buf_spec->sao_up.buf_start);
pr_info("swap_buf.buf_start :%x\n",
buf_spec->swap_buf.buf_start);
pr_info("swap_buf2.buf_start :%x\n",
buf_spec->swap_buf2.buf_start);
pr_info("scalelut.buf_start :%x\n",
buf_spec->scalelut.buf_start);
pr_info("dblk_para.buf_start :%x\n",
buf_spec->dblk_para.buf_start);
pr_info("dblk_data.buf_start :%x\n",
buf_spec->dblk_data.buf_start);
pr_info("seg_map.buf_start :%x\n",
buf_spec->seg_map.buf_start);
if (pbi->mmu_enable) {
pr_info("mmu_vbh.buf_start :%x\n",
buf_spec->mmu_vbh.buf_start);
}
pr_info("mpred_above.buf_start :%x\n",
buf_spec->mpred_above.buf_start);
#ifdef MV_USE_FIXED_BUF
pr_info("mpred_mv.buf_start :%x\n",
buf_spec->mpred_mv.buf_start);
#endif
if ((debug & VP9_DEBUG_SEND_PARAM_WITH_REG) == 0) {
pr_info("rpm.buf_start :%x\n",
buf_spec->rpm.buf_start);
mem_start_virt = codec_mm_vmap(
buf_spec->dblk_para.buf_start,
buf_spec->dblk_para.buf_size);
if (mem_start_virt) {
memset(mem_start_virt, 0,
buf_spec->dblk_para.buf_size);
codec_mm_dma_flush(mem_start_virt,
buf_spec->dblk_para.buf_size,
DMA_TO_DEVICE);
codec_mm_unmap_phyaddr(mem_start_virt);
} else {
/*not virt for tvp playing,
may need clear on ucode.*/
pr_err("mem_start_virt failed\n");
}
}
}
if (debug) {
pr_info("%s workspace (%x %x) size = %x\n", __func__,
buf_spec->start_adr, buf_spec->end_adr,
buf_spec->end_adr - buf_spec->start_adr);
}
if (debug) {
pr_info("ipp.buf_start :%x\n",
buf_spec->ipp.buf_start);
pr_info("sao_abv.buf_start :%x\n",
buf_spec->sao_abv.buf_start);
pr_info("sao_vb.buf_start :%x\n",
buf_spec->sao_vb.buf_start);
pr_info("short_term_rps.buf_start :%x\n",
buf_spec->short_term_rps.buf_start);
pr_info("vps.buf_start :%x\n",
buf_spec->vps.buf_start);
pr_info("sps.buf_start :%x\n",
buf_spec->sps.buf_start);
pr_info("pps.buf_start :%x\n",
buf_spec->pps.buf_start);
pr_info("sao_up.buf_start :%x\n",
buf_spec->sao_up.buf_start);
pr_info("swap_buf.buf_start :%x\n",
buf_spec->swap_buf.buf_start);
pr_info("swap_buf2.buf_start :%x\n",
buf_spec->swap_buf2.buf_start);
pr_info("scalelut.buf_start :%x\n",
buf_spec->scalelut.buf_start);
pr_info("dblk_para.buf_start :%x\n",
buf_spec->dblk_para.buf_start);
pr_info("dblk_data.buf_start :%x\n",
buf_spec->dblk_data.buf_start);
pr_info("seg_map.buf_start :%x\n",
buf_spec->seg_map.buf_start);
if (pbi->mmu_enable) {
pr_info("mmu_vbh.buf_start :%x\n",
buf_spec->mmu_vbh.buf_start);
}
pr_info("mpred_above.buf_start :%x\n",
buf_spec->mpred_above.buf_start);
#ifdef MV_USE_FIXED_BUF
pr_info("mpred_mv.buf_start :%x\n",
buf_spec->mpred_mv.buf_start);
#endif
if ((debug & VP9_DEBUG_SEND_PARAM_WITH_REG) == 0) {
pr_info("rpm.buf_start :%x\n",
buf_spec->rpm.buf_start);
}
}
}
/* cache_util.c */
@@ -8405,20 +8422,37 @@ static unsigned char get_data_check_sum
{
int jj;
int sum = 0;
u8 *data = ((u8 *)pbi->chunk->block->start_virt) +
pbi->chunk->offset;
u8 *data = NULL;
if (!pbi->chunk->block->is_mapped)
data = codec_mm_vmap(pbi->chunk->block->start +
pbi->chunk->offset, size);
else
data = ((u8 *)pbi->chunk->block->start_virt) +
pbi->chunk->offset;
for (jj = 0; jj < size; jj++)
sum += data[jj];
if (!pbi->chunk->block->is_mapped)
codec_mm_unmap_phyaddr(data);
return sum;
}
static void dump_data(struct VP9Decoder_s *pbi, int size)
{
int jj;
u8 *data = ((u8 *)pbi->chunk->block->start_virt) +
pbi->chunk->offset;
u8 *data = NULL;
int padding_size = pbi->chunk->offset &
(VDEC_FIFO_ALIGN - 1);
if (!pbi->chunk->block->is_mapped)
data = codec_mm_vmap(pbi->chunk->block->start +
pbi->chunk->offset, size);
else
data = ((u8 *)pbi->chunk->block->start_virt) +
pbi->chunk->offset;
vp9_print(pbi, 0, "padding: ");
for (jj = padding_size; jj > 0; jj--)
vp9_print_cont(pbi,
@@ -8443,6 +8477,9 @@ static void dump_data(struct VP9Decoder_s *pbi, int size)
vp9_print(pbi,
0,
"\n");
if (!pbi->chunk->block->is_mapped)
codec_mm_unmap_phyaddr(data);
}
static void vp9_work(struct work_struct *work)
@@ -8769,13 +8806,23 @@ static void run_front(struct vdec_s *vdec)
READ_VREG(HEVC_STREAM_RD_PTR),
pbi->start_shift_bytes);
if (vdec_frame_based(vdec) && pbi->chunk) {
u8 *data = ((u8 *)pbi->chunk->block->start_virt) +
pbi->chunk->offset;
u8 *data = NULL;
if (!pbi->chunk->block->is_mapped)
data = codec_mm_vmap(pbi->chunk->block->start +
pbi->chunk->offset, 8);
else
data = ((u8 *)pbi->chunk->block->start_virt) +
pbi->chunk->offset;
vp9_print_cont(pbi, 0, "data adr %p:",
data);
for (ii = 0; ii < 8; ii++)
vp9_print_cont(pbi, 0, "%02x ",
data[ii]);
if (!pbi->chunk->block->is_mapped)
codec_mm_unmap_phyaddr(data);
}
vp9_print_cont(pbi, 0, "\r\n");
}
@@ -9133,9 +9180,16 @@ static void vp9_dump_state(struct vdec_s *vdec)
int jj;
if (pbi->chunk && pbi->chunk->block &&
pbi->chunk->size > 0) {
u8 *data =
((u8 *)pbi->chunk->block->start_virt) +
pbi->chunk->offset;
u8 *data = NULL;
if (!pbi->chunk->block->is_mapped)
data = codec_mm_vmap(
pbi->chunk->block->start +
pbi->chunk->offset,
pbi->chunk->size);
else
data = ((u8 *)pbi->chunk->block->start_virt)
+ pbi->chunk->offset;
vp9_print(pbi, 0,
"frame data size 0x%x\n",
pbi->chunk->size);
@@ -9149,6 +9203,9 @@ static void vp9_dump_state(struct vdec_s *vdec)
vp9_print_cont(pbi, 0,
"\n");
}
if (!pbi->chunk->block->is_mapped)
codec_mm_unmap_phyaddr(data);
}
}