blob: ceda93cf6ec1cefdc6800ecb1a939ccfcdd0c5d0 [file] [log] [blame]
/* linux/drivers/media/video/samsung/fimg2d4x/fimg2d.h
*
* Copyright (c) 2011 Samsung Electronics Co., Ltd.
* http://www.samsung.com/
*
* Samsung Graphics 2D driver
*
* 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.
*/
#ifndef __FIMG2D_H
#define __FIMG2D_H __FILE__
#ifdef __KERNEL__
#include <linux/clk.h>
#include <linux/list.h>
#include <linux/device.h>
#include <linux/workqueue.h>
#include <linux/platform_device.h>
#include <linux/atomic.h>
#include <linux/dma-mapping.h>
#include <linux/dma-buf.h>
#define FIMG2D_MINOR (240)
#define to_fimg2d_plat(d) (to_platform_device(d)->dev.platform_data)
#ifdef CONFIG_VIDEO_FIMG2D_DEBUG
#define fimg2d_debug(fmt, arg...) printk(KERN_INFO "[%s] " fmt, __func__, ## arg)
#else
#define fimg2d_debug(fmt, arg...) do { } while (0)
#endif
#endif /* __KERNEL__ */
#define FIMG2D_MAX_PLANES 2
/* ioctl commands */
#define FIMG2D_IOCTL_MAGIC 'F'
#define FIMG2D_BITBLT_BLIT _IOWR(FIMG2D_IOCTL_MAGIC, 0, struct fimg2d_blit)
#define FIMG2D_BITBLT_SYNC _IOW(FIMG2D_IOCTL_MAGIC, 1, int)
#define FIMG2D_BITBLT_VERSION _IOR(FIMG2D_IOCTL_MAGIC, 2, struct fimg2d_version)
struct fimg2d_version {
unsigned int hw;
unsigned int sw;
};
/**
* @BLIT_SYNC: sync mode, to wait for blit done irq
* @BLIT_ASYNC: async mode, not to wait for blit done irq
*
*/
enum blit_sync {
BLIT_SYNC,
BLIT_ASYNC,
};
/**
* @ADDR_NONE: no image/solid color
* @ADDR_DMA_BUF: dma-buf fds
*/
enum addr_space {
ADDR_NONE = 0,
ADDR_DMA_BUF,
};
/**
* Pixel order complies with little-endian style
*
* DO NOT CHANGE THIS ORDER
*/
enum pixel_order {
AX_RGB = 0,
RGB_AX,
AX_BGR,
BGR_AX,
ARGB_ORDER_END,
P1_CRY1CBY0,
P1_CBY1CRY0,
P1_Y1CRY0CB,
P1_Y1CBY0CR,
P1_ORDER_END,
P2_CRCB,
P2_CBCR,
P2_ORDER_END,
};
/**
* DO NOT CHANGE THIS ORDER
*/
enum color_format {
CF_XRGB_8888 = 0,
CF_ARGB_8888,
CF_RGB_565,
CF_XRGB_1555,
CF_ARGB_1555,
CF_XRGB_4444,
CF_ARGB_4444,
CF_RGB_888,
CF_YCBCR_444,
CF_YCBCR_422,
CF_YCBCR_420,
CF_A8,
CF_L8,
SRC_DST_FORMAT_END,
CF_MSK_1BIT,
CF_MSK_4BIT,
CF_MSK_8BIT,
CF_MSK_16BIT_565,
CF_MSK_16BIT_1555,
CF_MSK_16BIT_4444,
CF_MSK_32BIT_8888,
MSK_FORMAT_END,
};
enum rotation {
ORIGIN,
ROT_90, /* clockwise */
ROT_180,
ROT_270,
XFLIP, /* x-axis flip */
YFLIP, /* y-axis flip */
};
/**
* @NO_REPEAT: no effect
* @REPEAT_NORMAL: repeat horizontally and vertically
* @REPEAT_PAD: pad with pad color
* @REPEAT_REFLECT: reflect horizontally and vertically
* @REPEAT_CLAMP: pad with edge color of original image
*
* DO NOT CHANGE THIS ORDER
*/
enum repeat {
NO_REPEAT = 0,
REPEAT_NORMAL, /* default setting */
REPEAT_PAD,
REPEAT_REFLECT, REPEAT_MIRROR = REPEAT_REFLECT,
REPEAT_CLAMP,
};
enum scaling {
NO_SCALING,
SCALING_NEAREST,
SCALING_BILINEAR,
};
/**
* @SCALING_PIXELS: ratio in pixels
* @SCALING_RATIO: ratio in fixed point 16
*/
enum scaling_factor {
SCALING_PIXELS,
SCALING_RATIO,
};
/**
* premultiplied alpha
*/
enum premultiplied {
PREMULTIPLIED,
NON_PREMULTIPLIED,
};
/**
* @TRANSP: discard bluescreen color
* @BLUSCR: replace bluescreen color with background color
*/
enum bluescreen {
OPAQUE,
TRANSP,
BLUSCR,
};
/**
* DO NOT CHANGE THIS ORDER
*/
enum blit_op {
BLIT_OP_SOLID_FILL = 0,
BLIT_OP_CLR,
BLIT_OP_SRC, BLIT_OP_SRC_COPY = BLIT_OP_SRC,
BLIT_OP_DST,
BLIT_OP_SRC_OVER,
BLIT_OP_DST_OVER, BLIT_OP_OVER_REV = BLIT_OP_DST_OVER,
BLIT_OP_SRC_IN,
BLIT_OP_DST_IN, BLIT_OP_IN_REV = BLIT_OP_DST_IN,
BLIT_OP_SRC_OUT,
BLIT_OP_DST_OUT, BLIT_OP_OUT_REV = BLIT_OP_DST_OUT,
BLIT_OP_SRC_ATOP,
BLIT_OP_DST_ATOP, BLIT_OP_ATOP_REV = BLIT_OP_DST_ATOP,
BLIT_OP_XOR,
BLIT_OP_ADD,
BLIT_OP_MULTIPLY,
BLIT_OP_SCREEN,
BLIT_OP_DARKEN,
BLIT_OP_LIGHTEN,
BLIT_OP_DISJ_SRC_OVER,
BLIT_OP_DISJ_DST_OVER, BLIT_OP_SATURATE = BLIT_OP_DISJ_DST_OVER,
BLIT_OP_DISJ_SRC_IN,
BLIT_OP_DISJ_DST_IN, BLIT_OP_DISJ_IN_REV = BLIT_OP_DISJ_DST_IN,
BLIT_OP_DISJ_SRC_OUT,
BLIT_OP_DISJ_DST_OUT, BLIT_OP_DISJ_OUT_REV = BLIT_OP_DISJ_DST_OUT,
BLIT_OP_DISJ_SRC_ATOP,
BLIT_OP_DISJ_DST_ATOP, BLIT_OP_DISJ_ATOP_REV = BLIT_OP_DISJ_DST_ATOP,
BLIT_OP_DISJ_XOR,
BLIT_OP_CONJ_SRC_OVER,
BLIT_OP_CONJ_DST_OVER, BLIT_OP_CONJ_OVER_REV = BLIT_OP_CONJ_DST_OVER,
BLIT_OP_CONJ_SRC_IN,
BLIT_OP_CONJ_DST_IN, BLIT_OP_CONJ_IN_REV = BLIT_OP_CONJ_DST_IN,
BLIT_OP_CONJ_SRC_OUT,
BLIT_OP_CONJ_DST_OUT, BLIT_OP_CONJ_OUT_REV = BLIT_OP_CONJ_DST_OUT,
BLIT_OP_CONJ_SRC_ATOP,
BLIT_OP_CONJ_DST_ATOP, BLIT_OP_CONJ_ATOP_REV = BLIT_OP_CONJ_DST_ATOP,
BLIT_OP_CONJ_XOR,
/* user select coefficient manually */
BLIT_OP_USER_COEFF,
BLIT_OP_USER_SRC_GA,
/* Add new operation type here */
/* end of blit operation */
BLIT_OP_END,
};
#define MAX_FIMG2D_BLIT_OP (int)BLIT_OP_END
#ifdef __KERNEL__
/**
* @TMP: temporary buffer for 2-step blit at a single command
*
* DO NOT CHANGE THIS ORDER
*/
enum image_object {
IMAGE_SRC = 0,
IMAGE_MSK,
IMAGE_TMP,
IMAGE_DST,
IMAGE_END,
};
#define MAX_IMAGES IMAGE_END
#define ISRC IMAGE_SRC
#define IMSK IMAGE_MSK
#define ITMP IMAGE_TMP
#define IDST IMAGE_DST
#define image_table(u) \
{ \
(u)->src, \
(u)->msk, \
(u)->tmp, \
(u)->dst \
}
struct fimg2d_dma {
struct dma_buf *dma_buf;
struct dma_buf_attachment *attachment;
struct sg_table *sg_table;
dma_addr_t dma_addr;
enum dma_data_direction direction;
};
#endif /* __KERNEL__ */
struct fimg2d_addr {
enum addr_space type;
int fd[FIMG2D_MAX_PLANES];
};
struct fimg2d_rect {
int x1;
int y1;
int x2; /* x1 + width */
int y2; /* y1 + height */
};
/**
* pixels can be different from src, dst or clip rect
*/
struct fimg2d_scale {
enum scaling mode;
/* ratio in pixels */
int src_w, src_h;
int dst_w, dst_h;
};
struct fimg2d_clip {
__u32 enable;
int x1;
int y1;
int x2; /* x1 + width */
int y2; /* y1 + height */
};
struct fimg2d_repeat {
enum repeat mode;
unsigned long pad_color;
};
/**
* @bg_color: bg_color is valid only if bluescreen mode is BLUSCR.
*/
struct fimg2d_bluscr {
enum bluescreen mode;
unsigned long bs_color;
unsigned long bg_color;
};
/**
* @plane2: address info for CbCr in YCbCr 2plane mode
* @rect: crop/clip rect
*/
struct fimg2d_image {
int width;
int height;
int stride;
enum pixel_order order;
enum color_format fmt;
struct fimg2d_addr addr;
struct fimg2d_rect rect;
};
/**
* @solid_color:
* src color instead of src image
* color format and order must be ARGB8888(A is MSB).
* @g_alpha: global(constant) alpha. 0xff is opaque, 0 is transparnet
* @dither: dithering
* @rotate: rotation degree in clockwise
* @premult: alpha premultiplied mode for read & write
* @scaling: common scaling info for src and mask image.
* @repeat: repeat type (tile mode)
* @bluscr: blue screen and transparent mode
* @clipping: clipping rect within dst rect
*/
struct fimg2d_param {
unsigned long solid_color;
unsigned char g_alpha;
__u32 dither;
enum rotation rotate;
enum premultiplied premult;
struct fimg2d_scale scaling;
struct fimg2d_repeat repeat;
struct fimg2d_bluscr bluscr;
struct fimg2d_clip clipping;
};
/**
* @op: blit operation mode
* @src: set when using src image
* @msk: set when using mask image
* @tmp: set when using 2-step blit at a single command
* @dst: dst must not be null
* * tmp image must be the same to dst except memory address
* @seq_no: user debugging info.
* for example, user can set sequence number or pid.
*/
struct fimg2d_blit {
enum blit_op op;
struct fimg2d_param param;
struct fimg2d_image *src;
struct fimg2d_image *msk;
struct fimg2d_image *tmp;
struct fimg2d_image *dst;
enum blit_sync sync;
unsigned int seq_no;
};
#ifdef __KERNEL__
/**
* @ncmd: request count in blit command queue
* @wait_q: conext wait queue head
*/
struct fimg2d_context {
atomic_t ncmd;
wait_queue_head_t wait_q;
};
/**
* @op: blit operation mode
* @sync: sync/async blit mode (currently support sync mode only)
* @image: array of image object.
* [0] is for src image
* [1] is for mask image
* [2] is for temporary buffer
* set when using 2-step blit at a single command
* [3] is for dst, dst must not be null
* * tmp image must be the same to dst except memory address
* @seq_no: user debugging info.
* for example, user can set sequence number or pid.
* @dma_all: total dma size of src, msk, dst
* @dma: array of dma info for each src, msk, tmp and dst
* @ctx: context is created when user open fimg2d device.
* @node: list head of blit command queue
*/
struct fimg2d_bltcmd {
enum blit_op op;
enum blit_sync sync;
unsigned int seq_no;
struct fimg2d_param param;
struct fimg2d_image image[MAX_IMAGES];
struct fimg2d_dma dma[MAX_IMAGES][FIMG2D_MAX_PLANES];
struct fimg2d_context *ctx;
struct list_head node;
};
/**
* @suspended: in suspend mode
* @clkon: power status for runtime pm
* @mem: resource platform device
* @regs: base address of hardware
* @dev: pointer to device struct
* @err: true if hardware is timed out while blitting
* @irq: irq number
* @nctx: context count
* @busy: 1 if hardware is running
* @bltlock: spinlock for blit
* @wait_q: blit wait queue head
* @cmd_q: blit command queue
* @workqueue: workqueue_struct for kfimg2dd
*/
struct fimg2d_control {
atomic_t suspended;
atomic_t clkon;
struct clk *clock;
struct device *dev;
struct resource *mem;
void __iomem *regs;
bool err;
int irq;
atomic_t nctx;
atomic_t busy;
atomic_t active;
spinlock_t bltlock;
wait_queue_head_t wait_q;
struct list_head cmd_q;
struct workqueue_struct *work_q;
void (*blit)(struct fimg2d_control *info);
int (*configure)(struct fimg2d_control *info,
struct fimg2d_bltcmd *cmd);
void (*run)(struct fimg2d_control *info);
void (*stop)(struct fimg2d_control *info);
void (*dump)(struct fimg2d_control *info);
void (*finalize)(struct fimg2d_control *info);
};
int fimg2d_register_ops(struct fimg2d_control *info);
#endif /* __KERNEL__ */
#endif /* __FIMG2D_H__ */