mirror of
https://github.com/torvalds/linux.git
synced 2024-12-21 10:31:54 +00:00
e6599adfad
Previously, vpu->recv_buf and send_buf are forced cast from
void __iomem *tcm. vpu->recv_buf->share_buf is passed to
vpu_ipi_desc.handler(). It's not able to do unaligned access. Otherwise
kernel would crash due to unable to handle kernel paging request.
struct vpu_run {
u32 signaled;
char fw_ver[VPU_FW_VER_LEN];
unsigned int dec_capability;
unsigned int enc_capability;
wait_queue_head_t wq;
};
fw_ver starts at 4 byte boundary. If system enables
CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS, strscpy() will do
read_word_at_a_time(), which tries to read 8-byte: *(unsigned long *)addr
vpu_init_ipi_handler() calls strscpy(), which would lead to crash.
vpu_init_ipi_handler() and several other handlers (eg.
vpu_dec_ipi_handler) only do read access to this data, so they can be
const, and we can use memcpy_fromio() to copy the buf to another non iomem
buffer then pass to handler.
Fixes: 85709cbf15
("media: replace strncpy() by strscpy()")
Signed-off-by: Hsin-Yi Wang <hsinyi@chromium.org>
Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl>
Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
187 lines
5.3 KiB
C
187 lines
5.3 KiB
C
/* SPDX-License-Identifier: GPL-2.0-only */
|
|
/*
|
|
* Copyright (c) 2016 MediaTek Inc.
|
|
* Author: Andrew-CT Chen <andrew-ct.chen@mediatek.com>
|
|
*/
|
|
|
|
#ifndef _MTK_VPU_H
|
|
#define _MTK_VPU_H
|
|
|
|
#include <linux/platform_device.h>
|
|
|
|
/**
|
|
* VPU (video processor unit) is a tiny processor controlling video hardware
|
|
* related to video codec, scaling and color format converting.
|
|
* VPU interfaces with other blocks by share memory and interrupt.
|
|
**/
|
|
|
|
typedef void (*ipi_handler_t) (const void *data,
|
|
unsigned int len,
|
|
void *priv);
|
|
|
|
/**
|
|
* enum ipi_id - the id of inter-processor interrupt
|
|
*
|
|
* @IPI_VPU_INIT: The interrupt from vpu is to notfiy kernel
|
|
* VPU initialization completed.
|
|
* IPI_VPU_INIT is sent from VPU when firmware is
|
|
* loaded. AP doesn't need to send IPI_VPU_INIT
|
|
* command to VPU.
|
|
* For other IPI below, AP should send the request
|
|
* to VPU to trigger the interrupt.
|
|
* @IPI_VDEC_H264: The interrupt from vpu is to notify kernel to
|
|
* handle H264 vidoe decoder job, and vice versa.
|
|
* Decode output format is always MT21 no matter what
|
|
* the input format is.
|
|
* @IPI_VDEC_VP8: The interrupt from is to notify kernel to
|
|
* handle VP8 video decoder job, and vice versa.
|
|
* Decode output format is always MT21 no matter what
|
|
* the input format is.
|
|
* @IPI_VDEC_VP9: The interrupt from vpu is to notify kernel to
|
|
* handle VP9 video decoder job, and vice versa.
|
|
* Decode output format is always MT21 no matter what
|
|
* the input format is.
|
|
* @IPI_VENC_H264: The interrupt from vpu is to notify kernel to
|
|
* handle H264 video encoder job, and vice versa.
|
|
* @IPI_VENC_VP8: The interrupt fro vpu is to notify kernel to
|
|
* handle VP8 video encoder job,, and vice versa.
|
|
* @IPI_MDP: The interrupt from vpu is to notify kernel to
|
|
* handle MDP (Media Data Path) job, and vice versa.
|
|
* @IPI_MAX: The maximum IPI number
|
|
*/
|
|
|
|
enum ipi_id {
|
|
IPI_VPU_INIT = 0,
|
|
IPI_VDEC_H264,
|
|
IPI_VDEC_VP8,
|
|
IPI_VDEC_VP9,
|
|
IPI_VENC_H264,
|
|
IPI_VENC_VP8,
|
|
IPI_MDP,
|
|
IPI_MAX,
|
|
};
|
|
|
|
/**
|
|
* enum rst_id - reset id to register reset function for VPU watchdog timeout
|
|
*
|
|
* @VPU_RST_ENC: encoder reset id
|
|
* @VPU_RST_DEC: decoder reset id
|
|
* @VPU_RST_MDP: MDP (Media Data Path) reset id
|
|
* @VPU_RST_MAX: maximum reset id
|
|
*/
|
|
enum rst_id {
|
|
VPU_RST_ENC,
|
|
VPU_RST_DEC,
|
|
VPU_RST_MDP,
|
|
VPU_RST_MAX,
|
|
};
|
|
|
|
/**
|
|
* vpu_ipi_register - register an ipi function
|
|
*
|
|
* @pdev: VPU platform device
|
|
* @id: IPI ID
|
|
* @handler: IPI handler
|
|
* @name: IPI name
|
|
* @priv: private data for IPI handler
|
|
*
|
|
* Register an ipi function to receive ipi interrupt from VPU.
|
|
*
|
|
* Return: Return 0 if ipi registers successfully, otherwise it is failed.
|
|
*/
|
|
int vpu_ipi_register(struct platform_device *pdev, enum ipi_id id,
|
|
ipi_handler_t handler, const char *name, void *priv);
|
|
|
|
/**
|
|
* vpu_ipi_send - send data from AP to vpu.
|
|
*
|
|
* @pdev: VPU platform device
|
|
* @id: IPI ID
|
|
* @buf: the data buffer
|
|
* @len: the data buffer length
|
|
*
|
|
* This function is thread-safe. When this function returns,
|
|
* VPU has received the data and starts the processing.
|
|
* When the processing completes, IPI handler registered
|
|
* by vpu_ipi_register will be called in interrupt context.
|
|
*
|
|
* Return: Return 0 if sending data successfully, otherwise it is failed.
|
|
**/
|
|
int vpu_ipi_send(struct platform_device *pdev,
|
|
enum ipi_id id, void *buf,
|
|
unsigned int len);
|
|
|
|
/**
|
|
* vpu_get_plat_device - get VPU's platform device
|
|
*
|
|
* @pdev: the platform device of the module requesting VPU platform
|
|
* device for using VPU API.
|
|
*
|
|
* Return: Return NULL if it is failed.
|
|
* otherwise it is VPU's platform device
|
|
**/
|
|
struct platform_device *vpu_get_plat_device(struct platform_device *pdev);
|
|
|
|
/**
|
|
* vpu_wdt_reg_handler - register a VPU watchdog handler
|
|
*
|
|
* @pdev: VPU platform device
|
|
* @vpu_wdt_reset_func: the callback reset function
|
|
* @private_data: the private data for reset function
|
|
* @rst_id: reset id
|
|
*
|
|
* Register a handler performing own tasks when vpu reset by watchdog
|
|
*
|
|
* Return: Return 0 if the handler is added successfully,
|
|
* otherwise it is failed.
|
|
*
|
|
**/
|
|
int vpu_wdt_reg_handler(struct platform_device *pdev,
|
|
void vpu_wdt_reset_func(void *),
|
|
void *priv, enum rst_id id);
|
|
|
|
/**
|
|
* vpu_get_vdec_hw_capa - get video decoder hardware capability
|
|
*
|
|
* @pdev: VPU platform device
|
|
*
|
|
* Return: video decoder hardware capability
|
|
**/
|
|
unsigned int vpu_get_vdec_hw_capa(struct platform_device *pdev);
|
|
|
|
/**
|
|
* vpu_get_venc_hw_capa - get video encoder hardware capability
|
|
*
|
|
* @pdev: VPU platform device
|
|
*
|
|
* Return: video encoder hardware capability
|
|
**/
|
|
unsigned int vpu_get_venc_hw_capa(struct platform_device *pdev);
|
|
|
|
/**
|
|
* vpu_load_firmware - download VPU firmware and boot it
|
|
*
|
|
* @pdev: VPU platform device
|
|
*
|
|
* Return: Return 0 if downloading firmware successfully,
|
|
* otherwise it is failed
|
|
**/
|
|
int vpu_load_firmware(struct platform_device *pdev);
|
|
|
|
/**
|
|
* vpu_mapping_dm_addr - Mapping DTCM/DMEM to kernel virtual address
|
|
*
|
|
* @pdev: VPU platform device
|
|
* @dmem_addr: VPU's data memory address
|
|
*
|
|
* Mapping the VPU's DTCM (Data Tightly-Coupled Memory) /
|
|
* DMEM (Data Extended Memory) memory address to
|
|
* kernel virtual address.
|
|
*
|
|
* Return: Return ERR_PTR(-EINVAL) if mapping failed,
|
|
* otherwise the mapped kernel virtual address
|
|
**/
|
|
void *vpu_mapping_dm_addr(struct platform_device *pdev,
|
|
u32 dtcm_dmem_addr);
|
|
#endif /* _MTK_VPU_H */
|