18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-or-later */ 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * Copyright (c) 2017 Samsung Electronics Co., Ltd. 48c2ecf20Sopenharmony_ci */ 58c2ecf20Sopenharmony_ci 68c2ecf20Sopenharmony_ci#ifndef _EXYNOS_DRM_IPP_H_ 78c2ecf20Sopenharmony_ci#define _EXYNOS_DRM_IPP_H_ 88c2ecf20Sopenharmony_ci 98c2ecf20Sopenharmony_cistruct exynos_drm_ipp; 108c2ecf20Sopenharmony_cistruct exynos_drm_ipp_task; 118c2ecf20Sopenharmony_ci 128c2ecf20Sopenharmony_ci/** 138c2ecf20Sopenharmony_ci * struct exynos_drm_ipp_funcs - exynos_drm_ipp control functions 148c2ecf20Sopenharmony_ci */ 158c2ecf20Sopenharmony_cistruct exynos_drm_ipp_funcs { 168c2ecf20Sopenharmony_ci /** 178c2ecf20Sopenharmony_ci * @commit: 188c2ecf20Sopenharmony_ci * 198c2ecf20Sopenharmony_ci * This is the main entry point to start framebuffer processing 208c2ecf20Sopenharmony_ci * in the hardware. The exynos_drm_ipp_task has been already validated. 218c2ecf20Sopenharmony_ci * This function must not wait until the device finishes processing. 228c2ecf20Sopenharmony_ci * When the driver finishes processing, it has to call 238c2ecf20Sopenharmony_ci * exynos_exynos_drm_ipp_task_done() function. 248c2ecf20Sopenharmony_ci * 258c2ecf20Sopenharmony_ci * RETURNS: 268c2ecf20Sopenharmony_ci * 278c2ecf20Sopenharmony_ci * 0 on success or negative error codes in case of failure. 288c2ecf20Sopenharmony_ci */ 298c2ecf20Sopenharmony_ci int (*commit)(struct exynos_drm_ipp *ipp, 308c2ecf20Sopenharmony_ci struct exynos_drm_ipp_task *task); 318c2ecf20Sopenharmony_ci 328c2ecf20Sopenharmony_ci /** 338c2ecf20Sopenharmony_ci * @abort: 348c2ecf20Sopenharmony_ci * 358c2ecf20Sopenharmony_ci * Informs the driver that it has to abort the currently running 368c2ecf20Sopenharmony_ci * task as soon as possible (i.e. as soon as it can stop the device 378c2ecf20Sopenharmony_ci * safely), even if the task would not have been finished by then. 388c2ecf20Sopenharmony_ci * After the driver performs the necessary steps, it has to call 398c2ecf20Sopenharmony_ci * exynos_drm_ipp_task_done() (as if the task ended normally). 408c2ecf20Sopenharmony_ci * This function does not have to (and will usually not) wait 418c2ecf20Sopenharmony_ci * until the device enters a state when it can be stopped. 428c2ecf20Sopenharmony_ci */ 438c2ecf20Sopenharmony_ci void (*abort)(struct exynos_drm_ipp *ipp, 448c2ecf20Sopenharmony_ci struct exynos_drm_ipp_task *task); 458c2ecf20Sopenharmony_ci}; 468c2ecf20Sopenharmony_ci 478c2ecf20Sopenharmony_ci/** 488c2ecf20Sopenharmony_ci * struct exynos_drm_ipp - central picture processor module structure 498c2ecf20Sopenharmony_ci */ 508c2ecf20Sopenharmony_cistruct exynos_drm_ipp { 518c2ecf20Sopenharmony_ci struct drm_device *drm_dev; 528c2ecf20Sopenharmony_ci struct device *dev; 538c2ecf20Sopenharmony_ci struct list_head head; 548c2ecf20Sopenharmony_ci unsigned int id; 558c2ecf20Sopenharmony_ci 568c2ecf20Sopenharmony_ci const char *name; 578c2ecf20Sopenharmony_ci const struct exynos_drm_ipp_funcs *funcs; 588c2ecf20Sopenharmony_ci unsigned int capabilities; 598c2ecf20Sopenharmony_ci const struct exynos_drm_ipp_formats *formats; 608c2ecf20Sopenharmony_ci unsigned int num_formats; 618c2ecf20Sopenharmony_ci atomic_t sequence; 628c2ecf20Sopenharmony_ci 638c2ecf20Sopenharmony_ci spinlock_t lock; 648c2ecf20Sopenharmony_ci struct exynos_drm_ipp_task *task; 658c2ecf20Sopenharmony_ci struct list_head todo_list; 668c2ecf20Sopenharmony_ci wait_queue_head_t done_wq; 678c2ecf20Sopenharmony_ci}; 688c2ecf20Sopenharmony_ci 698c2ecf20Sopenharmony_cistruct exynos_drm_ipp_buffer { 708c2ecf20Sopenharmony_ci struct drm_exynos_ipp_task_buffer buf; 718c2ecf20Sopenharmony_ci struct drm_exynos_ipp_task_rect rect; 728c2ecf20Sopenharmony_ci 738c2ecf20Sopenharmony_ci struct exynos_drm_gem *exynos_gem[MAX_FB_BUFFER]; 748c2ecf20Sopenharmony_ci const struct drm_format_info *format; 758c2ecf20Sopenharmony_ci dma_addr_t dma_addr[MAX_FB_BUFFER]; 768c2ecf20Sopenharmony_ci}; 778c2ecf20Sopenharmony_ci 788c2ecf20Sopenharmony_ci/** 798c2ecf20Sopenharmony_ci * struct exynos_drm_ipp_task - a structure describing transformation that 808c2ecf20Sopenharmony_ci * has to be performed by the picture processor hardware module 818c2ecf20Sopenharmony_ci */ 828c2ecf20Sopenharmony_cistruct exynos_drm_ipp_task { 838c2ecf20Sopenharmony_ci struct device *dev; 848c2ecf20Sopenharmony_ci struct exynos_drm_ipp *ipp; 858c2ecf20Sopenharmony_ci struct list_head head; 868c2ecf20Sopenharmony_ci 878c2ecf20Sopenharmony_ci struct exynos_drm_ipp_buffer src; 888c2ecf20Sopenharmony_ci struct exynos_drm_ipp_buffer dst; 898c2ecf20Sopenharmony_ci 908c2ecf20Sopenharmony_ci struct drm_exynos_ipp_task_transform transform; 918c2ecf20Sopenharmony_ci struct drm_exynos_ipp_task_alpha alpha; 928c2ecf20Sopenharmony_ci 938c2ecf20Sopenharmony_ci struct work_struct cleanup_work; 948c2ecf20Sopenharmony_ci unsigned int flags; 958c2ecf20Sopenharmony_ci int ret; 968c2ecf20Sopenharmony_ci 978c2ecf20Sopenharmony_ci struct drm_pending_exynos_ipp_event *event; 988c2ecf20Sopenharmony_ci}; 998c2ecf20Sopenharmony_ci 1008c2ecf20Sopenharmony_ci#define DRM_EXYNOS_IPP_TASK_DONE (1 << 0) 1018c2ecf20Sopenharmony_ci#define DRM_EXYNOS_IPP_TASK_ASYNC (1 << 1) 1028c2ecf20Sopenharmony_ci 1038c2ecf20Sopenharmony_cistruct exynos_drm_ipp_formats { 1048c2ecf20Sopenharmony_ci uint32_t fourcc; 1058c2ecf20Sopenharmony_ci uint32_t type; 1068c2ecf20Sopenharmony_ci uint64_t modifier; 1078c2ecf20Sopenharmony_ci const struct drm_exynos_ipp_limit *limits; 1088c2ecf20Sopenharmony_ci unsigned int num_limits; 1098c2ecf20Sopenharmony_ci}; 1108c2ecf20Sopenharmony_ci 1118c2ecf20Sopenharmony_ci/* helper macros to set exynos_drm_ipp_formats structure and limits*/ 1128c2ecf20Sopenharmony_ci#define IPP_SRCDST_MFORMAT(f, m, l) \ 1138c2ecf20Sopenharmony_ci .fourcc = DRM_FORMAT_##f, .modifier = m, .limits = l, \ 1148c2ecf20Sopenharmony_ci .num_limits = ARRAY_SIZE(l), \ 1158c2ecf20Sopenharmony_ci .type = (DRM_EXYNOS_IPP_FORMAT_SOURCE | \ 1168c2ecf20Sopenharmony_ci DRM_EXYNOS_IPP_FORMAT_DESTINATION) 1178c2ecf20Sopenharmony_ci 1188c2ecf20Sopenharmony_ci#define IPP_SRCDST_FORMAT(f, l) IPP_SRCDST_MFORMAT(f, 0, l) 1198c2ecf20Sopenharmony_ci 1208c2ecf20Sopenharmony_ci#define IPP_SIZE_LIMIT(l, val...) \ 1218c2ecf20Sopenharmony_ci .type = (DRM_EXYNOS_IPP_LIMIT_TYPE_SIZE | \ 1228c2ecf20Sopenharmony_ci DRM_EXYNOS_IPP_LIMIT_SIZE_##l), val 1238c2ecf20Sopenharmony_ci 1248c2ecf20Sopenharmony_ci#define IPP_SCALE_LIMIT(val...) \ 1258c2ecf20Sopenharmony_ci .type = (DRM_EXYNOS_IPP_LIMIT_TYPE_SCALE), val 1268c2ecf20Sopenharmony_ci 1278c2ecf20Sopenharmony_ciint exynos_drm_ipp_register(struct device *dev, struct exynos_drm_ipp *ipp, 1288c2ecf20Sopenharmony_ci const struct exynos_drm_ipp_funcs *funcs, unsigned int caps, 1298c2ecf20Sopenharmony_ci const struct exynos_drm_ipp_formats *formats, 1308c2ecf20Sopenharmony_ci unsigned int num_formats, const char *name); 1318c2ecf20Sopenharmony_civoid exynos_drm_ipp_unregister(struct device *dev, 1328c2ecf20Sopenharmony_ci struct exynos_drm_ipp *ipp); 1338c2ecf20Sopenharmony_ci 1348c2ecf20Sopenharmony_civoid exynos_drm_ipp_task_done(struct exynos_drm_ipp_task *task, int ret); 1358c2ecf20Sopenharmony_ci 1368c2ecf20Sopenharmony_ci#ifdef CONFIG_DRM_EXYNOS_IPP 1378c2ecf20Sopenharmony_ciint exynos_drm_ipp_get_res_ioctl(struct drm_device *dev, void *data, 1388c2ecf20Sopenharmony_ci struct drm_file *file_priv); 1398c2ecf20Sopenharmony_ciint exynos_drm_ipp_get_caps_ioctl(struct drm_device *dev, void *data, 1408c2ecf20Sopenharmony_ci struct drm_file *file_priv); 1418c2ecf20Sopenharmony_ciint exynos_drm_ipp_get_limits_ioctl(struct drm_device *dev, void *data, 1428c2ecf20Sopenharmony_ci struct drm_file *file_priv); 1438c2ecf20Sopenharmony_ciint exynos_drm_ipp_commit_ioctl(struct drm_device *dev, 1448c2ecf20Sopenharmony_ci void *data, struct drm_file *file_priv); 1458c2ecf20Sopenharmony_ci#else 1468c2ecf20Sopenharmony_cistatic inline int exynos_drm_ipp_get_res_ioctl(struct drm_device *dev, 1478c2ecf20Sopenharmony_ci void *data, struct drm_file *file_priv) 1488c2ecf20Sopenharmony_ci{ 1498c2ecf20Sopenharmony_ci struct drm_exynos_ioctl_ipp_get_res *resp = data; 1508c2ecf20Sopenharmony_ci 1518c2ecf20Sopenharmony_ci resp->count_ipps = 0; 1528c2ecf20Sopenharmony_ci return 0; 1538c2ecf20Sopenharmony_ci} 1548c2ecf20Sopenharmony_cistatic inline int exynos_drm_ipp_get_caps_ioctl(struct drm_device *dev, 1558c2ecf20Sopenharmony_ci void *data, struct drm_file *file_priv) 1568c2ecf20Sopenharmony_ci{ 1578c2ecf20Sopenharmony_ci return -ENODEV; 1588c2ecf20Sopenharmony_ci} 1598c2ecf20Sopenharmony_cistatic inline int exynos_drm_ipp_get_limits_ioctl(struct drm_device *dev, 1608c2ecf20Sopenharmony_ci void *data, struct drm_file *file_priv) 1618c2ecf20Sopenharmony_ci{ 1628c2ecf20Sopenharmony_ci return -ENODEV; 1638c2ecf20Sopenharmony_ci} 1648c2ecf20Sopenharmony_cistatic inline int exynos_drm_ipp_commit_ioctl(struct drm_device *dev, 1658c2ecf20Sopenharmony_ci void *data, struct drm_file *file_priv) 1668c2ecf20Sopenharmony_ci{ 1678c2ecf20Sopenharmony_ci return -ENODEV; 1688c2ecf20Sopenharmony_ci} 1698c2ecf20Sopenharmony_ci#endif 1708c2ecf20Sopenharmony_ci#endif 171