242 lines · c
1/* SPDX-License-Identifier: GPL-2.0+ */2/*3 * NVIDIA Tegra Video decoder driver4 *5 * Copyright (C) 2016-2019 GRATE-DRIVER project6 */7 8#ifndef TEGRA_VDE_H9#define TEGRA_VDE_H10 11#include <linux/completion.h>12#include <linux/dma-direction.h>13#include <linux/iova.h>14#include <linux/list.h>15#include <linux/mutex.h>16#include <linux/types.h>17#include <linux/workqueue.h>18 19#include <media/media-device.h>20#include <media/videobuf2-dma-contig.h>21#include <media/videobuf2-dma-sg.h>22#include <media/v4l2-ctrls.h>23#include <media/v4l2-device.h>24#include <media/v4l2-event.h>25#include <media/v4l2-ioctl.h>26#include <media/v4l2-mem2mem.h>27 28#define ICMDQUE_WR 0x0029#define CMDQUE_CONTROL 0x0830#define INTR_STATUS 0x1831#define BSE_INT_ENB 0x4032#define BSE_CONFIG 0x4433 34#define BSE_ICMDQUE_EMPTY BIT(3)35#define BSE_DMA_BUSY BIT(23)36 37#define BSEV_ALIGN SZ_138#define FRAMEID_ALIGN SZ_25639#define SXE_BUFFER SZ_32K40#define VDE_ATOM SZ_1641 42struct clk;43struct dma_buf;44struct gen_pool;45struct tegra_ctx;46struct iommu_group;47struct iommu_domain;48struct reset_control;49struct dma_buf_attachment;50struct tegra_vde_h264_decoder_ctx;51 52struct tegra_video_frame {53 struct dma_buf_attachment *y_dmabuf_attachment;54 struct dma_buf_attachment *cb_dmabuf_attachment;55 struct dma_buf_attachment *cr_dmabuf_attachment;56 struct dma_buf_attachment *aux_dmabuf_attachment;57 dma_addr_t y_addr;58 dma_addr_t cb_addr;59 dma_addr_t cr_addr;60 dma_addr_t aux_addr;61 u32 frame_num;62 u32 flags;63 u32 luma_atoms_pitch;64 u32 chroma_atoms_pitch;65};66 67struct tegra_coded_fmt_desc {68 u32 fourcc;69 struct v4l2_frmsize_stepwise frmsize;70 unsigned int num_decoded_fmts;71 const u32 *decoded_fmts;72 int (*decode_run)(struct tegra_ctx *ctx);73 int (*decode_wait)(struct tegra_ctx *ctx);74};75 76struct tegra_vde_soc {77 bool supports_ref_pic_marking;78 const struct tegra_coded_fmt_desc *coded_fmts;79 u32 num_coded_fmts;80};81 82struct tegra_vde_bo {83 struct iova *iova;84 struct sg_table sgt;85 struct tegra_vde *vde;86 enum dma_data_direction dma_dir;87 unsigned long dma_attrs;88 dma_addr_t dma_handle;89 dma_addr_t dma_addr;90 void *dma_cookie;91 size_t size;92};93 94struct tegra_vde {95 void __iomem *sxe;96 void __iomem *bsev;97 void __iomem *mbe;98 void __iomem *ppe;99 void __iomem *mce;100 void __iomem *tfe;101 void __iomem *ppb;102 void __iomem *vdma;103 void __iomem *frameid;104 struct device *dev;105 struct mutex lock;106 struct mutex map_lock;107 struct list_head map_list;108 struct reset_control *rst;109 struct reset_control *rst_mc;110 struct gen_pool *iram_pool;111 struct completion decode_completion;112 struct clk *clk;113 struct iommu_domain *domain;114 struct iommu_group *group;115 struct iova_domain iova;116 struct iova *iova_resv_static_addresses;117 struct iova *iova_resv_last_page;118 const struct tegra_vde_soc *soc;119 struct tegra_vde_bo *secure_bo;120 dma_addr_t bitstream_data_addr;121 dma_addr_t iram_lists_addr;122 u32 *iram;123 struct v4l2_device v4l2_dev;124 struct v4l2_m2m_dev *m2m;125 struct media_device mdev;126 struct video_device vdev;127 struct mutex v4l2_lock;128 struct workqueue_struct *wq;129 struct tegra_video_frame frames[V4L2_H264_NUM_DPB_ENTRIES + 1];130};131 132int tegra_vde_alloc_bo(struct tegra_vde *vde,133 struct tegra_vde_bo **ret_bo,134 enum dma_data_direction dma_dir,135 size_t size);136void tegra_vde_free_bo(struct tegra_vde_bo *bo);137 138struct tegra_ctx_h264 {139 const struct v4l2_ctrl_h264_decode_params *decode_params;140 const struct v4l2_ctrl_h264_sps *sps;141 const struct v4l2_ctrl_h264_pps *pps;142};143 144struct tegra_ctx {145 struct tegra_vde *vde;146 struct tegra_ctx_h264 h264;147 struct work_struct work;148 struct v4l2_fh fh;149 struct v4l2_ctrl_handler hdl;150 struct v4l2_format coded_fmt;151 struct v4l2_format decoded_fmt;152 const struct tegra_coded_fmt_desc *coded_fmt_desc;153 struct v4l2_ctrl *ctrls[];154};155 156struct tegra_m2m_buffer {157 struct v4l2_m2m_buffer m2m;158 struct dma_buf_attachment *a[VB2_MAX_PLANES];159 dma_addr_t dma_base[VB2_MAX_PLANES];160 dma_addr_t dma_addr[VB2_MAX_PLANES];161 struct iova *iova[VB2_MAX_PLANES];162 struct tegra_vde_bo *aux;163 bool b_frame;164};165 166static inline struct tegra_m2m_buffer *167vb_to_tegra_buf(struct vb2_buffer *vb)168{169 struct v4l2_m2m_buffer *m2m = container_of(vb, struct v4l2_m2m_buffer,170 vb.vb2_buf);171 172 return container_of(m2m, struct tegra_m2m_buffer, m2m);173}174 175void tegra_vde_prepare_control_data(struct tegra_ctx *ctx, u32 id);176 177void tegra_vde_writel(struct tegra_vde *vde, u32 value, void __iomem *base,178 u32 offset);179u32 tegra_vde_readl(struct tegra_vde *vde, void __iomem *base, u32 offset);180void tegra_vde_set_bits(struct tegra_vde *vde, u32 mask, void __iomem *base,181 u32 offset);182 183int tegra_vde_h264_decode_run(struct tegra_ctx *ctx);184int tegra_vde_h264_decode_wait(struct tegra_ctx *ctx);185 186int tegra_vde_iommu_init(struct tegra_vde *vde);187void tegra_vde_iommu_deinit(struct tegra_vde *vde);188int tegra_vde_iommu_map(struct tegra_vde *vde,189 struct sg_table *sgt,190 struct iova **iovap,191 size_t size);192void tegra_vde_iommu_unmap(struct tegra_vde *vde, struct iova *iova);193 194int tegra_vde_dmabuf_cache_map(struct tegra_vde *vde,195 struct dma_buf *dmabuf,196 enum dma_data_direction dma_dir,197 struct dma_buf_attachment **ap,198 dma_addr_t *addrp);199void tegra_vde_dmabuf_cache_unmap(struct tegra_vde *vde,200 struct dma_buf_attachment *a,201 bool release);202void tegra_vde_dmabuf_cache_unmap_sync(struct tegra_vde *vde);203void tegra_vde_dmabuf_cache_unmap_all(struct tegra_vde *vde);204 205static __maybe_unused char const *206tegra_vde_reg_base_name(struct tegra_vde *vde, void __iomem *base)207{208 if (vde->sxe == base)209 return "SXE";210 211 if (vde->bsev == base)212 return "BSEV";213 214 if (vde->mbe == base)215 return "MBE";216 217 if (vde->ppe == base)218 return "PPE";219 220 if (vde->mce == base)221 return "MCE";222 223 if (vde->tfe == base)224 return "TFE";225 226 if (vde->ppb == base)227 return "PPB";228 229 if (vde->vdma == base)230 return "VDMA";231 232 if (vde->frameid == base)233 return "FRAMEID";234 235 return "???";236}237 238int tegra_vde_v4l2_init(struct tegra_vde *vde);239void tegra_vde_v4l2_deinit(struct tegra_vde *vde);240 241#endif /* TEGRA_VDE_H */242