Greg Hackmann | 8f10f92 | 2013-01-14 15:54:46 -0800 | [diff] [blame] | 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 | |
| 46 | struct 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 | */ |
| 56 | enum 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 | */ |
| 65 | enum 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 | */ |
| 75 | enum 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 | */ |
| 96 | enum 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 | |
| 122 | enum 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 | */ |
| 140 | enum 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 | |
| 148 | enum 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 | */ |
| 158 | enum scaling_factor { |
| 159 | SCALING_PIXELS, |
| 160 | SCALING_RATIO, |
| 161 | }; |
| 162 | |
| 163 | /** |
| 164 | * premultiplied alpha |
| 165 | */ |
| 166 | enum premultiplied { |
| 167 | PREMULTIPLIED, |
| 168 | NON_PREMULTIPLIED, |
| 169 | }; |
| 170 | |
| 171 | /** |
| 172 | * @TRANSP: discard bluescreen color |
| 173 | * @BLUSCR: replace bluescreen color with background color |
| 174 | */ |
| 175 | enum bluescreen { |
| 176 | OPAQUE, |
| 177 | TRANSP, |
| 178 | BLUSCR, |
| 179 | }; |
| 180 | |
| 181 | /** |
| 182 | * DO NOT CHANGE THIS ORDER |
| 183 | */ |
| 184 | enum 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 | */ |
| 245 | enum 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 | |
| 265 | struct 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 | |
| 275 | struct fimg2d_addr { |
| 276 | enum addr_space type; |
| 277 | int fd[FIMG2D_MAX_PLANES]; |
| 278 | }; |
| 279 | |
| 280 | struct 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 | */ |
| 290 | struct 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 | |
| 298 | struct fimg2d_clip { |
| 299 | __u32 enable; |
| 300 | int x1; |
| 301 | int y1; |
| 302 | int x2; /* x1 + width */ |
| 303 | int y2; /* y1 + height */ |
| 304 | }; |
| 305 | |
| 306 | struct 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 | */ |
| 314 | struct 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 | */ |
| 324 | struct 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 | */ |
| 347 | struct 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 | */ |
| 369 | struct 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 | */ |
| 386 | struct 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 | */ |
| 408 | struct 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 | */ |
| 434 | struct 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 | |
| 461 | int fimg2d_register_ops(struct fimg2d_control *info); |
| 462 | |
| 463 | #endif /* __KERNEL__ */ |
| 464 | |
| 465 | #endif /* __FIMG2D_H__ */ |