Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0-or-later */
0002 /*
0003  * Copyright (c) 2017 Samsung Electronics Co., Ltd.
0004  */
0005 
0006 #ifndef _EXYNOS_DRM_IPP_H_
0007 #define _EXYNOS_DRM_IPP_H_
0008 
0009 struct exynos_drm_ipp;
0010 struct exynos_drm_ipp_task;
0011 
0012 /**
0013  * struct exynos_drm_ipp_funcs - exynos_drm_ipp control functions
0014  */
0015 struct exynos_drm_ipp_funcs {
0016     /**
0017      * @commit:
0018      *
0019      * This is the main entry point to start framebuffer processing
0020      * in the hardware. The exynos_drm_ipp_task has been already validated.
0021      * This function must not wait until the device finishes processing.
0022      * When the driver finishes processing, it has to call
0023      * exynos_exynos_drm_ipp_task_done() function.
0024      *
0025      * RETURNS:
0026      *
0027      * 0 on success or negative error codes in case of failure.
0028      */
0029     int (*commit)(struct exynos_drm_ipp *ipp,
0030               struct exynos_drm_ipp_task *task);
0031 
0032     /**
0033      * @abort:
0034      *
0035      * Informs the driver that it has to abort the currently running
0036      * task as soon as possible (i.e. as soon as it can stop the device
0037      * safely), even if the task would not have been finished by then.
0038      * After the driver performs the necessary steps, it has to call
0039      * exynos_drm_ipp_task_done() (as if the task ended normally).
0040      * This function does not have to (and will usually not) wait
0041      * until the device enters a state when it can be stopped.
0042      */
0043     void (*abort)(struct exynos_drm_ipp *ipp,
0044               struct exynos_drm_ipp_task *task);
0045 };
0046 
0047 /**
0048  * struct exynos_drm_ipp - central picture processor module structure
0049  */
0050 struct exynos_drm_ipp {
0051     struct drm_device *drm_dev;
0052     struct device *dev;
0053     struct list_head head;
0054     unsigned int id;
0055 
0056     const char *name;
0057     const struct exynos_drm_ipp_funcs *funcs;
0058     unsigned int capabilities;
0059     const struct exynos_drm_ipp_formats *formats;
0060     unsigned int num_formats;
0061     atomic_t sequence;
0062 
0063     spinlock_t lock;
0064     struct exynos_drm_ipp_task *task;
0065     struct list_head todo_list;
0066     wait_queue_head_t done_wq;
0067 };
0068 
0069 struct exynos_drm_ipp_buffer {
0070     struct drm_exynos_ipp_task_buffer buf;
0071     struct drm_exynos_ipp_task_rect rect;
0072 
0073     struct exynos_drm_gem *exynos_gem[MAX_FB_BUFFER];
0074     const struct drm_format_info *format;
0075     dma_addr_t dma_addr[MAX_FB_BUFFER];
0076 };
0077 
0078 /**
0079  * struct exynos_drm_ipp_task - a structure describing transformation that
0080  * has to be performed by the picture processor hardware module
0081  */
0082 struct exynos_drm_ipp_task {
0083     struct device *dev;
0084     struct exynos_drm_ipp *ipp;
0085     struct list_head head;
0086 
0087     struct exynos_drm_ipp_buffer src;
0088     struct exynos_drm_ipp_buffer dst;
0089 
0090     struct drm_exynos_ipp_task_transform transform;
0091     struct drm_exynos_ipp_task_alpha alpha;
0092 
0093     struct work_struct cleanup_work;
0094     unsigned int flags;
0095     int ret;
0096 
0097     struct drm_pending_exynos_ipp_event *event;
0098 };
0099 
0100 #define DRM_EXYNOS_IPP_TASK_DONE    (1 << 0)
0101 #define DRM_EXYNOS_IPP_TASK_ASYNC   (1 << 1)
0102 
0103 struct exynos_drm_ipp_formats {
0104     uint32_t fourcc;
0105     uint32_t type;
0106     uint64_t modifier;
0107     const struct drm_exynos_ipp_limit *limits;
0108     unsigned int num_limits;
0109 };
0110 
0111 /* helper macros to set exynos_drm_ipp_formats structure and limits*/
0112 #define IPP_SRCDST_MFORMAT(f, m, l) \
0113     .fourcc = DRM_FORMAT_##f, .modifier = m, .limits = l, \
0114     .num_limits = ARRAY_SIZE(l), \
0115     .type = (DRM_EXYNOS_IPP_FORMAT_SOURCE | \
0116          DRM_EXYNOS_IPP_FORMAT_DESTINATION)
0117 
0118 #define IPP_SRCDST_FORMAT(f, l) IPP_SRCDST_MFORMAT(f, 0, l)
0119 
0120 #define IPP_SIZE_LIMIT(l, val...)   \
0121     .type = (DRM_EXYNOS_IPP_LIMIT_TYPE_SIZE | \
0122          DRM_EXYNOS_IPP_LIMIT_SIZE_##l), val
0123 
0124 #define IPP_SCALE_LIMIT(val...)     \
0125     .type = (DRM_EXYNOS_IPP_LIMIT_TYPE_SCALE), val
0126 
0127 int exynos_drm_ipp_register(struct device *dev, struct exynos_drm_ipp *ipp,
0128         const struct exynos_drm_ipp_funcs *funcs, unsigned int caps,
0129         const struct exynos_drm_ipp_formats *formats,
0130         unsigned int num_formats, const char *name);
0131 void exynos_drm_ipp_unregister(struct device *dev,
0132                    struct exynos_drm_ipp *ipp);
0133 
0134 void exynos_drm_ipp_task_done(struct exynos_drm_ipp_task *task, int ret);
0135 
0136 #ifdef CONFIG_DRM_EXYNOS_IPP
0137 int exynos_drm_ipp_get_res_ioctl(struct drm_device *dev, void *data,
0138                  struct drm_file *file_priv);
0139 int exynos_drm_ipp_get_caps_ioctl(struct drm_device *dev, void *data,
0140                   struct drm_file *file_priv);
0141 int exynos_drm_ipp_get_limits_ioctl(struct drm_device *dev, void *data,
0142                     struct drm_file *file_priv);
0143 int exynos_drm_ipp_commit_ioctl(struct drm_device *dev,
0144                 void *data, struct drm_file *file_priv);
0145 #else
0146 static inline int exynos_drm_ipp_get_res_ioctl(struct drm_device *dev,
0147      void *data, struct drm_file *file_priv)
0148 {
0149     struct drm_exynos_ioctl_ipp_get_res *resp = data;
0150 
0151     resp->count_ipps = 0;
0152     return 0;
0153 }
0154 static inline int exynos_drm_ipp_get_caps_ioctl(struct drm_device *dev,
0155      void *data, struct drm_file *file_priv)
0156 {
0157     return -ENODEV;
0158 }
0159 static inline int exynos_drm_ipp_get_limits_ioctl(struct drm_device *dev,
0160      void *data, struct drm_file *file_priv)
0161 {
0162     return -ENODEV;
0163 }
0164 static inline int exynos_drm_ipp_commit_ioctl(struct drm_device *dev,
0165      void *data, struct drm_file *file_priv)
0166 {
0167     return -ENODEV;
0168 }
0169 #endif
0170 #endif