/*
* 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_VENC_HYBRID_H264,
	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 */
