exynos_mixer.c 33 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305
  1. /*
  2. * Copyright (C) 2011 Samsung Electronics Co.Ltd
  3. * Authors:
  4. * Seung-Woo Kim <sw0312.kim@samsung.com>
  5. * Inki Dae <inki.dae@samsung.com>
  6. * Joonyoung Shim <jy0922.shim@samsung.com>
  7. *
  8. * Based on drivers/media/video/s5p-tv/mixer_reg.c
  9. *
  10. * This program is free software; you can redistribute it and/or modify it
  11. * under the terms of the GNU General Public License as published by the
  12. * Free Software Foundation; either version 2 of the License, or (at your
  13. * option) any later version.
  14. *
  15. */
  16. #include <drm/drmP.h>
  17. #include "regs-mixer.h"
  18. #include "regs-vp.h"
  19. #include <linux/kernel.h>
  20. #include <linux/spinlock.h>
  21. #include <linux/wait.h>
  22. #include <linux/i2c.h>
  23. #include <linux/platform_device.h>
  24. #include <linux/interrupt.h>
  25. #include <linux/irq.h>
  26. #include <linux/delay.h>
  27. #include <linux/pm_runtime.h>
  28. #include <linux/clk.h>
  29. #include <linux/regulator/consumer.h>
  30. #include <linux/of.h>
  31. #include <linux/component.h>
  32. #include <drm/exynos_drm.h>
  33. #include "exynos_drm_drv.h"
  34. #include "exynos_drm_crtc.h"
  35. #include "exynos_drm_plane.h"
  36. #include "exynos_drm_iommu.h"
  37. #define MIXER_WIN_NR 3
  38. #define VP_DEFAULT_WIN 2
  39. #define CURSOR_WIN 1
  40. /* The pixelformats that are natively supported by the mixer. */
  41. #define MXR_FORMAT_RGB565 4
  42. #define MXR_FORMAT_ARGB1555 5
  43. #define MXR_FORMAT_ARGB4444 6
  44. #define MXR_FORMAT_ARGB8888 7
  45. struct mixer_resources {
  46. int irq;
  47. void __iomem *mixer_regs;
  48. void __iomem *vp_regs;
  49. spinlock_t reg_slock;
  50. struct clk *mixer;
  51. struct clk *vp;
  52. struct clk *hdmi;
  53. struct clk *sclk_mixer;
  54. struct clk *sclk_hdmi;
  55. struct clk *mout_mixer;
  56. };
  57. enum mixer_version_id {
  58. MXR_VER_0_0_0_16,
  59. MXR_VER_16_0_33_0,
  60. MXR_VER_128_0_0_184,
  61. };
  62. enum mixer_flag_bits {
  63. MXR_BIT_POWERED,
  64. MXR_BIT_VSYNC,
  65. };
  66. static const uint32_t mixer_formats[] = {
  67. DRM_FORMAT_XRGB4444,
  68. DRM_FORMAT_XRGB1555,
  69. DRM_FORMAT_RGB565,
  70. DRM_FORMAT_XRGB8888,
  71. DRM_FORMAT_ARGB8888,
  72. };
  73. static const uint32_t vp_formats[] = {
  74. DRM_FORMAT_NV12,
  75. DRM_FORMAT_NV21,
  76. };
  77. struct mixer_context {
  78. struct platform_device *pdev;
  79. struct device *dev;
  80. struct drm_device *drm_dev;
  81. struct exynos_drm_crtc *crtc;
  82. struct exynos_drm_plane planes[MIXER_WIN_NR];
  83. int pipe;
  84. unsigned long flags;
  85. bool interlace;
  86. bool vp_enabled;
  87. bool has_sclk;
  88. struct mixer_resources mixer_res;
  89. enum mixer_version_id mxr_ver;
  90. wait_queue_head_t wait_vsync_queue;
  91. atomic_t wait_vsync_event;
  92. };
  93. struct mixer_drv_data {
  94. enum mixer_version_id version;
  95. bool is_vp_enabled;
  96. bool has_sclk;
  97. };
  98. static const u8 filter_y_horiz_tap8[] = {
  99. 0, -1, -1, -1, -1, -1, -1, -1,
  100. -1, -1, -1, -1, -1, 0, 0, 0,
  101. 0, 2, 4, 5, 6, 6, 6, 6,
  102. 6, 5, 5, 4, 3, 2, 1, 1,
  103. 0, -6, -12, -16, -18, -20, -21, -20,
  104. -20, -18, -16, -13, -10, -8, -5, -2,
  105. 127, 126, 125, 121, 114, 107, 99, 89,
  106. 79, 68, 57, 46, 35, 25, 16, 8,
  107. };
  108. static const u8 filter_y_vert_tap4[] = {
  109. 0, -3, -6, -8, -8, -8, -8, -7,
  110. -6, -5, -4, -3, -2, -1, -1, 0,
  111. 127, 126, 124, 118, 111, 102, 92, 81,
  112. 70, 59, 48, 37, 27, 19, 11, 5,
  113. 0, 5, 11, 19, 27, 37, 48, 59,
  114. 70, 81, 92, 102, 111, 118, 124, 126,
  115. 0, 0, -1, -1, -2, -3, -4, -5,
  116. -6, -7, -8, -8, -8, -8, -6, -3,
  117. };
  118. static const u8 filter_cr_horiz_tap4[] = {
  119. 0, -3, -6, -8, -8, -8, -8, -7,
  120. -6, -5, -4, -3, -2, -1, -1, 0,
  121. 127, 126, 124, 118, 111, 102, 92, 81,
  122. 70, 59, 48, 37, 27, 19, 11, 5,
  123. };
  124. static inline u32 vp_reg_read(struct mixer_resources *res, u32 reg_id)
  125. {
  126. return readl(res->vp_regs + reg_id);
  127. }
  128. static inline void vp_reg_write(struct mixer_resources *res, u32 reg_id,
  129. u32 val)
  130. {
  131. writel(val, res->vp_regs + reg_id);
  132. }
  133. static inline void vp_reg_writemask(struct mixer_resources *res, u32 reg_id,
  134. u32 val, u32 mask)
  135. {
  136. u32 old = vp_reg_read(res, reg_id);
  137. val = (val & mask) | (old & ~mask);
  138. writel(val, res->vp_regs + reg_id);
  139. }
  140. static inline u32 mixer_reg_read(struct mixer_resources *res, u32 reg_id)
  141. {
  142. return readl(res->mixer_regs + reg_id);
  143. }
  144. static inline void mixer_reg_write(struct mixer_resources *res, u32 reg_id,
  145. u32 val)
  146. {
  147. writel(val, res->mixer_regs + reg_id);
  148. }
  149. static inline void mixer_reg_writemask(struct mixer_resources *res,
  150. u32 reg_id, u32 val, u32 mask)
  151. {
  152. u32 old = mixer_reg_read(res, reg_id);
  153. val = (val & mask) | (old & ~mask);
  154. writel(val, res->mixer_regs + reg_id);
  155. }
  156. static void mixer_regs_dump(struct mixer_context *ctx)
  157. {
  158. #define DUMPREG(reg_id) \
  159. do { \
  160. DRM_DEBUG_KMS(#reg_id " = %08x\n", \
  161. (u32)readl(ctx->mixer_res.mixer_regs + reg_id)); \
  162. } while (0)
  163. DUMPREG(MXR_STATUS);
  164. DUMPREG(MXR_CFG);
  165. DUMPREG(MXR_INT_EN);
  166. DUMPREG(MXR_INT_STATUS);
  167. DUMPREG(MXR_LAYER_CFG);
  168. DUMPREG(MXR_VIDEO_CFG);
  169. DUMPREG(MXR_GRAPHIC0_CFG);
  170. DUMPREG(MXR_GRAPHIC0_BASE);
  171. DUMPREG(MXR_GRAPHIC0_SPAN);
  172. DUMPREG(MXR_GRAPHIC0_WH);
  173. DUMPREG(MXR_GRAPHIC0_SXY);
  174. DUMPREG(MXR_GRAPHIC0_DXY);
  175. DUMPREG(MXR_GRAPHIC1_CFG);
  176. DUMPREG(MXR_GRAPHIC1_BASE);
  177. DUMPREG(MXR_GRAPHIC1_SPAN);
  178. DUMPREG(MXR_GRAPHIC1_WH);
  179. DUMPREG(MXR_GRAPHIC1_SXY);
  180. DUMPREG(MXR_GRAPHIC1_DXY);
  181. #undef DUMPREG
  182. }
  183. static void vp_regs_dump(struct mixer_context *ctx)
  184. {
  185. #define DUMPREG(reg_id) \
  186. do { \
  187. DRM_DEBUG_KMS(#reg_id " = %08x\n", \
  188. (u32) readl(ctx->mixer_res.vp_regs + reg_id)); \
  189. } while (0)
  190. DUMPREG(VP_ENABLE);
  191. DUMPREG(VP_SRESET);
  192. DUMPREG(VP_SHADOW_UPDATE);
  193. DUMPREG(VP_FIELD_ID);
  194. DUMPREG(VP_MODE);
  195. DUMPREG(VP_IMG_SIZE_Y);
  196. DUMPREG(VP_IMG_SIZE_C);
  197. DUMPREG(VP_PER_RATE_CTRL);
  198. DUMPREG(VP_TOP_Y_PTR);
  199. DUMPREG(VP_BOT_Y_PTR);
  200. DUMPREG(VP_TOP_C_PTR);
  201. DUMPREG(VP_BOT_C_PTR);
  202. DUMPREG(VP_ENDIAN_MODE);
  203. DUMPREG(VP_SRC_H_POSITION);
  204. DUMPREG(VP_SRC_V_POSITION);
  205. DUMPREG(VP_SRC_WIDTH);
  206. DUMPREG(VP_SRC_HEIGHT);
  207. DUMPREG(VP_DST_H_POSITION);
  208. DUMPREG(VP_DST_V_POSITION);
  209. DUMPREG(VP_DST_WIDTH);
  210. DUMPREG(VP_DST_HEIGHT);
  211. DUMPREG(VP_H_RATIO);
  212. DUMPREG(VP_V_RATIO);
  213. #undef DUMPREG
  214. }
  215. static inline void vp_filter_set(struct mixer_resources *res,
  216. int reg_id, const u8 *data, unsigned int size)
  217. {
  218. /* assure 4-byte align */
  219. BUG_ON(size & 3);
  220. for (; size; size -= 4, reg_id += 4, data += 4) {
  221. u32 val = (data[0] << 24) | (data[1] << 16) |
  222. (data[2] << 8) | data[3];
  223. vp_reg_write(res, reg_id, val);
  224. }
  225. }
  226. static void vp_default_filter(struct mixer_resources *res)
  227. {
  228. vp_filter_set(res, VP_POLY8_Y0_LL,
  229. filter_y_horiz_tap8, sizeof(filter_y_horiz_tap8));
  230. vp_filter_set(res, VP_POLY4_Y0_LL,
  231. filter_y_vert_tap4, sizeof(filter_y_vert_tap4));
  232. vp_filter_set(res, VP_POLY4_C0_LL,
  233. filter_cr_horiz_tap4, sizeof(filter_cr_horiz_tap4));
  234. }
  235. static void mixer_vsync_set_update(struct mixer_context *ctx, bool enable)
  236. {
  237. struct mixer_resources *res = &ctx->mixer_res;
  238. /* block update on vsync */
  239. mixer_reg_writemask(res, MXR_STATUS, enable ?
  240. MXR_STATUS_SYNC_ENABLE : 0, MXR_STATUS_SYNC_ENABLE);
  241. if (ctx->vp_enabled)
  242. vp_reg_write(res, VP_SHADOW_UPDATE, enable ?
  243. VP_SHADOW_UPDATE_ENABLE : 0);
  244. }
  245. static void mixer_cfg_scan(struct mixer_context *ctx, unsigned int height)
  246. {
  247. struct mixer_resources *res = &ctx->mixer_res;
  248. u32 val;
  249. /* choosing between interlace and progressive mode */
  250. val = (ctx->interlace ? MXR_CFG_SCAN_INTERLACE :
  251. MXR_CFG_SCAN_PROGRESSIVE);
  252. if (ctx->mxr_ver != MXR_VER_128_0_0_184) {
  253. /* choosing between proper HD and SD mode */
  254. if (height <= 480)
  255. val |= MXR_CFG_SCAN_NTSC | MXR_CFG_SCAN_SD;
  256. else if (height <= 576)
  257. val |= MXR_CFG_SCAN_PAL | MXR_CFG_SCAN_SD;
  258. else if (height <= 720)
  259. val |= MXR_CFG_SCAN_HD_720 | MXR_CFG_SCAN_HD;
  260. else if (height <= 1080)
  261. val |= MXR_CFG_SCAN_HD_1080 | MXR_CFG_SCAN_HD;
  262. else
  263. val |= MXR_CFG_SCAN_HD_720 | MXR_CFG_SCAN_HD;
  264. }
  265. mixer_reg_writemask(res, MXR_CFG, val, MXR_CFG_SCAN_MASK);
  266. }
  267. static void mixer_cfg_rgb_fmt(struct mixer_context *ctx, unsigned int height)
  268. {
  269. struct mixer_resources *res = &ctx->mixer_res;
  270. u32 val;
  271. if (height == 480) {
  272. val = MXR_CFG_RGB601_0_255;
  273. } else if (height == 576) {
  274. val = MXR_CFG_RGB601_0_255;
  275. } else if (height == 720) {
  276. val = MXR_CFG_RGB709_16_235;
  277. mixer_reg_write(res, MXR_CM_COEFF_Y,
  278. (1 << 30) | (94 << 20) | (314 << 10) |
  279. (32 << 0));
  280. mixer_reg_write(res, MXR_CM_COEFF_CB,
  281. (972 << 20) | (851 << 10) | (225 << 0));
  282. mixer_reg_write(res, MXR_CM_COEFF_CR,
  283. (225 << 20) | (820 << 10) | (1004 << 0));
  284. } else if (height == 1080) {
  285. val = MXR_CFG_RGB709_16_235;
  286. mixer_reg_write(res, MXR_CM_COEFF_Y,
  287. (1 << 30) | (94 << 20) | (314 << 10) |
  288. (32 << 0));
  289. mixer_reg_write(res, MXR_CM_COEFF_CB,
  290. (972 << 20) | (851 << 10) | (225 << 0));
  291. mixer_reg_write(res, MXR_CM_COEFF_CR,
  292. (225 << 20) | (820 << 10) | (1004 << 0));
  293. } else {
  294. val = MXR_CFG_RGB709_16_235;
  295. mixer_reg_write(res, MXR_CM_COEFF_Y,
  296. (1 << 30) | (94 << 20) | (314 << 10) |
  297. (32 << 0));
  298. mixer_reg_write(res, MXR_CM_COEFF_CB,
  299. (972 << 20) | (851 << 10) | (225 << 0));
  300. mixer_reg_write(res, MXR_CM_COEFF_CR,
  301. (225 << 20) | (820 << 10) | (1004 << 0));
  302. }
  303. mixer_reg_writemask(res, MXR_CFG, val, MXR_CFG_RGB_FMT_MASK);
  304. }
  305. static void mixer_cfg_layer(struct mixer_context *ctx, unsigned int win,
  306. bool enable)
  307. {
  308. struct mixer_resources *res = &ctx->mixer_res;
  309. u32 val = enable ? ~0 : 0;
  310. switch (win) {
  311. case 0:
  312. mixer_reg_writemask(res, MXR_CFG, val, MXR_CFG_GRP0_ENABLE);
  313. break;
  314. case 1:
  315. mixer_reg_writemask(res, MXR_CFG, val, MXR_CFG_GRP1_ENABLE);
  316. break;
  317. case 2:
  318. if (ctx->vp_enabled) {
  319. vp_reg_writemask(res, VP_ENABLE, val, VP_ENABLE_ON);
  320. mixer_reg_writemask(res, MXR_CFG, val,
  321. MXR_CFG_VP_ENABLE);
  322. /* control blending of graphic layer 0 */
  323. mixer_reg_writemask(res, MXR_GRAPHIC_CFG(0), val,
  324. MXR_GRP_CFG_BLEND_PRE_MUL |
  325. MXR_GRP_CFG_PIXEL_BLEND_EN);
  326. }
  327. break;
  328. }
  329. }
  330. static void mixer_run(struct mixer_context *ctx)
  331. {
  332. struct mixer_resources *res = &ctx->mixer_res;
  333. mixer_reg_writemask(res, MXR_STATUS, ~0, MXR_STATUS_REG_RUN);
  334. }
  335. static void mixer_stop(struct mixer_context *ctx)
  336. {
  337. struct mixer_resources *res = &ctx->mixer_res;
  338. int timeout = 20;
  339. mixer_reg_writemask(res, MXR_STATUS, 0, MXR_STATUS_REG_RUN);
  340. while (!(mixer_reg_read(res, MXR_STATUS) & MXR_STATUS_REG_IDLE) &&
  341. --timeout)
  342. usleep_range(10000, 12000);
  343. }
  344. static void vp_video_buffer(struct mixer_context *ctx,
  345. struct exynos_drm_plane *plane)
  346. {
  347. struct mixer_resources *res = &ctx->mixer_res;
  348. struct drm_plane_state *state = plane->base.state;
  349. struct drm_framebuffer *fb = state->fb;
  350. struct drm_display_mode *mode = &state->crtc->mode;
  351. unsigned long flags;
  352. dma_addr_t luma_addr[2], chroma_addr[2];
  353. bool tiled_mode = false;
  354. bool crcb_mode = false;
  355. u32 val;
  356. switch (fb->pixel_format) {
  357. case DRM_FORMAT_NV12:
  358. crcb_mode = false;
  359. break;
  360. case DRM_FORMAT_NV21:
  361. crcb_mode = true;
  362. break;
  363. default:
  364. DRM_ERROR("pixel format for vp is wrong [%d].\n",
  365. fb->pixel_format);
  366. return;
  367. }
  368. luma_addr[0] = plane->dma_addr[0];
  369. chroma_addr[0] = plane->dma_addr[1];
  370. if (mode->flags & DRM_MODE_FLAG_INTERLACE) {
  371. ctx->interlace = true;
  372. if (tiled_mode) {
  373. luma_addr[1] = luma_addr[0] + 0x40;
  374. chroma_addr[1] = chroma_addr[0] + 0x40;
  375. } else {
  376. luma_addr[1] = luma_addr[0] + fb->pitches[0];
  377. chroma_addr[1] = chroma_addr[0] + fb->pitches[0];
  378. }
  379. } else {
  380. ctx->interlace = false;
  381. luma_addr[1] = 0;
  382. chroma_addr[1] = 0;
  383. }
  384. spin_lock_irqsave(&res->reg_slock, flags);
  385. mixer_vsync_set_update(ctx, false);
  386. /* interlace or progressive scan mode */
  387. val = (ctx->interlace ? ~0 : 0);
  388. vp_reg_writemask(res, VP_MODE, val, VP_MODE_LINE_SKIP);
  389. /* setup format */
  390. val = (crcb_mode ? VP_MODE_NV21 : VP_MODE_NV12);
  391. val |= (tiled_mode ? VP_MODE_MEM_TILED : VP_MODE_MEM_LINEAR);
  392. vp_reg_writemask(res, VP_MODE, val, VP_MODE_FMT_MASK);
  393. /* setting size of input image */
  394. vp_reg_write(res, VP_IMG_SIZE_Y, VP_IMG_HSIZE(fb->pitches[0]) |
  395. VP_IMG_VSIZE(fb->height));
  396. /* chroma height has to reduced by 2 to avoid chroma distorions */
  397. vp_reg_write(res, VP_IMG_SIZE_C, VP_IMG_HSIZE(fb->pitches[0]) |
  398. VP_IMG_VSIZE(fb->height / 2));
  399. vp_reg_write(res, VP_SRC_WIDTH, plane->src_w);
  400. vp_reg_write(res, VP_SRC_HEIGHT, plane->src_h);
  401. vp_reg_write(res, VP_SRC_H_POSITION,
  402. VP_SRC_H_POSITION_VAL(plane->src_x));
  403. vp_reg_write(res, VP_SRC_V_POSITION, plane->src_y);
  404. vp_reg_write(res, VP_DST_WIDTH, plane->crtc_w);
  405. vp_reg_write(res, VP_DST_H_POSITION, plane->crtc_x);
  406. if (ctx->interlace) {
  407. vp_reg_write(res, VP_DST_HEIGHT, plane->crtc_h / 2);
  408. vp_reg_write(res, VP_DST_V_POSITION, plane->crtc_y / 2);
  409. } else {
  410. vp_reg_write(res, VP_DST_HEIGHT, plane->crtc_h);
  411. vp_reg_write(res, VP_DST_V_POSITION, plane->crtc_y);
  412. }
  413. vp_reg_write(res, VP_H_RATIO, plane->h_ratio);
  414. vp_reg_write(res, VP_V_RATIO, plane->v_ratio);
  415. vp_reg_write(res, VP_ENDIAN_MODE, VP_ENDIAN_MODE_LITTLE);
  416. /* set buffer address to vp */
  417. vp_reg_write(res, VP_TOP_Y_PTR, luma_addr[0]);
  418. vp_reg_write(res, VP_BOT_Y_PTR, luma_addr[1]);
  419. vp_reg_write(res, VP_TOP_C_PTR, chroma_addr[0]);
  420. vp_reg_write(res, VP_BOT_C_PTR, chroma_addr[1]);
  421. mixer_cfg_scan(ctx, mode->vdisplay);
  422. mixer_cfg_rgb_fmt(ctx, mode->vdisplay);
  423. mixer_cfg_layer(ctx, plane->zpos, true);
  424. mixer_run(ctx);
  425. mixer_vsync_set_update(ctx, true);
  426. spin_unlock_irqrestore(&res->reg_slock, flags);
  427. mixer_regs_dump(ctx);
  428. vp_regs_dump(ctx);
  429. }
  430. static void mixer_layer_update(struct mixer_context *ctx)
  431. {
  432. struct mixer_resources *res = &ctx->mixer_res;
  433. mixer_reg_writemask(res, MXR_CFG, ~0, MXR_CFG_LAYER_UPDATE);
  434. }
  435. static int mixer_setup_scale(const struct exynos_drm_plane *plane,
  436. unsigned int *x_ratio, unsigned int *y_ratio)
  437. {
  438. if (plane->crtc_w != plane->src_w) {
  439. if (plane->crtc_w == 2 * plane->src_w)
  440. *x_ratio = 1;
  441. else
  442. goto fail;
  443. }
  444. if (plane->crtc_h != plane->src_h) {
  445. if (plane->crtc_h == 2 * plane->src_h)
  446. *y_ratio = 1;
  447. else
  448. goto fail;
  449. }
  450. return 0;
  451. fail:
  452. DRM_DEBUG_KMS("only 2x width/height scaling of plane supported\n");
  453. return -ENOTSUPP;
  454. }
  455. static void mixer_graph_buffer(struct mixer_context *ctx,
  456. struct exynos_drm_plane *plane)
  457. {
  458. struct mixer_resources *res = &ctx->mixer_res;
  459. struct drm_plane_state *state = plane->base.state;
  460. struct drm_framebuffer *fb = state->fb;
  461. struct drm_display_mode *mode = &state->crtc->mode;
  462. unsigned long flags;
  463. unsigned int win = plane->zpos;
  464. unsigned int x_ratio = 0, y_ratio = 0;
  465. unsigned int src_x_offset, src_y_offset, dst_x_offset, dst_y_offset;
  466. dma_addr_t dma_addr;
  467. unsigned int fmt;
  468. u32 val;
  469. switch (fb->pixel_format) {
  470. case DRM_FORMAT_XRGB4444:
  471. fmt = MXR_FORMAT_ARGB4444;
  472. break;
  473. case DRM_FORMAT_XRGB1555:
  474. fmt = MXR_FORMAT_ARGB1555;
  475. break;
  476. case DRM_FORMAT_RGB565:
  477. fmt = MXR_FORMAT_RGB565;
  478. break;
  479. case DRM_FORMAT_XRGB8888:
  480. case DRM_FORMAT_ARGB8888:
  481. fmt = MXR_FORMAT_ARGB8888;
  482. break;
  483. default:
  484. DRM_DEBUG_KMS("pixelformat unsupported by mixer\n");
  485. return;
  486. }
  487. /* check if mixer supports requested scaling setup */
  488. if (mixer_setup_scale(plane, &x_ratio, &y_ratio))
  489. return;
  490. dst_x_offset = plane->crtc_x;
  491. dst_y_offset = plane->crtc_y;
  492. /* converting dma address base and source offset */
  493. dma_addr = plane->dma_addr[0]
  494. + (plane->src_x * fb->bits_per_pixel >> 3)
  495. + (plane->src_y * fb->pitches[0]);
  496. src_x_offset = 0;
  497. src_y_offset = 0;
  498. if (mode->flags & DRM_MODE_FLAG_INTERLACE)
  499. ctx->interlace = true;
  500. else
  501. ctx->interlace = false;
  502. spin_lock_irqsave(&res->reg_slock, flags);
  503. mixer_vsync_set_update(ctx, false);
  504. /* setup format */
  505. mixer_reg_writemask(res, MXR_GRAPHIC_CFG(win),
  506. MXR_GRP_CFG_FORMAT_VAL(fmt), MXR_GRP_CFG_FORMAT_MASK);
  507. /* setup geometry */
  508. mixer_reg_write(res, MXR_GRAPHIC_SPAN(win),
  509. fb->pitches[0] / (fb->bits_per_pixel >> 3));
  510. /* setup display size */
  511. if (ctx->mxr_ver == MXR_VER_128_0_0_184 &&
  512. win == DEFAULT_WIN) {
  513. val = MXR_MXR_RES_HEIGHT(mode->vdisplay);
  514. val |= MXR_MXR_RES_WIDTH(mode->hdisplay);
  515. mixer_reg_write(res, MXR_RESOLUTION, val);
  516. }
  517. val = MXR_GRP_WH_WIDTH(plane->src_w);
  518. val |= MXR_GRP_WH_HEIGHT(plane->src_h);
  519. val |= MXR_GRP_WH_H_SCALE(x_ratio);
  520. val |= MXR_GRP_WH_V_SCALE(y_ratio);
  521. mixer_reg_write(res, MXR_GRAPHIC_WH(win), val);
  522. /* setup offsets in source image */
  523. val = MXR_GRP_SXY_SX(src_x_offset);
  524. val |= MXR_GRP_SXY_SY(src_y_offset);
  525. mixer_reg_write(res, MXR_GRAPHIC_SXY(win), val);
  526. /* setup offsets in display image */
  527. val = MXR_GRP_DXY_DX(dst_x_offset);
  528. val |= MXR_GRP_DXY_DY(dst_y_offset);
  529. mixer_reg_write(res, MXR_GRAPHIC_DXY(win), val);
  530. /* set buffer address to mixer */
  531. mixer_reg_write(res, MXR_GRAPHIC_BASE(win), dma_addr);
  532. mixer_cfg_scan(ctx, mode->vdisplay);
  533. mixer_cfg_rgb_fmt(ctx, mode->vdisplay);
  534. mixer_cfg_layer(ctx, win, true);
  535. /* layer update mandatory for mixer 16.0.33.0 */
  536. if (ctx->mxr_ver == MXR_VER_16_0_33_0 ||
  537. ctx->mxr_ver == MXR_VER_128_0_0_184)
  538. mixer_layer_update(ctx);
  539. mixer_run(ctx);
  540. mixer_vsync_set_update(ctx, true);
  541. spin_unlock_irqrestore(&res->reg_slock, flags);
  542. mixer_regs_dump(ctx);
  543. }
  544. static void vp_win_reset(struct mixer_context *ctx)
  545. {
  546. struct mixer_resources *res = &ctx->mixer_res;
  547. int tries = 100;
  548. vp_reg_write(res, VP_SRESET, VP_SRESET_PROCESSING);
  549. for (tries = 100; tries; --tries) {
  550. /* waiting until VP_SRESET_PROCESSING is 0 */
  551. if (~vp_reg_read(res, VP_SRESET) & VP_SRESET_PROCESSING)
  552. break;
  553. mdelay(10);
  554. }
  555. WARN(tries == 0, "failed to reset Video Processor\n");
  556. }
  557. static void mixer_win_reset(struct mixer_context *ctx)
  558. {
  559. struct mixer_resources *res = &ctx->mixer_res;
  560. unsigned long flags;
  561. u32 val; /* value stored to register */
  562. spin_lock_irqsave(&res->reg_slock, flags);
  563. mixer_vsync_set_update(ctx, false);
  564. mixer_reg_writemask(res, MXR_CFG, MXR_CFG_DST_HDMI, MXR_CFG_DST_MASK);
  565. /* set output in RGB888 mode */
  566. mixer_reg_writemask(res, MXR_CFG, MXR_CFG_OUT_RGB888, MXR_CFG_OUT_MASK);
  567. /* 16 beat burst in DMA */
  568. mixer_reg_writemask(res, MXR_STATUS, MXR_STATUS_16_BURST,
  569. MXR_STATUS_BURST_MASK);
  570. /* setting default layer priority: layer1 > layer0 > video
  571. * because typical usage scenario would be
  572. * layer1 - OSD
  573. * layer0 - framebuffer
  574. * video - video overlay
  575. */
  576. val = MXR_LAYER_CFG_GRP1_VAL(3);
  577. val |= MXR_LAYER_CFG_GRP0_VAL(2);
  578. if (ctx->vp_enabled)
  579. val |= MXR_LAYER_CFG_VP_VAL(1);
  580. mixer_reg_write(res, MXR_LAYER_CFG, val);
  581. /* setting background color */
  582. mixer_reg_write(res, MXR_BG_COLOR0, 0x008080);
  583. mixer_reg_write(res, MXR_BG_COLOR1, 0x008080);
  584. mixer_reg_write(res, MXR_BG_COLOR2, 0x008080);
  585. /* setting graphical layers */
  586. val = MXR_GRP_CFG_COLOR_KEY_DISABLE; /* no blank key */
  587. val |= MXR_GRP_CFG_WIN_BLEND_EN;
  588. val |= MXR_GRP_CFG_ALPHA_VAL(0xff); /* non-transparent alpha */
  589. /* Don't blend layer 0 onto the mixer background */
  590. mixer_reg_write(res, MXR_GRAPHIC_CFG(0), val);
  591. /* Blend layer 1 into layer 0 */
  592. val |= MXR_GRP_CFG_BLEND_PRE_MUL;
  593. val |= MXR_GRP_CFG_PIXEL_BLEND_EN;
  594. mixer_reg_write(res, MXR_GRAPHIC_CFG(1), val);
  595. /* setting video layers */
  596. val = MXR_GRP_CFG_ALPHA_VAL(0);
  597. mixer_reg_write(res, MXR_VIDEO_CFG, val);
  598. if (ctx->vp_enabled) {
  599. /* configuration of Video Processor Registers */
  600. vp_win_reset(ctx);
  601. vp_default_filter(res);
  602. }
  603. /* disable all layers */
  604. mixer_reg_writemask(res, MXR_CFG, 0, MXR_CFG_GRP0_ENABLE);
  605. mixer_reg_writemask(res, MXR_CFG, 0, MXR_CFG_GRP1_ENABLE);
  606. if (ctx->vp_enabled)
  607. mixer_reg_writemask(res, MXR_CFG, 0, MXR_CFG_VP_ENABLE);
  608. mixer_vsync_set_update(ctx, true);
  609. spin_unlock_irqrestore(&res->reg_slock, flags);
  610. }
  611. static irqreturn_t mixer_irq_handler(int irq, void *arg)
  612. {
  613. struct mixer_context *ctx = arg;
  614. struct mixer_resources *res = &ctx->mixer_res;
  615. u32 val, base, shadow;
  616. int win;
  617. spin_lock(&res->reg_slock);
  618. /* read interrupt status for handling and clearing flags for VSYNC */
  619. val = mixer_reg_read(res, MXR_INT_STATUS);
  620. /* handling VSYNC */
  621. if (val & MXR_INT_STATUS_VSYNC) {
  622. /* vsync interrupt use different bit for read and clear */
  623. val |= MXR_INT_CLEAR_VSYNC;
  624. val &= ~MXR_INT_STATUS_VSYNC;
  625. /* interlace scan need to check shadow register */
  626. if (ctx->interlace) {
  627. base = mixer_reg_read(res, MXR_GRAPHIC_BASE(0));
  628. shadow = mixer_reg_read(res, MXR_GRAPHIC_BASE_S(0));
  629. if (base != shadow)
  630. goto out;
  631. base = mixer_reg_read(res, MXR_GRAPHIC_BASE(1));
  632. shadow = mixer_reg_read(res, MXR_GRAPHIC_BASE_S(1));
  633. if (base != shadow)
  634. goto out;
  635. }
  636. drm_crtc_handle_vblank(&ctx->crtc->base);
  637. for (win = 0 ; win < MIXER_WIN_NR ; win++) {
  638. struct exynos_drm_plane *plane = &ctx->planes[win];
  639. if (!plane->pending_fb)
  640. continue;
  641. exynos_drm_crtc_finish_update(ctx->crtc, plane);
  642. }
  643. /* set wait vsync event to zero and wake up queue. */
  644. if (atomic_read(&ctx->wait_vsync_event)) {
  645. atomic_set(&ctx->wait_vsync_event, 0);
  646. wake_up(&ctx->wait_vsync_queue);
  647. }
  648. }
  649. out:
  650. /* clear interrupts */
  651. mixer_reg_write(res, MXR_INT_STATUS, val);
  652. spin_unlock(&res->reg_slock);
  653. return IRQ_HANDLED;
  654. }
  655. static int mixer_resources_init(struct mixer_context *mixer_ctx)
  656. {
  657. struct device *dev = &mixer_ctx->pdev->dev;
  658. struct mixer_resources *mixer_res = &mixer_ctx->mixer_res;
  659. struct resource *res;
  660. int ret;
  661. spin_lock_init(&mixer_res->reg_slock);
  662. mixer_res->mixer = devm_clk_get(dev, "mixer");
  663. if (IS_ERR(mixer_res->mixer)) {
  664. dev_err(dev, "failed to get clock 'mixer'\n");
  665. return -ENODEV;
  666. }
  667. mixer_res->hdmi = devm_clk_get(dev, "hdmi");
  668. if (IS_ERR(mixer_res->hdmi)) {
  669. dev_err(dev, "failed to get clock 'hdmi'\n");
  670. return PTR_ERR(mixer_res->hdmi);
  671. }
  672. mixer_res->sclk_hdmi = devm_clk_get(dev, "sclk_hdmi");
  673. if (IS_ERR(mixer_res->sclk_hdmi)) {
  674. dev_err(dev, "failed to get clock 'sclk_hdmi'\n");
  675. return -ENODEV;
  676. }
  677. res = platform_get_resource(mixer_ctx->pdev, IORESOURCE_MEM, 0);
  678. if (res == NULL) {
  679. dev_err(dev, "get memory resource failed.\n");
  680. return -ENXIO;
  681. }
  682. mixer_res->mixer_regs = devm_ioremap(dev, res->start,
  683. resource_size(res));
  684. if (mixer_res->mixer_regs == NULL) {
  685. dev_err(dev, "register mapping failed.\n");
  686. return -ENXIO;
  687. }
  688. res = platform_get_resource(mixer_ctx->pdev, IORESOURCE_IRQ, 0);
  689. if (res == NULL) {
  690. dev_err(dev, "get interrupt resource failed.\n");
  691. return -ENXIO;
  692. }
  693. ret = devm_request_irq(dev, res->start, mixer_irq_handler,
  694. 0, "drm_mixer", mixer_ctx);
  695. if (ret) {
  696. dev_err(dev, "request interrupt failed.\n");
  697. return ret;
  698. }
  699. mixer_res->irq = res->start;
  700. return 0;
  701. }
  702. static int vp_resources_init(struct mixer_context *mixer_ctx)
  703. {
  704. struct device *dev = &mixer_ctx->pdev->dev;
  705. struct mixer_resources *mixer_res = &mixer_ctx->mixer_res;
  706. struct resource *res;
  707. mixer_res->vp = devm_clk_get(dev, "vp");
  708. if (IS_ERR(mixer_res->vp)) {
  709. dev_err(dev, "failed to get clock 'vp'\n");
  710. return -ENODEV;
  711. }
  712. if (mixer_ctx->has_sclk) {
  713. mixer_res->sclk_mixer = devm_clk_get(dev, "sclk_mixer");
  714. if (IS_ERR(mixer_res->sclk_mixer)) {
  715. dev_err(dev, "failed to get clock 'sclk_mixer'\n");
  716. return -ENODEV;
  717. }
  718. mixer_res->mout_mixer = devm_clk_get(dev, "mout_mixer");
  719. if (IS_ERR(mixer_res->mout_mixer)) {
  720. dev_err(dev, "failed to get clock 'mout_mixer'\n");
  721. return -ENODEV;
  722. }
  723. if (mixer_res->sclk_hdmi && mixer_res->mout_mixer)
  724. clk_set_parent(mixer_res->mout_mixer,
  725. mixer_res->sclk_hdmi);
  726. }
  727. res = platform_get_resource(mixer_ctx->pdev, IORESOURCE_MEM, 1);
  728. if (res == NULL) {
  729. dev_err(dev, "get memory resource failed.\n");
  730. return -ENXIO;
  731. }
  732. mixer_res->vp_regs = devm_ioremap(dev, res->start,
  733. resource_size(res));
  734. if (mixer_res->vp_regs == NULL) {
  735. dev_err(dev, "register mapping failed.\n");
  736. return -ENXIO;
  737. }
  738. return 0;
  739. }
  740. static int mixer_initialize(struct mixer_context *mixer_ctx,
  741. struct drm_device *drm_dev)
  742. {
  743. int ret;
  744. struct exynos_drm_private *priv;
  745. priv = drm_dev->dev_private;
  746. mixer_ctx->drm_dev = drm_dev;
  747. mixer_ctx->pipe = priv->pipe++;
  748. /* acquire resources: regs, irqs, clocks */
  749. ret = mixer_resources_init(mixer_ctx);
  750. if (ret) {
  751. DRM_ERROR("mixer_resources_init failed ret=%d\n", ret);
  752. return ret;
  753. }
  754. if (mixer_ctx->vp_enabled) {
  755. /* acquire vp resources: regs, irqs, clocks */
  756. ret = vp_resources_init(mixer_ctx);
  757. if (ret) {
  758. DRM_ERROR("vp_resources_init failed ret=%d\n", ret);
  759. return ret;
  760. }
  761. }
  762. ret = drm_iommu_attach_device(drm_dev, mixer_ctx->dev);
  763. if (ret)
  764. priv->pipe--;
  765. return ret;
  766. }
  767. static void mixer_ctx_remove(struct mixer_context *mixer_ctx)
  768. {
  769. drm_iommu_detach_device(mixer_ctx->drm_dev, mixer_ctx->dev);
  770. }
  771. static int mixer_enable_vblank(struct exynos_drm_crtc *crtc)
  772. {
  773. struct mixer_context *mixer_ctx = crtc->ctx;
  774. struct mixer_resources *res = &mixer_ctx->mixer_res;
  775. __set_bit(MXR_BIT_VSYNC, &mixer_ctx->flags);
  776. if (!test_bit(MXR_BIT_POWERED, &mixer_ctx->flags))
  777. return 0;
  778. /* enable vsync interrupt */
  779. mixer_reg_writemask(res, MXR_INT_STATUS, ~0, MXR_INT_CLEAR_VSYNC);
  780. mixer_reg_writemask(res, MXR_INT_EN, ~0, MXR_INT_EN_VSYNC);
  781. return 0;
  782. }
  783. static void mixer_disable_vblank(struct exynos_drm_crtc *crtc)
  784. {
  785. struct mixer_context *mixer_ctx = crtc->ctx;
  786. struct mixer_resources *res = &mixer_ctx->mixer_res;
  787. __clear_bit(MXR_BIT_VSYNC, &mixer_ctx->flags);
  788. if (!test_bit(MXR_BIT_POWERED, &mixer_ctx->flags))
  789. return;
  790. /* disable vsync interrupt */
  791. mixer_reg_writemask(res, MXR_INT_STATUS, ~0, MXR_INT_CLEAR_VSYNC);
  792. mixer_reg_writemask(res, MXR_INT_EN, 0, MXR_INT_EN_VSYNC);
  793. }
  794. static void mixer_update_plane(struct exynos_drm_crtc *crtc,
  795. struct exynos_drm_plane *plane)
  796. {
  797. struct mixer_context *mixer_ctx = crtc->ctx;
  798. DRM_DEBUG_KMS("win: %d\n", plane->zpos);
  799. if (!test_bit(MXR_BIT_POWERED, &mixer_ctx->flags))
  800. return;
  801. if (plane->zpos > 1 && mixer_ctx->vp_enabled)
  802. vp_video_buffer(mixer_ctx, plane);
  803. else
  804. mixer_graph_buffer(mixer_ctx, plane);
  805. }
  806. static void mixer_disable_plane(struct exynos_drm_crtc *crtc,
  807. struct exynos_drm_plane *plane)
  808. {
  809. struct mixer_context *mixer_ctx = crtc->ctx;
  810. struct mixer_resources *res = &mixer_ctx->mixer_res;
  811. unsigned long flags;
  812. DRM_DEBUG_KMS("win: %d\n", plane->zpos);
  813. if (!test_bit(MXR_BIT_POWERED, &mixer_ctx->flags))
  814. return;
  815. spin_lock_irqsave(&res->reg_slock, flags);
  816. mixer_vsync_set_update(mixer_ctx, false);
  817. mixer_cfg_layer(mixer_ctx, plane->zpos, false);
  818. mixer_vsync_set_update(mixer_ctx, true);
  819. spin_unlock_irqrestore(&res->reg_slock, flags);
  820. }
  821. static void mixer_wait_for_vblank(struct exynos_drm_crtc *crtc)
  822. {
  823. struct mixer_context *mixer_ctx = crtc->ctx;
  824. int err;
  825. if (!test_bit(MXR_BIT_POWERED, &mixer_ctx->flags))
  826. return;
  827. err = drm_vblank_get(mixer_ctx->drm_dev, mixer_ctx->pipe);
  828. if (err < 0) {
  829. DRM_DEBUG_KMS("failed to acquire vblank counter\n");
  830. return;
  831. }
  832. atomic_set(&mixer_ctx->wait_vsync_event, 1);
  833. /*
  834. * wait for MIXER to signal VSYNC interrupt or return after
  835. * timeout which is set to 50ms (refresh rate of 20).
  836. */
  837. if (!wait_event_timeout(mixer_ctx->wait_vsync_queue,
  838. !atomic_read(&mixer_ctx->wait_vsync_event),
  839. HZ/20))
  840. DRM_DEBUG_KMS("vblank wait timed out.\n");
  841. drm_vblank_put(mixer_ctx->drm_dev, mixer_ctx->pipe);
  842. }
  843. static void mixer_enable(struct exynos_drm_crtc *crtc)
  844. {
  845. struct mixer_context *ctx = crtc->ctx;
  846. struct mixer_resources *res = &ctx->mixer_res;
  847. int ret;
  848. if (test_bit(MXR_BIT_POWERED, &ctx->flags))
  849. return;
  850. pm_runtime_get_sync(ctx->dev);
  851. ret = clk_prepare_enable(res->mixer);
  852. if (ret < 0) {
  853. DRM_ERROR("Failed to prepare_enable the mixer clk [%d]\n", ret);
  854. return;
  855. }
  856. ret = clk_prepare_enable(res->hdmi);
  857. if (ret < 0) {
  858. DRM_ERROR("Failed to prepare_enable the hdmi clk [%d]\n", ret);
  859. return;
  860. }
  861. if (ctx->vp_enabled) {
  862. ret = clk_prepare_enable(res->vp);
  863. if (ret < 0) {
  864. DRM_ERROR("Failed to prepare_enable the vp clk [%d]\n",
  865. ret);
  866. return;
  867. }
  868. if (ctx->has_sclk) {
  869. ret = clk_prepare_enable(res->sclk_mixer);
  870. if (ret < 0) {
  871. DRM_ERROR("Failed to prepare_enable the " \
  872. "sclk_mixer clk [%d]\n",
  873. ret);
  874. return;
  875. }
  876. }
  877. }
  878. set_bit(MXR_BIT_POWERED, &ctx->flags);
  879. mixer_reg_writemask(res, MXR_STATUS, ~0, MXR_STATUS_SOFT_RESET);
  880. if (test_bit(MXR_BIT_VSYNC, &ctx->flags)) {
  881. mixer_reg_writemask(res, MXR_INT_STATUS, ~0, MXR_INT_CLEAR_VSYNC);
  882. mixer_reg_writemask(res, MXR_INT_EN, ~0, MXR_INT_EN_VSYNC);
  883. }
  884. mixer_win_reset(ctx);
  885. }
  886. static void mixer_disable(struct exynos_drm_crtc *crtc)
  887. {
  888. struct mixer_context *ctx = crtc->ctx;
  889. struct mixer_resources *res = &ctx->mixer_res;
  890. int i;
  891. if (!test_bit(MXR_BIT_POWERED, &ctx->flags))
  892. return;
  893. mixer_stop(ctx);
  894. mixer_regs_dump(ctx);
  895. for (i = 0; i < MIXER_WIN_NR; i++)
  896. mixer_disable_plane(crtc, &ctx->planes[i]);
  897. clear_bit(MXR_BIT_POWERED, &ctx->flags);
  898. clk_disable_unprepare(res->hdmi);
  899. clk_disable_unprepare(res->mixer);
  900. if (ctx->vp_enabled) {
  901. clk_disable_unprepare(res->vp);
  902. if (ctx->has_sclk)
  903. clk_disable_unprepare(res->sclk_mixer);
  904. }
  905. pm_runtime_put_sync(ctx->dev);
  906. }
  907. /* Only valid for Mixer version 16.0.33.0 */
  908. static int mixer_atomic_check(struct exynos_drm_crtc *crtc,
  909. struct drm_crtc_state *state)
  910. {
  911. struct drm_display_mode *mode = &state->adjusted_mode;
  912. u32 w, h;
  913. w = mode->hdisplay;
  914. h = mode->vdisplay;
  915. DRM_DEBUG_KMS("xres=%d, yres=%d, refresh=%d, intl=%d\n",
  916. mode->hdisplay, mode->vdisplay, mode->vrefresh,
  917. (mode->flags & DRM_MODE_FLAG_INTERLACE) ? 1 : 0);
  918. if ((w >= 464 && w <= 720 && h >= 261 && h <= 576) ||
  919. (w >= 1024 && w <= 1280 && h >= 576 && h <= 720) ||
  920. (w >= 1664 && w <= 1920 && h >= 936 && h <= 1080))
  921. return 0;
  922. return -EINVAL;
  923. }
  924. static const struct exynos_drm_crtc_ops mixer_crtc_ops = {
  925. .enable = mixer_enable,
  926. .disable = mixer_disable,
  927. .enable_vblank = mixer_enable_vblank,
  928. .disable_vblank = mixer_disable_vblank,
  929. .wait_for_vblank = mixer_wait_for_vblank,
  930. .update_plane = mixer_update_plane,
  931. .disable_plane = mixer_disable_plane,
  932. .atomic_check = mixer_atomic_check,
  933. };
  934. static struct mixer_drv_data exynos5420_mxr_drv_data = {
  935. .version = MXR_VER_128_0_0_184,
  936. .is_vp_enabled = 0,
  937. };
  938. static struct mixer_drv_data exynos5250_mxr_drv_data = {
  939. .version = MXR_VER_16_0_33_0,
  940. .is_vp_enabled = 0,
  941. };
  942. static struct mixer_drv_data exynos4212_mxr_drv_data = {
  943. .version = MXR_VER_0_0_0_16,
  944. .is_vp_enabled = 1,
  945. };
  946. static struct mixer_drv_data exynos4210_mxr_drv_data = {
  947. .version = MXR_VER_0_0_0_16,
  948. .is_vp_enabled = 1,
  949. .has_sclk = 1,
  950. };
  951. static const struct platform_device_id mixer_driver_types[] = {
  952. {
  953. .name = "s5p-mixer",
  954. .driver_data = (unsigned long)&exynos4210_mxr_drv_data,
  955. }, {
  956. .name = "exynos5-mixer",
  957. .driver_data = (unsigned long)&exynos5250_mxr_drv_data,
  958. }, {
  959. /* end node */
  960. }
  961. };
  962. static struct of_device_id mixer_match_types[] = {
  963. {
  964. .compatible = "samsung,exynos4210-mixer",
  965. .data = &exynos4210_mxr_drv_data,
  966. }, {
  967. .compatible = "samsung,exynos4212-mixer",
  968. .data = &exynos4212_mxr_drv_data,
  969. }, {
  970. .compatible = "samsung,exynos5-mixer",
  971. .data = &exynos5250_mxr_drv_data,
  972. }, {
  973. .compatible = "samsung,exynos5250-mixer",
  974. .data = &exynos5250_mxr_drv_data,
  975. }, {
  976. .compatible = "samsung,exynos5420-mixer",
  977. .data = &exynos5420_mxr_drv_data,
  978. }, {
  979. /* end node */
  980. }
  981. };
  982. MODULE_DEVICE_TABLE(of, mixer_match_types);
  983. static int mixer_bind(struct device *dev, struct device *manager, void *data)
  984. {
  985. struct mixer_context *ctx = dev_get_drvdata(dev);
  986. struct drm_device *drm_dev = data;
  987. struct exynos_drm_plane *exynos_plane;
  988. unsigned int zpos;
  989. int ret;
  990. ret = mixer_initialize(ctx, drm_dev);
  991. if (ret)
  992. return ret;
  993. for (zpos = 0; zpos < MIXER_WIN_NR; zpos++) {
  994. enum drm_plane_type type;
  995. const uint32_t *formats;
  996. unsigned int fcount;
  997. if (zpos < VP_DEFAULT_WIN) {
  998. formats = mixer_formats;
  999. fcount = ARRAY_SIZE(mixer_formats);
  1000. } else {
  1001. formats = vp_formats;
  1002. fcount = ARRAY_SIZE(vp_formats);
  1003. }
  1004. type = exynos_plane_get_type(zpos, CURSOR_WIN);
  1005. ret = exynos_plane_init(drm_dev, &ctx->planes[zpos],
  1006. 1 << ctx->pipe, type, formats, fcount,
  1007. zpos);
  1008. if (ret)
  1009. return ret;
  1010. }
  1011. exynos_plane = &ctx->planes[DEFAULT_WIN];
  1012. ctx->crtc = exynos_drm_crtc_create(drm_dev, &exynos_plane->base,
  1013. ctx->pipe, EXYNOS_DISPLAY_TYPE_HDMI,
  1014. &mixer_crtc_ops, ctx);
  1015. if (IS_ERR(ctx->crtc)) {
  1016. mixer_ctx_remove(ctx);
  1017. ret = PTR_ERR(ctx->crtc);
  1018. goto free_ctx;
  1019. }
  1020. return 0;
  1021. free_ctx:
  1022. devm_kfree(dev, ctx);
  1023. return ret;
  1024. }
  1025. static void mixer_unbind(struct device *dev, struct device *master, void *data)
  1026. {
  1027. struct mixer_context *ctx = dev_get_drvdata(dev);
  1028. mixer_ctx_remove(ctx);
  1029. }
  1030. static const struct component_ops mixer_component_ops = {
  1031. .bind = mixer_bind,
  1032. .unbind = mixer_unbind,
  1033. };
  1034. static int mixer_probe(struct platform_device *pdev)
  1035. {
  1036. struct device *dev = &pdev->dev;
  1037. struct mixer_drv_data *drv;
  1038. struct mixer_context *ctx;
  1039. int ret;
  1040. ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_KERNEL);
  1041. if (!ctx) {
  1042. DRM_ERROR("failed to alloc mixer context.\n");
  1043. return -ENOMEM;
  1044. }
  1045. if (dev->of_node) {
  1046. const struct of_device_id *match;
  1047. match = of_match_node(mixer_match_types, dev->of_node);
  1048. drv = (struct mixer_drv_data *)match->data;
  1049. } else {
  1050. drv = (struct mixer_drv_data *)
  1051. platform_get_device_id(pdev)->driver_data;
  1052. }
  1053. ctx->pdev = pdev;
  1054. ctx->dev = dev;
  1055. ctx->vp_enabled = drv->is_vp_enabled;
  1056. ctx->has_sclk = drv->has_sclk;
  1057. ctx->mxr_ver = drv->version;
  1058. init_waitqueue_head(&ctx->wait_vsync_queue);
  1059. atomic_set(&ctx->wait_vsync_event, 0);
  1060. platform_set_drvdata(pdev, ctx);
  1061. ret = component_add(&pdev->dev, &mixer_component_ops);
  1062. if (!ret)
  1063. pm_runtime_enable(dev);
  1064. return ret;
  1065. }
  1066. static int mixer_remove(struct platform_device *pdev)
  1067. {
  1068. pm_runtime_disable(&pdev->dev);
  1069. component_del(&pdev->dev, &mixer_component_ops);
  1070. return 0;
  1071. }
  1072. struct platform_driver mixer_driver = {
  1073. .driver = {
  1074. .name = "exynos-mixer",
  1075. .owner = THIS_MODULE,
  1076. .of_match_table = mixer_match_types,
  1077. },
  1078. .probe = mixer_probe,
  1079. .remove = mixer_remove,
  1080. .id_table = mixer_driver_types,
  1081. };