| /* |
| * Copyright (c) 2016 MediaTek Inc. |
| * Author: Andrew-CT Chen <andrew-ct.chen@mediatek.com> |
| * |
| * This program is free software; you can redistribute it and/or modify |
| * it under the terms of the GNU General Public License version 2 as |
| * published by the Free Software Foundation. |
| * |
| * This program is distributed in the hope that it will be useful, |
| * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| * GNU General Public License for more details. |
| */ |
| |
| #ifndef _MTK_VPU_H |
| #define _MTK_VPU_H |
| |
| #include <linux/platform_device.h> |
| |
| |
| void vcu_get_task(struct task_struct **task, struct files_struct **f); |
| |
| /** |
| * 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 int (*ipi_handler_t) (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, |
| }; |
| |
| struct mtk_vpu_plat; |
| |
| struct mtk_vpu_ops { |
| int (*ipi_register)(struct mtk_vpu_plat *vpu, enum ipi_id id, |
| ipi_handler_t handler, const char *name, void *priv); |
| int (*ipi_send)(struct mtk_vpu_plat *vpu, |
| enum ipi_id id, void *buf, |
| unsigned int len); |
| int (*wdt_reg_handler)(struct mtk_vpu_plat *vpu, |
| void vpu_wdt_reset_func(void *), |
| void *priv, enum rst_id id); |
| unsigned int (*get_vdec_hw_capa)(struct mtk_vpu_plat *vpu); |
| unsigned int (*get_venc_hw_capa)(struct mtk_vpu_plat *vpu); |
| int (*load_firmware)(struct mtk_vpu_plat *vpu); |
| void *(*mapping_dm_addr)(struct mtk_vpu_plat *vpu, |
| uintptr_t dtcm_dmem_addr); |
| }; |
| |
| struct mtk_vpu_plat { |
| struct mtk_vpu_ops *ops; |
| }; |
| |
| /** |
| * 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. |
| */ |
| static inline int vpu_ipi_register(struct platform_device *pdev, enum ipi_id id, |
| ipi_handler_t handler, const char *name, void *priv) |
| { |
| struct mtk_vpu_plat *vpu = platform_get_drvdata(pdev); |
| |
| if (vpu->ops->ipi_register) |
| return vpu->ops->ipi_register(vpu, id, handler, name, priv); |
| |
| return -ENOTSUPP; |
| } |
| |
| /** |
| * 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. |
| **/ |
| static inline int vpu_ipi_send(struct platform_device *pdev, |
| enum ipi_id id, void *buf, |
| unsigned int len) |
| { |
| struct mtk_vpu_plat *vpu = platform_get_drvdata(pdev); |
| |
| if (vpu->ops->ipi_send) |
| return vpu->ops->ipi_send(vpu, id, buf, len); |
| |
| return -ENOTSUPP; |
| } |
| |
| /** |
| * 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. |
| * |
| **/ |
| static inline int vpu_wdt_reg_handler(struct platform_device *pdev, |
| void vpu_wdt_reset_func(void *), |
| void *priv, enum rst_id id) |
| { |
| struct mtk_vpu_plat *vpu = platform_get_drvdata(pdev); |
| |
| if (vpu->ops->wdt_reg_handler) |
| return vpu->ops->wdt_reg_handler(vpu, vpu_wdt_reset_func, priv, id); |
| |
| return -ENOTSUPP; |
| } |
| |
| /** |
| * vpu_get_vdec_hw_capa - get video decoder hardware capability |
| * |
| * @pdev: VPU platform device |
| * |
| * Return: video decoder hardware capability |
| **/ |
| static inline unsigned int vpu_get_vdec_hw_capa(struct platform_device *pdev) |
| { |
| struct mtk_vpu_plat *vpu = platform_get_drvdata(pdev); |
| |
| if (vpu->ops->get_vdec_hw_capa) |
| return vpu->ops->get_vdec_hw_capa(vpu); |
| |
| return 0; |
| } |
| |
| /** |
| * vpu_get_venc_hw_capa - get video encoder hardware capability |
| * |
| * @pdev: VPU platform device |
| * |
| * Return: video encoder hardware capability |
| **/ |
| static inline unsigned int vpu_get_venc_hw_capa(struct platform_device *pdev) |
| { |
| struct mtk_vpu_plat *vpu = platform_get_drvdata(pdev); |
| |
| if (vpu->ops->get_venc_hw_capa) |
| return vpu->ops->get_venc_hw_capa(vpu); |
| |
| return 0; |
| } |
| |
| /** |
| * vpu_load_firmware - download VPU firmware and boot it |
| * |
| * @pdev: VPU platform device |
| * |
| * Return: Return 0 if downloading firmware successfully, |
| * otherwise it is failed |
| **/ |
| static inline int vpu_load_firmware(struct platform_device *pdev) |
| { |
| struct mtk_vpu_plat *vpu = platform_get_drvdata(pdev); |
| |
| if (vpu->ops->load_firmware) |
| return vpu->ops->load_firmware(vpu); |
| |
| return -ENOTSUPP; |
| } |
| |
| /** |
| * 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 |
| **/ |
| static inline void *vpu_mapping_dm_addr(struct platform_device *pdev, |
| uintptr_t dtcm_dmem_addr) |
| { |
| struct mtk_vpu_plat *vpu = platform_get_drvdata(pdev); |
| |
| if (vpu->ops->mapping_dm_addr) |
| return vpu->ops->mapping_dm_addr(vpu, dtcm_dmem_addr); |
| |
| return ERR_PTR(-ENOTSUPP); |
| } |
| #endif /* _MTK_VPU_H */ |