This patch adds Exynos IPP v2 subsystem and userspace API.
New userspace API is focused ONLY on memory-to-memory image processing.
The two remainging operation modes of obsolete IPP v1 API (framebuffer
writeback and local-path output with image processing) can be implemented
using standard DRM features: writeback connectors and additional DRM planes
with scaling features.
V2 IPP userspace API is based on stateless approach, which much better fits
to memory-to-memory image processing model. It also provides support for
all image formats, which are both already defined in DRM API and supported
by the existing IPP hardware modules.
The API consists of the following ioctls:
- DRM_IOCTL_EXYNOS_IPP_GET_RESOURCES: to enumerate all available image
processing modules,
- DRM_IOCTL_EXYNOS_IPP_GET_CAPS: to query capabilities and supported image
formats of given IPP module,
- DRM_IOCTL_EXYNOS_IPP_GET_LIMITS: to query hardware limitiations for
selected image format of given IPP module,
- DRM_IOCTL_EXYNOS_IPP_COMMIT: to perform operation described by the
provided structures (source and destination buffers, operation rectangle,
transformation, etc).
The proposed userspace API is extensible. In the future more advanced image
processing operations can be defined to support for example blending.
Userspace API is fully functional also on DRM render nodes, so it is not
limited to the root/privileged client.
Internal driver API also has been completely rewritten. New IPP core
performs all possible input validation, checks and object life-time
control. The drivers can focus only on writing configuration to hardware
registers. Stateless nature of DRM_IOCTL_EXYNOS_IPP_COMMIT ioctl simplifies
the driver API. Minimal driver needs to provide a single callback for
starting processing and an array with supported image formats.
Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
Tested-by: Hoegeun Kwon <hoegeun.kwon@samsung.com>
Merge conflict so merged manually.
Signed-off-by: Inki Dae <inki.dae@samsung.com>
Exynos DRM IPP subsystem is in fact non-functional and frankly speaking
dead-code. This patch clearly marks that Exynos DRM IPP subsystem is
broken and never really functional. It will be replaced by a completely
rewritten API.
Exynos DRM IPP user-space API can be obsoleted for the following
reasons:
1. Exynos DRM IPP user-space API can be optional in Exynos DRM, so
userspace should not rely that it is always available and should have
a software fallback in case it is not there.
2. The only mode which was initially semi-working was memory-to-memory
image processing. The remaining modes (LCD-"writeback" and "output")
were never operational due to missing code (both in mainline and even
vendor kernels).
3. Exynos DRM IPP mainline user-space API compatibility for
memory-to-memory got broken very early by commit 083500baef ("drm:
remove DRM_FORMAT_NV12MT", which removed the support for tiled formats,
the main feature which made this API somehow useful on Exynos platforms
(video codec that time produced only tiled frames, to implement xvideo
or any other video overlay, one has to de-tile them for proper
display).
4. Broken drivers. Especially once support for IOMMU has been added,
it revealed that drivers don't configure DMA operations properly and in
many cases operate outside the provided buffers trashing memory around.
5. Need for external patches. Although IPP user-space API has been used
in some vendor kernels, but in such cases there were additional patches
applied (like reverting mentioned 083500baef patch) what means that
those userspace apps which might use it, still won't work with the
mainline kernel version.
We don't have time machines, so we cannot change it, but Exynos DRM IPP
extension should never have been merged to mainline in that form.
Exynos IPP subsystem and user-space API will be rewritten, so remove
current IPP core code and mark existing drivers as BROKEN.
Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
Acked-by: Daniel Stone <daniels@collabora.com>
Acked-by: Krzysztof Kozlowski <krzk@kernel.org>
Signed-off-by: Inki Dae <inki.dae@samsung.com>
Many user space API headers have licensing information, which is either
incomplete, badly formatted or just a shorthand for referring to the
license under which the file is supposed to be. This makes it hard for
compliance tools to determine the correct license.
Update these files with an SPDX license identifier. The identifier was
chosen based on the license information in the file.
GPL/LGPL licensed headers get the matching GPL/LGPL SPDX license
identifier with the added 'WITH Linux-syscall-note' exception, which is
the officially assigned exception identifier for the kernel syscall
exception:
NOTE! This copyright does *not* cover user programs that use kernel
services by normal system calls - this is merely considered normal use
of the kernel, and does *not* fall under the heading of "derived work".
This exception makes it possible to include GPL headers into non GPL
code, without confusing license compliance tools.
Headers which have either explicit dual licensing or are just licensed
under a non GPL license are updated with the corresponding SPDX
identifier and the GPLv2 with syscall exception identifier. The format
is:
((GPL-2.0 WITH Linux-syscall-note) OR SPDX-ID-OF-OTHER-LICENSE)
SPDX license identifiers are a legally binding shorthand, which can be
used instead of the full boiler plate text. The update does not remove
existing license information as this has to be done on a case by case
basis and the copyright holders might have to be consulted. This will
happen in a separate step.
This patch is based on work done by Thomas Gleixner and Kate Stewart and
Philippe Ombredanne. See the previous patch in this series for the
methodology of how this patch was researched.
Reviewed-by: Kate Stewart <kstewart@linuxfoundation.org>
Reviewed-by: Philippe Ombredanne <pombredanne@nexb.com>
Reviewed-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
The commit d931589c01 ("drm/exynos: remove DRM_EXYNOS_GEM_MAP_OFFSET
ioctl") removed it same with the ioctl that this patch adds. The reason
that removed DRM_EXYNOS_GEM_MAP_OFFSET was we could use
DRM_IOCTL_MODE_MAP_DUMB. Both did exactly same thing.
Now we again will revive it as DRM_EXYNOS_GEM_MAP because of render
node. DRM_IOCTL_MODE_MAP_DUMB isn't permitted in render node.
Signed-off-by: Joonyoung Shim <jy0922.shim@samsung.com>
Signed-off-by: Inki Dae <inki.dae@samsung.com>
User API structs should not use types which size/alignment/padding depends
on architecture. The patch fixes it for all structures except
drm_exynos_g2d_userptr, as g2d related stuff seems to be more complicated
and will be reviewed/adjusted later.
Signed-off-by: Andrzej Hajda <a.hajda@samsung.com>
Reviewed-by: Emil Velikov <emil.l.velikov@gmail.com>
Signed-off-by: Inki Dae <inki.dae@samsung.com>
Using `#include "drm.h"` instead of `#include <drm/drm.h>` allow drm
headers to be moved in another directory without changes, like for the
libdrm imports.
Signed-off-by: Gabriel Laskar <gabriel@lse.epita.fr>
Reviewed-by: Emil Velikov <emil.l.velikov@gmail.com>
CC: Emil Velikov <emil.l.velikov@gmail.com>
CC: Mikko Rapeli <mikko.rapeli@iki.fi>
This patch removes DRM_EXYNOS_GEM_MMAP ictrl feature specific
to Exynos drm and instead uses drm generic mmap.
We had used the interface specific to Exynos drm to do mmap directly,
not to use demand paging which maps each page with physical memory
at page fault handler. We don't need the specific mmap interface
because the drm generic mmap which uses vm offset manager stuff can
also do mmap directly.
This patch makes a userspace region to be mapped with whole physical
memory region allocated by userspace request when mmap system call is
requested.
Changelog v2:
- do not set VM_IO, VM_DONTEXPEND and VM_DONTDUMP. These flags were already
set by drm_gem_mmap
- do not include <linux/anon_inodes.h>, which isn't needed anymore.
Signed-off-by: Inki Dae <inki.dae@samsung.com>
This patch considers both case of vflip and hflip.
If we want that the contents in buffer to be rotated to 180 degree,
then we can use h,vflip or 180 degree.
Changelog v2:
- added EXYNOS_DRM_FLIP_BOTH enum value to avoid build warnning.
Signed-off-by: Eunchul Kim <chulspro.kim@samsung.com>
Signed-off-by: Inki Dae <inki.dae@samsung.com>
This patch changes file license to GPL
Most of exynos files had been copied from some random
file and not updated correctly. So this patch corrects
the file license.
Signed-off-by: Inki Dae <inki.dae@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
This patch adds Image Post Processing(IPP) support for exynos drm driver.
IPP supports image scaler/rotator and input/output DMA operations
using IPP subsystem framework to control FIMC, Rotator and GSC hardware
and supports some user interfaces for user side.
And each IPP-based drivers support Memory to Memory operations
with various converting. And in case of FIMC hardware, it also supports
Writeback and Display output operations through local path.
Features:
- Memory to Memory operation support.
- Various pixel formats support.
- Image scaling support.
- Color Space Conversion support.
- Image crop operation support.
- Rotate operation support to 90, 180 or 270 degree.
- Flip operation support to vertical, horizontal or both.
- Writeback operation support to display blended image of FIMD fifo on screen
A summary to IPP Subsystem operations:
First of all, user should get property capabilities from IPP subsystem
and set these properties to hardware registers for desired operations.
The properties could be pixel format, position, rotation degree and
flip operation.
And next, user should set source and destination buffer data using
DRM_EXYNOS_IPP_QUEUE_BUF ioctl command with gem handles to source and
destinition buffers.
And next, user can control user-desired hardware with desired operations
such as play, stop, pause and resume controls.
And finally, user can aware of dma operation completion and also get
destination buffer that it contains user-desried result through dequeue
command.
IOCTL commands:
- DRM_EXYNOS_IPP_GET_PROPERTY
. get ipp driver capabilitis and id.
- DRM_EXYNOS_IPP_SET_PROPERTY
. set format, position, rotation, flip to source and destination buffers
- DRM_EXYNOS_IPP_QUEUE_BUF
. enqueue/dequeue buffer and make event list.
- DRM_EXYNOS_IPP_CMD_CTRL
. play/stop/pause/resume control.
Event:
- DRM_EXYNOS_IPP_EVENT
. a event to notify dma operation completion to user side.
Basic control flow:
Open -> Get properties -> User choose desired IPP sub driver(FIMC, Rotator
or GSCALER) -> Set Property -> Create gem handle -> Enqueue to source and
destination buffers -> Command control(Play) -> Event is notified to User
-> User gets destinition buffer complated -> (Enqueue to source and
destination buffers -> Event is notified to User) * N -> Queue/Dequeue to
source and destination buffers -> Command control(Stop) -> Free gem handle
-> Close
Changelog v1 ~ v5:
- added comments, code fixups and cleanups.
Signed-off-by: Eunchul Kim <chulspro.kim@samsung.com>
Signed-off-by: Jinyoung Jeon <jy0.jeon@samsung.com>
Signed-off-by: Inki Dae <inki.dae@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
This patch adds userptr feautre for G2D module.
The userptr means user space address allocated by malloc().
And the purpose of this feature is to make G2D's dma able
to access the user space region.
To user this feature, user should flag G2D_BUF_USRPTR to
offset variable of struct drm_exynos_g2d_cmd and fill
struct drm_exynos_g2d_userptr with user space address
and size for it and then should set a pointer to
drm_exynos_g2d_userptr object to data variable of struct
drm_exynos_g2d_cmd. The last bit of offset variable is used
to check if the cmdlist's buffer type is userptr or not.
If userptr, the g2d driver gets user space address and size
and then gets pages through get_user_pages().
(another case is counted as gem handle)
Below is sample codes:
static void set_cmd(struct drm_exynos_g2d_cmd *cmd,
unsigned long offset, unsigned long data)
{
cmd->offset = offset;
cmd->data = data;
}
static int solid_fill_test(int x, int y, unsigned long userptr)
{
struct drm_exynos_g2d_cmd cmd_gem[5];
struct drm_exynos_g2d_userptr g2d_userptr;
unsigned int gem_nr = 0;
...
g2d_userptr.userptr = userptr;
g2d_userptr.size = x * y * 4;
set_cmd(&cmd_gem[gem_nr++], DST_BASE_ADDR_REG |
G2D_BUF_USERPTR,
(unsigned long)&g2d_userptr);
...
}
int main(int argc, char **argv)
{
unsigned long addr;
...
addr = malloc(x * y * 4);
...
solid_fill_test(x, y, addr);
...
}
And next, the pages are mapped with iommu table and the device
address is set to cmdlist so that G2D's dma can access it.
As you may know, the pages from get_user_pages() are pinned.
In other words, they CAN NOT be migrated and also swapped out.
So the dma access would be safe.
But the use of userptr feature has performance overhead so
this patch also has memory pool to the userptr feature.
Please, assume that user sends cmdlist filled with userptr
and size every time to g2d driver, and the get_user_pages
funcion will be called every time.
The memory pool has maximum 64MB size and the userptr that
user had ever sent, is holded in the memory pool.
This meaning is that if the userptr from user is same as one
in the memory pool, device address to the userptr in the memory
pool is set to cmdlist.
And last, the pages from get_user_pages() will be freed once
user calls free() and the dma access is completed. Actually,
get_user_pages() takes 2 reference counts if the user process
has never accessed user region allocated by malloc(). Then, if
the user calls free(), the page reference count becomes 1 and
becomes 0 with put_page() call. And the reverse holds as well.
This means how the pages backed are used by dma and freed.
This patch is based on "drm/exynos: add iommu support for g2d",
https://patchwork.kernel.org/patch/1629481/
Signed-off-by: Inki Dae <inki.dae@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
Signed-off-by: David Howells <dhowells@redhat.com>
Acked-by: Arnd Bergmann <arnd@arndb.de>
Acked-by: Thomas Gleixner <tglx@linutronix.de>
Acked-by: Michael Kerrisk <mtk.manpages@gmail.com>
Acked-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
Acked-by: Dave Jones <davej@redhat.com>