exynos_drm_fimc.c 36 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417
  1. // SPDX-License-Identifier: GPL-2.0-or-later
  2. /*
  3. * Copyright (C) 2012 Samsung Electronics Co.Ltd
  4. * Authors:
  5. * Eunchul Kim <chulspro.kim@samsung.com>
  6. * Jinyoung Jeon <jy0.jeon@samsung.com>
  7. * Sangmin Lee <lsmin.lee@samsung.com>
  8. */
  9. #include <linux/clk.h>
  10. #include <linux/component.h>
  11. #include <linux/kernel.h>
  12. #include <linux/mfd/syscon.h>
  13. #include <linux/of.h>
  14. #include <linux/platform_device.h>
  15. #include <linux/pm_runtime.h>
  16. #include <linux/regmap.h>
  17. #include <linux/spinlock.h>
  18. #include <drm/drm_fourcc.h>
  19. #include <drm/drm_print.h>
  20. #include <drm/exynos_drm.h>
  21. #include "exynos_drm_drv.h"
  22. #include "exynos_drm_ipp.h"
  23. #include "regs-fimc.h"
  24. /*
  25. * FIMC stands for Fully Interactive Mobile Camera and
  26. * supports image scaler/rotator and input/output DMA operations.
  27. * input DMA reads image data from the memory.
  28. * output DMA writes image data to memory.
  29. * FIMC supports image rotation and image effect functions.
  30. */
  31. #define FIMC_MAX_DEVS 4
  32. #define FIMC_MAX_SRC 2
  33. #define FIMC_MAX_DST 32
  34. #define FIMC_SHFACTOR 10
  35. #define FIMC_BUF_STOP 1
  36. #define FIMC_BUF_START 2
  37. #define FIMC_WIDTH_ITU_709 1280
  38. #define FIMC_AUTOSUSPEND_DELAY 2000
  39. static unsigned int fimc_mask = 0xc;
  40. module_param_named(fimc_devs, fimc_mask, uint, 0644);
  41. MODULE_PARM_DESC(fimc_devs, "Alias mask for assigning FIMC devices to Exynos DRM");
  42. #define get_fimc_context(dev) dev_get_drvdata(dev)
  43. enum {
  44. FIMC_CLK_LCLK,
  45. FIMC_CLK_GATE,
  46. FIMC_CLK_WB_A,
  47. FIMC_CLK_WB_B,
  48. FIMC_CLKS_MAX
  49. };
  50. static const char * const fimc_clock_names[] = {
  51. [FIMC_CLK_LCLK] = "sclk_fimc",
  52. [FIMC_CLK_GATE] = "fimc",
  53. [FIMC_CLK_WB_A] = "pxl_async0",
  54. [FIMC_CLK_WB_B] = "pxl_async1",
  55. };
  56. /*
  57. * A structure of scaler.
  58. *
  59. * @range: narrow, wide.
  60. * @bypass: unused scaler path.
  61. * @up_h: horizontal scale up.
  62. * @up_v: vertical scale up.
  63. * @hratio: horizontal ratio.
  64. * @vratio: vertical ratio.
  65. */
  66. struct fimc_scaler {
  67. bool range;
  68. bool bypass;
  69. bool up_h;
  70. bool up_v;
  71. u32 hratio;
  72. u32 vratio;
  73. };
  74. /*
  75. * A structure of fimc context.
  76. *
  77. * @regs: memory mapped io registers.
  78. * @lock: locking of operations.
  79. * @clocks: fimc clocks.
  80. * @sc: scaler infomations.
  81. * @pol: porarity of writeback.
  82. * @id: fimc id.
  83. * @irq: irq number.
  84. */
  85. struct fimc_context {
  86. struct exynos_drm_ipp ipp;
  87. struct drm_device *drm_dev;
  88. void *dma_priv;
  89. struct device *dev;
  90. struct exynos_drm_ipp_task *task;
  91. struct exynos_drm_ipp_formats *formats;
  92. unsigned int num_formats;
  93. void __iomem *regs;
  94. spinlock_t lock;
  95. struct clk *clocks[FIMC_CLKS_MAX];
  96. struct fimc_scaler sc;
  97. int id;
  98. int irq;
  99. };
  100. static u32 fimc_read(struct fimc_context *ctx, u32 reg)
  101. {
  102. return readl(ctx->regs + reg);
  103. }
  104. static void fimc_write(struct fimc_context *ctx, u32 val, u32 reg)
  105. {
  106. writel(val, ctx->regs + reg);
  107. }
  108. static void fimc_set_bits(struct fimc_context *ctx, u32 reg, u32 bits)
  109. {
  110. void __iomem *r = ctx->regs + reg;
  111. writel(readl(r) | bits, r);
  112. }
  113. static void fimc_clear_bits(struct fimc_context *ctx, u32 reg, u32 bits)
  114. {
  115. void __iomem *r = ctx->regs + reg;
  116. writel(readl(r) & ~bits, r);
  117. }
  118. static void fimc_sw_reset(struct fimc_context *ctx)
  119. {
  120. u32 cfg;
  121. /* stop dma operation */
  122. cfg = fimc_read(ctx, EXYNOS_CISTATUS);
  123. if (EXYNOS_CISTATUS_GET_ENVID_STATUS(cfg))
  124. fimc_clear_bits(ctx, EXYNOS_MSCTRL, EXYNOS_MSCTRL_ENVID);
  125. fimc_set_bits(ctx, EXYNOS_CISRCFMT, EXYNOS_CISRCFMT_ITU601_8BIT);
  126. /* disable image capture */
  127. fimc_clear_bits(ctx, EXYNOS_CIIMGCPT,
  128. EXYNOS_CIIMGCPT_IMGCPTEN_SC | EXYNOS_CIIMGCPT_IMGCPTEN);
  129. /* s/w reset */
  130. fimc_set_bits(ctx, EXYNOS_CIGCTRL, EXYNOS_CIGCTRL_SWRST);
  131. /* s/w reset complete */
  132. fimc_clear_bits(ctx, EXYNOS_CIGCTRL, EXYNOS_CIGCTRL_SWRST);
  133. /* reset sequence */
  134. fimc_write(ctx, 0x0, EXYNOS_CIFCNTSEQ);
  135. }
  136. static void fimc_set_type_ctrl(struct fimc_context *ctx)
  137. {
  138. u32 cfg;
  139. cfg = fimc_read(ctx, EXYNOS_CIGCTRL);
  140. cfg &= ~(EXYNOS_CIGCTRL_TESTPATTERN_MASK |
  141. EXYNOS_CIGCTRL_SELCAM_ITU_MASK |
  142. EXYNOS_CIGCTRL_SELCAM_MIPI_MASK |
  143. EXYNOS_CIGCTRL_SELCAM_FIMC_MASK |
  144. EXYNOS_CIGCTRL_SELWB_CAMIF_MASK |
  145. EXYNOS_CIGCTRL_SELWRITEBACK_MASK);
  146. cfg |= (EXYNOS_CIGCTRL_SELCAM_ITU_A |
  147. EXYNOS_CIGCTRL_SELWRITEBACK_A |
  148. EXYNOS_CIGCTRL_SELCAM_MIPI_A |
  149. EXYNOS_CIGCTRL_SELCAM_FIMC_ITU);
  150. fimc_write(ctx, cfg, EXYNOS_CIGCTRL);
  151. }
  152. static void fimc_handle_jpeg(struct fimc_context *ctx, bool enable)
  153. {
  154. u32 cfg;
  155. DRM_DEV_DEBUG_KMS(ctx->dev, "enable[%d]\n", enable);
  156. cfg = fimc_read(ctx, EXYNOS_CIGCTRL);
  157. if (enable)
  158. cfg |= EXYNOS_CIGCTRL_CAM_JPEG;
  159. else
  160. cfg &= ~EXYNOS_CIGCTRL_CAM_JPEG;
  161. fimc_write(ctx, cfg, EXYNOS_CIGCTRL);
  162. }
  163. static void fimc_mask_irq(struct fimc_context *ctx, bool enable)
  164. {
  165. u32 cfg;
  166. DRM_DEV_DEBUG_KMS(ctx->dev, "enable[%d]\n", enable);
  167. cfg = fimc_read(ctx, EXYNOS_CIGCTRL);
  168. if (enable) {
  169. cfg &= ~EXYNOS_CIGCTRL_IRQ_OVFEN;
  170. cfg |= EXYNOS_CIGCTRL_IRQ_ENABLE | EXYNOS_CIGCTRL_IRQ_LEVEL;
  171. } else
  172. cfg &= ~EXYNOS_CIGCTRL_IRQ_ENABLE;
  173. fimc_write(ctx, cfg, EXYNOS_CIGCTRL);
  174. }
  175. static void fimc_clear_irq(struct fimc_context *ctx)
  176. {
  177. fimc_set_bits(ctx, EXYNOS_CIGCTRL, EXYNOS_CIGCTRL_IRQ_CLR);
  178. }
  179. static bool fimc_check_ovf(struct fimc_context *ctx)
  180. {
  181. u32 status, flag;
  182. status = fimc_read(ctx, EXYNOS_CISTATUS);
  183. flag = EXYNOS_CISTATUS_OVFIY | EXYNOS_CISTATUS_OVFICB |
  184. EXYNOS_CISTATUS_OVFICR;
  185. DRM_DEV_DEBUG_KMS(ctx->dev, "flag[0x%x]\n", flag);
  186. if (status & flag) {
  187. fimc_set_bits(ctx, EXYNOS_CIWDOFST,
  188. EXYNOS_CIWDOFST_CLROVFIY | EXYNOS_CIWDOFST_CLROVFICB |
  189. EXYNOS_CIWDOFST_CLROVFICR);
  190. DRM_DEV_ERROR(ctx->dev,
  191. "occurred overflow at %d, status 0x%x.\n",
  192. ctx->id, status);
  193. return true;
  194. }
  195. return false;
  196. }
  197. static bool fimc_check_frame_end(struct fimc_context *ctx)
  198. {
  199. u32 cfg;
  200. cfg = fimc_read(ctx, EXYNOS_CISTATUS);
  201. DRM_DEV_DEBUG_KMS(ctx->dev, "cfg[0x%x]\n", cfg);
  202. if (!(cfg & EXYNOS_CISTATUS_FRAMEEND))
  203. return false;
  204. cfg &= ~(EXYNOS_CISTATUS_FRAMEEND);
  205. fimc_write(ctx, cfg, EXYNOS_CISTATUS);
  206. return true;
  207. }
  208. static int fimc_get_buf_id(struct fimc_context *ctx)
  209. {
  210. u32 cfg;
  211. int frame_cnt, buf_id;
  212. cfg = fimc_read(ctx, EXYNOS_CISTATUS2);
  213. frame_cnt = EXYNOS_CISTATUS2_GET_FRAMECOUNT_BEFORE(cfg);
  214. if (frame_cnt == 0)
  215. frame_cnt = EXYNOS_CISTATUS2_GET_FRAMECOUNT_PRESENT(cfg);
  216. DRM_DEV_DEBUG_KMS(ctx->dev, "present[%d]before[%d]\n",
  217. EXYNOS_CISTATUS2_GET_FRAMECOUNT_PRESENT(cfg),
  218. EXYNOS_CISTATUS2_GET_FRAMECOUNT_BEFORE(cfg));
  219. if (frame_cnt == 0) {
  220. DRM_DEV_ERROR(ctx->dev, "failed to get frame count.\n");
  221. return -EIO;
  222. }
  223. buf_id = frame_cnt - 1;
  224. DRM_DEV_DEBUG_KMS(ctx->dev, "buf_id[%d]\n", buf_id);
  225. return buf_id;
  226. }
  227. static void fimc_handle_lastend(struct fimc_context *ctx, bool enable)
  228. {
  229. u32 cfg;
  230. DRM_DEV_DEBUG_KMS(ctx->dev, "enable[%d]\n", enable);
  231. cfg = fimc_read(ctx, EXYNOS_CIOCTRL);
  232. if (enable)
  233. cfg |= EXYNOS_CIOCTRL_LASTENDEN;
  234. else
  235. cfg &= ~EXYNOS_CIOCTRL_LASTENDEN;
  236. fimc_write(ctx, cfg, EXYNOS_CIOCTRL);
  237. }
  238. static void fimc_src_set_fmt_order(struct fimc_context *ctx, u32 fmt)
  239. {
  240. u32 cfg;
  241. DRM_DEV_DEBUG_KMS(ctx->dev, "fmt[0x%x]\n", fmt);
  242. /* RGB */
  243. cfg = fimc_read(ctx, EXYNOS_CISCCTRL);
  244. cfg &= ~EXYNOS_CISCCTRL_INRGB_FMT_RGB_MASK;
  245. switch (fmt) {
  246. case DRM_FORMAT_RGB565:
  247. cfg |= EXYNOS_CISCCTRL_INRGB_FMT_RGB565;
  248. fimc_write(ctx, cfg, EXYNOS_CISCCTRL);
  249. return;
  250. case DRM_FORMAT_RGB888:
  251. case DRM_FORMAT_XRGB8888:
  252. cfg |= EXYNOS_CISCCTRL_INRGB_FMT_RGB888;
  253. fimc_write(ctx, cfg, EXYNOS_CISCCTRL);
  254. return;
  255. default:
  256. /* bypass */
  257. break;
  258. }
  259. /* YUV */
  260. cfg = fimc_read(ctx, EXYNOS_MSCTRL);
  261. cfg &= ~(EXYNOS_MSCTRL_ORDER2P_SHIFT_MASK |
  262. EXYNOS_MSCTRL_C_INT_IN_2PLANE |
  263. EXYNOS_MSCTRL_ORDER422_YCBYCR);
  264. switch (fmt) {
  265. case DRM_FORMAT_YUYV:
  266. cfg |= EXYNOS_MSCTRL_ORDER422_YCBYCR;
  267. break;
  268. case DRM_FORMAT_YVYU:
  269. cfg |= EXYNOS_MSCTRL_ORDER422_YCRYCB;
  270. break;
  271. case DRM_FORMAT_UYVY:
  272. cfg |= EXYNOS_MSCTRL_ORDER422_CBYCRY;
  273. break;
  274. case DRM_FORMAT_VYUY:
  275. case DRM_FORMAT_YUV444:
  276. cfg |= EXYNOS_MSCTRL_ORDER422_CRYCBY;
  277. break;
  278. case DRM_FORMAT_NV21:
  279. case DRM_FORMAT_NV61:
  280. cfg |= (EXYNOS_MSCTRL_ORDER2P_LSB_CRCB |
  281. EXYNOS_MSCTRL_C_INT_IN_2PLANE);
  282. break;
  283. case DRM_FORMAT_YUV422:
  284. case DRM_FORMAT_YUV420:
  285. case DRM_FORMAT_YVU420:
  286. cfg |= EXYNOS_MSCTRL_C_INT_IN_3PLANE;
  287. break;
  288. case DRM_FORMAT_NV12:
  289. case DRM_FORMAT_NV16:
  290. cfg |= (EXYNOS_MSCTRL_ORDER2P_LSB_CBCR |
  291. EXYNOS_MSCTRL_C_INT_IN_2PLANE);
  292. break;
  293. }
  294. fimc_write(ctx, cfg, EXYNOS_MSCTRL);
  295. }
  296. static void fimc_src_set_fmt(struct fimc_context *ctx, u32 fmt, bool tiled)
  297. {
  298. u32 cfg;
  299. DRM_DEV_DEBUG_KMS(ctx->dev, "fmt[0x%x]\n", fmt);
  300. cfg = fimc_read(ctx, EXYNOS_MSCTRL);
  301. cfg &= ~EXYNOS_MSCTRL_INFORMAT_RGB;
  302. switch (fmt) {
  303. case DRM_FORMAT_RGB565:
  304. case DRM_FORMAT_RGB888:
  305. case DRM_FORMAT_XRGB8888:
  306. cfg |= EXYNOS_MSCTRL_INFORMAT_RGB;
  307. break;
  308. case DRM_FORMAT_YUV444:
  309. cfg |= EXYNOS_MSCTRL_INFORMAT_YCBCR420;
  310. break;
  311. case DRM_FORMAT_YUYV:
  312. case DRM_FORMAT_YVYU:
  313. case DRM_FORMAT_UYVY:
  314. case DRM_FORMAT_VYUY:
  315. cfg |= EXYNOS_MSCTRL_INFORMAT_YCBCR422_1PLANE;
  316. break;
  317. case DRM_FORMAT_NV16:
  318. case DRM_FORMAT_NV61:
  319. case DRM_FORMAT_YUV422:
  320. cfg |= EXYNOS_MSCTRL_INFORMAT_YCBCR422;
  321. break;
  322. case DRM_FORMAT_YUV420:
  323. case DRM_FORMAT_YVU420:
  324. case DRM_FORMAT_NV12:
  325. case DRM_FORMAT_NV21:
  326. cfg |= EXYNOS_MSCTRL_INFORMAT_YCBCR420;
  327. break;
  328. }
  329. fimc_write(ctx, cfg, EXYNOS_MSCTRL);
  330. cfg = fimc_read(ctx, EXYNOS_CIDMAPARAM);
  331. cfg &= ~EXYNOS_CIDMAPARAM_R_MODE_MASK;
  332. if (tiled)
  333. cfg |= EXYNOS_CIDMAPARAM_R_MODE_64X32;
  334. else
  335. cfg |= EXYNOS_CIDMAPARAM_R_MODE_LINEAR;
  336. fimc_write(ctx, cfg, EXYNOS_CIDMAPARAM);
  337. fimc_src_set_fmt_order(ctx, fmt);
  338. }
  339. static void fimc_src_set_transf(struct fimc_context *ctx, unsigned int rotation)
  340. {
  341. unsigned int degree = rotation & DRM_MODE_ROTATE_MASK;
  342. u32 cfg1, cfg2;
  343. DRM_DEV_DEBUG_KMS(ctx->dev, "rotation[%x]\n", rotation);
  344. cfg1 = fimc_read(ctx, EXYNOS_MSCTRL);
  345. cfg1 &= ~(EXYNOS_MSCTRL_FLIP_X_MIRROR |
  346. EXYNOS_MSCTRL_FLIP_Y_MIRROR);
  347. cfg2 = fimc_read(ctx, EXYNOS_CITRGFMT);
  348. cfg2 &= ~EXYNOS_CITRGFMT_INROT90_CLOCKWISE;
  349. switch (degree) {
  350. case DRM_MODE_ROTATE_0:
  351. if (rotation & DRM_MODE_REFLECT_X)
  352. cfg1 |= EXYNOS_MSCTRL_FLIP_X_MIRROR;
  353. if (rotation & DRM_MODE_REFLECT_Y)
  354. cfg1 |= EXYNOS_MSCTRL_FLIP_Y_MIRROR;
  355. break;
  356. case DRM_MODE_ROTATE_90:
  357. cfg2 |= EXYNOS_CITRGFMT_INROT90_CLOCKWISE;
  358. if (rotation & DRM_MODE_REFLECT_X)
  359. cfg1 |= EXYNOS_MSCTRL_FLIP_X_MIRROR;
  360. if (rotation & DRM_MODE_REFLECT_Y)
  361. cfg1 |= EXYNOS_MSCTRL_FLIP_Y_MIRROR;
  362. break;
  363. case DRM_MODE_ROTATE_180:
  364. cfg1 |= (EXYNOS_MSCTRL_FLIP_X_MIRROR |
  365. EXYNOS_MSCTRL_FLIP_Y_MIRROR);
  366. if (rotation & DRM_MODE_REFLECT_X)
  367. cfg1 &= ~EXYNOS_MSCTRL_FLIP_X_MIRROR;
  368. if (rotation & DRM_MODE_REFLECT_Y)
  369. cfg1 &= ~EXYNOS_MSCTRL_FLIP_Y_MIRROR;
  370. break;
  371. case DRM_MODE_ROTATE_270:
  372. cfg1 |= (EXYNOS_MSCTRL_FLIP_X_MIRROR |
  373. EXYNOS_MSCTRL_FLIP_Y_MIRROR);
  374. cfg2 |= EXYNOS_CITRGFMT_INROT90_CLOCKWISE;
  375. if (rotation & DRM_MODE_REFLECT_X)
  376. cfg1 &= ~EXYNOS_MSCTRL_FLIP_X_MIRROR;
  377. if (rotation & DRM_MODE_REFLECT_Y)
  378. cfg1 &= ~EXYNOS_MSCTRL_FLIP_Y_MIRROR;
  379. break;
  380. }
  381. fimc_write(ctx, cfg1, EXYNOS_MSCTRL);
  382. fimc_write(ctx, cfg2, EXYNOS_CITRGFMT);
  383. }
  384. static void fimc_set_window(struct fimc_context *ctx,
  385. struct exynos_drm_ipp_buffer *buf)
  386. {
  387. unsigned int real_width = buf->buf.pitch[0] / buf->format->cpp[0];
  388. u32 cfg, h1, h2, v1, v2;
  389. /* cropped image */
  390. h1 = buf->rect.x;
  391. h2 = real_width - buf->rect.w - buf->rect.x;
  392. v1 = buf->rect.y;
  393. v2 = buf->buf.height - buf->rect.h - buf->rect.y;
  394. DRM_DEV_DEBUG_KMS(ctx->dev, "x[%d]y[%d]w[%d]h[%d]hsize[%d]vsize[%d]\n",
  395. buf->rect.x, buf->rect.y, buf->rect.w, buf->rect.h,
  396. real_width, buf->buf.height);
  397. DRM_DEV_DEBUG_KMS(ctx->dev, "h1[%d]h2[%d]v1[%d]v2[%d]\n", h1, h2, v1,
  398. v2);
  399. /*
  400. * set window offset 1, 2 size
  401. * check figure 43-21 in user manual
  402. */
  403. cfg = fimc_read(ctx, EXYNOS_CIWDOFST);
  404. cfg &= ~(EXYNOS_CIWDOFST_WINHOROFST_MASK |
  405. EXYNOS_CIWDOFST_WINVEROFST_MASK);
  406. cfg |= (EXYNOS_CIWDOFST_WINHOROFST(h1) |
  407. EXYNOS_CIWDOFST_WINVEROFST(v1));
  408. cfg |= EXYNOS_CIWDOFST_WINOFSEN;
  409. fimc_write(ctx, cfg, EXYNOS_CIWDOFST);
  410. cfg = (EXYNOS_CIWDOFST2_WINHOROFST2(h2) |
  411. EXYNOS_CIWDOFST2_WINVEROFST2(v2));
  412. fimc_write(ctx, cfg, EXYNOS_CIWDOFST2);
  413. }
  414. static void fimc_src_set_size(struct fimc_context *ctx,
  415. struct exynos_drm_ipp_buffer *buf)
  416. {
  417. unsigned int real_width = buf->buf.pitch[0] / buf->format->cpp[0];
  418. u32 cfg;
  419. DRM_DEV_DEBUG_KMS(ctx->dev, "hsize[%d]vsize[%d]\n", real_width,
  420. buf->buf.height);
  421. /* original size */
  422. cfg = (EXYNOS_ORGISIZE_HORIZONTAL(real_width) |
  423. EXYNOS_ORGISIZE_VERTICAL(buf->buf.height));
  424. fimc_write(ctx, cfg, EXYNOS_ORGISIZE);
  425. DRM_DEV_DEBUG_KMS(ctx->dev, "x[%d]y[%d]w[%d]h[%d]\n", buf->rect.x,
  426. buf->rect.y, buf->rect.w, buf->rect.h);
  427. /* set input DMA image size */
  428. cfg = fimc_read(ctx, EXYNOS_CIREAL_ISIZE);
  429. cfg &= ~(EXYNOS_CIREAL_ISIZE_HEIGHT_MASK |
  430. EXYNOS_CIREAL_ISIZE_WIDTH_MASK);
  431. cfg |= (EXYNOS_CIREAL_ISIZE_WIDTH(buf->rect.w) |
  432. EXYNOS_CIREAL_ISIZE_HEIGHT(buf->rect.h));
  433. fimc_write(ctx, cfg, EXYNOS_CIREAL_ISIZE);
  434. /*
  435. * set input FIFO image size
  436. * for now, we support only ITU601 8 bit mode
  437. */
  438. cfg = (EXYNOS_CISRCFMT_ITU601_8BIT |
  439. EXYNOS_CISRCFMT_SOURCEHSIZE(real_width) |
  440. EXYNOS_CISRCFMT_SOURCEVSIZE(buf->buf.height));
  441. fimc_write(ctx, cfg, EXYNOS_CISRCFMT);
  442. /* offset Y(RGB), Cb, Cr */
  443. cfg = (EXYNOS_CIIYOFF_HORIZONTAL(buf->rect.x) |
  444. EXYNOS_CIIYOFF_VERTICAL(buf->rect.y));
  445. fimc_write(ctx, cfg, EXYNOS_CIIYOFF);
  446. cfg = (EXYNOS_CIICBOFF_HORIZONTAL(buf->rect.x) |
  447. EXYNOS_CIICBOFF_VERTICAL(buf->rect.y));
  448. fimc_write(ctx, cfg, EXYNOS_CIICBOFF);
  449. cfg = (EXYNOS_CIICROFF_HORIZONTAL(buf->rect.x) |
  450. EXYNOS_CIICROFF_VERTICAL(buf->rect.y));
  451. fimc_write(ctx, cfg, EXYNOS_CIICROFF);
  452. fimc_set_window(ctx, buf);
  453. }
  454. static void fimc_src_set_addr(struct fimc_context *ctx,
  455. struct exynos_drm_ipp_buffer *buf)
  456. {
  457. fimc_write(ctx, buf->dma_addr[0], EXYNOS_CIIYSA(0));
  458. fimc_write(ctx, buf->dma_addr[1], EXYNOS_CIICBSA(0));
  459. fimc_write(ctx, buf->dma_addr[2], EXYNOS_CIICRSA(0));
  460. }
  461. static void fimc_dst_set_fmt_order(struct fimc_context *ctx, u32 fmt)
  462. {
  463. u32 cfg;
  464. DRM_DEV_DEBUG_KMS(ctx->dev, "fmt[0x%x]\n", fmt);
  465. /* RGB */
  466. cfg = fimc_read(ctx, EXYNOS_CISCCTRL);
  467. cfg &= ~EXYNOS_CISCCTRL_OUTRGB_FMT_RGB_MASK;
  468. switch (fmt) {
  469. case DRM_FORMAT_RGB565:
  470. cfg |= EXYNOS_CISCCTRL_OUTRGB_FMT_RGB565;
  471. fimc_write(ctx, cfg, EXYNOS_CISCCTRL);
  472. return;
  473. case DRM_FORMAT_RGB888:
  474. cfg |= EXYNOS_CISCCTRL_OUTRGB_FMT_RGB888;
  475. fimc_write(ctx, cfg, EXYNOS_CISCCTRL);
  476. return;
  477. case DRM_FORMAT_XRGB8888:
  478. cfg |= (EXYNOS_CISCCTRL_OUTRGB_FMT_RGB888 |
  479. EXYNOS_CISCCTRL_EXTRGB_EXTENSION);
  480. fimc_write(ctx, cfg, EXYNOS_CISCCTRL);
  481. break;
  482. default:
  483. /* bypass */
  484. break;
  485. }
  486. /* YUV */
  487. cfg = fimc_read(ctx, EXYNOS_CIOCTRL);
  488. cfg &= ~(EXYNOS_CIOCTRL_ORDER2P_MASK |
  489. EXYNOS_CIOCTRL_ORDER422_MASK |
  490. EXYNOS_CIOCTRL_YCBCR_PLANE_MASK);
  491. switch (fmt) {
  492. case DRM_FORMAT_XRGB8888:
  493. cfg |= EXYNOS_CIOCTRL_ALPHA_OUT;
  494. break;
  495. case DRM_FORMAT_YUYV:
  496. cfg |= EXYNOS_CIOCTRL_ORDER422_YCBYCR;
  497. break;
  498. case DRM_FORMAT_YVYU:
  499. cfg |= EXYNOS_CIOCTRL_ORDER422_YCRYCB;
  500. break;
  501. case DRM_FORMAT_UYVY:
  502. cfg |= EXYNOS_CIOCTRL_ORDER422_CBYCRY;
  503. break;
  504. case DRM_FORMAT_VYUY:
  505. cfg |= EXYNOS_CIOCTRL_ORDER422_CRYCBY;
  506. break;
  507. case DRM_FORMAT_NV21:
  508. case DRM_FORMAT_NV61:
  509. cfg |= EXYNOS_CIOCTRL_ORDER2P_LSB_CRCB;
  510. cfg |= EXYNOS_CIOCTRL_YCBCR_2PLANE;
  511. break;
  512. case DRM_FORMAT_YUV422:
  513. case DRM_FORMAT_YUV420:
  514. case DRM_FORMAT_YVU420:
  515. cfg |= EXYNOS_CIOCTRL_YCBCR_3PLANE;
  516. break;
  517. case DRM_FORMAT_NV12:
  518. case DRM_FORMAT_NV16:
  519. cfg |= EXYNOS_CIOCTRL_ORDER2P_LSB_CBCR;
  520. cfg |= EXYNOS_CIOCTRL_YCBCR_2PLANE;
  521. break;
  522. }
  523. fimc_write(ctx, cfg, EXYNOS_CIOCTRL);
  524. }
  525. static void fimc_dst_set_fmt(struct fimc_context *ctx, u32 fmt, bool tiled)
  526. {
  527. u32 cfg;
  528. DRM_DEV_DEBUG_KMS(ctx->dev, "fmt[0x%x]\n", fmt);
  529. cfg = fimc_read(ctx, EXYNOS_CIEXTEN);
  530. if (fmt == DRM_FORMAT_AYUV) {
  531. cfg |= EXYNOS_CIEXTEN_YUV444_OUT;
  532. fimc_write(ctx, cfg, EXYNOS_CIEXTEN);
  533. } else {
  534. cfg &= ~EXYNOS_CIEXTEN_YUV444_OUT;
  535. fimc_write(ctx, cfg, EXYNOS_CIEXTEN);
  536. cfg = fimc_read(ctx, EXYNOS_CITRGFMT);
  537. cfg &= ~EXYNOS_CITRGFMT_OUTFORMAT_MASK;
  538. switch (fmt) {
  539. case DRM_FORMAT_RGB565:
  540. case DRM_FORMAT_RGB888:
  541. case DRM_FORMAT_XRGB8888:
  542. cfg |= EXYNOS_CITRGFMT_OUTFORMAT_RGB;
  543. break;
  544. case DRM_FORMAT_YUYV:
  545. case DRM_FORMAT_YVYU:
  546. case DRM_FORMAT_UYVY:
  547. case DRM_FORMAT_VYUY:
  548. cfg |= EXYNOS_CITRGFMT_OUTFORMAT_YCBCR422_1PLANE;
  549. break;
  550. case DRM_FORMAT_NV16:
  551. case DRM_FORMAT_NV61:
  552. case DRM_FORMAT_YUV422:
  553. cfg |= EXYNOS_CITRGFMT_OUTFORMAT_YCBCR422;
  554. break;
  555. case DRM_FORMAT_YUV420:
  556. case DRM_FORMAT_YVU420:
  557. case DRM_FORMAT_NV12:
  558. case DRM_FORMAT_NV21:
  559. cfg |= EXYNOS_CITRGFMT_OUTFORMAT_YCBCR420;
  560. break;
  561. }
  562. fimc_write(ctx, cfg, EXYNOS_CITRGFMT);
  563. }
  564. cfg = fimc_read(ctx, EXYNOS_CIDMAPARAM);
  565. cfg &= ~EXYNOS_CIDMAPARAM_W_MODE_MASK;
  566. if (tiled)
  567. cfg |= EXYNOS_CIDMAPARAM_W_MODE_64X32;
  568. else
  569. cfg |= EXYNOS_CIDMAPARAM_W_MODE_LINEAR;
  570. fimc_write(ctx, cfg, EXYNOS_CIDMAPARAM);
  571. fimc_dst_set_fmt_order(ctx, fmt);
  572. }
  573. static void fimc_dst_set_transf(struct fimc_context *ctx, unsigned int rotation)
  574. {
  575. unsigned int degree = rotation & DRM_MODE_ROTATE_MASK;
  576. u32 cfg;
  577. DRM_DEV_DEBUG_KMS(ctx->dev, "rotation[0x%x]\n", rotation);
  578. cfg = fimc_read(ctx, EXYNOS_CITRGFMT);
  579. cfg &= ~EXYNOS_CITRGFMT_FLIP_MASK;
  580. cfg &= ~EXYNOS_CITRGFMT_OUTROT90_CLOCKWISE;
  581. switch (degree) {
  582. case DRM_MODE_ROTATE_0:
  583. if (rotation & DRM_MODE_REFLECT_X)
  584. cfg |= EXYNOS_CITRGFMT_FLIP_X_MIRROR;
  585. if (rotation & DRM_MODE_REFLECT_Y)
  586. cfg |= EXYNOS_CITRGFMT_FLIP_Y_MIRROR;
  587. break;
  588. case DRM_MODE_ROTATE_90:
  589. cfg |= EXYNOS_CITRGFMT_OUTROT90_CLOCKWISE;
  590. if (rotation & DRM_MODE_REFLECT_X)
  591. cfg |= EXYNOS_CITRGFMT_FLIP_X_MIRROR;
  592. if (rotation & DRM_MODE_REFLECT_Y)
  593. cfg |= EXYNOS_CITRGFMT_FLIP_Y_MIRROR;
  594. break;
  595. case DRM_MODE_ROTATE_180:
  596. cfg |= (EXYNOS_CITRGFMT_FLIP_X_MIRROR |
  597. EXYNOS_CITRGFMT_FLIP_Y_MIRROR);
  598. if (rotation & DRM_MODE_REFLECT_X)
  599. cfg &= ~EXYNOS_CITRGFMT_FLIP_X_MIRROR;
  600. if (rotation & DRM_MODE_REFLECT_Y)
  601. cfg &= ~EXYNOS_CITRGFMT_FLIP_Y_MIRROR;
  602. break;
  603. case DRM_MODE_ROTATE_270:
  604. cfg |= (EXYNOS_CITRGFMT_OUTROT90_CLOCKWISE |
  605. EXYNOS_CITRGFMT_FLIP_X_MIRROR |
  606. EXYNOS_CITRGFMT_FLIP_Y_MIRROR);
  607. if (rotation & DRM_MODE_REFLECT_X)
  608. cfg &= ~EXYNOS_CITRGFMT_FLIP_X_MIRROR;
  609. if (rotation & DRM_MODE_REFLECT_Y)
  610. cfg &= ~EXYNOS_CITRGFMT_FLIP_Y_MIRROR;
  611. break;
  612. }
  613. fimc_write(ctx, cfg, EXYNOS_CITRGFMT);
  614. }
  615. static int fimc_set_prescaler(struct fimc_context *ctx, struct fimc_scaler *sc,
  616. struct drm_exynos_ipp_task_rect *src,
  617. struct drm_exynos_ipp_task_rect *dst)
  618. {
  619. u32 cfg, cfg_ext, shfactor;
  620. u32 pre_dst_width, pre_dst_height;
  621. u32 hfactor, vfactor;
  622. int ret = 0;
  623. u32 src_w, src_h, dst_w, dst_h;
  624. cfg_ext = fimc_read(ctx, EXYNOS_CITRGFMT);
  625. if (cfg_ext & EXYNOS_CITRGFMT_INROT90_CLOCKWISE) {
  626. src_w = src->h;
  627. src_h = src->w;
  628. } else {
  629. src_w = src->w;
  630. src_h = src->h;
  631. }
  632. if (cfg_ext & EXYNOS_CITRGFMT_OUTROT90_CLOCKWISE) {
  633. dst_w = dst->h;
  634. dst_h = dst->w;
  635. } else {
  636. dst_w = dst->w;
  637. dst_h = dst->h;
  638. }
  639. /* fimc_ippdrv_check_property assures that dividers are not null */
  640. hfactor = fls(src_w / dst_w / 2);
  641. if (hfactor > FIMC_SHFACTOR / 2) {
  642. dev_err(ctx->dev, "failed to get ratio horizontal.\n");
  643. return -EINVAL;
  644. }
  645. vfactor = fls(src_h / dst_h / 2);
  646. if (vfactor > FIMC_SHFACTOR / 2) {
  647. dev_err(ctx->dev, "failed to get ratio vertical.\n");
  648. return -EINVAL;
  649. }
  650. pre_dst_width = src_w >> hfactor;
  651. pre_dst_height = src_h >> vfactor;
  652. DRM_DEV_DEBUG_KMS(ctx->dev, "pre_dst_width[%d]pre_dst_height[%d]\n",
  653. pre_dst_width, pre_dst_height);
  654. DRM_DEV_DEBUG_KMS(ctx->dev, "hfactor[%d]vfactor[%d]\n", hfactor,
  655. vfactor);
  656. sc->hratio = (src_w << 14) / (dst_w << hfactor);
  657. sc->vratio = (src_h << 14) / (dst_h << vfactor);
  658. sc->up_h = (dst_w >= src_w);
  659. sc->up_v = (dst_h >= src_h);
  660. DRM_DEV_DEBUG_KMS(ctx->dev, "hratio[%d]vratio[%d]up_h[%d]up_v[%d]\n",
  661. sc->hratio, sc->vratio, sc->up_h, sc->up_v);
  662. shfactor = FIMC_SHFACTOR - (hfactor + vfactor);
  663. DRM_DEV_DEBUG_KMS(ctx->dev, "shfactor[%d]\n", shfactor);
  664. cfg = (EXYNOS_CISCPRERATIO_SHFACTOR(shfactor) |
  665. EXYNOS_CISCPRERATIO_PREHORRATIO(1 << hfactor) |
  666. EXYNOS_CISCPRERATIO_PREVERRATIO(1 << vfactor));
  667. fimc_write(ctx, cfg, EXYNOS_CISCPRERATIO);
  668. cfg = (EXYNOS_CISCPREDST_PREDSTWIDTH(pre_dst_width) |
  669. EXYNOS_CISCPREDST_PREDSTHEIGHT(pre_dst_height));
  670. fimc_write(ctx, cfg, EXYNOS_CISCPREDST);
  671. return ret;
  672. }
  673. static void fimc_set_scaler(struct fimc_context *ctx, struct fimc_scaler *sc)
  674. {
  675. u32 cfg, cfg_ext;
  676. DRM_DEV_DEBUG_KMS(ctx->dev, "range[%d]bypass[%d]up_h[%d]up_v[%d]\n",
  677. sc->range, sc->bypass, sc->up_h, sc->up_v);
  678. DRM_DEV_DEBUG_KMS(ctx->dev, "hratio[%d]vratio[%d]\n",
  679. sc->hratio, sc->vratio);
  680. cfg = fimc_read(ctx, EXYNOS_CISCCTRL);
  681. cfg &= ~(EXYNOS_CISCCTRL_SCALERBYPASS |
  682. EXYNOS_CISCCTRL_SCALEUP_H | EXYNOS_CISCCTRL_SCALEUP_V |
  683. EXYNOS_CISCCTRL_MAIN_V_RATIO_MASK |
  684. EXYNOS_CISCCTRL_MAIN_H_RATIO_MASK |
  685. EXYNOS_CISCCTRL_CSCR2Y_WIDE |
  686. EXYNOS_CISCCTRL_CSCY2R_WIDE);
  687. if (sc->range)
  688. cfg |= (EXYNOS_CISCCTRL_CSCR2Y_WIDE |
  689. EXYNOS_CISCCTRL_CSCY2R_WIDE);
  690. if (sc->bypass)
  691. cfg |= EXYNOS_CISCCTRL_SCALERBYPASS;
  692. if (sc->up_h)
  693. cfg |= EXYNOS_CISCCTRL_SCALEUP_H;
  694. if (sc->up_v)
  695. cfg |= EXYNOS_CISCCTRL_SCALEUP_V;
  696. cfg |= (EXYNOS_CISCCTRL_MAINHORRATIO((sc->hratio >> 6)) |
  697. EXYNOS_CISCCTRL_MAINVERRATIO((sc->vratio >> 6)));
  698. fimc_write(ctx, cfg, EXYNOS_CISCCTRL);
  699. cfg_ext = fimc_read(ctx, EXYNOS_CIEXTEN);
  700. cfg_ext &= ~EXYNOS_CIEXTEN_MAINHORRATIO_EXT_MASK;
  701. cfg_ext &= ~EXYNOS_CIEXTEN_MAINVERRATIO_EXT_MASK;
  702. cfg_ext |= (EXYNOS_CIEXTEN_MAINHORRATIO_EXT(sc->hratio) |
  703. EXYNOS_CIEXTEN_MAINVERRATIO_EXT(sc->vratio));
  704. fimc_write(ctx, cfg_ext, EXYNOS_CIEXTEN);
  705. }
  706. static void fimc_dst_set_size(struct fimc_context *ctx,
  707. struct exynos_drm_ipp_buffer *buf)
  708. {
  709. unsigned int real_width = buf->buf.pitch[0] / buf->format->cpp[0];
  710. u32 cfg, cfg_ext;
  711. DRM_DEV_DEBUG_KMS(ctx->dev, "hsize[%d]vsize[%d]\n", real_width,
  712. buf->buf.height);
  713. /* original size */
  714. cfg = (EXYNOS_ORGOSIZE_HORIZONTAL(real_width) |
  715. EXYNOS_ORGOSIZE_VERTICAL(buf->buf.height));
  716. fimc_write(ctx, cfg, EXYNOS_ORGOSIZE);
  717. DRM_DEV_DEBUG_KMS(ctx->dev, "x[%d]y[%d]w[%d]h[%d]\n", buf->rect.x,
  718. buf->rect.y,
  719. buf->rect.w, buf->rect.h);
  720. /* CSC ITU */
  721. cfg = fimc_read(ctx, EXYNOS_CIGCTRL);
  722. cfg &= ~EXYNOS_CIGCTRL_CSC_MASK;
  723. if (buf->buf.width >= FIMC_WIDTH_ITU_709)
  724. cfg |= EXYNOS_CIGCTRL_CSC_ITU709;
  725. else
  726. cfg |= EXYNOS_CIGCTRL_CSC_ITU601;
  727. fimc_write(ctx, cfg, EXYNOS_CIGCTRL);
  728. cfg_ext = fimc_read(ctx, EXYNOS_CITRGFMT);
  729. /* target image size */
  730. cfg = fimc_read(ctx, EXYNOS_CITRGFMT);
  731. cfg &= ~(EXYNOS_CITRGFMT_TARGETH_MASK |
  732. EXYNOS_CITRGFMT_TARGETV_MASK);
  733. if (cfg_ext & EXYNOS_CITRGFMT_OUTROT90_CLOCKWISE)
  734. cfg |= (EXYNOS_CITRGFMT_TARGETHSIZE(buf->rect.h) |
  735. EXYNOS_CITRGFMT_TARGETVSIZE(buf->rect.w));
  736. else
  737. cfg |= (EXYNOS_CITRGFMT_TARGETHSIZE(buf->rect.w) |
  738. EXYNOS_CITRGFMT_TARGETVSIZE(buf->rect.h));
  739. fimc_write(ctx, cfg, EXYNOS_CITRGFMT);
  740. /* target area */
  741. cfg = EXYNOS_CITAREA_TARGET_AREA(buf->rect.w * buf->rect.h);
  742. fimc_write(ctx, cfg, EXYNOS_CITAREA);
  743. /* offset Y(RGB), Cb, Cr */
  744. cfg = (EXYNOS_CIOYOFF_HORIZONTAL(buf->rect.x) |
  745. EXYNOS_CIOYOFF_VERTICAL(buf->rect.y));
  746. fimc_write(ctx, cfg, EXYNOS_CIOYOFF);
  747. cfg = (EXYNOS_CIOCBOFF_HORIZONTAL(buf->rect.x) |
  748. EXYNOS_CIOCBOFF_VERTICAL(buf->rect.y));
  749. fimc_write(ctx, cfg, EXYNOS_CIOCBOFF);
  750. cfg = (EXYNOS_CIOCROFF_HORIZONTAL(buf->rect.x) |
  751. EXYNOS_CIOCROFF_VERTICAL(buf->rect.y));
  752. fimc_write(ctx, cfg, EXYNOS_CIOCROFF);
  753. }
  754. static void fimc_dst_set_buf_seq(struct fimc_context *ctx, u32 buf_id,
  755. bool enqueue)
  756. {
  757. unsigned long flags;
  758. u32 buf_num;
  759. u32 cfg;
  760. DRM_DEV_DEBUG_KMS(ctx->dev, "buf_id[%d]enqueu[%d]\n", buf_id, enqueue);
  761. spin_lock_irqsave(&ctx->lock, flags);
  762. cfg = fimc_read(ctx, EXYNOS_CIFCNTSEQ);
  763. if (enqueue)
  764. cfg |= (1 << buf_id);
  765. else
  766. cfg &= ~(1 << buf_id);
  767. fimc_write(ctx, cfg, EXYNOS_CIFCNTSEQ);
  768. buf_num = hweight32(cfg);
  769. if (enqueue && buf_num >= FIMC_BUF_START)
  770. fimc_mask_irq(ctx, true);
  771. else if (!enqueue && buf_num <= FIMC_BUF_STOP)
  772. fimc_mask_irq(ctx, false);
  773. spin_unlock_irqrestore(&ctx->lock, flags);
  774. }
  775. static void fimc_dst_set_addr(struct fimc_context *ctx,
  776. struct exynos_drm_ipp_buffer *buf)
  777. {
  778. fimc_write(ctx, buf->dma_addr[0], EXYNOS_CIOYSA(0));
  779. fimc_write(ctx, buf->dma_addr[1], EXYNOS_CIOCBSA(0));
  780. fimc_write(ctx, buf->dma_addr[2], EXYNOS_CIOCRSA(0));
  781. fimc_dst_set_buf_seq(ctx, 0, true);
  782. }
  783. static void fimc_stop(struct fimc_context *ctx);
  784. static irqreturn_t fimc_irq_handler(int irq, void *dev_id)
  785. {
  786. struct fimc_context *ctx = dev_id;
  787. int buf_id;
  788. DRM_DEV_DEBUG_KMS(ctx->dev, "fimc id[%d]\n", ctx->id);
  789. fimc_clear_irq(ctx);
  790. if (fimc_check_ovf(ctx))
  791. return IRQ_NONE;
  792. if (!fimc_check_frame_end(ctx))
  793. return IRQ_NONE;
  794. buf_id = fimc_get_buf_id(ctx);
  795. if (buf_id < 0)
  796. return IRQ_HANDLED;
  797. DRM_DEV_DEBUG_KMS(ctx->dev, "buf_id[%d]\n", buf_id);
  798. if (ctx->task) {
  799. struct exynos_drm_ipp_task *task = ctx->task;
  800. ctx->task = NULL;
  801. pm_runtime_mark_last_busy(ctx->dev);
  802. pm_runtime_put_autosuspend(ctx->dev);
  803. exynos_drm_ipp_task_done(task, 0);
  804. }
  805. fimc_dst_set_buf_seq(ctx, buf_id, false);
  806. fimc_stop(ctx);
  807. return IRQ_HANDLED;
  808. }
  809. static void fimc_clear_addr(struct fimc_context *ctx)
  810. {
  811. int i;
  812. for (i = 0; i < FIMC_MAX_SRC; i++) {
  813. fimc_write(ctx, 0, EXYNOS_CIIYSA(i));
  814. fimc_write(ctx, 0, EXYNOS_CIICBSA(i));
  815. fimc_write(ctx, 0, EXYNOS_CIICRSA(i));
  816. }
  817. for (i = 0; i < FIMC_MAX_DST; i++) {
  818. fimc_write(ctx, 0, EXYNOS_CIOYSA(i));
  819. fimc_write(ctx, 0, EXYNOS_CIOCBSA(i));
  820. fimc_write(ctx, 0, EXYNOS_CIOCRSA(i));
  821. }
  822. }
  823. static void fimc_reset(struct fimc_context *ctx)
  824. {
  825. /* reset h/w block */
  826. fimc_sw_reset(ctx);
  827. /* reset scaler capability */
  828. memset(&ctx->sc, 0x0, sizeof(ctx->sc));
  829. fimc_clear_addr(ctx);
  830. }
  831. static void fimc_start(struct fimc_context *ctx)
  832. {
  833. u32 cfg0, cfg1;
  834. fimc_mask_irq(ctx, true);
  835. /* If set true, we can save jpeg about screen */
  836. fimc_handle_jpeg(ctx, false);
  837. fimc_set_scaler(ctx, &ctx->sc);
  838. fimc_set_type_ctrl(ctx);
  839. fimc_handle_lastend(ctx, false);
  840. /* setup dma */
  841. cfg0 = fimc_read(ctx, EXYNOS_MSCTRL);
  842. cfg0 &= ~EXYNOS_MSCTRL_INPUT_MASK;
  843. cfg0 |= EXYNOS_MSCTRL_INPUT_MEMORY;
  844. fimc_write(ctx, cfg0, EXYNOS_MSCTRL);
  845. /* Reset status */
  846. fimc_write(ctx, 0x0, EXYNOS_CISTATUS);
  847. cfg0 = fimc_read(ctx, EXYNOS_CIIMGCPT);
  848. cfg0 &= ~EXYNOS_CIIMGCPT_IMGCPTEN_SC;
  849. cfg0 |= EXYNOS_CIIMGCPT_IMGCPTEN_SC;
  850. /* Scaler */
  851. cfg1 = fimc_read(ctx, EXYNOS_CISCCTRL);
  852. cfg1 &= ~EXYNOS_CISCCTRL_SCAN_MASK;
  853. cfg1 |= (EXYNOS_CISCCTRL_PROGRESSIVE |
  854. EXYNOS_CISCCTRL_SCALERSTART);
  855. fimc_write(ctx, cfg1, EXYNOS_CISCCTRL);
  856. /* Enable image capture*/
  857. cfg0 |= EXYNOS_CIIMGCPT_IMGCPTEN;
  858. fimc_write(ctx, cfg0, EXYNOS_CIIMGCPT);
  859. /* Disable frame end irq */
  860. fimc_clear_bits(ctx, EXYNOS_CIGCTRL, EXYNOS_CIGCTRL_IRQ_END_DISABLE);
  861. fimc_clear_bits(ctx, EXYNOS_CIOCTRL, EXYNOS_CIOCTRL_WEAVE_MASK);
  862. fimc_set_bits(ctx, EXYNOS_MSCTRL, EXYNOS_MSCTRL_ENVID);
  863. }
  864. static void fimc_stop(struct fimc_context *ctx)
  865. {
  866. u32 cfg;
  867. /* Source clear */
  868. cfg = fimc_read(ctx, EXYNOS_MSCTRL);
  869. cfg &= ~EXYNOS_MSCTRL_INPUT_MASK;
  870. cfg &= ~EXYNOS_MSCTRL_ENVID;
  871. fimc_write(ctx, cfg, EXYNOS_MSCTRL);
  872. fimc_mask_irq(ctx, false);
  873. /* reset sequence */
  874. fimc_write(ctx, 0x0, EXYNOS_CIFCNTSEQ);
  875. /* Scaler disable */
  876. fimc_clear_bits(ctx, EXYNOS_CISCCTRL, EXYNOS_CISCCTRL_SCALERSTART);
  877. /* Disable image capture */
  878. fimc_clear_bits(ctx, EXYNOS_CIIMGCPT,
  879. EXYNOS_CIIMGCPT_IMGCPTEN_SC | EXYNOS_CIIMGCPT_IMGCPTEN);
  880. /* Enable frame end irq */
  881. fimc_set_bits(ctx, EXYNOS_CIGCTRL, EXYNOS_CIGCTRL_IRQ_END_DISABLE);
  882. }
  883. static int fimc_commit(struct exynos_drm_ipp *ipp,
  884. struct exynos_drm_ipp_task *task)
  885. {
  886. struct fimc_context *ctx =
  887. container_of(ipp, struct fimc_context, ipp);
  888. int ret;
  889. ret = pm_runtime_resume_and_get(ctx->dev);
  890. if (ret < 0) {
  891. dev_err(ctx->dev, "failed to enable FIMC device.\n");
  892. return ret;
  893. }
  894. ctx->task = task;
  895. fimc_src_set_fmt(ctx, task->src.buf.fourcc, task->src.buf.modifier);
  896. fimc_src_set_size(ctx, &task->src);
  897. fimc_src_set_transf(ctx, DRM_MODE_ROTATE_0);
  898. fimc_src_set_addr(ctx, &task->src);
  899. fimc_dst_set_fmt(ctx, task->dst.buf.fourcc, task->dst.buf.modifier);
  900. fimc_dst_set_transf(ctx, task->transform.rotation);
  901. fimc_dst_set_size(ctx, &task->dst);
  902. fimc_dst_set_addr(ctx, &task->dst);
  903. fimc_set_prescaler(ctx, &ctx->sc, &task->src.rect, &task->dst.rect);
  904. fimc_start(ctx);
  905. return 0;
  906. }
  907. static void fimc_abort(struct exynos_drm_ipp *ipp,
  908. struct exynos_drm_ipp_task *task)
  909. {
  910. struct fimc_context *ctx =
  911. container_of(ipp, struct fimc_context, ipp);
  912. fimc_reset(ctx);
  913. if (ctx->task) {
  914. struct exynos_drm_ipp_task *task = ctx->task;
  915. ctx->task = NULL;
  916. pm_runtime_mark_last_busy(ctx->dev);
  917. pm_runtime_put_autosuspend(ctx->dev);
  918. exynos_drm_ipp_task_done(task, -EIO);
  919. }
  920. }
  921. static const struct exynos_drm_ipp_funcs ipp_funcs = {
  922. .commit = fimc_commit,
  923. .abort = fimc_abort,
  924. };
  925. static int fimc_bind(struct device *dev, struct device *master, void *data)
  926. {
  927. struct fimc_context *ctx = dev_get_drvdata(dev);
  928. struct drm_device *drm_dev = data;
  929. struct exynos_drm_ipp *ipp = &ctx->ipp;
  930. ctx->drm_dev = drm_dev;
  931. ipp->drm_dev = drm_dev;
  932. exynos_drm_register_dma(drm_dev, dev, &ctx->dma_priv);
  933. exynos_drm_ipp_register(dev, ipp, &ipp_funcs,
  934. DRM_EXYNOS_IPP_CAP_CROP | DRM_EXYNOS_IPP_CAP_ROTATE |
  935. DRM_EXYNOS_IPP_CAP_SCALE | DRM_EXYNOS_IPP_CAP_CONVERT,
  936. ctx->formats, ctx->num_formats, "fimc");
  937. dev_info(dev, "The exynos fimc has been probed successfully\n");
  938. return 0;
  939. }
  940. static void fimc_unbind(struct device *dev, struct device *master,
  941. void *data)
  942. {
  943. struct fimc_context *ctx = dev_get_drvdata(dev);
  944. struct drm_device *drm_dev = data;
  945. struct exynos_drm_ipp *ipp = &ctx->ipp;
  946. exynos_drm_ipp_unregister(dev, ipp);
  947. exynos_drm_unregister_dma(drm_dev, dev, &ctx->dma_priv);
  948. }
  949. static const struct component_ops fimc_component_ops = {
  950. .bind = fimc_bind,
  951. .unbind = fimc_unbind,
  952. };
  953. static void fimc_put_clocks(struct fimc_context *ctx)
  954. {
  955. int i;
  956. for (i = 0; i < FIMC_CLKS_MAX; i++) {
  957. if (IS_ERR(ctx->clocks[i]))
  958. continue;
  959. clk_put(ctx->clocks[i]);
  960. ctx->clocks[i] = ERR_PTR(-EINVAL);
  961. }
  962. }
  963. static int fimc_setup_clocks(struct fimc_context *ctx)
  964. {
  965. struct device *fimc_dev = ctx->dev;
  966. struct device *dev;
  967. int ret, i;
  968. for (i = 0; i < FIMC_CLKS_MAX; i++)
  969. ctx->clocks[i] = ERR_PTR(-EINVAL);
  970. for (i = 0; i < FIMC_CLKS_MAX; i++) {
  971. if (i == FIMC_CLK_WB_A || i == FIMC_CLK_WB_B)
  972. dev = fimc_dev->parent;
  973. else
  974. dev = fimc_dev;
  975. ctx->clocks[i] = clk_get(dev, fimc_clock_names[i]);
  976. if (IS_ERR(ctx->clocks[i])) {
  977. ret = PTR_ERR(ctx->clocks[i]);
  978. dev_err(fimc_dev, "failed to get clock: %s\n",
  979. fimc_clock_names[i]);
  980. goto e_clk_free;
  981. }
  982. }
  983. ret = clk_prepare_enable(ctx->clocks[FIMC_CLK_LCLK]);
  984. if (!ret)
  985. return ret;
  986. e_clk_free:
  987. fimc_put_clocks(ctx);
  988. return ret;
  989. }
  990. int exynos_drm_check_fimc_device(struct device *dev)
  991. {
  992. int id = of_alias_get_id(dev->of_node, "fimc");
  993. if (id >= 0 && (BIT(id) & fimc_mask))
  994. return 0;
  995. return -ENODEV;
  996. }
  997. static const unsigned int fimc_formats[] = {
  998. DRM_FORMAT_XRGB8888, DRM_FORMAT_RGB565,
  999. DRM_FORMAT_NV12, DRM_FORMAT_NV16, DRM_FORMAT_NV21, DRM_FORMAT_NV61,
  1000. DRM_FORMAT_UYVY, DRM_FORMAT_VYUY, DRM_FORMAT_YUYV, DRM_FORMAT_YVYU,
  1001. DRM_FORMAT_YUV420, DRM_FORMAT_YVU420, DRM_FORMAT_YUV422,
  1002. DRM_FORMAT_YUV444,
  1003. };
  1004. static const unsigned int fimc_tiled_formats[] = {
  1005. DRM_FORMAT_NV12, DRM_FORMAT_NV21,
  1006. };
  1007. static const struct drm_exynos_ipp_limit fimc_4210_limits_v1[] = {
  1008. { IPP_SIZE_LIMIT(BUFFER, .h = { 16, 8192, 8 }, .v = { 16, 8192, 2 }) },
  1009. { IPP_SIZE_LIMIT(AREA, .h = { 16, 4224, 2 }, .v = { 16, 0, 2 }) },
  1010. { IPP_SIZE_LIMIT(ROTATED, .h = { 128, 1920 }, .v = { 128, 0 }) },
  1011. { IPP_SCALE_LIMIT(.h = { (1 << 16) / 64, (1 << 16) * 64 },
  1012. .v = { (1 << 16) / 64, (1 << 16) * 64 }) },
  1013. };
  1014. static const struct drm_exynos_ipp_limit fimc_4210_limits_v2[] = {
  1015. { IPP_SIZE_LIMIT(BUFFER, .h = { 16, 8192, 8 }, .v = { 16, 8192, 2 }) },
  1016. { IPP_SIZE_LIMIT(AREA, .h = { 16, 1920, 2 }, .v = { 16, 0, 2 }) },
  1017. { IPP_SIZE_LIMIT(ROTATED, .h = { 128, 1366 }, .v = { 128, 0 }) },
  1018. { IPP_SCALE_LIMIT(.h = { (1 << 16) / 64, (1 << 16) * 64 },
  1019. .v = { (1 << 16) / 64, (1 << 16) * 64 }) },
  1020. };
  1021. static const struct drm_exynos_ipp_limit fimc_4210_limits_tiled_v1[] = {
  1022. { IPP_SIZE_LIMIT(BUFFER, .h = { 128, 1920, 128 }, .v = { 32, 1920, 32 }) },
  1023. { IPP_SIZE_LIMIT(AREA, .h = { 128, 1920, 2 }, .v = { 128, 0, 2 }) },
  1024. { IPP_SCALE_LIMIT(.h = { (1 << 16) / 64, (1 << 16) * 64 },
  1025. .v = { (1 << 16) / 64, (1 << 16) * 64 }) },
  1026. };
  1027. static const struct drm_exynos_ipp_limit fimc_4210_limits_tiled_v2[] = {
  1028. { IPP_SIZE_LIMIT(BUFFER, .h = { 128, 1920, 128 }, .v = { 32, 1920, 32 }) },
  1029. { IPP_SIZE_LIMIT(AREA, .h = { 128, 1366, 2 }, .v = { 128, 0, 2 }) },
  1030. { IPP_SCALE_LIMIT(.h = { (1 << 16) / 64, (1 << 16) * 64 },
  1031. .v = { (1 << 16) / 64, (1 << 16) * 64 }) },
  1032. };
  1033. static int fimc_probe(struct platform_device *pdev)
  1034. {
  1035. const struct drm_exynos_ipp_limit *limits;
  1036. struct exynos_drm_ipp_formats *formats;
  1037. struct device *dev = &pdev->dev;
  1038. struct fimc_context *ctx;
  1039. int ret;
  1040. int i, j, num_limits, num_formats;
  1041. if (exynos_drm_check_fimc_device(dev) != 0)
  1042. return -ENODEV;
  1043. ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL);
  1044. if (!ctx)
  1045. return -ENOMEM;
  1046. ctx->dev = dev;
  1047. ctx->id = of_alias_get_id(dev->of_node, "fimc");
  1048. /* construct formats/limits array */
  1049. num_formats = ARRAY_SIZE(fimc_formats) + ARRAY_SIZE(fimc_tiled_formats);
  1050. formats = devm_kcalloc(dev, num_formats, sizeof(*formats),
  1051. GFP_KERNEL);
  1052. if (!formats)
  1053. return -ENOMEM;
  1054. /* linear formats */
  1055. if (ctx->id < 3) {
  1056. limits = fimc_4210_limits_v1;
  1057. num_limits = ARRAY_SIZE(fimc_4210_limits_v1);
  1058. } else {
  1059. limits = fimc_4210_limits_v2;
  1060. num_limits = ARRAY_SIZE(fimc_4210_limits_v2);
  1061. }
  1062. for (i = 0; i < ARRAY_SIZE(fimc_formats); i++) {
  1063. formats[i].fourcc = fimc_formats[i];
  1064. formats[i].type = DRM_EXYNOS_IPP_FORMAT_SOURCE |
  1065. DRM_EXYNOS_IPP_FORMAT_DESTINATION;
  1066. formats[i].limits = limits;
  1067. formats[i].num_limits = num_limits;
  1068. }
  1069. /* tiled formats */
  1070. if (ctx->id < 3) {
  1071. limits = fimc_4210_limits_tiled_v1;
  1072. num_limits = ARRAY_SIZE(fimc_4210_limits_tiled_v1);
  1073. } else {
  1074. limits = fimc_4210_limits_tiled_v2;
  1075. num_limits = ARRAY_SIZE(fimc_4210_limits_tiled_v2);
  1076. }
  1077. for (j = i, i = 0; i < ARRAY_SIZE(fimc_tiled_formats); j++, i++) {
  1078. formats[j].fourcc = fimc_tiled_formats[i];
  1079. formats[j].modifier = DRM_FORMAT_MOD_SAMSUNG_64_32_TILE;
  1080. formats[j].type = DRM_EXYNOS_IPP_FORMAT_SOURCE |
  1081. DRM_EXYNOS_IPP_FORMAT_DESTINATION;
  1082. formats[j].limits = limits;
  1083. formats[j].num_limits = num_limits;
  1084. }
  1085. ctx->formats = formats;
  1086. ctx->num_formats = num_formats;
  1087. /* resource memory */
  1088. ctx->regs = devm_platform_ioremap_resource(pdev, 0);
  1089. if (IS_ERR(ctx->regs))
  1090. return PTR_ERR(ctx->regs);
  1091. /* resource irq */
  1092. ret = platform_get_irq(pdev, 0);
  1093. if (ret < 0)
  1094. return ret;
  1095. ret = devm_request_irq(dev, ret, fimc_irq_handler,
  1096. 0, dev_name(dev), ctx);
  1097. if (ret < 0) {
  1098. dev_err(dev, "failed to request irq.\n");
  1099. return ret;
  1100. }
  1101. ret = fimc_setup_clocks(ctx);
  1102. if (ret < 0)
  1103. return ret;
  1104. spin_lock_init(&ctx->lock);
  1105. platform_set_drvdata(pdev, ctx);
  1106. pm_runtime_use_autosuspend(dev);
  1107. pm_runtime_set_autosuspend_delay(dev, FIMC_AUTOSUSPEND_DELAY);
  1108. pm_runtime_enable(dev);
  1109. ret = component_add(dev, &fimc_component_ops);
  1110. if (ret)
  1111. goto err_pm_dis;
  1112. dev_info(dev, "drm fimc registered successfully.\n");
  1113. return 0;
  1114. err_pm_dis:
  1115. pm_runtime_dont_use_autosuspend(dev);
  1116. pm_runtime_disable(dev);
  1117. fimc_put_clocks(ctx);
  1118. return ret;
  1119. }
  1120. static void fimc_remove(struct platform_device *pdev)
  1121. {
  1122. struct device *dev = &pdev->dev;
  1123. struct fimc_context *ctx = get_fimc_context(dev);
  1124. component_del(dev, &fimc_component_ops);
  1125. pm_runtime_dont_use_autosuspend(dev);
  1126. pm_runtime_disable(dev);
  1127. fimc_put_clocks(ctx);
  1128. }
  1129. static int fimc_runtime_suspend(struct device *dev)
  1130. {
  1131. struct fimc_context *ctx = get_fimc_context(dev);
  1132. DRM_DEV_DEBUG_KMS(dev, "id[%d]\n", ctx->id);
  1133. clk_disable_unprepare(ctx->clocks[FIMC_CLK_GATE]);
  1134. return 0;
  1135. }
  1136. static int fimc_runtime_resume(struct device *dev)
  1137. {
  1138. struct fimc_context *ctx = get_fimc_context(dev);
  1139. DRM_DEV_DEBUG_KMS(dev, "id[%d]\n", ctx->id);
  1140. return clk_prepare_enable(ctx->clocks[FIMC_CLK_GATE]);
  1141. }
  1142. static DEFINE_RUNTIME_DEV_PM_OPS(fimc_pm_ops, fimc_runtime_suspend,
  1143. fimc_runtime_resume, NULL);
  1144. static const struct of_device_id fimc_of_match[] = {
  1145. { .compatible = "samsung,exynos4210-fimc" },
  1146. { .compatible = "samsung,exynos4212-fimc" },
  1147. { },
  1148. };
  1149. MODULE_DEVICE_TABLE(of, fimc_of_match);
  1150. struct platform_driver fimc_driver = {
  1151. .probe = fimc_probe,
  1152. .remove_new = fimc_remove,
  1153. .driver = {
  1154. .of_match_table = fimc_of_match,
  1155. .name = "exynos-drm-fimc",
  1156. .pm = pm_ptr(&fimc_pm_ops),
  1157. },
  1158. };