exynos_mixer.c 34 KB

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