1/* linux/drivers/media/video/samsung/fimg2d4x/fimg2d.h
2 *
3 * Copyright (c) 2011 Samsung Electronics Co., Ltd.
4 *	http://www.samsung.com/
5 *
6 * Samsung Graphics 2D driver
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11*/
12
13#ifndef __FIMG2D_H
14#define __FIMG2D_H __FILE__
15
16#ifdef __KERNEL__
17
18#include <linux/clk.h>
19#include <linux/list.h>
20#include <linux/device.h>
21#include <linux/workqueue.h>
22#include <linux/platform_device.h>
23#include <linux/atomic.h>
24#include <linux/dma-mapping.h>
25#include <linux/dma-buf.h>
26
27#define FIMG2D_MINOR			(240)
28#define to_fimg2d_plat(d)		(to_platform_device(d)->dev.platform_data)
29
30#ifdef CONFIG_VIDEO_FIMG2D_DEBUG
31#define fimg2d_debug(fmt, arg...)	printk(KERN_INFO "[%s] " fmt, __func__, ## arg)
32#else
33#define fimg2d_debug(fmt, arg...)	do { } while (0)
34#endif
35
36#endif /* __KERNEL__ */
37
38#define FIMG2D_MAX_PLANES	2
39
40/* ioctl commands */
41#define FIMG2D_IOCTL_MAGIC	'F'
42#define FIMG2D_BITBLT_BLIT	_IOWR(FIMG2D_IOCTL_MAGIC, 0, struct fimg2d_blit)
43#define FIMG2D_BITBLT_SYNC	_IOW(FIMG2D_IOCTL_MAGIC, 1, int)
44#define FIMG2D_BITBLT_VERSION	_IOR(FIMG2D_IOCTL_MAGIC, 2, struct fimg2d_version)
45
46struct fimg2d_version {
47	unsigned int hw;
48	unsigned int sw;
49};
50
51/**
52 * @BLIT_SYNC: sync mode, to wait for blit done irq
53 * @BLIT_ASYNC: async mode, not to wait for blit done irq
54 *
55 */
56enum blit_sync {
57	BLIT_SYNC,
58	BLIT_ASYNC,
59};
60
61/**
62 * @ADDR_NONE: no image/solid color
63 * @ADDR_DMA_BUF: dma-buf fds
64 */
65enum addr_space {
66	ADDR_NONE = 0,
67	ADDR_DMA_BUF,
68};
69
70/**
71 * Pixel order complies with little-endian style
72 *
73 * DO NOT CHANGE THIS ORDER
74 */
75enum pixel_order {
76	AX_RGB = 0,
77	RGB_AX,
78	AX_BGR,
79	BGR_AX,
80	ARGB_ORDER_END,
81
82	P1_CRY1CBY0,
83	P1_CBY1CRY0,
84	P1_Y1CRY0CB,
85	P1_Y1CBY0CR,
86	P1_ORDER_END,
87
88	P2_CRCB,
89	P2_CBCR,
90	P2_ORDER_END,
91};
92
93/**
94 * DO NOT CHANGE THIS ORDER
95 */
96enum color_format {
97	CF_XRGB_8888 = 0,
98	CF_ARGB_8888,
99	CF_RGB_565,
100	CF_XRGB_1555,
101	CF_ARGB_1555,
102	CF_XRGB_4444,
103	CF_ARGB_4444,
104	CF_RGB_888,
105	CF_YCBCR_444,
106	CF_YCBCR_422,
107	CF_YCBCR_420,
108	CF_A8,
109	CF_L8,
110	SRC_DST_FORMAT_END,
111
112	CF_MSK_1BIT,
113	CF_MSK_4BIT,
114	CF_MSK_8BIT,
115	CF_MSK_16BIT_565,
116	CF_MSK_16BIT_1555,
117	CF_MSK_16BIT_4444,
118	CF_MSK_32BIT_8888,
119	MSK_FORMAT_END,
120};
121
122enum rotation {
123	ORIGIN,
124	ROT_90,	/* clockwise */
125	ROT_180,
126	ROT_270,
127	XFLIP,	/* x-axis flip */
128	YFLIP,	/* y-axis flip */
129};
130
131/**
132 * @NO_REPEAT: no effect
133 * @REPEAT_NORMAL: repeat horizontally and vertically
134 * @REPEAT_PAD: pad with pad color
135 * @REPEAT_REFLECT: reflect horizontally and vertically
136 * @REPEAT_CLAMP: pad with edge color of original image
137 *
138 * DO NOT CHANGE THIS ORDER
139 */
140enum repeat {
141	NO_REPEAT = 0,
142	REPEAT_NORMAL,	/* default setting */
143	REPEAT_PAD,
144	REPEAT_REFLECT, REPEAT_MIRROR = REPEAT_REFLECT,
145	REPEAT_CLAMP,
146};
147
148enum scaling {
149	NO_SCALING,
150	SCALING_NEAREST,
151	SCALING_BILINEAR,
152};
153
154/**
155 * @SCALING_PIXELS: ratio in pixels
156 * @SCALING_RATIO: ratio in fixed point 16
157 */
158enum scaling_factor {
159	SCALING_PIXELS,
160	SCALING_RATIO,
161};
162
163/**
164 * premultiplied alpha
165 */
166enum premultiplied {
167	PREMULTIPLIED,
168	NON_PREMULTIPLIED,
169};
170
171/**
172 * @TRANSP: discard bluescreen color
173 * @BLUSCR: replace bluescreen color with background color
174 */
175enum bluescreen {
176	OPAQUE,
177	TRANSP,
178	BLUSCR,
179};
180
181/**
182 * DO NOT CHANGE THIS ORDER
183 */
184enum blit_op {
185	BLIT_OP_SOLID_FILL = 0,
186
187	BLIT_OP_CLR,
188	BLIT_OP_SRC, BLIT_OP_SRC_COPY = BLIT_OP_SRC,
189	BLIT_OP_DST,
190	BLIT_OP_SRC_OVER,
191	BLIT_OP_DST_OVER, BLIT_OP_OVER_REV = BLIT_OP_DST_OVER,
192	BLIT_OP_SRC_IN,
193	BLIT_OP_DST_IN, BLIT_OP_IN_REV = BLIT_OP_DST_IN,
194	BLIT_OP_SRC_OUT,
195	BLIT_OP_DST_OUT, BLIT_OP_OUT_REV = BLIT_OP_DST_OUT,
196	BLIT_OP_SRC_ATOP,
197	BLIT_OP_DST_ATOP, BLIT_OP_ATOP_REV = BLIT_OP_DST_ATOP,
198	BLIT_OP_XOR,
199
200	BLIT_OP_ADD,
201	BLIT_OP_MULTIPLY,
202	BLIT_OP_SCREEN,
203	BLIT_OP_DARKEN,
204	BLIT_OP_LIGHTEN,
205
206	BLIT_OP_DISJ_SRC_OVER,
207	BLIT_OP_DISJ_DST_OVER, BLIT_OP_SATURATE = BLIT_OP_DISJ_DST_OVER,
208	BLIT_OP_DISJ_SRC_IN,
209	BLIT_OP_DISJ_DST_IN, BLIT_OP_DISJ_IN_REV = BLIT_OP_DISJ_DST_IN,
210	BLIT_OP_DISJ_SRC_OUT,
211	BLIT_OP_DISJ_DST_OUT, BLIT_OP_DISJ_OUT_REV = BLIT_OP_DISJ_DST_OUT,
212	BLIT_OP_DISJ_SRC_ATOP,
213	BLIT_OP_DISJ_DST_ATOP, BLIT_OP_DISJ_ATOP_REV = BLIT_OP_DISJ_DST_ATOP,
214	BLIT_OP_DISJ_XOR,
215
216	BLIT_OP_CONJ_SRC_OVER,
217	BLIT_OP_CONJ_DST_OVER, BLIT_OP_CONJ_OVER_REV = BLIT_OP_CONJ_DST_OVER,
218	BLIT_OP_CONJ_SRC_IN,
219	BLIT_OP_CONJ_DST_IN, BLIT_OP_CONJ_IN_REV = BLIT_OP_CONJ_DST_IN,
220	BLIT_OP_CONJ_SRC_OUT,
221	BLIT_OP_CONJ_DST_OUT, BLIT_OP_CONJ_OUT_REV = BLIT_OP_CONJ_DST_OUT,
222	BLIT_OP_CONJ_SRC_ATOP,
223	BLIT_OP_CONJ_DST_ATOP, BLIT_OP_CONJ_ATOP_REV = BLIT_OP_CONJ_DST_ATOP,
224	BLIT_OP_CONJ_XOR,
225
226	/* user select coefficient manually */
227	BLIT_OP_USER_COEFF,
228
229	BLIT_OP_USER_SRC_GA,
230
231	/* Add new operation type here */
232
233	/* end of blit operation */
234	BLIT_OP_END,
235};
236#define MAX_FIMG2D_BLIT_OP (int)BLIT_OP_END
237
238#ifdef __KERNEL__
239
240/**
241 * @TMP: temporary buffer for 2-step blit at a single command
242 *
243 * DO NOT CHANGE THIS ORDER
244 */
245enum image_object {
246	IMAGE_SRC = 0,
247	IMAGE_MSK,
248	IMAGE_TMP,
249	IMAGE_DST,
250	IMAGE_END,
251};
252#define MAX_IMAGES		IMAGE_END
253#define ISRC			IMAGE_SRC
254#define IMSK			IMAGE_MSK
255#define ITMP			IMAGE_TMP
256#define IDST			IMAGE_DST
257#define image_table(u)		\
258	{			\
259		(u)->src,	\
260		(u)->msk,	\
261		(u)->tmp,	\
262		(u)->dst	\
263	}
264
265struct fimg2d_dma {
266	struct dma_buf *dma_buf;
267	struct dma_buf_attachment *attachment;
268	struct sg_table *sg_table;
269	dma_addr_t dma_addr;
270	enum dma_data_direction direction;
271};
272
273#endif /* __KERNEL__ */
274
275struct fimg2d_addr {
276	enum addr_space type;
277	int fd[FIMG2D_MAX_PLANES];
278};
279
280struct fimg2d_rect {
281	int x1;
282	int y1;
283	int x2;	/* x1 + width */
284	int y2; /* y1 + height */
285};
286
287/**
288 * pixels can be different from src, dst or clip rect
289 */
290struct fimg2d_scale {
291	enum scaling mode;
292
293	/* ratio in pixels */
294	int src_w, src_h;
295	int dst_w, dst_h;
296};
297
298struct fimg2d_clip {
299	__u32 enable;
300	int x1;
301	int y1;
302	int x2;	/* x1 + width */
303	int y2; /* y1 + height */
304};
305
306struct fimg2d_repeat {
307	enum repeat mode;
308	unsigned long pad_color;
309};
310
311/**
312 * @bg_color: bg_color is valid only if bluescreen mode is BLUSCR.
313 */
314struct fimg2d_bluscr {
315	enum bluescreen mode;
316	unsigned long bs_color;
317	unsigned long bg_color;
318};
319
320/**
321 * @plane2: address info for CbCr in YCbCr 2plane mode
322 * @rect: crop/clip rect
323 */
324struct fimg2d_image {
325	int width;
326	int height;
327	int stride;
328	enum pixel_order order;
329	enum color_format fmt;
330	struct fimg2d_addr addr;
331	struct fimg2d_rect rect;
332};
333
334/**
335 * @solid_color:
336 *         src color instead of src image
337 *         color format and order must be ARGB8888(A is MSB).
338 * @g_alpha: global(constant) alpha. 0xff is opaque, 0 is transparnet
339 * @dither: dithering
340 * @rotate: rotation degree in clockwise
341 * @premult: alpha premultiplied mode for read & write
342 * @scaling: common scaling info for src and mask image.
343 * @repeat: repeat type (tile mode)
344 * @bluscr: blue screen and transparent mode
345 * @clipping: clipping rect within dst rect
346 */
347struct fimg2d_param {
348	unsigned long solid_color;
349	unsigned char g_alpha;
350	__u32 dither;
351	enum rotation rotate;
352	enum premultiplied premult;
353	struct fimg2d_scale scaling;
354	struct fimg2d_repeat repeat;
355	struct fimg2d_bluscr bluscr;
356	struct fimg2d_clip clipping;
357};
358
359/**
360 * @op: blit operation mode
361 * @src: set when using src image
362 * @msk: set when using mask image
363 * @tmp: set when using 2-step blit at a single command
364 * @dst: dst must not be null
365 *         * tmp image must be the same to dst except memory address
366 * @seq_no: user debugging info.
367 *          for example, user can set sequence number or pid.
368 */
369struct fimg2d_blit {
370	enum blit_op op;
371	struct fimg2d_param param;
372	struct fimg2d_image *src;
373	struct fimg2d_image *msk;
374	struct fimg2d_image *tmp;
375	struct fimg2d_image *dst;
376	enum blit_sync sync;
377	unsigned int seq_no;
378};
379
380#ifdef __KERNEL__
381
382/**
383 * @ncmd: request count in blit command queue
384 * @wait_q: conext wait queue head
385*/
386struct fimg2d_context {
387	atomic_t ncmd;
388	wait_queue_head_t wait_q;
389};
390
391/**
392 * @op: blit operation mode
393 * @sync: sync/async blit mode (currently support sync mode only)
394 * @image: array of image object.
395 *         [0] is for src image
396 *         [1] is for mask image
397 *         [2] is for temporary buffer
398 *             set when using 2-step blit at a single command
399 *         [3] is for dst, dst must not be null
400 *         * tmp image must be the same to dst except memory address
401 * @seq_no: user debugging info.
402 *          for example, user can set sequence number or pid.
403 * @dma_all: total dma size of src, msk, dst
404 * @dma: array of dma info for each src, msk, tmp and dst
405 * @ctx: context is created when user open fimg2d device.
406 * @node: list head of blit command queue
407 */
408struct fimg2d_bltcmd {
409	enum blit_op op;
410	enum blit_sync sync;
411	unsigned int seq_no;
412	struct fimg2d_param param;
413	struct fimg2d_image image[MAX_IMAGES];
414	struct fimg2d_dma dma[MAX_IMAGES][FIMG2D_MAX_PLANES];
415	struct fimg2d_context *ctx;
416	struct list_head node;
417};
418
419/**
420 * @suspended: in suspend mode
421 * @clkon: power status for runtime pm
422 * @mem: resource platform device
423 * @regs: base address of hardware
424 * @dev: pointer to device struct
425 * @err: true if hardware is timed out while blitting
426 * @irq: irq number
427 * @nctx: context count
428 * @busy: 1 if hardware is running
429 * @bltlock: spinlock for blit
430 * @wait_q: blit wait queue head
431 * @cmd_q: blit command queue
432 * @workqueue: workqueue_struct for kfimg2dd
433*/
434struct fimg2d_control {
435	atomic_t suspended;
436	atomic_t clkon;
437	struct clk *clock;
438	struct device *dev;
439	struct resource *mem;
440	void __iomem *regs;
441
442	bool err;
443	int irq;
444	atomic_t nctx;
445	atomic_t busy;
446	atomic_t active;
447	spinlock_t bltlock;
448	wait_queue_head_t wait_q;
449	struct list_head cmd_q;
450	struct workqueue_struct *work_q;
451
452	void (*blit)(struct fimg2d_control *info);
453	int (*configure)(struct fimg2d_control *info,
454			struct fimg2d_bltcmd *cmd);
455	void (*run)(struct fimg2d_control *info);
456	void (*stop)(struct fimg2d_control *info);
457	void (*dump)(struct fimg2d_control *info);
458	void (*finalize)(struct fimg2d_control *info);
459};
460
461int fimg2d_register_ops(struct fimg2d_control *info);
462
463#endif /* __KERNEL__ */
464
465#endif /* __FIMG2D_H__ */
466