diff --git a/include/grabber/AmlogicGrabber.h b/include/grabber/AmlogicGrabber.h index 5b74840a..19778899 100755 --- a/include/grabber/AmlogicGrabber.h +++ b/include/grabber/AmlogicGrabber.h @@ -2,9 +2,11 @@ // Utils includes #include +#include #include #include +class IonBuffer; /// /// @@ -37,13 +39,16 @@ private: * @return True if video is playing else false */ bool isVideoPlaying(); - int grabFrame_amvideocap(Image & image); void closeDev(int &fd); - bool openDev(int &fd, const char* dev, int flags); + bool openDev(int &fd, const char* dev); + + int grabFrame_amvideocap(Image & image); + int grabFrame_ge2d(Image & image); /** The snapshot/capture device of the amlogic video chip */ int _captureDev; int _videoDev; + int _ge2dDev; Image _image_bgr; @@ -51,4 +56,7 @@ private: bool _videoPlaying; FramebufferFrameGrabber _fbGrabber; int _grabbingModeNotification; + bool _ge2dAvailable; + void* _ge2dVideoBufferPtr; + IonBuffer* _ge2dIonBuffer; }; diff --git a/libsrc/grabber/amlogic/AmlogicGrabber.cpp b/libsrc/grabber/amlogic/AmlogicGrabber.cpp index 321bd423..90d76a85 100755 --- a/libsrc/grabber/amlogic/AmlogicGrabber.cpp +++ b/libsrc/grabber/amlogic/AmlogicGrabber.cpp @@ -19,15 +19,19 @@ #define VIDEO_DEVICE "/dev/amvideo" #define CAPTURE_DEVICE "/dev/amvideocap0" -#include +#define GE2D_DEVICE "/dev/ge2d" AmlogicGrabber::AmlogicGrabber(const unsigned width, const unsigned height) : Grabber("AMLOGICGRABBER", qMax(160u, width), qMax(160u, height)) // Minimum required width or height is 160 , _captureDev(-1) , _videoDev(-1) + , _ge2dDev(-1) , _lastError(0) , _fbGrabber("/dev/fb0",width,height) , _grabbingModeNotification(0) + , _ge2dAvailable(true) + , _ge2dVideoBufferPtr(nullptr) + , _ge2dIonBuffer(nullptr) { Debug(_log, "constructed(%d x %d)",_width,_height); } @@ -36,13 +40,14 @@ AmlogicGrabber::~AmlogicGrabber() { closeDev(_captureDev); closeDev(_videoDev); + closeDev(_ge2dDev); } -bool AmlogicGrabber::openDev(int &fd, const char* dev, int flags) +bool AmlogicGrabber::openDev(int &fd, const char* dev) { if (fd<0) { - fd = open(dev, flags); + fd = open(dev, O_RDWR); } return fd >= 0; } @@ -61,7 +66,7 @@ bool AmlogicGrabber::isVideoPlaying() if(!QFile::exists(VIDEO_DEVICE)) return false; int videoDisabled = 1; - if (!openDev(_videoDev, VIDEO_DEVICE, O_RDWR)) + if (!openDev(_videoDev, VIDEO_DEVICE)) { Error(_log, "Failed to open video device(%s): %d - %s", VIDEO_DEVICE, errno, strerror(errno)); return false; @@ -95,7 +100,25 @@ int AmlogicGrabber::grabFrame(Image & image) _lastError = 0; } - if (QFile::exists(CAPTURE_DEVICE)) + if (_ge2dAvailable) + { + try + { + _ge2dAvailable = (QFile::exists(GE2D_DEVICE) && grabFrame_ge2d(image) == 0); + } + catch (...) + { + _ge2dAvailable = false; + } + + if (!_ge2dAvailable) + { + closeDev(_videoDev); + closeDev(_ge2dDev); + Warning(_log, "GE2D capture interface not available! try Amvideocap instead"); + } + } + else if (QFile::exists(CAPTURE_DEVICE)) { grabFrame_amvideocap(image); } @@ -120,7 +143,7 @@ int AmlogicGrabber::grabFrame(Image & image) int AmlogicGrabber::grabFrame_amvideocap(Image & image) { // If the device is not open, attempt to open it - if (! openDev(_captureDev, CAPTURE_DEVICE, O_RDWR)) + if (! openDev(_captureDev, CAPTURE_DEVICE)) { ErrorIf( _lastError != 1, _log,"Failed to open the AMLOGIC device (%d - %s):", errno, strerror(errno)); _lastError = 1; @@ -161,11 +184,142 @@ int AmlogicGrabber::grabFrame_amvideocap(Image & image) } closeDev(_captureDev); - + _useImageResampler = true; _imageResampler.processImage((const uint8_t*)image_ptr, _width, _height, _width*3, PIXELFORMAT_BGR24, image); - _lastError = 0; return 0; } + +int AmlogicGrabber::grabFrame_ge2d(Image & image) +{ + if ( ! openDev(_ge2dDev, GE2D_DEVICE) || ! openDev(_videoDev, VIDEO_DEVICE)) + { + Error(_log, "cannot open devices"); + return -1; + } + + // Ion + if (_ge2dIonBuffer == nullptr) + { + _ge2dIonBuffer = new IonBuffer(_width * _height * 3); // BGR + _ge2dVideoBufferPtr = _ge2dIonBuffer->Map(); + memset(_ge2dVideoBufferPtr, 0, _ge2dIonBuffer->BufferSize()); + } + + int canvas_index; + if (ioctl(_videoDev, AMVIDEO_EXT_GET_CURRENT_VIDEOFRAME, &canvas_index) < 0) + { + Error(_log, "AMSTREAM_EXT_GET_CURRENT_VIDEOFRAME failed."); + return -1; + } + + uint32_t canvas0addr; + + if (ioctl(_videoDev, AMVIDEO_EXT_CURRENT_VIDEOFRAME_GET_CANVAS0ADDR, &canvas0addr) < 0) + { + Error(_log, "AMSTREAM_EXT_CURRENT_VIDEOFRAME_GET_CANVAS0ADDR failed."); + return -1; + } + + uint32_t ge2dformat; + if (ioctl(_videoDev, AMVIDEO_EXT_CURRENT_VIDEOFRAME_GET_GE2D_FORMAT, &ge2dformat) <0) + { + Error(_log, "AMSTREAM_EXT_CURRENT_VIDEOFRAME_GET_GE2D_FORMAT failed."); + return -1; + } + + uint64_t size; + if (ioctl(_videoDev, AMVIDEO_EXT_CURRENT_VIDEOFRAME_GET_SIZE, &size) < 0) + { + Error(_log, "AMSTREAM_EXT_CURRENT_VIDEOFRAME_GET_SIZE failed."); + return -1; + } + + unsigned cropLeft = _cropLeft; + unsigned cropRight = _cropRight; + unsigned cropTop = _cropTop; + unsigned cropBottom = _cropBottom; + int videoWidth = (size >> 32) - cropLeft - cropRight; + int videoHeight = (size & 0xffffff) - cropTop - cropBottom; + + // calculate final image dimensions and adjust top/left cropping in 3D modes + switch (_videoMode) + { + case VIDEO_3DSBS: + videoWidth /= 2; + cropLeft /= 2; + break; + case VIDEO_3DTAB: + videoHeight /= 2; + cropTop /= 2; + break; + case VIDEO_2D: + default: + break; + } + + struct config_para_ex_s configex = { 0 }; + configex.src_para.mem_type = CANVAS_TYPE_INVALID; + configex.src_para.canvas_index = canvas0addr; + configex.src_para.left = cropLeft; + configex.src_para.top = cropTop; + configex.src_para.width = videoWidth; + configex.src_para.height = videoHeight / 2; + configex.src_para.format = ge2dformat; + + configex.dst_para.mem_type = CANVAS_ALLOC; + configex.dst_para.format = GE2D_FORMAT_S24_RGB; + configex.dst_para.left = 0; + configex.dst_para.top = 0; + configex.dst_para.width = _width; + configex.dst_para.height = _height; + + configex.dst_planes[0].addr = (long unsigned int)_ge2dIonBuffer->PhysicalAddress(); + configex.dst_planes[0].w = configex.dst_para.width; + configex.dst_planes[0].h = configex.dst_para.height; + + if (ioctl(_ge2dDev, GE2D_CONFIG_EX, &configex) < 0) + { + Error(_log, "video GE2D_CONFIG_EX failed."); + return -1; + } + + ge2d_para_s blitRect = { 0 }; + blitRect.src1_rect.x = 0; + blitRect.src1_rect.y = 0; + blitRect.src1_rect.w = configex.src_para.width; + blitRect.src1_rect.h = configex.src_para.height; + + blitRect.dst_rect.x = 0; + blitRect.dst_rect.y = 0; + blitRect.dst_rect.w = configex.dst_para.width ; + blitRect.dst_rect.h = configex.dst_para.height; + + // Blit to videoBuffer + if (ioctl(_ge2dDev, GE2D_STRETCHBLIT_NOALPHA, &blitRect) < 0) + { + Error(_log,"GE2D_STRETCHBLIT_NOALPHA failed."); + return -1; + } + + // Return video frame + if (ioctl(_videoDev, AMVIDEO_EXT_PUT_CURRENT_VIDEOFRAME) < 0) + { + Error(_log, "AMSTREAM_EXT_PUT_CURRENT_VIDEOFRAME failed."); + return -1; + } + + _ge2dIonBuffer->Sync(); + + // Read the snapshot into the memory + _useImageResampler = false; + _imageResampler.processImage((const uint8_t*)_ge2dVideoBufferPtr, _width, _height, _width*3, PIXELFORMAT_BGR24, image); + + closeDev(_videoDev); + closeDev(_ge2dDev); + + return 0; +} + diff --git a/libsrc/grabber/amlogic/Amvideocap.h b/libsrc/grabber/amlogic/Amvideocap.h index 577b843c..ad1a89ee 100644 --- a/libsrc/grabber/amlogic/Amvideocap.h +++ b/libsrc/grabber/amlogic/Amvideocap.h @@ -1,7 +1,10 @@ #pragma once #include -//#include +// #include +#include "ion.h" +#include "meson_ion.h" +#include "IonBuffer.h" #define AMVIDEOCAP_IOC_MAGIC 'V' #define CAP_FLAG_AT_CURRENT 0 @@ -22,59 +25,154 @@ GE2D_FORMAT_S24_RGB #define GE2D_FORMAT_S24_BGR (GE2D_FMT_S24_RGB | GE2D_COLOR_MAP_BGR888) #define GE2D_FORMAT_S24_RGB (GE2D_FMT_S24_RGB | GE2D_COLOR_MAP_RGB888) -#define AMVIDEOCAP_IOW_SET_WANTFRAME_FORMAT _IOW(AMVIDEOCAP_IOC_MAGIC, 0x01, int) +// #define AMVIDEOCAP_IOW_SET_WANTFRAME_FORMAT _IOW(AMVIDEOCAP_IOC_MAGIC, 0x01, int) #define AMVIDEOCAP_IOW_SET_WANTFRAME_WIDTH _IOW(AMVIDEOCAP_IOC_MAGIC, 0x02, int) #define AMVIDEOCAP_IOW_SET_WANTFRAME_HEIGHT _IOW(AMVIDEOCAP_IOC_MAGIC, 0x03, int) -#define AMVIDEOCAP_IOW_SET_WANTFRAME_TIMESTAMP_MS _IOW(AMVIDEOCAP_IOC_MAGIC, 0x04, unsigned long) -#define AMVIDEOCAP_IOW_SET_WANTFRAME_WAIT_MAX_MS _IOW(AMVIDEOCAP_IOC_MAGIC, 0x05, unsigned long) -#define AMVIDEOCAP_IOW_SET_WANTFRAME_AT_FLAGS _IOW(AMVIDEOCAP_IOC_MAGIC, 0x06, int) - - -#define AMVIDEOCAP_IOR_GET_FRAME_FORMAT _IOR(AMVIDEOCAP_IOC_MAGIC, 0x10, int) -#define AMVIDEOCAP_IOR_GET_FRAME_WIDTH _IOR(AMVIDEOCAP_IOC_MAGIC, 0x11, int) -#define AMVIDEOCAP_IOR_GET_FRAME_HEIGHT _IOR(AMVIDEOCAP_IOC_MAGIC, 0x12, int) -#define AMVIDEOCAP_IOR_GET_FRAME_TIMESTAMP_MS _IOR(AMVIDEOCAP_IOC_MAGIC, 0x13, unsigned long) - - -#define AMVIDEOCAP_IOR_GET_SRCFRAME_FORMAT _IOR(AMVIDEOCAP_IOC_MAGIC, 0x20, int) -#define AMVIDEOCAP_IOR_GET_SRCFRAME_WIDTH _IOR(AMVIDEOCAP_IOC_MAGIC, 0x21, int) -#define AMVIDEOCAP_IOR_GET_SRCFRAME_HEIGHT _IOR(AMVIDEOCAP_IOC_MAGIC, 0x22, int) - - -#define AMVIDEOCAP_IOR_GET_STATE _IOR(AMVIDEOCAP_IOC_MAGIC, 0x31, int) -#define AMVIDEOCAP_IOW_SET_START_CAPTURE _IOW(AMVIDEOCAP_IOC_MAGIC, 0x32, int) -#define AMVIDEOCAP_IOW_SET_CANCEL_CAPTURE _IOW(AMVIDEOCAP_IOC_MAGIC, 0x33, int) - -#define AMVIDEOCAP_IOR_SET_SRC_X _IOR(AMVIDEOCAP_IOC_MAGIC, 0x40, int) -#define AMVIDEOCAP_IOR_SET_SRC_Y _IOR(AMVIDEOCAP_IOC_MAGIC, 0x41, int) -#define AMVIDEOCAP_IOR_SET_SRC_WIDTH _IOR(AMVIDEOCAP_IOC_MAGIC, 0x42, int) -#define AMVIDEOCAP_IOR_SET_SRC_HEIGHT _IOR(AMVIDEOCAP_IOC_MAGIC, 0x43, int) - -enum amvideocap_state{ - AMVIDEOCAP_STATE_INIT=0, - AMVIDEOCAP_STATE_ON_CAPTURE=200, - AMVIDEOCAP_STATE_FINISHED_CAPTURE=300, - AMVIDEOCAP_STATE_ERROR=0xffff, -}; +#define _A_M 'S' +#define AMSTREAM_IOC_GET_VIDEO_DISABLE _IOR((_A_M), 0x48, int) #define AMVIDEO_MAGIC 'X' -#define AMVIDEO_EXT_GET_CURRENT_VIDEOFRAME _IOR((AMVIDEO_MAGIC), 0x01, int32_t) +#define AMVIDEO_EXT_GET_CURRENT_VIDEOFRAME _IOR((AMVIDEO_MAGIC), 0x01, int) #define AMVIDEO_EXT_PUT_CURRENT_VIDEOFRAME _IO((AMVIDEO_MAGIC), 0x02) #define AMVIDEO_EXT_CURRENT_VIDEOFRAME_GET_GE2D_FORMAT _IOR((AMVIDEO_MAGIC), 0x03, uint32_t) #define AMVIDEO_EXT_CURRENT_VIDEOFRAME_GET_SIZE _IOR((AMVIDEO_MAGIC), 0x04, uint64_t) #define AMVIDEO_EXT_CURRENT_VIDEOFRAME_GET_CANVAS0ADDR _IOR((AMVIDEO_MAGIC), 0x05, uint32_t) -#define _A_M 'S' -#define AMSTREAM_IOC_GET_VIDEO_DISABLE _IOR((_A_M), 0x48, int) -#define AMSTREAM_IOC_SET_VIDEO_DISABLE _IOW((_A_M), 0x49, int) -struct Rectangle -{ - int X; - int Y; - int Width; - int Height; +// GE2D commands +#define GE2D_STRETCHBLIT_NOALPHA 0x4702 +#define GE2D_CONFIG_EX 0x46fa + + +// data structures +struct rectangle_s { + int x; /* X coordinate of its top-left point */ + int y; /* Y coordinate of its top-left point */ + int w; /* width of it */ + int h; /* height of it */ }; +struct ge2d_para_s { + unsigned int color; + struct rectangle_s src1_rect; + struct rectangle_s src2_rect; + struct rectangle_s dst_rect; + int op; +}; + + +enum ge2d_src_dst_e { + OSD0_OSD0 = 0, + OSD0_OSD1, + OSD1_OSD1, + OSD1_OSD0, + ALLOC_OSD0, + ALLOC_OSD1, + ALLOC_ALLOC, + TYPE_INVALID, +}; + +enum ge2d_src_canvas_type_e { + CANVAS_OSD0 = 0, + CANVAS_OSD1, + CANVAS_ALLOC, + CANVAS_TYPE_INVALID, +}; + + +struct src_dst_para_s { + int xres; + int yres; + int canvas_index; + int bpp; + int ge2d_color_index; +}; + +enum ge2d_op_type_e { + GE2D_OP_DEFAULT = 0, + GE2D_OP_FILLRECT, + GE2D_OP_BLIT, + GE2D_OP_STRETCHBLIT, + GE2D_OP_BLEND, + GE2D_OP_MAXNUM +}; + +struct config_planes_s { + unsigned long addr; + unsigned int w; + unsigned int h; +}; + +struct src_key_ctrl_s { + int key_enable; + int key_color; + int key_mask; + int key_mode; +}; + +struct config_para_s { + int src_dst_type; + int alu_const_color; + unsigned int src_format; + unsigned int dst_format; /* add for src&dst all in user space. */ + + struct config_planes_s src_planes[4]; + struct config_planes_s dst_planes[4]; + struct src_key_ctrl_s src_key; +}; + +struct src_dst_para_ex_s { + int canvas_index; + int top; + int left; + int width; + int height; + int format; + int mem_type; + int color; + unsigned char x_rev; + unsigned char y_rev; + unsigned char fill_color_en; + unsigned char fill_mode; +}; + +struct config_para_ex_s { + struct src_dst_para_ex_s src_para; + struct src_dst_para_ex_s src2_para; + struct src_dst_para_ex_s dst_para; + + /* key mask */ + struct src_key_ctrl_s src_key; + struct src_key_ctrl_s src2_key; + + int alu_const_color; + unsigned src1_gb_alpha; + unsigned op_mode; + unsigned char bitmask_en; + unsigned char bytemask_only; + unsigned int bitmask; + unsigned char dst_xy_swap; + + /* scaler and phase releated */ + unsigned hf_init_phase; + int hf_rpt_num; + unsigned hsc_start_phase_step; + int hsc_phase_slope; + unsigned vf_init_phase; + int vf_rpt_num; + unsigned vsc_start_phase_step; + int vsc_phase_slope; + unsigned char src1_vsc_phase0_always_en; + unsigned char src1_hsc_phase0_always_en; + /* 1bit, 0: using minus, 1: using repeat data */ + unsigned char src1_hsc_rpt_ctrl; + /* 1bit, 0: using minus 1: using repeat data */ + unsigned char src1_vsc_rpt_ctrl; + + /* canvas info */ + struct config_planes_s src_planes[4]; + struct config_planes_s src2_planes[4]; + struct config_planes_s dst_planes[4]; +}; diff --git a/libsrc/grabber/amlogic/IonBuffer.cpp b/libsrc/grabber/amlogic/IonBuffer.cpp new file mode 100644 index 00000000..4a450b64 --- /dev/null +++ b/libsrc/grabber/amlogic/IonBuffer.cpp @@ -0,0 +1,19 @@ +/* +* +* Copyright (C) 2016 OtherCrashOverride@users.noreply.github.com. +* All rights reserved. +* +* 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. +* +*/ +#include "IonBuffer.h" + +int IonBuffer::ion_fd = -1; + diff --git a/libsrc/grabber/amlogic/IonBuffer.h b/libsrc/grabber/amlogic/IonBuffer.h new file mode 100644 index 00000000..457114b4 --- /dev/null +++ b/libsrc/grabber/amlogic/IonBuffer.h @@ -0,0 +1,189 @@ +/* + * + * Copyright (C) 2016 OtherCrashOverride@users.noreply.github.com. + * All rights reserved. + * + * 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. + * +*/ +#pragma once + +#include +#include +#include +#include +#include +#include + +#include "ion.h" +#include "meson_ion.h" + + +class IonBuffer +{ + size_t bufferSize = 0; + ion_user_handle_t handle = 0; + int exportHandle = 0; + size_t length = 0; + unsigned long physicalAddress = 0; + + + static int ion_fd; // = -1; + + +public: + + size_t BufferSize() const + { + return bufferSize; + } + + ion_user_handle_t Handle() const + { + return handle; + } + + int ExportHandle() const + { + return exportHandle; + } + + size_t Length() const + { + return length; + } + + unsigned long PhysicalAddress() const + { + return physicalAddress; + } + + + + IonBuffer(size_t bufferSize) + : bufferSize(bufferSize) + { + if (bufferSize < 1) + throw std::runtime_error("bufferSize < 1"); + + + if (ion_fd < 0) + { + ion_fd = open("/dev/ion", O_RDWR); + if (ion_fd < 0) + { + throw std::runtime_error("open ion failed."); + } + } + + + int io; + + // Allocate a buffer + ion_allocation_data allocation_data = { 0 }; + allocation_data.len = bufferSize; + allocation_data.heap_id_mask = ION_HEAP_CARVEOUT_MASK; + +#if defined(__aarch64__) + allocation_data.flags = ION_FLAG_CACHED_NEEDS_SYNC; //ION_FLAG_CACHED; +#else + allocation_data.flags = 0; +#endif + + io = ioctl(ion_fd, ION_IOC_ALLOC, &allocation_data); + if (io != 0) + { + throw std::runtime_error("ION_IOC_ALLOC failed."); + } + +// fprintf(stderr, "ion handle=%d\n", allocation_data.handle); + + + // Map/share the buffer + ion_fd_data ionData = { 0 }; + ionData.handle = allocation_data.handle; + + io = ioctl(ion_fd, ION_IOC_SHARE, &ionData); + if (io != 0) + { + throw std::runtime_error("ION_IOC_SHARE failed."); + } + +// fprintf(stderr, "ion map=%d\n", ionData.fd); + + + // Get the physical address for the buffer + meson_phys_data physData = { 0 }; + physData.handle = ionData.fd; + + ion_custom_data ionCustomData = { 0 }; + ionCustomData.cmd = ION_IOC_MESON_PHYS_ADDR; + ionCustomData.arg = (long unsigned int)&physData; + + io = ioctl(ion_fd, ION_IOC_CUSTOM, &ionCustomData); + if (io != 0) + { + throw std::runtime_error("ION_IOC_CUSTOM failed."); + } + + // Assignment + handle = allocation_data.handle; + exportHandle = ionData.fd; + length = allocation_data.len; + physicalAddress = physData.phys_addr; + +// fprintf(stderr, "ion phys_addr=%lu\n", physicalAddress); + } + + virtual ~IonBuffer() + { + ion_handle_data ionHandleData = { 0 }; + ionHandleData.handle = handle; + + int io = ioctl(ion_fd, ION_IOC_FREE, &ionHandleData); + if (io != 0) + { + throw std::runtime_error("ION_IOC_FREE failed."); + } + } + + + void Sync() + { + +#if defined(__aarch64__) + ion_fd_data ionFdData = { 0 }; + ionFdData.fd = ExportHandle(); + + int io = ioctl(ion_fd, ION_IOC_SYNC, &ionFdData); + if (io != 0) + { + throw std::runtime_error("ION_IOC_SYNC failed."); + } +#endif + + } + + void* Map() + { + void* result = mmap(NULL, + Length(), + PROT_READ | PROT_WRITE, + MAP_FILE | MAP_SHARED, + ExportHandle(), + 0); + if (result == MAP_FAILED) + { + throw std::runtime_error("mmap failed."); + } + + return result; + } +}; diff --git a/libsrc/grabber/amlogic/ion.h b/libsrc/grabber/amlogic/ion.h new file mode 100644 index 00000000..1b624d93 --- /dev/null +++ b/libsrc/grabber/amlogic/ion.h @@ -0,0 +1,197 @@ +/* + * drivers/staging/android/uapi/ion.h + * + * Copyright (C) 2011 Google, Inc. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * 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 _UAPI_LINUX_ION_H +#define _UAPI_LINUX_ION_H + +#include +#include + +typedef int ion_user_handle_t; + +/** + * enum ion_heap_types - list of all possible types of heaps + * @ION_HEAP_TYPE_SYSTEM: memory allocated via vmalloc + * @ION_HEAP_TYPE_SYSTEM_CONTIG: memory allocated via kmalloc + * @ION_HEAP_TYPE_CARVEOUT: memory allocated from a prereserved + * carveout heap, allocations are physically + * contiguous + * @ION_HEAP_TYPE_DMA: memory allocated via DMA API + * @ION_NUM_HEAPS: helper for iterating over heaps, a bit mask + * is used to identify the heaps, so only 32 + * total heap types are supported + */ +enum ion_heap_type { + ION_HEAP_TYPE_SYSTEM, + ION_HEAP_TYPE_SYSTEM_CONTIG, + ION_HEAP_TYPE_CARVEOUT, + ION_HEAP_TYPE_CHUNK, + ION_HEAP_TYPE_DMA, + ION_HEAP_TYPE_CUSTOM, /* must be last so device specific heaps always + are at the end of this enum */ + ION_NUM_HEAPS = 16, +}; + +#define ION_HEAP_SYSTEM_MASK (1 << ION_HEAP_TYPE_SYSTEM) +#define ION_HEAP_SYSTEM_CONTIG_MASK (1 << ION_HEAP_TYPE_SYSTEM_CONTIG) +#define ION_HEAP_CARVEOUT_MASK (1 << ION_HEAP_TYPE_CARVEOUT) +#define ION_HEAP_TYPE_DMA_MASK (1 << ION_HEAP_TYPE_DMA) + +#define ION_NUM_HEAP_IDS sizeof(unsigned int) * 8 + +/** + * allocation flags - the lower 16 bits are used by core ion, the upper 16 + * bits are reserved for use by the heaps themselves. + */ +#define ION_FLAG_CACHED 1 /* mappings of this buffer should be + cached, ion will do cache + maintenance when the buffer is + mapped for dma */ +#define ION_FLAG_CACHED_NEEDS_SYNC 2 /* mappings of this buffer will created + at mmap time, if this is set + caches must be managed manually */ + +/** + * DOC: Ion Userspace API + * + * create a client by opening /dev/ion + * most operations handled via following ioctls + * + */ + +/** + * struct ion_allocation_data - metadata passed from userspace for allocations + * @len: size of the allocation + * @align: required alignment of the allocation + * @heap_id_mask: mask of heap ids to allocate from + * @flags: flags passed to heap + * @handle: pointer that will be populated with a cookie to use to + * refer to this allocation + * + * Provided by userspace as an argument to the ioctl + */ +struct ion_allocation_data { + size_t len; + size_t align; + unsigned int heap_id_mask; + unsigned int flags; + ion_user_handle_t handle; +}; + +/** + * struct ion_fd_data - metadata passed to/from userspace for a handle/fd pair + * @handle: a handle + * @fd: a file descriptor representing that handle + * + * For ION_IOC_SHARE or ION_IOC_MAP userspace populates the handle field with + * the handle returned from ion alloc, and the kernel returns the file + * descriptor to share or map in the fd field. For ION_IOC_IMPORT, userspace + * provides the file descriptor and the kernel returns the handle. + */ +struct ion_fd_data { + ion_user_handle_t handle; + int fd; +}; + +/** + * struct ion_handle_data - a handle passed to/from the kernel + * @handle: a handle + */ +struct ion_handle_data { + ion_user_handle_t handle; +}; + +/** + * struct ion_custom_data - metadata passed to/from userspace for a custom ioctl + * @cmd: the custom ioctl function to call + * @arg: additional data to pass to the custom ioctl, typically a user + * pointer to a predefined structure + * + * This works just like the regular cmd and arg fields of an ioctl. + */ +struct ion_custom_data { + unsigned int cmd; + unsigned long arg; +}; + +#define ION_IOC_MAGIC 'I' + +/** + * DOC: ION_IOC_ALLOC - allocate memory + * + * Takes an ion_allocation_data struct and returns it with the handle field + * populated with the opaque handle for the allocation. + */ +#define ION_IOC_ALLOC _IOWR(ION_IOC_MAGIC, 0, \ + struct ion_allocation_data) + +/** + * DOC: ION_IOC_FREE - free memory + * + * Takes an ion_handle_data struct and frees the handle. + */ +#define ION_IOC_FREE _IOWR(ION_IOC_MAGIC, 1, struct ion_handle_data) + +/** + * DOC: ION_IOC_MAP - get a file descriptor to mmap + * + * Takes an ion_fd_data struct with the handle field populated with a valid + * opaque handle. Returns the struct with the fd field set to a file + * descriptor open in the current address space. This file descriptor + * can then be used as an argument to mmap. + */ +#define ION_IOC_MAP _IOWR(ION_IOC_MAGIC, 2, struct ion_fd_data) + +/** + * DOC: ION_IOC_SHARE - creates a file descriptor to use to share an allocation + * + * Takes an ion_fd_data struct with the handle field populated with a valid + * opaque handle. Returns the struct with the fd field set to a file + * descriptor open in the current address space. This file descriptor + * can then be passed to another process. The corresponding opaque handle can + * be retrieved via ION_IOC_IMPORT. + */ +#define ION_IOC_SHARE _IOWR(ION_IOC_MAGIC, 4, struct ion_fd_data) + +/** + * DOC: ION_IOC_IMPORT - imports a shared file descriptor + * + * Takes an ion_fd_data struct with the fd field populated with a valid file + * descriptor obtained from ION_IOC_SHARE and returns the struct with the handle + * filed set to the corresponding opaque handle. + */ +#define ION_IOC_IMPORT _IOWR(ION_IOC_MAGIC, 5, struct ion_fd_data) + +/** + * DOC: ION_IOC_SYNC - syncs a shared file descriptors to memory + * + * Deprecated in favor of using the dma_buf api's correctly (syncing + * will happend automatically when the buffer is mapped to a device). + * If necessary should be used after touching a cached buffer from the cpu, + * this will make the buffer in memory coherent. + */ +#define ION_IOC_SYNC _IOWR(ION_IOC_MAGIC, 7, struct ion_fd_data) + +/** + * DOC: ION_IOC_CUSTOM - call architecture specific ion ioctl + * + * Takes the argument of the architecture specific ioctl to call and + * passes appropriate userdata for that ioctl + */ +#define ION_IOC_CUSTOM _IOWR(ION_IOC_MAGIC, 6, struct ion_custom_data) + +#endif /* _UAPI_LINUX_ION_H */ + diff --git a/libsrc/grabber/amlogic/meson_ion.h b/libsrc/grabber/amlogic/meson_ion.h new file mode 100644 index 00000000..bdb16705 --- /dev/null +++ b/libsrc/grabber/amlogic/meson_ion.h @@ -0,0 +1,60 @@ +/* + * include/linux/amlogic/dev_ion.h + * + * Copyright (C) 2014 Amlogic, Inc. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * 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 __LINUX_AMLOGIC_ION_H__ +#define __LINUX_AMLOGIC_ION_H__ + +//#include +//#include + +/** +* CUSTOM IOCTL - CMD +*/ + +#define ION_IOC_MESON_PHYS_ADDR 8 + +struct meson_phys_data { + int handle; + unsigned int phys_addr; + unsigned int size; +}; + + +#if 0 + +/** + * meson_ion_client_create() - allocate a client and returns it + * @heap_type_mask: mask of heaps this client can allocate from + * @name: used for debugging + */ +struct ion_client *meson_ion_client_create(unsigned int heap_mask, + const char *name); + +/** + * meson_ion_share_fd_to_phys - + * associate with a share fd + * @client: the client + * @share_fd: passed from the user space + * @addr point to the physical address + * @size point to the size of this ion buffer + */ + +int meson_ion_share_fd_to_phys(struct ion_client *client, + int share_fd, ion_phys_addr_t *addr, size_t *len); +#endif + +#endif + diff --git a/src/hyperion-remote/hyperion-remote.cpp b/src/hyperion-remote/hyperion-remote.cpp index 1b499012..5c108b2a 100644 --- a/src/hyperion-remote/hyperion-remote.cpp +++ b/src/hyperion-remote/hyperion-remote.cpp @@ -92,7 +92,7 @@ int main(int argc, char * argv[]) ColorOption & argWAdjust = parser.add ('W', "whiteAdjustment", "Set the adjustment of the white color (requires colors in hex format as RRGGBB)"); ColorOption & argbAdjust = parser.add ('b', "blackAdjustment", "Set the adjustment of the black color (requires colors in hex format as RRGGBB)"); Option & argMapping = parser.add